Skip to content

fix(webui): use theme-aware semantic colors - #6041

Merged
italic-jinxin merged 11 commits into
mainfrom
issue-6039-light-theme-contrast
Jul 14, 2026
Merged

italic-jinxin merged 11 commits into
mainfrom
issue-6039-light-theme-contrast

Conversation

@italic-jinxin

@italic-jinxin italic-jinxin commented Jul 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Replaces dark-theme-specific outline and danger button colors with theme-aware semantic tokens.
  • Migrates fixed emerald success states and undefined iron-500 / iron-600 utilities to readable semantic colors across the WebUI v2 frontend.
  • Adds source-level regression coverage and browser E2E contrast checks for light and dark themes.
image

Linked Issue

Closes #6039

Validation

  • TZ=UTC corepack pnpm test
  • corepack pnpm typecheck
  • corepack pnpm lint
  • corepack pnpm build
  • cargo test -p ironclaw_webui_v2 --features webui-v2-beta
  • cargo clippy -p ironclaw_webui_v2 --all-targets --all-features -- -D warnings
  • Reborn WebUI v2 Playwright contrast E2E
  • scripts/pre-commit-safety.sh
  • git diff --check

Security Impact

No. This changes frontend presentation tokens only and does not alter authentication, authorization, request handling, or runtime behavior.

Database Impact

No schema, migration, or persistence changes.

Blast Radius

Limited to WebUI v2 button, status, success-state, and secondary-text styling.

Rollback Plan

Revert this PR to restore the previous WebUI v2 color utilities.


Review track: B

@italic-jinxin italic-jinxin added size: L 200-499 changed lines risk: low Changes to docs, tests, or low-risk modules contributor: core 20+ merged PRs labels Jul 13, 2026
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6041 July 13, 2026 11:40 Destroyed
@italic-jinxin

Copy link
Copy Markdown
Contributor Author

@claude review

@github-actions github-actions Bot added size: M 50-199 changed lines and removed size: L 200-499 changed lines labels Jul 13, 2026
@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 648901e8-17b5-47d7-92d2-81c2d1429001

📥 Commits

Reviewing files that changed from the base of the PR and between cc4a32d and 1e83252.

📒 Files selected for processing (3)
  • crates/ironclaw_webui_v2/frontend/src/styles/app.css
  • tests/e2e/helpers.py
  • tests/e2e/scenarios/test_reborn_webui_v2_smoke.py

📝 Walkthrough

Summary by CodeRabbit

  • Style

    • Updated interface colors across Slack setup, automations, chat, projects, settings, extensions, and tool panels to use theme-aware semantic colors.
    • Improved light-theme accent color contrast and refined success, muted, and status indicator styling.
    • Updated outline and danger buttons to adapt consistently across themes.
  • Tests

    • Added coverage to verify theme-safe color usage and WCAG AA contrast for key controls and status messages.

Walkthrough

The frontend replaces fixed emerald and iron color utilities with v2 semantic CSS variables, updates outline and danger button variants, adjusts the light-theme accent token, and adds static token and cross-theme contrast checks.

Changes

Semantic theme color migration

