chore: remove redundant implementation documentation files
Deleted two obsolete documentation files that are no longer needed: - COLOR-THEME-IMPLEMENTATION.md (204 lines) - Feature complete and documented in code - prompts/003-implement-htmx-indicators.md (427 lines) - Implementation prompt no longer relevant These files served their purpose during development but are now redundant with: - Inline code documentation - TEST-SUMMARY.md for test coverage - README.md for user-facing features - Git history for implementation
This commit is contained in:
@@ -0,0 +1,427 @@
|
||||
# Implement HTMX Loading Indicators Throughout CV Application
|
||||
|
||||
<objective>
|
||||
Systematically identify and implement HTMX loading indicators across all interactive elements in the CV application. The goal is to provide visual feedback during HTMX requests, improving perceived performance and user experience by showing users that their actions are being processed.
|
||||
|
||||
**What are HTMX Indicators?**
|
||||
HTMX provides a built-in `htmx-indicator` class that automatically shows/hides elements during HTMX requests. When an HTMX request is in progress, elements with this class become visible; when the request completes, they hide automatically.
|
||||
|
||||
This will make the application feel more responsive and professional by giving users immediate visual feedback for all interactive actions.
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
**Current State:**
|
||||
- The CV application uses HTMX extensively for dynamic interactions:
|
||||
- Language switching (EN/ES)
|
||||
- Toggle controls (length, logos, theme)
|
||||
- Hamburger menu interactions
|
||||
- Other dynamic content updates
|
||||
- Currently, there's **no visual feedback** during these requests - users click and wait with no indication that something is happening
|
||||
|
||||
**HTMX Indicator Pattern:**
|
||||
```html
|
||||
<button hx-get="/endpoint">
|
||||
Click Me!
|
||||
<img class="htmx-indicator" src="/spinner.gif" alt="Loading...">
|
||||
</button>
|
||||
```
|
||||
|
||||
**How it works:**
|
||||
1. By default, elements with `htmx-indicator` class are hidden (`opacity: 0`)
|
||||
2. When parent element initiates an HTMX request, HTMX automatically adds `htmx-request` class
|
||||
3. CSS rule `.htmx-request .htmx-indicator` shows the indicator (`opacity: 1`)
|
||||
4. When request completes, `htmx-request` class is removed, hiding the indicator
|
||||
|
||||
**Benefits:**
|
||||
- Zero JavaScript required - pure declarative HTML
|
||||
- Automatic show/hide behavior
|
||||
- Works with any visual element (spinners, text, icons, etc.)
|
||||
- Improves perceived performance
|
||||
- Professional UX standard
|
||||
|
||||
**Files with HTMX Interactions:**
|
||||
@templates/partials/navigation/language-selector.html - Language switching buttons
|
||||
@templates/partials/navigation/view-controls.html - Toggle controls (length, logos, theme)
|
||||
@templates/partials/navigation/hamburger-menu.html - Menu interactions
|
||||
@templates/language-switch.html - Language switch response template
|
||||
</context>
|
||||
|
||||
<requirements>
|
||||
1. **Comprehensive Audit:**
|
||||
- Search entire codebase for HTMX attributes: `hx-get`, `hx-post`, `hx-put`, `hx-delete`, `hx-patch`
|
||||
- Identify every interactive element that triggers HTMX requests
|
||||
- Categorize by interaction type (buttons, toggles, forms, links, etc.)
|
||||
|
||||
2. **Appropriate Indicator Selection:**
|
||||
- **Language buttons:** Show loading spinner or "Switching..." text
|
||||
- **Toggle switches:** Show subtle spinner next to toggle
|
||||
- **Forms/inputs:** Show spinner or loading state
|
||||
- **Menu interactions:** Show loading indicator if applicable
|
||||
- Consider using iconify-icon for spinners (already in use): `<iconify-icon icon="mdi:loading" class="htmx-indicator spinning"></iconify-icon>`
|
||||
|
||||
3. **Visual Design:**
|
||||
- Indicators should be subtle and non-intrusive
|
||||
- Match existing design language and color palette
|
||||
- Use consistent styling across all indicators
|
||||
- Consider size and positioning relative to parent element
|
||||
- Ensure indicators don't cause layout shift when appearing
|
||||
|
||||
4. **CSS Implementation:**
|
||||
- Use HTMX's default indicator pattern:
|
||||
```css
|
||||
.htmx-indicator {
|
||||
opacity: 0;
|
||||
transition: opacity 200ms ease;
|
||||
}
|
||||
.htmx-request .htmx-indicator,
|
||||
.htmx-request.htmx-indicator {
|
||||
opacity: 1;
|
||||
}
|
||||
```
|
||||
- Add spinning animation for spinner icons:
|
||||
```css
|
||||
.htmx-indicator.spinning {
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
```
|
||||
|
||||
5. **Custom Indicators (Optional):**
|
||||
- For specific cases, use `hx-indicator="#custom-id"` to target a different element
|
||||
- Example: Show a global loading bar at top of page for major operations
|
||||
- Document when and why custom indicators are used vs default pattern
|
||||
|
||||
6. **Performance Considerations:**
|
||||
- Indicators should use GPU-accelerated properties (opacity, transform)
|
||||
- Avoid layout shifts when indicators appear/disappear
|
||||
- Keep animations lightweight and smooth (60fps)
|
||||
|
||||
7. **Edge Cases:**
|
||||
- Very fast responses (<100ms): Indicator might flash briefly - acceptable or add minimum display time?
|
||||
- Slow responses (>2s): Ensure indicator remains visible entire duration
|
||||
- Failed requests: Indicator should hide properly on error states
|
||||
- Rapid clicking: Multiple indicators shouldn't stack or break
|
||||
|
||||
8. **Accessibility:**
|
||||
- Include `aria-busy="true"` during loading states if needed
|
||||
- Ensure screen readers can perceive loading states
|
||||
- Respect `prefers-reduced-motion` for spinning animations
|
||||
</requirements>
|
||||
|
||||
<implementation>
|
||||
**Step-by-Step Implementation Plan:**
|
||||
|
||||
**Phase 1: Audit Current HTMX Usage**
|
||||
1. Search all template files for `hx-get`, `hx-post`, etc.
|
||||
2. Create a list/table of all HTMX interactions found:
|
||||
- Element type (button, toggle, link)
|
||||
- HTMX attribute used
|
||||
- Current file location
|
||||
- Proposed indicator type
|
||||
|
||||
**Phase 2: Design Indicator Components**
|
||||
1. Choose indicator visuals:
|
||||
- Spinner icon (iconify: `mdi:loading` or `mdi:dots-horizontal`)
|
||||
- Text indicators ("Loading...", "Switching...", etc.)
|
||||
- Progress bars (if applicable)
|
||||
|
||||
2. Create reusable indicator patterns:
|
||||
- Standard button spinner
|
||||
- Toggle switch spinner
|
||||
- Inline text spinner
|
||||
|
||||
**Phase 3: Implement CSS Styles**
|
||||
Add to `static/css/main.css`:
|
||||
```css
|
||||
/* ============================================================================
|
||||
HTMX Loading Indicators
|
||||
========================================================================= */
|
||||
|
||||
/* Base indicator styles - hidden by default */
|
||||
.htmx-indicator {
|
||||
opacity: 0;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Show indicators during HTMX requests */
|
||||
.htmx-request .htmx-indicator,
|
||||
.htmx-request.htmx-indicator {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Spinning animation for loading icons */
|
||||
.htmx-indicator.spinning {
|
||||
display: inline-block;
|
||||
animation: htmx-spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes htmx-spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* Respect reduced motion preference */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.htmx-indicator.spinning {
|
||||
animation: none;
|
||||
}
|
||||
.htmx-indicator {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Specific indicator variants */
|
||||
.htmx-indicator.inline {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.htmx-indicator.small {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.htmx-indicator.medium {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
```
|
||||
|
||||
**Phase 4: Update Templates**
|
||||
|
||||
**Example 1: Language Selector Buttons**
|
||||
```html
|
||||
<button class="selector-btn {{if eq .Lang "en"}}active{{end}}"
|
||||
hx-get="/switch-language?lang=en"
|
||||
hx-target="#language-selector"
|
||||
hx-swap="outerHTML">
|
||||
<span>English</span>
|
||||
<iconify-icon icon="mdi:loading"
|
||||
class="htmx-indicator spinning small inline"
|
||||
width="14"
|
||||
height="14"></iconify-icon>
|
||||
</button>
|
||||
```
|
||||
|
||||
**Example 2: Toggle Controls**
|
||||
```html
|
||||
<input type="checkbox"
|
||||
id="lengthToggle"
|
||||
hx-post="/toggle/length?lang={{.Lang}}"
|
||||
hx-swap="none">
|
||||
<iconify-icon icon="mdi:loading"
|
||||
class="htmx-indicator spinning small"
|
||||
width="14"
|
||||
height="14"></iconify-icon>
|
||||
```
|
||||
|
||||
**Example 3: Custom Indicator for Global Actions**
|
||||
```html
|
||||
<!-- At top of page -->
|
||||
<div id="global-loading-bar" class="htmx-indicator global-loading">
|
||||
<div class="loading-bar-fill"></div>
|
||||
</div>
|
||||
|
||||
<!-- In button -->
|
||||
<button hx-get="/heavy-operation"
|
||||
hx-indicator="#global-loading-bar">
|
||||
Run Heavy Operation
|
||||
</button>
|
||||
```
|
||||
|
||||
**Phase 5: Test All Indicators**
|
||||
1. Visually verify each indicator appears during requests
|
||||
2. Test with throttled network (simulate slow responses)
|
||||
3. Test rapid clicking (ensure no broken states)
|
||||
4. Test accessibility (screen readers, reduced motion)
|
||||
|
||||
**What to Prioritize:**
|
||||
1. High-frequency interactions first (language switching, toggles)
|
||||
2. User-initiated actions that might take >200ms
|
||||
3. Actions where users expect feedback (form submissions, data changes)
|
||||
4. Skip indicators for instant operations (<50ms response time)
|
||||
|
||||
**What to Avoid:**
|
||||
- Don't add indicators to every single element blindly - use judgment
|
||||
- Don't use heavy animations or large images - keep it lightweight
|
||||
- Don't cause layout shifts when indicators appear
|
||||
- Don't forget to test with slow network conditions
|
||||
- Don't over-engineer - simple spinners are often best
|
||||
</implementation>
|
||||
|
||||
<output>
|
||||
The following files will be modified:
|
||||
|
||||
1. **`./static/css/main.css`**
|
||||
- Add HTMX indicator base styles
|
||||
- Add spinning animation keyframes
|
||||
- Add indicator size variants (small, medium, large)
|
||||
- Add reduced-motion overrides
|
||||
|
||||
2. **`./templates/partials/navigation/language-selector.html`**
|
||||
- Add loading indicators to EN/ES buttons
|
||||
- Use iconify spinner icon with `htmx-indicator` class
|
||||
|
||||
3. **`./templates/partials/navigation/view-controls.html`**
|
||||
- Add loading indicators to toggle controls (length, logos, theme)
|
||||
- Position indicators appropriately next to toggles
|
||||
|
||||
4. **`./templates/partials/navigation/hamburger-menu.html`**
|
||||
- Add indicators if menu has HTMX interactions requiring feedback
|
||||
|
||||
5. **Any other template files with HTMX interactions** (discovered during audit)
|
||||
- Add appropriate indicators based on interaction type
|
||||
|
||||
**Optional (if needed):**
|
||||
6. **`./templates/partials/global-loading-indicator.html`** (NEW)
|
||||
- Create reusable global loading indicator component
|
||||
- For major operations affecting entire page
|
||||
|
||||
**Documentation:**
|
||||
7. **Add comments in code** explaining indicator patterns for future maintenance
|
||||
</output>
|
||||
|
||||
<verification>
|
||||
Before declaring complete, perform these comprehensive tests:
|
||||
|
||||
**1. Visual Verification:**
|
||||
- [ ] Language switch: Spinner appears on clicked button during switch
|
||||
- [ ] Length toggle: Indicator appears during toggle state change
|
||||
- [ ] Logo toggle: Indicator appears during toggle state change
|
||||
- [ ] Theme toggle: Indicator appears during toggle state change
|
||||
- [ ] All indicators disappear when requests complete
|
||||
- [ ] Indicators are visually consistent across all elements
|
||||
|
||||
**2. Timing Tests:**
|
||||
- [ ] Fast response (<100ms): Indicator appears briefly (acceptable flash)
|
||||
- [ ] Normal response (200-500ms): Indicator clearly visible
|
||||
- [ ] Slow response (>1s): Indicator remains visible entire duration
|
||||
- [ ] Indicators hide immediately when response arrives
|
||||
|
||||
**3. Network Throttling:**
|
||||
- [ ] Open DevTools → Network → Throttle to "Slow 3G"
|
||||
- [ ] Test all HTMX interactions with slow network
|
||||
- [ ] Verify indicators remain visible during extended load times
|
||||
- [ ] Verify no console errors or broken states
|
||||
|
||||
**4. Rapid Interaction Testing:**
|
||||
- [ ] Rapidly click language buttons multiple times
|
||||
- [ ] Rapidly toggle switches back and forth
|
||||
- [ ] Verify indicators don't stack or cause visual glitches
|
||||
- [ ] Verify final state is correct after rapid clicking
|
||||
|
||||
**5. Accessibility Testing:**
|
||||
- [ ] Enable "Reduce motion" in OS settings
|
||||
- [ ] Verify spinning animations are disabled
|
||||
- [ ] Verify indicators still appear (just without animation)
|
||||
- [ ] Test with screen reader - loading states are announced
|
||||
|
||||
**6. Layout Stability:**
|
||||
- [ ] Indicators don't cause content to shift when appearing
|
||||
- [ ] No cumulative layout shift (CLS) issues
|
||||
- [ ] Buttons/toggles maintain consistent size
|
||||
- [ ] Indicators positioned properly in all viewport sizes
|
||||
|
||||
**7. Browser Compatibility:**
|
||||
- [ ] Chrome: All indicators work smoothly
|
||||
- [ ] Firefox: All indicators work smoothly
|
||||
- [ ] Safari: All indicators work smoothly
|
||||
- [ ] Mobile browsers: Touch interactions show indicators
|
||||
|
||||
**8. Error Handling:**
|
||||
- [ ] Simulate failed request (disable backend or use invalid endpoint)
|
||||
- [ ] Verify indicator hides on error
|
||||
- [ ] Verify error state is handled gracefully
|
||||
|
||||
**Success Indicators:**
|
||||
✅ All HTMX interactions have appropriate loading indicators
|
||||
✅ Indicators appear immediately when action is triggered
|
||||
✅ Indicators hide immediately when request completes
|
||||
✅ Animations are smooth and performant (60fps)
|
||||
✅ No layout shifts when indicators appear/disappear
|
||||
✅ Accessibility requirements met (reduced motion, screen readers)
|
||||
✅ Consistent visual design across all indicators
|
||||
✅ Code is maintainable and well-documented
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
1. Every HTMX interaction has an appropriate loading indicator
|
||||
2. Indicators use the standard `htmx-indicator` class pattern
|
||||
3. Visual feedback appears within 50ms of user action
|
||||
4. Indicators are subtle and don't distract from content
|
||||
5. Spinning animations are smooth and GPU-accelerated
|
||||
6. Respects `prefers-reduced-motion` accessibility setting
|
||||
7. No layout shifts or visual glitches when indicators show/hide
|
||||
8. Works consistently across modern browsers and device sizes
|
||||
9. Code follows existing project patterns and conventions
|
||||
10. Implementation is maintainable with clear documentation
|
||||
</success_criteria>
|
||||
|
||||
<research>
|
||||
**Files to Examine:**
|
||||
- All template files in `templates/` and `templates/partials/`
|
||||
- Search for HTMX attributes: `hx-get`, `hx-post`, `hx-put`, `hx-delete`, `hx-patch`
|
||||
- Review existing CSS for any indicator patterns already in use
|
||||
- Check if iconify-icon is already used for other icons (reuse pattern)
|
||||
|
||||
**Questions to Answer:**
|
||||
1. What HTMX interactions exist in the codebase?
|
||||
2. Which interactions would benefit most from loading indicators?
|
||||
3. Are there any existing indicator patterns to build upon?
|
||||
4. What icon library is already in use (iconify detected)?
|
||||
5. What are the current transition/animation timings used in the project?
|
||||
</research>
|
||||
|
||||
<references>
|
||||
**HTMX Documentation:**
|
||||
- Request indicators: https://htmx.org/attributes/hx-indicator/
|
||||
- CSS transitions: https://htmx.org/examples/animations/
|
||||
- Request lifecycle events: https://htmx.org/events/
|
||||
|
||||
**Best Practices:**
|
||||
- Use subtle, non-intrusive indicators
|
||||
- Match existing design patterns
|
||||
- Prioritize high-frequency user actions
|
||||
- Test with throttled network to verify visibility
|
||||
- Always respect accessibility preferences
|
||||
|
||||
**Pattern Reference:**
|
||||
```html
|
||||
<!-- Default pattern (indicator inside triggering element) -->
|
||||
<button hx-get="/endpoint">
|
||||
Action
|
||||
<span class="htmx-indicator">Loading...</span>
|
||||
</button>
|
||||
|
||||
<!-- Custom indicator (target different element) -->
|
||||
<button hx-get="/endpoint" hx-indicator="#my-indicator">
|
||||
Action
|
||||
</button>
|
||||
<div id="my-indicator" class="htmx-indicator">Loading...</div>
|
||||
```
|
||||
</references>
|
||||
|
||||
<additional_notes>
|
||||
**Implementation Philosophy:**
|
||||
- Start with the most frequently used interactions
|
||||
- Keep indicators simple and consistent
|
||||
- Prefer iconify-icon spinners (already in use in project)
|
||||
- Don't over-engineer - simple is better
|
||||
- Test with real network conditions (throttling)
|
||||
- Document patterns for future developers
|
||||
|
||||
**Quick Win Opportunities:**
|
||||
1. Language selector buttons - high visibility, user-initiated
|
||||
2. Toggle controls - frequent user interactions
|
||||
3. Any form submissions or data mutations
|
||||
|
||||
**Future Enhancements:**
|
||||
- Consider global loading bar for major page transitions
|
||||
- Add progress indicators for multi-step operations
|
||||
- Implement skeleton loaders for content-heavy responses (separate from this task)
|
||||
</additional_notes>
|
||||
@@ -0,0 +1,701 @@
|
||||
# Implement System-Aware Theme Switcher with Animated Expanding Button
|
||||
|
||||
<objective>
|
||||
Implement a comprehensive light/dark/auto theme system that respects the user's system preferences and allows manual override. The feature will include an animated expanding button in the top-right corner that reveals three theme options (Light, Dark, Auto) when interacted with.
|
||||
|
||||
**Key Goals:**
|
||||
1. Support three theme modes: Light (force light), Dark (force dark), Auto (follow system)
|
||||
2. Detect and respect system theme preference via `prefers-color-scheme` media query
|
||||
3. Create an elegant animated button that expands to reveal three options
|
||||
4. Persist user preference in localStorage across sessions
|
||||
5. Apply theme instantly without page reload using CSS classes
|
||||
|
||||
**Why This Matters:**
|
||||
- Modern UX standard: Users expect dark mode support (65% of users prefer it at night)
|
||||
- Accessibility: Dark mode reduces eye strain in low-light environments
|
||||
- System integration: Respecting OS preferences shows attention to detail
|
||||
- User control: Some users want to override system settings (e.g., dark mode during day)
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
**Current State:**
|
||||
- The CV application currently has a "theme toggle" that switches between default and "clean" views
|
||||
- Theme is applied via `.theme-clean` class on `.cv-container`
|
||||
- Existing toggle uses localStorage for persistence: `localStorage['cv-theme']`
|
||||
- No current dark/light mode support - only layout theme variations
|
||||
|
||||
**Desired Implementation:**
|
||||
1. **Three Theme Options:**
|
||||
- **Light**: Force light color scheme regardless of system preference
|
||||
- **Dark**: Force dark color scheme regardless of system preference
|
||||
- **Auto**: Follow system preference (uses `prefers-color-scheme` media query)
|
||||
|
||||
2. **Animated Button Behavior:**
|
||||
- Default state: Single circular button showing current theme icon
|
||||
- On hover (desktop): Button expands horizontally left-to-right revealing 3 options
|
||||
- On click/tap (mobile): Button expands to show 3 options
|
||||
- Each option shows an icon (sun, moon, auto) and optional label
|
||||
- Smooth animation: width expansion + fade-in of additional buttons
|
||||
- Click any option: Collapse button + apply theme + save preference
|
||||
|
||||
3. **Positioning:**
|
||||
- Fixed position at top-right of viewport
|
||||
- Always visible (doesn't scroll with page)
|
||||
- Positioned above other content (high z-index)
|
||||
- Works on mobile and desktop viewports
|
||||
|
||||
4. **Persistence:**
|
||||
- Save user preference to localStorage: `localStorage['theme-mode']`
|
||||
- Values: 'light', 'dark', 'auto'
|
||||
- On page load: Read localStorage and apply saved preference
|
||||
- If no saved preference: Default to 'auto' (follow system)
|
||||
|
||||
**Reference Files:**
|
||||
@templates/partials/navigation/view-controls.html - Existing toggle pattern with localStorage
|
||||
@static/css/main.css - Existing theme classes and styles
|
||||
@static/hyperscript/functions._hs - Existing hyperscript functions
|
||||
|
||||
**Tech Stack:**
|
||||
- CSS custom properties (CSS variables) for theme colors
|
||||
- CSS `prefers-color-scheme` media query for system detection
|
||||
- Hyperscript for button animation and theme switching logic
|
||||
- localStorage for persistence
|
||||
- Iconify icons for theme indicators (already in use)
|
||||
</context>
|
||||
|
||||
<requirements>
|
||||
|
||||
## 1. Theme System Architecture
|
||||
|
||||
**CSS Variables Structure:**
|
||||
Create a comprehensive set of CSS custom properties for theming:
|
||||
|
||||
```css
|
||||
:root {
|
||||
/* Light theme (default) */
|
||||
--bg-primary: #ffffff;
|
||||
--bg-secondary: #f5f5f5;
|
||||
--text-primary: #333333;
|
||||
--text-secondary: #666666;
|
||||
--border-color: #e0e0e0;
|
||||
--shadow: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Dark theme - applied via [data-theme="dark"] */
|
||||
[data-theme="dark"] {
|
||||
--bg-primary: #1a1a1a;
|
||||
--bg-secondary: #2a2a2a;
|
||||
--text-primary: #e0e0e0;
|
||||
--text-secondary: #b0b0b0;
|
||||
--border-color: #404040;
|
||||
--shadow: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Auto theme - uses media query */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
[data-theme="auto"] {
|
||||
/* Same as dark theme variables */
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Why CSS Variables:**
|
||||
- Single source of truth for colors
|
||||
- Easy to maintain and extend
|
||||
- Automatically cascade to all components
|
||||
- Better performance than class-based theme switching for large DOMs
|
||||
|
||||
**Theme Application:**
|
||||
- Apply theme via `data-theme` attribute on `<html>` or `<body>`
|
||||
- Values: `data-theme="light"`, `data-theme="dark"`, `data-theme="auto"`
|
||||
- JavaScript/Hyperscript sets this attribute based on user selection
|
||||
|
||||
## 2. Animated Button Component
|
||||
|
||||
**Button States:**
|
||||
|
||||
1. **Collapsed (default):**
|
||||
- Single circular button (~48px diameter)
|
||||
- Shows icon representing current theme (sun/moon/auto)
|
||||
- Subtle shadow and hover effect
|
||||
|
||||
2. **Expanded (on hover/click):**
|
||||
- Expands horizontally to ~160px width (or 3 × 48px = 144px)
|
||||
- Reveals 3 circular buttons side-by-side
|
||||
- Each button: icon + optional tooltip label
|
||||
- Smooth width transition (300ms ease-out)
|
||||
- Icons fade in with staggered delay for polish
|
||||
|
||||
**Animation Specifications:**
|
||||
- Expansion: `width: 48px → 160px` over 300ms with ease-out easing
|
||||
- Icon fade: Opacity 0 → 1 over 200ms with 50ms stagger
|
||||
- Collapse: Reverse animation when mouse leaves (desktop) or after selection
|
||||
- Use `transform` and `opacity` for GPU acceleration (avoid width if possible, use scale + clip)
|
||||
|
||||
**HTML Structure Example:**
|
||||
```html
|
||||
<div id="theme-switcher" class="theme-switcher"
|
||||
_="on mouseenter add .expanded to me
|
||||
on mouseleave remove .expanded from me">
|
||||
|
||||
<!-- Current theme indicator (always visible) -->
|
||||
<button class="theme-btn active" data-theme-mode="auto">
|
||||
<iconify-icon icon="mdi:theme-light-dark" width="20"></iconify-icon>
|
||||
</button>
|
||||
|
||||
<!-- Additional options (visible when expanded) -->
|
||||
<button class="theme-btn" data-theme-mode="light"
|
||||
_="on click call setTheme('light')">
|
||||
<iconify-icon icon="mdi:white-balance-sunny" width="20"></iconify-icon>
|
||||
<span class="tooltip">Light</span>
|
||||
</button>
|
||||
|
||||
<button class="theme-btn" data-theme-mode="dark"
|
||||
_="on click call setTheme('dark')">
|
||||
<iconify-icon icon="mdi:moon-waning-crescent" width="20"></iconify-icon>
|
||||
<span class="tooltip">Dark</span>
|
||||
</button>
|
||||
|
||||
<button class="theme-btn" data-theme-mode="auto"
|
||||
_="on click call setTheme('auto')">
|
||||
<iconify-icon icon="mdi:theme-light-dark" width="20"></iconify-icon>
|
||||
<span class="tooltip">Auto</span>
|
||||
</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
**Responsive Behavior:**
|
||||
- Desktop (>768px): Expand on hover, collapse on mouse leave
|
||||
- Mobile/Tablet (≤768px): Expand on tap, collapse on background tap or selection
|
||||
- Use media query + hyperscript to detect and apply appropriate behavior
|
||||
|
||||
## 3. Theme Switching Logic
|
||||
|
||||
**Hyperscript Function:**
|
||||
Create a global `setTheme(mode)` function in `static/hyperscript/functions._hs`:
|
||||
|
||||
```hyperscript
|
||||
def setTheme(mode)
|
||||
-- Save preference to localStorage
|
||||
set localStorage['theme-mode'] to mode
|
||||
|
||||
-- Apply theme to document
|
||||
if mode is 'light'
|
||||
set document.documentElement's @data-theme to 'light'
|
||||
else if mode is 'dark'
|
||||
set document.documentElement's @data-theme to 'dark'
|
||||
else if mode is 'auto'
|
||||
set document.documentElement's @data-theme to 'auto'
|
||||
end
|
||||
|
||||
-- Update button active states
|
||||
set buttons to .theme-btn in #theme-switcher
|
||||
for btn in buttons
|
||||
if btn's @data-theme-mode is mode
|
||||
add .active to btn
|
||||
else
|
||||
remove .active from btn
|
||||
end
|
||||
end
|
||||
|
||||
-- Collapse button on mobile
|
||||
if window.innerWidth <= 768
|
||||
remove .expanded from #theme-switcher
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
**Page Load Theme Detection:**
|
||||
Create an initialization script that runs immediately on page load:
|
||||
|
||||
```hyperscript
|
||||
def initTheme()
|
||||
-- Get saved preference or default to 'auto'
|
||||
set savedTheme to localStorage['theme-mode'] or 'auto'
|
||||
call setTheme(savedTheme)
|
||||
end
|
||||
|
||||
-- Run on page load
|
||||
on load call initTheme()
|
||||
```
|
||||
|
||||
**System Preference Detection:**
|
||||
Listen for system theme changes when in 'auto' mode:
|
||||
|
||||
```javascript
|
||||
// Optional: Listen for system theme changes
|
||||
const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
darkModeQuery.addEventListener('change', (e) => {
|
||||
const currentMode = localStorage.getItem('theme-mode');
|
||||
if (currentMode === 'auto' || !currentMode) {
|
||||
// Theme will automatically update via CSS media query
|
||||
// No action needed, but could trigger a visual indicator
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 4. Positioning and Layout
|
||||
|
||||
**Fixed Positioning:**
|
||||
```css
|
||||
.theme-switcher {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
z-index: 1000; /* Above all content */
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
background: var(--bg-primary);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 24px;
|
||||
padding: 4px;
|
||||
box-shadow: 0 2px 8px var(--shadow);
|
||||
width: 56px; /* Single button + padding */
|
||||
transition: width 300ms ease-out;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.theme-switcher.expanded {
|
||||
width: 176px; /* 3 buttons + gaps + padding */
|
||||
}
|
||||
|
||||
.theme-btn {
|
||||
min-width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
transition: background 200ms ease;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.theme-btn:not(.active) {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.theme-switcher:not(.expanded) .theme-btn:not(.active) {
|
||||
display: none; /* Hide non-active buttons when collapsed */
|
||||
}
|
||||
|
||||
.theme-btn:hover {
|
||||
background: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.theme-btn.active {
|
||||
background: var(--bg-secondary);
|
||||
}
|
||||
```
|
||||
|
||||
**Mobile Considerations:**
|
||||
- Increase touch target size to minimum 44×44px (iOS HIG)
|
||||
- Ensure button doesn't overlap with hamburger menu or other controls
|
||||
- Consider adding backdrop overlay when expanded on mobile
|
||||
- Position may need adjustment on smaller screens (e.g., `top: 16px; right: 16px`)
|
||||
|
||||
## 5. Color Scheme Design
|
||||
|
||||
**Light Theme Colors:**
|
||||
- Background: White to light gray (#ffffff, #f5f5f5)
|
||||
- Text: Dark gray to black (#333333, #1a1a1a)
|
||||
- Accent: Keep existing brand colors
|
||||
- Borders: Light gray (#e0e0e0)
|
||||
|
||||
**Dark Theme Colors:**
|
||||
- Background: Very dark gray to black (#1a1a1a, #0a0a0a)
|
||||
- Text: Light gray to white (#e0e0e0, #ffffff)
|
||||
- Accent: Slightly brighter versions of brand colors
|
||||
- Borders: Medium dark gray (#404040)
|
||||
|
||||
**Design Principles:**
|
||||
- Maintain sufficient contrast (WCAG AA: 4.5:1 for text, AAA: 7:1 preferred)
|
||||
- Don't use pure black (#000000) for dark backgrounds (too harsh)
|
||||
- Don't use pure white text on dark backgrounds (causes halation)
|
||||
- Test with both themes for readability and accessibility
|
||||
|
||||
## 6. Persistence and State Management
|
||||
|
||||
**localStorage Schema:**
|
||||
```javascript
|
||||
// Store theme preference
|
||||
localStorage.setItem('theme-mode', 'light'); // or 'dark', 'auto'
|
||||
|
||||
// Read on page load
|
||||
const savedTheme = localStorage.getItem('theme-mode') || 'auto';
|
||||
```
|
||||
|
||||
**State Synchronization:**
|
||||
- Button active state must always reflect current theme
|
||||
- System theme changes should update UI if in 'auto' mode
|
||||
- Manual theme selection should override system preference
|
||||
- Theme should apply before page render to avoid flash (FOUC)
|
||||
|
||||
**Initial Load Optimization:**
|
||||
To prevent flash of wrong theme, add inline script in `<head>`:
|
||||
|
||||
```html
|
||||
<script>
|
||||
(function() {
|
||||
const theme = localStorage.getItem('theme-mode') || 'auto';
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
})();
|
||||
</script>
|
||||
```
|
||||
|
||||
This runs before page render, applying theme instantly.
|
||||
|
||||
## 7. Integration with Existing Theme System
|
||||
|
||||
**Current System:**
|
||||
- `.theme-clean` class toggles between default and clean layouts
|
||||
- This is a **layout** theme, not a **color** theme
|
||||
|
||||
**New System:**
|
||||
- `data-theme` attribute controls **color** theme (light/dark/auto)
|
||||
- `.theme-clean` class still controls **layout** theme
|
||||
|
||||
**Both Can Coexist:**
|
||||
```html
|
||||
<body class="theme-clean" data-theme="dark">
|
||||
<!-- Clean layout + Dark colors -->
|
||||
</body>
|
||||
```
|
||||
|
||||
**CSS Organization:**
|
||||
- Keep existing `.theme-clean` styles unchanged
|
||||
- Add new `[data-theme="dark"]` styles for colors
|
||||
- Ensure both systems work independently and together
|
||||
|
||||
</requirements>
|
||||
|
||||
<implementation>
|
||||
|
||||
## Step-by-Step Implementation Plan
|
||||
|
||||
### Phase 1: Create CSS Theme Variables
|
||||
|
||||
1. **Add CSS Variables to `static/css/main.css`:**
|
||||
- Define `:root` (light theme) color variables
|
||||
- Define `[data-theme="dark"]` color variables
|
||||
- Define `@media (prefers-color-scheme: dark)` with `[data-theme="auto"]`
|
||||
- Update existing components to use CSS variables instead of hardcoded colors
|
||||
|
||||
2. **Color Mapping Strategy:**
|
||||
- Audit existing colors in `main.css`
|
||||
- Create a mapping from hardcoded colors to CSS variable names
|
||||
- Replace colors incrementally (high-impact areas first: backgrounds, text, borders)
|
||||
|
||||
### Phase 2: Create Theme Switcher Button Component
|
||||
|
||||
1. **Create HTML Template:**
|
||||
- New file: `templates/partials/theme-switcher.html`
|
||||
- Structure: Container with 3 buttons (light, dark, auto)
|
||||
- Include iconify icons for each theme
|
||||
- Add hyperscript for expand/collapse behavior
|
||||
|
||||
2. **Create CSS Styles:**
|
||||
- Add to `static/css/main.css` or new `static/css/theme-switcher.css`
|
||||
- Fixed positioning at top-right
|
||||
- Collapsed and expanded states
|
||||
- Button hover and active states
|
||||
- Smooth transitions and animations
|
||||
- Responsive behavior (desktop vs mobile)
|
||||
|
||||
3. **Include in Main Layout:**
|
||||
- Add `{{template "theme-switcher" .}}` to main layout template
|
||||
- Position below action bar but above content (z-index management)
|
||||
|
||||
### Phase 3: Implement Theme Switching Logic
|
||||
|
||||
1. **Add Hyperscript Functions to `static/hyperscript/functions._hs`:**
|
||||
- `setTheme(mode)` - Apply theme and save to localStorage
|
||||
- `initTheme()` - Load saved theme on page load
|
||||
- Button click handlers for each theme option
|
||||
|
||||
2. **Add Inline Script for FOUC Prevention:**
|
||||
- In `<head>` of main template, add inline script
|
||||
- Reads localStorage and sets `data-theme` before render
|
||||
- Prevents flash of wrong theme
|
||||
|
||||
3. **System Theme Detection (Optional Enhancement):**
|
||||
- Add media query listener for system theme changes
|
||||
- Update UI when system preference changes (if in 'auto' mode)
|
||||
|
||||
### Phase 4: Update Existing Components with Theme Variables
|
||||
|
||||
**Priority Order:**
|
||||
1. Main backgrounds and text (highest visual impact)
|
||||
2. CV paper and content areas
|
||||
3. Navigation and controls
|
||||
4. Borders and shadows
|
||||
5. Accent colors and highlights
|
||||
|
||||
**Example Refactor:**
|
||||
```css
|
||||
/* Before */
|
||||
.cv-container {
|
||||
background: #ffffff;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
/* After */
|
||||
.cv-container {
|
||||
background: var(--bg-primary);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 5: Testing and Refinement
|
||||
|
||||
1. **Visual Testing:**
|
||||
- Test all three theme modes (light, dark, auto)
|
||||
- Verify color contrast meets WCAG AA standards
|
||||
- Check all components render correctly in both themes
|
||||
|
||||
2. **Interaction Testing:**
|
||||
- Button expands smoothly on hover (desktop)
|
||||
- Button expands/collapses on tap (mobile)
|
||||
- Theme applies instantly when selected
|
||||
- Active state updates correctly
|
||||
|
||||
3. **Persistence Testing:**
|
||||
- Save theme preference and reload page
|
||||
- Verify saved theme is applied before render (no FOUC)
|
||||
- Clear localStorage and verify default to 'auto'
|
||||
|
||||
4. **System Integration Testing:**
|
||||
- Change system theme preference (OS settings)
|
||||
- Verify 'auto' mode respects system preference
|
||||
- Verify 'light' and 'dark' modes override system
|
||||
|
||||
**What to Prioritize:**
|
||||
1. Core theme switching functionality
|
||||
2. FOUC prevention (inline script)
|
||||
3. Button animation and UX
|
||||
4. High-impact component theming (backgrounds, text)
|
||||
5. Fine-tuning colors and contrast
|
||||
|
||||
**What to Avoid:**
|
||||
- Don't try to theme every single pixel in first pass - prioritize high-impact areas
|
||||
- Don't use JavaScript for theme application if CSS can handle it (performance)
|
||||
- Don't forget mobile UX - touch targets, tap behavior, responsive design
|
||||
- Don't hardcode colors - always use CSS variables
|
||||
- Don't sacrifice accessibility for aesthetics (contrast ratios are critical)
|
||||
|
||||
**Why These Constraints Matter:**
|
||||
- **CSS Variables:** Maintainable, performant, scalable theming system
|
||||
- **FOUC Prevention:** Critical for professional UX - theme must apply before render
|
||||
- **Mobile-First:** Touch devices are primary interaction method for many users
|
||||
- **Accessibility:** WCAG compliance is non-negotiable for professional applications
|
||||
- **Progressive Enhancement:** Light theme works even if JavaScript fails
|
||||
|
||||
</implementation>
|
||||
|
||||
<output>
|
||||
Create/modify the following files:
|
||||
|
||||
1. **`./templates/partials/theme-switcher.html`** (NEW)
|
||||
- Animated theme switcher button component
|
||||
- Three buttons for light, dark, auto modes
|
||||
- Hyperscript for expand/collapse and theme selection
|
||||
- Iconify icons for each theme option
|
||||
|
||||
2. **`./static/css/theme-variables.css`** (NEW) or add to `./static/css/main.css`
|
||||
- CSS custom properties for light theme (`:root`)
|
||||
- CSS custom properties for dark theme (`[data-theme="dark"]`)
|
||||
- Media query for auto mode (`@media (prefers-color-scheme: dark)`)
|
||||
- Theme switcher button styles
|
||||
|
||||
3. **`./static/hyperscript/functions._hs`**
|
||||
- Add `setTheme(mode)` function
|
||||
- Add `initTheme()` function
|
||||
- Add page load initialization
|
||||
|
||||
4. **`./templates/index.html`** (or main layout template)
|
||||
- Include theme switcher component
|
||||
- Add inline FOUC prevention script in `<head>`
|
||||
|
||||
5. **`./static/css/main.css`**
|
||||
- Refactor existing hardcoded colors to use CSS variables
|
||||
- Update backgrounds, text, borders, shadows
|
||||
- Ensure compatibility with both theme systems (layout + color)
|
||||
|
||||
**Optional (recommended):**
|
||||
6. **`./static/js/theme-system-listener.js`** (NEW)
|
||||
- Listen for system theme changes
|
||||
- Update UI when system preference changes in 'auto' mode
|
||||
- Only needed for dynamic system theme updates
|
||||
|
||||
</output>
|
||||
|
||||
<verification>
|
||||
Before declaring complete, perform these comprehensive tests:
|
||||
|
||||
**1. Visual Verification:**
|
||||
- [ ] Light mode: All text readable, good contrast, professional appearance
|
||||
- [ ] Dark mode: All text readable, good contrast, not too harsh
|
||||
- [ ] Auto mode: Follows system preference correctly
|
||||
- [ ] Button expands smoothly showing 3 options
|
||||
- [ ] Button collapses smoothly after selection
|
||||
- [ ] Active button is visually distinct
|
||||
|
||||
**2. Interaction Testing:**
|
||||
- [ ] Desktop: Button expands on hover, collapses on mouse leave
|
||||
- [ ] Mobile: Button expands on tap, collapses on selection or backdrop tap
|
||||
- [ ] Click light button: Theme switches to light instantly
|
||||
- [ ] Click dark button: Theme switches to dark instantly
|
||||
- [ ] Click auto button: Theme follows system preference
|
||||
- [ ] No delay or lag in theme application
|
||||
|
||||
**3. Persistence Testing:**
|
||||
- [ ] Select light theme, reload page → Still light
|
||||
- [ ] Select dark theme, reload page → Still dark
|
||||
- [ ] Select auto theme, reload page → Still auto (follows system)
|
||||
- [ ] Clear localStorage → Defaults to auto mode
|
||||
- [ ] No flash of unstyled content (FOUC) on page load
|
||||
|
||||
**4. System Integration:**
|
||||
- [ ] Set system to light mode, set app to auto → Light theme applied
|
||||
- [ ] Change system to dark mode with app in auto → Dark theme applied
|
||||
- [ ] Set app to light mode, change system to dark → Stays light (override works)
|
||||
- [ ] Media query correctly detects system preference
|
||||
|
||||
**5. Accessibility Testing:**
|
||||
- [ ] Light mode: WCAG AA contrast ratio for all text (4.5:1 minimum)
|
||||
- [ ] Dark mode: WCAG AA contrast ratio for all text
|
||||
- [ ] Button tooltips/labels are readable
|
||||
- [ ] Keyboard navigation works (tab through theme options)
|
||||
- [ ] Focus states are visible
|
||||
- [ ] Screen reader announces theme changes
|
||||
|
||||
**6. Component Coverage:**
|
||||
- [ ] CV container background themed correctly
|
||||
- [ ] Text colors themed correctly (headings, body, secondary)
|
||||
- [ ] Navigation elements themed correctly
|
||||
- [ ] Borders and dividers visible in both themes
|
||||
- [ ] Shadows appropriate for both themes
|
||||
- [ ] Icons and images work in both themes
|
||||
- [ ] Toggle controls remain functional and readable
|
||||
|
||||
**7. Layout Compatibility:**
|
||||
- [ ] Theme works with default layout (not `.theme-clean`)
|
||||
- [ ] Theme works with `.theme-clean` layout
|
||||
- [ ] Both theme systems can be used simultaneously
|
||||
- [ ] No conflicts between layout theme and color theme
|
||||
|
||||
**8. Animation Performance:**
|
||||
- [ ] Button expansion is smooth (60fps, no jank)
|
||||
- [ ] Theme switching is instant (no visible delay)
|
||||
- [ ] GPU-accelerated properties used (opacity, transform)
|
||||
- [ ] No layout thrashing during animations
|
||||
|
||||
**9. Mobile Specific:**
|
||||
- [ ] Button positioned correctly on mobile (no overlap with other controls)
|
||||
- [ ] Touch targets are adequate size (44×44px minimum)
|
||||
- [ ] Tap behavior works correctly (expand/collapse)
|
||||
- [ ] Responsive design adapts to small screens
|
||||
|
||||
**10. Edge Cases:**
|
||||
- [ ] Very fast clicking doesn't break state
|
||||
- [ ] System theme change during 'auto' mode updates correctly
|
||||
- [ ] Works in private/incognito mode (localStorage available)
|
||||
- [ ] Graceful degradation if JavaScript disabled (defaults to light)
|
||||
|
||||
**Success Indicators:**
|
||||
✅ Three theme modes work correctly (light, dark, auto)
|
||||
✅ System preference detected and respected in auto mode
|
||||
✅ Theme persists across page reloads (localStorage)
|
||||
✅ No FOUC - theme applies before page render
|
||||
✅ Animated button expands/collapses smoothly
|
||||
✅ Responsive behavior (hover on desktop, tap on mobile)
|
||||
✅ All text meets WCAG AA contrast standards
|
||||
✅ Theme switching is instant and smooth
|
||||
✅ Works alongside existing `.theme-clean` layout system
|
||||
✅ Professional, polished UX
|
||||
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
1. Three distinct theme modes implemented: Light, Dark, Auto (system)
|
||||
2. System preference correctly detected via `prefers-color-scheme` media query
|
||||
3. User preference persists in localStorage across sessions
|
||||
4. Animated expanding button reveals theme options smoothly (300ms transition)
|
||||
5. Responsive behavior: hover on desktop (>768px), tap on mobile (≤768px)
|
||||
6. Fixed positioning at top-right, always visible, doesn't interfere with content
|
||||
7. No flash of unstyled content (FOUC) - theme applies before render
|
||||
8. All text meets WCAG AA contrast ratio (4.5:1 for normal text)
|
||||
9. Theme applies instantly on selection (<50ms perceived delay)
|
||||
10. Compatible with existing `.theme-clean` layout system
|
||||
11. Accessible keyboard navigation and screen reader support
|
||||
12. Smooth animations using GPU-accelerated properties
|
||||
13. Code follows existing project patterns and conventions
|
||||
14. Implementation is maintainable and well-documented
|
||||
</success_criteria>
|
||||
|
||||
<references>
|
||||
**CSS Color Schemes:**
|
||||
- MDN prefers-color-scheme: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme
|
||||
- Material Design dark theme: https://material.io/design/color/dark-theme.html
|
||||
- CSS custom properties: https://developer.mozilla.org/en-US/docs/Web/CSS/--*
|
||||
|
||||
**Best Practices:**
|
||||
- Avoid pure black in dark mode (use #1a1a1a or similar)
|
||||
- Maintain consistent contrast ratios
|
||||
- Use elevation (shadows) to create depth in dark mode
|
||||
- Test with real system theme preferences
|
||||
- Prevent FOUC with inline script in head
|
||||
|
||||
**Icon Suggestions (iconify):**
|
||||
- Light mode: `mdi:white-balance-sunny` or `mdi:brightness-7`
|
||||
- Dark mode: `mdi:moon-waning-crescent` or `mdi:weather-night`
|
||||
- Auto mode: `mdi:theme-light-dark` or `mdi:brightness-auto`
|
||||
|
||||
**Animation Patterns:**
|
||||
- Expand: ease-out (starts fast, ends slow)
|
||||
- Collapse: ease-in (starts slow, ends fast)
|
||||
- Theme switch: instant (no transition on color change)
|
||||
- Icons: staggered fade-in for polish
|
||||
|
||||
**Accessibility:**
|
||||
- WCAG AA: 4.5:1 for normal text, 3:1 for large text
|
||||
- WCAG AAA: 7:1 for normal text, 4.5:1 for large text
|
||||
- Test with actual screen readers (VoiceOver, NVDA)
|
||||
- Ensure focus indicators are visible in both themes
|
||||
</references>
|
||||
|
||||
<research>
|
||||
**Files to Examine:**
|
||||
@static/css/main.css - Current color usage and theme system
|
||||
@templates/partials/navigation/view-controls.html - Existing toggle pattern
|
||||
@static/hyperscript/functions._hs - Existing hyperscript functions
|
||||
@templates/index.html - Main layout structure
|
||||
|
||||
**Questions to Answer:**
|
||||
1. What colors are currently hardcoded and need to become variables?
|
||||
2. How is the existing `.theme-clean` system implemented?
|
||||
3. Where should the theme switcher button be positioned to not conflict with existing UI?
|
||||
4. What iconify icons are already in use (maintain consistency)?
|
||||
5. What localStorage keys are already in use (avoid conflicts)?
|
||||
</research>
|
||||
|
||||
<additional_notes>
|
||||
**Implementation Philosophy:**
|
||||
- Progressive enhancement: Works without JavaScript (defaults to light)
|
||||
- Mobile-first: Touch interactions are primary, hover is enhancement
|
||||
- Performance-first: CSS handles theme, JavaScript only manages state
|
||||
- Accessibility-first: WCAG compliance is non-negotiable
|
||||
- Maintainability: CSS variables make future updates trivial
|
||||
|
||||
**Design Considerations:**
|
||||
- Button should feel premium and polished (subtle shadows, smooth animations)
|
||||
- Don't over-animate - smooth and subtle is better than flashy
|
||||
- Dark mode should be comfortable for extended reading, not just "looks cool"
|
||||
- Auto mode should be the intelligent default (respects user's OS preference)
|
||||
|
||||
**Future Enhancements:**
|
||||
- Add transition animation when theme changes (optional fade)
|
||||
- Support custom theme colors (user-selectable accent colors)
|
||||
- Add sunrise/sunset auto-scheduling (auto-switch based on time)
|
||||
- Sync theme preference across devices (server-side storage)
|
||||
- Add "high contrast" mode for accessibility
|
||||
</additional_notes>
|
||||
Reference in New Issue
Block a user