Doom 64 design-token system with light/dark theme#132
Conversation
Introduce the app's first semantic design-token layer and render the v0 "Doom 64" palette across the whole UI, replacing ~46 files of hardcoded inline colors. - globals.css: :root (light) + .dark (dark) oklch tokens, mapped via `@theme inline` so a class swap re-cascades at runtime; `--edit`/`--portal` app-specific tokens; themed `--xy-*` React Flow vars (scoped to [data-canvas-scope]); a pointer-events:none retro scanline overlay. - next-themes light/dark toggle (class strategy, dark default, no FOUC via suppressHydrationWarning + pre-paint script); ThemeProvider shim + ThemeToggle. - Oxanium display font for headings (font-display); Geist stays body. - Sweep every surface to semantic utilities (bg-card/bg-popover/bg-muted, text-foreground/text-muted-foreground, bg-primary [blood red], text-destructive [orange], border-edit, border-portal); border-2 + lines grid for the retro panel look. - Docs: ADR-0045 + CONTEXT.md theming section. Verified: pnpm check + 508 vitest tests green; dark/light verified in-browser (no FOUC), zoom/select interactions intact. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address review feedback on the Doom 64 theme: - No-FOUC default: :root now carries the DARK palette (the app's default), with `:root.light` overriding for light mode (higher specificity so it wins regardless of source order). next-themes gets an explicit value map so it ADDS the `.light` class. The classless first paint can no longer flash a wrong palette. - Fix the actual flash source: the canvas island's dynamic-import loading fallback (index.tsx) still hardcoded bg-[#1b1c33] (indigo). Now bg-background. - connection-edge.tsx was entirely unconverted — grep skips NUL-containing files as binary (it uses a NUL cuid-joiner), so the sweep missed it. Converted to tokens. - Connections + node connection-dots now render in Doom red (--primary), matching the v0 chart, for contrast against the grid; selected edges brighten to foreground. - Soften canvas grid lines to ~28% border alpha (low contrast). - color-scheme set per theme so native controls/scrollbars match. Verified in-browser: no indigo FOUC (dark from first paint), light mode applies the light palette, red edges/dots + faint grid in both themes; pnpm check green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…cript warning)
next-themes renders its no-FOUC <script> from a client component, and React 19
warns on every client-rendered inline <script> ("Scripts inside React components are
never executed when rendering on the client"). The app only needs class-based
light/dark with a dark default + localStorage, so replace the dependency with ~40
lines:
- src/lib/theme.ts (plain module): `themeInitScript`, a literal string the SERVER
root layout inlines as a <script> at the top of <body>. Runs before first paint,
applies the stored/default theme class + color-scheme to <html> — no FOUC, and
server-rendered so React never client-renders a <script> (no warning).
- theme-toggle.tsx: `useTheme` via useSyncExternalStore (MutationObserver on the
<html> class) — no setState-in-effect, no hydration error when the server snapshot
("dark") differs from the client's actual theme. setTheme swaps class + writes
localStorage.
- Remove next-themes + the client provider shim.
Docs (ADR-0045, CONTEXT.md, globals.css comment) updated to the in-house mechanism
and to the dark-default `:root` / `:root.light` token structure.
Verified in-browser: 0 console errors, no FOUC (dark from first paint), toggle works
both ways with the palette flipping; pnpm check green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Too much diff to scan? Review this PR in Change Stack to start with the highest-impact changes. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThis PR adds a Doom 64 semantic design-token system, injects a server-side theme init script and client ThemeToggle, updates RootLayout and fonts, and migrates UI components (canvas, trace, dialogs, panels, primitives) from hardcoded colors to tokenized Tailwind classes. ChangesDesign-Token System Migration
🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly Related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/adr/0045-design-token-system-doom-64-theme.md`:
- Around line 41-42: Update the ADR sentence that currently reads "Tailwind v4
wraps any color in `color-mix`. oklch + `color-mix` need Safari 16.2+/Chrome
111+ — a modern-browser baseline we accept." to reference Tailwind v4's
documented minimums by changing "Safari 16.2+" to "Safari 16.4+" so the
statement matches Tailwind's compatibility guidance (retain the rest of the text
including `color-mix`, oklch, and Chrome 111+).
In `@src/app/_components/connect-agent.tsx`:
- Around line 170-171: The code block rendering revealedToken currently uses a
hardcoded background class ("bg-black/40") which can break contrast in light
mode; update the className on the <code> element that renders revealedToken to
use semantic surface and text tokens (the component/file is connect-agent.tsx
and the element is the <code> with className containing "flex-1 ...
text-foreground") — replace the hardcoded bg with the appropriate semantic
background token (e.g., a surface token) and pair it with the matching semantic
foreground/text token so contrast is stable across themes while preserving the
existing layout classes (flex-1, overflow-x-auto, rounded-lg, px-3, py-2,
font-mono, text-sm).
In `@src/app/_components/mcp-instructions.tsx`:
- Around line 68-69: The pre block uses a hardcoded dark backdrop (bg-black/40)
which can reduce contrast in light themes; in the <pre> element that renders
{snippet} inside mcp-instructions.tsx, replace the literal bg-black/40 with a
semantic background token (for example BG tokens like bg-muted, bg-surface or
bg-secondary with an opacity variant such as bg-muted/40) so the background
adapts to theme, keep existing text token (text-foreground) and other classes
(overflow-x-auto rounded-lg px-3 py-2 font-mono text-sm whitespace-pre)
unchanged.
In `@src/app/p/`[slug]/_canvas/copy-markdown.tsx:
- Line 52: Replace the hardcoded focus ring color token
"focus-visible:ring-white/40" in the class string (the "flex items-center ..."
literal in copy-markdown.tsx) with a semantic ring token so focus is visible in
both light and dark themes (for example "focus-visible:ring-ring/40" or the
project's semantic equivalent); update every occurrence (also the one referenced
at lines 90-90) so all focus-visible classes use the semantic token instead of
"white/40".
In `@src/app/p/`[slug]/_components/invite-create.tsx:
- Around line 177-178: The code block uses a hardcoded class "bg-black/40" which
can produce low contrast in light theme; update the code element in the
invite-create component (the <code> element that renders inviteUrl) to use
semantic token classes (e.g., replace "bg-black/40" with a token like "bg-muted"
or "bg-card" and ensure the foreground token aligns such as
"text-muted-foreground" or "text-foreground" so both light and dark themes keep
proper contrast), keeping the rest of the utilities (flex-1 overflow-x-auto
rounded px-2 py-1.5 font-mono text-xs) intact.
In `@src/app/p/`[slug]/_components/share-menu.tsx:
- Line 59: In the ShareMenu component's button/menu item className (the long
Tailwind string containing "focus-visible:ring-white/40"), replace the hardcoded
white alpha token with a semantic ring token (for example
"focus-visible:ring-ring" or "focus-visible:ring-primary/40") so the focus ring
uses the theme-aware token; update the className in _components/share-menu.tsx
where the string includes "focus-visible:ring-white/40" to the chosen semantic
token to ensure consistent focus contrast across themes.
In `@src/styles/globals.css`:
- Line 67: The CSS defines --radius only inside :root.light so when the default
:root (dark/initial) is used those derived variables (--radius-sm, --radius-md,
--radius-lg, --radius-xl) resolve from an undefined base; fix by declaring a
fallback/base --radius in the global :root (or in :root.dark) before the theme
blocks so the derived vars have a defined value on first paint—update the
declaration near :root (or add a matching --radius inside :root.dark) and ensure
--radius-sm/md/lg/xl continue to compute from that base.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: fbcd3cde-9d3e-440f-bb3f-02842e6e037f
📒 Files selected for processing (50)
CONTEXT.mddocs/adr/0045-design-token-system-doom-64-theme.mdsrc/app/_components/connect-agent.tsxsrc/app/_components/copy-button.tsxsrc/app/_components/delete-project-dialog.tsxsrc/app/_components/mcp-instructions.tsxsrc/app/_components/post.tsxsrc/app/_components/project-dashboard.tsxsrc/app/_components/theme-toggle.tsxsrc/app/connect/page.tsxsrc/app/i/[token]/_components/invalid-invite.tsxsrc/app/layout.tsxsrc/app/p/[slug]/_canvas/add-component.tsxsrc/app/p/[slug]/_canvas/attach-spec-section.tsxsrc/app/p/[slug]/_canvas/boundary-proxy.tsxsrc/app/p/[slug]/_canvas/breadcrumbs.tsxsrc/app/p/[slug]/_canvas/canvas.tsxsrc/app/p/[slug]/_canvas/component-detail-panel.tsxsrc/app/p/[slug]/_canvas/component-docs-editor.tsxsrc/app/p/[slug]/_canvas/component-node.tsxsrc/app/p/[slug]/_canvas/connect-to-palette.tsxsrc/app/p/[slug]/_canvas/connection-edge.tsxsrc/app/p/[slug]/_canvas/copy-markdown.tsxsrc/app/p/[slug]/_canvas/embed-project.tsxsrc/app/p/[slug]/_canvas/index.tsxsrc/app/p/[slug]/_canvas/kind-palette.tsxsrc/app/p/[slug]/_canvas/spec-conflict-modal.tsxsrc/app/p/[slug]/_components/invite-create.tsxsrc/app/p/[slug]/_components/manage-access-dialog.tsxsrc/app/p/[slug]/_components/member-add.tsxsrc/app/p/[slug]/_components/project-header.tsxsrc/app/p/[slug]/_components/share-menu.tsxsrc/app/p/[slug]/_components/view-only-badge.tsxsrc/app/p/[slug]/_trace/trace-edge.tsxsrc/app/p/[slug]/_trace/trace-flow.tsxsrc/app/p/[slug]/_trace/trace-node.tsxsrc/app/p/[slug]/n/[nodeId]/error.tsxsrc/app/p/[slug]/n/[nodeId]/page.tsxsrc/app/p/[slug]/not-found.tsxsrc/app/p/[slug]/page.tsxsrc/app/p/[slug]/trace/[traceId]/page.tsxsrc/app/p/[slug]/trace/_trace-view.tsxsrc/app/p/[slug]/trace/page.tsxsrc/app/p/[slug]/trace/trace-island.tsxsrc/app/page.tsxsrc/components/ui/command.tsxsrc/components/ui/dialog.tsxsrc/components/ui/tooltip.tsxsrc/lib/theme.tssrc/styles/globals.css
- globals.css: --radius was only defined in :root.light, leaving it undefined on the dark/default path (and --radius-sm/md/lg/xl derived from it). Moved to the :root/.dark default block (theme-independent). - Tokenize hardcoded dark code/token blocks (bg-black/40 -> bg-muted) in connect-agent, mcp-instructions, invite-create so they stay readable in light mode. - Tokenize hardcoded focus rings (ring-white/40 -> ring-ring) in copy-markdown and share-menu so keyboard focus stays visible in light mode. - ADR-0045: correct the browser baseline to Tailwind v4's documented floor (Safari 16.4+/Chrome 111+/Firefox 128+). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fixes Applied SuccessfullyApplied 7 CodeRabbit feedback items across 7 files. Files modified:
Commit:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.env.example:
- Around line 21-22: The .env.example exposes AUTH_GITHUB_ID and
AUTH_GITHUB_SECRET but the auth config never wires a GitHub provider, so either
register GitHub in the auth providers or mark the env vars as
optional/unimplemented; specifically, add the GitHub provider to the providers
array in the auth config (the "providers" export in src/server/auth/config.ts)
using the same env vars (AUTH_GITHUB_ID, AUTH_GITHUB_SECRET) or update
.env.example to comment/annotate those keys as "not wired" to make intent clear.
Ensure the provider name and env var names match exactly so the runtime config
picks them up.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e7777a80-75dc-4d47-b3b5-8f0222e2750f
📒 Files selected for processing (8)
.env.exampledocs/adr/0045-design-token-system-doom-64-theme.mdsrc/app/_components/connect-agent.tsxsrc/app/_components/mcp-instructions.tsxsrc/app/p/[slug]/_canvas/copy-markdown.tsxsrc/app/p/[slug]/_components/invite-create.tsxsrc/app/p/[slug]/_components/share-menu.tsxsrc/styles/globals.css
✅ Files skipped from review due to trivial changes (5)
- src/app/p/[slug]/_components/invite-create.tsx
- src/app/p/[slug]/_canvas/copy-markdown.tsx
- src/app/_components/connect-agent.tsx
- docs/adr/0045-design-token-system-doom-64-theme.md
- src/app/p/[slug]/_components/share-menu.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- src/app/_components/mcp-instructions.tsx
- src/styles/globals.css
| AUTH_GITHUB_ID="" | ||
| AUTH_GITHUB_SECRET="" |
There was a problem hiding this comment.
GitHub env vars are documented but not wired into auth providers.
Line 21 and Line 22 add GitHub credentials, but current auth config only registers Discord (src/server/auth/config.ts: providers). This can mislead setup and docs expectations unless GitHub provider wiring is included (or these vars are clearly marked as planned/not yet active).
🧰 Tools
🪛 dotenv-linter (4.0.0)
[warning] 21-21: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 22-22: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.env.example around lines 21 - 22, The .env.example exposes AUTH_GITHUB_ID
and AUTH_GITHUB_SECRET but the auth config never wires a GitHub provider, so
either register GitHub in the auth providers or mark the env vars as
optional/unimplemented; specifically, add the GitHub provider to the providers
array in the auth config (the "providers" export in src/server/auth/config.ts)
using the same env vars (AUTH_GITHUB_ID, AUTH_GITHUB_SECRET) or update
.env.example to comment/annotate those keys as "not wired" to make intent clear.
Ensure the provider name and env var names match exactly so the runtime config
picks them up.
copy-markdown's toolbar container still used bg-black/40 while every sibling canvas toolbar (add-component, embed-project, edge chips) is tokenized — it read as a dark bar in light mode. Switch to bg-card/80 + border-border to match. The dialog bg-black/60 (modal scrim) and the native <select> <option> text-black (OS-rendered popups) are intentionally left. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…#138) Group the Add palette (#129) and Copy menu (#130) triggers into a single floating top-left toolbar shell with one design language, resolving the three competing radius/background systems the free-standing controls carried. - Shell: the top-left Panel becomes a `bg-card/85 backdrop-blur` token surface (theme-aware, flips light/dark) with one nested radius scale — shell rounded-xl → triggers rounded-lg → menu rows rounded-md. - Add trigger: the bg-primary (Doom red) PRIMARY fill; Copy trigger: the bg-muted SECONDARY ghost. Each shows a pressed-while-open state via Base UI's data-popup-open. The Add palette panel is aligned to the header Share-menu surface (rounded-xl + shadow-xl). - Viewer (no edit): the shell is unconditional and Copy is ungated, so a viewer sees a clean Copy-only toolbar. Note: #131 predated the #132 Doom-64 token system (ADR-0045), which retired purple (→ primary red) and bans hardcoded color literals. Per the maintainer, the shell uses the bg-card/85 token surface rather than the issue's literal bg-black/40, and "purple" is read as primary/red — both already the codebase's reality. - CONTEXT.md: new `### Canvas toolbar` glossary entry tying the Add palette + Copy menu + shell together; cross-links on both entries; a scoped primary-fill note in the Theming section. Cross-refs ADR-0045. The breadcrumb Copy mount stays outside the shell (compact). No backend / tRPC / schema change. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Adopts the Doom 64 design system (from the linked v0 design) across the app as a centralized, theme-switchable design-token layer — replacing ~46 files of hardcoded inline colors. See ADR-0045.
What changed
src/styles/globals.css): semantic CSS variables (background/foreground,card,popover,primary,secondary,accent,muted,destructive,border,ring, charts, sidebar) + two app-specific tokens--edit/--portal, mapped into Tailwind v4 via@theme inlineso a class swap re-cascades at runtime. The palette is desaturated gunmetal grays with a blood-red primary, muted-green secondary, steel-blue accent, orange destructive.:rootcarries the dark values (no-flash default);:root.lightoverrides. Toggle is a small in-house mechanism (nonext-themes): a server-rendered init script applies the theme class before first paint (no FOUC, no React-19 inline-<script>warning), anduseThemereads it viauseSyncExternalStore.Verification
pnpm check(eslint + tsc) green.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Style
Documentation
Chores