# qumo.io Website Rebuild — Migration Steps

_An ordered list of migration steps for rebuilding qumo.io from Webflow to Astro. Each step is designed to be run as an OpenSpec change with `/opsx:explore`, which will evaluate whether additional intermediate steps are needed before implementation._

_Reference site: `https://qumo-pmj.webflow.io/` (staging — this is the version we are rebuilding, NOT the live production site at qumo.io)_

_Run each step as: `/opsx:explore See step NNN — <title>`_

---

## How to use this document

1. Work through the steps **in order** — each one builds on the previous.
2. For every step, run `/opsx:explore` with the step description. Explore will decide if intermediate steps are needed before implementation.
3. **Before starting each step**: open `https://qumo-pmj.webflow.io/` (and the relevant subpage) in your browser. Study the layout, spacing, colors, typography, animations, and interactions you need to replicate. Take note of anything that isn't captured in the text description below.
4. **After completing each step**: run `npm run build` inside `website/`, then `npm run dev` and compare the result side-by-side with the staging Webflow site. Note discrepancies for the next iteration.
5. The staging site is always the visual source of truth. This document describes *what* to build; the staging site shows *how it should look*.

### Site map of the staging site

| Route (EN) | Route (NL) | Page |
|---|---|---|
| `/` | `/nl` | Homepage |
| `/about` | `/nl/about` | About — mission, founders |
| `/ai-launchpad` | `/nl/ai-launchpad` | AI Launchpad product page |
| `/contact` | `/nl/contact` | Contact form |
| `/privacy` | `/nl/privacy` | Privacy policy (new — no content on staging yet) |

Navigation links across all pages: **Services** (anchor to `/#services`), **AI Launchpad** (`/ai-launchpad`), **About** (`/about`), plus the **Connect** CTA button.

---

## Phase 1 — Foundation

These steps establish the project skeleton. Nothing will look like the real site yet — the goal is a working Astro project with the correct brand tokens, fonts, and base layout shell.

---

### Step 001 — Project scaffolding and Tailwind brand tokens

**Goal:** A working Astro project with Tailwind configured using the exact Qumo brand palette and Archia font. No pages with real content yet — just a smoke-test index page that displays all brand colors and font weights to confirm everything is wired correctly.

