Design System — Tokens
Dark Mode
bg-base#0C0C0C
bg-card#161616
border#2A2A2A
text-primary#F0F0F0
text-secondary#888888
text-tertiary#555555
accent-gold#D4A853
gold-tint#3A2E10
Light Mode
bg-base#EDE6D3
bg-card#F7F2E6
border#D8CCAA
text-primary#1A1209
text-body#4A3E2A
text-secondary#9A8C74
accent-gold#D4A853 ←shared
accent-rust#C4401C
Type System — Shared Across Both Modes
Display Playfair Display
Italic 700 · 28–40px
Log a Show
Setlist / Body Crimson Pro
Italic 400 · 13–16px
The End Where We Start
UI Labels DM Mono
400–500 · 9–12px
From Memory · Thalia Hall · ★★★★★
Bold UI Syne
800 · 13–20px
marcus_ears
Log a Show — Both Themes
Showing "From Memory" mode with a partial setlist entered. Live Now mode swaps the date field for auto-detected venue.
Dark Vintage
9:41
●●● ▲ ▮
← Cancel Log a Show Save
Setlist
01 Medley Intro ×
02 Ice to Never Rare ×
03 Secret Scream ×
04 The End Where We Start ×
5.0
From Memory No ticket needed. We trust you.
Vintage Bold
9:41
●●● ▲ ▮
← Cancel Log a Show Save
Setlist
01 Medley Intro ×
02 Ice to Never Rare ×
03 Secret Scream ×
04 The End Where We Start ×
5.0
From Memory No ticket needed. We trust you.
Component Inventory

Every component on this screen.

ModeToggle Atomic
Propsmode: 'live' | 'memory'
BehaviorSwitches form context. Live mode hides date field, auto-detects location. Memory mode shows date picker.
DarkActive pill: #D4A853 bg / #0C0C0C text. Inactive: #444
LightActive pill: #1A1209 bg / #EDE6D3 text. Inactive: #B8A880
FieldInput Atomic
Statesempty · focused · filled · error
FontDM Mono 400 · 12px · letter-spacing .02em
Dark filledborder: #3A2E10 (gold tint) — signals API pre-fill vs manual entry
Light filledborder: #D4A853 — same signal, lighter context
SongRow Molecule
Propsindex: number · title: string · isRare: boolean
Song fontCrimson Pro Italic · 14px — the setlist is the hero, deserves a serif
Index fontDM Mono · 10px · muted — supporting info, not the focus
Rare badgeAuto-triggered by algorithm. Dark: #3A2E10 bg / #D4A853 text. Light: gold tint bg.
StarRating Atomic
Propsvalue: 0–5 · onChange: fn
ColorFilled: #D4A853 — shared across both modes. Empty: #222 dark / #D8CCAA light
Size18px tap target · 44px minimum touch zone per star
FromMemoryToggle Molecule
DefaultON when mode is 'memory'. Auto-set. User can override.
Copy"No ticket needed. We trust you." — this is a design principle, not a disclaimer. Tone matters here.
ImpactAdds subtle "from memory" tag on feed card. Not a warning. A signal.
SetlistBuilder Organism
ChildrenSongRow (list) + SongInput + AddButton
Pre-fillWhen artist+date match Setlist.fm API, songs populate automatically. User confirms or edits.
ManualFree text input. No validation — trust the fan. Wrong setlist > no setlist.
Rare logicFlag triggers if song hasn't appeared in last 20 setlists for that artist. P1 feature — stub the badge now.
PrimaryButton Atomic
Label"Save to Archive" — not "Submit" or "Post". Language reinforces the diary metaphor.
Dark#D4A853 bg / #0C0C0C text — gold is the action color
Light#1A1209 bg / #EDE6D3 text — ink black takes the action role
FontDM Mono · 11px · .2em tracking · uppercase — matches nav label language
Figma Setup — Next Steps
What to build in Figma from this spec.
Create a Local Variables collection with two modes: Dark and Light. Map every token above to a variable. This is what enables one-click theme switching on every frame.
Build Text Styles for all four type roles: Display/Playfair, Body/Crimson, Label/DM Mono, Bold/Syne. Apply them globally — never hard-code font sizes in components.
Build atomic components first: FieldInput, SongRow, StarRating, RareBadge, PrimaryButton. Then compose molecules and organisms from them.
Use component properties for states (empty/filled/error) and the isRare flag on SongRow — not separate components for each state.
Frame the phone screens at 390×844 (iPhone 14 base). Build both dark and light variants as separate frames in the same Figma page.