Added agentic files.
This commit is contained in:
@@ -0,0 +1,642 @@
|
||||
# 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
|
||||
<?php
|
||||
$themeSection = $themeSection ?? null;
|
||||
|
||||
if ($themeSection === 'head') {
|
||||
// output head-only theme bootstrap and shared CSS
|
||||
} elseif ($themeSection === 'body') {
|
||||
// output body-only floating toggle and behavior script
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Implement `head` output with early theme bootstrap script**
|
||||
|
||||
```php
|
||||
<script>
|
||||
(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);
|
||||
})();
|
||||
</script>
|
||||
```
|
||||
|
||||
Expected output:
|
||||
- `<html>` 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
|
||||
<style>
|
||||
:root {
|
||||
--theme-bg: #f3f4f6;
|
||||
--theme-surface: #ffffff;
|
||||
--theme-surface-alt: #f9fafb;
|
||||
--theme-text: #1f2937;
|
||||
--theme-text-muted: #4b5563;
|
||||
--theme-border: #d1d5db;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
--theme-bg: #0f172a;
|
||||
--theme-surface: #111827;
|
||||
--theme-surface-alt: #1f2937;
|
||||
--theme-text: #e5e7eb;
|
||||
--theme-text-muted: #9ca3af;
|
||||
--theme-border: #374151;
|
||||
}
|
||||
|
||||
.theme-page { background-color: var(--theme-bg); color: var(--theme-text); }
|
||||
.theme-surface { background-color: var(--theme-surface); color: var(--theme-text); }
|
||||
.theme-surface-alt { background-color: var(--theme-surface-alt); }
|
||||
.theme-text { color: var(--theme-text); }
|
||||
.theme-text-muted { color: var(--theme-text-muted); }
|
||||
.theme-border { border-color: var(--theme-border); }
|
||||
.theme-input { background-color: var(--theme-surface); color: var(--theme-text); border-color: var(--theme-border); }
|
||||
|
||||
#themeToggle {
|
||||
position: fixed;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
#themeToggle:focus-visible {
|
||||
outline: 2px solid #2563eb;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
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
|
||||
<button id="themeToggle" type="button" aria-label="Switch to dark mode" title="Switch to dark mode">
|
||||
<i id="themeToggleIcon" class="bi bi-moon-stars-fill"></i>
|
||||
</button>
|
||||
<noscript><style>#themeToggle{display:none;}</style></noscript>
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Implement `body` behavior script with cookie helpers and state sync**
|
||||
|
||||
```php
|
||||
<script>
|
||||
(function() {
|
||||
var toggle = document.getElementById('themeToggle');
|
||||
var icon = document.getElementById('themeToggleIcon');
|
||||
|
||||
function readThemeCookie() {
|
||||
var match = document.cookie.match(/(?:^|; )theme=([^;]+)/);
|
||||
if (!match) return null;
|
||||
var value = decodeURIComponent(match[1]);
|
||||
return (value === 'dark' || value === 'light') ? value : null;
|
||||
}
|
||||
|
||||
function writeThemeCookie(theme) {
|
||||
document.cookie = 'theme=' + encodeURIComponent(theme) + '; max-age=31536000; path=/; SameSite=Lax';
|
||||
}
|
||||
|
||||
function applyTheme(theme) {
|
||||
var isDark = theme === 'dark';
|
||||
document.documentElement.classList.toggle('dark', isDark);
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
}
|
||||
|
||||
function syncToggle(theme) {
|
||||
var isDark = theme === 'dark';
|
||||
icon.className = isDark ? 'bi bi-sun-fill' : 'bi bi-moon-stars-fill';
|
||||
var nextAction = isDark ? 'Switch to light mode' : 'Switch to dark mode';
|
||||
toggle.setAttribute('aria-label', nextAction);
|
||||
toggle.setAttribute('title', nextAction);
|
||||
}
|
||||
|
||||
var currentTheme = document.documentElement.classList.contains('dark') ? 'dark' : (readThemeCookie() || 'light');
|
||||
syncToggle(currentTheme);
|
||||
|
||||
toggle.addEventListener('click', function() {
|
||||
currentTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
||||
applyTheme(currentTheme);
|
||||
writeThemeCookie(currentTheme);
|
||||
syncToggle(currentTheme);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
```
|
||||
|
||||
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
|
||||
<?php $themeSection = 'head'; include __DIR__ . '/partials/theme.php'; ?>
|
||||
```
|
||||
|
||||
Placement: in `<head>`, after Tailwind/bootstrap includes, before `</head>`.
|
||||
|
||||
- [ ] **Step 2: Insert body include in `views/login.php`**
|
||||
|
||||
```php
|
||||
<?php $themeSection = 'body'; include __DIR__ . '/partials/theme.php'; ?>
|
||||
```
|
||||
|
||||
Placement: before `</body>`.
|
||||
|
||||
- [ ] **Step 3: Apply color-only updates in `views/login.php`**
|
||||
|
||||
Apply concrete replacements:
|
||||
- `<body class="bg-gray-100 ...">` -> `<body class="theme-page ...">`
|
||||
- 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
|
||||
<?php $themeSection = 'head'; include __DIR__ . '/partials/theme.php'; ?>
|
||||
```
|
||||
|
||||
Placement: in `<head>`, after Tailwind/bootstrap includes, before `</head>`.
|
||||
|
||||
- [ ] **Step 5: Insert body include in `views/setup.php`**
|
||||
|
||||
```php
|
||||
<?php $themeSection = 'body'; include __DIR__ . '/partials/theme.php'; ?>
|
||||
```
|
||||
|
||||
Placement: before `</body>`.
|
||||
|
||||
- [ ] **Step 6: Apply color-only updates in `views/setup.php`**
|
||||
|
||||
Apply concrete replacements:
|
||||
- `<body class="bg-gray-100 ...">` -> `<body class="theme-page ...">`
|
||||
- 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
|
||||
<?php $themeSection = 'head'; include __DIR__ . '/partials/theme.php'; ?>
|
||||
```
|
||||
|
||||
Placement requirement: after Tailwind/bootstrap includes and before `</head>`.
|
||||
|
||||
Expected outcome: exactly one head include in required position.
|
||||
|
||||
- [ ] **Step 2: Add body include in `views/index.php`**
|
||||
|
||||
```php
|
||||
<?php $themeSection = 'body'; include __DIR__ . '/partials/theme.php'; ?>
|
||||
```
|
||||
|
||||
Placement requirement: before local page scripts and before `</body>`.
|
||||
|
||||
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 `<thead class="bg-gray-50 border-b">` -> 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
|
||||
<?php $themeSection = 'head'; include __DIR__ . '/partials/theme.php'; ?>
|
||||
```
|
||||
|
||||
Placement requirement: after Tailwind/bootstrap includes and before `</head>`.
|
||||
|
||||
Expected outcome: exactly one head include in required position.
|
||||
|
||||
- [ ] **Step 2: Add body include in `views/vehicle.php`**
|
||||
|
||||
```php
|
||||
<?php $themeSection = 'body'; include __DIR__ . '/partials/theme.php'; ?>
|
||||
```
|
||||
|
||||
Placement requirement: before page-local scripts and before `</body>`.
|
||||
|
||||
Expected outcome: exactly one body include in required position.
|
||||
|
||||
- [ ] **Step 3: Update page shell, vehicle card, and maintenance form in `views/vehicle.php`**
|
||||
|
||||
Concrete updates:
|
||||
- body/header/card backgrounds `bg-white/bg-gray-*` -> theme classes
|
||||
- text grays on headings/body -> `theme-text` / `theme-text-muted`
|
||||
- form inputs/borders -> `theme-input theme-border`
|
||||
|
||||
Expected outcome: top section and add-maintenance form are readable in both themes.
|
||||
|
||||
- [ ] **Step 4: Update dropdown menu surfaces in `views/vehicle.php`**
|
||||
|
||||
Concrete updates:
|
||||
- suggestions box `bg-white border-gray-300` -> `theme-surface theme-border`
|
||||
- export menu panel `bg-white` -> `theme-surface`
|
||||
- export menu links `hover:bg-gray-100` -> `hover:opacity-95`
|
||||
- export menu link text grays -> `theme-text`
|
||||
|
||||
Expected outcome: dropdown menus remain readable and interactive in both themes.
|
||||
|
||||
- [ ] **Step 5: Update maintenance history surfaces in `views/vehicle.php`**
|
||||
|
||||
Concrete updates:
|
||||
- history container `bg-white` -> `theme-surface`
|
||||
- item cards `border-gray-200` -> `theme-border`
|
||||
- item card hover `hover:border-blue-300` -> `hover:border-blue-500`
|
||||
- item metadata text gray shades -> `theme-text-muted`
|
||||
|
||||
Expected outcome: maintenance history cards remain readable in both themes.
|
||||
|
||||
- [ ] **Step 6: Update modal panel and input surfaces in `views/vehicle.php`**
|
||||
|
||||
Concrete updates:
|
||||
- edit modal panels `bg-white` -> `theme-surface`
|
||||
- modal input `border-gray-300` -> `theme-input theme-border`
|
||||
- modal close/cancel text grays -> `theme-text-muted`
|
||||
|
||||
Expected outcome: dropdowns, history cards, and modals remain readable and interactive in both themes.
|
||||
|
||||
- [ ] **Step 7: Run syntax check for `views/vehicle.php`**
|
||||
|
||||
Run: `php -l views/vehicle.php`
|
||||
|
||||
Expected: `No syntax errors detected in views/vehicle.php`.
|
||||
|
||||
- [ ] **Step 8: Manual verification for `/vehicles/{id}`**
|
||||
|
||||
Expected:
|
||||
- theme toggles and persists
|
||||
- forms/dropdowns/modals remain readable in both themes
|
||||
- navigation to/from `/home` keeps cookie-based preference
|
||||
|
||||
- [ ] **Step 9: Commit Task 4**
|
||||
|
||||
```bash
|
||||
git add views/vehicle.php
|
||||
git commit -m "feat: integrate dark mode support in vehicle detail view"
|
||||
```
|
||||
|
||||
### Task 5: Integrate theme partial into settings view
|
||||
|
||||
**Files:**
|
||||
- Modify: `views/settings.php`
|
||||
- Test: `/settings`
|
||||
|
||||
- [ ] **Step 1: Add head include in `views/settings.php`**
|
||||
|
||||
```php
|
||||
<?php $themeSection = 'head'; include __DIR__ . '/partials/theme.php'; ?>
|
||||
```
|
||||
|
||||
Placement requirement: after Tailwind/bootstrap includes and before `</head>`.
|
||||
|
||||
Expected outcome: exactly one head include in required position.
|
||||
|
||||
- [ ] **Step 2: Add body include in `views/settings.php`**
|
||||
|
||||
```php
|
||||
<?php $themeSection = 'body'; include __DIR__ . '/partials/theme.php'; ?>
|
||||
```
|
||||
|
||||
Placement requirement: before local scripts (if any) and before `</body>`.
|
||||
|
||||
Expected outcome: exactly one body include in required position.
|
||||
|
||||
- [ ] **Step 3: Update page/header/card surfaces in `views/settings.php`**
|
||||
|
||||
Concrete updates:
|
||||
- body/header/cards `bg-white/bg-gray-*` -> `theme-page`/`theme-surface`/`theme-surface-alt`
|
||||
- gray text classes -> `theme-text` / `theme-text-muted`
|
||||
|
||||
Expected outcome: page shell and cards remain readable in both themes.
|
||||
|
||||
- [ ] **Step 4: Update list rows and password form surfaces in `views/settings.php`**
|
||||
|
||||
Concrete updates:
|
||||
- quick-task row hover/background and borders -> theme classes
|
||||
- password input borders/backgrounds -> `theme-input theme-border`
|
||||
|
||||
Expected outcome: list rows and form fields are readable and distinguishable in both themes.
|
||||
|
||||
- [ ] **Step 5: Verify action/footer contrast in `views/settings.php`**
|
||||
|
||||
Concrete updates:
|
||||
- logout action danger colors may be adjusted if needed for dark-mode contrast while preserving danger semantics
|
||||
- powered footer card `bg-white` -> `theme-surface`
|
||||
- powered footer title/body grays -> `theme-text` / `theme-text-muted`
|
||||
- GitHub icon/link muted grays -> `theme-text-muted` while preserving blue link emphasis
|
||||
|
||||
Expected outcome: call-to-action and footer text remain legible in both themes.
|
||||
|
||||
- [ ] **Step 6: Run syntax check for `views/settings.php`**
|
||||
|
||||
Run: `php -l views/settings.php`
|
||||
|
||||
Expected: `No syntax errors detected in views/settings.php`.
|
||||
|
||||
- [ ] **Step 7: Manual verification for `/settings`**
|
||||
|
||||
Expected:
|
||||
- theme toggles and persists
|
||||
- cards/list rows/inputs remain readable in both themes
|
||||
- navigation to/from `/home` keeps cookie-based preference
|
||||
|
||||
- [ ] **Step 8: Commit Task 5**
|
||||
|
||||
```bash
|
||||
git add views/settings.php
|
||||
git commit -m "feat: integrate dark mode support in settings view"
|
||||
```
|
||||
|
||||
### Task 6: Validate export exception and complete end-to-end checks
|
||||
|
||||
**Files:**
|
||||
- Verify unchanged: `views/export.php`
|
||||
- Verify behavior: `views/partials/theme.php`
|
||||
- Verify integrated views: `views/login.php`, `views/setup.php`, `views/index.php`, `views/vehicle.php`, `views/settings.php`
|
||||
|
||||
- [ ] **Step 1: Verify `views/export.php` has no theme include/toggle**
|
||||
|
||||
Expected:
|
||||
- no `$themeSection` include
|
||||
- no `#themeToggle` markup
|
||||
- no dark-mode bootstrap script and no `html.dark` application path in export template
|
||||
|
||||
- [ ] **Step 2: Verify cookie contract in devtools**
|
||||
|
||||
Flow:
|
||||
- toggle theme on any themed page
|
||||
- inspect cookie attributes
|
||||
|
||||
Expected:
|
||||
- cookie name `theme`
|
||||
- value `dark` or `light`
|
||||
- `Max-Age=31536000`
|
||||
- `Path=/`
|
||||
- `SameSite=Lax`
|
||||
|
||||
- [ ] **Step 3: Verify accessibility state updates on toggle**
|
||||
|
||||
Flow:
|
||||
- focus toggle via keyboard
|
||||
- activate twice
|
||||
|
||||
Expected per click:
|
||||
- icon swaps moon/sun
|
||||
- `aria-label` and `title` update to next action
|
||||
|
||||
- [ ] **Step 4: Verify export is always light**
|
||||
|
||||
Flow:
|
||||
- set `theme=dark`
|
||||
- open `/vehicles/{id}/export/html`
|
||||
|
||||
Expected:
|
||||
- export remains light styled
|
||||
- toggle not present
|
||||
- `<html>` does not receive `dark` class on export, even when `theme=dark`
|
||||
|
||||
- [ ] **Step 5: Verify toggle stays visible above modals/dropdowns**
|
||||
|
||||
Flow:
|
||||
- open each page with modal/dropdown support (`/home`, `/vehicles/{id}`)
|
||||
- open add/edit modals and export/suggestions dropdowns
|
||||
|
||||
Expected:
|
||||
- floating toggle remains visible and clickable above overlays
|
||||
|
||||
- [ ] **Step 5a: Apply layering remediation if Step 5 fails**
|
||||
|
||||
Flow:
|
||||
- if toggle is hidden or unclickable over overlays, adjust stacking order in `views/partials/theme.php`
|
||||
|
||||
Concrete remediation:
|
||||
- increase `#themeToggle` z-index above conflicting overlay layer
|
||||
- if conflict persists, reduce non-critical overlay z-index where safe without breaking modal usability
|
||||
|
||||
Expected:
|
||||
- toggle remains visible/clickable while modals/dropdowns still function correctly
|
||||
|
||||
- [ ] **Step 6: Verify no-cookie fallback uses system preference**
|
||||
|
||||
Flow:
|
||||
- delete `theme` cookie
|
||||
- load `/home`
|
||||
|
||||
Expected:
|
||||
- resolved theme follows current `prefers-color-scheme`
|
||||
|
||||
- [ ] **Step 7: Verify invalid-cookie fallback**
|
||||
|
||||
Flow:
|
||||
- set `theme=invalid`
|
||||
- reload `/home`
|
||||
|
||||
Expected:
|
||||
- invalid cookie ignored
|
||||
- resolved theme follows current system preference
|
||||
|
||||
- [ ] **Step 8: Verify no-JS fallback**
|
||||
|
||||
Flow:
|
||||
- disable JS in browser
|
||||
- open `/login`
|
||||
|
||||
Expected:
|
||||
- light mode only
|
||||
- no visible floating toggle
|
||||
- login form remains usable
|
||||
|
||||
- [ ] **Step 9: Verify cookie-write-failure behavior**
|
||||
|
||||
Flow:
|
||||
- use a browser mode/policy that blocks cookie writes (or simulate via devtools/privacy settings)
|
||||
- click toggle on `/home`
|
||||
|
||||
Expected:
|
||||
- theme still switches immediately on the current page
|
||||
- no error message is shown to the user
|
||||
- persistence across reload is not required in this scenario
|
||||
|
||||
- [ ] **Step 10: Run final PHP syntax sweep**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
php -l views/partials/theme.php && \
|
||||
php -l views/login.php && \
|
||||
php -l views/setup.php && \
|
||||
php -l views/index.php && \
|
||||
php -l views/vehicle.php && \
|
||||
php -l views/settings.php
|
||||
```
|
||||
|
||||
Expected: all report `No syntax errors detected`.
|
||||
|
||||
- [ ] **Step 11: No additional commit for verification-only task**
|
||||
|
||||
Expected:
|
||||
- Task 6 records verification results only.
|
||||
- No new commit is created unless this task introduces actual file changes.
|
||||
Reference in New Issue
Block a user