feat(theme): add 5 tinted-neutral families + adjustable gray base#211
Conversation
Part A — 5 new Tinted Neutral families (clay/olive/sage/steel/plum), hues spaced ≥25° from the existing stone/slate/zinc/mauve set so they stay perceptually distinct at TINTED_NEUTRAL_CHROMA. ThemeSelector now lays the families out as a 5-column grid (2 rows) instead of one flex row. Part B — tinted presets get a softened gray base: lighter in dark mode, deeper in light mode. Surface lightness is extracted to per-token --*-l CSS variables so the new .dark.tone-tinted / .light.tone-tinted blocks override only L (uniform +0.05 dark / -0.05 light); foreground / primary / ring stay fixed so WCAG AA contrast and surface separation hold. The tone-tinted class is scoped to 0 < chroma < COLOR_PRESET_CHROMA, so the pure-neutral default and full-color presets keep the crisp ramp — the default app appearance is unchanged. Toggled in redux/listener.ts and the pre-hydration bootstrap (both index.html + settings/index.html) to avoid a first-paint flash for persisted tinted themes. Tests: contrast.test.ts evaluates tinted presets against the shifted L (dark muted/muted-fg stays 4.2:1 > AA UI floor) and drift-guards the tone-tinted blocks; bootstrap.test.ts runs against both windows and asserts they stay byte-identical; themeSlice/listener cover the new families and the tone-tinted toggle.
Codex design review flagged that .dark.tone-tinted lifted --muted-l to 0.3, dropping muted-foreground on bg-muted to 4.21:1. The 10px ThemeSelector family labels sit on hover:bg-muted, so that pair is WCAG normal text and must clear 4.5:1, not the 3.0:1 UI floor. Verified live in the running app (canvas-resolved oklch): 0.3 = 4.21:1, 0.27 = 4.63:1. - Cap the dark-tinted secondary/muted lift at +0.02 (L 0.27) instead of +0.05; headline surfaces (background/card/popover/border/input) keep the full +0.05 lighter-gray-base lift. Light tinted muted (0.9 = 5.53:1) is already safe and unchanged. - Raise the muted/muted-foreground contrast assertion to AA 4.5:1 for all presets (all pass: base 4.95, tinted 4.66, color 4.94) so the test encodes the real normal-text requirement the 10px label demands. - Fix two stale comments: --theme-chroma now documents the 0.05 tinted value; the .tone-tinted note no longer claims border-l stays fixed.
Close the /review F1 drift-guard gap: the existing bootstrap guard only
pinned the QUOTED setProperty arg ('0.16'), not the BARE `chromaVal < 0.16`
comparison literal in the .tone-tinted gate. If COLOR_PRESET_CHROMA is
retuned but the bare literal is not, the pre-hydration bootstrap and the
post-hydration listener disagree at the chroma boundary -> flash of the
wrong gray base on first paint. Multi-model confirmed (Claude + Codex).
Test-only, zero runtime change.
Close the last coverage gap on the .tone-tinted pre-hydration gate: the `chromaVal === null` arm (parseable theme with hue/mode but no numeric chroma and no recognized presetType) reaching the gate was untested. New test seeds tone-tinted then asserts the else arm strips it, proving a stale tinted base can't survive an unclassifiable theme. Runs across both the main and settings windows via describe.each. Test-only, zero runtime change. Branch coverage now 100%.
Three comment-accuracy fixes from the /ship specialist pass (all INFORMATIONAL, comment-only, zero runtime change): - listener.ts: applyThemeToDOM summary now names the .tone-tinted class it toggles (was only .light/.dark) - ThemeSelector.tsx: family-grid docblock says 'grid' not 'horizontal row' after the flex->grid layout change - listener.test.ts: split a mislabeled AAA comment so the zinc-light (light tinted) and neutral-dark (pure neutral) assertions each read true
The +5 tinted families (clay/olive/sage/steel/plum) raised the catalog to 37 presets / 54 visual themes (2 pure neutral + 17 color + 18 tinted). This updates every count-bearing doc the feature left stale: - README.md: 44 -> 54 themes - SPEC.md: total line, type-table row, and the Tinted Neutral Families table (4 -> 9 families, sorted by hue with characters from constants.ts) - website/public/llms.txt + Features.tsx: 27 -> 37 presets, 44 -> 54 themes Counts derive from THEME_PRESETS in src/shared/constants.ts; theme tests already count dynamically via Object.keys(THEME_PRESETS), so no test churn.
DESIGN.md is the binding visual source of truth, and the tinted-neutral gray base shipped in this branch had no entry there. Add a Color System subsection covering: which presets trigger `.tone-tinted` (the open (0, 0.16) chroma band), the per-mode effect (deeper gray in Light, lighter gray in Dark), where it is implemented (globals.css overrides + listener.ts runtime toggle + the no-FOUC bootstrap IIFEs), and the AA 4.5:1 dark-muted L<=0.27 contrast guardrail for the 10px ThemeSelector labels.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughこのPRは、新しいティント付きニュートラルテーマを 5 ファミリー追加し、CSS の光度変数抽出、ランタイム DOM クラストグル、HTML プリハイドレーション、および包括的なテスト・ドキュメント更新を含む。総テーマ数は 44 から 54 に拡張。 ChangesTinted Neutral Theme Implementation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Biome (2.4.16)src/renderer/src/styles/globals.cssFile contains syntax errors that prevent linting: Line 2: Tailwind-specific syntax is disabled.; Line 4: Tailwind-specific syntax is disabled.; Line 199: Tailwind-specific syntax is disabled.; Line 203: Tailwind-specific syntax is disabled. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #211 +/- ##
==========================================
+ Coverage 67.15% 67.16% +0.01%
==========================================
Files 199 199
Lines 6165 6167 +2
Branches 1390 1391 +1
==========================================
+ Hits 4140 4142 +2
Misses 1603 1603
Partials 422 422
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
SPEC.md (1)
918-920:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLanding Page セクションのテーマプリセット数が旧値のままです。
Line 919 の
27 theme presetsが、同ファイル Line 310 の37 presetsと不整合です。仕様書内の数値を統一してください。🔧 修正案
-- Feature grid (68 agents, symlink status, 27 theme presets) +- Feature grid (68 agents, symlink status, 37 theme presets)🤖 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 `@SPEC.md` around lines 918 - 920, The spec contains inconsistent theme preset counts: update the textual occurrences so they match (change "27 theme presets" to "37 theme presets" or vice versa depending on the approved canonical value); locate the two offending strings ("27 theme presets" in the landing page section and "37 presets" elsewhere) and make them identical so the specification is consistent across the document.website/public/llms.txt (1)
9-10:⚠️ Potential issue | 🟠 Major | ⚡ Quick winダウンロードURLが最新リリースを指していません。
Line 9-10 が
v0.22.2固定です。GitHub Releases では Latest がv0.23.0(2026年6月12日公開)なので、両アーキテクチャURLを最新へ更新してください。🔧 修正案
-- [Download for macOS (Apple Silicon)](https://github.com/laststance/skills-desktop/releases/download/v0.22.2/skills-desktop-0.22.2-arm64.dmg): DMG installer for M1/M2/M3 Macs. -- [Download for macOS (Intel)](https://github.com/laststance/skills-desktop/releases/download/v0.22.2/skills-desktop-0.22.2-x64.dmg): DMG installer for Intel-based Macs. +- [Download for macOS (Apple Silicon)](https://github.com/laststance/skills-desktop/releases/download/v0.23.0/skills-desktop-0.23.0-arm64.dmg): DMG installer for M1/M2/M3 Macs. +- [Download for macOS (Intel)](https://github.com/laststance/skills-desktop/releases/download/v0.23.0/skills-desktop-0.23.0-x64.dmg): DMG installer for Intel-based Macs.As per coding guidelines, "website/**: Download URLs must point to the latest release version on GitHub Releases. Both ARM64 and x64 DMG links must be updated together."
🤖 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 `@website/public/llms.txt` around lines 9 - 10, Update the two hard-coded DMG download links that reference "skills-desktop-0.22.2-arm64.dmg" and "skills-desktop-0.22.2-x64.dmg" so they point to the current latest release (v0.23.0) on GitHub Releases by replacing "0.22.2" with "0.23.0" in both ARM64 and x64 URLs; ensure both links are changed together and keep the same filename pattern (skills-desktop-0.23.0-arm64.dmg and skills-desktop-0.23.0-x64.dmg).Sources: Coding guidelines, MCP 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.
Outside diff comments:
In `@SPEC.md`:
- Around line 918-920: The spec contains inconsistent theme preset counts:
update the textual occurrences so they match (change "27 theme presets" to "37
theme presets" or vice versa depending on the approved canonical value); locate
the two offending strings ("27 theme presets" in the landing page section and
"37 presets" elsewhere) and make them identical so the specification is
consistent across the document.
In `@website/public/llms.txt`:
- Around line 9-10: Update the two hard-coded DMG download links that reference
"skills-desktop-0.22.2-arm64.dmg" and "skills-desktop-0.22.2-x64.dmg" so they
point to the current latest release (v0.23.0) on GitHub Releases by replacing
"0.22.2" with "0.23.0" in both ARM64 and x64 URLs; ensure both links are changed
together and keep the same filename pattern (skills-desktop-0.23.0-arm64.dmg and
skills-desktop-0.23.0-x64.dmg).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 8ee36099-8efa-4ae2-97db-7a50211981ed
📒 Files selected for processing (16)
DESIGN.mdREADME.mdSPEC.mdsrc/renderer/index.htmlsrc/renderer/settings/index.htmlsrc/renderer/src/bootstrap.test.tssrc/renderer/src/components/theme/ThemeSelector.browser.test.tsxsrc/renderer/src/components/theme/ThemeSelector.tsxsrc/renderer/src/redux/listener.test.tssrc/renderer/src/redux/listener.tssrc/renderer/src/redux/slices/themeSlice.test.tssrc/renderer/src/styles/contrast.test.tssrc/renderer/src/styles/globals.csssrc/shared/constants.tswebsite/public/llms.txtwebsite/src/components/Features.tsx
Summary
Expands the theme catalog with 5 new tinted-neutral families and a tinted-only adjustable gray base, taking the catalog from 27 presets / 44 themes → 37 presets / 54 visual themes (2 pure neutral + 17 color hues + 18 tinted = 9 families × dark/light).
Theme feature
feat(theme)6dcc596— Add 5 tinted-neutral families (clay, olive, sage, steel, plum) toTHEME_PRESETS, joining the existing zinc/slate/stone/mauve. All nine shareTINTED_NEUTRAL_CHROMA = 0.05with hues ≥25° apart for perceptual distinctness. Adds the.tone-tintedgray-base mechanism: deeper gray surfaces in Light, lighter gray surfaces in Dark — pure-neutral (0) and full-color (0.16) presets keep the crisp default ramp untouched. ThemeSelector becomes a 5×2 palette grid (10 families).style(theme)4c77c10— Hold dark tinted--secondary/--mutedlightness at L≤0.27 so the 10px ThemeSelector family labels keep AA 4.5:1 contrast onhover:bg-muted(verified live at 4.66:1).Tests
test53f0729— Pin the inline tinted-gate upper bound toCOLOR_PRESET_CHROMAso a constant bump cannot silently desync first paint.testc615533— Cover the bootstrap tinted-gatenull-chroma arm (a stale.tone-tintedclass must be stripped for an unclassifiable persisted theme).Docs
docs6ebb33f— Fix stale comments flagged by pre-landing review.docs691956a— Sync every count-bearing doc (README, SPEC + 9-family table, website llms.txt + Features.tsx) to 37 presets / 54 themes.docs(design)846d11d— Document the.tone-tintedgray-base mechanism in DESIGN.md (the binding visual source of truth).Test Coverage
pnpm validategreen — 1493 tests + lint (--max-warnings 0) + typecheck + dead-code + storybook build.Coverage audit: 94% (above the 80% gate). The one defensive gap (the bootstrap
chromaVal === nullarm) was closed inc615533rather than waived. Theme tests count presets dynamically viaObject.keys(THEME_PRESETS), so they auto-adapt to the new families.Pre-Landing Review
/review→ approved-with-followup.'0.16'setProperty arg, not the barechromaVal < 0.16comparison): multi-model confirmed, fixed in53f0729.typeof==='number'accepts NaN/Infinity, C3 tone-tinted float boundary, C4 OKLCH gamut untested. All reduce to FS-staged spoofing of UI-only signals on the tamperer's own machine = the repo's documented threat model ("user-side FS is trusted; ship-as-is on theoretical FS-staged spoofing of UI-only signals"). C1/C2/C4 pre-existing; C3 unreachable (chroma is always an exact literal). Overridden ship-as-is; advisor concurred.Design Review
/design-reviewran for this branch and passed. DESIGN.md additionally refined (846d11d) to document the new.tone-tintedmechanism, per the project's living-document principle.Adversarial Review
Claude adversarial subagent → evidence-based APPROVE. Verified no IIFE/listener desync (chroma distribution is exactly 2×
0/ 17×0.16/ 18×0.05— the open(0, 0.16)band contains only0.05), and no v0→v1 tinted FOUC (the tinted-families commit postdates the v0→v1 chroma refactor and is not an ancestor of it, so no legacy payload can resolve into the tinted band).Eval Results
No prompt-related files changed — evals skipped.
Plan Completion
/autoplanplan (feat-tinted-neutral-expansion-plan.md) — all items complete. Electron e2e run fresh this session: 58 passed.Documentation
No documentation changes were needed beyond those already in this branch. Commit
691956asynced every count-bearing doc the tinted-neutral expansion made stale (README.md, SPEC.md + the 9-family table, website/public/llms.txt, website/src/components/Features.tsx), and846d11dadded the.tone-tintedmechanism to DESIGN.md. An independent/document-releaseaudit of DESIGN.md, TODOS.md, .storybook, and all of website/src confirmed nothing else was invalidated by this branch's diff.Notes
package.jsonstays0.23.0. Versioning + release are owned exclusively by the project's/electron-releasepipeline (Phase 13). PR title follows the repo's conventional-commit convention (no version prefix).🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Documentation
Tests