Keystack · staging.keystack.com · design review

Keystack staging is one broken theme away from looking finished.

Khoa's right that it looks rough — but it's not dozens of unrelated bugs. Almost everything traces to one root cause: the signed-in app runs on the dark "EmuBrain" family theme, but the content (headings, body, labels, form controls, buttons) is still colored for a light background — so text renders dark-on-dark and is barely legible on every surface. Fix the theme's colour contract and ~80% of the "ugly" disappears at once. This is the same move as the Catalogue panel: find the systemic cause, not just the symptoms.

Walked staging.keystack.com · via CF Access service token + demo gate Created a family account, walked Team · Catalogue · Tasks · Children · Gallery · Chat · Account Owner: Rafi (keystack-web) · design-only

The one finding that matters

P0 · App-wide unreadable text on the dark theme

What happens: the authed shell renders on a near-black background (the "EmuBrain" family theme), but headings, body copy, metric labels/values, form fields and buttons keep their light-theme dark colours — e.g. dark-grey text on #0d0f12. The result is dark-on-dark across the whole app: "Your family team", the metric numbers, "Agent readiness", the Catalogue card copy, the Account settings — all present, all nearly invisible. Only the agent photos and the top-right user chip read.

Why it's systemic: it's not per-page — it's the theme's colour tokens. The dark theme flips the background but not the text / surface / border / control tokens (or the theme was designed to sit on a background image — note the Account page's "Readability overlay" slider — and with no image the text has nothing to sit on). Either way the contrast floor is missing.

The fix (one contract, applied once): give the theme system a real light+dark token pair — --tx/--tx-muted/--surface/--line/--control-bg — and make the dark theme redefine all of them, not just the background. Every heading/label/input/button must read from tokens, never hardcoded hexes. Guarantee WCAG AA (4.5:1) for body text and controls on the themed background, and make the "Readability overlay" enforce a minimum contrast floor so a background image can never push text below AA. Ship the default theme already readable.

The evidence (every surface, same failure)

P0

Team / Overview — the landing page is unreadable

rail → Team · the first thing anyone sees after login
Keystack Team page rendering dark-on-dark
Wrong
"WORKSPACE / Your family team", the "New task" button, the four metrics (SERVICE OK · AVAILABLE AGENTS 5 · HIRED AGENTS 0 · WORK ORDERS 0) and "Agent readiness / No agents hired yet" are all dark-grey on near-black. The header ("Keystack / Your managed agent workspace / Checking API") is also dark-on-dark and jammed to the very top-left edge.
Fix
Theme text tokens (P0 above). Separately: the header row needs the page gutter/container it's missing, and the status should resolve out of "Checking API" (see P1s).
P0

Account / Appearance — the theme control itself, and the fields, are invisible

rail → Account · where "Family theme = EmuBrain" is set
Keystack Account/Appearance page dark-on-dark
Wrong
Every label ("Family theme", "Background", "Readability overlay", "AI connections", "OpenAI / Not connected") and every control (the theme select, the API-key inputs, the slider) is dark-on-dark. The select and inputs have near-invisible borders and dark text on a dark field — you can't tell they're editable.
Note
This page is the smoking gun: Family theme = "EmuBrain" (dark) + a "Readability overlay" slider confirm the theme is background-driven. The contrast contract is the missing piece.
Fix
Tokenise control colours: --control-bg, --control-tx, --control-line that flip with theme; inputs/selects get a visible border + AA text in both themes. Add a visible :focus-visible ring (currently none).
P0

Catalogue — only the agent photos survive

rail → Catalogue · the tenant "hire an agent" grid
Keystack Catalogue grid dark-on-dark
Wrong
The agent cards render their photos fine, but every card's title (Project Coordinator, Software Engineer, Code Reviewer/QA…), description, "Requires anthropic/openai" meta, the "Hire" buttons, the name inputs and "Not hired" status are all dark-on-dark. The page reads as a wall of photos with no legible text.
Fix
Same theme-token fix. Card surfaces should use --surface/--surface-2; the "Hire" button becomes a real primary in both themes; the name field gets --control-*.
P1

Chat — a full agent video plays with no agent selected

rail → Chat
Keystack Chat page with an avatar video and no agent chosen
Wrong
Left half is a full-bleed digital-avatar video of a person, while the state is "No available agents · connect a provider or wait for approval" and the right panel says "Choose an active agent to open the conversation." A large avatar of nobody-in-particular shows before any agent is chosen — plus the usual dark-on-dark labels.
Fix
Gate the avatar stage on an active agent; until one is chosen show a calm placeholder (agent picker / "pick an agent to start"), not an autoplaying face. Then apply the theme tokens.
P1

Header: cramped to the edge + a status that never resolves

every authed page (top bar)
Wrong
The brand block ("Keystack / Your managed agent workspace / Checking API") sits flush against the top-left viewport edge with no gutter, and the status is stuck on "Checking API" even though the page below shows "SERVICE OK". Dark-on-dark on top of that.
Fix
Wrap the header content in the same max-width/gutter container the body uses (it's missing it). Resolve the health check to a real state (Live / Degraded / Offline) and colour the dot semantically; don't leave it on "Checking".
P2

Sign-in (the one light screen) — duplicate "Log in" & three button colours

/ before auth (light-themed)
Keystack sign-in screen
Wrong
The auth toggle's active tab is labelled "Log in" (dark navy) and the submit button below is also "Log in" (teal) — same word, two buttons, two colours. "Create family account" is a third colour (slate). No unified button system; the brand header is edge-cramped here too; focus rings are inconsistent (email has one, password doesn't).
Fix
Rename the tab pair to "Sign in / Create account" (mode toggle) and keep one primary submit ("Sign in"). Unify buttons into .btn + .btn--primary/.btn--ghost variants driven by tokens; add one consistent :focus-visible style; give the header its gutter.
P2

Positional colour with no meaning + no interaction polish

Catalogue/agent cards & buttons
Wrong
Agent cards alternate a teal / blue top-border by position (odd vs even card), which encodes nothing — it just looks noisy. Buttons have no hover/transition, so nothing feels interactive.
Fix
Drop the positional border (or map colour to a real attribute — provider, status). Add a shared hover/active state + a 120ms transition on all interactive elements.

Fix plan — order for Rafi

Ship in this order (keystack-web)

  1. 1 · The theme colour contract (P0). Define a full light+dark token set (--tx, --tx-muted, --surface, --surface-2, --line, --control-bg/-tx/-line, --btn-*); make the "EmuBrain"/dark theme redefine all of them; route every component through tokens; verify AA (4.5:1) on both themes. Make the "Readability overlay" enforce a contrast floor. This alone clears the "ugly" across every surface.
  2. 2 · Header container + status. Add the missing gutter/max-width wrapper; resolve "Checking API" to a real Live/Degraded state with a semantic dot.
  3. 3 · Controls & buttons. One .btn system with primary/ghost variants + :focus-visible + hover; tokenised inputs/selects with visible borders.
  4. 4 · Chat empty state. Don't render the avatar video until an agent is active; show a picker/placeholder.
  5. 5 · Sign-in polish. Rename the toggle to Sign in / Create account, one primary submit, unified buttons, header gutter.
  6. 6 · Housekeeping. Drop positional card borders; add interaction transitions.

I can turn #1 into an exact token table + before/after mock (same as the Catalogue spec) and pair with you on the rollout — say the word. This audit is design-only; implementation is yours.

Keystack staging visual audit & fix plan · Sana → Lena / Rafi · 2026-07-24 · grounded by walking staging.keystack.com (CF Access + demo gate, family test account) across all authed surfaces. Evidence screenshots are real captures. No product code touched.