7.0 KiB
01 - Visual Design
This document defines the visual language of YouTube Studio Flow. All UI work must follow these rules. For CSS implementation details, see 02 - CSS Conventions.
Colors
The app uses a warm off-white background with a teal primary color. Two themes are supported: light and dark. Both use the same CSS variable names — the values swap via a [data-theme="dark"] selector in globals.css.
Never use inline hex values. Always reference the variables below. Test every new color usage in both themes before committing.
Light Theme
| Variable | Value | Usage |
|---|---|---|
--color-bg |
#f7f6f2 |
Page background |
--color-surface |
#f9f8f5 |
Card and panel backgrounds |
--color-surface-2 |
#fbfbf9 |
Elevated surfaces (nested cards) |
--color-surface-offset |
#f3f0ec |
Inset/recessed areas |
--color-border |
#d4d1ca |
Borders |
--color-divider |
#dcd9d5 |
Subtle dividers between sections |
--color-text |
#28251d |
Primary text |
--color-text-muted |
#66645d |
Secondary/supporting text |
--color-text-faint |
#9f9c94 |
Placeholder and hint text |
--color-text-inverse |
#f9f8f4 |
Text placed on dark backgrounds |
--color-primary |
#01696f |
Teal — primary actions, active nav, links |
--color-primary-hover |
#0c4e54 |
Primary button hover state |
--color-primary-highlight |
#cedcd8 |
Primary tint — active nav items, selection backgrounds |
--color-success |
#437a22 |
Success states |
--color-warning |
#964219 |
Warning states |
--color-error |
#a12c7b |
Error states — magenta, not red |
--color-blue |
#006494 |
Info and link accent |
--color-purple |
#7a39bb |
Secondary accent |
Dark Theme
Dark theme uses the same variable names. Key differences:
- Surfaces shift to near-black:
#171614,#1c1b19,#201f1d - Primary lightens for contrast:
#4f98a3 - Error, success, and warning all lighten to maintain legibility on dark backgrounds
When adding any new color usage, verify it works in both themes. The dark theme overrides are defined in globals.css under [data-theme="dark"].
Semantic mapping quick reference
| Situation | Variable |
|---|---|
| Page background | --color-bg |
| Card or panel | --color-surface |
| Input background | --color-surface |
| Sidebar / elevated container | --color-surface-2 |
| Recessed input or inner area | --color-surface-offset |
| Standard border | --color-border |
| Divider line | --color-divider |
| Body copy | --color-text |
| Labels, captions | --color-text-muted |
| Placeholders | --color-text-faint |
| Primary button, active state | --color-primary |
| Hover on primary | --color-primary-hover |
| Active nav background | --color-primary-highlight |
Typography
Fonts
| Role | Family | Fallback | CSS Variable |
|---|---|---|---|
| Body / UI | General Sans | Inter, sans-serif | --font-body |
| Display / Headings | Cabinet Grotesk | Inter, sans-serif | --font-display |
Both fonts are loaded from the Fontshare CDN via <link> in layout.tsx. Do not use system fonts for headings.
Type Scale
All sizes use fluid clamp() values so text scales smoothly between viewport breakpoints.
| Variable | Approximate range | Typical use |
|---|---|---|
--text-xs |
0.75rem → 0.875rem | Badges, footnotes, timestamps |
--text-sm |
0.875rem → 1rem | Labels, captions, secondary UI |
--text-base |
1rem → 1.125rem | Body copy, inputs |
--text-lg |
1.125rem → 1.5rem | Sub-headings, card titles |
--text-xl |
1.5rem → 2.25rem | Section headings |
--text-2xl |
2rem → 3.5rem | Page titles |
Usage rules
- Page titles —
font-family: var(--font-display),font-weight: 700,font-size: var(--text-xl)or--text-2xl - Section labels —
font-size: var(--text-sm),text-transform: uppercase,letter-spacing: 0.05em,color: var(--color-text-muted) - Body text —
font-family: var(--font-body),font-size: var(--text-base),color: var(--color-text) - Input text —
font-size: var(--text-base)or--text-sm
Never set font sizes in raw px or rem values — always use the scale variables.
Spacing
Use the spacing scale for all margins, padding, and gaps. Never use raw pixel values in component CSS.
| Variable | Value | Rough equivalent |
|---|---|---|
--space-1 |
0.25rem |
4px |
--space-2 |
0.5rem |
8px |
--space-3 |
0.75rem |
12px |
--space-4 |
1rem |
16px |
--space-5 |
1.25rem |
20px |
--space-6 |
1.5rem |
24px |
--space-8 |
2rem |
32px |
--space-10 |
2.5rem |
40px |
--space-12 |
3rem |
48px |
--space-16 |
4rem |
64px |
Borders and Radius
| Variable | Value | Typical use |
|---|---|---|
--radius-sm |
0.375rem |
Small inputs, tight chips |
--radius-md |
0.5rem |
Buttons, standard inputs |
--radius-lg |
0.75rem |
Cards, panels |
--radius-xl |
1rem |
Large cards, modals |
--radius-full |
9999px |
Pills, badges, avatar circles, fully-round buttons |
All bordered elements use --color-border for their border color unless a semantic variant applies (e.g. --color-error for invalid inputs).
Shadows
| Variable | Typical use |
|---|---|
--shadow-sm |
Subtle card lift — separates surface from background |
--shadow-md |
Popovers and dropdowns |
--shadow-lg |
Modals and full-screen overlays |
Use the lightest shadow that achieves the visual separation needed. Do not stack multiple shadows.
Layout Constants
| Variable / Value | Definition |
|---|---|
--sidebar-width: 280px |
Expanded navigation sidebar |
--sidebar-width-collapsed: 64px |
Collapsed sidebar (icon-only) |
--header-height: 72px |
Top bar height |
The main content area is offset by the sidebar width. See 03 - Component Patterns for the sidebar collapse pattern.