* feat(ui): add light/dark theme toggle in PortalShell header
Mount ThemeToggle (sun/moon icon button) in the top-right of every
PortalShell page (Sovereign Apps, Jobs, AppDetail, JobDetail). Click
flips the `data-theme` attribute on `<html>` and persists to
`localStorage['oo-theme']`, in lockstep with the existing bootstrap
script in index.html and the useTheme hook.
Light theme palette: extend [data-theme="light"] in globals.css with
peers for every console token (--color-bg, --color-bg-2, --color-text,
--color-text-strong, --color-text-dim, --color-text-dimmer,
--color-border, --color-border-strong, --color-surface,
--color-surface-hover, --color-accent, --color-accent-hover,
--color-warn, --color-danger, --color-success). All ratios are
WCAG AA-or-better against --color-bg = #ffffff:
text-on-bg 17.85:1 AAA
text-strong-on-bg 20.17:1 AAA
text-dim-on-bg 7.58:1 AAA
text-dimmer-on-bg 4.76:1 AA
accent-on-bg 5.17:1 AA
danger-on-bg 6.47:1 AAA
warn-on-bg 5.02:1 AA
success-on-bg 5.48:1 AA
Two cosmetic-guard regression tests are added:
• theme-toggle is present in PortalShell header
• clicking theme-toggle flips data-theme on the html element +
persists to localStorage[oo-theme]
Refs #179.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(wizard): card description = 2 lines, + bubble floats over body
Two regressions on the StepComponents grid (#179):
1) Some cards rendered with a 1-line description because the
.corp-comp-desc rule clamped at 2 lines but did NOT reserve 2
lines of vertical space. Short descriptions collapsed the card
body by ~14px and pulled the chip row (line 4) up, leaving the
chips on a visibly ragged Y across the grid.
Fix: add `min-height: 2.5em` to .corp-comp-desc. Computed value
= 2.5 × 0.76rem × 1.4 lh × 16px = 30.4px reserved height — every
card now hosts 2 lines of description even when the actual copy
is one line. Verified: chipsY identical at 523.1 / 641.5 / 759.8
across each row of three cards on the choose-stack grid.
2) The right ¼ of every card body was effectively empty because
the inline "+" Add button shared line 1 with the family chip,
reserving horizontal space the description never got to use.
Fix: lift the toggle button out of .corp-comp-body and absolute-
position it at top: 0.5rem; right: 0.5rem; z-index: 10 so it
OVERLAYS the description's top-right corner instead of reserving
width. Lines 2-3 (description) now span the full body width.
Acceptance:
• All 93 StepComponents.test.tsx unit tests still pass
• All 17 cosmetic-guard tests still pass (16 unrelated failures
are pre-existing on origin/main, sibling agent territory)
• New cosmetic-guard test "every component card has min-h:108px
and 2-line description" added (asserts webkitLineClamp === '2',
descBox.height ≥ 26px, chip-row Y spread ≤ 2px within a row)
Refs #179.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: hatiyildiz <hatice.yildiz@openova.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>