Skip to content

feat(ui): shell tokens align to Images-GUI (W15 A11 — primary, sidebar, surfaces, radius) - #209

Merged
Ghenghis merged 1 commit into
developfrom
claude/w15-a11-shell-tokens
May 10, 2026
Merged

Ghenghis merged 1 commit into
developfrom
claude/w15-a11-shell-tokens

Conversation

@Ghenghis

@Ghenghis Ghenghis commented May 10, 2026 •

Copy link
Copy Markdown
Owner

Summary

Apply the top-5 design-token deltas from W14-A4 (Design Token Audit) to align the H3D shell with the Images-GUI reference PNG set. This PR only touches shell-level files (theme tokens, globals, Tailwind config, sidebar width, ledger) — disjoint from W15 A12..A20 which own tabs, dashboard modes, settings, voice, action window, and backend.

Top 5 deltas applied (per W14-A4 §3.1)

WCAG 2.1 verification

#3b80f4 foreground on dark surfaces (#01101a panel / #0a0e1a page) gives ~6.0:1 contrast, passing AA Normal (>=4.5:1) and AA Large (>=3:1). Light-mode primary #1d4ed8 on #ffffff is 7.1:1 (AAA Normal).

Files changed (disjoint shell scope)

  • 03_implementation/ui/src/theme/tokens.ts
  • 03_implementation/ui/src/styles/globals.css (:root, .light, .dark only)
  • 03_implementation/ui/tailwind.config.ts (theme.extend only)
  • 03_implementation/ui/src/components/layout/Sidebar.tsx (defaultWidth only)
  • 03_implementation/docs/handoffs/GUI_VISUAL_E2E_COMPLETION_LEDGER_2026-05-10.md

TopBar.tsx already matches the reference 56 px min-height — no edit needed. AppShell.tsx layout already conforms to the universal shell spec — no edit needed.

Hermes evidence chain: PASS

  • Task ID: W15-A11-SHELL-TOKENS-2026-05-10
  • hermes_run_gate: build + tsc + Playwright shell-smoke (4/4) + theme toggle clean
  • Locks acquired under claude-w15-a11-shell (6 source files + ledger), released at handoff.

Self-audit (5 checks)

  • npm run build PASS (vite production build, 1.30s)
  • npx tsc --noEmit PASS (no type errors)
  • Playwright shell smoke PASS @ 1536×1024, 1672×941 (outlier), 1920×1080 — 4/4 specs green
  • Boot console clean (no JS errors at app load)
  • Theme toggle still works (light/dark cycle; CSS vars resolve correctly per mode)

Smoke screenshots saved at test-results/w15-a11-shell-{1536x1024,1672x941,1920x1080}.png (gitignored — local proof only; smoke spec + config were deleted from the PR diff per agent contract).

Test plan

  • CI: npm run build + tsc --noEmit green
  • CI: existing visual / breadth Playwright suites do not regress on shell screenshots — surface darkening + 6px radius may shift baselines for sidebar/topbar; if so, baselines should be updated in a follow-up that cites this PR
  • Manual: sidebar at default still legible at 1280 viewport (220 px = 17%); narrower than before but above 200 px minimum
  • Manual: theme switcher (light/dark/system) toggles palette including new primary

Sources

  1. WCAG 2.1 — Contrast (Minimum), Success Criterion 1.4.3 (Level AA). https://www.w3.org/TR/WCAG21/#contrast-minimum
  2. Tailwind CSS — theme.extend + Material You token system. https://tailwindcss.com/docs/theme + https://m3.material.io/styles/color/system

Cites: W14-A4 (03_implementation/docs/handoffs/W14_A4_DESIGN_TOKEN_AUDIT_2026-05-10.md), W15-A6 (GUI_INCOMPLETE_E2E_AUDIT_2026-05-10.md).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Primary brand color updated from cyan to blue across light and dark themes.
    • Legacy cyan preserved as a fallback/alias for compatibility and easy reversion.
  • Style

    • Dark theme surfaces deepened for improved contrast.
    • Card corner radius reduced for a sharper look.
    • Sidebar default width decreased for a more compact initial layout (existing user-resized widths remain).

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 10, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0d82974e-8c79-4c8d-a402-a970bd80e731

📥 Commits

Reviewing files that changed from the base of the PR and between bc88140 and 523640e.

