nandi/gleanpublic⑂ Fork 0
⑂ 830e577
Commits
⬇ Clone ▾
git clone https://git.rickub.com/nandi/glean.git
git clone ssh://git@rickub.com/nandi/glean.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Rename Glean design system and adopt Inter fontUnverified

Julien Robert committed 2026-04-20T13:57:15+02:00 Browse files
830e577 parent: cc6316c
modified docs/design.md +121 -574
@@ -1,621 +1,168 @@
1-# Design System Inspired by Starbucks
1+# Glean Design System
22
3-## 1. Visual Theme & Atmosphere
4-
5-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.
6-
7-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.
8-
9-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.
10-
11-**Key Characteristics:**
12-
13-- Four-tier green brand system (Starbucks / Accent / House / Uplift) each mapped to a distinct surface role — not a single "brand green"
14-- Gold reserved for Rewards-status moments only; never a general-purpose accent
15-- Warm-neutral canvas (`#f2f0eb` / `#edebe9`) instead of cold white — references café materials
16-- Custom proprietary typeface (SoDoSans) with tight `-0.16px` letter-spacing as the universal voice
17-- Context-specific type switches: serif (Lander Tall) for Rewards, script (Kalam) for Careers cup-names
18-- Full-pill buttons (`50px` radius) universal, `scale(0.95)` active press the signature micro-interaction
19-- Floating "Frap" circular CTA (`56px`, Green Accent fill, layered shadow stack) — the product's signature elevation element
20-- Gift-card surfaces designed as **photographed physical product** — every card is a distinct illustrated photograph rather than a generated graphic
21-- 12px card radius + whisper-soft shadows keep content cards flat-plus-hint-of-lift
22-- Rem-based spacing scale anchored at 1.6rem (~16px) = `--space-3`, stepping to 6.4rem (~64px)
23-
24-**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.
25-
26-## 2. Color Palette & Roles
27-
28-**Source pages analyzed:** homepage, rewards, gift cards, product detail (Pink Energy Drink), product nutrition (Cold Brew).
29-
30-### Primary
31-
32-- **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.
33-- **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.
34-- **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.
35-- **Green Uplift** (`#2b5148`): A secondary mid-dark green used sparingly on decorative accents and dark-gradient moments.
36-- **Green Light** (`#d4e9e2`): A pale mint wash used for form-valid-state tints and light green utility surfaces.
37-
38-### Secondary & Accent
39-
40-- **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.
41-- **Gold Light** (`#dfc49d`): Softer gold for background washes on gold-tier sections.
42-- **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.
43-
44-### Surface & Background
3+Adapted from the Starbucks-inspired green palette. Warm, confident, and grounded in a four-tier green system with a dark/light theme switch.
454
46-- **White** (`#ffffff`): Primary card and modal surface. Also card fill on gift-card tiles.
47-- **Neutral Cool** (`#f9f9f9`): Subtle cool-gray surface used on dropdown menus ("Account" dropdown), form-card wraps, and quiet utility containers.
48-- **Neutral Warm** (`#f2f0eb`): The warm cream **primary page canvas** for Rewards utility zones and hero bands.
49-- **Ceramic** (`#edebe9`): A slightly warmer/darker cream for zone separators, soft page-section washes, and Rewards partnership band.
50-- **Black** (`#000000`): Deep ink reserved for the dark top-of-page CTA strip ("Join now") and high-contrast top-nav sign-in buttons.
51-
52-### Neutrals & Text
53-
54-- **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.
55-- **Text Black Soft** (`rgba(0, 0, 0, 0.58)`): Secondary/metadata text on light surfaces.
56-- **Text White** (`rgba(255, 255, 255, 1)`): Primary heading/body text on dark green surfaces.
57-- **Text White Soft** (`rgba(255, 255, 255, 0.70)`): Secondary text on dark-green surfaces — footer link descriptions, caption text.
58-- **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.
59-
60-### Semantic & Accent
61-
62-- **Red** (`#c82014`): Error and destructive state (form invalid, destructive actions).
63-- **Yellow** (`#fbbc05`): Warning state, legacy brand touch.
64-- **Green Light** (`#d4e9e2` at 33% opacity = `hsl(160 32% 87% / 33%)`): Form valid-field tint background.
65-- **Red Tint** (`hsl(4 82% 43% / 5%)`): Invalid-field tint on forms.
66-
67-### Black / White Alpha Ladders
68-
69-Two parallel translucent scales for overlay and secondary-text use:
70-
71-- `rgba(0,0,0,0.06)` through `rgba(0,0,0,0.90)` in 10% steps — for dark overlays on light surfaces
72-- `rgba(255,255,255,0.10)` through `rgba(255,255,255,0.90)` in 10% steps — for light overlays on dark surfaces
73-
74-### Gradient System
75-
76-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.
5+## 1. Visual Theme & Atmosphere
776
78-## 3. Typography Rules
7+Glean is a **warm, focused reading environment**. The canvas alternates between a deep forest green (dark mode) and a warm cream (light mode), with Green Accent (`#00754A`) anchoring all CTAs, links, and brand moments. The palette is deliberately not blue, not purple — it references natural, grounded tones.
798
80-### Font Family
9+Typography uses **Inter** (Google Fonts) as the universal typeface, with tight `-0.01em` letter-spacing across the entire product. A single typeface, a single voice.
8110
82-- **Primary:** `SoDoSans, "Helvetica Neue", Helvetica, Arial, sans-serif` — Starbucks' proprietary corporate typeface, used across nearly every surface
83-- **Loading Fallback:** `"Helvetica Neue", Helvetica, Arial, sans-serif` — what users see before SoDoSans loads
84-- **Rewards Serif:** `"Lander Tall", "Iowan Old Style", Georgia, serif` — used on specific Rewards-page headline moments for a warm editorial feel
85-- **Careers Script:** `"Kalam", "Comic Sans MS", cursive` — used exclusively for Careers-page "cup name" decorative touches, referencing the hand-written names on Starbucks cups
11+Surfaces breathe through rounded geometry: pill buttons (`9999px`), `12px` card corners, and `50%` circular avatars. Shadows are whisper-soft dual-layers, never heavy. The system feels like a well-lit reading room.
8612
87-No OpenType stylistic sets explicitly activated at `:root`.
13+**Color-block rhythm (landing page):** Cream/forest hero → white card sections → House Green (`#1E3932`) feature band with white text → cream utility zone → House Green footer.
8814
89-### Hierarchy
15+## 2. Color Palette
9016
91-| Role | Size | Weight | Line Height | Letter Spacing | Notes |
92-| ------------------- | -------------- | ------- | --------------- | -------------- | -------------------------------------------- |
93-| Display (text-10) | 5.0rem / 80px | 400–600 | 1.2 | -0.16px | Largest Rewards/hero display |
94-| Jumbo (text-9) | 3.6rem / 58px | 400–600 | 1.2 | -0.16px | Secondary hero headings |
95-| Hero Large (text-8) | 2.8rem / 45px | 400–600 | 1.2–1.5 | -0.16px | Landing section headlines |
96-| H1 | 24px | 600 | 36px | -0.16px | Starbucks-Green primary heading |
97-| H2 | 24px | 400 | 36px | -0.16px | Regular-weight section title in Text Black |
98-| Body Large | 19px | 400–600 | 33.25px (~1.75) | -0.16px | Hero intro copy, feature-band body |
99-| Body (text-3) | 1.6rem / 16px | 400 | 1.5 (24px) | -0.01em | Default body copy |
100-| Small (text-2) | 1.4rem / ~14px | 400–600 | 1.5 | -0.01em | Button label, metadata, form labels |
101-| Micro (text-1) | 1.3rem / ~13px | 400 | 1.5 | -0.01em | Active float-label state, caption micro-copy |
102-| Button Label | 14–16px | 400–600 | 1.2 | -0.01em | All pill-button labels |
17+### Primary Greens
10318
104-**Letter-spacing tokens:**
19+| Name | Hex | Role |
20+| --------------- | --------- | ------------------------------------------------ |
21+| Green Accent | `#00754A` | CTAs, active states, link hovers, brand accent |
22+| Green Dark | `#006241` | Headings on landing page, stronger brand moments |
23+| House Green | `#1E3932` | Dark bands, footer, feature sections |
24+| Green Uplift | `#2b5148` | Decorative accents, mid-dark green |
25+| Green Light | `#d4e9e2` | Light green utility surfaces, valid-state tints |
10526
106-- `letterSpacingNormal`: `-0.01em` (default — tight, characteristic)
107-- `letterSpacingLoose`: `0.1em` (emphasized caps)
108-- `letterSpacingLooser`: `0.15em` (uppercase-style labels, extreme emphasis)
27+### Dark Theme (default)
10928
110-**Line-height tokens:**
29+| Token | Value | Use |
30+| ------------------ | ------------------------------ | ------------------------------------ |
31+| `--spot-bg` | `#0f1f1a` | Page background, sidebar |
32+| `--spot-surface` | `#152b24` | Card background |
33+| `--spot-hover` | `#1a362e` | Hover state, input background |
34+| `--spot-text` | `#ffffff` | Primary text |
35+| `--spot-secondary` | `rgba(255,255,255,0.70)` | Secondary/metadata text |
36+| `--spot-body` | `rgba(255,255,255,0.87)` | Body copy, article content |
37+| `--spot-muted` | `rgba(255,255,255,0.25)` | Disabled/tertiary text |
38+| `--spot-divider` | `rgba(255,255,255,0.08)` | Borders, dividers |
39+| `--spot-outline` | `rgba(255,255,255,0.20)` | Button borders, input borders |
11140
112-- `lineHeightNormal`: `1.5` (body)
113-- `lineHeightCompact`: `1.2` (display/buttons)
41+### Light Theme
11442
115-### Principles
43+| Token | Value | Use |
44+| ------------------ | ------------------------------ | ------------------------------------ |
45+| `--spot-bg` | `#f2f0eb` | Page canvas (warm cream) |
46+| `--spot-surface` | `#ffffff` | Card background |
47+| `--spot-hover` | `#edebe9` | Hover state (ceramic) |
48+| `--spot-text` | `rgba(0,0,0,0.87)` | Primary text (warm black) |
49+| `--spot-secondary` | `rgba(0,0,0,0.58)` | Secondary/metadata text |
50+| `--spot-body` | `rgba(0,0,0,0.70)` | Body copy |
51+| `--spot-muted` | `rgba(0,0,0,0.25)` | Disabled/tertiary text |
52+| `--spot-divider` | `rgba(0,0,0,0.08)` | Borders, dividers |
53+| `--spot-outline` | `rgba(0,0,0,0.15)` | Button borders, input borders |
11654
117-- **Tight negative tracking (`-0.01em`)** is applied almost universally — the entire product reads slightly compressed, which gives SoDoSans its confident presence without feeling squeezed.
118-- **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.
119-- **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.
120-- **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.
121-- **Body text never goes pure black** — it sits at `rgba(0,0,0,0.87)` to match the warm-neutral canvas temperature.
55+### Semantic
12256
123-### Note on Font Substitutes
57+| Name | Hex | Use |
58+| ----- | --------- | ---------------- |
59+| Red | `#c82014` | Errors, likes |
60+| Orange| `#ffa42b` | Ratings, warnings|
61+| Blue | `#539df5` | External links |
12462
125-SoDoSans is proprietary to Starbucks (licensed from House Industries, not publicly available). Reasonable open-source substitutes:
63+## 3. Typography
12664
127-- **Inter** (Google Fonts) — similar humanist geometric proportions, wide weight range
128-- **Manrope** — slightly rounder, similar confident feel
129-- **Nunito Sans** — warmer, good for a "café" brand substitute
65+**Font:** Inter (Google Fonts), weights 400/500/600/700
13066
131-If substituting, verify the tight `-0.01em` / `-0.16px` tracking still reads well; some open-source fonts need `-0.005em` instead.
67+**Global:** `letter-spacing: -0.01em` on body
13268
133-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.
69+| Role | Size | Weight | Tailwind Class |
70+| ------------- | ---------- | ------ | ------------------ |
71+| Page title | 24px | 700 | `text-2xl font-bold` |
72+| Section title | 18px | 600 | `text-lg font-semibold` |
73+| Body | 14px | 400 | `text-sm` |
74+| Small/meta | 12px | 400 | `text-xs` |
75+| Button label | 14px | 700 | `text-sm font-bold uppercase tracking-button` |
76+| Micro | 10px | 400 | `text-[10px]` |
13477
135-## 4. Component Stylings
78+## 4. Components
13679
13780 ### Buttons
13881
139-**1. Primary Filled — "Explore our afternoon menu / Sign up for free"**
140-
141-- Background: `#00754A` (Green Accent)
142-- Text: `#ffffff`
143-- Border: `1px solid #00754A`
144-- Radius: `50px` (full pill)
145-- Padding: `7px 16px`
146-- Font: SoDoSans, 16px, weight 600, letter-spacing `-0.01em`
147-- Active state: `transform: scale(0.95)` via `--buttonActiveScale`
148-- Transition: `all 0.2s ease`
149-
150-**2. Primary Outlined — "Give them a try / Start an order"**
151-
152-- Background: transparent
153-- Text: `#00754A` (Green Accent)
154-- Border: `1px solid #00754A`
155-- Same radius/padding/active/transition as Primary Filled
156-
157-**3. Black Filled — "Join now"**
82+All buttons use full-pill radius (`rounded-pill` = `9999px`).
15883
159-- Background: `#000000`
160-- Text: `#ffffff`
161-- Border: `1px solid #000000`
162-- Radius: `50px`, Padding: `7px 16px`
163-- Font: 14px, weight 600
164-- Used on the top-of-page join strip and similar conversion moments
84+**Primary Filled:**
85+```
86+bg-spot-green text-white rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition
87+```
16588
166-**4. Dark Outlined — "Sign in"**
89+**Primary Outlined:**
90+```
91+border border-spot-outline text-spot-text rounded-pill px-4 py-1.5 text-xs font-bold uppercase tracking-button hover:border-spot-text transition
92+```
16793
168-- Background: transparent
169-- Text: `rgba(0, 0, 0, 0.87)` (Text Black)
170-- Border: `1px solid rgba(0, 0, 0, 0.87)`
171-- Radius: `50px`, Padding: `7px 16px`
172-- Font: 14px, weight 600
94+### Cards
17395
174-**5. Green-on-Green Inverted — "See the spring menu"**
96+`rounded-xl` (12px) radius, `shadow-spot` elevation, `bg-spot-surface` background.
17597
176-- Background: `#ffffff`
177-- Text: `#00754A`
178-- Border: `1px solid #ffffff`
179-- 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
98+```
99+bg-spot-surface rounded-xl p-4 shadow-spot hover:bg-spot-hover-50 transition
100+```
180101
181-**6. Outlined on Dark — "Learn more / Order now"**
102+### Shadows
182103
183-- Background: transparent
184-- Text: `#ffffff`
185-- Border: `1px solid #ffffff`
186-- Used on dark-green feature bands for secondary action paired with a white filled CTA
187-
188-**7. Consent Agree (dark-green variant)**
189-
190-- Background: `rgb(0, 130, 72)` (a specific variant green used in the cookie-consent module)
191-- Text: `#ffffff`
192-- No border, `50px` radius, `7px 16px` padding, 14px / weight 400
193-- Slightly brighter than Green Accent — reserved for the consent-banner Agree action
194-
195-**8. Frap — Floating Circular Order Button**
196-
197-- Background: `#00754A` (Green Accent)
198-- Icon: `#ffffff`
199-- Size: `5.6rem / 56px` (standard), `4rem / 40px` (mini variant)
200-- Radius: `50%` (full circle)
201-- Fixed bottom-right, `-0.8rem` touch offset for extra tap comfort
202-- Shadow stack: base `0 0 6px rgba(0,0,0,0.24)` + ambient `0 8px 12px rgba(0,0,0,0.14)`
203-- Active state: ambient shadow fades to `0 8px 12px rgba(0,0,0,0)`
204-- This is the product's signature elevation element — it floats over every scrolled surface
205-
206-**9. Full-width Feedback Tab — "Provide feedback"**
207-
208-- Background: `#00754A`
209-- Text: `#ffffff`
210-- Radius: `12px 12px 0px 0px` (top-rounded only)
211-- Padding: `8px 16px`
212-- Font: 14px, weight 400
213-- Positioned fixed bottom-right-inside, attached to the viewport edge
214-
215-### Cards & Containers
216-
217-**Content Card (default)**
218-
219-- Background: `#ffffff` (`--cardBackgroundColor`)
220-- Radius: `12px` (`--cardBorderRadius`)
221-- Shadow: `0px 0px .5px 0px rgba(0,0,0,0.14), 0px 1px 1px 0px rgba(0,0,0,0.24)` (`--cardBoxShadow`)
222-- Used for: feature cards, menu-item tiles, reward-status panels
223-
224-**Gift Card Tile**
225-
226-- Background: illustrated photography fills the card (no solid bg)
227-- Radius: similar to cards (`~12px`, slightly tighter on corners)
228-- Shadow: lighter than default card — these are treated like physical cards laid on the canvas
229-- Labeled by category above the card grid (Spring, Thank You, Birthday, Celebration, Mother's Day, Appreciation, Encouragement, Milestones, Anytime)
230-
231-**Rewards Status Cards (Rewards page signature)**
232-
233-- Three-column grid: Bronze / Gold / Silver-ish — each a dark-green (`#1E3932`) panel with:
234- - Colored gradient/color header ring
235- - Numbered "Level" badge
236- - Status title in large SoDoSans weight 600
237- - Stars / benefits list in white/translucent-white text
238- - Bottom "As you earn more stars…" progression caption
239-
240-**Partnership Card (Rewards)**
241-
242-- Background: `#faf6ee` (Gold Lightest) warm-cream surface
243-- Content: partner logos ("SkyMiles", "Bonvoy") centered, with descriptive text below
244-- Radius and shadow follow default card spec
245-
246-**Dropdown Menu (Account dropdown, top-nav)**
247-
248-- Background: `#f9f9f9` (Neutral Cool)
249-- Menu items at `24px / weight 400` in Text Black
250-- No border — just background surface shift against white nav
251-
252-**Modal**
253-
254-- Padding: `2.4rem` (`--modalPadding`)
255-- Top padding: `8.8rem` (`--modalTopPadding`) — leaves room for close button / header
256-- Combined vertical padding: `11.2rem`
257-- Radius inherits from card spec (`12px`)
258-
259-### Inputs & Forms
260-
261-**Floating Label Input**
262-
263-- Label floats above the input border when focused/filled
264-- Desktop label font size: `1.9rem` default, animates to `1.4rem` when active
265-- Mobile label font size: `1.6rem` default, animates to `1.3rem` active
266-- Label horizontal offset: `12px` from left
267-- Active label translate: up to `-12px` with `-50%` Y translation
268-- Field padding: `12px`
269-- Form horizontal padding: `1.6rem`
270-- Validation: valid-field gets `rgba(green-light, 0.33)` tint; invalid-field gets `rgba(red, 0.05)` tint
271-- Transition: `0.3s option-label-marker-expansion cubic-bezier(0.32, 2.32, 0.61, 0.27)` on checked-input
272-
273-**Option Icon (checkbox/radio)**
274-
275-- Padding: `3px` inner
276-- Uses the checked-input cubic-bezier animation above (a slightly "springy" 2.32 overshoot curve)
104+| Token | Value | Use |
105+| -------------- | ---------------------------------------------------- | ------------ |
106+| `shadow-spot` | `0 0 0.5px rgba(0,0,0,0.14), 0 1px 1px rgba(0,0,0,0.24)` | Cards |
107+| `shadow-spot-heavy` | `0 0 6px rgba(0,0,0,0.24), 0 8px 12px rgba(0,0,0,0.14)` | Modals, hero |
277108
278109 ### Navigation
279110
280-**Global Nav (top bar)**
281-
282-- Fixed position with progressive heights: `64px` xs → `72px` mobile → `83px` tablet → `99px` desktop
283-- 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
284-- Left: Starbucks wordmark logo, offsetting by `99px` (md) / `131px` (lg) from left edge
285-- Primary links inline in SoDoSans weight 400–600: Menu · Rewards · Gift Cards
286-- Right: Find a store link + Sign in (outlined) + Join now (black filled)
287-
288-**Sub-nav (second bar, e.g., Rewards internal)**
289-
290-- Height: `53px` (global subnav) / `48px` (internal subnav)
291-- Typically horizontal tab group beneath the global nav
292-
293-**Mobile Nav**
294-
295-- Collapses to a hamburger drawer below tablet breakpoint
296-- Frap floating button persists at bottom-right regardless of nav state
297-
298-### Image Treatment
299-
300-- **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`)
301-- **Gift card illustrations**: Each card is a distinct illustrated photograph (painted-feel, hand-drawn-looking, warm color palette). Never generic generated graphics.
302-- **Rewards ceremony imagery**: Photographs of Starbucks Rewards App screens held in-hand, angled compositions — product-in-context photography.
303-- **Menu thumbnails**: Square or 4:3 product photography with clean white/cream backdrops, slight soft drop-shadow around the glass.
304-- **Image fade-in**: `opacity 0.3s ease-in` transition on image load (`--imageFadeTransition`).
305-
306-### Feature Band (dark-green hero strip)
307-
308-Full-width `#1E3932` (House Green) band with:
309-
310-- Left: white headline + subhead + CTA row
311-- Right: product photography or illustration
312-- Split ratio ~40/60 or 50/50 depending on section
313-- White text throughout with `rgba(255,255,255,0.70)` for secondary copy
314-- CTAs follow Green-on-Green Inverted (white filled) + Outlined on Dark (white outline) pairing
315-
316-### Expander / Accordion
317-
318-- Duration: `300ms` (`--expanderDuration`)
319-- Timing curve: `cubic-bezier(0.25, 0.46, 0.45, 0.94)` — a measured ease-out
320-- Used for FAQ sections on Rewards and gift page
321-
322-### Cookie Consent Module
323-
324-Dark-green modal card at top of page with "Agree" (green-filled) and "Manage preferences" (outlined) buttons. Appears on first visit; dismissible.
325-
326-### Product Detail Components (PDP signature cluster)
327-
328-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.
329-
330-**Size Options Selector**
331-
332-- Horizontal row of 4 cup-icon buttons (Tall / Grande / Venti / Trenta)
333-- Each item: cup silhouette icon on top, size name below (16/700 in Starbucks-Green), fluid-ounce caption (13/400 in Text Black Soft)
334-- Active state: a green circular ring outline (`2px solid #00754A`) around the selected cup icon
335-- Inactive: no ring, same typography
336-- Full-width row, equal spacing
337-- Radius of container: `12px` or flat; individual icons are `50%` circular
338-- Padding: `16px 24px` internal
339-
340-**Add-in / Milk Select (outlined rectangle)**
341-
342-- Background: `#ffffff`
343-- Border: `1px solid #d6dbde` (Input Border)
344-- Radius: `4px`
345-- Full-width in its column
346-- Floating label above top border: "Add-ins" / "Milk" / "Add-ins" — 13/700 in Text Black, uppercase, `0.325px` letter-spacing
347-- Value displayed centered (e.g., "Ice", "Coconut", "Strawberry Fruit Inclusions scoop"): 16/400 Text Black
348-- Chevron-down icon right side in Text Black Soft
349-- Focus: border shifts to Green Accent (`#00754A`)
350-
351-**Numeric Stepper**
352-
353-- Embedded inside an Add-in row when a quantity is required (e.g., Strawberry Fruit Inclusions scoop)
354-- `−` minus button + count number + `+` plus button, all inline right of the label
355-- Buttons: circular `32×32px` with `1px solid #d6dbde` border, neutral gray icon
356-- Count number: 16/700 Text Black centered
357-
358-**Customize Button**
359-
360-- Background: `#ffffff`
361-- Text: `#00754A` (Green Accent)
362-- Border: `1.5px solid #00754A`
363-- Radius: `50px` (full pill)
364-- Padding: `14px 40px` (generously larger than default pills — this is a secondary primary action)
365-- Label: "Customize" with a gold sparkle ✨ icon inset left
366-- Used for: entering the drink-customization flow after size/milk selection
367-
368-**Add to Order Button (PDP)**
369-
370-- Background: `#00754A` (Green Accent)
371-- Text: `#ffffff`
372-- Radius: `50px`
373-- Padding: `14px 32px`
374-- Pinned top-right of product card and/or aligned right within the store-availability band
375-- Same scale(0.95) active behavior as other primary CTAs
376-
377-**Rewards Cost Pill — "200★ item"**
378-
379-- Background: transparent
380-- Border: `1px solid #cba258` (Gold)
381-- Text: `#cba258` (Gold)
382-- Radius: `50px` (full pill)
383-- Padding: `4px 12px`
384-- Content: "200★ item" where `★` is a small filled star glyph — indicates the Rewards Stars required to redeem this item
385-- Font: Proxima Nova 13/700 with `0.5px` letter-spacing
386-- Used only on products that are Rewards-redeemable
387-
388-**Product Description Band**
389-
390-- Full-width dark-green band (`#1E3932` House Green)
391-- Contains top-to-bottom:
392- 1. Rewards Cost Pill (gold) if applicable
393- 2. Product description body copy in white (16/400/1.5)
394- 3. Nutritional summary inline ("140 calories, 25g sugar, 2.5g fat") with info-icon tooltip — 14/700 white
395- 4. "Full nutrition & ingredients list" outlined-white-on-green pill button
396-- Padding: `32px` vertical
397-- Appears beneath the primary product header band
398-
399-**Ingredients / Nutrition Table**
400-
401-- Two-column layout on the Nutrition page
402-- Left column: "Ingredients" header + list or "Not available for this item" placeholder text block with an explanatory paragraph in Text Black Soft 14/400
403-- Right column: "Nutrition" header + label/value rows
404-- 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
405-- Footnote for caffeine/asterisk markers in 13/400 Text Black Soft at the bottom
406-- Reusable pattern for nutrition facts regulation-compliant tables
407-
408-**Store Availability Selector**
409-
410-- Appears on dark-green feature band above the size-options row
411-- Full-width rounded rectangle with transparent-white interior
412-- Text: "For item availability, choose a store" in white, 14/400
413-- Right side: chevron-down affordance + shopping-bag SVG icon in white outline
414-- Radius: `4px`
415-- Height: ~48px
416-
417-**PDP Breadcrumb**
418-
419-- "Menu / Refreshers / Pink Energy Drink" trail above the product title
420-- Separator: `/` slash character in Text Black Soft
421-- Current page is unlinked, prior pages are underlined green-accent links
422-- Font: 14/400 Proxima Nova
423-- Appears on all PDP pages
424-
425-**Back Chevron Link (PDP nutrition / detail sub-pages)**
426-
427-- "← Back" text link above section headings on the nutrition page
428-- Text in Green Accent (`#00754A`) 14/700 Proxima Nova
429-- Left chevron `<` in the same green
430-- Alternative to full breadcrumb on deep sub-pages
431-
432-## 5. Layout Principles
433-
434-### Spacing System
435-
436-Rem-based semantic scale (anchored `1rem = 10px`):
437-
438-| Token | Rem | Pixels | Typical Use |
439-| ----------- | -------- | ------ | ----------------------------------------- |
440-| `--space-1` | `0.4rem` | 4px | Tightest inline padding |
441-| `--space-2` | `0.8rem` | 8px | Small gap, button vertical padding |
442-| `--space-3` | `1.6rem` | 16px | Default — card padding, outer gutter xs |
443-| `--space-4` | `2.4rem` | 24px | Section inner spacing, outer gutter md |
444-| `--space-5` | `3.2rem` | 32px | Major between-section spacing |
445-| `--space-6` | `4rem` | 40px | Large gaps, outer gutter lg, header crate |
446-| `--space-7` | `4.8rem` | 48px | Section-to-section spacing |
447-| `--space-8` | `5.6rem` | 56px | Very large breathing — Frap height |
448-| `--space-9` | `6.4rem` | 64px | Widest section padding |
449-
450-**Gutter tokens:**
451-
452-- `--outerGutter: 1.6rem` (16px, default / mobile)
453-- `--outerGutterMedium: 2.4rem` (24px, tablet)
454-- `--outerGutterLarge: 4.0rem` (40px, desktop)
455-
456-**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.
457-
458-### Grid & Container
459-
460-- Column width scale: `--columnWidthSmall: 343px` / `Medium: 500px` / `Large: 720px` / `XLarge: 1440px`
461-- Gift-card grid uses a 3-5-up responsive grid of `~343px` tiles
462-- Rewards status section: 3-up dark-green panels at `lg+` breakpoints
463-- Hero: asymmetric split 40% (image) / 60% (content) via `--headerCrateProportion` / `--contentCrateProportion`
464-
465-### Whitespace Philosophy
466-
467-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.
468-
469-### Border Radius Scale
470-
471-| Value | Use |
472-| --------------- | ----------------------------------------------------------------------------------- |
473-| `12px` | Cards, modals, menu-item tiles (`--cardBorderRadius`) |
474-| `12px 12px 0 0` | Full-width feedback tab (top-rounded only) |
475-| `50px` | All buttons — full-pill radius (`--buttonBorderRadius`) |
476-| `50%` | Circular icons, Frap floating button, avatar thumbnails |
477-| Specialty | `3.3333%/5.298%` elliptical for Starbucks-Visa-Card mockups (`--svcRoundedCorners`) |
478-
479-## 6. Depth & Elevation
480-
481-| Level | Treatment | Use |
482-| -------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------- |
483-| 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 |
484-| 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 |
485-| Frap Base | `0 0 6px rgba(0,0,0,0.24)` | Base halo around the floating circular CTA |
486-| Frap Ambient | `0 8px 12px rgba(0,0,0,0.14)` | Stacked directional ambient — floats the Frap forward |
487-| Gift Card | Light drop shadow around illustrated photograph | Physical-card feel for gift tiles |
488-| 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 |
489-
490-**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.
491-
492-### Decorative Depth
493-
494-- **No gradient system** — surfaces are solid color-block
495-- **Color-block banding** carries perceived depth (dark-green bands read as "recessed feature zones" between cream/white body sections)
496-- **SVG filter shadows** on Starbucks-Card visuals add a slight 3D physicality without a box-shadow
497-
498-## 7. Do's and Don'ts
499-
500-### Do
501-
502-- Use Neutral Warm (`#f2f0eb`) or Ceramic (`#edebe9`) as page canvas instead of pure white — the warm cream is the signature
503-- 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
504-- Keep tracking tight at `-0.01em` / `-0.16px` on SoDoSans across the whole system
505-- Use 50px full-pill radius on every button without exception
506-- Apply `transform: scale(0.95)` as the universal button active state
507-- Reserve Gold for Rewards-status ceremony moments only
508-- Use SoDoSans for nearly everything; switch to Lander Tall serif only for Rewards editorial headlines; reserve Kalam script for Careers "cup name" moments
509-- Layer 2–3 low-alpha shadows instead of one heavier drop shadow for elevation
510-- Use the Frap circular CTA as the persistent floating order entry on every shopping surface
511-- Let the cream canvas breathe between content cards — use whitespace, not dividers
512-
513-### Don't
514-
515-- Don't use pure white as the page canvas — the warm cream temperature is load-bearing
516-- Don't pick "one brand green" — the four-green system is intentional; using only `#006241` everywhere flattens the brand
517-- Don't use Gold as a general-purpose accent — it's a Rewards signal only
518-- Don't square the corners on buttons — the 50px pill is universal
519-- Don't introduce gradient fills — the system is color-block throughout
520-- Don't weight-contrast h1 and h2 by size — the hierarchy comes from weight + color (600 Starbucks-Green vs 400 Text Black)
521-- Don't use pure black for body text — `rgba(0,0,0,0.87)` matches the warm canvas
522-- Don't skip the `scale(0.95)` active feedback on buttons — it's a signature micro-interaction
523-- Don't stack single heavy shadows; always layer 2–3 low-alpha ones
524-- Don't introduce serifs or scripts into the main shopping flow — they belong to Rewards and Careers contexts respectively
525-
526-## 8. Responsive Behavior
527-
528-### Breakpoints
529-
530-Inferred from component width tokens and progressive nav heights:
531-
532-| Name | Width | Key Changes |
533-| ------- | ----------- | ------------------------------------------------------------------------------- |
534-| xs | < 480px | Global nav 64px; hamburger menu; single-column layouts; pill buttons full-width |
535-| Mobile | 480–767px | Global nav 72px; gift-card grid 2-up; card padding tightens |
536-| Tablet | 768–1023px | Global nav 83px; gift-card grid 3-up; hero split begins to appear |
537-| Desktop | 1024–1439px | Global nav 99px; gift-card grid 4-up; full asymmetric hero 40/60 |
538-| XLarge | 1440px+ | Content caps at `--columnWidthXLarge`; gift-card grid 5-up; extra cream margin |
539-
540-### Touch Targets
541-
542-- 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.
543-- Frap floating circular button at `56px` is well above minimum.
544-- Frap uses `--frapTouchOffset: calc(-1 * .8rem)` to extend tap area 8px beyond visual edge.
545-- 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.
546-
547-### Collapsing Strategy
548-
549-- **Global nav height scales progressively**: 64 → 72 → 83 → 99px across breakpoints, not a single value
550-- **Hero split collapses**: 40/60 asymmetric split → stacked (image top, content below) at mobile
551-- **Gift-card grid**: 5-up → 4-up → 3-up → 2-up → 1-up across breakpoints with adjusted card widths
552-- **Feature bands**: Stay full-width but text + imagery stack vertically on mobile
553-- **Outer gutter scales**: 16px → 24px → 40px as viewport grows
554-- **Rewards 3-column status panels**: Stack to single column on mobile
555-
556-### Image Behavior
557-
558-- Hero product photography crops tighter vertically on mobile; content becomes the visual anchor
559-- Gift-card illustrations preserve aspect ratio; card grid reflows
560-- `opacity 0.3s ease-in` fade-in transition on image load (prevents jarring pop-in)
561-- Rewards app-in-hand photography scales proportionally; never stretches
562-
563-## 9. Agent Prompt Guide
564-
565-### Quick Color Reference
566-
567-- Primary CTA: "Green Accent (`#00754A`)"
568-- Primary CTA text: "White (`#ffffff`)"
569-- Brand heading: "Starbucks Green (`#006241`)"
570-- Feature band / footer: "House Green (`#1E3932`)"
571-- Page canvas: "Neutral Warm (`#f2f0eb`)"
572-- Card canvas: "White (`#ffffff`)"
573-- Heading text on light: "Text Black (`rgba(0,0,0,0.87)`)"
574-- Body text on light: "Text Black Soft (`rgba(0,0,0,0.58)`)"
575-- Body text on dark-green: "Text White Soft (`rgba(255,255,255,0.70)`)"
576-- Rewards accent: "Gold (`#cba258`)"
577-- Rewards text: "Rewards Green (`#33433d`)"
578-- Destructive: "Red (`#c82014`)"
579-
580-### Example Component Prompts
581-
582-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."
111+- **Sidebar** (desktop): Fixed left, `w-60`, logo at top, nav links, user profile at bottom
112+- **Bottom nav** (mobile): Fixed bottom, 5-tab horizontal bar
113+- **Active link**: `bg-spot-hover text-spot-text font-bold`
583114
584-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."
115+### Forms
585116
586-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)`."
117+- Input fields: `bg-spot-hover rounded-pill px-5 py-2 text-sm focus:ring-2 focus:ring-spot-green`
118+- Textareas: `bg-spot-hover rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-spot-green`
119+- File inputs: native browser style with pill-styled file button
587120
588-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`."
121+### Badges / Tags
589122
590-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."
123+- Unread count: `bg-spot-green/20 text-spot-green px-2.5 py-0.5 rounded-full font-bold`
124+- Category pills: `bg-spot-hover text-spot-secondary px-4 py-1.5 rounded-full font-bold`
125+- Active category: `bg-spot-active-pill-bg text-spot-active-pill-text`
591126
592-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."
127+## 5. Layout
593128
594-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."
129+- **Content max-width:** `max-w-6xl` (72rem)
130+- **Sidebar:** `w-60` fixed left (desktop only)
131+- **Main content:** `lg:ml-60` offset with `px-4 lg:px-8 py-6`
132+- **Landing page:** Full-width (`w-full`) — no max-width wrapper
133+- **Footer:** `bg-spot-surface border-t border-spot-divider`
595134
596-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."
135+### Responsive Breakpoints
597136
598-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 &amp; ingredients list'. 32px vertical padding."
137+| Name | Width | Nav behavior |
138+| ------- | --------- | ----------------------------------- |
139+| Mobile | < 768px | Bottom tab nav, stacked layouts |
140+| Tablet | 768–1023px| Bottom nav, wider gutters |
141+| Desktop | 1024px+ | Sidebar nav, 3-column grids |
599142
600-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."
143+## 6. Tailwind Config
601144
602-### Iteration Guide
145+All custom colors live under the `spot` namespace in `tailwind.config.js`. CSS variables provide theme switching via `[data-theme]` attribute. Build output goes to `static/output.css` via `npx tailwindcss`.
603146
604-When refining existing screens generated with this design system:
147+## 7. Asset Pipeline
605148
606-1. Focus on ONE component at a time
607-2. Reference specific color names and hex codes from this document
608-3. Use natural language descriptions ("warm cream canvas," "four-tier green system") alongside exact values
609-4. Preserve the 50px pill + `scale(0.95)` active state universally
610-5. Check that greens are mapped to their correct role (Green Accent for CTA, Starbucks Green for heading, House Green for band)
611-6. Don't introduce gradients — the system is color-block
612-7. Keep SoDoSans tracking at `-0.01em` / `-0.16px` across the board
149+- **CSS build:** `make css` (minified) or `make css-watch` (dev with live reload)
150+- **Source:** `static/input.css` — contains `@tailwind` directives, CSS variables for themes, `@layer components` for article-body styles, and base utilities
151+- **Output:** `static/output.css` (gitignored, rebuilt on deploy)
152+- **Favicon:** `static/favicon.svg` — wheat stalk SVG on House Green background
153+- **Logo:** Inline SVG in base.html sidebar and index.html hero
613154
614-### Known Gaps
155+## 8. Page Structure
615156
616-- SoDoSans is a proprietary typeface not available on Google Fonts — when implementing publicly, use Inter or Manrope as a substitute and document the swap
617-- Lander Tall (Rewards serif) is also custom — substitute with Iowan Old Style, Lora, or Source Serif Pro
618-- 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
619-- Form error-state full styling (red border weight, icon placement) visible on the tint token but not exhaustively extracted
620-- Careers-page specific components (cup-name card, search radio grid) are referenced in token names but not covered by this extraction
621-- Starbucks Visa Card / Starbucks-Card (SVC) detailed mockup specs are hinted at by `--svcRoundedCorners` and `--svcShadowFilter` tokens but not fully documented
157+| Page | Layout | Key Features |
158+| -------------- | ------------------------------ | --------------------------------------- |
159+| Index (landing)| Full-width, no sidebar | Hero with mockup, feature cols, dark band, CTA |
160+| Login | Centered card | Bluesky + Atmosphere sign-in buttons |
161+| Dashboard | 2/3 + 1/3 grid | Articles + trending/recommendations sidebar |
162+| Articles | Full-width list | Keyboard nav (j/k/o/m), mark-all-read |
163+| Article Detail | `max-w-3xl` centered | Content, like/share/read buttons, annotations |
164+| Feeds | 2/3 + 1/3 grid | Feed list with categories + add/import sidebar |
165+| Trending | Full-width list | Like/annotation counts on each article |
166+| Discover | Mixed grid | Recommendations + people + browse all |
167+| Annotations | Full-width list | Filter by article URL, load more |
168+| Profile | `max-w-2xl` centered | Avatar, stats, feeds, annotations |
@@ -1,621 +1,168 @@
1-# Design System Inspired by Starbucks1+# Glean Design System
2 2
3-## 1. Visual Theme & Atmosphere3+Adapted from the Starbucks-inspired green palette. Warm, confident, and grounded in a four-tier green system with a dark/light theme switch.
4-
5-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.
6-
7-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.
8-
9-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.
10-
11-**Key Characteristics:**
12-
13-- Four-tier green brand system (Starbucks / Accent / House / Uplift) each mapped to a distinct surface role — not a single "brand green"
14-- Gold reserved for Rewards-status moments only; never a general-purpose accent
15-- Warm-neutral canvas (`#f2f0eb` / `#edebe9`) instead of cold white — references café materials
16-- Custom proprietary typeface (SoDoSans) with tight `-0.16px` letter-spacing as the universal voice
17-- Context-specific type switches: serif (Lander Tall) for Rewards, script (Kalam) for Careers cup-names
18-- Full-pill buttons (`50px` radius) universal, `scale(0.95)` active press the signature micro-interaction
19-- Floating "Frap" circular CTA (`56px`, Green Accent fill, layered shadow stack) — the product's signature elevation element
20-- Gift-card surfaces designed as **photographed physical product** — every card is a distinct illustrated photograph rather than a generated graphic
21-- 12px card radius + whisper-soft shadows keep content cards flat-plus-hint-of-lift
22-- Rem-based spacing scale anchored at 1.6rem (~16px) = `--space-3`, stepping to 6.4rem (~64px)
23-
24-**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.
25-
26-## 2. Color Palette & Roles
27-
28-**Source pages analyzed:** homepage, rewards, gift cards, product detail (Pink Energy Drink), product nutrition (Cold Brew).
29-
30-### Primary
31-
32-- **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.
33-- **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.
34-- **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.
35-- **Green Uplift** (`#2b5148`): A secondary mid-dark green used sparingly on decorative accents and dark-gradient moments.
36-- **Green Light** (`#d4e9e2`): A pale mint wash used for form-valid-state tints and light green utility surfaces.
37-
38-### Secondary & Accent
39-
40-- **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.
41-- **Gold Light** (`#dfc49d`): Softer gold for background washes on gold-tier sections.
42-- **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.
43-
44-### Surface & Background
45 4
46-- **White** (`#ffffff`): Primary card and modal surface. Also card fill on gift-card tiles.5+## 1. Visual Theme & Atmosphere
47-- **Neutral Cool** (`#f9f9f9`): Subtle cool-gray surface used on dropdown menus ("Account" dropdown), form-card wraps, and quiet utility containers.
48-- **Neutral Warm** (`#f2f0eb`): The warm cream **primary page canvas** for Rewards utility zones and hero bands.
49-- **Ceramic** (`#edebe9`): A slightly warmer/darker cream for zone separators, soft page-section washes, and Rewards partnership band.
50-- **Black** (`#000000`): Deep ink reserved for the dark top-of-page CTA strip ("Join now") and high-contrast top-nav sign-in buttons.
51-
52-### Neutrals & Text
53-
54-- **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.
55-- **Text Black Soft** (`rgba(0, 0, 0, 0.58)`): Secondary/metadata text on light surfaces.
56-- **Text White** (`rgba(255, 255, 255, 1)`): Primary heading/body text on dark green surfaces.
57-- **Text White Soft** (`rgba(255, 255, 255, 0.70)`): Secondary text on dark-green surfaces — footer link descriptions, caption text.
58-- **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.
59-
60-### Semantic & Accent
61-
62-- **Red** (`#c82014`): Error and destructive state (form invalid, destructive actions).
63-- **Yellow** (`#fbbc05`): Warning state, legacy brand touch.
64-- **Green Light** (`#d4e9e2` at 33% opacity = `hsl(160 32% 87% / 33%)`): Form valid-field tint background.
65-- **Red Tint** (`hsl(4 82% 43% / 5%)`): Invalid-field tint on forms.
66-
67-### Black / White Alpha Ladders
68-
69-Two parallel translucent scales for overlay and secondary-text use:
70-
71-- `rgba(0,0,0,0.06)` through `rgba(0,0,0,0.90)` in 10% steps — for dark overlays on light surfaces
72-- `rgba(255,255,255,0.10)` through `rgba(255,255,255,0.90)` in 10% steps — for light overlays on dark surfaces
73-
74-### Gradient System
75-
76-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.
77 6
78-## 3. Typography Rules7+Glean is a **warm, focused reading environment**. The canvas alternates between a deep forest green (dark mode) and a warm cream (light mode), with Green Accent (`#00754A`) anchoring all CTAs, links, and brand moments. The palette is deliberately not blue, not purple — it references natural, grounded tones.
79 8
80-### Font Family9+Typography uses **Inter** (Google Fonts) as the universal typeface, with tight `-0.01em` letter-spacing across the entire product. A single typeface, a single voice.
81 10
82-- **Primary:** `SoDoSans, "Helvetica Neue", Helvetica, Arial, sans-serif` — Starbucks' proprietary corporate typeface, used across nearly every surface11+Surfaces breathe through rounded geometry: pill buttons (`9999px`), `12px` card corners, and `50%` circular avatars. Shadows are whisper-soft dual-layers, never heavy. The system feels like a well-lit reading room.
83-- **Loading Fallback:** `"Helvetica Neue", Helvetica, Arial, sans-serif` — what users see before SoDoSans loads
84-- **Rewards Serif:** `"Lander Tall", "Iowan Old Style", Georgia, serif` — used on specific Rewards-page headline moments for a warm editorial feel
85-- **Careers Script:** `"Kalam", "Comic Sans MS", cursive` — used exclusively for Careers-page "cup name" decorative touches, referencing the hand-written names on Starbucks cups
86 12
87-No OpenType stylistic sets explicitly activated at `:root`.13+**Color-block rhythm (landing page):** Cream/forest hero → white card sections → House Green (`#1E3932`) feature band with white text → cream utility zone → House Green footer.
88 14
89-### Hierarchy15+## 2. Color Palette
90 16
91-| Role | Size | Weight | Line Height | Letter Spacing | Notes |17+### Primary Greens
92-| ------------------- | -------------- | ------- | --------------- | -------------- | -------------------------------------------- |
93-| Display (text-10) | 5.0rem / 80px | 400–600 | 1.2 | -0.16px | Largest Rewards/hero display |
94-| Jumbo (text-9) | 3.6rem / 58px | 400–600 | 1.2 | -0.16px | Secondary hero headings |
95-| Hero Large (text-8) | 2.8rem / 45px | 400–600 | 1.2–1.5 | -0.16px | Landing section headlines |
96-| H1 | 24px | 600 | 36px | -0.16px | Starbucks-Green primary heading |
97-| H2 | 24px | 400 | 36px | -0.16px | Regular-weight section title in Text Black |
98-| Body Large | 19px | 400–600 | 33.25px (~1.75) | -0.16px | Hero intro copy, feature-band body |
99-| Body (text-3) | 1.6rem / 16px | 400 | 1.5 (24px) | -0.01em | Default body copy |
100-| Small (text-2) | 1.4rem / ~14px | 400–600 | 1.5 | -0.01em | Button label, metadata, form labels |
101-| Micro (text-1) | 1.3rem / ~13px | 400 | 1.5 | -0.01em | Active float-label state, caption micro-copy |
102-| Button Label | 14–16px | 400–600 | 1.2 | -0.01em | All pill-button labels |
103 18
104-**Letter-spacing tokens:**19+| Name | Hex | Role |
20+| --------------- | --------- | ------------------------------------------------ |
21+| Green Accent | `#00754A` | CTAs, active states, link hovers, brand accent |
22+| Green Dark | `#006241` | Headings on landing page, stronger brand moments |
23+| House Green | `#1E3932` | Dark bands, footer, feature sections |
24+| Green Uplift | `#2b5148` | Decorative accents, mid-dark green |
25+| Green Light | `#d4e9e2` | Light green utility surfaces, valid-state tints |
105 26
106-- `letterSpacingNormal`: `-0.01em` (default — tight, characteristic)27+### Dark Theme (default)
107-- `letterSpacingLoose`: `0.1em` (emphasized caps)
108-- `letterSpacingLooser`: `0.15em` (uppercase-style labels, extreme emphasis)
109 28
110-**Line-height tokens:**29+| Token | Value | Use |
30+| ------------------ | ------------------------------ | ------------------------------------ |
31+| `--spot-bg` | `#0f1f1a` | Page background, sidebar |
32+| `--spot-surface` | `#152b24` | Card background |
33+| `--spot-hover` | `#1a362e` | Hover state, input background |
34+| `--spot-text` | `#ffffff` | Primary text |
35+| `--spot-secondary` | `rgba(255,255,255,0.70)` | Secondary/metadata text |
36+| `--spot-body` | `rgba(255,255,255,0.87)` | Body copy, article content |
37+| `--spot-muted` | `rgba(255,255,255,0.25)` | Disabled/tertiary text |
38+| `--spot-divider` | `rgba(255,255,255,0.08)` | Borders, dividers |
39+| `--spot-outline` | `rgba(255,255,255,0.20)` | Button borders, input borders |
111 40
112-- `lineHeightNormal`: `1.5` (body)41+### Light Theme
113-- `lineHeightCompact`: `1.2` (display/buttons)
114 42
115-### Principles43+| Token | Value | Use |
44+| ------------------ | ------------------------------ | ------------------------------------ |
45+| `--spot-bg` | `#f2f0eb` | Page canvas (warm cream) |
46+| `--spot-surface` | `#ffffff` | Card background |
47+| `--spot-hover` | `#edebe9` | Hover state (ceramic) |
48+| `--spot-text` | `rgba(0,0,0,0.87)` | Primary text (warm black) |
49+| `--spot-secondary` | `rgba(0,0,0,0.58)` | Secondary/metadata text |
50+| `--spot-body` | `rgba(0,0,0,0.70)` | Body copy |
51+| `--spot-muted` | `rgba(0,0,0,0.25)` | Disabled/tertiary text |
52+| `--spot-divider` | `rgba(0,0,0,0.08)` | Borders, dividers |
53+| `--spot-outline` | `rgba(0,0,0,0.15)` | Button borders, input borders |
116 54
117-- **Tight negative tracking (`-0.01em`)** is applied almost universally — the entire product reads slightly compressed, which gives SoDoSans its confident presence without feeling squeezed.55+### Semantic
118-- **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.
119-- **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.
120-- **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.
121-- **Body text never goes pure black** — it sits at `rgba(0,0,0,0.87)` to match the warm-neutral canvas temperature.
122 56
123-### Note on Font Substitutes57+| Name | Hex | Use |
58+| ----- | --------- | ---------------- |
59+| Red | `#c82014` | Errors, likes |
60+| Orange| `#ffa42b` | Ratings, warnings|
61+| Blue | `#539df5` | External links |
124 62
125-SoDoSans is proprietary to Starbucks (licensed from House Industries, not publicly available). Reasonable open-source substitutes:63+## 3. Typography
126 64
127-- **Inter** (Google Fonts) — similar humanist geometric proportions, wide weight range65+**Font:** Inter (Google Fonts), weights 400/500/600/700
128-- **Manrope** — slightly rounder, similar confident feel
129-- **Nunito Sans** — warmer, good for a "café" brand substitute
130 66
131-If substituting, verify the tight `-0.01em` / `-0.16px` tracking still reads well; some open-source fonts need `-0.005em` instead.67+**Global:** `letter-spacing: -0.01em` on body
132 68
133-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.69+| Role | Size | Weight | Tailwind Class |
70+| ------------- | ---------- | ------ | ------------------ |
71+| Page title | 24px | 700 | `text-2xl font-bold` |
72+| Section title | 18px | 600 | `text-lg font-semibold` |
73+| Body | 14px | 400 | `text-sm` |
74+| Small/meta | 12px | 400 | `text-xs` |
75+| Button label | 14px | 700 | `text-sm font-bold uppercase tracking-button` |
76+| Micro | 10px | 400 | `text-[10px]` |
134 77
135-## 4. Component Stylings78+## 4. Components
136 79
137 ### Buttons80 ### Buttons
138 81
139-**1. Primary Filled — "Explore our afternoon menu / Sign up for free"**82+All buttons use full-pill radius (`rounded-pill` = `9999px`).
140-
141-- Background: `#00754A` (Green Accent)
142-- Text: `#ffffff`
143-- Border: `1px solid #00754A`
144-- Radius: `50px` (full pill)
145-- Padding: `7px 16px`
146-- Font: SoDoSans, 16px, weight 600, letter-spacing `-0.01em`
147-- Active state: `transform: scale(0.95)` via `--buttonActiveScale`
148-- Transition: `all 0.2s ease`
149-
150-**2. Primary Outlined — "Give them a try / Start an order"**
151-
152-- Background: transparent
153-- Text: `#00754A` (Green Accent)
154-- Border: `1px solid #00754A`
155-- Same radius/padding/active/transition as Primary Filled
156-
157-**3. Black Filled — "Join now"**
158 83
159-- Background: `#000000`84+**Primary Filled:**
160-- Text: `#ffffff`85+```
161-- Border: `1px solid #000000`86+bg-spot-green text-white rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition
162-- Radius: `50px`, Padding: `7px 16px`87+```
163-- Font: 14px, weight 600
164-- Used on the top-of-page join strip and similar conversion moments
165 88
166-**4. Dark Outlined — "Sign in"**89+**Primary Outlined:**
90+```
91+border border-spot-outline text-spot-text rounded-pill px-4 py-1.5 text-xs font-bold uppercase tracking-button hover:border-spot-text transition
92+```
167 93
168-- Background: transparent94+### Cards
169-- Text: `rgba(0, 0, 0, 0.87)` (Text Black)
170-- Border: `1px solid rgba(0, 0, 0, 0.87)`
171-- Radius: `50px`, Padding: `7px 16px`
172-- Font: 14px, weight 600
173 95
174-**5. Green-on-Green Inverted — "See the spring menu"**96+`rounded-xl` (12px) radius, `shadow-spot` elevation, `bg-spot-surface` background.
175 97
176-- Background: `#ffffff`98+```
177-- Text: `#00754A`99+bg-spot-surface rounded-xl p-4 shadow-spot hover:bg-spot-hover-50 transition
178-- Border: `1px solid #ffffff`100+```
179-- 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
180 101
181-**6. Outlined on Dark — "Learn more / Order now"**102+### Shadows
182 103
183-- Background: transparent104+| Token | Value | Use |
184-- Text: `#ffffff`105+| -------------- | ---------------------------------------------------- | ------------ |
185-- Border: `1px solid #ffffff`106+| `shadow-spot` | `0 0 0.5px rgba(0,0,0,0.14), 0 1px 1px rgba(0,0,0,0.24)` | Cards |
186-- Used on dark-green feature bands for secondary action paired with a white filled CTA107+| `shadow-spot-heavy` | `0 0 6px rgba(0,0,0,0.24), 0 8px 12px rgba(0,0,0,0.14)` | Modals, hero |
187-
188-**7. Consent Agree (dark-green variant)**
189-
190-- Background: `rgb(0, 130, 72)` (a specific variant green used in the cookie-consent module)
191-- Text: `#ffffff`
192-- No border, `50px` radius, `7px 16px` padding, 14px / weight 400
193-- Slightly brighter than Green Accent — reserved for the consent-banner Agree action
194-
195-**8. Frap — Floating Circular Order Button**
196-
197-- Background: `#00754A` (Green Accent)
198-- Icon: `#ffffff`
199-- Size: `5.6rem / 56px` (standard), `4rem / 40px` (mini variant)
200-- Radius: `50%` (full circle)
201-- Fixed bottom-right, `-0.8rem` touch offset for extra tap comfort
202-- Shadow stack: base `0 0 6px rgba(0,0,0,0.24)` + ambient `0 8px 12px rgba(0,0,0,0.14)`
203-- Active state: ambient shadow fades to `0 8px 12px rgba(0,0,0,0)`
204-- This is the product's signature elevation element — it floats over every scrolled surface
205-
206-**9. Full-width Feedback Tab — "Provide feedback"**
207-
208-- Background: `#00754A`
209-- Text: `#ffffff`
210-- Radius: `12px 12px 0px 0px` (top-rounded only)
211-- Padding: `8px 16px`
212-- Font: 14px, weight 400
213-- Positioned fixed bottom-right-inside, attached to the viewport edge
214-
215-### Cards & Containers
216-
217-**Content Card (default)**
218-
219-- Background: `#ffffff` (`--cardBackgroundColor`)
220-- Radius: `12px` (`--cardBorderRadius`)
221-- Shadow: `0px 0px .5px 0px rgba(0,0,0,0.14), 0px 1px 1px 0px rgba(0,0,0,0.24)` (`--cardBoxShadow`)
222-- Used for: feature cards, menu-item tiles, reward-status panels
223-
224-**Gift Card Tile**
225-
226-- Background: illustrated photography fills the card (no solid bg)
227-- Radius: similar to cards (`~12px`, slightly tighter on corners)
228-- Shadow: lighter than default card — these are treated like physical cards laid on the canvas
229-- Labeled by category above the card grid (Spring, Thank You, Birthday, Celebration, Mother's Day, Appreciation, Encouragement, Milestones, Anytime)
230-
231-**Rewards Status Cards (Rewards page signature)**
232-
233-- Three-column grid: Bronze / Gold / Silver-ish — each a dark-green (`#1E3932`) panel with:
234- - Colored gradient/color header ring
235- - Numbered "Level" badge
236- - Status title in large SoDoSans weight 600
237- - Stars / benefits list in white/translucent-white text
238- - Bottom "As you earn more stars…" progression caption
239-
240-**Partnership Card (Rewards)**
241-
242-- Background: `#faf6ee` (Gold Lightest) warm-cream surface
243-- Content: partner logos ("SkyMiles", "Bonvoy") centered, with descriptive text below
244-- Radius and shadow follow default card spec
245-
246-**Dropdown Menu (Account dropdown, top-nav)**
247-
248-- Background: `#f9f9f9` (Neutral Cool)
249-- Menu items at `24px / weight 400` in Text Black
250-- No border — just background surface shift against white nav
251-
252-**Modal**
253-
254-- Padding: `2.4rem` (`--modalPadding`)
255-- Top padding: `8.8rem` (`--modalTopPadding`) — leaves room for close button / header
256-- Combined vertical padding: `11.2rem`
257-- Radius inherits from card spec (`12px`)
258-
259-### Inputs & Forms
260-
261-**Floating Label Input**
262-
263-- Label floats above the input border when focused/filled
264-- Desktop label font size: `1.9rem` default, animates to `1.4rem` when active
265-- Mobile label font size: `1.6rem` default, animates to `1.3rem` active
266-- Label horizontal offset: `12px` from left
267-- Active label translate: up to `-12px` with `-50%` Y translation
268-- Field padding: `12px`
269-- Form horizontal padding: `1.6rem`
270-- Validation: valid-field gets `rgba(green-light, 0.33)` tint; invalid-field gets `rgba(red, 0.05)` tint
271-- Transition: `0.3s option-label-marker-expansion cubic-bezier(0.32, 2.32, 0.61, 0.27)` on checked-input
272-
273-**Option Icon (checkbox/radio)**
274-
275-- Padding: `3px` inner
276-- Uses the checked-input cubic-bezier animation above (a slightly "springy" 2.32 overshoot curve)
277 108
278 ### Navigation109 ### Navigation
279 110
280-**Global Nav (top bar)**111+- **Sidebar** (desktop): Fixed left, `w-60`, logo at top, nav links, user profile at bottom
281-112+- **Bottom nav** (mobile): Fixed bottom, 5-tab horizontal bar
282-- Fixed position with progressive heights: `64px` xs → `72px` mobile → `83px` tablet → `99px` desktop113+- **Active link**: `bg-spot-hover text-spot-text font-bold`
283-- 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
284-- Left: Starbucks wordmark logo, offsetting by `99px` (md) / `131px` (lg) from left edge
285-- Primary links inline in SoDoSans weight 400–600: Menu · Rewards · Gift Cards
286-- Right: Find a store link + Sign in (outlined) + Join now (black filled)
287-
288-**Sub-nav (second bar, e.g., Rewards internal)**
289-
290-- Height: `53px` (global subnav) / `48px` (internal subnav)
291-- Typically horizontal tab group beneath the global nav
292-
293-**Mobile Nav**
294-
295-- Collapses to a hamburger drawer below tablet breakpoint
296-- Frap floating button persists at bottom-right regardless of nav state
297-
298-### Image Treatment
299-
300-- **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`)
301-- **Gift card illustrations**: Each card is a distinct illustrated photograph (painted-feel, hand-drawn-looking, warm color palette). Never generic generated graphics.
302-- **Rewards ceremony imagery**: Photographs of Starbucks Rewards App screens held in-hand, angled compositions — product-in-context photography.
303-- **Menu thumbnails**: Square or 4:3 product photography with clean white/cream backdrops, slight soft drop-shadow around the glass.
304-- **Image fade-in**: `opacity 0.3s ease-in` transition on image load (`--imageFadeTransition`).
305-
306-### Feature Band (dark-green hero strip)
307-
308-Full-width `#1E3932` (House Green) band with:
309-
310-- Left: white headline + subhead + CTA row
311-- Right: product photography or illustration
312-- Split ratio ~40/60 or 50/50 depending on section
313-- White text throughout with `rgba(255,255,255,0.70)` for secondary copy
314-- CTAs follow Green-on-Green Inverted (white filled) + Outlined on Dark (white outline) pairing
315-
316-### Expander / Accordion
317-
318-- Duration: `300ms` (`--expanderDuration`)
319-- Timing curve: `cubic-bezier(0.25, 0.46, 0.45, 0.94)` — a measured ease-out
320-- Used for FAQ sections on Rewards and gift page
321-
322-### Cookie Consent Module
323-
324-Dark-green modal card at top of page with "Agree" (green-filled) and "Manage preferences" (outlined) buttons. Appears on first visit; dismissible.
325-
326-### Product Detail Components (PDP signature cluster)
327-
328-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.
329-
330-**Size Options Selector**
331-
332-- Horizontal row of 4 cup-icon buttons (Tall / Grande / Venti / Trenta)
333-- Each item: cup silhouette icon on top, size name below (16/700 in Starbucks-Green), fluid-ounce caption (13/400 in Text Black Soft)
334-- Active state: a green circular ring outline (`2px solid #00754A`) around the selected cup icon
335-- Inactive: no ring, same typography
336-- Full-width row, equal spacing
337-- Radius of container: `12px` or flat; individual icons are `50%` circular
338-- Padding: `16px 24px` internal
339-
340-**Add-in / Milk Select (outlined rectangle)**
341-
342-- Background: `#ffffff`
343-- Border: `1px solid #d6dbde` (Input Border)
344-- Radius: `4px`
345-- Full-width in its column
346-- Floating label above top border: "Add-ins" / "Milk" / "Add-ins" — 13/700 in Text Black, uppercase, `0.325px` letter-spacing
347-- Value displayed centered (e.g., "Ice", "Coconut", "Strawberry Fruit Inclusions scoop"): 16/400 Text Black
348-- Chevron-down icon right side in Text Black Soft
349-- Focus: border shifts to Green Accent (`#00754A`)
350-
351-**Numeric Stepper**
352-
353-- Embedded inside an Add-in row when a quantity is required (e.g., Strawberry Fruit Inclusions scoop)
354-- `−` minus button + count number + `+` plus button, all inline right of the label
355-- Buttons: circular `32×32px` with `1px solid #d6dbde` border, neutral gray icon
356-- Count number: 16/700 Text Black centered
357-
358-**Customize Button**
359-
360-- Background: `#ffffff`
361-- Text: `#00754A` (Green Accent)
362-- Border: `1.5px solid #00754A`
363-- Radius: `50px` (full pill)
364-- Padding: `14px 40px` (generously larger than default pills — this is a secondary primary action)
365-- Label: "Customize" with a gold sparkle ✨ icon inset left
366-- Used for: entering the drink-customization flow after size/milk selection
367-
368-**Add to Order Button (PDP)**
369-
370-- Background: `#00754A` (Green Accent)
371-- Text: `#ffffff`
372-- Radius: `50px`
373-- Padding: `14px 32px`
374-- Pinned top-right of product card and/or aligned right within the store-availability band
375-- Same scale(0.95) active behavior as other primary CTAs
376-
377-**Rewards Cost Pill — "200★ item"**
378-
379-- Background: transparent
380-- Border: `1px solid #cba258` (Gold)
381-- Text: `#cba258` (Gold)
382-- Radius: `50px` (full pill)
383-- Padding: `4px 12px`
384-- Content: "200★ item" where `★` is a small filled star glyph — indicates the Rewards Stars required to redeem this item
385-- Font: Proxima Nova 13/700 with `0.5px` letter-spacing
386-- Used only on products that are Rewards-redeemable
387-
388-**Product Description Band**
389-
390-- Full-width dark-green band (`#1E3932` House Green)
391-- Contains top-to-bottom:
392- 1. Rewards Cost Pill (gold) if applicable
393- 2. Product description body copy in white (16/400/1.5)
394- 3. Nutritional summary inline ("140 calories, 25g sugar, 2.5g fat") with info-icon tooltip — 14/700 white
395- 4. "Full nutrition & ingredients list" outlined-white-on-green pill button
396-- Padding: `32px` vertical
397-- Appears beneath the primary product header band
398-
399-**Ingredients / Nutrition Table**
400-
401-- Two-column layout on the Nutrition page
402-- Left column: "Ingredients" header + list or "Not available for this item" placeholder text block with an explanatory paragraph in Text Black Soft 14/400
403-- Right column: "Nutrition" header + label/value rows
404-- 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
405-- Footnote for caffeine/asterisk markers in 13/400 Text Black Soft at the bottom
406-- Reusable pattern for nutrition facts regulation-compliant tables
407-
408-**Store Availability Selector**
409-
410-- Appears on dark-green feature band above the size-options row
411-- Full-width rounded rectangle with transparent-white interior
412-- Text: "For item availability, choose a store" in white, 14/400
413-- Right side: chevron-down affordance + shopping-bag SVG icon in white outline
414-- Radius: `4px`
415-- Height: ~48px
416-
417-**PDP Breadcrumb**
418-
419-- "Menu / Refreshers / Pink Energy Drink" trail above the product title
420-- Separator: `/` slash character in Text Black Soft
421-- Current page is unlinked, prior pages are underlined green-accent links
422-- Font: 14/400 Proxima Nova
423-- Appears on all PDP pages
424-
425-**Back Chevron Link (PDP nutrition / detail sub-pages)**
426-
427-- "← Back" text link above section headings on the nutrition page
428-- Text in Green Accent (`#00754A`) 14/700 Proxima Nova
429-- Left chevron `<` in the same green
430-- Alternative to full breadcrumb on deep sub-pages
431-
432-## 5. Layout Principles
433-
434-### Spacing System
435-
436-Rem-based semantic scale (anchored `1rem = 10px`):
437-
438-| Token | Rem | Pixels | Typical Use |
439-| ----------- | -------- | ------ | ----------------------------------------- |
440-| `--space-1` | `0.4rem` | 4px | Tightest inline padding |
441-| `--space-2` | `0.8rem` | 8px | Small gap, button vertical padding |
442-| `--space-3` | `1.6rem` | 16px | Default — card padding, outer gutter xs |
443-| `--space-4` | `2.4rem` | 24px | Section inner spacing, outer gutter md |
444-| `--space-5` | `3.2rem` | 32px | Major between-section spacing |
445-| `--space-6` | `4rem` | 40px | Large gaps, outer gutter lg, header crate |
446-| `--space-7` | `4.8rem` | 48px | Section-to-section spacing |
447-| `--space-8` | `5.6rem` | 56px | Very large breathing — Frap height |
448-| `--space-9` | `6.4rem` | 64px | Widest section padding |
449-
450-**Gutter tokens:**
451-
452-- `--outerGutter: 1.6rem` (16px, default / mobile)
453-- `--outerGutterMedium: 2.4rem` (24px, tablet)
454-- `--outerGutterLarge: 4.0rem` (40px, desktop)
455-
456-**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.
457-
458-### Grid & Container
459-
460-- Column width scale: `--columnWidthSmall: 343px` / `Medium: 500px` / `Large: 720px` / `XLarge: 1440px`
461-- Gift-card grid uses a 3-5-up responsive grid of `~343px` tiles
462-- Rewards status section: 3-up dark-green panels at `lg+` breakpoints
463-- Hero: asymmetric split 40% (image) / 60% (content) via `--headerCrateProportion` / `--contentCrateProportion`
464-
465-### Whitespace Philosophy
466-
467-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.
468-
469-### Border Radius Scale
470-
471-| Value | Use |
472-| --------------- | ----------------------------------------------------------------------------------- |
473-| `12px` | Cards, modals, menu-item tiles (`--cardBorderRadius`) |
474-| `12px 12px 0 0` | Full-width feedback tab (top-rounded only) |
475-| `50px` | All buttons — full-pill radius (`--buttonBorderRadius`) |
476-| `50%` | Circular icons, Frap floating button, avatar thumbnails |
477-| Specialty | `3.3333%/5.298%` elliptical for Starbucks-Visa-Card mockups (`--svcRoundedCorners`) |
478-
479-## 6. Depth & Elevation
480-
481-| Level | Treatment | Use |
482-| -------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------- |
483-| 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 |
484-| 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 |
485-| Frap Base | `0 0 6px rgba(0,0,0,0.24)` | Base halo around the floating circular CTA |
486-| Frap Ambient | `0 8px 12px rgba(0,0,0,0.14)` | Stacked directional ambient — floats the Frap forward |
487-| Gift Card | Light drop shadow around illustrated photograph | Physical-card feel for gift tiles |
488-| 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 |
489-
490-**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.
491-
492-### Decorative Depth
493-
494-- **No gradient system** — surfaces are solid color-block
495-- **Color-block banding** carries perceived depth (dark-green bands read as "recessed feature zones" between cream/white body sections)
496-- **SVG filter shadows** on Starbucks-Card visuals add a slight 3D physicality without a box-shadow
497-
498-## 7. Do's and Don'ts
499-
500-### Do
501-
502-- Use Neutral Warm (`#f2f0eb`) or Ceramic (`#edebe9`) as page canvas instead of pure white — the warm cream is the signature
503-- 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
504-- Keep tracking tight at `-0.01em` / `-0.16px` on SoDoSans across the whole system
505-- Use 50px full-pill radius on every button without exception
506-- Apply `transform: scale(0.95)` as the universal button active state
507-- Reserve Gold for Rewards-status ceremony moments only
508-- Use SoDoSans for nearly everything; switch to Lander Tall serif only for Rewards editorial headlines; reserve Kalam script for Careers "cup name" moments
509-- Layer 2–3 low-alpha shadows instead of one heavier drop shadow for elevation
510-- Use the Frap circular CTA as the persistent floating order entry on every shopping surface
511-- Let the cream canvas breathe between content cards — use whitespace, not dividers
512-
513-### Don't
514-
515-- Don't use pure white as the page canvas — the warm cream temperature is load-bearing
516-- Don't pick "one brand green" — the four-green system is intentional; using only `#006241` everywhere flattens the brand
517-- Don't use Gold as a general-purpose accent — it's a Rewards signal only
518-- Don't square the corners on buttons — the 50px pill is universal
519-- Don't introduce gradient fills — the system is color-block throughout
520-- Don't weight-contrast h1 and h2 by size — the hierarchy comes from weight + color (600 Starbucks-Green vs 400 Text Black)
521-- Don't use pure black for body text — `rgba(0,0,0,0.87)` matches the warm canvas
522-- Don't skip the `scale(0.95)` active feedback on buttons — it's a signature micro-interaction
523-- Don't stack single heavy shadows; always layer 2–3 low-alpha ones
524-- Don't introduce serifs or scripts into the main shopping flow — they belong to Rewards and Careers contexts respectively
525-
526-## 8. Responsive Behavior
527-
528-### Breakpoints
529-
530-Inferred from component width tokens and progressive nav heights:
531-
532-| Name | Width | Key Changes |
533-| ------- | ----------- | ------------------------------------------------------------------------------- |
534-| xs | < 480px | Global nav 64px; hamburger menu; single-column layouts; pill buttons full-width |
535-| Mobile | 480–767px | Global nav 72px; gift-card grid 2-up; card padding tightens |
536-| Tablet | 768–1023px | Global nav 83px; gift-card grid 3-up; hero split begins to appear |
537-| Desktop | 1024–1439px | Global nav 99px; gift-card grid 4-up; full asymmetric hero 40/60 |
538-| XLarge | 1440px+ | Content caps at `--columnWidthXLarge`; gift-card grid 5-up; extra cream margin |
539-
540-### Touch Targets
541-
542-- 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.
543-- Frap floating circular button at `56px` is well above minimum.
544-- Frap uses `--frapTouchOffset: calc(-1 * .8rem)` to extend tap area 8px beyond visual edge.
545-- 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.
546-
547-### Collapsing Strategy
548-
549-- **Global nav height scales progressively**: 64 → 72 → 83 → 99px across breakpoints, not a single value
550-- **Hero split collapses**: 40/60 asymmetric split → stacked (image top, content below) at mobile
551-- **Gift-card grid**: 5-up → 4-up → 3-up → 2-up → 1-up across breakpoints with adjusted card widths
552-- **Feature bands**: Stay full-width but text + imagery stack vertically on mobile
553-- **Outer gutter scales**: 16px → 24px → 40px as viewport grows
554-- **Rewards 3-column status panels**: Stack to single column on mobile
555-
556-### Image Behavior
557-
558-- Hero product photography crops tighter vertically on mobile; content becomes the visual anchor
559-- Gift-card illustrations preserve aspect ratio; card grid reflows
560-- `opacity 0.3s ease-in` fade-in transition on image load (prevents jarring pop-in)
561-- Rewards app-in-hand photography scales proportionally; never stretches
562-
563-## 9. Agent Prompt Guide
564-
565-### Quick Color Reference
566-
567-- Primary CTA: "Green Accent (`#00754A`)"
568-- Primary CTA text: "White (`#ffffff`)"
569-- Brand heading: "Starbucks Green (`#006241`)"
570-- Feature band / footer: "House Green (`#1E3932`)"
571-- Page canvas: "Neutral Warm (`#f2f0eb`)"
572-- Card canvas: "White (`#ffffff`)"
573-- Heading text on light: "Text Black (`rgba(0,0,0,0.87)`)"
574-- Body text on light: "Text Black Soft (`rgba(0,0,0,0.58)`)"
575-- Body text on dark-green: "Text White Soft (`rgba(255,255,255,0.70)`)"
576-- Rewards accent: "Gold (`#cba258`)"
577-- Rewards text: "Rewards Green (`#33433d`)"
578-- Destructive: "Red (`#c82014`)"
579-
580-### Example Component Prompts
581-
582-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."
583 114
584-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."115+### Forms
585 116
586-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)`."117+- Input fields: `bg-spot-hover rounded-pill px-5 py-2 text-sm focus:ring-2 focus:ring-spot-green`
118+- Textareas: `bg-spot-hover rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-spot-green`
119+- File inputs: native browser style with pill-styled file button
587 120
588-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`."121+### Badges / Tags
589 122
590-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."123+- Unread count: `bg-spot-green/20 text-spot-green px-2.5 py-0.5 rounded-full font-bold`
124+- Category pills: `bg-spot-hover text-spot-secondary px-4 py-1.5 rounded-full font-bold`
125+- Active category: `bg-spot-active-pill-bg text-spot-active-pill-text`
591 126
592-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."127+## 5. Layout
593 128
594-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."129+- **Content max-width:** `max-w-6xl` (72rem)
130+- **Sidebar:** `w-60` fixed left (desktop only)
131+- **Main content:** `lg:ml-60` offset with `px-4 lg:px-8 py-6`
132+- **Landing page:** Full-width (`w-full`) — no max-width wrapper
133+- **Footer:** `bg-spot-surface border-t border-spot-divider`
595 134
596-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."135+### Responsive Breakpoints
597 136
598-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 &amp; ingredients list'. 32px vertical padding."137+| Name | Width | Nav behavior |
138+| ------- | --------- | ----------------------------------- |
139+| Mobile | < 768px | Bottom tab nav, stacked layouts |
140+| Tablet | 768–1023px| Bottom nav, wider gutters |
141+| Desktop | 1024px+ | Sidebar nav, 3-column grids |
599 142
600-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."143+## 6. Tailwind Config
601 144
602-### Iteration Guide145+All custom colors live under the `spot` namespace in `tailwind.config.js`. CSS variables provide theme switching via `[data-theme]` attribute. Build output goes to `static/output.css` via `npx tailwindcss`.
603 146
604-When refining existing screens generated with this design system:147+## 7. Asset Pipeline
605 148
606-1. Focus on ONE component at a time149+- **CSS build:** `make css` (minified) or `make css-watch` (dev with live reload)
607-2. Reference specific color names and hex codes from this document150+- **Source:** `static/input.css` — contains `@tailwind` directives, CSS variables for themes, `@layer components` for article-body styles, and base utilities
608-3. Use natural language descriptions ("warm cream canvas," "four-tier green system") alongside exact values151+- **Output:** `static/output.css` (gitignored, rebuilt on deploy)
609-4. Preserve the 50px pill + `scale(0.95)` active state universally152+- **Favicon:** `static/favicon.svg` — wheat stalk SVG on House Green background
610-5. Check that greens are mapped to their correct role (Green Accent for CTA, Starbucks Green for heading, House Green for band)153+- **Logo:** Inline SVG in base.html sidebar and index.html hero
611-6. Don't introduce gradients — the system is color-block
612-7. Keep SoDoSans tracking at `-0.01em` / `-0.16px` across the board
613 154
614-### Known Gaps155+## 8. Page Structure
615 156
616-- SoDoSans is a proprietary typeface not available on Google Fonts — when implementing publicly, use Inter or Manrope as a substitute and document the swap157+| Page | Layout | Key Features |
617-- Lander Tall (Rewards serif) is also custom — substitute with Iowan Old Style, Lora, or Source Serif Pro158+| -------------- | ------------------------------ | --------------------------------------- |
618-- 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 surface159+| Index (landing)| Full-width, no sidebar | Hero with mockup, feature cols, dark band, CTA |
619-- Form error-state full styling (red border weight, icon placement) visible on the tint token but not exhaustively extracted160+| Login | Centered card | Bluesky + Atmosphere sign-in buttons |
620-- Careers-page specific components (cup-name card, search radio grid) are referenced in token names but not covered by this extraction161+| Dashboard | 2/3 + 1/3 grid | Articles + trending/recommendations sidebar |
621-- Starbucks Visa Card / Starbucks-Card (SVC) detailed mockup specs are hinted at by `--svcRoundedCorners` and `--svcShadowFilter` tokens but not fully documented162+| Articles | Full-width list | Keyboard nav (j/k/o/m), mark-all-read |
163+| Article Detail | `max-w-3xl` centered | Content, like/share/read buttons, annotations |
164+| Feeds | 2/3 + 1/3 grid | Feed list with categories + add/import sidebar |
165+| Trending | Full-width list | Like/annotation counts on each article |
166+| Discover | Mixed grid | Recommendations + people + browse all |
167+| Annotations | Full-width list | Filter by article URL, load more |
168+| Profile | `max-w-2xl` centered | Avatar, stats, feeds, annotations |
modified internal/tmpl/annotations.html +1 -1
@@ -1,6 +1,6 @@
11 {{define "annotations.html"}}
22 <div class="flex items-center justify-between mb-6">
3- <h1 class="text-2xl font-bold font-title text-spot-text">Annotations</h1>
3+ <h1 class="text-2xl font-bold text-spot-text">Annotations</h1>
44 </div>
55
66 {{if .ArticleURL}}
@@ -1,6 +1,6 @@
1 {{define "annotations.html"}}1 {{define "annotations.html"}}
2 <div class="flex items-center justify-between mb-6">2 <div class="flex items-center justify-between mb-6">
3- <h1 class="text-2xl font-bold font-title text-spot-text">Annotations</h1>3+ <h1 class="text-2xl font-bold text-spot-text">Annotations</h1>
4 </div>4 </div>
5 5
6 {{if .ArticleURL}}6 {{if .ArticleURL}}
modified internal/tmpl/article_detail.html +3 -3
@@ -3,7 +3,7 @@
33 <a href="/articles" class="text-sm text-spot-secondary hover:text-spot-text mb-4 inline-block transition">&larr; Back to articles</a>
44
55 <article>
6- <h1 class="text-3xl font-bold font-title leading-tight">
6+ <h1 class="text-3xl font-bold leading-tight">
77 {{if .Article.URL.Valid}}<a href="{{.Article.URL.String}}" target="_blank" rel="noopener noreferrer" class="text-spot-text hover:text-spot-green transition">{{.Article.Title}}</a>
88 {{else}}<span class="text-spot-text">{{.Article.Title}}</span>{{end}}
99 </h1>
@@ -68,7 +68,7 @@
6868
6969 <form hx-post="/annotations/create" hx-target="#annotations-list" hx-swap="beforeend"
7070 hx-on::after-request="this.reset()"
71- class="bg-spot-surface rounded-lg shadow-spot p-4 mb-4 space-y-3">
71+ class="bg-spot-surface rounded-xl shadow-spot p-4 mb-4 space-y-3">
7272 {{csrfInput .CSRFToken}}
7373 <input type="hidden" name="feed_url" value="{{.Article.FeedURL}}">
7474 <input type="hidden" name="article_url" value="{{if .Article.URL.Valid}}{{.Article.URL.String}}{{end}}">
@@ -82,7 +82,7 @@
8282 <input type="text" name="tags" placeholder="Tags (comma separated)"
8383 class="flex-1 bg-spot-hover text-spot-text rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">
8484 </div>
85- <button type="submit" class="bg-spot-green text-spot-bg rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Annotate</button>
85+ <button type="submit" class="bg-spot-green text-white rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Annotate</button>
8686 </form>
8787
8888 <div id="annotations-list" class="space-y-3">
@@ -3,7 +3,7 @@
3 <a href="/articles" class="text-sm text-spot-secondary hover:text-spot-text mb-4 inline-block transition">&larr; Back to articles</a>3 <a href="/articles" class="text-sm text-spot-secondary hover:text-spot-text mb-4 inline-block transition">&larr; Back to articles</a>
4 4
5 <article>5 <article>
6- <h1 class="text-3xl font-bold font-title leading-tight">6+ <h1 class="text-3xl font-bold leading-tight">
7 {{if .Article.URL.Valid}}<a href="{{.Article.URL.String}}" target="_blank" rel="noopener noreferrer" class="text-spot-text hover:text-spot-green transition">{{.Article.Title}}</a>7 {{if .Article.URL.Valid}}<a href="{{.Article.URL.String}}" target="_blank" rel="noopener noreferrer" class="text-spot-text hover:text-spot-green transition">{{.Article.Title}}</a>
8 {{else}}<span class="text-spot-text">{{.Article.Title}}</span>{{end}}8 {{else}}<span class="text-spot-text">{{.Article.Title}}</span>{{end}}
9 </h1>9 </h1>
@@ -68,7 +68,7 @@
68 68
69 <form hx-post="/annotations/create" hx-target="#annotations-list" hx-swap="beforeend"69 <form hx-post="/annotations/create" hx-target="#annotations-list" hx-swap="beforeend"
70 hx-on::after-request="this.reset()"70 hx-on::after-request="this.reset()"
71- class="bg-spot-surface rounded-lg shadow-spot p-4 mb-4 space-y-3">71+ class="bg-spot-surface rounded-xl shadow-spot p-4 mb-4 space-y-3">
72 {{csrfInput .CSRFToken}}72 {{csrfInput .CSRFToken}}
73 <input type="hidden" name="feed_url" value="{{.Article.FeedURL}}">73 <input type="hidden" name="feed_url" value="{{.Article.FeedURL}}">
74 <input type="hidden" name="article_url" value="{{if .Article.URL.Valid}}{{.Article.URL.String}}{{end}}">74 <input type="hidden" name="article_url" value="{{if .Article.URL.Valid}}{{.Article.URL.String}}{{end}}">
@@ -82,7 +82,7 @@
82 <input type="text" name="tags" placeholder="Tags (comma separated)"82 <input type="text" name="tags" placeholder="Tags (comma separated)"
83 class="flex-1 bg-spot-hover text-spot-text rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">83 class="flex-1 bg-spot-hover text-spot-text rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">
84 </div>84 </div>
85- <button type="submit" class="bg-spot-green text-spot-bg rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Annotate</button>85+ <button type="submit" class="bg-spot-green text-white rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Annotate</button>
86 </form>86 </form>
87 87
88 <div id="annotations-list" class="space-y-3">88 <div id="annotations-list" class="space-y-3">
modified internal/tmpl/articles.html +1 -1
@@ -1,6 +1,6 @@
11 {{define "articles.html"}}
22 <div class="flex items-center justify-between mb-6">
3- <h1 class="text-2xl font-bold font-title text-spot-text">Articles</h1>
3+ <h1 class="text-2xl font-bold text-spot-text">Articles</h1>
44 <form hx-post="/articles/mark-all-read" hx-confirm="Mark all articles as read?">
55 {{csrfInput .CSRFToken}}
66 {{if .FeedURL}}<input type="hidden" name="feed" value="{{.FeedURL}}">{{end}}
@@ -1,6 +1,6 @@
1 {{define "articles.html"}}1 {{define "articles.html"}}
2 <div class="flex items-center justify-between mb-6">2 <div class="flex items-center justify-between mb-6">
3- <h1 class="text-2xl font-bold font-title text-spot-text">Articles</h1>3+ <h1 class="text-2xl font-bold text-spot-text">Articles</h1>
4 <form hx-post="/articles/mark-all-read" hx-confirm="Mark all articles as read?">4 <form hx-post="/articles/mark-all-read" hx-confirm="Mark all articles as read?">
5 {{csrfInput .CSRFToken}}5 {{csrfInput .CSRFToken}}
6 {{if .FeedURL}}<input type="hidden" name="feed" value="{{.FeedURL}}">{{end}}6 {{if .FeedURL}}<input type="hidden" name="feed" value="{{.FeedURL}}">{{end}}
modified internal/tmpl/base.html +3 -3
@@ -18,7 +18,7 @@
1818 <body class="bg-spot-bg text-spot-text min-h-screen flex">
1919 {{if .User}}
2020 <aside class="hidden lg:flex flex-col w-60 bg-spot-bg h-screen fixed left-0 top-0 px-3 py-4 z-20">
21- <a href="/" class="text-spot-green font-bold text-xl font-title tracking-tight mb-8 px-3 flex items-center gap-2">
21+ <a href="/" class="text-spot-green font-bold text-xl tracking-tight mb-8 px-3 flex items-center gap-2">
2222 <svg class="w-7 h-7" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
2323 <rect width="32" height="32" rx="8" fill="#00754A"/>
2424 <path d="M16 8 L16 22" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/>
@@ -116,7 +116,7 @@
116116 <div class="max-w-6xl mx-auto px-4 lg:px-8 py-8">
117117 <div class="hidden md:grid md:grid-cols-[auto_1fr_auto] md:gap-12 md:items-start">
118118 <div>
119- <a href="/" class="text-spot-green font-bold text-lg font-title tracking-tight">Glean</a>
119+ <a href="/" class="text-spot-green font-bold text-lg tracking-tight">Glean</a>
120120 <p class="text-xs text-spot-secondary mt-1 max-w-[200px]">A social RSS reader<br>on the AT Protocol.</p>
121121 </div>
122122 <div class="grid grid-cols-3 gap-8">
@@ -167,7 +167,7 @@
167167 </div>
168168
169169 <div class="md:hidden flex flex-col gap-6">
170- <a href="/" class="text-spot-green font-bold text-lg font-title tracking-tight">Glean</a>
170+ <a href="/" class="text-spot-green font-bold text-lg tracking-tight">Glean</a>
171171 <div class="grid grid-cols-2 gap-6">
172172 <div class="flex flex-col gap-1.5">
173173 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Browse</div>
@@ -18,7 +18,7 @@
18 <body class="bg-spot-bg text-spot-text min-h-screen flex">18 <body class="bg-spot-bg text-spot-text min-h-screen flex">
19 {{if .User}}19 {{if .User}}
20 <aside class="hidden lg:flex flex-col w-60 bg-spot-bg h-screen fixed left-0 top-0 px-3 py-4 z-20">20 <aside class="hidden lg:flex flex-col w-60 bg-spot-bg h-screen fixed left-0 top-0 px-3 py-4 z-20">
21- <a href="/" class="text-spot-green font-bold text-xl font-title tracking-tight mb-8 px-3 flex items-center gap-2">21+ <a href="/" class="text-spot-green font-bold text-xl tracking-tight mb-8 px-3 flex items-center gap-2">
22 <svg class="w-7 h-7" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">22 <svg class="w-7 h-7" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
23 <rect width="32" height="32" rx="8" fill="#00754A"/>23 <rect width="32" height="32" rx="8" fill="#00754A"/>
24 <path d="M16 8 L16 22" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/>24 <path d="M16 8 L16 22" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/>
@@ -116,7 +116,7 @@
116 <div class="max-w-6xl mx-auto px-4 lg:px-8 py-8">116 <div class="max-w-6xl mx-auto px-4 lg:px-8 py-8">
117 <div class="hidden md:grid md:grid-cols-[auto_1fr_auto] md:gap-12 md:items-start">117 <div class="hidden md:grid md:grid-cols-[auto_1fr_auto] md:gap-12 md:items-start">
118 <div>118 <div>
119- <a href="/" class="text-spot-green font-bold text-lg font-title tracking-tight">Glean</a>119+ <a href="/" class="text-spot-green font-bold text-lg tracking-tight">Glean</a>
120 <p class="text-xs text-spot-secondary mt-1 max-w-[200px]">A social RSS reader<br>on the AT Protocol.</p>120 <p class="text-xs text-spot-secondary mt-1 max-w-[200px]">A social RSS reader<br>on the AT Protocol.</p>
121 </div>121 </div>
122 <div class="grid grid-cols-3 gap-8">122 <div class="grid grid-cols-3 gap-8">
@@ -167,7 +167,7 @@
167 </div>167 </div>
168 168
169 <div class="md:hidden flex flex-col gap-6">169 <div class="md:hidden flex flex-col gap-6">
170- <a href="/" class="text-spot-green font-bold text-lg font-title tracking-tight">Glean</a>170+ <a href="/" class="text-spot-green font-bold text-lg tracking-tight">Glean</a>
171 <div class="grid grid-cols-2 gap-6">171 <div class="grid grid-cols-2 gap-6">
172 <div class="flex flex-col gap-1.5">172 <div class="flex flex-col gap-1.5">
173 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Browse</div>173 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Browse</div>
modified internal/tmpl/dashboard.html +4 -4
@@ -2,7 +2,7 @@
22 <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
33 <div class="lg:col-span-2">
44 <div class="flex items-center justify-between mb-6">
5- <h1 class="text-2xl font-bold font-title text-spot-text">Dashboard</h1>
5+ <h1 class="text-2xl font-bold text-spot-text">Dashboard</h1>
66 <div class="flex gap-4 text-sm">
77 <span class="text-spot-secondary"><strong class="text-spot-text">{{.UnreadCount}}</strong> unread</span>
88 <span class="text-spot-secondary"><strong class="text-spot-text">{{.SubscriptionCount}}</strong> feeds</span>
@@ -33,7 +33,7 @@
3333 </div>
3434 <div class="space-y-3">
3535 {{range .Trending}}
36- <a href="/articles/{{.ArticleID}}" class="block bg-spot-surface rounded-lg p-4 hover:bg-spot-hover-50 transition">
36+ <a href="/articles/{{.ArticleID}}" class="block bg-spot-surface rounded-xl p-4 hover:bg-spot-hover-50 transition">
3737 <div class="font-bold text-sm text-spot-text leading-tight">{{.Title}}</div>
3838 <div class="flex items-center gap-2 mt-1 text-xs text-spot-secondary">
3939 {{if .Author}}<span>{{.Author}}</span>{{end}}
@@ -57,7 +57,7 @@
5757 </div>
5858 <div class="space-y-3">
5959 {{range .PeopleRecommendations}}
60- <div class="bg-spot-surface rounded-lg p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">
60+ <div class="bg-spot-surface rounded-xl p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">
6161 {{if .avatar_url}}<img src="{{.avatar_url}}" class="w-10 h-10 rounded-full">{{end}}
6262 <div class="min-w-0 flex-1">
6363 <a href="/profile/{{.handle}}" class="font-bold text-spot-text hover:text-spot-green transition">@{{.handle}}</a>
@@ -91,7 +91,7 @@
9191 <input type="url" name="feed_url" placeholder="Feed URL"
9292 class="flex-1 bg-spot-hover text-spot-text rounded-pill px-5 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder"
9393 required>
94- <button type="submit" class="bg-spot-green text-spot-bg rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Add</button>
94+ <button type="submit" class="bg-spot-green text-white rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Add</button>
9595 </form>
9696 </div>
9797 </div>
@@ -2,7 +2,7 @@
2 <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">2 <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
3 <div class="lg:col-span-2">3 <div class="lg:col-span-2">
4 <div class="flex items-center justify-between mb-6">4 <div class="flex items-center justify-between mb-6">
5- <h1 class="text-2xl font-bold font-title text-spot-text">Dashboard</h1>5+ <h1 class="text-2xl font-bold text-spot-text">Dashboard</h1>
6 <div class="flex gap-4 text-sm">6 <div class="flex gap-4 text-sm">
7 <span class="text-spot-secondary"><strong class="text-spot-text">{{.UnreadCount}}</strong> unread</span>7 <span class="text-spot-secondary"><strong class="text-spot-text">{{.UnreadCount}}</strong> unread</span>
8 <span class="text-spot-secondary"><strong class="text-spot-text">{{.SubscriptionCount}}</strong> feeds</span>8 <span class="text-spot-secondary"><strong class="text-spot-text">{{.SubscriptionCount}}</strong> feeds</span>
@@ -33,7 +33,7 @@
33 </div>33 </div>
34 <div class="space-y-3">34 <div class="space-y-3">
35 {{range .Trending}}35 {{range .Trending}}
36- <a href="/articles/{{.ArticleID}}" class="block bg-spot-surface rounded-lg p-4 hover:bg-spot-hover-50 transition">36+ <a href="/articles/{{.ArticleID}}" class="block bg-spot-surface rounded-xl p-4 hover:bg-spot-hover-50 transition">
37 <div class="font-bold text-sm text-spot-text leading-tight">{{.Title}}</div>37 <div class="font-bold text-sm text-spot-text leading-tight">{{.Title}}</div>
38 <div class="flex items-center gap-2 mt-1 text-xs text-spot-secondary">38 <div class="flex items-center gap-2 mt-1 text-xs text-spot-secondary">
39 {{if .Author}}<span>{{.Author}}</span>{{end}}39 {{if .Author}}<span>{{.Author}}</span>{{end}}
@@ -57,7 +57,7 @@
57 </div>57 </div>
58 <div class="space-y-3">58 <div class="space-y-3">
59 {{range .PeopleRecommendations}}59 {{range .PeopleRecommendations}}
60- <div class="bg-spot-surface rounded-lg p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">60+ <div class="bg-spot-surface rounded-xl p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">
61 {{if .avatar_url}}<img src="{{.avatar_url}}" class="w-10 h-10 rounded-full">{{end}}61 {{if .avatar_url}}<img src="{{.avatar_url}}" class="w-10 h-10 rounded-full">{{end}}
62 <div class="min-w-0 flex-1">62 <div class="min-w-0 flex-1">
63 <a href="/profile/{{.handle}}" class="font-bold text-spot-text hover:text-spot-green transition">@{{.handle}}</a>63 <a href="/profile/{{.handle}}" class="font-bold text-spot-text hover:text-spot-green transition">@{{.handle}}</a>
@@ -91,7 +91,7 @@
91 <input type="url" name="feed_url" placeholder="Feed URL"91 <input type="url" name="feed_url" placeholder="Feed URL"
92 class="flex-1 bg-spot-hover text-spot-text rounded-pill px-5 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder"92 class="flex-1 bg-spot-hover text-spot-text rounded-pill px-5 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder"
93 required>93 required>
94- <button type="submit" class="bg-spot-green text-spot-bg rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Add</button>94+ <button type="submit" class="bg-spot-green text-white rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Add</button>
95 </form>95 </form>
96 </div>96 </div>
97 </div>97 </div>
modified internal/tmpl/discover.html +6 -6
@@ -1,6 +1,6 @@
11 {{define "discover.html"}}
22 <div class="flex items-center justify-between mb-6">
3- <h1 class="text-2xl font-bold font-title text-spot-text">Discover</h1>
3+ <h1 class="text-2xl font-bold text-spot-text">Discover</h1>
44 </div>
55
66 {{if .ArticleRecommendations}}
@@ -8,7 +8,7 @@
88 <h2 class="text-lg font-semibold text-spot-text mb-4">Recommended articles</h2>
99 <div class="space-y-3">
1010 {{range .ArticleRecommendations}}
11- <a href="/articles/{{.ArticleID}}" class="block bg-spot-surface rounded-lg p-4 hover:bg-spot-hover-50 transition">
11+ <a href="/articles/{{.ArticleID}}" class="block bg-spot-surface rounded-xl p-4 hover:bg-spot-hover-50 transition">
1212 <div class="font-bold text-sm text-spot-text leading-tight">{{.Title}}</div>
1313 <div class="flex items-center gap-2 mt-1 text-xs text-spot-secondary">
1414 {{if .Author}}<span>{{.Author}}</span>{{end}}
@@ -38,7 +38,7 @@
3838 <h2 class="text-lg font-semibold text-spot-text mb-4">Similar readers</h2>
3939 <div class="space-y-3">
4040 {{range .PeopleRecommendations}}
41- <div class="bg-spot-surface rounded-lg p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">
41+ <div class="bg-spot-surface rounded-xl p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">
4242 {{if .avatar_url}}<img src="{{.avatar_url}}" class="w-10 h-10 rounded-full">{{end}}
4343 <div class="min-w-0 flex-1">
4444 <a href="/profile/{{.handle}}" class="font-bold text-spot-text hover:text-spot-green transition">@{{.handle}}</a>
@@ -55,9 +55,9 @@
5555
5656 <div class="mt-8">
5757 <h2 class="text-lg font-semibold text-spot-text mb-4">Browse all feeds</h2>
58- <div class="bg-spot-surface rounded-lg divide-y divide-spot-divider">
58+ <div class="bg-spot-surface rounded-xl divide-y divide-spot-divider">
5959 {{range .PopularFeeds}}
60- <div class="px-5 py-4 flex items-center justify-between hover:bg-spot-hover-50 transition rounded-lg">
60+ <div class="px-5 py-4 flex items-center justify-between hover:bg-spot-hover-50 transition rounded-xl">
6161 <div class="min-w-0">
6262 <div class="font-bold text-spot-text">{{if .Title.Valid}}{{.Title.String}}{{else}}{{.FeedURL}}{{end}}</div>
6363 {{if .Description.Valid}}<p class="text-sm text-spot-secondary truncate">{{.Description.String}}</p>{{end}}
@@ -65,7 +65,7 @@
6565 <div class="flex items-center gap-3 shrink-0">
6666 <span class="text-xs text-spot-secondary">{{.SubscriberCount}} subscribers</span>
6767 <button hx-post="/feeds" hx-vals='{"feed_url": "{{.FeedURL}}"}' hx-target="this" hx-swap="outerHTML"
68- class="text-xs bg-spot-green/20 text-spot-green px-4 py-1.5 rounded-pill font-bold uppercase tracking-button hover:bg-spot-green hover:text-spot-bg transition">Subscribe</button>
68+ class="text-xs bg-spot-green/20 text-spot-green px-4 py-1.5 rounded-pill font-bold uppercase tracking-button hover:bg-spot-green hover:text-white transition">Subscribe</button>
6969 </div>
7070 </div>
7171 {{else}}
@@ -1,6 +1,6 @@
1 {{define "discover.html"}}1 {{define "discover.html"}}
2 <div class="flex items-center justify-between mb-6">2 <div class="flex items-center justify-between mb-6">
3- <h1 class="text-2xl font-bold font-title text-spot-text">Discover</h1>3+ <h1 class="text-2xl font-bold text-spot-text">Discover</h1>
4 </div>4 </div>
5 5
6 {{if .ArticleRecommendations}}6 {{if .ArticleRecommendations}}
@@ -8,7 +8,7 @@
8 <h2 class="text-lg font-semibold text-spot-text mb-4">Recommended articles</h2>8 <h2 class="text-lg font-semibold text-spot-text mb-4">Recommended articles</h2>
9 <div class="space-y-3">9 <div class="space-y-3">
10 {{range .ArticleRecommendations}}10 {{range .ArticleRecommendations}}
11- <a href="/articles/{{.ArticleID}}" class="block bg-spot-surface rounded-lg p-4 hover:bg-spot-hover-50 transition">11+ <a href="/articles/{{.ArticleID}}" class="block bg-spot-surface rounded-xl p-4 hover:bg-spot-hover-50 transition">
12 <div class="font-bold text-sm text-spot-text leading-tight">{{.Title}}</div>12 <div class="font-bold text-sm text-spot-text leading-tight">{{.Title}}</div>
13 <div class="flex items-center gap-2 mt-1 text-xs text-spot-secondary">13 <div class="flex items-center gap-2 mt-1 text-xs text-spot-secondary">
14 {{if .Author}}<span>{{.Author}}</span>{{end}}14 {{if .Author}}<span>{{.Author}}</span>{{end}}
@@ -38,7 +38,7 @@
38 <h2 class="text-lg font-semibold text-spot-text mb-4">Similar readers</h2>38 <h2 class="text-lg font-semibold text-spot-text mb-4">Similar readers</h2>
39 <div class="space-y-3">39 <div class="space-y-3">
40 {{range .PeopleRecommendations}}40 {{range .PeopleRecommendations}}
41- <div class="bg-spot-surface rounded-lg p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">41+ <div class="bg-spot-surface rounded-xl p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">
42 {{if .avatar_url}}<img src="{{.avatar_url}}" class="w-10 h-10 rounded-full">{{end}}42 {{if .avatar_url}}<img src="{{.avatar_url}}" class="w-10 h-10 rounded-full">{{end}}
43 <div class="min-w-0 flex-1">43 <div class="min-w-0 flex-1">
44 <a href="/profile/{{.handle}}" class="font-bold text-spot-text hover:text-spot-green transition">@{{.handle}}</a>44 <a href="/profile/{{.handle}}" class="font-bold text-spot-text hover:text-spot-green transition">@{{.handle}}</a>
@@ -55,9 +55,9 @@
55 55
56 <div class="mt-8">56 <div class="mt-8">
57 <h2 class="text-lg font-semibold text-spot-text mb-4">Browse all feeds</h2>57 <h2 class="text-lg font-semibold text-spot-text mb-4">Browse all feeds</h2>
58- <div class="bg-spot-surface rounded-lg divide-y divide-spot-divider">58+ <div class="bg-spot-surface rounded-xl divide-y divide-spot-divider">
59 {{range .PopularFeeds}}59 {{range .PopularFeeds}}
60- <div class="px-5 py-4 flex items-center justify-between hover:bg-spot-hover-50 transition rounded-lg">60+ <div class="px-5 py-4 flex items-center justify-between hover:bg-spot-hover-50 transition rounded-xl">
61 <div class="min-w-0">61 <div class="min-w-0">
62 <div class="font-bold text-spot-text">{{if .Title.Valid}}{{.Title.String}}{{else}}{{.FeedURL}}{{end}}</div>62 <div class="font-bold text-spot-text">{{if .Title.Valid}}{{.Title.String}}{{else}}{{.FeedURL}}{{end}}</div>
63 {{if .Description.Valid}}<p class="text-sm text-spot-secondary truncate">{{.Description.String}}</p>{{end}}63 {{if .Description.Valid}}<p class="text-sm text-spot-secondary truncate">{{.Description.String}}</p>{{end}}
@@ -65,7 +65,7 @@
65 <div class="flex items-center gap-3 shrink-0">65 <div class="flex items-center gap-3 shrink-0">
66 <span class="text-xs text-spot-secondary">{{.SubscriberCount}} subscribers</span>66 <span class="text-xs text-spot-secondary">{{.SubscriberCount}} subscribers</span>
67 <button hx-post="/feeds" hx-vals='{"feed_url": "{{.FeedURL}}"}' hx-target="this" hx-swap="outerHTML"67 <button hx-post="/feeds" hx-vals='{"feed_url": "{{.FeedURL}}"}' hx-target="this" hx-swap="outerHTML"
68- class="text-xs bg-spot-green/20 text-spot-green px-4 py-1.5 rounded-pill font-bold uppercase tracking-button hover:bg-spot-green hover:text-spot-bg transition">Subscribe</button>68+ class="text-xs bg-spot-green/20 text-spot-green px-4 py-1.5 rounded-pill font-bold uppercase tracking-button hover:bg-spot-green hover:text-white transition">Subscribe</button>
69 </div>69 </div>
70 </div>70 </div>
71 {{else}}71 {{else}}
modified internal/tmpl/feeds.html +6 -6
@@ -1,6 +1,6 @@
11 {{define "feeds.html"}}
22 <div class="flex items-center justify-between mb-6">
3- <h1 class="text-2xl font-bold font-title text-spot-text">Feeds</h1>
3+ <h1 class="text-2xl font-bold text-spot-text">Feeds</h1>
44 <div class="flex items-center gap-3">
55 <button hx-post="/feeds/refresh" hx-target="#feed-list" hx-swap="innerHTML"
66 hx-indicator="#refresh-indicator"
@@ -39,9 +39,9 @@
3939 </div>
4040 {{end}}
4141
42- <div id="feed-list" class="bg-spot-surface rounded-lg divide-y divide-spot-divider">
42+ <div id="feed-list" class="bg-spot-surface rounded-xl divide-y divide-spot-divider">
4343 {{range .Subscriptions}}
44- <div class="px-5 py-4 flex items-center justify-between hover:bg-spot-hover-50 transition rounded-lg">
44+ <div class="px-5 py-4 flex items-center justify-between hover:bg-spot-hover-50 transition rounded-xl">
4545 <div class="min-w-0">
4646 <div class="font-bold text-spot-text">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</div>
4747 {{if .Category.Valid}}<span class="text-xs text-spot-secondary">{{.Category.String}}</span>{{end}}
@@ -76,7 +76,7 @@
7676 </div>
7777
7878 <div class="space-y-6">
79- <div class="bg-spot-surface rounded-lg p-4 space-y-4">
79+ <div class="bg-spot-surface rounded-xl p-4 space-y-4">
8080 <h2 class="text-sm font-bold text-spot-text uppercase tracking-wide">Add feed</h2>
8181 <form hx-post="/feeds/add" hx-target="#feed-list" hx-swap="beforeend" class="space-y-3">
8282 {{csrfInput .CSRFToken}}
@@ -85,7 +85,7 @@
8585 required>
8686 <input type="text" name="category" placeholder="Category (optional)"
8787 class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">
88- <button type="submit" class="w-full bg-spot-green text-spot-bg rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Add</button>
88+ <button type="submit" class="w-full bg-spot-green text-white rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Add</button>
8989 </form>
9090 <form hx-post="/feeds/opml/upload" hx-encoding="multipart/form-data" class="flex flex-col gap-2">
9191 {{csrfInput .CSRFToken}}
@@ -117,7 +117,7 @@
117117 </div>
118118 <div class="space-y-3">
119119 {{range .PeopleRecommendations}}
120- <div class="bg-spot-surface rounded-lg p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">
120+ <div class="bg-spot-surface rounded-xl p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">
121121 {{if .avatar_url}}<img src="{{.avatar_url}}" class="w-10 h-10 rounded-full">{{end}}
122122 <div class="min-w-0 flex-1">
123123 <a href="/profile/{{.handle}}" class="font-bold text-spot-text hover:text-spot-green transition">@{{.handle}}</a>
@@ -1,6 +1,6 @@
1 {{define "feeds.html"}}1 {{define "feeds.html"}}
2 <div class="flex items-center justify-between mb-6">2 <div class="flex items-center justify-between mb-6">
3- <h1 class="text-2xl font-bold font-title text-spot-text">Feeds</h1>3+ <h1 class="text-2xl font-bold text-spot-text">Feeds</h1>
4 <div class="flex items-center gap-3">4 <div class="flex items-center gap-3">
5 <button hx-post="/feeds/refresh" hx-target="#feed-list" hx-swap="innerHTML"5 <button hx-post="/feeds/refresh" hx-target="#feed-list" hx-swap="innerHTML"
6 hx-indicator="#refresh-indicator"6 hx-indicator="#refresh-indicator"
@@ -39,9 +39,9 @@
39 </div>39 </div>
40 {{end}}40 {{end}}
41 41
42- <div id="feed-list" class="bg-spot-surface rounded-lg divide-y divide-spot-divider">42+ <div id="feed-list" class="bg-spot-surface rounded-xl divide-y divide-spot-divider">
43 {{range .Subscriptions}}43 {{range .Subscriptions}}
44- <div class="px-5 py-4 flex items-center justify-between hover:bg-spot-hover-50 transition rounded-lg">44+ <div class="px-5 py-4 flex items-center justify-between hover:bg-spot-hover-50 transition rounded-xl">
45 <div class="min-w-0">45 <div class="min-w-0">
46 <div class="font-bold text-spot-text">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</div>46 <div class="font-bold text-spot-text">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</div>
47 {{if .Category.Valid}}<span class="text-xs text-spot-secondary">{{.Category.String}}</span>{{end}}47 {{if .Category.Valid}}<span class="text-xs text-spot-secondary">{{.Category.String}}</span>{{end}}
@@ -76,7 +76,7 @@
76 </div>76 </div>
77 77
78 <div class="space-y-6">78 <div class="space-y-6">
79- <div class="bg-spot-surface rounded-lg p-4 space-y-4">79+ <div class="bg-spot-surface rounded-xl p-4 space-y-4">
80 <h2 class="text-sm font-bold text-spot-text uppercase tracking-wide">Add feed</h2>80 <h2 class="text-sm font-bold text-spot-text uppercase tracking-wide">Add feed</h2>
81 <form hx-post="/feeds/add" hx-target="#feed-list" hx-swap="beforeend" class="space-y-3">81 <form hx-post="/feeds/add" hx-target="#feed-list" hx-swap="beforeend" class="space-y-3">
82 {{csrfInput .CSRFToken}}82 {{csrfInput .CSRFToken}}
@@ -85,7 +85,7 @@
85 required>85 required>
86 <input type="text" name="category" placeholder="Category (optional)"86 <input type="text" name="category" placeholder="Category (optional)"
87 class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">87 class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">
88- <button type="submit" class="w-full bg-spot-green text-spot-bg rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Add</button>88+ <button type="submit" class="w-full bg-spot-green text-white rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Add</button>
89 </form>89 </form>
90 <form hx-post="/feeds/opml/upload" hx-encoding="multipart/form-data" class="flex flex-col gap-2">90 <form hx-post="/feeds/opml/upload" hx-encoding="multipart/form-data" class="flex flex-col gap-2">
91 {{csrfInput .CSRFToken}}91 {{csrfInput .CSRFToken}}
@@ -117,7 +117,7 @@
117 </div>117 </div>
118 <div class="space-y-3">118 <div class="space-y-3">
119 {{range .PeopleRecommendations}}119 {{range .PeopleRecommendations}}
120- <div class="bg-spot-surface rounded-lg p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">120+ <div class="bg-spot-surface rounded-xl p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">
121 {{if .avatar_url}}<img src="{{.avatar_url}}" class="w-10 h-10 rounded-full">{{end}}121 {{if .avatar_url}}<img src="{{.avatar_url}}" class="w-10 h-10 rounded-full">{{end}}
122 <div class="min-w-0 flex-1">122 <div class="min-w-0 flex-1">
123 <a href="/profile/{{.handle}}" class="font-bold text-spot-text hover:text-spot-green transition">@{{.handle}}</a>123 <a href="/profile/{{.handle}}" class="font-bold text-spot-text hover:text-spot-green transition">@{{.handle}}</a>
modified internal/tmpl/login.html +2 -2
@@ -1,7 +1,7 @@
11 {{define "login.html"}}
22 <div class="max-w-md mx-auto mt-20">
3- <div class="bg-spot-surface rounded-lg shadow-spot-heavy p-8">
4- <h1 class="text-2xl font-bold font-title text-spot-text mb-2">Sign in to Glean</h1>
3+ <div class="bg-spot-surface rounded-xl shadow-spot-heavy p-8">
4+ <h1 class="text-2xl font-bold text-spot-text mb-2">Sign in to Glean</h1>
55 <p class="text-spot-secondary text-sm mb-6">Enter your handle.</p>
66
77 <form action="/auth/start" method="POST" id="login-form">
@@ -1,7 +1,7 @@
1 {{define "login.html"}}1 {{define "login.html"}}
2 <div class="max-w-md mx-auto mt-20">2 <div class="max-w-md mx-auto mt-20">
3- <div class="bg-spot-surface rounded-lg shadow-spot-heavy p-8">3+ <div class="bg-spot-surface rounded-xl shadow-spot-heavy p-8">
4- <h1 class="text-2xl font-bold font-title text-spot-text mb-2">Sign in to Glean</h1>4+ <h1 class="text-2xl font-bold text-spot-text mb-2">Sign in to Glean</h1>
5 <p class="text-spot-secondary text-sm mb-6">Enter your handle.</p>5 <p class="text-spot-secondary text-sm mb-6">Enter your handle.</p>
6 6
7 <form action="/auth/start" method="POST" id="login-form">7 <form action="/auth/start" method="POST" id="login-form">
modified internal/tmpl/partials/annotation-card.html +1 -1
@@ -1,5 +1,5 @@
11 {{define "annotation-card.html"}}
2-<div class="bg-spot-surface rounded-lg p-4">
2+<div class="bg-spot-surface rounded-xl p-4">
33 {{if .Quote.Valid}}
44 <blockquote class="border-l-2 border-spot-green pl-3 text-sm text-spot-body italic">{{.Quote.String}}</blockquote>
55 {{end}}
@@ -1,5 +1,5 @@
1 {{define "annotation-card.html"}}1 {{define "annotation-card.html"}}
2-<div class="bg-spot-surface rounded-lg p-4">2+<div class="bg-spot-surface rounded-xl p-4">
3 {{if .Quote.Valid}}3 {{if .Quote.Valid}}
4 <blockquote class="border-l-2 border-spot-green pl-3 text-sm text-spot-body italic">{{.Quote.String}}</blockquote>4 <blockquote class="border-l-2 border-spot-green pl-3 text-sm text-spot-body italic">{{.Quote.String}}</blockquote>
5 {{end}}5 {{end}}
modified internal/tmpl/partials/article-card.html +1 -1
@@ -1,5 +1,5 @@
11 {{define "article-card.html"}}
2-<article data-article-id="{{.ID}}" class="bg-spot-surface rounded-lg px-5 py-4 hover:bg-spot-hover-50 transition shadow-spot">
2+<article data-article-id="{{.ID}}" class="bg-spot-surface rounded-xl px-5 py-4 hover:bg-spot-hover-50 transition shadow-spot">
33 <div class="flex items-start justify-between gap-4">
44 <div class="min-w-0 flex-1">
55 <a href="/articles/{{.ID}}" class="font-bold text-spot-text hover:text-spot-green transition text-lg leading-tight">{{.Title}}</a>
@@ -1,5 +1,5 @@
1 {{define "article-card.html"}}1 {{define "article-card.html"}}
2-<article data-article-id="{{.ID}}" class="bg-spot-surface rounded-lg px-5 py-4 hover:bg-spot-hover-50 transition shadow-spot">2+<article data-article-id="{{.ID}}" class="bg-spot-surface rounded-xl px-5 py-4 hover:bg-spot-hover-50 transition shadow-spot">
3 <div class="flex items-start justify-between gap-4">3 <div class="flex items-start justify-between gap-4">
4 <div class="min-w-0 flex-1">4 <div class="min-w-0 flex-1">
5 <a href="/articles/{{.ID}}" class="font-bold text-spot-text hover:text-spot-green transition text-lg leading-tight">{{.Title}}</a>5 <a href="/articles/{{.ID}}" class="font-bold text-spot-text hover:text-spot-green transition text-lg leading-tight">{{.Title}}</a>
modified internal/tmpl/partials/article-list.html +1 -1
@@ -1,6 +1,6 @@
11 {{define "article-list.html"}}
22 {{range .Articles}}
3-<article class="bg-spot-surface rounded-lg px-5 py-4 hover:bg-spot-hover-50 transition shadow-spot">
3+<article class="bg-spot-surface rounded-xl px-5 py-4 hover:bg-spot-hover-50 transition shadow-spot">
44 <div class="flex items-start justify-between gap-4">
55 <div class="min-w-0 flex-1">
66 <a href="/articles/{{.ID}}" class="font-bold text-spot-text hover:text-spot-green transition text-lg leading-tight">{{.Title}}</a>
@@ -1,6 +1,6 @@
1 {{define "article-list.html"}}1 {{define "article-list.html"}}
2 {{range .Articles}}2 {{range .Articles}}
3-<article class="bg-spot-surface rounded-lg px-5 py-4 hover:bg-spot-hover-50 transition shadow-spot">3+<article class="bg-spot-surface rounded-xl px-5 py-4 hover:bg-spot-hover-50 transition shadow-spot">
4 <div class="flex items-start justify-between gap-4">4 <div class="flex items-start justify-between gap-4">
5 <div class="min-w-0 flex-1">5 <div class="min-w-0 flex-1">
6 <a href="/articles/{{.ID}}" class="font-bold text-spot-text hover:text-spot-green transition text-lg leading-tight">{{.Title}}</a>6 <a href="/articles/{{.ID}}" class="font-bold text-spot-text hover:text-spot-green transition text-lg leading-tight">{{.Title}}</a>
modified internal/tmpl/partials/feed-list.html +1 -1
@@ -1,6 +1,6 @@
11 {{define "feed-list.html"}}
22 {{range .Subscriptions}}
3-<div class="px-5 py-4 flex items-center justify-between hover:bg-spot-hover-50 transition rounded-lg">
3+<div class="px-5 py-4 flex items-center justify-between hover:bg-spot-hover-50 transition rounded-xl">
44 <div class="min-w-0">
55 <div class="font-bold text-spot-text">{{.FeedURL}}</div>
66 {{if .Category.Valid}}<span class="text-xs text-spot-secondary">{{.Category.String}}</span>{{end}}
@@ -1,6 +1,6 @@
1 {{define "feed-list.html"}}1 {{define "feed-list.html"}}
2 {{range .Subscriptions}}2 {{range .Subscriptions}}
3-<div class="px-5 py-4 flex items-center justify-between hover:bg-spot-hover-50 transition rounded-lg">3+<div class="px-5 py-4 flex items-center justify-between hover:bg-spot-hover-50 transition rounded-xl">
4 <div class="min-w-0">4 <div class="min-w-0">
5 <div class="font-bold text-spot-text">{{.FeedURL}}</div>5 <div class="font-bold text-spot-text">{{.FeedURL}}</div>
6 {{if .Category.Valid}}<span class="text-xs text-spot-secondary">{{.Category.String}}</span>{{end}}6 {{if .Category.Valid}}<span class="text-xs text-spot-secondary">{{.Category.String}}</span>{{end}}
modified internal/tmpl/partials/profile-card.html +1 -1
@@ -1,5 +1,5 @@
11 {{define "profile-card.html"}}
2-<div class="bg-spot-surface rounded-lg p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">
2+<div class="bg-spot-surface rounded-xl p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">
33 <div class="min-w-0 flex-1">
44 <a href="/profile/{{.did}}" class="font-bold text-spot-text hover:text-spot-green transition">@{{.handle}}</a>
55 {{if .display_name}}<div class="text-sm text-spot-secondary">{{.display_name}}</div>{{end}}
@@ -1,5 +1,5 @@
1 {{define "profile-card.html"}}1 {{define "profile-card.html"}}
2-<div class="bg-spot-surface rounded-lg p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">2+<div class="bg-spot-surface rounded-xl p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition">
3 <div class="min-w-0 flex-1">3 <div class="min-w-0 flex-1">
4 <a href="/profile/{{.did}}" class="font-bold text-spot-text hover:text-spot-green transition">@{{.handle}}</a>4 <a href="/profile/{{.did}}" class="font-bold text-spot-text hover:text-spot-green transition">@{{.handle}}</a>
5 {{if .display_name}}<div class="text-sm text-spot-secondary">{{.display_name}}</div>{{end}}5 {{if .display_name}}<div class="text-sm text-spot-secondary">{{.display_name}}</div>{{end}}
modified internal/tmpl/partials/recommendation-card.html +1 -1
@@ -1,5 +1,5 @@
11 {{define "recommendation-card.html"}}
2-<div class="bg-spot-surface rounded-lg p-3 hover:bg-spot-hover-50 transition">
2+<div class="bg-spot-surface rounded-xl p-3 hover:bg-spot-hover-50 transition">
33 <div class="flex items-center justify-between">
44 <div class="min-w-0">
55 <div class="font-bold text-sm text-spot-text">{{if .title}}{{.title}}{{else}}{{.feed_url}}{{end}}</div>
@@ -1,5 +1,5 @@
1 {{define "recommendation-card.html"}}1 {{define "recommendation-card.html"}}
2-<div class="bg-spot-surface rounded-lg p-3 hover:bg-spot-hover-50 transition">2+<div class="bg-spot-surface rounded-xl p-3 hover:bg-spot-hover-50 transition">
3 <div class="flex items-center justify-between">3 <div class="flex items-center justify-between">
4 <div class="min-w-0">4 <div class="min-w-0">
5 <div class="font-bold text-sm text-spot-text">{{if .title}}{{.title}}{{else}}{{.feed_url}}{{end}}</div>5 <div class="font-bold text-sm text-spot-text">{{if .title}}{{.title}}{{else}}{{.feed_url}}{{end}}</div>
modified internal/tmpl/profile.html +6 -6
@@ -1,10 +1,10 @@
11 {{define "profile.html"}}
22 <div class="max-w-2xl mx-auto">
3- <div class="bg-spot-surface rounded-lg p-6 mb-6">
3+ <div class="bg-spot-surface rounded-xl p-6 mb-6">
44 <div class="flex items-center gap-4">
55 {{if .ProfileUser.AvatarURL.Valid}}<img src="{{.ProfileUser.AvatarURL.String}}" class="w-16 h-16 rounded-full">{{end}}
66 <div>
7- <h1 class="text-2xl font-bold font-title text-spot-text">
7+ <h1 class="text-2xl font-bold text-spot-text">
88 {{if .ProfileUser.DisplayName.Valid}}{{.ProfileUser.DisplayName.String}}{{end}}
99 </h1>
1010 <p class="text-spot-secondary">@{{.ProfileUser.Handle}}</p>
@@ -13,20 +13,20 @@
1313 </div>
1414
1515 <div class="grid grid-cols-2 gap-4 mb-6">
16- <div class="bg-spot-surface rounded-lg p-4 text-center">
16+ <div class="bg-spot-surface rounded-xl p-4 text-center">
1717 <div class="text-2xl font-bold text-spot-text">{{.SubscriptionCount}}</div>
1818 <div class="text-sm text-spot-secondary">Feeds</div>
1919 </div>
20- <div class="bg-spot-surface rounded-lg p-4 text-center">
20+ <div class="bg-spot-surface rounded-xl p-4 text-center">
2121 <div class="text-2xl font-bold text-spot-text">{{.AnnotationCount}}</div>
2222 <div class="text-sm text-spot-secondary">Annotations</div>
2323 </div>
2424 </div>
2525
2626 <h2 class="text-lg font-semibold text-spot-text mb-3">Feeds</h2>
27- <div class="bg-spot-surface rounded-lg divide-y divide-spot-divider mb-6">
27+ <div class="bg-spot-surface rounded-xl divide-y divide-spot-divider mb-6">
2828 {{range .Subscriptions}}
29- <div class="px-5 py-3 hover:bg-spot-hover-50 transition rounded-lg">
29+ <div class="px-5 py-3 hover:bg-spot-hover-50 transition rounded-xl">
3030 <div class="font-bold text-spot-text">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</div>
3131 {{if .Category.Valid}}<span class="text-xs text-spot-secondary">{{.Category.String}}</span>{{end}}
3232 </div>
@@ -1,10 +1,10 @@
1 {{define "profile.html"}}1 {{define "profile.html"}}
2 <div class="max-w-2xl mx-auto">2 <div class="max-w-2xl mx-auto">
3- <div class="bg-spot-surface rounded-lg p-6 mb-6">3+ <div class="bg-spot-surface rounded-xl p-6 mb-6">
4 <div class="flex items-center gap-4">4 <div class="flex items-center gap-4">
5 {{if .ProfileUser.AvatarURL.Valid}}<img src="{{.ProfileUser.AvatarURL.String}}" class="w-16 h-16 rounded-full">{{end}}5 {{if .ProfileUser.AvatarURL.Valid}}<img src="{{.ProfileUser.AvatarURL.String}}" class="w-16 h-16 rounded-full">{{end}}
6 <div>6 <div>
7- <h1 class="text-2xl font-bold font-title text-spot-text">7+ <h1 class="text-2xl font-bold text-spot-text">
8 {{if .ProfileUser.DisplayName.Valid}}{{.ProfileUser.DisplayName.String}}{{end}}8 {{if .ProfileUser.DisplayName.Valid}}{{.ProfileUser.DisplayName.String}}{{end}}
9 </h1>9 </h1>
10 <p class="text-spot-secondary">@{{.ProfileUser.Handle}}</p>10 <p class="text-spot-secondary">@{{.ProfileUser.Handle}}</p>
@@ -13,20 +13,20 @@
13 </div>13 </div>
14 14
15 <div class="grid grid-cols-2 gap-4 mb-6">15 <div class="grid grid-cols-2 gap-4 mb-6">
16- <div class="bg-spot-surface rounded-lg p-4 text-center">16+ <div class="bg-spot-surface rounded-xl p-4 text-center">
17 <div class="text-2xl font-bold text-spot-text">{{.SubscriptionCount}}</div>17 <div class="text-2xl font-bold text-spot-text">{{.SubscriptionCount}}</div>
18 <div class="text-sm text-spot-secondary">Feeds</div>18 <div class="text-sm text-spot-secondary">Feeds</div>
19 </div>19 </div>
20- <div class="bg-spot-surface rounded-lg p-4 text-center">20+ <div class="bg-spot-surface rounded-xl p-4 text-center">
21 <div class="text-2xl font-bold text-spot-text">{{.AnnotationCount}}</div>21 <div class="text-2xl font-bold text-spot-text">{{.AnnotationCount}}</div>
22 <div class="text-sm text-spot-secondary">Annotations</div>22 <div class="text-sm text-spot-secondary">Annotations</div>
23 </div>23 </div>
24 </div>24 </div>
25 25
26 <h2 class="text-lg font-semibold text-spot-text mb-3">Feeds</h2>26 <h2 class="text-lg font-semibold text-spot-text mb-3">Feeds</h2>
27- <div class="bg-spot-surface rounded-lg divide-y divide-spot-divider mb-6">27+ <div class="bg-spot-surface rounded-xl divide-y divide-spot-divider mb-6">
28 {{range .Subscriptions}}28 {{range .Subscriptions}}
29- <div class="px-5 py-3 hover:bg-spot-hover-50 transition rounded-lg">29+ <div class="px-5 py-3 hover:bg-spot-hover-50 transition rounded-xl">
30 <div class="font-bold text-spot-text">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</div>30 <div class="font-bold text-spot-text">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</div>
31 {{if .Category.Valid}}<span class="text-xs text-spot-secondary">{{.Category.String}}</span>{{end}}31 {{if .Category.Valid}}<span class="text-xs text-spot-secondary">{{.Category.String}}</span>{{end}}
32 </div>32 </div>