# Implementation Plan: Candle Company Marketing Webpage ## Goal Design and implement a single-page (or small multi-section) marketing website for a candle company that showcases products, brand story, and enables direct purchase or wholesale inquiries. ## Ambiguity to Resolve Before Coding The request is underspecified. Before implementation, the parent/owner should confirm the following (these are listed in **Risks** as well): - Company name, brand voice, color palette, and logo (or placeholders acceptable). - Product catalog: number of SKUs, scent names, prices, sizes, and imagery (or placeholders acceptable). - Commerce model: direct checkout (Shopify, Stripe, Snipcart) vs. "request a quote" / wholesale form vs. informational only. - Tech stack: plain HTML/CSS/JS, a static site generator (Astro, Eleventy, Hugo), or a React/Next.js app. - Hosting target: GitHub Pages, Netlify, Vercel, or self-hosted. - Pages required: single landing page, or Home / Shop / About / Contact split. - Compliance: any claims (e.g., "eco-friendly", "soy", "hand-poured") need substantiation; FDA/CPSC prop-65 warnings if marketed in CA. Default assumptions (used to make the plan concrete; can be overridden): - **Stack**: Astro (static-first, SEO-friendly, easy to deploy to Netlify/Vercel). - **Scope**: Home, Shop, About, Contact — 4 routes plus a shared layout. - **Commerce**: Snipcart (drop-in cart) or a simple "Add to Cart" UI that posts to a hosted checkout. If the owner prefers no commerce, replace Shop with a product gallery and a Contact form. - **Brand**: placeholder name "Ember & Wick", warm neutral palette, serif display + sans body. - **Assets**: SVG placeholders for product imagery, real assets to be supplied later. --- ## Tasks 1. **Task 1: Scaffold project** - Files: `package.json`, `astro.config.mjs`, `tsconfig.json`, `.gitignore`, `README.md`. - Steps: `npm create astro@latest -- --template minimal --no-install`, add Tailwind via `npx astro add tailwind`, install Snipcart loader if commerce is in scope. - Acceptance: `npm run dev` serves a blank page at `http://localhost:4321`; `npm run build` produces `dist/`. 2. **Task 2: Define design tokens and global styles** - File: `src/styles/global.css` (or `tailwind.config.mjs` if using Tailwind). - Changes: palette (e.g., warm cream `#F6F1E7`, charcoal `#2B2A28`, ember `#C8553D`, wax `#E9DFC9`), typography scale (serif display, sans body), spacing scale, focus ring, reduced-motion media query. - Acceptance: Lighthouse contrast checks pass AA on body text and CTAs. 3. **Task 3: Build shared layout** - Files: `src/layouts/BaseLayout.astro`, `src/components/SiteHeader.astro`, `src/components/SiteFooter.astro`, `src/components/SeoHead.astro`. - Changes: sticky header with nav (Home / Shop / About / Contact), mobile hamburger, footer with newsletter signup (Mailchimp/Buttondown embed), SEO meta, Open Graph, favicon, JSON-LD `Organization` schema. - Acceptance: Header collapses to a working menu at <768px; OG image preview renders when sharing. 4. **Task 4: Author content collection for products** - Files: `src/content/config.ts`, `src/content/products/*.md` (one file per candle). - Changes: Zod schema with `name`, `slug`, `scentNotes` (top/heart/base), `burnHours`, `sizeOz`, `priceUSD`, `image`, `inStock`, `tags[]`. Seed with 6 placeholder SKUs. - Acceptance: `astro build` validates all entries; missing fields fail the build. 5. **Task 5: Home page** - File: `src/pages/index.astro`. - Sections: hero with brand tagline + CTA, "Best Sellers" carousel (3–6 products from collection), brand story teaser, Instagram/UGC grid (placeholder images), email capture, footer. - Acceptance: LCP < 2.5s on a simulated Fast 3G; hero CTA is keyboard-reachable. 6. **Task 6: Shop page** - File: `src/pages/shop.astro` plus `src/components/ProductCard.astro`, `src/components/ProductGrid.astro`, `src/components/FilterBar.astro`. - Changes: grid of `ProductCard`, client-side filter by `tags` (scent family, size), sort by price/name, "Add to Cart" button wired to Snipcart (or a placeholder alert if commerce out of scope). - Acceptance: filter/sort works with no layout shift; empty state when no results. 7. **Task 7: Product detail page** - File: `src/pages/shop/[slug].astro`. - Changes: large image, scent pyramid, burn time, ingredients, care instructions, related products, add-to-cart. - Acceptance: dynamic route generates one page per content entry; 404 for unknown slugs. 8. **Task 8: About page** - File: `src/pages/about.astro`. - Sections: founder story, process (sourcing, pouring, curing), sustainability claims (with citations where required), atelier/team photos. - Acceptance: every quantitative claim is either sourced or labeled as aspirational. 9. **Task 9: Contact / Wholesale page** - File: `src/pages/contact.astro`. - Changes: form fields (name, email, message, inquiry type: retail/wholesale/press), serverless handler (Astro endpoint `src/pages/api/contact.ts` posting to Resend or Formspree), inline validation, honeypot + Cloudflare Turnstile. - Acceptance: form rejects bots in staging; successful submission shows thank-you state and writes nothing to the client console. 10. **Task 10: Accessibility and performance pass** - Files: across components. - Changes: semantic landmarks, alt text on every ``, `aria-live` for cart updates, focus management on mobile menu, lazy-load below-the-fold images (`loading="lazy"`, `decoding="async"`), preload hero image, self-host or subset fonts. - Acceptance: axe-core run via `npm run test:a11y` reports zero serious/critical issues; Lighthouse Performance ≥ 90, Accessibility ≥ 95 on the built site. 11. **Task 11: Analytics and consent** - File: `src/components/Analytics.astro`. - Changes: Plausible (cookieless, preferred) or GA4 with a cookie consent banner; respect `prefers-reduced-motion`. - Acceptance: no analytics scripts fire before consent; events tracked: `add_to_cart`, `view_item`, `form_submit`. 12. **Task 12: Deploy** - File: `netlify.toml` or `vercel.json`. - Changes: build command `npm run build`, publish `dist/`, security headers (CSP, X-Frame-Options, Referrer-Policy, Permissions-Policy), redirects for trailing slashes. - Acceptance: preview deploy URL returns 200; security headers present in response. --- ## Files to Modify - `package.json` — add deps (`@astrojs/tailwind`, `astro`, `@astrojs/sitemap`, `snipcart` if used). - `astro.config.mjs` — integrations, site URL, sitemap, image service. - `src/styles/global.css` — tokens, base resets, typography. - `src/layouts/BaseLayout.astro` — shell, SEO, header, footer. - `src/components/*` — header, footer, product card, filter bar, analytics, seo head. - `src/pages/index.astro`, `src/pages/shop.astro`, `src/pages/shop/[slug].astro`, `src/pages/about.astro`, `src/pages/contact.astro`. - `src/pages/api/contact.ts` — form handler. - `src/content/config.ts` and `src/content/products/*.md` — product schema and seeds. ## New Files - `public/og-image.png`, `public/favicon.svg` — share assets. - `public/images/products/*.svg` — placeholder product imagery. - `src/env.d.ts` — Astro types. - `README.md` — run/build/deploy instructions and content authoring guide. ## Dependencies - Task 1 blocks all others. - Tasks 2 and 3 should land before 5–9. - Task 4 blocks Tasks 6 and 7. - Task 10 depends on every page being authored. - Task 12 depends on Task 10. ## Risks - **Underspecification**: brand name, palette, copy, product data, and commerce model are not provided. Plan defaults to placeholders; the owner should confirm before design polish. - **Compliance**: fragrance allergens (EU IFRA / US FDA), prop-65 in California, and "natural"/"eco" claims need legal review. Include a disclaimer block on product pages until cleared. - **Imagery**: stock or original photography significantly affects perceived quality; SVG placeholders look unfinished in production. - **Commerce integration**: Snipcart/Stripe accounts and tax/shipping configuration are external dependencies; budget setup time. - **Email deliverability**: domain DNS (SPF/DKIM/DMARC) must be set for the contact form and newsletter to avoid spam foldering. - **Performance budgets**: large hero images and web fonts are common regression sources; specify a max hero image size (e.g., 200 KB WebP/AVIF) and subset fonts. - **Accessibility regressions**: Snipcart's modal and the mobile menu are frequent focus-trap pitfalls; allocate explicit testing time. - **i18n**: if the brand sells internationally, currency, language, and date formatting need a strategy (Astro i18n routes or a future migration to a localized CMS).