Engineering docs
UI Standard — one light system (REVISED 2026-08-30, founder decision)
Last updated Oct 22, 2026 · 5 sections
Premium and clean, LIGHT everywhere — the Superpower model: warm off-white canvas, near-black ink,
mono labels, one hot accent, saturated color reserved for data. The earlier dark "control room"
face is retired (founder reviewed it and chose light); do not reintroduce dark surfaces.
One token set in packages/shared/design-tokens/tokens.json; web maps it into Tailwind config.
Never hardcode a color/size in a component.
The one face (everything: landing, booking, dashboards, ops, auth)
- Canvas
#F7F6F3(paper) / raised cards#FFFFFFwith hairline borders#16181A/10. - Ink
#16181A, muted#5F6462, faint#9A9E9B. - Accent (single, hot):
#D85A30(signal coral — CTAs, active states, the brand's temperature). - Data ramp (charts/metrics only, never chrome): green
#0F7B4D(good/watchers), blue#185FA5(neutral series), amber#BA7517(warnings), red#A32D2D(errors/quarantine). Charts on white panels with faint gridlines — Bloomberg-on-paper, not neon-on-black. - Screens themselves (hero visuals, player frames, screen thumbnails) remain dark objects — a dark device on a light canvas is the Superpower product-photography move and keeps the glow story.
- Dashboards stay premium via scale + mono discipline: big 48-64px mono numbers in ink, definitions under every stat, generous card padding, tabular numerals everywhere.
Typography
- Display + body: Instrument Sans (or Inter fallback). Weights 400 and 500 ONLY — hierarchy comes from size, spacing, and case, never from bolding.
- Data values, timestamps, units: JetBrains Mono (or Fragment Mono) — mono is for numbers only, never decorative text.
- Scale: 34/26/20/16/14/12. Numbers on dashboards may go 48–64.
The third register: Marquee (marketing/landing only)
The public landing page sells attention, so it may break the app-face austerity — deliberately and only there. LIGHT cinematic base (paper canvas, like superpower.com), oversized display type (up to 96px hero), and the glow story inverted: dark screen-objects glowing ON the light canvas (the product photographed in daylight, screens alight). No dark page sections. Product UI (real dashboard components with demo data) is the hero imagery — never stock photos. Scroll-triggered reveals and number count-ups are allowed; keep them 300ms-class, never parallax soup. Everything below the fold must still pass AA contrast and render fine with JS disabled (no content behind animation). App faces (booking + control room) keep the base rules — no marquee effects there.
Rules
- Radius: 16 cards / 12 inputs / pill buttons. Borders (1px, low-contrast) for structure; shadows only on floating elements (menus, dialogs) and always layered low-alpha.
- No gradients-as-decoration, no glassmorphism, no emoji in UI chrome. Icons: Lucide, outline, 1 color.
- Motion: 150–200ms ease-out, only on state change (numbers ticking, rows appearing). No idle animation.
- Empty states always say what to do next with one button. Errors are sentences, not codes.
- Booking flow max 4 steps: Creative → Screens & dates → Review → Done. Progress shown as text ("Step 2 of 4"), not a widget.
- Dashboard hierarchy: one hero row (Plays · Watchers · Avg attention · Attention rate), then the funnel, then breakdowns. Every metric card shows the definition on hover ("Watchers: people whose face was oriented toward the screen ≥1s").
- Accessibility: AA contrast minimum on both faces; touch targets ≥44px; the whole booking flow must work on a phone browser.
App shell (REVISED 2026-10-22 — sidebar + soft canvas)
Signed-in pages (advertiser portal, ops portal) sit in components/app-shell.tsx:
- Left sidebar (240px, white) grouped by job, with badges (e.g. approvals waiting) and the
account card at the bottom; collapses to a top bar + drawer under
lg. - Canvas
page#F3F4F8(cool tint) behind white cards withshadow-card. Paper#F7F6F3stays the marketing/auth canvas. - Page header greets the person (
Good morning, Priya), shows the date, and carries the page's one primary action + the global range picker. - Pastel tints (
tint.blue/green/amber/violet/rose/ink) are for KPI icons, status pills and schedule bars — the accent stays reserved for the one primary action per page. - Widgets in
components/widgets.tsx:KpiCard(delta vs previous period + sparkline),WidgetCard,ProgressBar,Gauge,ScheduleTimeline(hour axis, a row per screen),AlertStrip,Checklist. Weight 600 is allowed for KPI values and page titles. - Homes: advertisers land on
/dashboard(Home), ops on/ops(Today)./campaignsand/reportsare their own pages; old?tab=links redirect.