` with three buttons
- Each button: `type="button"`, `aria-pressed={theme === v}`, `onClick={() => select(v)}`
- Active state: `bg-primary text-on-primary font-medium`
- Inactive state: `bg-surface-container text-on-surface-container hover:bg-surface`
- Icons: Sun for Light, Moon for Dark, Monitor for System (use Unicode or simple SVG inline icons)
- Outer div: `flex rounded-md border border-outline overflow-hidden text-sm`
Run tests — they must PASS (GREEN).
**App.tsx** updates:
1. Add `import { ThemeToggle } from './components/ui/ThemeToggle';`
2. Change the header from centered h1 to a flex row: `
`
3. h1 keeps `text-3xl font-bold` but change `text-gray-900` to `text-on-surface`, remove `text-center`
4. Add `
` as second child in the flex row
5. Change outer div `bg-gray-50` to `bg-surface`
6. Change h1 `text-gray-900` to `text-on-surface`
Run full test suite to confirm no regressions.
cd C:/Users/SebastienQUEROL/Documents/projets/Ready2Blob && npm test 2>&1 | tail -20
ThemeToggle.test.tsx has 6+ passing tests. ThemeToggle renders segmented control with Light/Dark/System. App.tsx header shows title left and ThemeToggle right. All existing tests still pass. App outer div uses bg-surface, h1 uses text-on-surface.
1. `npx vite build` completes without errors
2. `npm test` — all tests pass (existing + new ThemeToggle tests)
3. `grep -c "@theme" src/index.css` returns 1 (theme block exists)
4. `grep -c "r2b-theme" index.html` returns at least 1 (inline script present)
5. `grep "ThemeToggle" src/App.tsx` confirms component is wired in
- Token system produces working Tailwind utility classes: bg-surface, text-on-surface, bg-primary, etc.
- Dark mode toggle works: clicking Dark applies .dark class, Light removes it, System checks OS preference
- Flash prevention: inline script in index.html reads localStorage before CSS paints
- ThemeToggle has passing unit tests covering all three modes and DOM class toggling
- No regression in existing test suite