[luv-332] feat: restyle dashboard for befailproof.ai theme; drop light mode#332
Conversation
…t mode Swap the dashboard palette from deep-navy + sky-blue to near-black + electric cyan (#0a0a0a / #06b6d4) with a sharper 0.5rem radius, wire Geist Mono via next/font/google, paint a faint cyan radial vignette behind the canvas, and turn the loading splash into a terminal-prompt with a blinking caret. The navbar drops the Exosphere icon + "Failproof AI" text combo for the failproof wordmark from the CDN. Light mode is removed entirely — ThemeContext, ThemeProvider, ThemeToggle, Logo (theme-branching), the localStorage-keyed pre-paint script, the .light CSS block, and the obsolete public/exospheresmall* assets all go. Also fixes the entry-highlight keyframe (which referenced hsl(var(--primary)/0.15) against a hex variable, so the row-click highlight never actually painted) using color-mix(in oklch, …). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The "## Theme" section in docs/dashboard.mdx described a runtime light/dark toggle that no longer exists. Drop it rather than rewriting to "the dashboard is dark" — that line adds no information for the reader. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Keep the restyle as a single coherent changelog entry rather than splitting across "feature" and "docs" lines, since the docs deletion is downstream of the same code change. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR hardcodes dark mode, removes theme context and toggles, replaces global CSS tokens with a dark/electric-cyan palette and Geist Mono font, updates button/badge styles, swaps navbar branding to an external wordmark, and removes related tests and docs entries. ChangesDashboard Redesign: Dark-Only Theme with Electric Cyan Accent
Estimated code review effort🎯 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
Comment |
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 `@app/globals.css`:
- Around line 127-129: The body CSS block violates the stylelint
declaration-empty-line-before rule; open the body selector (the block containing
"@apply bg-background text-foreground font-sans;") and insert a single blank
line before the "position: relative;" declaration so there is an empty line
separating the previous declaration and the position property, satisfying the
rule.
In `@app/layout.tsx`:
- Around line 39-45: Remove the inline script that sets
document.documentElement.classList.add('dark') and instead render the dark class
statically on the root <html> element (the element using
className={geistMono.variable} and suppressHydrationWarning); also move any
dynamic loading CSS referenced in this block into app/globals.css so no inline
<script> or <style> is required in layout.tsx and the dark theme is applied by
default via the HTML class and global CSS.
In `@CHANGELOG.md`:
- Line 6: Replace the long narrative paragraph under the "Unreleased" changelog
entry that begins "Restyle the dashboard to match befailproof.ai…" with a
single-line summary that follows the project's changelog format (brief
description + PR number), e.g. "Restyle dashboard to dark theme, update branding
and UI tokens (`#332`)"; move the detailed implementation notes from that
paragraph into the PR description or docs (e.g., README/PR body or
docs/dashboard.mdx) so CHANGELOG.md contains only the concise one-line entry.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 296b871f-5306-43ee-9b64-b872728d1ee4
⛔ Files ignored due to path filters (2)
public/exospheresmall-dark.pngis excluded by!**/*.pngpublic/exospheresmall.pngis excluded by!**/*.png
📒 Files selected for processing (14)
CHANGELOG.md__tests__/components/button.test.tsx__tests__/components/theme-context.test.tsx__tests__/components/theme-toggle.test.tsx__tests__/helpers/test-utils.tsxapp/components/cli-badge.tsxapp/globals.cssapp/layout.tsxcomponents/logo.tsxcomponents/navbar.tsxcomponents/theme-toggle.tsxcomponents/ui/button.tsxcontexts/ThemeContext.tsxdocs/dashboard.mdx
💤 Files with no reviewable changes (6)
- components/theme-toggle.tsx
- tests/components/theme-context.test.tsx
- components/logo.tsx
- contexts/ThemeContext.tsx
- tests/components/theme-toggle.test.tsx
- docs/dashboard.mdx
- app/layout.tsx: drop the inline <script> (used to set the dark class) and
inline <style> (loading-screen CSS). The dark class is now rendered
statically via className={`${geistMono.variable} dark`} so no inline JS is
required, and the loading-screen placeholder is removed entirely — with no
theme indeterminacy there's no FOUC to mask. Cleaner CSP posture, fewer
ast-grep warnings on dangerouslySetInnerHTML.
- app/globals.css: also drop the now-unused #__loading and body > * unhide
rules and the caret-blink keyframe; add the empty line before
`position: relative;` in the body block to satisfy the
declaration-empty-line-before stylelint rule.
- CHANGELOG.md: tighten the Unreleased entry from a long narrative paragraph
to a single dense paragraph (~half the prior length). The CodeRabbit
guideline of "single line" is honored in spirit but not literally — every
existing entry under Unreleased / 0.0.10-beta.x is multi-paragraph prose,
so a true one-liner here would diverge from house style.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/globals.css (1)
123-124: ⚡ Quick winSet
color-scheme: darkat the root.Now that the app is hard dark-only, putting
color-scheme: darkonhtmlwill keep all native browser surfaces consistent, instead of handlingselectandinput[type="date"]one by one.Suggested diff
html { font-size: 120%; + color-scheme: dark; }Also applies to: 149-162
🤖 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 `@app/globals.css` around lines 123 - 124, Add the CSS property color-scheme: dark to the root html selector so the browser renders native controls in dark mode consistently (update the existing html { font-size: 120%; } block to include color-scheme: dark); also remove or avoid ad-hoc per-control overrides (e.g., for select and input[type="date"]) in the later blocks (lines referencing those rules) so they inherit the global dark color scheme instead of patching individual elements.
🤖 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.
Nitpick comments:
In `@app/globals.css`:
- Around line 123-124: Add the CSS property color-scheme: dark to the root html
selector so the browser renders native controls in dark mode consistently
(update the existing html { font-size: 120%; } block to include color-scheme:
dark); also remove or avoid ad-hoc per-control overrides (e.g., for select and
input[type="date"]) in the later blocks (lines referencing those rules) so they
inherit the global dark color scheme instead of patching individual elements.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 48ef748d-e068-438d-a545-d14c6f081f70
📒 Files selected for processing (3)
CHANGELOG.mdapp/globals.cssapp/layout.tsx
✅ Files skipped from review due to trivial changes (1)
- CHANGELOG.md
Per the CHANGELOG.md format rule documented in CLAUDE.md ("Each entry should
be a single line: a short description followed by the PR number") and
reiterated in CodeRabbit's review on PR #332. The detailed prose now lives
only in the PR description.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the cyan-on-near-black scheme from the prior commits with the actual failproofai brand: black-dominant canvas (#09090b — matches the dark logo SVG's text fill), pink primary #e4587d (from docs/docs.json's colors.light), green accent (#4ade80 / #16a34a / #18e299 — the leaf gradient stops in docs/logo/dark.svg). The faint top-of-page wash is now pink instead of cyan, focus rings + active states + the entry-highlight keyframe pick up the new --primary automatically through the existing @theme inline tokens. Also swap the navbar wordmark from the CDN PNG to the local SVG copy at public/wordmark.svg (sourced from docs/logo/dark.svg) — sharper at any size, includes the green leaf, and removes the external-host dependency. New CSS variables --success / --success-deep / --success-glow expose the green leaf gradient stops as theme tokens for status indicators. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/globals.css (1)
141-150: ⚡ Quick winTokenize the vignette tint instead of hardcoding pink.
Line 149 hardcodes
rgba(228, 88, 125, 0.06), which can drift from the palette tokens on future rebrands. Prefer deriving it from--primaryfor consistency.♻️ Proposed patch
body::before { content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0; background: - radial-gradient(ellipse 80% 50% at 50% -10%, rgba(228, 88, 125, 0.06), transparent 65%); + radial-gradient( + ellipse 80% 50% at 50% -10%, + color-mix(in oklch, var(--primary), transparent 94%), + transparent 65% + ); }🤖 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 `@app/globals.css` around lines 141 - 150, Replace the hardcoded rgba(228, 88, 125, 0.06) in the body::before radial-gradient with a palette-derived value using the --primary token; for example, inside the body::before rule update the radial-gradient stop to use color-mix(in srgb, var(--primary) 6%, transparent) (or an equivalent approach like rgba(var(--primary-rgb), 0.06) if you maintain a --primary-rgb variable) so the vignette tint is derived from the --primary token instead of a hardcoded color.
🤖 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.
Nitpick comments:
In `@app/globals.css`:
- Around line 141-150: Replace the hardcoded rgba(228, 88, 125, 0.06) in the
body::before radial-gradient with a palette-derived value using the --primary
token; for example, inside the body::before rule update the radial-gradient stop
to use color-mix(in srgb, var(--primary) 6%, transparent) (or an equivalent
approach like rgba(var(--primary-rgb), 0.06) if you maintain a --primary-rgb
variable) so the vignette tint is derived from the --primary token instead of a
hardcoded color.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c666ea1c-28ea-4eb0-988a-cc214e730ff2
⛔ Files ignored due to path filters (1)
public/wordmark.svgis excluded by!**/*.svg
📒 Files selected for processing (3)
CHANGELOG.mdapp/globals.csscomponents/navbar.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- CHANGELOG.md
- components/navbar.tsx
Summary
#0a0a0a) with pink primary#e4587d(fromdocs/docs.jsoncolors.light) replacing the cyan I'd initially picked. Sharper0.5remradius. The change cascades through the existing@theme inlineCSS variables inapp/globals.css, so every consumer ofbg-background/text-foreground/text-muted-foreground/bg-primary/text-primary/ etc. picks up the new look without per-component edits — folder icons, active nav-link underline, pagination selected, focus rings, button selection rings all turn pink in one shot.--chart-2stays on#4ade80(green leaf family) so the "policies enabled" status dot and other success indicators read correctly on near-black.next/font/googleas--font-mono. Newbody::beforepaints a faint pink wash at the top of the canvas so true-black has subtle atmosphere.font-mono uppercase tracking-widerso they read as terminal labels (per-CLI hue fromlib/cli-registry.tsis unchanged — the Copilot blue / Claude orange / OpenAI purple / Cursor emerald / OpenCode amber / Pi pink / Gemini sky brand colors stay).default→ sky /bypassPermissions→ amber) keep their distinct colors — they're a binary status indicator, not a primary accent.contexts/ThemeContext.tsx,components/theme-toggle.tsx,components/logo.tsx, the<ThemeProvider>wrapper inapp/layout.tsx, thelocalStorage-keyed pre-paint<script>(thedarkclass is now rendered statically on<html>so no inline JS orsuppressHydrationWarningis needed), the loading-splash<style>block (no theme indeterminacy means no FOUC to mask), the entire.light { ... }block inglobals.cssplus its.light input[type="date"]/.light selectoverrides, the now-unreferencedpublic/exospheresmall*.pngassets, and the## Themesection indocs/dashboard.mdx.entry-highlightkeyframe which referencedhsl(var(--primary) / 0.15)against a hex CSS variable (so the row-click highlight didn't actually paint a background) — now usescolor-mix(in oklch, var(--primary), transparent 82%)and a1pxaccent-tinted outline.Test plan
bun run lint— clean (one pre-existing<img>warning inlog-viewer/tool-input-output.tsx, not from this change)bunx tsc --noEmit— cleanbun run test:run— 1573/1573 passbun run build— compiled successfully, all routes generated/projects(folder icons + pagination),/policies(active nav underline + status dot)🤖 Generated with Claude Code