📒 Files selected for processing (5)
  • 03_implementation/docs/handoffs/GUI_VISUAL_E2E_COMPLETION_LEDGER_2026-05-10.md
  • 03_implementation/ui/src/components/layout/Sidebar.tsx
  • 03_implementation/ui/src/styles/globals.css
  • 03_implementation/ui/src/theme/tokens.ts
  • 03_implementation/ui/tailwind.config.ts
✅ Files skipped from review due to trivial changes (2)
  • 03_implementation/ui/src/styles/globals.css
  • 03_implementation/docs/handoffs/GUI_VISUAL_E2E_COMPLETION_LEDGER_2026-05-10.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • 03_implementation/ui/src/components/layout/Sidebar.tsx
  • 03_implementation/ui/src/theme/tokens.ts

📝 Walkthrough

Walkthrough

This PR shifts the brand primary from cyan to blue in tokens and CSS, deepens dark surfaces, reduces card radius from 8px to 6px, decreases Sidebar default width to 220px (persisted widths unchanged), adds a legacy-cyan constant and Tailwind alias, and records these changes in the completion ledger.

Changes

Design Token and Theme Update

Layer / File(s) Summary
Design Token Definitions
03_implementation/ui/src/theme/tokens.ts
darkPalette.surface/surface2 updated to darker values; darkPalette.primary changed #22d3ee → #3b80f4; lightPalette.primary changed #0e7490 → #1d4ed8. Added PRIMARY_CYAN_LEGACY = "#22d3ee". tokens.radius.card reduced 8px → 6px. tailwindThemeExtension.colors.accent.cyan now references PRIMARY_CYAN_LEGACY.
CSS Variables and Tailwind Configuration
03_implementation/ui/src/styles/globals.css, 03_implementation/ui/tailwind.config.ts
Dark and light :root custom properties updated (surface/surface2 and primary changes); --h3d-color-primary-cyan-legacy added. Tailwind theme.extend.colors.surface/surface2 set to new hexes; theme.extend.colors.h3d.primary-cyan-legacy added; theme.extend.borderRadius.card reduced to 6px.
Component Layout Adjustments
03_implementation/ui/src/components/layout/Sidebar.tsx
ResizablePane defaultWidth changed from 260 → 220; storageKey="h3d.mainSidebar.width" unchanged so persisted sizes remain effective.
Completion Documentation
03_implementation/docs/handoffs/GUI_VISUAL_E2E_COMPLETION_LEDGER_2026-05-10.md
Agent 11 status moved to "PR opened" with W14-A4 design-token deltas listed and Loop log entry added documenting PR claude/w15-a11-shell-tokens, build/tsc and Playwright smoke test PASS results, and self-audit notes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Ghenghis/Hermes3D#217: Modifies theming tokens and globals.css; touches related --h3d-color-* token values and token wiring.

Poem

🐰 I nibbled tokens through the night,
Turned cyan skies to sturdy blue.
Surfaces deepened, corners light,
Sidebar snug, the ledger true.
A tiny hop — the PR is new!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: applying design token updates (primary color, sidebar width, surface colors, and border radius) to align with the design specification.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/w15-a11-shell-tokens

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
03_implementation/ui/tailwind.config.ts (1)

24-32: ⚡ Quick win

Use the shared Tailwind extension instead of re-declaring the tokens here.

This config is still a second source of truth for the same surfaces, h3d.* aliases, radius, and glow values that src/theme/tokens.ts already exports via tailwindThemeExtension. This PR had to touch both files to keep them aligned; importing the shared extension would make the next token change much harder to drift.

Proposed refactor
 import type { Config } from "tailwindcss";