**What to build:**
- `astro.config.mjs` with Tailwind and sitemap integrations
- `tailwind.config.mjs` with custom theme:
  - Colors: `midnight` (#102022), `snow` (#F3F3F3), `brand-blue` (#5257E4), `brand-red` (#F71E3E)
  - Font family: `archia` with system fallbacks (geometric sans-serif)
  - Any brand-specific spacing, border-radius, or breakpoint overrides
- `src/styles/global.css` with Tailwind directives and `@font-face` declarations for all Archia weights (Thin, Light, Regular, Medium, SemiBold, Bold) using woff2 files from `src/assets/fonts/archia/`
- A temporary `src/pages/index.astro` that renders: a color swatch grid showing Midnight, Snow, Blue, Red, and the gradient; sample text in each Archia weight; a gradient bar to verify the CSS gradient renders correctly
- `tsconfig.json` with strict mode
- `package.json` with all required dependencies

**Verification:**
- `npm run build` succeeds
- `npm run dev` shows the brand palette and all font weights rendering correctly
- Compare the gradient against the staging site's gradient elements (hero accent, CTA sections)

**Note on fonts:** The Archia woff2 files need to be manually copied from SharePoint (Branding > Brand Fonts) into `src/assets/fonts/archia/` before or during this step. If the font files are not yet available, use the system fallback and leave a TODO — the font-face declarations should still be in place.

---

### Step 002 — Base layout shell (HTML head, meta tags, empty nav/footer slots)

**Goal:** A `BaseLayout.astro` component that provides the HTML document shell for every page: correct `<head>` with charset, viewport, favicon, Archia font preloads, and slots for page-specific meta tags (title, description, OG, hreflang, JSON-LD). The body has placeholder slots for navigation and footer but no content yet.

**What to build:**
- `src/layouts/BaseLayout.astro` with:
  - Props for `title`, `description`, `locale` (default `en`), `alternateLocale`, `canonicalUrl`, `ogImage`
  - `<head>`: charset, viewport, favicon (`/favicon.svg`), preconnect for fonts, Archia font preloading, canonical link, hreflang alternate links (en ↔ nl), OG tags, Twitter card tags
  - `<body>` with Midnight background, Snow text defaults, font-archia applied
  - Named slots or component placeholders for `<Nav />` and `<Footer />`
  - A `<slot />` for page content
  - A slot or prop for injecting page-specific JSON-LD structured data
- Update `src/pages/index.astro` to use the BaseLayout
- `src/content/en.json` and `src/content/nl.json` — initial structure with just the global meta fields (site name, default description, default OG image path)
- A `src/content/i18n.ts` helper function that loads the correct JSON based on locale

**Verification:**
- `npm run build` succeeds
- View page source in browser: check that `<head>` contains all required meta tags, hreflang links, OG tags
- Verify the body has the correct background color (Midnight) and default text color (Snow)

---

### Step 003 — Navigation bar (desktop + mobile)

**Goal:** A fully functional navigation bar matching the staging site's layout and behavior. The nav is consistent across all pages.

**Before starting:** Open `https://qumo-pmj.webflow.io/` and study the navigation carefully:
- Logo on the left (Qumo wordmark + Q icon, full-color logo on Midnight backgrounds)
- Three navigation links: **Services** (links to `/#services`), **AI Launchpad** (links to `/ai-launchpad`), **About** (links to `/about`)
- Language switcher (EN/NL dropdown) on the right
- "Connect" CTA button with arrow icon on the right
- Transparent/overlay background that becomes solid on scroll (observe the scroll behavior)
- Mobile hamburger menu behavior (resize your browser to see it)
- The nav links and CTA are the same across all pages (homepage, about, ai-launchpad, contact)

**What to build:**
- `src/components/Nav.astro` — responsive navigation matching the staging site
- `src/components/LanguageSwitcher.astro` — EN/NL toggle that swaps between locale routes
- Navigation links from `en.json` / `nl.json` (NL nav: "Diensten", "AI Launchpad", "Over Ons"; NL CTA: "Verbind")
- Mobile hamburger menu with slide-in behavior
- The "Connect" button styled with the arrow icon (replicate the custom arrow SVG from the staging site)
- Scroll behavior: transparent → solid background on scroll (minimal vanilla JS in a `<script>` tag)
- Add nav content strings to `en.json` and `nl.json`

**Verification:**
- `npm run dev` — compare nav side-by-side with `https://qumo-pmj.webflow.io/`
- Test responsive behavior: resize browser from desktop to mobile
- Test language switcher: links should point to `/nl/...` variants (pages don't need to exist yet — just verify the URLs are correct)
- Test scroll behavior: background should transition on scroll

---

### Step 004 — Footer

**Goal:** A footer matching the staging site's layout, with all links, contact info, and the booking CTA.

**Before starting:** Scroll to the bottom of `https://qumo-pmj.webflow.io/` and study the footer:
- Qumo logo
- Four columns: Company (About us, Our Mission, The Team), Services (Insights, Automation, Solutions), Approach (Discovery, Development, Integration), Contact (email, phone, LinkedIn)
- "Schedule a meeting" CTA button linking to the Outlook booking page
- Copyright line (© 2026), Privacy Policy link, Terms of Service link, KvK number (95514953)
- Terms and Conditions PDF link
- "Get a Demo" label above the schedule button
- Overall dark styling on Midnight background

**Note:** The footer on the staging site still references the old nav structure (Services: Insights/Automation/Solutions, Approach: Discovery/Development/Integration). Build it as-is — we can update the footer link labels in a later step if the team decides to align them with the new nav.

**What to build:**
- `src/components/Footer.astro` — full footer matching the staging layout
- All footer content strings in `en.json` / `nl.json` (NL footer: Bedrijf, Diensten, Aanpak, Contact columns; "Plan een gesprek" CTA)
- Links should use proper locale-aware paths
- External links (email `mailto:info@qumo.io?subject=Website%20Lead`, phone `tel:`, LinkedIn, booking URL `https://outlook.office365.com/book/QumoMeeting@qumo.io/`, Terms PDF) should open in new tabs where appropriate
- Integrate the footer into `BaseLayout.astro`

**Verification:**
- `npm run dev` — compare footer side-by-side with the staging site
- Verify all links point to correct destinations
- Test responsive layout (footer columns should stack on mobile)

---

## Phase 2 — Homepage (section by section)

Now we build the homepage incrementally, one section at a time. After each step, the homepage becomes progressively more complete. No animations yet — just structure, layout, and content.

---

### Step 005 — Homepage hero section

**Goal:** The hero section of the homepage, matching the staging site's layout.

**Before starting:** Open `https://qumo-pmj.webflow.io/` and focus on the hero area:
- Small label text above the main heading: "We build the AI & data solutions that make it happen."
- Large heading with a line break: "Faster answers, lower costs" / "Smarter decisions" (the line break placement matters for the visual rhythm)
- No explicit CTA button in the hero (unlike the old site) — the heading itself is the hook
- Background styling — note any gradient elements, patterns, or the Q-corner brand motif
- How it sits relative to the transparent nav overlay
- Spacing and padding on desktop vs mobile

**NL version:** "Wij bouwen de data- en AI-oplossingen die dat mogelijk maken." / "Sneller inzicht, lagere kosten" / "betere beslissingen"

**What to build:**
- `src/components/Hero.astro`
- Wire it into `src/pages/index.astro` using `BaseLayout`
- Add all hero content to `en.json` and `nl.json`
- Create the NL homepage at `src/pages/nl/index.astro` using the same component with NL strings

**Verification:**
- Compare hero side-by-side with the staging site at `https://qumo-pmj.webflow.io/`
- Check typography: heading should be Archia Bold, uppercase (per brand guidelines)
- Check the gradient or accent elements match
- Check NL version at `/nl` has the Dutch content
- Test mobile responsiveness — the heading line breaks may change on smaller screens

---

### Step 006 — Homepage services section (three service cards)

**Goal:** The services section with three cards: AI Launchpad, Data & Business Intelligence, Embedded Expertise.

**Before starting:** Scroll to the services section on `https://qumo-pmj.webflow.io/`:
- Section heading: "What we do"
- Subheading: "Three areas of expertise, one team. Combine what you need."
- Three cards, each with:
  - A tag label (Innovation / Analytics / Expertise)
  - A title (AI Launchpad / Data & Business Intelligence / Embedded Expertise)
  - Body text (longer descriptions, quite different from the old site)
  - A numbered circle illustration (1, 2, 3)
  - The first card has a "Learn More" link to `/ai-launchpad`; the other two link to `#how-we-work`
- Note the card layout — observe styling, whether they alternate, background treatments

**NL version:** "Wat we doen" / "Drie expertises, één team. Combineer wat nodig is." / card content fully translated

**What to build:**
- `src/components/ServiceCard.astro` — reusable card component
- Services section in the homepage with proper `id="services"` anchor
- All three cards with correct content from `en.json` / `nl.json`
- Numbered circle illustration SVGs (replicate from the staging site)
- "Learn More" / "Meer info" links

**Verification:**
- Compare the services section side-by-side with the staging site
- Check card layout, spacing, and typography
- Check that the `#services` anchor works from the nav link
- Mobile: verify cards stack properly

---

### Step 007 — Homepage "Our approach" text section and cloud provider logos

**Goal:** The approach description text block and the cloud provider logo strip.

**Before starting:** Study this section on `https://qumo-pmj.webflow.io/`:
- **"Our approach" section**: A text block (no heading tag visible, but the text starts with "We always start small.") followed by a paragraph about starting with one conversation, biggest-impact project, first result. Then a second paragraph about what comes next.
- **Cloud provider logos**: Below that, a section with "any cloud platform — including EU-based providers" label, followed by two rows of logos:
  - Row 1: Microsoft Azure, Amazon Web Services, Google Cloud
  - Row 2: EU flag + "European providers" label, then Hostinger, Hetzner, "and more" (three dots icon)
- The logos are SVGs with specific styling (likely monochrome/brand-appropriate)

**NL version:** "Onze werkwijze" text fully translated, "Elk cloudplatform — inclusief Europese providers" label

**What to build:**
- "Our approach" text section with an `id` anchor (the nav doesn't link here directly, but the service cards link to `#how-we-work`)
- Cloud provider logo strip with SVG logos
- All content from `en.json` / `nl.json`
- The SVG logos should be inlined or stored in `src/assets/icons/` — source from the staging site's CDN or recreate

**Verification:**
- Compare layout with the staging site
- Logo strip should display correctly across breakpoints
- `#how-we-work` anchor from service card links should land here

---

### Step 008 — Homepage mission section with founders CTA

**Goal:** The "About Qumo" mission paragraph with the "Our founders" CTA link.

**Before starting:** Study this section on `https://qumo-pmj.webflow.io/`:
- Label: "About Qumo"
- Heading: "Our mission is to empower organizations to unlock the full potential of their data"
- Body text: paragraph about subjective perspectives, extracting actionable insights, Qumo's support
- "Our founders" CTA button with arrow, linking to `/about#founders`
- Two small gradient accent images flanking the section
- Note the background treatment and spacing

**NL version:** "Over Qumo" label, fully translated heading and body, "Onze oprichters" CTA linking to `/about#founders`

**What to build:**
- Mission section component
- Content from `en.json` / `nl.json`
- Gradient accent elements (small decorative gradient blobs from the staging site)
- CTA link to `/about#founders`

**Verification:**
- Compare with the staging site
- CTA link should point to the About page's founders section

---

### Step 009 — Homepage "Delivered Solutions" stats and industry stats ticker

**Goal:** The two-layer stats section: project-specific "Delivered Solutions" stats on top, and the scrolling industry stats ticker below.

**Before starting:** Study this section carefully on `https://qumo-pmj.webflow.io/`:
- **"Delivered Solutions" row** (static, not scrolling):
  - Label: "Our Expertise" + heading: "Delivered Solutions"
  - Four stat cards: "Data Platform" (75% cloud cost reduction), "Fast Dashboards" (1w kickoff to working dashboard), "AI Agent" (85% reduction in research time), "Computer Vision" (0 manual review)
  - Each card has: a label, large stat, description, decorative icon
  - These are NOT the same generic industry stats from the old site — they're project-specific achievements
- **Industry stats ticker** (scrolling):
  - Horizontal infinite scroll with cards: Action 61%, Revenue 8%, Efficiency 10%, Insight 66%, Operating Margin 60%, Critical 90%, Real-time 30%, Growth 84x, ROI 1300%, etc.
  - Each card has: label, stat, description, icon, source info icon linking to the citation URL
  - The ticker duplicates its cards for seamless looping

**NL version:** Delivered Solutions stats are translated ("Data Platform" → "Data Platform", "Snelle Dashboards", "AI Agent", "Computer Vision" with NL descriptions). The industry ticker stats appear to stay in English on the NL page (verify visually).

**What to build:**
- `src/components/DeliveredSolutions.astro` — the static four-card stats section
- `src/components/StatsTicker.astro` — the infinite horizontal scroll
- CSS-only animation for the ticker (`@keyframes` + `animation: scroll linear infinite`) — no JavaScript
- All stat data in `en.json` / `nl.json` (label, stat, description for delivered solutions; label, stat, description, source URL for ticker stats)

**Verification:**
- Delivered Solutions cards match the staging site's content and layout
- The ticker should scroll smoothly and loop infinitely without visible jumps
- Compare speed and direction with the staging site
- Mobile: verify both sections are readable

---

### Step 010 — Homepage final CTA section

**Goal:** The bottom CTA section before the footer ("Quantify More with Qumo").

**Before starting:** Study the very bottom of `https://qumo-pmj.webflow.io/` (above the footer):
- "Turn complex data into insights" label text
- "Quantify More with Qumo" heading
- "Contact Us" CTA button with arrow, linking to `/contact`
- Background treatment — likely gradient or accent pattern

**NL version:** "Zet complexe gegevens om in inzichten" / "Meer innovatie met Qumo" (note: the NL staging site currently has a rendering glitch "Meer innovatieantifyre withmet Qumo" — use the correct translation) / "Neem contact op" CTA

**What to build:**
- CTA section component
- Content from `en.json` / `nl.json`
- CTA button linking to `/contact`

**Verification:**
- Compare with the staging site's bottom CTA
- The homepage should now be complete in structure (no animations yet)
- Navigate through the full homepage from hero to footer and compare the flow with the staging site

---

## Phase 3 — About page

---

### Step 011 — About page hero and mission section

**Goal:** The About page hero and mission statement.

**Before starting:** Open `https://qumo-pmj.webflow.io/about` and study:
- Hero: Q-corner pattern SVG in background, label "Building sustainable partnerships", main heading "Our mission is to empower organizations to unlock the full potential of their data", "Discover Qumo" scroll button
- Below the hero: subheading "Our data solutions integrate seamlessly into your organization for long-term sustainability." with decorative icon
- Mission section (`#mission`): "Our Mission" heading, two paragraphs of mission text, "Work with us" CTA button linking to `/contact`
- The nav links remain consistent (Services, AI Launchpad, About)

**What to build:**
- `src/pages/about.astro` and `src/pages/nl/about.astro`
- About hero with Q-corner pattern background (SVG from the staging site)
- Mission section with `id="mission"` anchor
- All content in `en.json` / `nl.json`

**Verification:**
- Compare with `https://qumo-pmj.webflow.io/about`
- Check the hero background pattern matches
- Verify `#mission` anchor works

---

### Step 012 — About page founders section

**Goal:** The "Our Founders" section with three team members (simplified from the old site's five).

**Before starting:** Study the founders section on `https://qumo-pmj.webflow.io/about`:
- Section heading: "Our Founders" (NOT "Meet The Team" — this changed)
- **Three founders** (not five):
  - **Luigi Maiorano** — "Co-founder · Head of AI & Engineering" — bio about CV to LLM agents, aerospace background, satellite systems and GIS
  - **Jelle Duives** — "Co-founder · Head of Strategy & Growth" — bio about client conversations, management consulting, enterprise software, analytics leadership
  - **Matthijs Torsij** — "Co-founder · Head of Data Analytics & Platforms" — bio about data foundation, pipelines, dashboards, aerospace background, "and shoe sales"
- Each card: photo, role label, name, "Email Me" link, "LinkedIn" link, bio paragraph
- The card layout is different from the old site — larger cards with bios visible, not just name + links
- Photo styling: note any specific cropping, filters, or backgrounds
- Note that Luigi's "Email Me" link appears to be missing the mailto: href on the staging site (just shows text) — fix this in the rebuild

**Note:** Jorn van Beek and Stijn van Selling are no longer in the founders section on the staging site. Only Luigi, Jelle, Matthijs appear.

**What to build:**
- `src/components/FounderCard.astro` (renamed from TeamMember to match the new framing)
- Founder data in `en.json` / `nl.json` (names, roles, bios, email addresses, LinkedIn URLs)
- Photos in `src/assets/images/founders/` (source from staging site CDN or SharePoint)
- Section with `id="founders"` anchor (the homepage CTA links to `/about#founders`)
- Email links with `?subject=Website%20Lead` query parameter
- Fix Luigi's missing mailto: link

**Verification:**
- Compare founder cards with the staging site
- Verify three founders appear with correct names, roles, and bios
- `#founders` anchor works from homepage "Our founders" link
- All email and LinkedIn links work correctly

---

### Step 013 — About page CTA

**Goal:** The "Ready to get started with Qumo?" CTA at the bottom of the About page.

**Before starting:** Check the bottom of `https://qumo-pmj.webflow.io/about`:
- "Let's Connect" label
- "Ready to get started with Qumo?" heading
- "Contact us" CTA button linking to `/contact`

**What to build:**
- Reuse or adapt the homepage CTA component
- Content from `en.json` / `nl.json`

**Verification:**
- The About page should now be structurally complete
- Compare the full page flow with the staging site

---

## Phase 4 — AI Launchpad page

This is a new page that doesn't exist on the current production site. It's a product page for Qumo's AI offering.

---

### Step 014 — AI Launchpad hero and "Sound familiar?" section

**Goal:** The AI Launchpad page hero and the pain-points section.

**Before starting:** Open `https://qumo-pmj.webflow.io/ai-launchpad` and study:
- Hero: "AI Launchpad" label, heading "Integrated AI solution within 2 to 4 weeks", subtext "From assessment to working application, embedded in your daily work. Not a report — something that actually works."
- **"Sound familiar?" section**: Five pain-point items, each with an exclamation mark icon and a description:
  - Contracts/invoices processed manually
  - Customer service answering same 20 questions
  - Operational data scattered
  - Quotes assembled manually
  - Technicians spending hours on inspection
- The layout of these items (list? cards? grid?)

**NL version:** Fully translated hero and pain points

**What to build:**
- `src/pages/ai-launchpad.astro` and `src/pages/nl/ai-launchpad.astro`
- AI Launchpad hero section
- "Sound familiar?" pain-points section
- All content in `en.json` / `nl.json`

**Verification:**
- Compare with `https://qumo-pmj.webflow.io/ai-launchpad`
- Hero and pain points should match layout and content

---

### Step 015 — AI Launchpad "What we build" and process steps

**Goal:** The solutions list and the four-step process.

**Before starting:** Study the middle sections of the AI Launchpad page:
- **"What we build" section**: Five solution items, each with a checkmark and description:
  - Document processing pipeline
  - AI agent trained on documentation
  - Dashboard with automated pipeline
  - Semantic search tool
  - Computer vision model
- **"How it works" section**: "From assessment to working application" heading, four numbered steps:
  1. Mapping opportunities — bullet points, deliverable label ("Value stream mapping, ROI overview"), environment label ("Qumo Environment")
  2. Prioritize & concept — bullets, deliverable, environment label ("Client Environment")
  3. Implementation — bullets, deliverable
  4. Training & adoption — bullets, deliverable
- Note the visual treatment: numbered steps with connecting flow, environment tags, deliverable callouts

**What to build:**
- "What we build" solutions list component
- Process steps component (four steps with numbered indicators, deliverables, environment tags)
- All content in `en.json` / `nl.json`

**Verification:**
- Compare solutions and process steps with the staging site
- Check the numbered flow layout
- Environment tags and deliverable labels should be visible

---

### Step 016 — AI Launchpad practical details and CTA

**Goal:** The "Fits your environment" section and the final CTA.

**Before starting:** Study the bottom of the AI Launchpad page:
- **"Practical details" / "Fits your environment"**: Two checkmark items about building on existing environments and alternatives for sensitive data
- A callout block with a rocket icon: "Built by engineers from aerospace and mathematics. Accustomed to systems where failure isn't an option — the same standard, now applied to your business."
- **CTA section**: "Let's Connect" label, "Interested how AI can help your organization?" heading, "Contact us" button

**What to build:**
- Practical details section with checkmark items
- Callout block with rocket icon (Phosphor Icons rocket-launch)
- CTA section (reuse/adapt from other pages)
- All content in `en.json` / `nl.json`

**Verification:**
- Compare with the staging site's bottom sections
- The AI Launchpad page should now be structurally complete
- Navigate through the full page and compare

---

## Phase 5 — Contact page and remaining pages

---

### Step 017 — Contact page (form frontend only)

**Goal:** The contact page with the form UI. The form doesn't actually submit yet — that comes in a later step with the Go backend.

**Before starting:** Open `https://qumo-pmj.webflow.io/contact` and study:
- Hero: "Connect with Qumo" label, heading "Ready to level up your data? Let's start a conversation."
- The form: inspect in DevTools — look for field names, types, hidden fields
- Form styling: input borders, focus states, the "Let's Connect" submit button with arrow
- Success message: "Thank you! Your submission has been received!"
- Error message: "Oops! Something went wrong while submitting the form."
- Background image on the right side
- Below the form: "Still not sure yet? Discover more" section with "About Qumo" link

**What to build:**
- `src/pages/contact.astro` and `src/pages/nl/contact.astro`
- `src/components/ContactForm.astro` — the form UI with:
  - Fields matching the staging site (inspect to find exact fields)
  - Honeypot hidden field (for spam protection)
  - JavaScript timestamp token (set on page load, validated server-side)
  - Client-side validation (required fields, email format)
  - Submit handler that POSTs to `/api/contact` (will fail until backend exists — that's fine)
  - Success and error state display
- "Still not sure" section below the form
- Content in `en.json` / `nl.json`

**Verification:**
- Compare form layout with the staging site
- Test form validation (try submitting empty, try invalid email)
- The form will fail on submit (no backend yet) — verify it shows the error state
- Check mobile layout

---

### Step 018 — Privacy policy page

**Goal:** A privacy policy page. The staging site has a placeholder link (`#`) — this is new content.

**What to build:**
- `src/pages/privacy.astro` and `src/pages/nl/privacy.astro`
- Privacy policy content in `en.json` / `nl.json` — cover: what data is collected via the contact form, how it's used, who processes it (SMTP relay provider), data retention, user rights under GDPR, contact info for data requests
- Simple text-heavy page using BaseLayout
- Link the footer's "Privacy Policy" link to this page

**Verification:**
- The page renders with clean typography
- Footer privacy link works
- Both EN and NL versions are available

---

### Step 019 — 404 page

**Goal:** A custom 404 page.

**What to build:**
- `src/pages/404.astro` — a clean 404 page with:
  - "Page not found" message
  - Link back to homepage
  - Consistent with the site's design (Midnight background, Archia font, maybe a subtle brand element)
- Content in `en.json` / `nl.json` (404 page defaults to EN since Astro can't detect locale from a missing URL)

**Verification:**
- Visit a non-existent URL in dev mode — the 404 page should render
- Check it looks on-brand

---

## Phase 6 — Animations and polish

Now we add the visual polish that makes the site feel alive. Go back to the staging site and study every animation and transition carefully.

---

### Step 020 — Scroll-triggered animations (fade-in, slide-up)

**Goal:** Add the scroll-triggered entrance animations that the Webflow site uses.

**Before starting:** Open `https://qumo-pmj.webflow.io/` in a fresh browser window and scroll slowly through the entire page. Note:
- Which elements animate in (headings, cards, sections, images)
- What type of animation (fade-in, slide-up, slide-in-from-left/right, scale)
- Timing: how fast, any stagger between elements in a group (e.g., service cards appearing one after another)
- Do the same for `/about`, `/ai-launchpad`, and `/contact`

**What to build:**
- CSS `@keyframes` for: fade-in, slide-up, slide-in-left, slide-in-right (and any others observed)
- A small `<script>` using `IntersectionObserver` that adds an `.in-view` class when elements enter the viewport
- Apply the appropriate animation classes to elements across all pages
- Stagger support for card groups (e.g., `animation-delay: 0.1s, 0.2s, 0.3s`)

**Verification:**
- Scroll through each page and compare animation behavior with the staging site
- Animations should feel smooth and match the timing of the Webflow originals
- Elements should only animate once (not re-trigger on scroll up)
- Test on mobile

---

### Step 021 — Navigation scroll effects and page transitions

**Goal:** Polish the nav scroll behavior and add Astro View Transitions.

**Before starting:** On the staging site, pay attention to:
- How the nav background transitions from transparent to solid as you scroll
- Any blur/backdrop effect on the solid state
- Page transition animations when clicking between pages (if any)

**What to build:**
- Refine the nav scroll effect: smooth transition (not a hard toggle), correct opacity/blur values
- Astro View Transitions (`transition:animate`) between pages for smooth navigation
- Ensure the mobile menu has smooth open/close animation

**Verification:**
- Nav scroll transition should be smooth and match the staging site
- Clicking between pages should have a smooth transition
- Mobile menu opens and closes smoothly

---

### Step 022 — Hover effects and micro-interactions

**Goal:** Add all the small interaction details: button hovers, card hovers, link underlines, CTA arrow animations.

**Before starting:** On the staging site, hover over:
- The "Connect" and CTA buttons (arrow animation? color change?)
- Service cards (elevation, border, scale?)
- Founder cards (overlay, zoom?)
- Footer links
- The language switcher
- Nav links
- The "Learn More" links on service cards

**What to build:**
- Button hover states (the arrow icons likely animate on hover)
- Card hover effects
- Link hover underline animations
- Focus states for keyboard navigation (accessibility)
- Transition timing matching the staging site

**Verification:**
- Hover over every interactive element and compare with the staging site
- Test keyboard focus states (Tab through the page)
- Check that transitions are smooth

---

## Phase 7 — SEO, structured data, and forms backend

---

### Step 023 — JSON-LD structured data for all pages

**Goal:** Add schema.org structured data to every page.

**What to build:**
- Homepage: `ProfessionalService` schema (org info, services, contact), `BreadcrumbList`
- About: `Organization` schema, `Person` schema for each founder, `BreadcrumbList`
- AI Launchpad: `Service` or `Product` schema, `BreadcrumbList`
- Contact: `ContactPage` schema, `BreadcrumbList`
- Privacy: `BreadcrumbList`
- Inject via the BaseLayout's JSON-LD slot/prop

**Verification:**
- View page source and check the `<script type="application/ld+json">` blocks
- Validate with schema.org validator
- Ensure no errors or warnings

---

### Step 024 — Sitemap, robots.txt, and SEO final pass

**Goal:** Finalize all SEO elements.

**What to build:**
- Configure `@astrojs/sitemap` in `astro.config.mjs` with all EN and NL URLs (including `/ai-launchpad` and `/nl/ai-launchpad`)
- `public/robots.txt` — allow all crawlers including AI bots
- Audit every page for: unique `<title>`, meta description, canonical URL, hreflang alternates, OG tags, Twitter card tags
- Verify all images have `alt` text
- Verify heading hierarchy (single `h1` per page, logical nesting)
- OG image in `public/og-image.png`

**Verification:**
- `npm run build` — check that sitemap is generated with all URLs
- Check `dist/robots.txt` is correct
- View source on each page and audit the `<head>` section

---

### Step 025 — Contact form Go backend

**Goal:** The Go form handler that receives contact form submissions and sends email.

**What to build:**
- `form-handler/main.go`:
  - HTTP server listening on `:8080`
  - `POST /api/contact` endpoint
  - JSON body parsing (fields matching the contact form)
  - Validation: required fields, email format
  - Honeypot check: if hidden field has a value, silently accept but don't send
  - Timestamp check: reject if < 3 seconds after page load
  - Rate limiting: in-memory counter, max 5 per IP per hour
  - Send email via SMTP relay (Resend or Brevo)
  - JSON response
  - CORS headers
- `form-handler/go.mod`, `go.sum`, `Dockerfile`
- Update `.env.example` with SMTP config variables

**Verification:**
- Build and test with curl
- Test honeypot rejection, rate limiting
- Integration test with the contact page

---

## Phase 8 — Docker and deployment

---

### Step 026 — Dockerfiles and docker-compose.yml

**Goal:** Production-ready containerization.

**What to build:**
- `website/Dockerfile`: multi-stage Node → nginx:stable-alpine-slim
- `website/nginx.conf`: static file serving, SPA fallback to 404.html, gzip
- `form-handler/Dockerfile`: multi-stage Go → Alpine
- Root `docker-compose.yml` with both services on `qumo_services_proxy_network`
- `.env.example` documented
- `README.md` with build and deploy instructions

**Verification:**
- `docker compose build` succeeds
- `docker compose up -d` starts both containers
- Both containers respond correctly
- `docker compose down` stops cleanly

---

### Step 027 — Caddyfile block and deployment documentation

**Goal:** The Caddy configuration for serving qumo.io in production.

**What to build:**
- Caddyfile block: security headers, caching rules, `/api/contact` route, www→apex redirect, no `import authentik` (public site)
- Complete deployment guide in `README.md`
- Document the DNS cutover procedure

**Verification:**
- Caddyfile block matches the rebuild plan
- README is self-contained

---

## Phase 9 — Final QA

---

### Step 028 — Full visual QA pass

**Goal:** Thorough side-by-side comparison of every page against the staging site.

**Before starting:** Open dev server and `https://qumo-pmj.webflow.io/` side-by-side. Go through every page at every breakpoint.

**What to check:**
- Typography: sizes, weights, line heights, letter spacing
- Spacing: padding, margins, gaps
- Colors: gradients, Midnight shades
- Images: are placeholders replaced?
- Responsive: 375px, 768px, 1024px, 1440px
- Animations: timing and easing
- Forms: field layout and styling
- All links work (footer, nav, CTAs, anchors)
- Language switcher works on every page
- Accessibility: Tab navigation, focus states, heading structure, alt text

**Verification:**
- Every page matches the staging site (or is an intentional improvement)
- `npm run build` succeeds
- Lighthouse score ≥ 90 on Performance, Accessibility, Best Practices, SEO

---

## Step summary table

| #   | Step name                                      | Phase         | Depends on |
|-----|------------------------------------------------|---------------|------------|
| 001 | Project scaffolding and Tailwind tokens        | Foundation    | —          |
| 002 | Base layout shell                              | Foundation    | 001        |
| 003 | Navigation bar                                 | Foundation    | 002        |
| 004 | Footer                                         | Foundation    | 002        |
| 005 | Homepage hero section                          | Homepage      | 003, 004   |
| 006 | Homepage services section                      | Homepage      | 005        |
| 007 | Homepage approach text + cloud logos            | Homepage      | 006        |
| 008 | Homepage mission section + founders CTA        | Homepage      | 007        |
| 009 | Homepage delivered solutions + stats ticker    | Homepage      | 008        |
| 010 | Homepage final CTA                             | Homepage      | 009        |
| 011 | About page hero + mission                      | About         | 004        |
| 012 | About page founders section                    | About         | 011        |
| 013 | About page CTA                                 | About         | 012        |
| 014 | AI Launchpad hero + pain points                | AI Launchpad  | 004        |
| 015 | AI Launchpad solutions + process steps          | AI Launchpad  | 014        |
| 016 | AI Launchpad practical details + CTA            | AI Launchpad  | 015        |
| 017 | Contact page (form frontend)                   | Contact       | 004        |
| 018 | Privacy policy page                            | Other pages   | 002        |
| 019 | 404 page                                       | Other pages   | 002        |
| 020 | Scroll-triggered animations                    | Animations    | 010, 013, 016 |
| 021 | Nav scroll effects + page transitions          | Animations    | 020        |
| 022 | Hover effects + micro-interactions             | Animations    | 021        |
| 023 | JSON-LD structured data                        | SEO           | 016, 017   |
| 024 | Sitemap, robots.txt, SEO final pass            | SEO           | 023        |
| 025 | Contact form Go backend                        | Backend       | 017        |
| 026 | Dockerfiles and docker-compose.yml             | Deployment    | 024, 025   |
| 027 | Caddyfile block + deploy docs                  | Deployment    | 026        |
| 028 | Full visual QA pass                            | QA            | 027        |
