# Stream C: design (rewritten 2026-09-05 Sat, against build plan v3 §7/§9 and the dated tasks on /plan)
> **Status 10 Sep:** C1 to C4 landed (handoff 5 Sep); C5 (banners and sponsor sizes) is blocked until rian is in the session. The body below is the brief as asked on 5 Sep.
**Runs:** Mon 7 → Wed 10 (C2, C5, C3), then Mon 14 (C4). Pass one (logo, #003F6C palette, stand-in
serif, v0.30.0) is done; this is pass two. **C5 needs rian in the session** for the sponsor sizes.

## Goal
The site reads as Duty Free Professor, not a generic app, without a redesign: a mega menu that
exposes the structure the SEO plan depends on, banners designed into the pages so sponsor sizes
can be told to Adam, and the featured savings and exclusives given the prominence the quote
promised. Aligned, not rebuilt; a full reskin is a later phase.

## Tasks, in order (ids are `/plan` tasks; record each with `main/scripts/plan-set.py`)
1. **C2 Mega menu (Wed 9).** One header panel: categories (the three families and their
   categories from `taxonomy`), brands (the brands table once A8/A9 land; until then the top
   brands by product count from `/api/stats`-backed data, never a typed list), airports (the
   visible locations). Every link targets a route that exists in `App.tsx` today or that Stream B
   ships in B4/B7 (airport pages); no dead links. Keyboard and touch usable, closes on Escape,
   no layout shift (CLS stays near zero). **Server-side mirror rule:** `header_html()` in
   `app/services/seo.py` copies the header for the server-rendered product page; when the
   header's structure changes, file an issue for Stream B (`items.py add --kind issue --owner B
   --blocks C2`) in the same commit so the mirror moves in the same deploy.
2. **C5 Brand pass two, with rian (Wed 9).** Banners designed into the templates: home, airport
   page, product page, brand page, article. Decide the sponsor positions and their IAB sizes with
   rian (Leaderboard 728×90, Medium Rectangle 300×250, Mobile 320×50 are the likely set); reserve
   the space so a late creative never shifts the layout. Output: the list of positions and sizes
   goes to Adam via the `/todo` sponsor item (flip it from waiting to open with the sizes in its
   detail) and to Stream D for D4. Rian decides sparse / average / heavy presence here.
3. **C3 Featured savings and exclusives (Thu 10).** More prominent positions on the home page and
   on product pages, using the featured service as it stands; no new selection logic (that is
   Stream F's picker). Every number shown comes from the API, never typed.
4. **C4 Instagram and YouTube links (Mon 14).** Header and footer, from the URLs Adam and Mark
   give on `/todo`; hidden until the URLs exist. Plus any CSS the Q and R surfaces request.

## Owns
`web/src/styles/*`, `web/public/` assets, `SiteHeader`, `SiteFooter`, `AnnouncementBar`,
`HomePage.tsx`, all `*.css`, the sponsor-slot placeholder component's styling.

## Must not touch
Anything under `main/app/`; Stream B's page components and `seo.py`; the plan and todo pages.

## Rules
- Fonts stay self-hosted (`web/public/fonts`, `@font-face` in `styles/tokens.css`); never a
  third-party font or script request. Re-check PageSpeed after the menu lands.
- Contrast pairs meet WCAG AA; `--gold-ink` for text, `--gold-strong` for buttons.
- Client-facing text: no em dashes. Adam's words stand: "new colors and scheme".
- Everything else per `OVERNIGHT-RULES.md`: never deploy, own files only, commit prefixed `C:`,
  `main/check.sh` green, handoff ≤25 lines, `/plan` updated, decisions on the running list.
