Files
Keysat 1741fb11a5 Add design/ contract extracted from the as-built UI
Inventory the as-built recaps.cc look and distill it into a durable,
vendor-neutral design contract: design/DESIGN.md (nine-section brand
brief) + design/tokens.tokens.json (W3C DTCG tokens), plus brand icon
and provenance notes. Canonical calls reconciled with the owner:
indigo #818cf8 as the single interactive accent, purple #a855f7 for
premium only, the #0a0e1a->#111827->#0f172a surface ladder, and a
normalized type scale. Wire the AGENTS.md Design line and record the
contract-vs-code drift as a cleanup backlog in ROADMAP.md.
2026-06-16 23:08:41 -05:00

214 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Recap — Design brief
The durable brand contract for Recap's user-facing UI. Read this and
`design/tokens.tokens.json` before building or changing any UI. This was
**extracted** from the as-built `recaps.cc` interface (no prior guidelines), then
**reconciled** with the owner on 2026-06-16 — so where the live code still
disagrees with a value here, *this file is the intent* and the code is the cleanup
backlog (see `ROADMAP.md`). Provenance: there was no design tool or export; the
source is the shipped `public/index.html`, `public/auth.html`, and the app icon.
---
## 1. Visual theme
A **dense, dark, information-first developer-tool aesthetic.** Restraint over
decoration: small type, tight radii, thin hairline borders, flat panels on a
near-black navy field, with the indigo accent used sparingly to mark what's
interactive or active. It should read like a fast, technical instrument — closer
to a code editor or an ops dashboard than a consumer media app. Calm, quiet, and
legible at high density; never glossy, never playful.
The brand mark (app icon) is a **play-triangle filled with a blue→purple gradient
over four light "transcript" lines**, on the dark navy field — the product in one
glyph: *press play on a video, get the text back.* That blue→purple gradient is
the origin of the whole accent story (§2).
Voice: precise, plain-spoken, unhyped. The UI explains tersely and trusts the
user. What it is **not**: not gradient-heavy, not glassmorphic beyond a light
overlay blur, not rounded-and-bubbly, not light-mode, not framework-flashy.
## 2. Color palette
Built almost entirely on the **Tailwind Slate + Indigo** ramps over a custom
near-black navy base. Canonical roles below; full values in
`tokens.tokens.json`.
**Surface ladder (warm/cool split — the agreed system).**
| Role | Value | Where |
|---|---|---|
| Base | `#0a0e1a` | page, body, sticky top bars, full-height side panels (history sidebar, log drawer). Also the PWA `theme_color`. |
| Card | `#111827` (warm gray-900) | raised cards, modals, popovers, toasts, icon-buttons, pipeline steps, skeletons. |
| Inset | `#0f172a` (cool slate-900) | recessed fields & list rows: settings/key inputs, queue items, subscription items, model buttons, expanded-chunk bg. |
| Raised field | `#1e293b` | the **primary URL input only** — deliberately lighter than the inset so the hero field pops. |
> Legacy darks **`#0a0e17`, `#0b1120`, `#020617`** are near-duplicates that
> leaked in; fold them into the nearest rung (`#0a0e17`/`#0b1120` → Base,
> `#020617` → Inset). Don't add new background darks.
**Accent — indigo (THE single interactive accent).**
- `#818cf8` (indigo-400) — **the accent.** Fills (submit button, active tab/icon,
processing badge) and marks (links, focus ring, active state, timestamps,
expanded-chunk arrow).
- `#a5b4fc` (indigo-300) — accent hover (lighter), active-line emphasis.
- Indigo tints `rgba(129,140,248, .06.20)` — hover washes, active backgrounds,
the `0 0 0 3px …/.15` focus ring, the `0 4px 24px …/.3` submit glow.
- **Demoted:** `#6366f1` (indigo-500) and its hovers `#4f46e5`/`#4338ca` are
legacy dups — migrate them to `#818cf8`; do not introduce new ones.
**Premium — purple (RESERVED for paid/upgrade only).**
- `#a855f7` (purple-500) — upgrade button, highlighted tier, buy badge, primary
buy CTA. `#c084fc` hover; `#9333ea` deep.
- `#c4b5fd`/`#d8b4fe` (purple-300/200) — tier-badge & Pro text.
- Purple appears **nowhere** in non-premium UI.
**Text ramp (slate).**
`#e2e8f0` primary · `#f1f5f9` strong/headings (canonical near-white — fold the
stray `#f5f9ff` into this) · `#cbd5e1` running body copy · `#94a3b8` muted/
secondary · `#64748b` labels & placeholders · `#475569` faint meta/timestamps ·
`#334155` dimmest (doubles as the hover-border). `#fff` only on filled
accent/premium buttons.
**Borders.** `#1e293b` (slate-800) default hairline → `#334155` (slate-700) on
hover/active → `#475569` (slate-600) strongest hover. Borders, not shadows, are
the primary way surfaces are separated.
**Semantic status (consistent, intentional — keep).**
- Success/green: `#22c55e` base · `#4ade80` text · `#86efac` soft · `#16a34a` deep.
- Error/red: `#ef4444` base · `#f87171` text · `#fca5a5` soft · `#dc2626` deep.
- Warning/amber: `#fbbf24` base/dot · `#fcd34d` · `#fde68a` · `#f59e0b` (update btn).
- Info/blue: `#3b82f6` base · `#60a5fa` · `#93c5fd`. **Blue is status/info only**
(and the legacy auth-screen accent, which should migrate to indigo) — never a
primary interactive color in-app.
**Speaker chips (8-hue categorical set — intentional, keep as-is).** A→H:
red/blue/green/amber/purple/sky/pink/slate, each as the *tinted triplet*
(background α≈.18, light-shade text, border α≈.35).
## 3. Typography
- **Sans (everything):** `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
sans-serif`. System stack — **no web fonts.**
- **Mono (timestamps, license keys, URLs, code):** `ui-monospace, "SF Mono",
Menlo, Consolas, monospace`. One canonical stack — snap the near-variants to it.
- **Scale (px):** `10 · 11 · 12 · 13 · 14 · 16 · 18 · 20 · 22 · 28`.
- 1011 — micro labels, badges, meta, section labels, pills, hints.
- 12 — secondary UI default (buttons, labels, stats, list titles).
- 13 — body default (descriptions, list items, transcript-adjacent).
- 14 — emphasis / larger body, drawer & settings headers.
- 16 — input text, modal `h2`, section heads.
- 18 — sub-headers, logo wordmark, large numerals.
- 2022 — headings, modal/activation titles, tier names.
- 28 — display (price). Snap strays `15→16`, `24→22`, fractionals
`12.5/11.5→12`, `10.5/9→10`.
- **Weights:** 400 normal · 500 medium · **600 semibold (the UI default)** · 700
bold (headings, badges) · 800 extrabold (tier badge, big numerals). Snap
`650→600`, `680→700`.
- **Line-height:** 1.5 body · 1.55 denser reading blocks · 1.31.4 titles · 1.25
large titles · 1 single-line badges.
- **Letter-spacing:** 0 default. Uppercase micro-labels track `0.05em`; badges
`0.04em`; tier/section labels `0.060.08em`; one display title tightens
`-0.01em`.
## 4. Component styling
- **Buttons.** *Primary:* filled `#818cf8`, white text, radius 810px, weight
600, hover lifts `translateY(-1px)` + indigo glow; disabled → `#1e293b` bg /
`#475569` text. *Secondary:* `#1e293b` fill, `#334155` border, `#94a3b8`→
`#cbd5e1` text. *Icon/ghost:* `#111827` (or transparent), `#1e293b` border,
muted glyph; hover lightens bg + border; `.active` → accent fill. *Premium:*
filled `#a855f7`.
- **Inputs.** Inset `#0f172a` (or `#1e293b` for the hero URL input), `#334155`/
`#1e293b` border; focus → accent border + `0 0 0 3px rgba(129,140,248,.15)`
ring. Mono font for keys/codes; placeholders `#64748b`/`#475569`.
- **Cards.** `#111827` bg, `#1e293b` border, radius 1014px; border lightens on
hover; expanded/active → accent border + faint `0 2px 16px …/.06` accent glow.
- **Pills / badges / chips — the "tinted triplet".** Background at α≈.1,
text in the light shade, border at α≈.2.45 of the same hue. Status pills,
tier badges, `queue-from` tags, clip badges, and speaker chips all follow this
one rule.
- **Modals.** `#111827` (settings) / `#0f172a` (buy) bg, radius 16px, sticky
header with `1px #1e293b` bottom border, `slideUp` entrance, scrim
`rgba(0,0,0,.6)` + `backdrop-filter: blur(4px)`.
- **Toasts.** Top-right stack, `#1e293b` bg, `#334155` border, slide-in from
right, auto-fade.
- **Spinner.** 3px ring, `#1e293b` track, `#818cf8` top, `spin 0.8s linear`.
- **Pipeline / tracker.** Stepped pills: idle neutral, `.active` → accent
tint+border, `.done` → green tint+border.
## 5. Layout
- **Single fluid column.** `.container` `max-width:100%`, padding `36px 24px`
(landing) tightening to `16px 24px` (results) and down on mobile.
- **Results = split screen.** `.results-left` 58% (video/player, sticky top) +
`.results-right` (scrolling chunk list), 16px gap; stacks vertically <900px.
- **Persistent left history sidebar**, 320px, *pushes* content on desktop /
overlays on mobile. **Right log drawer**, 440px, slides in.
- **Dense vertical rhythm.** Card margin 14px, chunk margin 6px, gaps 616px.
- **Spacing steps (de-facto):** `4 · 6 · 8 · 10 · 12 · 14 · 16 · 20 · 24` for
controls/gaps, `28 · 32 · 36` for section padding. Not a strict 4/8 grid —
dense and organic by design; prefer these steps over new in-between values.
## 6. Depth / elevation
**Flat by default — separation comes from 1px borders, not shadows.** Shadows are
reserved for things that genuinely float:
- Overlays/drawers/modals: `0 8px 24px …/.3` (toast) · `0 8px 32px …/.4` (video,
side drawers `±8px 0 32px`) · `0 12px 32px …/.5` (menu) · `0 20px 60px …/.5`
and `0 24px 64px …/.5.6` (panel, settings/buy modal). All `rgba(0,0,0,α)`.
- **Accent glows** signal primary/active: submit `0 4px 24px rgba(129,140,248,.3)`;
focus ring `0 0 0 3px rgba(129,140,248,.15)`; expanded chunk `0 2px 16px …/.06`;
premium tier `0 12px 40px rgba(168,85,247,.25)`.
- Overlay scrims use `rgba(0,0,0,.4.65)` + `backdrop-filter: blur(46px)`.
- Drag/drop affordance is an accent line: `box-shadow: 0 ±2px 0 0 #818cf8`.
## 7. Do's and don'ts
**Do**
- Use `#818cf8` as the *single* interactive accent; reserve purple `#a855f7`
strictly for premium/upgrade.
- Separate surfaces with 1px `#1e293b` borders that lighten to `#334155` on hover;
keep shadows for true overlays only.
- Build every status/category chip as the tinted triplet (bg α.1 / light text /
border α.2).
- Keep type dense — 1213px body, 1011px meta — with 600 as the default weight.
- Follow the surface ladder: base `#0a0e1a` → card `#111827` → inset `#0f172a`.
- Use the system font stack; mono only for timestamps / keys / URLs.
**Don't**
- Don't introduce new `#6366f1`/`#4f46e5` indigos — they migrate to `#818cf8`.
- Don't put blue `#3b82f6` on primary interactive elements; blue is info/status
(and legacy auth) only — auth should move to indigo.
- Don't add new background darks (`#0a0e17`/`#0b1120`/`#020617` are legacy dups).
- Don't use purple for non-premium UI, or the accent indigo for premium.
- Don't add fractional font sizes (12.5/11.5/10.5) or off-scale weights (650/680).
- Don't reach for a framework, web font, or heavy drop shadows — vanilla JS,
system fonts, flat-with-borders is the intentional language.
## 8. Responsive behavior
- **Breakpoints:** `900px` (primary: split→stack, sidebar push→overlay), `880px`
(tablet: top breadcrumb swaps to a hoisted mobile copy), `600px` (phone:
icon-only submit, hamburger menu, desktop toolbar/pills hidden), `640px` (share
export). Plus `≤900px landscape` → fullscreen video.
- **Mobile rules:** form inputs forced to `16px` (iOS auto-zoom guard); touch
targets 4448px; sticky top bar; full-width drawers/panels; hover-gated
controls pinned visible (touch has no hover). Use `100dvh` for full-height.
## 9. Agent prompt guide
When building or changing UI in this repo:
- Read `design/tokens.tokens.json` and pull values from it — don't eyeball new hex.
- Match the **dense dark vanilla-JS** style. The frontend is one file,
`public/index.html`, with two `<style>` blocks + ~447 inline `style=` attrs and
a render-into-`innerHTML` loop. No framework, no bundler, no web fonts — keep it
that way.
- Accent is `#818cf8`; purple is premium-only; follow the surface ladder; build
chips as the tinted triplet; system font for text, mono for timestamps/keys.
- **Three surfaces stay in sync:** the main app stylesheet, the `SHARE_PAGE_CSS`
string (the self-contained share export), and `public/auth.html`. A token change
must be reflected in all three. Auth currently uses the legacy blue accent —
new auth work should adopt indigo.
- Sanitize operator-internal strings at error boundaries (per `AGENTS.md`) — they
must never reach cloud users, design surfaces included.