The VoD System — Frontend Design Reference
Warm, editorial, low-key. Soft shadows instead of borders, cream surfaces, one terracotta and one olive accent. No dark-dashboard chrome.
1. Typography
| Role |
Family |
Usage |
| Display / headings |
Newsreader (serif, weight 400) |
Page titles, card headings, item titles, greeting, logo wordmark. Always regular weight — never bold. |
| UI / body |
IBM Plex Sans (400, 500) |
Nav, labels, buttons, body copy, table cells. 500 only for the active nav item. |
| Data / mono |
IBM Plex Mono (400, 500) |
Timecodes, stream key, ingest URL, durations, bitrates, file facts, kickers, job stages. |
Fallbacks: system-ui, sans-serif for Plex Sans; serif for Newsreader; monospace for Plex Mono.
Type scale
| Element |
Size |
Family |
Notes |
| Greeting (dashboard h1) |
40px |
Newsreader |
letter-spacing: -0.015em |
| Page h1 |
36px |
Newsreader |
-0.015em |
| Detail title |
31px |
Newsreader |
-0.015em |
| Drop-zone headline |
25px |
Newsreader |
|
| Section h2 |
23px |
Newsreader |
|
| Logo wordmark |
22px |
Newsreader |
-0.01em |
| Card heading (in-panel) |
20–22px |
Newsreader |
|
| Status headline |
27px |
Newsreader |
line-height 1.25 |
| VOD tile title |
17.5–18px |
Newsreader |
line-height 1.3 |
| Big metric |
21px |
Plex Mono |
elapsed, marker count, bitrate |
| Range length |
15px |
Plex Mono |
|
| Body paragraph |
14.5px |
Plex Sans |
line-height 1.65, text-wrap: pretty, max 62ch |
| Primary button |
13.5–14px |
Plex Sans |
|
| Field value |
13.5–14px |
Plex Sans / Mono |
mono for timecodes and sizes |
| Table cell |
13.5px |
Plex Sans |
mono for numeric columns |
| Clip tile title |
13.5px |
Plex Sans |
|
| Meta line |
12–13px |
Plex Sans |
muted ink |
| Field label |
11.5px |
Plex Sans |
muted ink |
| Kicker / eyebrow |
10.5–11px |
Plex Mono |
letter-spacing: 0.10–0.14em, uppercase |
| Ruler / tick caption |
10–10.5px |
Plex Mono |
|
2. Colour
Surfaces
| Token |
Hex |
Where |
| Canvas |
#F7F4EE |
Page background |
| Sidebar |
#F2EEE6 |
Nav column and collapsed rail |
| Card |
#FDFBF7 |
Cards, library tiles, active nav pill |
| Field well |
#F4F0E8 |
Inputs, credential wells, timeline track |
| Muted panel |
#F1ECE3 / #F1EDE4 |
Secondary buttons, "how it works", clip-cutter panel |
| Drop zone (idle) |
#F9F6EF |
Upload empty state |
| Armed / selected |
#F6EFE6 |
Selected marker row, filled range card |
| Live card |
#F0EBE1 |
Dashboard status block when live |
| Player body |
#2B2620 |
Video chrome, also the dark button |
| Player stripes |
#3A342C / #332E27 |
Placeholder frame texture |
Ink
| Token |
Hex |
Where |
| Primary |
#2B2620 |
Headings, metrics |
| Strong |
#35302A |
Field values, tile titles |
| Body |
#554D44 |
Paragraph copy |
| Control label |
#4A423A |
Secondary button text |
| Secondary |
#6E6559 |
Supporting copy |
| Table value |
#7A7166 |
History rows |
| Muted |
#9A9084 |
Labels, meta, kickers |
| Faint |
#A79C8E |
Mono captions, ruler ticks, hints |
| On dark |
#FBF8F2 |
Text on player / dark button |
| On accent |
#FDFBF7 |
Text on terracotta / olive |
Accents
| Token |
Hex |
Where |
| Terracotta |
#A85A38 |
Logo mark, primary CTA, links, marker timecodes, playheads |
| Terracotta hover |
#94492A |
Primary button hover |
| Terracotta light |
#C87A52 |
Progress bars, scrubber fill, selected marker ring |
| Terracotta disabled |
#C9AE9C |
"Waiting for a file" button |
| Olive |
#6E7A50 |
Clip actions, trim in/out handles |
| Olive hover |
#5D6843 |
|
| Olive light |
#8A9668 |
Completed job bar |
| Live red |
#B5432E |
Live dot and "LIVE NOW" label |
Lines, chips, placeholders
| Token |
Hex |
Where |
| Hairline |
#F0EBE2 |
Row dividers (1px) |
| Chip fill |
#EAE3D7, #EFE9DE, #E4DDD0 |
Progress track, toggles, nav-hide button |
| Chip hover |
#E7E0D2, #DAD1C0, #EAE4D9 |
|
| Drop-zone ring |
#E2DACB |
inset 0 0 0 1.5px |
| Inactive marks |
#DED7CA, #C4BAA9 |
Unchecked boxes, unselected ticks |
| Zoom window outline |
#8E8577 |
Overview strip frame |
| VOD thumbnail |
#E3DACB / #DAD0BF |
135° stripes, 9px |
| Clip thumbnail |
#DFE0D2 / #D6D8C7 |
135° stripes, 9px |
| Avatar |
#D9C9AE on #5C4A32 |
Google account chip |
3. Elevation & shape
- Card:
0 1px 2px rgba(60,48,32,.05), 0 10px 26px -18px rgba(60,48,32,.35)
- Card hover:
0 2px 4px rgba(60,48,32,.07), 0 18px 34px -18px rgba(60,48,32,.45)
- Panel (heavier):
0 1px 2px rgba(60,48,32,.05), 0 16px 36px -22px rgba(60,48,32,.3)
- Player:
0 1px 2px rgba(60,48,32,.08), 0 22px 46px -26px rgba(60,48,32,.5)
- Terracotta button:
0 1px 2px rgba(90,40,20,.2), 0 12px 22px -14px rgba(90,40,20,.55)
- Olive button:
0 1px 2px rgba(50,60,30,.18), 0 10px 20px -14px rgba(50,60,30,.55)
- Inset ring (used instead of borders):
inset 0 0 0 1px rgba(60,48,32,.08)
Radii: 16px hero/status blocks · 15px panels · 13px tiles · 12px thumbnails/player · 10px inputs & dark buttons · 9px buttons, nav pills, logo mark · 8px chips and fields · 5–6px overlay badges · 50% avatars and play button.
Media ratios: 16/9 VOD thumbnails and player · 4/3 clip thumbnails · 16/7 upload drop zone.
4. Layout
- Shell:
252px sidebar + fluid main; collapsed rail is 62px.
- Main padding
40px 52px 72px, content max-width 1060–1180px.
- Library grids: 3 columns for VODs (gap 22px), 4 for clips (gap 18–20px).
- Detail and stream pages: content column +
330–340px sticky side panel, gap 26px.
- Spacing rhythm: 26–34px between sections, 14–20px inside cards, 6–10px label-to-field. Always flex/grid with
gap.
5. Motion & state
livePulse — 2.2s ease-in-out infinite opacity/scale pulse, live dot only. Nothing else animates decoratively.
- Hover: background shifts one step darker within the same family; cards deepen their shadow. No transforms.
- Selection:
#F6EFE6 fill plus a 1.5px terracotta inset ring.
- Progress is always a bar with a stage word and remaining time (
queued → reading source → encoding → writing file → complete) — never a spinner.
6. Copy tone
Lowercase mono for machine facts, sentence case for everything else. Personal and specific ("Cat walks across the patch bay"), never marketing voice. Durations as h:mm:ss, timecodes as hh:mm:ss, sizes in MB/GB.