Skip to content

feat(studio): docShots can write elsewhere and shoot dark mode - #779

Merged
LinuxDevil merged 5 commits into
mainfrom
redesign/d1-tokens
Oct 29, 2026
Merged

LinuxDevil merged 5 commits into
mainfrom
redesign/d1-tokens

Conversation

@LinuxDevil

@LinuxDevil LinuxDevil commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Foundation of the Studio redesign: zinc/indigo light-dark tokens, Inter Variable (latin only), lucide-react, restyled base primitives, and docShots OUT/SCHEME overrides for before/after review.

Ticket: D1 (Agent Forge Studio redesign, audit/forge-redesign/PLAN.md)

Changes

  • fix(studio): playground provider select fits its label, toast close is 24px, docShots scheme checked only when shooting
  • feat(studio): redesign tokens, Inter Variable, lucide-react and restyled base primitives
  • style(studio): drop the .design-ref mockup provenance comments
  • feat(studio): docShots can write elsewhere and shoot dark mode

Verification: focused vitest, tsc --noEmit, eslint, affected Playwright specs, light + dark screenshots reviewed; full suite and fallow run in CI.

Measurements: Studio dist 1,423,135 B (3 files) -> ~1,483,583 B (4 files; one Inter latin woff2, 48,256 B). pack-smoke 859 entries / 4.7 MB packed / 16.4 MB unpacked (budgets 940 / 5 MiB / 18 MiB). size-check tarball 16.36 MB of 16.46 MB budget.

Deviations from the brief: --success light #157e3c (brief #15803d is 4.45:1 on --success-soft); new --accent-solid-hover (brief forbids filter: brightness); .btn-ghost keeps a --border hairline (text ghost actions read as loose text without it; icon ghosts are borderless); shadows written as per-layer light-dark() colours (renders identically); .fallowrc.json ignores @fontsource-variable/inter (referenced only from CSS url()); Playground provider row widened so Inter fits its label.

Screenshot overrides for later tickets: LOUSHO_DOC_SHOTS=1 LOUSHO_DOC_SHOTS_OUT=<dir> LOUSHO_DOC_SHOTS_SCHEME=<light|dark> npx playwright test -c apps/agent-forge/playwright.config.ts docShots.

Design Brief (source of truth for theme.css)

Design Brief (binding for every ticket)

Character. Calm, precise, dense where data is (tables, trees), airy elsewhere (cards, forms, empty states). Neutral zinc greys, one indigo accent, status colours only for status. Depth from 1px hairline borders + very soft shadows, never heavy drop shadows. Dark mode is the hero: near-black canvas, slightly lifted surfaces, borders that glow faintly, not grey slabs.

Tokens (theme.css; every colour stays a light-dark(<light>, <dark>) pair; contrast.test.ts must stay green — adjust a hex by the smallest step if a pair fails, and add new text/background pairs to its PAIRS list).

token light dark
--bg (app canvas behind panels) #f6f6f7 #0a0a0c
--surface (cards, panels, tables) #ffffff #111114
--surface-2 (inputs, table header, hover) #f2f2f4 #18181c
--surface-3 (NEW: pressed / selected neutral, code blocks) #e9e9ec #202026
--border #e4e4e8 #26262c
--border-strong (NEW: input borders, focused cards) #d2d2d8 #34343c
--text #18181b #f4f4f5
--text-muted #52525b #a1a1aa
--text-faint #5f5f68 #8a8a94
--accent #4f46e5 #8b8cf8
--accent-soft #eef0ff #1e1d3f
--accent-solid #4f46e5 #5b54e8
--on-accent #ffffff #ffffff
--success / --success-soft #15803d / #e3f6e9 #4ade80 / #0f2a1b
--warning / --warning-soft #a15c07 / #fdf1d8 #fbbf24 / #2f2408
--danger / --danger-soft #c0262d / #fde8e8 #f87171 / #3a1517
--info / --info-soft (NEW) #0369a1 / #e3f2fb #38bdf8 / #0b2635
--violet / --violet-soft (NEW, LLM/agent accent) #6d28d9 / #f1eafe #a78bfa / #241a3d

