# Dark Mode Support Implementation Plan > **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Add cookie-persisted dark/light theming with a floating top-right toggle on all regular views, while keeping export always light. **Architecture:** Theme behavior is centralized in one reusable partial with two include modes (`head` and `body`) so every themed page gets identical bootstrap, cookie logic, and toggle UI. Existing views keep structure/layout classes and only adjust color-related classes needed for dark-mode readability. Export is explicitly excluded and remains light-only. **Tech Stack:** PHP 8, server-rendered PHP views, Tailwind via CDN, Bootstrap Icons, vanilla JavaScript, browser cookies. --- ## Chunk 1: Shared Theme Unit and Core Integration ### Task 1: Create shared theme partial with explicit section contract **Files:** - Create: `views/partials/theme.php` - Test: browser manual validation on `/login` after integration - [ ] **Step 1: Add section-gated partial skeleton** ```php (function() { function readThemeCookie() { var match = document.cookie.match(/(?:^|; )theme=([^;]+)/); if (!match) return null; var value = decodeURIComponent(match[1]); return (value === 'dark' || value === 'light') ? value : null; } var cookieTheme = readThemeCookie(); var systemDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; var resolved = cookieTheme || (systemDark ? 'dark' : 'light'); document.documentElement.classList.toggle('dark', resolved === 'dark'); document.documentElement.setAttribute('data-theme', resolved); })(); ``` Expected output: - `` has `dark` class before body render when resolved theme is dark. - `data-theme` is set to `dark` or `light`. - [ ] **Step 3: Implement `head` shared CSS tokens and semantic utility classes** ```php ``` Expected output: - Shared classes exist for page/surface/text/border/input mappings. - Toggle has fixed top-right placement and z-index 50. - [ ] **Step 4: Implement `body` output with toggle markup and no-JS fallback** ```php ``` - [ ] **Step 5: Implement `body` behavior script with cookie helpers and state sync** ```php ``` Expected output: - Click toggles theme immediately, updates icon, `aria-label`, and `title`. - Cookie write attempt does not block visual switch if persistence is restricted. - [ ] **Step 6: Run syntax check for new partial** Run: `php -l views/partials/theme.php` Expected: `No syntax errors detected in views/partials/theme.php`. - [ ] **Step 7: Commit Task 1** ```bash git add views/partials/theme.php git commit -m "feat: add shared theme partial with cookie-based dark mode" ``` ### Task 2: Integrate theme partial into login and setup views **Files:** - Modify: `views/login.php` - Modify: `views/setup.php` - Test: `/login`, `/setup` - [ ] **Step 1: Insert head include in `views/login.php`** ```php ``` Placement: in `
`, after Tailwind/bootstrap includes, before ``. - [ ] **Step 2: Insert body include in `views/login.php`** ```php ``` Placement: before ``. - [ ] **Step 3: Apply color-only updates in `views/login.php`** Apply concrete replacements: - `` -> `` - login card `bg-white` -> `theme-surface` - heading `text-gray-800` -> `theme-text` - label text `text-gray-700` -> `theme-text` - input `border-gray-300` -> add `theme-input theme-border` Expected outcome: login card, labels, and input fields are readable in both themes without layout shift. - [ ] **Step 4: Insert head include in `views/setup.php`** ```php ``` Placement: in ``, after Tailwind/bootstrap includes, before ``. - [ ] **Step 5: Insert body include in `views/setup.php`** ```php ``` Placement: before ``. - [ ] **Step 6: Apply color-only updates in `views/setup.php`** Apply concrete replacements: - `` -> `` - setup card `bg-white` -> `theme-surface` - title and labels `text-gray-*` -> `theme-text` / `theme-text-muted` - password inputs `border-gray-300` -> add `theme-input theme-border` Expected outcome: setup page remains visually consistent, with readable text/inputs in both themes. - [ ] **Step 7: Run syntax checks for auth/setup views** Run: `php -l views/login.php && php -l views/setup.php` Expected: both report `No syntax errors detected`. - [ ] **Step 8: Manual verification on `/login` and `/setup`** Expected: - toggle appears fixed top-right - keyboard Tab focuses toggle with visible focus style - Enter/Space toggles theme - icon and `aria-label`/`title` change each toggle - reload preserves preference - [ ] **Step 9: Commit Task 2** ```bash git add views/login.php views/setup.php git commit -m "feat: integrate dark mode toggle on auth and setup views" ``` ## Chunk 2: Main Views, Export Exception, and Final Verification ### Task 3: Integrate theme partial into home view **Files:** - Modify: `views/index.php` - Test: `/home` - [ ] **Step 1: Add head include in `views/index.php`** ```php ``` Placement requirement: after Tailwind/bootstrap includes and before ``. Expected outcome: exactly one head include in required position. - [ ] **Step 2: Add body include in `views/index.php`** ```php ``` Placement requirement: before local page scripts and before ``. Expected outcome: exactly one body include in required position. - [ ] **Step 3: Update page and header surfaces in `views/index.php`** Concrete updates: - body wrapper `bg-gray-100` -> `theme-page` - header/card wrappers `bg-white` -> `theme-surface` - heading/body text `text-gray-*` -> `theme-text` / `theme-text-muted` Expected outcome: page shell and header are readable in both themes. - [ ] **Step 4: Update table surfaces in `views/index.php`** Concrete updates: - table header `` -> use `theme-surface-alt theme-border` - table body divider `divide-gray-200` -> `theme-border` - table cell text classes `text-gray-500`, `text-gray-600`, `text-gray-900` -> `theme-text`/`theme-text-muted` Expected outcome: table head/body text and borders remain readable in both themes. - [ ] **Step 5: Update vehicle cards/list rows in `views/index.php`** Concrete updates: - grid cards `bg-white` -> `theme-surface` - list container `bg-white` -> `theme-surface` - row hover `hover:bg-gray-50` -> `hover:opacity-95` and apply `theme-surface-alt` on row container where needed - small metadata text `text-gray-*` -> `theme-text-muted` Expected outcome: vehicle cards/list rows remain readable in both themes. - [ ] **Step 6: Update modal container and input surfaces in `views/index.php`** Concrete updates: - modal panel `bg-white` -> `theme-surface` - modal close/cancel gray text -> `theme-text-muted` - inputs with `border-gray-300` -> add `theme-input theme-border` - optional helper text gray shades -> `theme-text-muted` Expected outcome: cards, table, and modal inputs remain readable/usable in both themes. - [ ] **Step 7: Verify and adjust flash message contrast in `views/index.php`** Concrete updates: - keep existing light-mode classes for base state (`bg-red-100 border-red-400 text-red-700`, `bg-green-100 border-green-400 text-green-700`) - add dark-only variants (using `dark:` classes or equivalent conditional class strategy) for error/success contrast in dark mode - keep existing rounded/padding/layout classes unchanged Expected outcome: error and success flash messages are legible and visually distinct in both light and dark modes. - [ ] **Step 8: Run syntax check for `views/index.php`** Run: `php -l views/index.php` Expected: `No syntax errors detected in views/index.php`. - [ ] **Step 9: Manual verification for `/home`** Expected: - theme toggles correctly - theme persists after reload - cards/tables/modals remain readable in both themes - [ ] **Step 10: Commit Task 3** ```bash git add views/index.php git commit -m "feat: integrate dark mode support in home view" ``` ### Task 4: Integrate theme partial into vehicle detail view **Files:** - Modify: `views/vehicle.php` - Test: `/vehicles/{id}` - [ ] **Step 1: Add head include in `views/vehicle.php`** ```php ``` Placement requirement: after Tailwind/bootstrap includes and before ``. Expected outcome: exactly one head include in required position. - [ ] **Step 2: Add body include in `views/vehicle.php`** ```php ``` Placement requirement: before page-local scripts and before `