Layer / File(s) Summary
Button semantic variants
crates/ironclaw_webui_v2/frontend/src/design-system/button.tsx, crates/ironclaw_webui_v2/frontend/src/design-system/button.test.tsx, crates/ironclaw_webui_v2/frontend/src/styles/app.css
Outline and danger variants use CSS-variable-based colors, tests verify semantic classes, and the light-theme accent token is updated.
Production UI color migration
crates/ironclaw_webui_v2/frontend/src/components/*, crates/ironclaw_webui_v2/frontend/src/pages/{automations,chat,extensions,projects,settings}/...
Slack, automation, chat, extension, project, and settings states replace fixed emerald and iron utilities with v2 positive and muted color variables.
Theme token enforcement
crates/ironclaw_webui_v2/frontend/src/styles/theme-colors.test.ts
A Vitest scan flags forbidden emerald utilities and undefined iron color utilities in production TypeScript files.
Cross-theme contrast validation
tests/e2e/helpers.py, tests/e2e/scenarios/test_reborn_webui_v2_smoke.py
A selector entry, color-luminance helpers, and a smoke test validate WCAG AA contrast for semantic controls and messages in light and dark themes.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SmokeTest
  participant RebornV2Page
  participant BrowserStyles
  participant ContrastHelpers
  SmokeTest->>RebornV2Page: Set light theme and expose target controls
  RebornV2Page->>BrowserStyles: Read computed foreground/background styles
  BrowserStyles-->>ContrastHelpers: Return colors and ancestor backgrounds
  ContrastHelpers-->>SmokeTest: Calculate effective colors and WCAG contrast
  SmokeTest->>RebornV2Page: Switch dark theme and validate target controls
  SmokeTest->>RebornV2Page: Toggle skill setting and inspect success banner
Loading

Possibly related PRs

  • nearai/ironclaw#5375: Updates the same project filesystem component area and related WebUI v2 selector coverage.

Suggested reviewers: benkurrek, ilblackdragon

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Conventional Commits style title clearly matches the theme-aware semantic color fix.
Description check ✅ Passed The description follows the template well and covers summary, linked issue, validation, impact, and rollback sections.
Linked Issues check ✅ Passed The changes address #6039 by replacing hard-coded emerald/iron colors with semantic tokens and adding contrast regression tests.
Out of Scope Changes check ✅ Passed No clearly unrelated code changes stand out; the touched UI, token, and test files all support the contrast and theme-color fix.

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.5.3)
crates/ironclaw_webui_v2/frontend/src/styles/app.css

File contains syntax errors that prevent linting: Line 2: Tailwind-specific syntax is disabled.; Line 4: Tailwind-specific syntax is disabled.


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.

❤️ Share

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

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

Copy link
Copy Markdown
Contributor

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 replaces hardcoded color classes with theme-aware CSS variables across various frontend components to support consistent styling and contrast compliance. It also introduces a static test to prevent future regressions of hardcoded colors and an E2E smoke test to verify WCAG AA contrast ratios in both light and dark themes. The review feedback suggests improving path resolution in the new test file using node:path's join function for platform independence, and adding a data-testid to the skill action result container to make the E2E test selector more robust and less fragile.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread crates/ironclaw_webui_v2/frontend/src/styles/theme-colors.test.ts
Comment thread crates/ironclaw_webui_v2/frontend/src/styles/theme-colors.test.ts
Comment thread tests/e2e/scenarios/test_reborn_webui_v2_smoke.py Outdated

@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: 4

🤖 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 `@crates/ironclaw_webui_v2/frontend/src/styles/theme-colors.test.ts`:
- Around line 22-24: Broaden the fixed-emerald detection in the theme-color
guard to cover all Tailwind utility prefixes that can reference emerald,
including ring, gradient, divide, fill, stroke, decoration, outline, shadow,
accent, and caret alongside the existing bg, border, and text prefixes. Update
the regular expression in the test so any matching emerald shade is added to
violations.
- Around line 20-30: Add a scanned-file count in the test around
productionTypeScriptFiles and assert that at least one file was discovered
before validating violations. Keep the existing utility checks and
assert.deepEqual(violations, []) behavior unchanged.

In `@tests/e2e/scenarios/test_reborn_webui_v2_smoke.py`:
- Around line 174-176: Update the cancel_button locator to use the first
matching Cancel button, consistent with the other locators in this test, so
visibility and readability assertions do not fail under Playwright strict mode
when multiple matches exist.
- Around line 217-221: Add a dedicated data-testid to the success banner
rendered by the restart-banner component, then replace the brittle class-based
locator in the smoke test with the corresponding helpers.SEL_V2 selector. Define
the SEL_V2 hook using the repository’s existing selector conventions and
preserve the visibility and readability assertions.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 83f2b63a-4015-4a41-9cb3-062c761d03f6

📥 Commits

Reviewing files that changed from the base of the PR and between 9f445f0 and 4fc2153.

📒 Files selected for processing (18)
  • crates/ironclaw_webui_v2/frontend/src/components/slack-channel-picker.tsx
  • crates/ironclaw_webui_v2/frontend/src/components/slack-setup-panel.tsx
  • crates/ironclaw_webui_v2/frontend/src/design-system/button.test.tsx
  • crates/ironclaw_webui_v2/frontend/src/design-system/button.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/automations/components/automation-detail-panel.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/automations/components/automation-recent-runs.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/automations/components/automations-empty-state.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/automations/lib/automations-presenters.ts
  • crates/ironclaw_webui_v2/frontend/src/pages/chat/components/message-bubble.test.ts
  • crates/ironclaw_webui_v2/frontend/src/pages/chat/components/message-bubble.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/chat/components/tool-activity.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/extensions/components/pairing-section.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/projects/components/project-filesystem-panel.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/projects/components/projects-grid.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/settings/components/restart-banner.tsx
  • crates/ironclaw_webui_v2/frontend/src/pages/settings/components/skills-tab.tsx
  • crates/ironclaw_webui_v2/frontend/src/styles/theme-colors.test.ts
  • tests/e2e/scenarios/test_reborn_webui_v2_smoke.py

Comment thread crates/ironclaw_webui_v2/frontend/src/styles/theme-colors.test.ts Outdated
Comment thread crates/ironclaw_webui_v2/frontend/src/styles/theme-colors.test.ts Outdated
Comment thread tests/e2e/scenarios/test_reborn_webui_v2_smoke.py Outdated
Comment thread tests/e2e/scenarios/test_reborn_webui_v2_smoke.py Outdated
@github-actions

github-actions Bot commented Jul 13, 2026 •

Copy link
Copy Markdown
Contributor

Coverage ratchet

Ratchet mode: ENFORCING

RATCHET PASS: global
  observed: 85.56% (302422 / 353446 lines)
  floor:    85.3% (tolerance 0.5pp -> effective floor 84.8%)
  denominator: 353446 lines now vs 320188 at floor capture (+33258 lines, +10.39%) — material change (>5%)

⚠️ 2 Reborn crate(s) have 0 int-tier coverage (target: 0) — ironclaw_prompt_envelope, ironclaw_scripts

Reborn integration-tier coverage

Line coverage (Reborn crates): 85.56% — 302422 / 353446 lines

Per-crate breakdown (63 crates, lowest-covered first)
Crate Line % Covered / Total
ironclaw_prompt_envelope 0% 0 / 88
ironclaw_scripts 0% 0 / 345
ironclaw_runtime_policy 31.75% 80 / 252
ironclaw_event_projections 43.31% 673 / 1554
ironclaw_run_state 53.07% 225 / 424
ironclaw_authorization 53.89% 464 / 861
ironclaw_triggers 59.89% 1792 / 2992
ironclaw_observability 61.54% 16 / 26
ironclaw_webui_v2 62.93% 2679 / 4257
ironclaw_mcp 63.03% 578 / 917
ironclaw_reborn_cli 66.18% 4488 / 6781
ironclaw_filesystem 67.1% 3833 / 5712
ironclaw_dispatcher 67.15% 92 / 137
ironclaw_memory 69.2% 773 / 1117
ironclaw_reborn_migration 71.57% 1551 / 2167
ironclaw_trust 72.88% 661 / 907
ironclaw_capabilities 74.39% 1685 / 2265
ironclaw_wasm_limiter 74.6% 47 / 63
ironclaw_reborn_event_store 74.67% 958 / 1283
ironclaw_extractors 74.72% 538 / 720
ironclaw_llm 78.36% 20328 / 25941
ironclaw_product_context 78.57% 11 / 14
ironclaw_first_party_extensions 78.81% 5576 / 7075
ironclaw_process_sandbox 80.65% 671 / 832
ironclaw_wasm_product_adapters 80.71% 1448 / 1794
ironclaw_memory_native 81.22% 3205 / 3946
ironclaw_secrets 82.7% 2791 / 3375
ironclaw_events 82.86% 1765 / 2130
ironclaw_reborn_identity 83.59% 433 / 518
ironclaw_wasm 83.97% 1011 / 1204
ironclaw_auth 83.99% 3147 / 3747
ironclaw_reborn_config 84.06% 1814 / 2158
ironclaw_processes 84.44% 993 / 1176
ironclaw_common 84.85% 1490 / 1756
ironclaw_turns 85.08% 13684 / 16084
ironclaw_host_api 85.13% 2663 / 3128
ironclaw_product_workflow 85.57% 10845 / 12674
ironclaw_projects 85.92% 659 / 767
ironclaw_network 86.12% 670 / 778
ironclaw_threads 86.7% 4594 / 5299
ironclaw_slack_v2_adapter 86.79% 1806 / 2081
ironclaw_product_adapters 87.18% 3265 / 3745
ironclaw_skills 87.6% 4471 / 5104
ironclaw_hooks 87.78% 9921 / 11302
ironclaw_product_adapter_registry 88.06% 531 / 603
ironclaw_reborn_traces 88.19% 11946 / 13546
ironclaw_host_runtime 88.59% 17395 / 19635
ironclaw_reborn_composition 89.28% 80125 / 89747
ironclaw_extensions 89.38% 2971 / 3324
ironclaw_approvals 89.41% 1587 / 1775
ironclaw_runner 89.41% 16916 / 18919
ironclaw_reborn_openai_compat 89.55% 3798 / 4241
ironclaw_conversations 90.33% 3121 / 3455
ironclaw_event_streams 90.82% 1009 / 1111
ironclaw_loop_host 92.52% 14811 / 16008
ironclaw_resources 92.83% 4736 / 5102
ironclaw_attachments 93.06% 630 / 677
ironclaw_reborn_webui_ingress 93.19% 2217 / 2379
ironclaw_telegram_v2_adapter 93.62% 2511 / 2682
ironclaw_agent_loop 94.83% 9148 / 9647
ironclaw_safety 95.04% 3677 / 3869
ironclaw_first_party_extension_ports 95.24% 3343 / 3510
ironclaw_outbound 95.59% 3556 / 3720

This table itself is informational and never gates the PR on its own — not the percentage, not the per-crate holes, not the 0-coverage callout. A separate coverage ratchet (dry-run until enforce=true; see tests/integration/coverage-floor.toml) can fail the build on specific configured floors.

Exemptions (3 entry/entries excluded from the accounting above)
Module / Crate Reason Issue
crate: ironclaw_embeddings v1-only: consumed only by root ironclaw (src/app.rs, src/tools/builtin/memory.rs, src/workspace/mod.rs, src/config/{mod,embeddings}.rs); no crates/* dependents. Covered by "Tests (Legacy)". #5657
crate: ironclaw_gateway v1-only: consumed only by root ironclaw (src/channels/web/platform/static_files.rs, src/channels/web/handlers/frontend.rs); no crates/* dependents. Covered by "Tests (Legacy)". #5657
crate: ironclaw_tui v1-only: consumed only by root ironclaw (src/main.rs, src/channels/tui.rs); no crates/* dependents. Crate's own doc comment confirms it bridges INTO v1, not Reborn. Covered by "Tests (Legacy)". #5657

@railway-app

railway-app Bot commented Jul 13, 2026 •

Copy link
Copy Markdown

🚅 Deployed to the ironclaw-pr-6041 environment in ironclaw-ci-preview

Service Status Web Updated (UTC)
ironclaw ✅ Success (View Logs) Web Jul 14, 2026 at 11:01 am

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6041 July 13, 2026 11:55 Destroyed
@italic-jinxin italic-jinxin added the human-verified Manually tested and verified label Jul 13, 2026
@italic-jinxin italic-jinxin self-assigned this Jul 13, 2026
…e-contrast

# Conflicts:
#	crates/ironclaw_webui_v2/frontend/src/design-system/button.test.tsx
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6041 July 14, 2026 05:36 Destroyed
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6041 July 14, 2026 06:12 Destroyed

@hanakannzashi hanakannzashi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: The outline button still misses WCAG AA in interactive states.

For the Registry Install button on --v2-surface-soft: #eef4fa, the 12px --v2-accent-text: #146fae text is approximately 4.39:1 on the hover background and 4.09:1 on the active background, both below the required 4.5:1. The current E2E contrast assertion checks only the idle state, so CI remains green.

Please darken the text or reduce/change the interactive background mix, and add hover plus pressed-state contrast assertions.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6041 July 14, 2026 10:37 Destroyed
@italic-jinxin

Copy link
Copy Markdown
Contributor Author

P2: The outline button still misses WCAG AA in interactive states.

For the Registry Install button on --v2-surface-soft: #eef4fa, the 12px --v2-accent-text: #146fae text is approximately 4.39:1 on the hover background and 4.09:1 on the active background, both below the required 4.5:1. The current E2E contrast assertion checks only the idle state, so CI remains green.

Please darken the text or reduce/change the interactive background mix, and add hover plus pressed-state contrast assertions.

Good catch — fixed in 182a7532f and 3476fdec3.

I darkened the light-theme --v2-accent-text from #146fae to #10649e. The resulting contrast ratios are approximately:

  • Idle: 5.68:1
  • Hover: 5.15:1
  • Pressed: 4.80:1

I also extended the Playwright E2E test to exercise the real Registry Install button in idle, hover, and mouse-down pressed states. The test reproduced the original hover failure at 4.39:1 before the fix and now passes for all three states.

@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6041 July 14, 2026 10:39 Destroyed
@railway-app
railway-app Bot temporarily deployed to ironclaw-ci-preview / ironclaw-pr-6041 July 14, 2026 10:45 Destroyed

@hanakannzashi hanakannzashi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Re-reviewed current head 1e83252. The previous outline interaction-state contrast finding is resolved. Against the actual Registry card background, contrast is approximately 5.68:1 idle, 5.15:1 hover, and 4.80:1 active, all above WCAG AA 4.5:1. The new browser assertion correctly exercises and distinguishes hover/pressed backgrounds. With TZ=UTC, all 728 frontend tests pass; typecheck and current CI are green. No remaining actionable findings.

@italic-jinxin
italic-jinxin added this pull request to the merge queue Jul 14, 2026
Merged via the queue into main with commit c41d3f6 Jul 14, 2026
63 checks passed
@italic-jinxin
italic-jinxin deleted the issue-6039-light-theme-contrast branch July 14, 2026 15:04
@coderabbitai coderabbitai Bot mentioned this pull request Jul 31, 2026
5 of 22 tasks

This branch was successfully deployed

No deployments
ironclaw-ci-preview / ironclaw-pr-6041 — 1e832522 Deployed Jul 14, 2026 by railway-app[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs human-verified Manually tested and verified risk: low Changes to docs, tests, or low-risk modules size: M 50-199 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Light theme has unreadable button and status colors

2 participants