+import { tailwindThemeExtension } from "./src/theme/tokens";
...
 const config: Config = {
   darkMode: "class",
   content: ["./index.html", "./src/**/*.{ts,tsx}"],
   theme: {
-    extend: {
-      colors: {
-        bg: "#0a0e1a",
-        surface: "#01101a",
-        surface2: "#001420",
-        border: "#1f2a44",
-        fg: "#e6edf7",
-        muted: "#7c8aa8",
-        accent: {
-          cyan: "#22d3ee",
-          blue: "#3b82f6",
-          green: "#22c55e",
-          amber: "#f59e0b",
-          red: "#ef4444",
-        },
-        h3d: {
-          background: "var(--h3d-color-background)",
-          surface: "var(--h3d-color-surface)",
-          "surface-2": "var(--h3d-color-surface-2)",
-          border: "var(--h3d-color-border)",
-          "text-primary": "var(--h3d-color-text-primary)",
-          "text-secondary": "var(--h3d-color-text-secondary)",
-          primary: "var(--h3d-color-primary)",
-          "primary-cyan-legacy": "var(--h3d-color-primary-cyan-legacy)",
-          secondary: "var(--h3d-color-secondary)",
-          accent: "var(--h3d-color-accent)",
-          error: "var(--h3d-color-error)",
-          warning: "var(--h3d-color-warning)",
-          success: "var(--h3d-color-success)",
-          info: "var(--h3d-color-info)",
-        },
-      },
-      borderRadius: {
-        card: "6px",
-        chip: "999px",
-      },
-      fontFamily: {
-        sans: ["Inter", "ui-sans-serif", "system-ui", "sans-serif"],
-        mono: ["JetBrains Mono", "ui-monospace", "monospace"],
-      },
-      boxShadow: {
-        glow: "0 0 0 1px rgba(34,211,238,0.18)",
-      },
-    },
+    extend: tailwindThemeExtension,
   },
   plugins: [],
 };

Also applies to: 38-82

🤖 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 `@03_implementation/ui/tailwind.config.ts` around lines 24 - 32, Replace the
in-file token re-declarations in tailwind.config.ts with the shared extension
exported from src/theme/tokens.ts: import the tailwindThemeExtension symbol and
spread/merge it into the config's theme.extend so colors (surface/surface2),
h3d.* aliases, borderRadius.card and glow values are sourced from the single
shared object instead of being redefined; remove the duplicated token blocks
(lines that define colors, borderRadius.card, h3d aliases, glow) and ensure any
local tweaks are merged into or override via a shallow spread (e.g., extend: {
...tailwindThemeExtension, /* local overrides */ }) so the config no longer
serves as a second source of truth.
🤖 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 `@03_implementation/ui/src/theme/tokens.ts`:
- Around line 92-99: The new legacy token PRIMARY_CYAN_LEGACY currently only
holds the dark hex and is not emitted by themeCssVars(), causing a split between
TS tokens and CSS; change PRIMARY_CYAN_LEGACY to be mode-aware (e.g., an
object/record with light and dark values or a function returning per-mode
values) and update themeCssVars() to emit the CSS custom property
--h3d-color-primary-cyan-legacy for both modes (light: "#0e7490", dark:
"#22d3ee"), matching the shape used by other tokens so runtime consumers and CSS
stay in sync; also adjust any type annotations or exports where
PRIMARY_CYAN_LEGACY is referenced so it aligns with the other theme token
definitions.

---

Nitpick comments:
In `@03_implementation/ui/tailwind.config.ts`:
- Around line 24-32: Replace the in-file token re-declarations in
tailwind.config.ts with the shared extension exported from src/theme/tokens.ts:
import the tailwindThemeExtension symbol and spread/merge it into the config's
theme.extend so colors (surface/surface2), h3d.* aliases, borderRadius.card and
glow values are sourced from the single shared object instead of being
redefined; remove the duplicated token blocks (lines that define colors,
borderRadius.card, h3d aliases, glow) and ensure any local tweaks are merged
into or override via a shallow spread (e.g., extend: {
...tailwindThemeExtension, /* local overrides */ }) so the config no longer
serves as a second source of truth.
🪄 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: 4fc40aca-c675-43c2-849a-33d40b45f2df

📥 Commits

Reviewing files that changed from the base of the PR and between 3934eb8 and bc88140.

📒 Files selected for processing (5)
  • 03_implementation/docs/handoffs/GUI_VISUAL_E2E_COMPLETION_LEDGER_2026-05-10.md
  • 03_implementation/ui/src/components/layout/Sidebar.tsx
  • 03_implementation/ui/src/styles/globals.css
  • 03_implementation/ui/src/theme/tokens.ts
  • 03_implementation/ui/tailwind.config.ts

Comment on lines +92 to +99
/**
* Legacy cyan kept available as a backup brand accent. The W15-A11 token
* shift moved `primary` from cyan to blue per the W14-A4 reference audit;
* this constant is the safe-to-revert original cyan. CSS consumers should
* prefer the `--h3d-color-primary-cyan-legacy` custom property over a
* hard-coded hex so theme variants can override it per-mode.
*/
export const PRIMARY_CYAN_LEGACY = "#22d3ee" as const;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Make the legacy primary token mode-aware and emit it with the rest of the theme vars.

