Align web UI with Lumen Design System#36
Conversation
Adopt the Lumen "warm light" visual language across the web app: IBM Plex type, the Atelier (light, default) / Vault (dark) dual theme, and the quiet-utility ethos. Everything flows through the CSS token layer, so page components (all semantic classes) need no markup changes. - tokens: Geist -> IBM Plex Sans/SC/Mono; Atelier + Vault palettes mapped onto existing var names; radius scale 10/12/16/20/999; shadows limited to shell + popovers; global :focus-visible accent ring. - ethos: drop body radial gradients + grid texture and backdrop blur for flat warm backgrounds; strip shadows from inline cards (borders do the structural work). - default theme flips dark -> Atelier light, with a no-flash boot script in index.html. Verified: typecheck, web tests (47), and production build all pass.
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Warning Review limit reached
Next review available in: 53 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe web app now applies a light theme before first paint, uses light as the runtime fallback, and adopts updated Lumen-aligned typography, tokens, colors, radii, motion, focus styling, and surface treatments. ChangesTheme initialization and UI styling
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant ThemeBoot as index.html theme boot
participant LocalStorage
participant DocumentRoot as document.documentElement
participant AppTheme as App.tsx getStoredTheme
ThemeBoot->>LocalStorage: Read involute.theme
LocalStorage-->>ThemeBoot: dark, light, or error
ThemeBoot->>DocumentRoot: Set data-theme
AppTheme->>LocalStorage: Read stored theme
LocalStorage-->>AppTheme: Stored theme or error
AppTheme->>DocumentRoot: Apply runtime theme fallback
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
packages/web/src/styles/app.css (2)
8-8: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winStylelint
import-notationwill fail CI. The rule expects the plain string form rather thanurl(...). Both are valid CSS; switching to a string satisfies the configured lint rule.♻️ Proposed fix
-@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Sans+SC:wght@400;500;600;700&display=swap'); +@import 'https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Sans+SC:wght@400;500;600;700&display=swap';🤖 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 `@packages/web/src/styles/app.css` at line 8, Update the Google Fonts `@import` declaration in app.css to use the plain quoted string form instead of url(...), preserving the existing font URL and query parameters so it satisfies Stylelint’s import-notation rule.Source: Linters/SAST tools
11-13: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
value-keyword-caseis flagging real font-family names. Stylelint wantsBlinkMacSystemFont,Roboto,Menlo,Consolas,Georgialowercased, but these are proper font names and blindly lowercasing them is undesirable. Prefer adding them toignoreKeywords(or disabling the rule for these declarations) in your Stylelint config rather than editing the names, so CI passes without altering the intended font stack.🤖 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 `@packages/web/src/styles/app.css` around lines 11 - 13, Update the Stylelint configuration for value-keyword-case to ignore the proper font-family names used by the --font-sans, --font-mono, and --font-serif declarations, including BlinkMacSystemFont, Roboto, Menlo, Consolas, and Georgia. Preserve the original font stack casing and avoid changing the CSS declarations.Source: Linters/SAST tools
🤖 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 `@packages/web/src/styles/app.css`:
- Around line 171-175: Increase the contrast of the :focus-visible outline in
app.css by replacing the 32% mixed accent color with var(--accent) or another
stronger-contrast accent shade. Preserve the existing 3px outline and 2px offset
while ensuring the light-theme focus ring meets the required visibility.
---
Nitpick comments:
In `@packages/web/src/styles/app.css`:
- Line 8: Update the Google Fonts `@import` declaration in app.css to use the
plain quoted string form instead of url(...), preserving the existing font URL
and query parameters so it satisfies Stylelint’s import-notation rule.
- Around line 11-13: Update the Stylelint configuration for value-keyword-case
to ignore the proper font-family names used by the --font-sans, --font-mono, and
--font-serif declarations, including BlinkMacSystemFont, Roboto, Menlo,
Consolas, and Georgia. Preserve the original font stack casing and avoid
changing the CSS declarations.
🪄 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 Plus
Run ID: c36aa95e-51c8-476b-825a-73f8506b1e41
📒 Files selected for processing (3)
packages/web/index.htmlpackages/web/src/App.tsxpackages/web/src/styles/app.css
| /* Focus — 3px accent outline at 2px offset (Lumen :focus-visible). */ | ||
| :focus-visible { | ||
| outline: 3px solid color-mix(in srgb, var(--accent) 32%, transparent); | ||
| outline-offset: 2px; | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
python3 - <<'PY'
def lin(c):
c/=255
return c/12.92 if c<=0.03928 else ((c+0.055)/1.055)**2.4
def L(r,g,b):
return 0.2126*lin(r)+0.7152*lin(g)+0.0722*lin(b)
def ratio(a,b):
l1,l2=L(*a),L(*b)
hi,lo=max(l1,l2),min(l1,l2)
return (hi+0.05)/(lo+0.05)
accent=(159,79,36); alpha=0.32
for name,bg in [("bg",(247,246,242)),("bg-raised",(255,253,250)),("bg-sunken",(239,236,229))]:
eff=tuple(round(alpha*a+(1-alpha)*b) for a,b in zip(accent,bg))
print(f"over {name}: outline≈{eff} contrast={ratio(eff,bg):.2f}:1 (need >=3:1)")
PYRepository: fakechris/Involute
Length of output: 356
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate app.css =="
fd -a 'app.css' . | sed 's#^\./##'
echo
echo "== relevant CSS variables and focus rules =="
if [ -f packages/web/src/styles/app.css ]; then
nl -ba packages/web/src/styles/app.css | sed -n '1,230p'
fi
echo
echo "== search for Atelier/light palette usage =="
rg -n "Atelier|atelier|accent|bg-raised|bg-sunken|--bg" -S . -g '!node_modules' -g '!dist' -g '!build' | head -n 200Repository: fakechris/Involute
Length of output: 315
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== relevant CSS variables and focus rules =="
[ -f packages/web/src/styles/app.css ] && sed -n '1,230p' packages/web/src/styles/app.css
echo
echo "== search for Atelier/light palette usage =="
rg -n "Atelier|atelier|accent|bg-raised|bg-sunken|--bg" -S . -g '!node_modules' -g '!dist' -g '!build' | head -n 200Repository: fakechris/Involute
Length of output: 13771
🌐 Web query:
WCAG 2.4.11 Focus Appearance level AA contrast outline outline offset specification
💡 Result:
There is a common confusion regarding the numbering of the WCAG Focus Appearance criteria. Success Criterion 2.4.11 is titled Focus Not Obscured (Minimum) (Level AA) [1][2], while the criteria detailing specific requirements for focus indicator size and contrast are found under Success Criterion 2.4.13 Focus Appearance (Level AAA) [3][4][5]. WCAG 2.4.11 (Level AA) does not specify requirements for outline thickness, contrast, or offset [1][2]. Its purpose is to ensure that when a component receives keyboard focus, it is not entirely hidden by author-created content (such as sticky headers or footers) [1][2]. Requirements for focus indicator size and contrast are specified in WCAG 2.4.13 (Level AAA) [3][4]. While 2.4.13 is the relevant standard for appearance, it does not mandate specific CSS properties like outline or outline-offset, but rather defines functional requirements for the indicator's area and contrast change [3][6][5]: 1. Size (Minimum Area): The focus indicator must be at least as large as the area of a 2 CSS pixel thick perimeter of the unfocused component [3][6][4]. 2. Contrast (State Change): There must be a contrast ratio of at least 3:1 between the pixels of the indicator in the focused state versus the same pixels in the unfocused state [3][6][5]. Although not required by the standard, using the CSS outline and outline-offset properties is a widely accepted technique to meet these criteria [6][7][5]. A common, compliant implementation is to use an outline at least 2px thick, often combined with an outline-offset to separate the indicator from the component's edge, ensuring it remains distinct [6][4][5]. Top Results: [1], [2], [3], [6], [4], [5]
Citations:
- 1: https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum.html
- 2: https://w3c.github.io/wcag/understanding/focus-not-obscured-minimum
- 3: https://www.w3.org/WAI/WCAG22/Understanding/focus-appearance
- 4: https://accessibility.build/wcag/2-4-13
- 5: https://a11ybot.app/learn/2-4-13-focus-appearance/
- 6: https://www.w3.org/WAI/WCAG22/Understanding/focus-appearance.html
- 7: https://w3c.github.io/wcag/techniques/css/C40
Increase the Atelier focus-ring contrast
The 32% mixed light accent produces ~1.6:1 contrast against the parchment backgrounds, below WCAG 2.4.13 Focus Appearance’s 3:1 state-change requirement. Use var(--accent) or a stronger contrast shade for :focus-visible so keyboard focus remains reliably visible in the light theme.
🤖 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 `@packages/web/src/styles/app.css` around lines 171 - 175, Increase the
contrast of the :focus-visible outline in app.css by replacing the 32% mixed
accent color with var(--accent) or another stronger-contrast accent shade.
Preserve the existing 3px outline and 2px offset while ensuring the light-theme
focus ring meets the required visibility.
# Conflicts: # packages/web/src/styles/app.css
Aligns Involute's web UI/UX to the Lumen Design System — the warm, quiet, local-first visual language (IBM Plex, Atelier/Vault dual theme, quiet-utility ethos).
All changes flow through the CSS token layer; page components use semantic classes and need no markup edits.
Changes
:focus-visibleaccent ringindex.htmlVerification
pnpm --filter @turnkeyai/involute-web typecheck✅Note
In Vault (dark), Lumen's
--dangeris pink (#f472b6), so the "urgent" label reads pink in dark mode — faithful to the scheme. Easy to swap for a conventional red if preferred.Summary by CodeRabbit
New Features
Bug Fixes