|
3 | 3 | ## Goals |
4 | 4 |
|
5 | 5 | 1. Three-mode theme control — **light / dark / system** — with small images |
6 | | - (icons) for each mode, on a sub-row below the top menu bar. |
| 6 | + (icons) for each mode, on a row below the site header. |
7 | 7 | 2. The control's right edge aligns with the menu bar's right content edge at |
8 | 8 | every viewport (mirroring how the breadcrumb trail aligns with the menu's |
9 | 9 | left edge). |
|
19 | 19 | renders three radios named `rf-theme` (`rf-theme-light`, `rf-theme-dark`, |
20 | 20 | `rf-theme-system`, with `system` `defaultChecked`), each wrapped in a labelled |
21 | 21 | icon pill (inline SVG: sun / moon / monitor). The toggle sits on the |
22 | | -**`.theme-bar` sub-row under `.menu-bar`**, inside `#top-menu`, right-aligned |
23 | | -with the menu bar's content edge. |
| 22 | +**`.theme-bar` row below `#top-menu`**, rendered by `app/layout.jsx` right |
| 23 | +after `<SiteHeader />` (and before the persistence shim, which needs the |
| 24 | +radios parsed), right-aligned with the menu bar's content edge. |
24 | 25 |
|
25 | 26 | Why radios: "one of three modes" is exactly a radio group, the checked state |
26 | 27 | is queryable from CSS (`:has(#id:checked)`), and switching requires zero JS. |
@@ -122,15 +123,16 @@ practices" and "only CSS" conflict here, so the plan resolves it as: |
122 | 123 |
|
123 | 124 | ### Alignment with the menu |
124 | 125 |
|
125 | | -The toggle lives on a `.theme-bar` sub-row inside `#top-menu`, right after |
126 | | -`.menu-bar`, and pinned right via `justify-content: flex-end`. The row |
127 | | -reuses the breadcrumbs' exact alignment formula — `max-width: |
128 | | -var(--width-content)`, `box-sizing: border-box`, `margin: 0 auto`, |
129 | | -`padding: 0.2rem 0.8rem 0.45rem` (see `tests/unit/layout-styles.test.js` for |
130 | | -the breadcrumb invariant this mirrors) — so its right content edge is the |
131 | | -menu bar's right content edge at every viewport, with no positioning tricks |
132 | | -or magic numbers; the formula works identically at mobile widths, where the |
133 | | -sub-row simply follows the wrapped menu bar. |
| 126 | +The toggle lives on a `.theme-bar` row rendered by `app/layout.jsx` right |
| 127 | +after `<SiteHeader />`, below the header block, pinned right via |
| 128 | +`justify-content: flex-end`. The row reuses the breadcrumbs' exact alignment |
| 129 | +formula — `max-width: var(--width-content)`, `box-sizing: border-box`, |
| 130 | +`margin: 0 auto`, `padding: 0.4rem 0.8rem 0.45rem` (see |
| 131 | +`tests/unit/layout-styles.test.js` for the breadcrumb invariant this mirrors) |
| 132 | +— so its right content edge is the menu bar's right content edge at every |
| 133 | +viewport, with no positioning tricks or magic numbers; the formula works |
| 134 | +identically at mobile widths, where the row simply follows the wrapped menu |
| 135 | +bar. |
134 | 136 |
|
135 | 137 | ### Toggle UI / a11y |
136 | 138 |
|
@@ -191,8 +193,9 @@ mustache-rendered). |
191 | 193 | ## Implementation steps |
192 | 194 |
|
193 | 195 | 1. Write the failing unit/integration tests (above). |
194 | | -2. `components/theme-toggle.jsx` + render it in `components/site-header.jsx` |
195 | | - on a `.theme-bar` sub-row after `.menu-bar`. |
| 196 | +2. `components/theme-toggle.jsx` + render it in `app/layout.jsx` on a |
| 197 | + `.theme-bar` row right after `<SiteHeader />`, before the persistence |
| 198 | + shim. |
196 | 199 | 3. globals.css: split color roles, sweep hardcoded colors into variables, add |
197 | 200 | the three cascade blocks + mvp variable overrides + dark overrides for the |
198 | 201 | report template's light-only rules + `.theme-bar`/toggle styles. |
@@ -254,7 +257,7 @@ mustache-rendered). |
254 | 257 | were pre-verified (dark bg/text ≈13:1, muted ≈8:1, links ≈7.7:1, focus |
255 | 258 | indicator 3.8:1 on the page bg (3.3:1 on surfaces), brand-bg+white 5.5:1, |
256 | 259 | error/success ≈8:1). |
257 | | -10. **Alignment is structural, not geometric** — the `.theme-bar` sub-row |
| 260 | +10. **Alignment is structural, not geometric** — the `.theme-bar` row |
258 | 261 | reuses the breadcrumbs' `--width-content` column + 0.8rem padding formula, |
259 | 262 | so the toggle's right edge is the menu bar's right content edge at every |
260 | 263 | viewport with zero positioning code; the E2E test pins it with a |
|
0 commit comments