Non-colour tokens (NEW, plain values):

  • Radius: --radius-sm: 6px (pills' inner, small buttons, inputs), --radius: 8px (buttons, inputs, menus), --radius-lg: 12px (cards, panels, dialogs, canvas nodes), --radius-full: 999px (pills, avatars).
  • Space scale: --space-1: 4px … --space-2: 8px, --space-3: 12px, --space-4: 16px, --space-5: 20px, --space-6: 24px, --space-8: 32px, --space-10: 40px. Page gutter 24px desktop, 16px narrow.
  • Shadow: --shadow-sm (hairline lift for cards: 0 1px 2px rgb(0 0 0 / 0.04) light, 0 1px 2px rgb(0 0 0 / 0.5) dark), --shadow (menus/popovers: 0 4px 12px -2px rgb(16 16 24 / 0.08), 0 2px 4px -2px rgb(16 16 24 / 0.06) light; dark 0 8px 24px -6px rgb(0 0 0 / 0.6) + 0 0 0 1px rgb(255 255 255 / 0.04)), --shadow-lg (dialogs, command palette: 0 24px 48px -12px rgb(16 16 24 / 0.18) light; dark 0 24px 64px -12px rgb(0 0 0 / 0.75)).
  • Focus ring: --ring: 0 0 0 3px color-mix(in srgb, var(--accent) 28%, transparent) plus border-color: var(--accent) on inputs; buttons use outline: 2px solid var(--accent); outline-offset: 2px on :focus-visible.
  • Motion: --ease: cubic-bezier(0.2, 0, 0, 1), --dur-fast: 120ms, --dur: 180ms. Wrap transitions so @media (prefers-reduced-motion: reduce) disables them.
  • Chart series: --chart-1 … --chart-6 light #4f46e5 #0891b2 #d97706 #db2777 #059669 #7c3aed, dark #8b8cf8 #22d3ee #fbbf24 #f472b6 #34d399 #c4b5fd (as light-dark pairs).
  • Type: --font-ui: 'Inter Variable', 'Inter', 'Geist', ui-sans-serif, system-ui, 'Segoe UI', sans-serif; --font-mono: 'JetBrains Mono', 'Geist Mono', ui-monospace, 'Cascadia Code', 'SF Mono', Menlo, monospace. Bundle Inter Variable (latin subset only) from @fontsource-variable/inter as an agent-forge devDependency, imported once in main.tsx; no CDN. font-feature-settings: 'cv11', 'ss01' on body; tabular numbers (font-variant-numeric: tabular-nums) on every numeric table cell, metric and duration.
  • Type scale: body 13.5px/1.5; table 13px; small/meta 12px; label/overline 11px 600 uppercase tracking 0.04em in --text-faint; page title 18px 600 tracking -0.01em; card title 13.5px 600; metric value 24px 600 tabular.

Icons. lucide-react (ISC) as an agent-forge devDependency — bundled by Vite, so nothing is added to the SDK's runtime dependencies. 16px in nav, buttons and table actions, 14px inside pills/chips, stroke-width 1.75. Icon-only buttons always carry aria-label. Replace text glyphs (▾ ▸ × + ✓ ⌘) with icons.

Components (look).

  • Buttons: height 32px (sm 28px), radius 8, 13px 500. Variants: primary (accent-solid fill, subtle inner top highlight), secondary (surface fill + border-strong hairline + shadow-sm), ghost (transparent, surface-2 on hover), danger (danger text, danger-soft on hover), success (Run). Leading icon slot. Hover/active: background shift, never filter: brightness.
  • Inputs/selects/textarea: 32px, surface bg, border-strong, radius 8, focus = accent border + --ring. Selects get a chevron icon (background-image or wrapper).
  • Status pill: 20px tall, radius-full, 12px 500 sentence case (not uppercase), 6px dot in currentColor; tones ok/error/warning/running/neutral + violet. Running dot pulses (reduced-motion safe).
  • Cards: surface, border, radius-lg, shadow-sm, 16–20px padding, header row (title + muted description left, actions right).
  • Tables (DataTable): full width inside a card; sticky 36px header in surface-2 with 12px 500 --text-muted labels; rows 40px comfortable / 32px compact; hairline row dividers; hover row surface-2; selected row accent-soft with a 2px accent left inset (box-shadow inset); numbers right-aligned tabular; first column text 500; error text in danger with an alert-circle icon; truncation with title tooltip.
  • Segmented control (time ranges, tabs-in-toolbar): one rounded container (surface-2, radius 8, 2px padding), selected segment = surface + shadow-sm.
  • Tabs (page-level, EvalsTabs, drawer tabs, inspector tabs): underline style — 13px 500 muted text, active text + 2px accent underline, hover text.
  • Page header (ui/PageHeader.tsx, NEW): title (h1 18px 600), optional description (13px muted), right-side actions slot, optional breadcrumbs above title, bottom hairline; 56–64px tall; every routed screen uses it.
  • Empty states: centered in their card, 40px icon tile (surface-2, radius-lg, muted icon), title 14px 600, hint 13px muted max 48ch, primary action button.
  • Loading: ui/Skeleton.tsx (NEW) shimmer blocks (surface-2 → surface-3 gradient, reduced-motion = static); tables show 6 skeleton rows; cards show skeleton lines; never a bare "Loading…" text alone.
  • Metric card (ui/MetricCard.tsx, NEW): label (overline), value 24px, optional delta (▲/▼ icon, success/danger tone) and sparkline (tiny inline SVG, --chart-1).
  • Charts (TimeSeriesChart): area fill under lines (gradient from series colour at 18% to 0), 2px lines with round joins, dashed --border gridlines, axis text 11px --text-faint, hover crosshair + floating tooltip card (surface, shadow, series dots, values tabular), legend as pill chips that toggle series. Colours from --chart-N.
  • Command palette: centered 640px dialog, radius-lg, shadow-lg, backdrop blur 4px over a 40% scrim, 48px search row with search icon and Esc kbd hint, grouped results with section labels, 36px rows with icon + label + right-aligned kbd/shortcut, active row accent-soft, footer hint row (↑↓ navigate, ↵ open, esc close).
  • Toasts: surface, radius-lg, shadow, leading status icon in tone colour (replace the coloured left border).
  • Kbd: <kbd> styled 18px tall, surface-2, border, radius-sm, mono 11px.

Shell.

  • Left nav 232px, collapsible to a 56px icon rail (toggle button in the nav header, state remembered in localStorage forge.nav.collapsed; collapsed items show a tooltip and keep aria-label). Logo mark (small indigo rounded square with an anvil/hammer or sparkles icon) + "Agent Forge" wordmark + muted version tag.
  • Nav sections Build / Observe / Evaluate / Assets with overline labels; items 32px, radius 8, icon + label; hover surface-2; active = surface-3 (light) / surface-2 (dark) background + text color + accent icon + 2px accent indicator bar at the left edge. Settings pinned bottom with the collector status card.
  • Collector status card at the nav bottom: dot (success / danger) + "Collector running" / "Collector unreachable", the URL in mono 11px faint, compact.
  • Top of each screen: PageHeader. The Agents screen keeps its builder toolbar but restyled as a 52px toolbar: breadcrumb (Agents / name with status pill), center model badge (provider · model chip), right actions grouped: [Debug] [Stop][Run] | [Import][Export] [Save primary]; secondary actions may collapse into a "more" menu at narrow widths.
  • Narrow (≤ 860px): nav becomes a drawer (existing behaviour), page gutter 16px, no horizontal page scroll.

Pages (each ticket below). Functionality, routes, URL state, test ids, accessible names and keyboard behaviour stay identical unless a ticket says otherwise.

🤖 Generated with Claude Code

LinuxDevil and others added 5 commits October 29, 2026 07:00
LOUSHO_DOC_SHOTS_OUT=<dir> overrides the output directory and
LOUSHO_DOC_SHOTS_SCHEME=light|dark picks the colour scheme (anything else
fails fast), so a restyle can be reviewed before and after in both themes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Studio redesign Design Brief is now the source of truth for the look,
implemented by theme.css; the old mockup references no longer apply.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…led base primitives

theme.css implements the redesign brief: zinc neutrals with --surface-3 and
--border-strong, indigo accent (+ --accent-solid-hover), status tones with
new --info-soft and --violet/--violet-soft, chart series, radius, space,
shadow (light-dark() layer colours), ring, motion and type-scale tokens.
Light --success is #157e3c (brief #15803d reads 4.45:1 on --success-soft).

Inter Variable ships as one latin-only woff2 (fonts.css, a single
@font-face pointing at @fontsource-variable/inter's latin wght file).
lucide-react draws the toast close icon.

base.css restyles buttons (secondary/primary/ghost/danger/success, -sm,
-icon), sentence-case status pills with a pulsing running dot and a violet
tone, fields, inputs, a chevron select, chips, the switch, toggle rows, kbd
and the scrollbar; every transition is off under reduced motion.
contrast.test.ts gains info, violet, surface-3, accent-solid-hover and
accent-soft pairs. The narrow top bar gets min-width: 0 so the wider pill
and buttons never widen the page at 375px.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s 24px, docShots scheme checked only when shooting

Inter is wider than the old fallback, so the Playground's provider/model row
now favours the select (1.4fr / 1fr) and "custom (provider/model)" shows whole.
The toast close button gets a 24x24 hit target. LOUSHO_DOC_SHOTS_SCHEME is
validated only when LOUSHO_DOC_SHOTS is set, so a stray value cannot break
collection of a normal e2e run. Docs: drop a stray triple space.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Picks up the docShots LOUSHO_DOC_SHOTS_OUT / LOUSHO_DOC_SHOTS_SCHEME paragraph in docs/agent-forge.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@LinuxDevil
LinuxDevil merged commit c6f2cfd into main Oct 29, 2026
2 checks passed
@LinuxDevil
LinuxDevil deleted the redesign/d1-tokens branch October 29, 2026 04:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant