···11-.PHONY: dev run build test clean
11+.PHONY: dev run build test clean css css-watch
2233-dev:
33+dev: css
44 @if [ -f .env ]; then set -a; . ./.env; set +a; fi && go run .
5566-build:
66+build: css
77 go build -o glean .
8899+css:
1010+ npx tailwindcss -i ./static/input.css -o ./static/output.css --minify
1111+1212+css-watch:
1313+ npx tailwindcss -i ./static/input.css -o ./static/output.css --watch
1414+915test:
1016 go test ./...
11171218clean:
1313- rm -f glean glean.db
1919+ rm -f glean glean.db static/output.css
+534-228
docs/design.md
···11-# Design System Inspired by Spotify
11+# Design System Inspired by Starbucks
2233## 1. Visual Theme & Atmosphere
4455-Spotify's web interface is a dark, immersive music player that wraps listeners in a near-black cocoon (`#121212`, `#181818`, `#1f1f1f`) where album art and content become the primary source of color. The design philosophy is "content-first darkness" — the UI recedes into shadow so that music, podcasts, and playlists can glow. Every surface is a shade of charcoal, creating a theater-like environment where the only true color comes from the brand Accent Purple (`#a855f7`) and the album artwork itself.
55+Starbucks' design system is a **warm, confident retail flagship** wearing the green of their storefront apron across every surface. The canvas alternates between a neutral-warm cream (`#f2f0eb`) and a ceramic off-white (`#edebe9`) — colors that reference actual store materials: the paper napkins, the café walls, the wood finishes — while the signature **Starbucks Green** (`#006241`) anchors the brand moment on hero bands, CTAs, and the Rewards experience. The greens come in four calibrated shades (Starbucks, Accent, House, Uplift) each mapped to a specific surface role, and gold (`#cba258`) appears only around Rewards-status ceremony — not as a general accent.
6677-The typography uses SpotifyMixUI and SpotifyMixUITitle — proprietary fonts from the CircularSp family (Circular by Lineto, customized for Spotify) with an extensive fallback stack that includes Arabic, Hebrew, Cyrillic, Greek, Devanagari, and CJK fonts, reflecting Spotify's global reach. The type system is compact and functional: 700 (bold) for emphasis and navigation, 600 (semibold) for secondary emphasis, and 400 (regular) for body. Buttons use uppercase with positive letter-spacing (1.4px–2px) for a systematic, label-like quality.
77+Typography carries most of the brand voice. The proprietary **SoDoSans** typeface (custom to Starbucks) sits across nearly every surface with a tight `-0.16px` letter-spacing — it reads confident and friendly rather than fashion-magazine severe. What's unusual: the Rewards page switches to a warm serif (`"Lander Tall", "Iowan Old Style", Georgia`) for specific headline moments, subtly echoing the nostalgic feel of a coffeehouse chalkboard. And the Careers pages use a handwritten script (`"Kalam", "Comic Sans MS", cursive`) for personal cup-name touches. Three typefaces, three contexts — the system is disciplined about when each appears.
8899-What distinguishes Spotify is its pill-and-circle geometry. Primary buttons use 500px–9999px radius (full pill), circular play buttons use 50% radius, and search inputs are 500px pills. Combined with heavy shadows (`rgba(0,0,0,0.5) 0px 8px 24px`) on elevated elements and a unique inset border-shadow combo (`rgb(18,18,18) 0px 1px 0px, rgb(124,124,124) 0px 0px 0px 1px inset`), the result is an interface that feels like a premium audio device — tactile, rounded, and built for touch.
99+The surfaces breathe through rounded geometry. Every button is a 50px full-pill. Cards take a 12px rounded-rectangle. The "Frap" floating CTA — a 56px circular order button in Green Accent (`#00754A`) — is the product's signature depth move: it floats bottom-right with a layered shadow stack (`0 0 6px rgba(0,0,0,0.24)` base + `0 8px 12px rgba(0,0,0,0.14)` ambient) and compresses via `scale(0.95)` on press. Elevations are otherwise restrained — card shadows stay at a whispered `0.14/0.24` alpha, global nav gets a quiet three-layer shadow stack. The whole system feels like clean café signage: legible, warm, and never shouting.
10101111**Key Characteristics:**
12121313-- Near-black immersive dark theme (`#121212`–`#1f1f1f`) — UI disappears behind content
1414-- Accent Purple (`#a855f7`) as singular brand accent — never decorative, always functional
1515-- SpotifyMixUI/CircularSp font family with global script support
1616-- Pill buttons (500px–9999px) and circular controls (50%) — rounded, touch-optimized
1717-- Uppercase button labels with wide letter-spacing (1.4px–2px)
1818-- Heavy shadows on elevated elements (`rgba(0,0,0,0.5) 0px 8px 24px`)
1919-- Semantic colors: negative red (`#f3727f`), warning orange (`#ffa42b`), announcement blue (`#539df5`)
2020-- Album art as the primary color source — the UI is achromatic by design
2121-- Light/dark theme toggle — persisted in localStorage, dark is default
1313+- Four-tier green brand system (Starbucks / Accent / House / Uplift) each mapped to a distinct surface role — not a single "brand green"
1414+- Gold reserved for Rewards-status moments only; never a general-purpose accent
1515+- Warm-neutral canvas (`#f2f0eb` / `#edebe9`) instead of cold white — references café materials
1616+- Custom proprietary typeface (SoDoSans) with tight `-0.16px` letter-spacing as the universal voice
1717+- Context-specific type switches: serif (Lander Tall) for Rewards, script (Kalam) for Careers cup-names
1818+- Full-pill buttons (`50px` radius) universal, `scale(0.95)` active press the signature micro-interaction
1919+- Floating "Frap" circular CTA (`56px`, Green Accent fill, layered shadow stack) — the product's signature elevation element
2020+- Gift-card surfaces designed as **photographed physical product** — every card is a distinct illustrated photograph rather than a generated graphic
2121+- 12px card radius + whisper-soft shadows keep content cards flat-plus-hint-of-lift
2222+- Rem-based spacing scale anchored at 1.6rem (~16px) = `--space-3`, stepping to 6.4rem (~64px)
2323+2424+**Color-block page rhythm:** Cream hero → White content sections → Dark-green (`#1E3932`) feature band with white text → Cream utility zone → Dark-green (`#1E3932`) footer with gold / white text — an espresso-dark bookend around the bright body.
22252326## 2. Color Palette & Roles
24272525-All theme-dependent colors use CSS custom properties defined on `:root` (dark, default) and `[data-theme="light"]` (light). Accent and semantic colors are constant across themes.
2828+**Source pages analyzed:** homepage, rewards, gift cards, product detail (Pink Energy Drink), product nutrition (Cold Brew).
26292727-### Tailwind Token Mapping
3030+### Primary
28312929-The `spot.*` namespace provides semantic tokens. Theme-dependent tokens resolve to CSS variables.
3232+- **Starbucks Green** (`#006241`): The historic brand green. Used on h1 headings, primary section headers on the Rewards page, and as the main brand signal wherever a single dominant color is needed.
3333+- **Green Accent** (`#00754A`): A slightly brighter, more luminous green. The primary filled-CTA color ("Explore our afternoon menu", "See the spring menu") and the fill of the floating Frap circular button.
3434+- **House Green** (`#1E3932`): The deep near-black brand green. Footer surface, feature-band backgrounds, reward-status dark surfaces, and the headline "Free coffee is just the beginning" hero band on Rewards.
3535+- **Green Uplift** (`#2b5148`): A secondary mid-dark green used sparingly on decorative accents and dark-gradient moments.
3636+- **Green Light** (`#d4e9e2`): A pale mint wash used for form-valid-state tints and light green utility surfaces.
30373131-| Token | CSS Variable | Dark (default) | Light | Use |
3232-| ---------------------- | --------------------- | -------------------------------- | -------------------------------- | -------------------------------- |
3333-| `spot.purple` | — | `#a855f7` | `#a855f7` | Primary accent |
3434-| `spot.purple-border` | — | `#9333ea` | `#9333ea` | Accent border variant |
3535-| `spot.bg` | `--spot-bg` | `#121212` | `#f5f5f5` | Page background |
3636-| `spot.surface` | `--spot-surface` | `#181818` | `#ffffff` | Cards, containers, sidebar |
3737-| `spot.hover` | `--spot-hover` | `#1f1f1f` | `#f3f4f6` | Interactive surface, input bg |
3838-| `spot.hover-50` | `--spot-hover-50` | `rgba(31,31,31,0.5)` | `rgba(243,244,246,0.5)` | Card hover with transparency |
3939-| `spot.text` | `--spot-text` | `#ffffff` | `#111827` | Primary text, headings |
4040-| `spot.secondary` | `--spot-secondary` | `#b3b3b3` | `#6b7280` | Secondary text, muted labels |
4141-| `spot.body` | `--spot-body` | `#cbcbcb` | `#374151` | Article body text |
4242-| `spot.muted` | `--spot-muted` | `#4d4d4d` | `#9ca3af` | Very muted text, rank numbers |
4343-| `spot.divider` | `--spot-divider` | `rgba(77,77,77,0.2)` | `#e5e7eb` | Subtle border dividers |
4444-| `spot.divider-30` | `--spot-divider-30` | `rgba(77,77,77,0.3)` | `#d1d5db` | Slightly stronger dividers, hr |
4545-| `spot.outline` | `--spot-outline` | `#7c7c7c` | `#d1d5db` | Visible borders on buttons/inputs|
4646-| `spot.placeholder` | `--spot-placeholder` | `#4d4d4d` | `#9ca3af` | Input placeholder text |
4747-| `spot.active-pill-bg` | `--spot-active-bg` | `#ffffff` | `#111827` | Active filter pill background |
4848-| `spot.active-pill-text`| `--spot-active-text` | `#121212` | `#ffffff` | Active filter pill text |
4949-| `spot.shadow` | `--spot-shadow` | `rgba(0,0,0,0.3) 0px 8px 8px` | `rgba(0,0,0,0.08) 0px 2px 8px` | Card elevation shadow |
5050-| `spot.shadow-heavy` | `--spot-shadow-heavy` | `rgba(0,0,0,0.5) 0px 8px 24px` | `rgba(0,0,0,0.1) 0px 4px 16px` | Dialog/elevated panel shadow |
5151-| `spot.red` | — | `#f3727f` | `#f3727f` | Error states |
5252-| `spot.orange` | — | `#ffa42b` | `#ffa42b` | Warning states |
5353-| `spot.blue` | — | `#539df5` | `#539df5` | Info states |
3838+### Secondary & Accent
54395555-### Shadows
4040+- **Gold** (`#cba258`): Reserved almost exclusively for Rewards-status ceremony — Gold-tier callouts, partnership badges (SkyMiles, Bonvoy), and premium-feeling accents. Never a general-purpose brand color.
4141+- **Gold Light** (`#dfc49d`): Softer gold for background washes on gold-tier sections.
4242+- **Gold Lightest** (`#faf6ee`): Cream-gold page-surface wash used under partnership sections on the Rewards page — ties the gold accent back into the warm neutral system.
56435757-- **Card** (`var(--spot-shadow)`): Cards, dropdowns
5858-- **Heavy** (`var(--spot-shadow-heavy)`): Dialogs, menus, elevated panels
5959-- **Inset Border** (`rgb(18,18,18) 0px 1px 0px, rgb(124,124,124) 0px 0px 0px 1px inset`): Input border-shadow combo (dark only)
4444+### Surface & Background
60456161-## 3. Theme Toggle
4646+- **White** (`#ffffff`): Primary card and modal surface. Also card fill on gift-card tiles.
4747+- **Neutral Cool** (`#f9f9f9`): Subtle cool-gray surface used on dropdown menus ("Account" dropdown), form-card wraps, and quiet utility containers.
4848+- **Neutral Warm** (`#f2f0eb`): The warm cream **primary page canvas** for Rewards utility zones and hero bands.
4949+- **Ceramic** (`#edebe9`): A slightly warmer/darker cream for zone separators, soft page-section washes, and Rewards partnership band.
5050+- **Black** (`#000000`): Deep ink reserved for the dark top-of-page CTA strip ("Join now") and high-contrast top-nav sign-in buttons.
62516363-The app supports dark (default) and light themes. Theme preference is stored in `localStorage` under the key `theme`.
5252+### Neutrals & Text
5353+5454+- **Text Black** (`rgba(0, 0, 0, 0.87)`): Primary heading and body text color on light surfaces. Not pure black — an 87%-opacity black that reads warmer.
5555+- **Text Black Soft** (`rgba(0, 0, 0, 0.58)`): Secondary/metadata text on light surfaces.
5656+- **Text White** (`rgba(255, 255, 255, 1)`): Primary heading/body text on dark green surfaces.
5757+- **Text White Soft** (`rgba(255, 255, 255, 0.70)`): Secondary text on dark-green surfaces — footer link descriptions, caption text.
5858+- **Rewards Green** (`#33433d`): A dedicated muted slate-green used only on Rewards-page text blocks — a slightly "dustier" reading color than Text Black that signals "reward surface" without using full Starbucks Green.
5959+6060+### Semantic & Accent
6161+6262+- **Red** (`#c82014`): Error and destructive state (form invalid, destructive actions).
6363+- **Yellow** (`#fbbc05`): Warning state, legacy brand touch.
6464+- **Green Light** (`#d4e9e2` at 33% opacity = `hsl(160 32% 87% / 33%)`): Form valid-field tint background.
6565+- **Red Tint** (`hsl(4 82% 43% / 5%)`): Invalid-field tint on forms.
6666+6767+### Black / White Alpha Ladders
6868+6969+Two parallel translucent scales for overlay and secondary-text use:
64706565-### Implementation
7171+- `rgba(0,0,0,0.06)` through `rgba(0,0,0,0.90)` in 10% steps — for dark overlays on light surfaces
7272+- `rgba(255,255,255,0.10)` through `rgba(255,255,255,0.90)` in 10% steps — for light overlays on dark surfaces
66736767-- CSS custom properties are defined on `:root` for dark and `[data-theme="light"]` for light
6868-- A `<script>` block runs before render to set `data-theme` on `<html>`, preventing flash of wrong theme
6969-- Toggle buttons appear in the sidebar footer (desktop) and mobile top bar
7070-- Icon: moon (when in dark mode) / sun (when in light mode)
7171-- Default: dark
7474+### Gradient System
72757373-### CSS Variables
7676+No structural gradient tokens observed. Surface hierarchy is solid-color-block throughout — the system relies on its five-tier cream/green surface palette rather than gradients.
74777575-```css
7676-:root {
7777- --spot-bg: #121212;
7878- --spot-surface: #181818;
7979- --spot-hover: #1f1f1f;
8080- --spot-hover-50: rgba(31,31,31,0.5);
8181- --spot-text: #ffffff;
8282- --spot-secondary: #b3b3b3;
8383- --spot-body: #cbcbcb;
8484- --spot-muted: #4d4d4d;
8585- --spot-divider: rgba(77,77,77,0.2);
8686- --spot-divider-30: rgba(77,77,77,0.3);
8787- --spot-outline: #7c7c7c;
8888- --spot-placeholder: #4d4d4d;
8989- --spot-active-bg: #ffffff;
9090- --spot-active-text: #121212;
9191- --spot-shadow: rgba(0,0,0,0.3) 0px 8px 8px;
9292- --spot-shadow-heavy: rgba(0,0,0,0.5) 0px 8px 24px;
9393-}
9494-[data-theme="light"] {
9595- --spot-bg: #f5f5f5;
9696- --spot-surface: #ffffff;
9797- --spot-hover: #f3f4f6;
9898- --spot-hover-50: rgba(243,244,246,0.5);
9999- --spot-text: #111827;
100100- --spot-secondary: #6b7280;
101101- --spot-body: #374151;
102102- --spot-muted: #9ca3af;
103103- --spot-divider: #e5e7eb;
104104- --spot-divider-30: #d1d5db;
105105- --spot-outline: #d1d5db;
106106- --spot-placeholder: #9ca3af;
107107- --spot-active-bg: #111827;
108108- --spot-active-text: #ffffff;
109109- --spot-shadow: rgba(0,0,0,0.08) 0px 2px 8px;
110110- --spot-shadow-heavy: rgba(0,0,0,0.1) 0px 4px 16px;
111111-}
112112-```
7878+## 3. Typography Rules
11379114114-## 4. Typography Rules
8080+### Font Family
11581116116-### Font Families
8282+- **Primary:** `SoDoSans, "Helvetica Neue", Helvetica, Arial, sans-serif` — Starbucks' proprietary corporate typeface, used across nearly every surface
8383+- **Loading Fallback:** `"Helvetica Neue", Helvetica, Arial, sans-serif` — what users see before SoDoSans loads
8484+- **Rewards Serif:** `"Lander Tall", "Iowan Old Style", Georgia, serif` — used on specific Rewards-page headline moments for a warm editorial feel
8585+- **Careers Script:** `"Kalam", "Comic Sans MS", cursive` — used exclusively for Careers-page "cup name" decorative touches, referencing the hand-written names on Starbucks cups
11786118118-- **Title**: `SpotifyMixUITitle`, fallbacks: `CircularSp-Arab, CircularSp-Hebr, CircularSp-Cyrl, CircularSp-Grek, CircularSp-Deva, Helvetica Neue, helvetica, arial, Hiragino Sans, Hiragino Kaku Gothic ProN, Meiryo, MS Gothic`
119119-- **UI / Body**: `SpotifyMixUI`, same fallback stack
8787+No OpenType stylistic sets explicitly activated at `:root`.
1208812189### Hierarchy
12290123123-| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes |
124124-| ---------------- | ----------------- | ---------------- | ------- | ------------ | -------------- | ---------------------------- |
125125-| Section Title | SpotifyMixUITitle | 24px (1.50rem) | 700 | normal | normal | Bold title weight |
126126-| Feature Heading | SpotifyMixUI | 18px (1.13rem) | 600 | 1.30 (tight) | normal | Semibold section heads |
127127-| Body Bold | SpotifyMixUI | 16px (1.00rem) | 700 | normal | normal | Emphasized text |
128128-| Body | SpotifyMixUI | 16px (1.00rem) | 400 | normal | normal | Standard body |
129129-| Button Uppercase | SpotifyMixUI | 14px (0.88rem) | 600–700 | 1.00 (tight) | 1.4px–2px | `text-transform: uppercase` |
130130-| Button | SpotifyMixUI | 14px (0.88rem) | 700 | normal | 0.14px | Standard button |
131131-| Nav Link Bold | SpotifyMixUI | 14px (0.88rem) | 700 | normal | normal | Navigation |
132132-| Nav Link | SpotifyMixUI | 14px (0.88rem) | 400 | normal | normal | Inactive nav |
133133-| Caption Bold | SpotifyMixUI | 14px (0.88rem) | 700 | 1.50–1.54 | normal | Bold metadata |
134134-| Caption | SpotifyMixUI | 14px (0.88rem) | 400 | normal | normal | Metadata |
135135-| Small Bold | SpotifyMixUI | 12px (0.75rem) | 700 | 1.50 | normal | Tags, counts |
136136-| Small | SpotifyMixUI | 12px (0.75rem) | 400 | normal | normal | Fine print |
137137-| Badge | SpotifyMixUI | 10.5px (0.66rem) | 600 | 1.33 | normal | `text-transform: capitalize` |
138138-| Micro | SpotifyMixUI | 10px (0.63rem) | 400 | normal | normal | Smallest text |
9191+| Role | Size | Weight | Line Height | Letter Spacing | Notes |
9292+| ------------------- | -------------- | ------- | --------------- | -------------- | -------------------------------------------- |
9393+| Display (text-10) | 5.0rem / 80px | 400–600 | 1.2 | -0.16px | Largest Rewards/hero display |
9494+| Jumbo (text-9) | 3.6rem / 58px | 400–600 | 1.2 | -0.16px | Secondary hero headings |
9595+| Hero Large (text-8) | 2.8rem / 45px | 400–600 | 1.2–1.5 | -0.16px | Landing section headlines |
9696+| H1 | 24px | 600 | 36px | -0.16px | Starbucks-Green primary heading |
9797+| H2 | 24px | 400 | 36px | -0.16px | Regular-weight section title in Text Black |
9898+| Body Large | 19px | 400–600 | 33.25px (~1.75) | -0.16px | Hero intro copy, feature-band body |
9999+| Body (text-3) | 1.6rem / 16px | 400 | 1.5 (24px) | -0.01em | Default body copy |
100100+| Small (text-2) | 1.4rem / ~14px | 400–600 | 1.5 | -0.01em | Button label, metadata, form labels |
101101+| Micro (text-1) | 1.3rem / ~13px | 400 | 1.5 | -0.01em | Active float-label state, caption micro-copy |
102102+| Button Label | 14–16px | 400–600 | 1.2 | -0.01em | All pill-button labels |
103103+104104+**Letter-spacing tokens:**
105105+106106+- `letterSpacingNormal`: `-0.01em` (default — tight, characteristic)
107107+- `letterSpacingLoose`: `0.1em` (emphasized caps)
108108+- `letterSpacingLooser`: `0.15em` (uppercase-style labels, extreme emphasis)
109109+110110+**Line-height tokens:**
111111+112112+- `lineHeightNormal`: `1.5` (body)
113113+- `lineHeightCompact`: `1.2` (display/buttons)
139114140115### Principles
141116142142-- **Bold/regular binary**: Most text is either 700 (bold) or 400 (regular), with 600 used sparingly. This creates a clear visual hierarchy through weight contrast rather than size variation.
143143-- **Uppercase buttons as system**: Button labels use uppercase + wide letter-spacing (1.4px–2px), creating a systematic "label" voice distinct from content text.
144144-- **Compact sizing**: The range is 10px–24px — narrower than most systems. Spotify's type is compact and functional, designed for scanning playlists, not reading articles.
145145-- **Global script support**: The extensive fallback stack (Arabic, Hebrew, Cyrillic, Greek, Devanagari, CJK) reflects Spotify's 180+ market reach.
117117+- **Tight negative tracking (`-0.01em`)** is applied almost universally — the entire product reads slightly compressed, which gives SoDoSans its confident presence without feeling squeezed.
118118+- **Weight shifts carry hierarchy, not size shifts.** H1 and H2 share the same 24px/36px size; only weight (600 vs 400) and color (Starbucks-Green vs Text Black) separate them.
119119+- **Size tokens use rem, anchored to `1rem = 10px`** on this site (via a `font-size: 62.5%` root trick). So `1.6rem` = 16px, `2.4rem` = 24px, etc. The scale is semantic (textSize-1 through textSize-10), not arbitrary pixel values.
120120+- **Context-specific typeface swaps** — serif on Rewards, script on Careers — are deliberate and localized. Never mix them with the primary sans within the same surface.
121121+- **Body text never goes pure black** — it sits at `rgba(0,0,0,0.87)` to match the warm-neutral canvas temperature.
146122147147-## 5. Component Stylings
123123+### Note on Font Substitutes
124124+125125+SoDoSans is proprietary to Starbucks (licensed from House Industries, not publicly available). Reasonable open-source substitutes:
126126+127127+- **Inter** (Google Fonts) — similar humanist geometric proportions, wide weight range
128128+- **Manrope** — slightly rounder, similar confident feel
129129+- **Nunito Sans** — warmer, good for a "café" brand substitute
130130+131131+If substituting, verify the tight `-0.01em` / `-0.16px` tracking still reads well; some open-source fonts need `-0.005em` instead.
132132+133133+Lander Tall (the Rewards serif) is custom — open-source substitutes: **Iowan Old Style** (already in fallback), **Lora**, or **Source Serif Pro**. Kalam (Careers script) is available on Google Fonts directly.
134134+135135+## 4. Component Stylings
148136149137### Buttons
150138151151-**Accent Pill**
139139+**1. Primary Filled — "Explore our afternoon menu / Sign up for free"**
152140153153-- Background: `#a855f7`
154154-- Text: `var(--spot-bg)` (dark in dark mode, light in light mode)
155155-- Padding: 8px 16px
156156-- Radius: 9999px (full pill)
157157-- Use: Primary CTAs, add buttons
141141+- Background: `#00754A` (Green Accent)
142142+- Text: `#ffffff`
143143+- Border: `1px solid #00754A`
144144+- Radius: `50px` (full pill)
145145+- Padding: `7px 16px`
146146+- Font: SoDoSans, 16px, weight 600, letter-spacing `-0.01em`
147147+- Active state: `transform: scale(0.95)` via `--buttonActiveScale`
148148+- Transition: `all 0.2s ease`
149149+150150+**2. Primary Outlined — "Give them a try / Start an order"**
151151+152152+- Background: transparent
153153+- Text: `#00754A` (Green Accent)
154154+- Border: `1px solid #00754A`
155155+- Same radius/padding/active/transition as Primary Filled
158156159159-**Dark Pill**
157157+**3. Black Filled — "Join now"**
160158161161-- Background: `var(--spot-hover)`
162162-- Text: `var(--spot-text)` or `var(--spot-secondary)`
163163-- Padding: 8px 16px
164164-- Radius: 9999px (full pill)
165165-- Use: Navigation pills, secondary actions
159159+- Background: `#000000`
160160+- Text: `#ffffff`
161161+- Border: `1px solid #000000`
162162+- Radius: `50px`, Padding: `7px 16px`
163163+- Font: 14px, weight 600
164164+- Used on the top-of-page join strip and similar conversion moments
166165167167-**Outlined Pill**
166166+**4. Dark Outlined — "Sign in"**
168167169168- Background: transparent
170170-- Text: `var(--spot-text)`
171171-- Border: `1px solid var(--spot-outline)`
172172-- Radius: 9999px
173173-- Use: Follow buttons, secondary actions
169169+- Text: `rgba(0, 0, 0, 0.87)` (Text Black)
170170+- Border: `1px solid rgba(0, 0, 0, 0.87)`
171171+- Radius: `50px`, Padding: `7px 16px`
172172+- Font: 14px, weight 600
173173+174174+**5. Green-on-Green Inverted — "See the spring menu"**
175175+176176+- Background: `#ffffff`
177177+- Text: `#00754A`
178178+- Border: `1px solid #ffffff`
179179+- Used when the surface behind the button is the dark green House Green band — white button with green text instead of a filled green pill on green bg
174180175175-**Circular Play**
181181+**6. Outlined on Dark — "Learn more / Order now"**
182182+183183+- Background: transparent
184184+- Text: `#ffffff`
185185+- Border: `1px solid #ffffff`
186186+- Used on dark-green feature bands for secondary action paired with a white filled CTA
176187177177-- Background: `#a855f7`
178178-- Text: `var(--spot-bg)`
179179-- Padding: 12px
180180-- Radius: 50% (circle)
181181-- Use: Play/pause controls
188188+**7. Consent Agree (dark-green variant)**
189189+190190+- Background: `rgb(0, 130, 72)` (a specific variant green used in the cookie-consent module)
191191+- Text: `#ffffff`
192192+- No border, `50px` radius, `7px 16px` padding, 14px / weight 400
193193+- Slightly brighter than Green Accent — reserved for the consent-banner Agree action
194194+195195+**8. Frap — Floating Circular Order Button**
196196+197197+- Background: `#00754A` (Green Accent)
198198+- Icon: `#ffffff`
199199+- Size: `5.6rem / 56px` (standard), `4rem / 40px` (mini variant)
200200+- Radius: `50%` (full circle)
201201+- Fixed bottom-right, `-0.8rem` touch offset for extra tap comfort
202202+- Shadow stack: base `0 0 6px rgba(0,0,0,0.24)` + ambient `0 8px 12px rgba(0,0,0,0.14)`
203203+- Active state: ambient shadow fades to `0 8px 12px rgba(0,0,0,0)`
204204+- This is the product's signature elevation element — it floats over every scrolled surface
205205+206206+**9. Full-width Feedback Tab — "Provide feedback"**
207207+208208+- Background: `#00754A`
209209+- Text: `#ffffff`
210210+- Radius: `12px 12px 0px 0px` (top-rounded only)
211211+- Padding: `8px 16px`
212212+- Font: 14px, weight 400
213213+- Positioned fixed bottom-right-inside, attached to the viewport edge
182214183215### Cards & Containers
184216185185-- Background: `var(--spot-surface)`
186186-- Radius: 6px–8px
187187-- No visible borders on most cards
188188-- Hover: `var(--spot-hover-50)` background
189189-- Shadow: `var(--spot-shadow)` on elevated
217217+**Content Card (default)**
218218+219219+- Background: `#ffffff` (`--cardBackgroundColor`)
220220+- Radius: `12px` (`--cardBorderRadius`)
221221+- Shadow: `0px 0px .5px 0px rgba(0,0,0,0.14), 0px 1px 1px 0px rgba(0,0,0,0.24)` (`--cardBoxShadow`)
222222+- Used for: feature cards, menu-item tiles, reward-status panels
223223+224224+**Gift Card Tile**
225225+226226+- Background: illustrated photography fills the card (no solid bg)
227227+- Radius: similar to cards (`~12px`, slightly tighter on corners)
228228+- Shadow: lighter than default card — these are treated like physical cards laid on the canvas
229229+- Labeled by category above the card grid (Spring, Thank You, Birthday, Celebration, Mother's Day, Appreciation, Encouragement, Milestones, Anytime)
230230+231231+**Rewards Status Cards (Rewards page signature)**
232232+233233+- Three-column grid: Bronze / Gold / Silver-ish — each a dark-green (`#1E3932`) panel with:
234234+ - Colored gradient/color header ring
235235+ - Numbered "Level" badge
236236+ - Status title in large SoDoSans weight 600
237237+ - Stars / benefits list in white/translucent-white text
238238+ - Bottom "As you earn more stars…" progression caption
239239+240240+**Partnership Card (Rewards)**
241241+242242+- Background: `#faf6ee` (Gold Lightest) warm-cream surface
243243+- Content: partner logos ("SkyMiles", "Bonvoy") centered, with descriptive text below
244244+- Radius and shadow follow default card spec
245245+246246+**Dropdown Menu (Account dropdown, top-nav)**
247247+248248+- Background: `#f9f9f9` (Neutral Cool)
249249+- Menu items at `24px / weight 400` in Text Black
250250+- No border — just background surface shift against white nav
251251+252252+**Modal**
253253+254254+- Padding: `2.4rem` (`--modalPadding`)
255255+- Top padding: `8.8rem` (`--modalTopPadding`) — leaves room for close button / header
256256+- Combined vertical padding: `11.2rem`
257257+- Radius inherits from card spec (`12px`)
258258+259259+### Inputs & Forms
260260+261261+**Floating Label Input**
262262+263263+- Label floats above the input border when focused/filled
264264+- Desktop label font size: `1.9rem` default, animates to `1.4rem` when active
265265+- Mobile label font size: `1.6rem` default, animates to `1.3rem` active
266266+- Label horizontal offset: `12px` from left
267267+- Active label translate: up to `-12px` with `-50%` Y translation
268268+- Field padding: `12px`
269269+- Form horizontal padding: `1.6rem`
270270+- Validation: valid-field gets `rgba(green-light, 0.33)` tint; invalid-field gets `rgba(red, 0.05)` tint
271271+- Transition: `0.3s option-label-marker-expansion cubic-bezier(0.32, 2.32, 0.61, 0.27)` on checked-input
190272191191-### Inputs
273273+**Option Icon (checkbox/radio)**
192274193193-- Background: `var(--spot-hover)`
194194-- Text: `var(--spot-text)`
195195-- Radius: 500px (pill)
196196-- Focus ring: `#a855f7`
197197-- Placeholder: `var(--spot-placeholder)`
275275+- Padding: `3px` inner
276276+- Uses the checked-input cubic-bezier animation above (a slightly "springy" 2.32 overshoot curve)
198277199278### Navigation
200279201201-- Sidebar: `var(--spot-bg)` background
202202-- Active items: 14px weight 700, `var(--spot-text)`
203203-- Inactive items: 14px weight 400, `var(--spot-secondary)`
204204-- Circular icon buttons (50% radius)
205205-- Brand logo top-left in purple
280280+**Global Nav (top bar)**
281281+282282+- Fixed position with progressive heights: `64px` xs → `72px` mobile → `83px` tablet → `99px` desktop
283283+- Shadow stack: `0 1px 3px rgba(0,0,0,0.1), 0 2px 2px rgba(0,0,0,0.06), 0 0 2px rgba(0,0,0,0.07)` — three-layer soft lift
284284+- Left: Starbucks wordmark logo, offsetting by `99px` (md) / `131px` (lg) from left edge
285285+- Primary links inline in SoDoSans weight 400–600: Menu · Rewards · Gift Cards
286286+- Right: Find a store link + Sign in (outlined) + Join now (black filled)
287287+288288+**Sub-nav (second bar, e.g., Rewards internal)**
289289+290290+- Height: `53px` (global subnav) / `48px` (internal subnav)
291291+- Typically horizontal tab group beneath the global nav
292292+293293+**Mobile Nav**
294294+295295+- Collapses to a hamburger drawer below tablet breakpoint
296296+- Frap floating button persists at bottom-right regardless of nav state
297297+298298+### Image Treatment
299299+300300+- **Hero photography**: Product photos (beverages in clear glass with colored backgrounds — coral, sage, warm amber) occupy ~40vw of a split-hero layout; text occupies the other 60vw (`--headerCrateProportion: 40vw` / `--contentCrateProportion: 60vw`)
301301+- **Gift card illustrations**: Each card is a distinct illustrated photograph (painted-feel, hand-drawn-looking, warm color palette). Never generic generated graphics.
302302+- **Rewards ceremony imagery**: Photographs of Starbucks Rewards App screens held in-hand, angled compositions — product-in-context photography.
303303+- **Menu thumbnails**: Square or 4:3 product photography with clean white/cream backdrops, slight soft drop-shadow around the glass.
304304+- **Image fade-in**: `opacity 0.3s ease-in` transition on image load (`--imageFadeTransition`).
305305+306306+### Feature Band (dark-green hero strip)
307307+308308+Full-width `#1E3932` (House Green) band with:
309309+310310+- Left: white headline + subhead + CTA row
311311+- Right: product photography or illustration
312312+- Split ratio ~40/60 or 50/50 depending on section
313313+- White text throughout with `rgba(255,255,255,0.70)` for secondary copy
314314+- CTAs follow Green-on-Green Inverted (white filled) + Outlined on Dark (white outline) pairing
315315+316316+### Expander / Accordion
317317+318318+- Duration: `300ms` (`--expanderDuration`)
319319+- Timing curve: `cubic-bezier(0.25, 0.46, 0.45, 0.94)` — a measured ease-out
320320+- Used for FAQ sections on Rewards and gift page
321321+322322+### Cookie Consent Module
323323+324324+Dark-green modal card at top of page with "Agree" (green-filled) and "Manage preferences" (outlined) buttons. Appears on first visit; dismissible.
325325+326326+### Product Detail Components (PDP signature cluster)
327327+328328+A repeating component cluster used on menu product pages (e.g., `/menu/product/40498/iced` for a drink detail, `/menu/product/.../nutrition` for nutrition facts). These extend the component inventory without changing tokens.
329329+330330+**Size Options Selector**
331331+332332+- Horizontal row of 4 cup-icon buttons (Tall / Grande / Venti / Trenta)
333333+- Each item: cup silhouette icon on top, size name below (16/700 in Starbucks-Green), fluid-ounce caption (13/400 in Text Black Soft)
334334+- Active state: a green circular ring outline (`2px solid #00754A`) around the selected cup icon
335335+- Inactive: no ring, same typography
336336+- Full-width row, equal spacing
337337+- Radius of container: `12px` or flat; individual icons are `50%` circular
338338+- Padding: `16px 24px` internal
339339+340340+**Add-in / Milk Select (outlined rectangle)**
341341+342342+- Background: `#ffffff`
343343+- Border: `1px solid #d6dbde` (Input Border)
344344+- Radius: `4px`
345345+- Full-width in its column
346346+- Floating label above top border: "Add-ins" / "Milk" / "Add-ins" — 13/700 in Text Black, uppercase, `0.325px` letter-spacing
347347+- Value displayed centered (e.g., "Ice", "Coconut", "Strawberry Fruit Inclusions scoop"): 16/400 Text Black
348348+- Chevron-down icon right side in Text Black Soft
349349+- Focus: border shifts to Green Accent (`#00754A`)
350350+351351+**Numeric Stepper**
352352+353353+- Embedded inside an Add-in row when a quantity is required (e.g., Strawberry Fruit Inclusions scoop)
354354+- `−` minus button + count number + `+` plus button, all inline right of the label
355355+- Buttons: circular `32×32px` with `1px solid #d6dbde` border, neutral gray icon
356356+- Count number: 16/700 Text Black centered
357357+358358+**Customize Button**
359359+360360+- Background: `#ffffff`
361361+- Text: `#00754A` (Green Accent)
362362+- Border: `1.5px solid #00754A`
363363+- Radius: `50px` (full pill)
364364+- Padding: `14px 40px` (generously larger than default pills — this is a secondary primary action)
365365+- Label: "Customize" with a gold sparkle ✨ icon inset left
366366+- Used for: entering the drink-customization flow after size/milk selection
367367+368368+**Add to Order Button (PDP)**
369369+370370+- Background: `#00754A` (Green Accent)
371371+- Text: `#ffffff`
372372+- Radius: `50px`
373373+- Padding: `14px 32px`
374374+- Pinned top-right of product card and/or aligned right within the store-availability band
375375+- Same scale(0.95) active behavior as other primary CTAs
376376+377377+**Rewards Cost Pill — "200★ item"**
378378+379379+- Background: transparent
380380+- Border: `1px solid #cba258` (Gold)
381381+- Text: `#cba258` (Gold)
382382+- Radius: `50px` (full pill)
383383+- Padding: `4px 12px`
384384+- Content: "200★ item" where `★` is a small filled star glyph — indicates the Rewards Stars required to redeem this item
385385+- Font: Proxima Nova 13/700 with `0.5px` letter-spacing
386386+- Used only on products that are Rewards-redeemable
387387+388388+**Product Description Band**
389389+390390+- Full-width dark-green band (`#1E3932` House Green)
391391+- Contains top-to-bottom:
392392+ 1. Rewards Cost Pill (gold) if applicable
393393+ 2. Product description body copy in white (16/400/1.5)
394394+ 3. Nutritional summary inline ("140 calories, 25g sugar, 2.5g fat") with info-icon tooltip — 14/700 white
395395+ 4. "Full nutrition & ingredients list" outlined-white-on-green pill button
396396+- Padding: `32px` vertical
397397+- Appears beneath the primary product header band
398398+399399+**Ingredients / Nutrition Table**
400400+401401+- Two-column layout on the Nutrition page
402402+- Left column: "Ingredients" header + list or "Not available for this item" placeholder text block with an explanatory paragraph in Text Black Soft 14/400
403403+- Right column: "Nutrition" header + label/value rows
404404+- Each row: nutrient label (Proxima Nova 14/400) on the left, value (e.g., "140 calories", "25g", "205 mg\*\*") on the right, separated by a `1px solid #e7e7e7` hairline below
405405+- Footnote for caffeine/asterisk markers in 13/400 Text Black Soft at the bottom
406406+- Reusable pattern for nutrition facts regulation-compliant tables
407407+408408+**Store Availability Selector**
409409+410410+- Appears on dark-green feature band above the size-options row
411411+- Full-width rounded rectangle with transparent-white interior
412412+- Text: "For item availability, choose a store" in white, 14/400
413413+- Right side: chevron-down affordance + shopping-bag SVG icon in white outline
414414+- Radius: `4px`
415415+- Height: ~48px
416416+417417+**PDP Breadcrumb**
418418+419419+- "Menu / Refreshers / Pink Energy Drink" trail above the product title
420420+- Separator: `/` slash character in Text Black Soft
421421+- Current page is unlinked, prior pages are underlined green-accent links
422422+- Font: 14/400 Proxima Nova
423423+- Appears on all PDP pages
206424207207-## 6. Layout Principles
425425+**Back Chevron Link (PDP nutrition / detail sub-pages)**
426426+427427+- "← Back" text link above section headings on the nutrition page
428428+- Text in Green Accent (`#00754A`) 14/700 Proxima Nova
429429+- Left chevron `<` in the same green
430430+- Alternative to full breadcrumb on deep sub-pages
431431+432432+## 5. Layout Principles
208433209434### Spacing System
210435211211-- Base unit: 8px
212212-- Scale: 1px, 2px, 3px, 4px, 5px, 6px, 8px, 10px, 12px, 14px, 15px, 16px, 20px
436436+Rem-based semantic scale (anchored `1rem = 10px`):
437437+438438+| Token | Rem | Pixels | Typical Use |
439439+| ----------- | -------- | ------ | ----------------------------------------- |
440440+| `--space-1` | `0.4rem` | 4px | Tightest inline padding |
441441+| `--space-2` | `0.8rem` | 8px | Small gap, button vertical padding |
442442+| `--space-3` | `1.6rem` | 16px | Default — card padding, outer gutter xs |
443443+| `--space-4` | `2.4rem` | 24px | Section inner spacing, outer gutter md |
444444+| `--space-5` | `3.2rem` | 32px | Major between-section spacing |
445445+| `--space-6` | `4rem` | 40px | Large gaps, outer gutter lg, header crate |
446446+| `--space-7` | `4.8rem` | 48px | Section-to-section spacing |
447447+| `--space-8` | `5.6rem` | 56px | Very large breathing — Frap height |
448448+| `--space-9` | `6.4rem` | 64px | Widest section padding |
449449+450450+**Gutter tokens:**
451451+452452+- `--outerGutter: 1.6rem` (16px, default / mobile)
453453+- `--outerGutterMedium: 2.4rem` (24px, tablet)
454454+- `--outerGutterLarge: 4.0rem` (40px, desktop)
455455+456456+**Universal rhythm constant:** `1.6rem` (16px) appears across every page as the default outer gutter, card padding baseline, and text size 3 body — the system's most frequent spacing unit.
213457214458### Grid & Container
215459216216-- Sidebar (fixed) + main content area
217217-- Grid-based album/playlist cards
218218-- Responsive content area fills remaining space
460460+- Column width scale: `--columnWidthSmall: 343px` / `Medium: 500px` / `Large: 720px` / `XLarge: 1440px`
461461+- Gift-card grid uses a 3-5-up responsive grid of `~343px` tiles
462462+- Rewards status section: 3-up dark-green panels at `lg+` breakpoints
463463+- Hero: asymmetric split 40% (image) / 60% (content) via `--headerCrateProportion` / `--contentCrateProportion`
219464220465### Whitespace Philosophy
221466222222-- **Dark compression**: Spotify packs content densely — playlist grids, track lists, and navigation are all tightly spaced. The dark background provides visual rest between elements without needing large gaps.
223223-- **Content density over breathing room**: This is an app, not a marketing site. Every pixel serves the listening experience.
467467+Whitespace carries the feeling of "plenty of space in the café." Section padding leans generous (40–64px). Content blocks are separated by whitespace rather than dividers. The cream canvas (`#f2f0eb`) is itself a visual breath between white cards and green feature bands.
224468225469### Border Radius Scale
226470227227-- Minimal (2px): Badges, explicit tags
228228-- Subtle (4px): Inputs, small elements
229229-- Standard (6px): Album art containers, cards
230230-- Comfortable (8px): Sections, dialogs
231231-- Medium (10px–20px): Panels, overlay elements
232232-- Large (100px): Large pill buttons
233233-- Pill (500px): Primary buttons, search input
234234-- Full Pill (9999px): Navigation pills, search
235235-- Circle (50%): Play buttons, avatars, icons
471471+| Value | Use |
472472+| --------------- | ----------------------------------------------------------------------------------- |
473473+| `12px` | Cards, modals, menu-item tiles (`--cardBorderRadius`) |
474474+| `12px 12px 0 0` | Full-width feedback tab (top-rounded only) |
475475+| `50px` | All buttons — full-pill radius (`--buttonBorderRadius`) |
476476+| `50%` | Circular icons, Frap floating button, avatar thumbnails |
477477+| Specialty | `3.3333%/5.298%` elliptical for Starbucks-Visa-Card mockups (`--svcRoundedCorners`) |
236478237237-## 7. Depth & Elevation
479479+## 6. Depth & Elevation
238480239239-| Level | Treatment | Use |
240240-| ------------------ | ---------------------------- | ------------------------------ |
241241-| Base (Level 0) | `var(--spot-bg)` background | Deepest layer, page background |
242242-| Surface (Level 1) | `var(--spot-surface)` | Cards, sidebar, containers |
243243-| Elevated (Level 2) | `var(--spot-shadow)` | Dropdown menus, hover cards |
244244-| Dialog (Level 3) | `var(--spot-shadow-heavy)` | Modals, overlays, menus |
481481+| Level | Treatment | Use |
482482+| -------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------- |
483483+| Card | `0 0 0.5px rgba(0,0,0,0.14), 0 1px 1px rgba(0,0,0,0.24)` | Default content cards — a whisper-soft dual-shadow |
484484+| Global Nav | `0 1px 3px rgba(0,0,0,0.1), 0 2px 2px rgba(0,0,0,0.06), 0 0 2px rgba(0,0,0,0.07)` | Triple-layer soft lift on the fixed top bar |
485485+| Frap Base | `0 0 6px rgba(0,0,0,0.24)` | Base halo around the floating circular CTA |
486486+| Frap Ambient | `0 8px 12px rgba(0,0,0,0.14)` | Stacked directional ambient — floats the Frap forward |
487487+| Gift Card | Light drop shadow around illustrated photograph | Physical-card feel for gift tiles |
488488+| Starbucks Card (SVC) | `drop-shadow(0 4px 1px rgba(0,0,0,0.11)) drop-shadow(0 0 2px rgba(0,0,0,0.24))` | Stacked SVG drop shadows for Starbucks Card visuals |
245489246246-## 8. Do's and Don'ts
490490+**Shadow philosophy:** Whisper-soft, layered over solid — the system never reaches for a single heavy drop shadow. Instead, it stacks 2–3 low-alpha shadows with different offsets to simulate real-world ambient + direct lighting. The Frap button is the most elevated element on any page.
491491+492492+### Decorative Depth
493493+494494+- **No gradient system** — surfaces are solid color-block
495495+- **Color-block banding** carries perceived depth (dark-green bands read as "recessed feature zones" between cream/white body sections)
496496+- **SVG filter shadows** on Starbucks-Card visuals add a slight 3D physicality without a box-shadow
497497+498498+## 7. Do's and Don'ts
247499248500### Do
249501250250-- Use semantic color tokens (`spot-bg`, `spot-surface`, `spot-text`, etc.) — they adapt to theme
251251-- Apply Accent Purple (`#a855f7`) only for play controls, active states, and primary CTAs
252252-- Use pill shape (500px–9999px) for all buttons — circular (50%) for play controls
253253-- Apply uppercase + wide letter-spacing (1.4px–2px) on button labels
254254-- Keep typography compact (10px–24px range) — this is an app, not a magazine
255255-- Use theme-aware shadows via CSS variables
256256-- Test all components in both dark and light themes
502502+- Use Neutral Warm (`#f2f0eb`) or Ceramic (`#edebe9`) as page canvas instead of pure white — the warm cream is the signature
503503+- Map the green tiers to their intended surface role — Starbucks Green for headings, Green Accent for CTAs, House Green for deep bands, Uplift for decorative
504504+- Keep tracking tight at `-0.01em` / `-0.16px` on SoDoSans across the whole system
505505+- Use 50px full-pill radius on every button without exception
506506+- Apply `transform: scale(0.95)` as the universal button active state
507507+- Reserve Gold for Rewards-status ceremony moments only
508508+- Use SoDoSans for nearly everything; switch to Lander Tall serif only for Rewards editorial headlines; reserve Kalam script for Careers "cup name" moments
509509+- Layer 2–3 low-alpha shadows instead of one heavier drop shadow for elevation
510510+- Use the Frap circular CTA as the persistent floating order entry on every shopping surface
511511+- Let the cream canvas breathe between content cards — use whitespace, not dividers
257512258513### Don't
259514260260-- Don't use Accent Purple decoratively or on backgrounds — it's functional only
261261-- Don't hardcode theme-dependent colors — use CSS variable-backed tokens
262262-- Don't skip the pill/circle geometry on buttons — square buttons break the identity
263263-- Don't use hardcoded shadow values — use `shadow-spot` and `shadow-spot-heavy`
264264-- Don't add additional brand colors — purple + achromatic grays is the complete palette
265265-- Don't use `text-white` or `bg-white` directly — use `text-spot-text` and `bg-spot-active-pill-bg`
266266-- Don't expose raw gray borders — use `border-spot-divider` or `border-spot-outline`
515515+- Don't use pure white as the page canvas — the warm cream temperature is load-bearing
516516+- Don't pick "one brand green" — the four-green system is intentional; using only `#006241` everywhere flattens the brand
517517+- Don't use Gold as a general-purpose accent — it's a Rewards signal only
518518+- Don't square the corners on buttons — the 50px pill is universal
519519+- Don't introduce gradient fills — the system is color-block throughout
520520+- Don't weight-contrast h1 and h2 by size — the hierarchy comes from weight + color (600 Starbucks-Green vs 400 Text Black)
521521+- Don't use pure black for body text — `rgba(0,0,0,0.87)` matches the warm canvas
522522+- Don't skip the `scale(0.95)` active feedback on buttons — it's a signature micro-interaction
523523+- Don't stack single heavy shadows; always layer 2–3 low-alpha ones
524524+- Don't introduce serifs or scripts into the main shopping flow — they belong to Rewards and Careers contexts respectively
267525268268-## 9. Responsive Behavior
526526+## 8. Responsive Behavior
269527270528### Breakpoints
271529272272-| Name | Width | Key Changes |
273273-| ------------- | ----------- | --------------------- |
274274-| Mobile Small | <425px | Compact mobile layout |
275275-| Mobile | 425–576px | Standard mobile |
276276-| Tablet | 576–768px | 2-column grid |
277277-| Tablet Large | 768–896px | Expanded layout |
278278-| Desktop Small | 896–1024px | Sidebar visible |
279279-| Desktop | 1024–1280px | Full desktop layout |
280280-| Large Desktop | >1280px | Expanded grid |
530530+Inferred from component width tokens and progressive nav heights:
531531+532532+| Name | Width | Key Changes |
533533+| ------- | ----------- | ------------------------------------------------------------------------------- |
534534+| xs | < 480px | Global nav 64px; hamburger menu; single-column layouts; pill buttons full-width |
535535+| Mobile | 480–767px | Global nav 72px; gift-card grid 2-up; card padding tightens |
536536+| Tablet | 768–1023px | Global nav 83px; gift-card grid 3-up; hero split begins to appear |
537537+| Desktop | 1024–1439px | Global nav 99px; gift-card grid 4-up; full asymmetric hero 40/60 |
538538+| XLarge | 1440px+ | Content caps at `--columnWidthXLarge`; gift-card grid 5-up; extra cream margin |
539539+540540+### Touch Targets
541541+542542+- Pill buttons at `7px 16px` padding measure ~32px tall — below 44px WCAG AAA minimum for touch-only surfaces. On mobile, button padding may be visually expanded to meet the minimum.
543543+- Frap floating circular button at `56px` is well above minimum.
544544+- Frap uses `--frapTouchOffset: calc(-1 * .8rem)` to extend tap area 8px beyond visual edge.
545545+- Form float-label inputs grow their label font size on mobile (1.6rem base vs 1.9rem desktop) — easier to tap and read at arm's-length.
281546282547### Collapsing Strategy
283548284284-- Sidebar: full → collapsed → hidden
285285-- Album grid: 5 columns → 3 → 2 → 1
286286-- Search: pill input maintained, width adjusts
287287-- Navigation: sidebar → bottom bar on mobile
288288-- Theme toggle: always accessible in sidebar footer / mobile header
549549+- **Global nav height scales progressively**: 64 → 72 → 83 → 99px across breakpoints, not a single value
550550+- **Hero split collapses**: 40/60 asymmetric split → stacked (image top, content below) at mobile
551551+- **Gift-card grid**: 5-up → 4-up → 3-up → 2-up → 1-up across breakpoints with adjusted card widths
552552+- **Feature bands**: Stay full-width but text + imagery stack vertically on mobile
553553+- **Outer gutter scales**: 16px → 24px → 40px as viewport grows
554554+- **Rewards 3-column status panels**: Stack to single column on mobile
289555290290-## 10. Agent Prompt Guide
556556+### Image Behavior
557557+558558+- Hero product photography crops tighter vertically on mobile; content becomes the visual anchor
559559+- Gift-card illustrations preserve aspect ratio; card grid reflows
560560+- `opacity 0.3s ease-in` fade-in transition on image load (prevents jarring pop-in)
561561+- Rewards app-in-hand photography scales proportionally; never stretches
562562+563563+## 9. Agent Prompt Guide
291564292565### Quick Color Reference
293566294294-| Role | Token | Value (dark) |
295295-| -------------- | -------------------- | -------------- |
296296-| Background | `bg-spot-bg` | `#121212` |
297297-| Surface | `bg-spot-surface` | `#181818` |
298298-| Hover | `bg-spot-hover` | `#1f1f1f` |
299299-| Text primary | `text-spot-text` | `#ffffff` |
300300-| Text secondary | `text-spot-secondary`| `#b3b3b3` |
301301-| Text body | `text-spot-body` | `#cbcbcb` |
302302-| Text muted | `text-spot-muted` | `#4d4d4d` |
303303-| Accent | `text-spot-purple` | `#a855f7` |
304304-| Divider | `border-spot-divider`| `rgba(...)` |
305305-| Outline | `border-spot-outline`| `#7c7c7c` |
306306-| Error | `text-spot-red` | `#f3727f` |
567567+- Primary CTA: "Green Accent (`#00754A`)"
568568+- Primary CTA text: "White (`#ffffff`)"
569569+- Brand heading: "Starbucks Green (`#006241`)"
570570+- Feature band / footer: "House Green (`#1E3932`)"
571571+- Page canvas: "Neutral Warm (`#f2f0eb`)"
572572+- Card canvas: "White (`#ffffff`)"
573573+- Heading text on light: "Text Black (`rgba(0,0,0,0.87)`)"
574574+- Body text on light: "Text Black Soft (`rgba(0,0,0,0.58)`)"
575575+- Body text on dark-green: "Text White Soft (`rgba(255,255,255,0.70)`)"
576576+- Rewards accent: "Gold (`#cba258`)"
577577+- Rewards text: "Rewards Green (`#33433d`)"
578578+- Destructive: "Red (`#c82014`)"
579579+580580+### Example Component Prompts
581581+582582+1. "Create a primary Starbucks CTA pill button with Green Accent (`#00754A`) background, white text 'Explore our afternoon menu', SoDoSans font at 16px weight 600 with `-0.01em` letter-spacing, `50px` border-radius (full pill), `7px 16px` padding. Apply `transform: scale(0.95)` as the active state with a `0.2s ease` transition."
583583+584584+2. "Design a content card with White (`#ffffff`) background at `12px` border-radius, layered shadow `0 0 0.5px rgba(0,0,0,0.14), 0 1px 1px rgba(0,0,0,0.24)`. Pad contents `16–24px` (`--space-3` to `--space-4`). Place on a Neutral Warm (`#f2f0eb`) page canvas with `16px` gap to siblings."
585585+586586+3. "Build the Frap floating circular order button — `56px` diameter, Green Accent (`#00754A`) fill, white shopping-bag icon centered. Layered shadow: `0 0 6px rgba(0,0,0,0.24)` + `0 8px 12px rgba(0,0,0,0.14)`. Fixed position bottom-right with `-0.8rem` touch offset. Active state collapses the ambient shadow to `0 8px 12px rgba(0,0,0,0)` with `scale(0.95)`."
587587+588588+4. "Build a dark-green feature band — full-width section with House Green (`#1E3932`) background. Left column: white SoDoSans h2 at 24px weight 600, followed by a Text White Soft (`rgba(255,255,255,0.70)`) body paragraph and a CTA row with two buttons (White-filled with Green Accent text for primary, Outlined-on-Dark white border for secondary). Right column: product photography. Split ratio 40/60, stacked vertically below `768px`."
589589+590590+5. "Create a Rewards status card — House Green (`#1E3932`) panel with `12px` border-radius, colored gradient top stripe (Bronze/Silver/Gold tier). Title in SoDoSans 24px weight 600 in white. Benefits list as white bullets with `rgba(255,255,255,0.70)` secondary captions. Bottom progression text in Text White Soft. Stack 3 panels in a grid at `lg+`, single column on mobile."
591591+592592+6. "Design a gift-card tile — card radius matches `12px`, fills with an illustrated photograph (hand-drawn watercolor-painted feel) as the entire surface. Subtle drop shadow makes it feel like a physical card on the cream canvas. Group under a category label ('Spring', 'Thank You', 'Birthday') in SoDoSans 24px weight 400 above the grid."
593593+594594+7. "Create a Starbucks product-detail header — House Green (`#1E3932`) band with breadcrumb 'Menu / Refreshers / Pink Energy Drink' in 14/400 white above the product title in SoDoSans 32/700 uppercase white. Product photograph centered below title. Below photo: a 4-up size selector row — each cup-icon button shows a vertical cup silhouette, size name ('Tall' / 'Grande' / 'Venti' / 'Trenta') in 16/700 white, and fluid-ounce in 13/400 Text White Soft. Selected size wraps the cup icon in a `2px solid #00754A` circular ring."
595595+596596+8. "Build a Starbucks customize flow — under the size selector, 3 stacked outlined-rectangle input rows (white bg, `1px solid #d6dbde` border, `4px` radius). Each has a floating label ('Add-ins', 'Milk', 'Add-ins') above the top border in 13/700 Text Black uppercase. Value centered (e.g., 'Ice', 'Coconut'). Right side: chevron-down in Text Black Soft. For the scoop row, embed a numeric stepper (`−` `1` `+` with circular `32px` outlined buttons). Below all three fields: outlined green 'Customize' pill with gold sparkle icon, `50px` radius, `14px 40px` padding. Pair with a Green Accent filled 'Add to Order' pill in the same row."
597597+598598+9. "Design a Starbucks product description band — full-width House Green (`#1E3932`) below product header. Top: a gold-outlined '200★ item' Rewards Cost Pill (`50px` radius, `4px 12px` padding, gold `#cba258` border and text). Below: product description in white 16/400/1.5. Nutritional inline summary in white 14/700 ('140 calories, 25g sugar, 2.5g fat') with info-icon tooltip. Outlined-white-on-green pill button 'Full nutrition & ingredients list'. 32px vertical padding."
599599+600600+10. "Create a Starbucks nutrition facts table — two-column layout inside a White card. Left column: 'Ingredients' header (24/400 Text Black), followed by ingredient list or 'Not available for this item' placeholder paragraph in 14/400 Text Black Soft. Right column: 'Nutrition' header, then label/value rows (nutrient name left, value right) separated by `1px solid #e7e7e7` hairlines. Typography: labels in 14/400 Text Black, values in 14/700 Text Black right-aligned. Footnote asterisk markers in 13/400 Text Black Soft at the bottom."
307601308602### Iteration Guide
309603310310-1. Use semantic tokens (`spot-bg`, `spot-surface`, `spot-text`) — they handle theme switching
311311-2. Accent Purple (`spot-purple`) for functional highlights only (active, CTA)
312312-3. Pill everything — 500px for large, 9999px for small, 50% for circular
313313-4. Uppercase + wide tracking on buttons — the systematic label voice
314314-5. Theme-aware shadows via `shadow-spot` and `shadow-spot-heavy`
315315-6. Never hardcode `text-white` or `bg-white` — use semantic tokens
604604+When refining existing screens generated with this design system:
605605+606606+1. Focus on ONE component at a time
607607+2. Reference specific color names and hex codes from this document
608608+3. Use natural language descriptions ("warm cream canvas," "four-tier green system") alongside exact values
609609+4. Preserve the 50px pill + `scale(0.95)` active state universally
610610+5. Check that greens are mapped to their correct role (Green Accent for CTA, Starbucks Green for heading, House Green for band)
611611+6. Don't introduce gradients — the system is color-block
612612+7. Keep SoDoSans tracking at `-0.01em` / `-0.16px` across the board
613613+614614+### Known Gaps
615615+616616+- SoDoSans is a proprietary typeface not available on Google Fonts — when implementing publicly, use Inter or Manrope as a substitute and document the swap
617617+- Lander Tall (Rewards serif) is also custom — substitute with Iowan Old Style, Lora, or Source Serif Pro
618618+- Specific per-component animation timings beyond the few documented (`--duration: 0.4s`, `--iconTransition: all ease-out 0.2s`, `--expanderDuration: 300ms`) are not captured for every interactive surface
619619+- Form error-state full styling (red border weight, icon placement) visible on the tint token but not exhaustively extracted
620620+- Careers-page specific components (cup-name card, search radio grid) are referenced in token names but not covered by this extraction
621621+- Starbucks Visa Card / Starbucks-Card (SVC) detailed mockup specs are hinted at by `--svcRoundedCorners` and `--svcShadowFilter` tokens but not fully documented