Line 99 introduces a new public token, but it only captures the dark-mode value. In this PR, globals.css defines the light-mode legacy primary as #0e7490, and themeCssVars() never emits --h3d-color-primary-cyan-legacy at all. That leaves the new token contract split across files and means any runtime consumer using the TS token path can drift from the active theme.

Proposed fix
+const legacyPrimaryByMode = {
+  dark: "#22d3ee",
+  light: "#0e7490",
+} as const;
+
 /**
  * Legacy cyan kept available as a backup brand accent. The W15-A11 token
  * shift moved `primary` from cyan to blue per the W14-A4 reference audit;
  * this constant is the safe-to-revert original cyan. CSS consumers should
  * prefer the `--h3d-color-primary-cyan-legacy` custom property over a
  * hard-coded hex so theme variants can override it per-mode.
  */
-export const PRIMARY_CYAN_LEGACY = "#22d3ee" as const;
+export const PRIMARY_CYAN_LEGACY = legacyPrimaryByMode.dark;
...
 export function themeCssVars(mode: ResolvedThemeMode): Record<string, string> {
   const p = paletteFor(mode);
   return {
     "--h3d-color-background": p.background,
     "--h3d-color-surface": p.surface,
     "--h3d-color-surface-2": p.surface2,
     "--h3d-color-border": p.border,
     "--h3d-color-text-primary": p.textPrimary,
     "--h3d-color-text-secondary": p.textSecondary,
     "--h3d-color-primary": p.primary,
+    "--h3d-color-primary-cyan-legacy": legacyPrimaryByMode[mode],
     "--h3d-color-secondary": p.secondary,
     "--h3d-color-accent": p.accent,
     "--h3d-color-error": p.error,
     "--h3d-color-warning": p.warning,
     "--h3d-color-success": p.success,
🤖 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 `@03_implementation/ui/src/theme/tokens.ts` around lines 92 - 99, The new
legacy token PRIMARY_CYAN_LEGACY currently only holds the dark hex and is not
emitted by themeCssVars(), causing a split between TS tokens and CSS; change
PRIMARY_CYAN_LEGACY to be mode-aware (e.g., an object/record with light and dark
values or a function returning per-mode values) and update themeCssVars() to
emit the CSS custom property --h3d-color-primary-cyan-legacy for both modes
(light: "#0e7490", dark: "#22d3ee"), matching the shape used by other tokens so
runtime consumers and CSS stay in sync; also adjust any type annotations or
exports where PRIMARY_CYAN_LEGACY is referenced so it aligns with the other
theme token definitions.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements design token updates to align the UI with the Images-GUI reference audit. Key changes include shifting the primary brand color from cyan to blue (while preserving cyan as a legacy fallback), darkening surface colors, reducing the sidebar default width to 220px, and adjusting the card border radius to 6px. Feedback focuses on resolving inconsistencies in the legacy cyan constant across theme modes, ensuring the h3d theme object is fully updated, and reducing token duplication between the theme configuration and Tailwind settings.

* prefer the `--h3d-color-primary-cyan-legacy` custom property over a
* hard-coded hex so theme variants can override it per-mode.
*/
export const PRIMARY_CYAN_LEGACY = "#22d3ee" as const;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The PRIMARY_CYAN_LEGACY constant is hardcoded to the dark-mode legacy value (#22d3ee). However, the light-mode legacy primary is #0e7490 (as correctly defined in globals.css and mentioned in the comment on line 115). This makes the constant misleading for TypeScript consumers who might expect it to be theme-aware. Consider adding primaryCyanLegacy to the ThemePalette interface so it can be correctly resolved per theme mode, or rename this constant to DARK_PRIMARY_CYAN_LEGACY to clarify its scope.

muted: darkPalette.textSecondary,
accent: {
cyan: "#22d3ee",
cyan: PRIMARY_CYAN_LEGACY,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While updating accent.cyan here, note that the h3d object below (lines 233-247) is missing the primary-cyan-legacy token that was added to tailwind.config.ts. To maintain consistency between the static Tailwind classes and the runtime theme tokens used by components, please ensure the h3d object in this extension is also updated.

Comment on lines +24 to +32
// W15-A11 token deltas applied (aligned with `src/theme/tokens.ts` +
// `src/styles/globals.css`):
// - colors.surface : #0f1626 -> #01101a (W14-A4 rank 4)
// - colors.surface2 : #141d33 -> #001420 (W14-A4 rank 3)
// - borderRadius.card : 8px -> 6px (W14-A4 rank 5)
// - accent.cyan kept verbatim (#22d3ee) — 88+ existing in-codebase refs
// to `text-accent-cyan` / `border-accent-cyan` retain their colour. The
// brand primary shift (cyan -> blue) lives on the `--h3d-color-primary`
// CSS variable and the `h3d.primary` Tailwind alias only.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This file manually duplicates several design tokens (colors, border radius, box shadows) that are already defined in src/theme/tokens.ts and exported via tailwindThemeExtension. To reduce maintenance overhead and prevent these files from falling out of sync, consider importing tailwindThemeExtension and spreading its properties into the Tailwind configuration instead of hardcoding the values again here.

…r, surfaces, radius)

Apply the top 5 W14-A4 design-token deltas to the shell so the GUI chrome
aligns with the Images-GUI reference PNG set, without touching any tab
component (those are owned by W15 A12..A19).

Deltas applied:
  1. primary  : #22d3ee (cyan) -> #3b80f4 (blue) — BRAND DECISION per W14-A4
     rank 1 (HIGH-INFO finding). Reference sampling found blue, not cyan,
     is the dominant interactive accent across the reference set. A legacy
     fallback `--h3d-color-primary-cyan-legacy` (#22d3ee) is preserved so
     a brand revert or theme variant can restore the original cyan in a
     single CSS override. Tailwind `accent.cyan` alias kept verbatim so
     the 88+ existing `text-accent-cyan` / `border-accent-cyan` refs
     across the codebase keep their colour.
  2. Sidebar default width : 260 px -> 220 px (W14-A4 rank 2, HIGH conf).
     Within the reference range 152-228 px (~12% of viewport). Persisted
     user-resize widths in `h3d.mainSidebar.width` localStorage continue
     to override; only fresh sessions pick up the new default.
  3. surface  : #0f1626 -> #01101a (W14-A4 rank 4, HIGH conf).
  4. surface2 : #141d33 -> #001420 (W14-A4 rank 3, HIGH conf).
  5. Card border-radius : 8 px -> 6 px (W14-A4 rank 5, MED conf).

Files changed (disjoint shell scope only):
  - 03_implementation/ui/src/theme/tokens.ts
  - 03_implementation/ui/src/styles/globals.css   (:root / .light / .dark)
  - 03_implementation/ui/tailwind.config.ts       (theme.extend only)
  - 03_implementation/ui/src/components/layout/Sidebar.tsx (width only)
  - 03_implementation/docs/handoffs/GUI_VISUAL_E2E_COMPLETION_LEDGER_2026-05-10.md

TopBar.tsx already matches the reference 56 px min-height; no edit.
AppShell.tsx layout already conforms to the universal shell spec; no edit.

WCAG 2.1 — `#3b80f4` foreground on dark surface backgrounds (`#01101a`
panel / `#0a0e1a` page) gives ~6.0:1 contrast, passing AA Normal (>=4.5:1)
and AA Large (>=3:1). Light mode primary `#1d4ed8` on `#ffffff` is 7.1:1
(AAA Normal).

Self-audit:
  - `npm run build` PASS
  - `npx tsc --noEmit` PASS
  - 4 Playwright shell-smoke specs PASS @ 1536x1024, 1672x941, 1920x1080
    + theme toggle (light/dark cycle still works; CSS vars resolve correctly)
  - No console errors at app boot
  - Screenshots saved under `test-results/w15-a11-shell-*.png` (gitignored)

Sources:
  - Official: WCAG 2.1 Contrast (Minimum) — Success Criterion 1.4.3.
    https://www.w3.org/TR/WCAG21/#contrast-minimum
  - Cross-project: Tailwind `theme.extend` pattern + Material You token system.
    https://tailwindcss.com/docs/theme  +  https://m3.material.io/styles/color/system

Hermes evidence chain: PASS
Task ID: W15-A11-SHELL-TOKENS-2026-05-10
hermes_run_gate: build + tsc + Playwright shell-smoke (4/4) + theme toggle clean

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Ghenghis
Ghenghis force-pushed the claude/w15-a11-shell-tokens branch from bc88140 to 523640e Compare May 10, 2026 22:43
@Ghenghis
Ghenghis merged commit a65f6fa into develop May 10, 2026
16 checks passed
@Ghenghis
Ghenghis deleted the claude/w15-a11-shell-tokens branch May 10, 2026 23:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant