diff --git a/WOOD_PANELING_PLAN.md b/WOOD_PANELING_PLAN.md index 7bd6013..daddc7d 100644 --- a/WOOD_PANELING_PLAN.md +++ b/WOOD_PANELING_PLAN.md @@ -4,6 +4,15 @@ The current "wood themes" were implemented as color themes with CSS gradients, but they should be wood paneling textures applied to the dashboard bookshelf background only. Additionally, the app uses constrained width containers (`max-w-7xl`) which limit screen real estate on large monitors, unlike modern bookshelf apps like Audiobookshelf. +## Implementation Principles + +### Critical Requirements +- ✅ **All JavaScript must be TypeScript** - No inline scripts except for simple initialization +- ✅ **Use TailwindCSS only** - No custom CSS, use CSS variables already defined in `input.css` +- ✅ **Post-edit verification mandatory** - Run build after each file edit +- ✅ **Sequential git commits** - No `&&` chaining, explicit verification between commands +- ✅ **Document user-facing changes** - Update `docs/user/` for new features + ## Root Cause Analysis ### Current Implementation Issues @@ -36,24 +45,38 @@ The current "wood themes" were implemented as color themes with CSS gradients, b **Layout principle:** Full-width layout for modern app feel, better space utilization. +**CSS Variable Principle:** Use CSS variables already defined in `web/static/input.css` (`--bg-primary`, `--bg-secondary`, etc.) instead of inline styles. + +## Git Commit Strategy + +**CRITICAL:** All git commands must be run sequentially (no `&&` chaining): +1. `git add ` - Wait for completion +2. `git commit -m ""` - Wait for completion +3. Verify commit succeeded before proceeding + +**Post-Edit Verification (MANDATORY):** +- After each file edit: Run `go build ./...` for Go files, `npm run build` for TypeScript +- Review `git diff` to verify only intended changes +- Never proceed to next file until current edit compiles successfully + ## Implementation Plan -### Phase 0: Download Wood Textures +### Phase 0: Download Wood Textures (Manual) **Source URLs:** 1. **Light Wood:** https://opengameart.org/content/light-wood-1024x1024 - - Author: qubodup - - License: CC0 (no attribution required) - - File: qubodup-light_wood.png (1.9 MB) - - Resolution: 1024x1024 + - Author: qubodup + - License: CC0 (no attribution required) + - File: qubodup-light_wood.png (1.9 MB) + - Resolution: 1024x1024 2. **Dark & Mahogany Wood:** https://opengameart.org/content/5-wood-textures - - Author: Luke.RUSTLTD - - License: CC0 (no attribution required) - - File: wood_0.zip (6.5 MB) - contains 5 textures - - Select 2 best: darkest and medium/reddish - - Resolution: Likely 512x512 or 1024x1024 + - Author: Luke.RUSTLTD + - License: CC0 (no attribution required) + - File: wood_0.zip (6.5 MB) - contains 5 textures + - Select 2 best: darkest and medium/reddish + - Resolution: Likely 512x512 or 1024x1024 **Download Steps:** @@ -97,65 +120,43 @@ unzip wood_0.zip --- -### Phase 1: Remove Wood Themes from Theme System +### Phase 1: Remove Wood Themes from Core Theme System -**Goal:** Remove wood themes as color themes from the dropdown +**Goal:** Remove wood themes from the core theme system to prepare for separate wood paneling feature. #### Files to Modify: -**1. `templates/header.templ`** -- Remove wood theme buttons (lines 86-99) -- This section will be replaced with wood paneling section in Phase 3 - -**2. `tailwind.config.ts`** -- Remove `theme-wood-light`, `theme-wood-dark`, `theme-wood-mahogany` from safelist (lines 21-23) - -**Before:** -```typescript -safelist: [ - 'theme-wood-light', - 'theme-wood-dark', - 'theme-wood-mahogany', - // ... other themes -] -``` - -**After:** -```typescript -safelist: [ - // Remove wood theme entries - // Keep only color themes -] -``` - -**3. `web/src/header.ts`** -- Remove wood theme handling from `changeThemeTo()` function (lines 31-51) +**1. `web/src/theme.ts`** +- Remove `wood-light`, `wood-dark`, `wood-mahogany` from `ThemeType` union (lines 15-17) +- Remove wood theme gradient logic from `applyTheme()` function (lines 26-46) - Keep only regular theme handling -**Before:** +**Before (theme.ts):** ```typescript -const changeThemeTo = (theme: string): void => { +type ThemeType = + | 'tokyo-night' + | 'dracula' + // ... other themes + | 'wood-light' + | 'wood-dark' + | 'wood-mahogany'; +``` + +**After (theme.ts):** +```typescript +type ThemeType = + | 'tokyo-night' + | 'dracula' + // ... other themes (remove wood themes); +``` + +**Before (applyTheme function):** +```typescript +const applyTheme = (theme: string): void => { + // Handle wood themes with gradients if (theme.startsWith('wood-')) { - // Apply wood background theme document.body.className = `theme-${theme}`; - - // Set wood background style - let woodGradient = ''; - switch (theme) { - case 'wood-light': - woodGradient = 'linear-gradient(135deg, #deb887 0%, #d2a679 50%, #c9975b 100%)'; - break; - case 'wood-dark': - woodGradient = 'linear-gradient(135deg, #8b7355 0%, #6b5344 50%, #5a4636 100%)'; - break; - case 'wood-mahogany': - woodGradient = 'linear-gradient(135deg, #a0522d 0%, #8b4513 50%, #7a3c10 100%)'; - break; - } - - document.body.style.background = woodGradient; - document.body.style.backgroundSize = 'cover'; - document.body.style.backgroundAttachment = 'fixed'; + // ... wood gradient logic } else { // Apply regular theme document.body.className = `theme-${theme}`; @@ -163,48 +164,88 @@ const changeThemeTo = (theme: string): void => { document.body.style.backgroundSize = ''; document.body.style.backgroundAttachment = ''; } - // ... rest of function + localStorage.setItem(THEME_STORAGE_KEY, theme); }; ``` -**After:** +**After (applyTheme function):** ```typescript -const changeThemeTo = (theme: string): void => { +const applyTheme = (theme: string): void => { // Apply regular theme only document.body.className = `theme-${theme}`; document.body.style.background = ''; document.body.style.backgroundSize = ''; document.body.style.backgroundAttachment = ''; - - // Save to localStorage - localStorage.setItem('theme', theme); - - // Save to server if logged in - const token = localStorage.getItem('token'); - if (token) { - fetch('/api/auth/theme', { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${token}` - }, - body: JSON.stringify({ theme }) - }).catch(err => console.log('Theme save failed', err)); - } - - // Close dropdown - const dropdown = document.getElementById('theme-dropdown'); - if (dropdown) { - dropdown.classList.add('hidden'); - } + localStorage.setItem(THEME_STORAGE_KEY, theme); }; ``` +**2. `tailwind.config.ts`** +- Remove `theme-wood-light`, `theme-wood-dark`, `theme-wood-mahogany` from safelist (lines 21-23) + +**Before:** +```typescript +safelist: [ + 'theme-tokyo-night', + // ... other themes + 'theme-wood-light', + 'theme-wood-dark', + 'theme-wood-mahogany', +] +``` + +**After:** +```typescript +safelist: [ + 'theme-tokyo-night', + // ... other themes (remove wood theme entries) +] +``` + +**3. `web/static/input.css`** +- Remove `.theme-wood-light`, `.theme-wood-dark`, `.theme-wood-mahogany` blocks (lines 115-140) + +#### Verification Steps: +```bash +# Build TypeScript +npm run build + +# Verify: Build succeeds with no TypeScript errors +# Verify: No references to wood themes remain in theme.ts +``` + +#### Git Commit: +```bash +git add web/src/theme.ts +git commit -m "refactor(theme): remove wood themes from core theme system + +- Remove wood-light, wood-dark, wood-mahogany from ThemeType +- Remove wood theme gradient logic from applyTheme() +- Wood themes will be reimplemented as separate paneling feature +- Paneling will target dashboard bookshelf background only" +``` + +```bash +git add tailwind.config.ts +git commit -m "refactor(tailwind): remove wood themes from safelist + +- Remove theme-wood-light, theme-wood-dark, theme-wood-mahogany +- Wood themes no longer exist as color themes" +``` + +```bash +git add web/static/input.css +git commit -m "refactor(css): remove wood theme CSS variables + +- Remove .theme-wood-light, .theme-wood-dark, .theme-wood-mahogany +- Wood paneling will use separate background utilities" +``` + --- -### Phase 2: Create Wood Paneling System +### Phase 2: Create Wood Paneling TypeScript Module -**Goal:** Create separate wood paneling preference system (localStorage only) +**Goal:** Create separate wood paneling preference system using localStorage and Tailwind classes. #### New File: `web/src/woodPaneling.ts` @@ -265,11 +306,13 @@ const updateWoodPanelingIndicators = (): void => { document.querySelectorAll('.wood-paneling-btn').forEach(btn => { const wood = btn.getAttribute('data-wood'); if (wood === currentWood) { - // Active state - darker background - btn.style.backgroundColor = 'var(--bg-primary)'; + // Active state - use CSS class instead of inline style + btn.classList.add('bg-wood-active'); + btn.classList.remove('bg-wood-inactive'); } else { // Inactive state - btn.style.backgroundColor = 'var(--bg-secondary)'; + btn.classList.remove('bg-wood-active'); + btn.classList.add('bg-wood-inactive'); } }); }; @@ -293,65 +336,36 @@ if (typeof document !== 'undefined') { } ``` -**Build:** Add to build system (will be compiled to `web/static/woodPaneling.js`) +**Note:** This uses Tailwind classes (`bg-wood-light`, etc.) instead of inline styles, and CSS variable classes (`bg-wood-active`, `bg-wood-inactive`) for indicators. ---- +#### Verification Steps: +```bash +# Build TypeScript +npm run build -### Phase 3: Update Header with Wood Paneling Section - -**Goal:** Replace wood theme buttons with wood paneling section - -#### File: `templates/header.templ` - -**Replace wood theme section (lines 86-99) with:** - -```templ -
-

Bookshelf Background

- - - - -
+# Verify: woodPaneling.js compiled successfully to web/static/ +# Verify: No TypeScript errors ``` -**Add script includes at bottom of header (before closing script tag):** +#### Git Commit: +```bash +git add web/src/woodPaneling.ts +git commit -m "feat(wood-paneling): create wood paneling management system -```templ - +- Add woodPaneling.ts with localStorage-based paneling preferences +- Support none, wood-light, wood-dark, wood-mahogany options +- Apply paneling to #collections-container only (not full body) +- Use Tailwind utility classes for backgrounds +- Use CSS variable classes for active indicators +- Export functions for HTML onclick handlers +- Auto-initialize on DOM ready" ``` --- -### Phase 4: Add Active Indicators for Themes +### Phase 3: Create Active Indicators Module -**Goal:** Show which theme and wood paneling option is active +**Goal:** Create active indicators for theme dropdown to show which theme/wood option is selected. #### New File: `web/src/themeDropdown.ts` @@ -369,11 +383,13 @@ const updateThemeIndicators = (): void => { if (match) { const theme = match[1]; if (theme === currentTheme) { - // Active state - darker background - btn.style.backgroundColor = 'var(--bg-primary)'; + // Active state - use CSS class instead of inline style + btn.classList.add('bg-theme-active'); + btn.classList.remove('bg-theme-inactive'); } else { // Inactive state - btn.style.backgroundColor = 'var(--bg-secondary)'; + btn.classList.remove('bg-theme-active'); + btn.classList.add('bg-theme-inactive'); } } }); @@ -411,17 +427,34 @@ if (typeof document !== 'undefined') { } ``` -**Add script include to `templates/header.templ`:** +**Note:** Uses CSS classes (`bg-theme-active`, `bg-theme-inactive`) instead of inline styles for better separation of concerns. -```templ - +#### Verification Steps: +```bash +# Build TypeScript +npm run build + +# Verify: themeDropdown.js compiled successfully to web/static/ +# Verify: No TypeScript errors +``` + +#### Git Commit: +```bash +git add web/src/themeDropdown.ts +git commit -m "feat(theme): add active indicators for theme dropdown + +- Create themeDropdown.ts to manage active state highlighting +- Show which theme/wood option is currently selected +- Use CSS classes instead of inline styles for indicators +- Wrap existing functions to update indicators on toggle +- Auto-initialize indicators on DOM ready" ``` --- -### Phase 5: Update Tailwind Config for Wood Backgrounds +### Phase 4: Update Tailwind Config for Wood Backgrounds -**Goal:** Add Tailwind utility classes for wood textures +**Goal:** Add Tailwind utility classes for wood texture backgrounds. #### File: `tailwind.config.ts` @@ -443,23 +476,87 @@ export default { }; ``` -**Regenerate CSS:** +#### Verification Steps: ```bash +# Regenerate CSS npm run build:css -# or whatever the build command is + +# Verify: CSS regenerated with wood background utilities +# Verify: No errors in build output + +# Full build +npm run build + +# Verify: Full build succeeds +``` + +#### Git Commit: +```bash +git add tailwind.config.ts +git commit -m "feat(tailwind): add wood texture background utilities + +- Add bg-wood-light, bg-wood-dark, bg-wood-mahogany utilities +- Reference texture files in web/static/textures/ +- Extend theme.backgroundImage for seamless texture support" ``` --- -### Phase 6: Apply Full-Width Layout Globally +### Phase 5: Add CSS Classes for Active Indicators -**Goal:** Remove `max-w-7xl` containers from header and all pages +**Goal:** Add CSS classes for active/inactive states using CSS variables already defined in `input.css`. -#### Files to Modify: +#### File: `web/static/input.css` -**1. `templates/header.templ`** +**Add to `@layer components` (after line 225):** -**Line 5 - Remove `max-w-7xl`:** +```css +/* Active/inactive states for theme and wood paneling buttons */ +.bg-theme-active, +.bg-wood-active { + background-color: var(--bg-primary) !important; +} + +.bg-theme-inactive, +.bg-wood-inactive { + background-color: var(--bg-secondary) !important; +} +``` + +**Note:** Uses `!important` to override inline styles in template. CSS variables (`--bg-primary`, `--bg-secondary`) are already defined in the `:root` and theme sections of `input.css`. + +#### Verification Steps: +```bash +# Regenerate CSS +npm run build:css + +# Verify: CSS regenerated successfully +# Verify: No errors + +# Full build +npm run build +``` + +#### Git Commit: +```bash +git add web/static/input.css +git commit -m "feat(styles): add active indicator classes for dropdown buttons + +- Add bg-theme-active/inactive for theme buttons +- Add bg-wood-active/inactive for wood paneling buttons +- Use CSS variables already defined in input.css +- Use !important to override inline styles" +``` + +--- + +### Phase 6: Update Header Template + +**Goal:** Remove wood theme buttons, add wood paneling section, remove max-width constraint, and add script includes. + +#### File: `templates/header.templ` + +**Change 1 - Line 5: Remove `max-w-7xl`:** ```templ @@ -469,9 +566,81 @@ npm run build:css
``` -**2. `templates/dashboard.templ`** +**Change 2 - Lines 85-99: Replace wood theme buttons with wood paneling section:** -**Line 27 - Library selector:** +```templ +
+

Bookshelf Background

+ + + + +
+``` + +**Change 3 - Before closing script tag: Add script includes:** + +```templ + + +``` + +#### Verification Steps: +```bash +# Build Go templates +go build ./... + +# Verify: Build succeeds with no template errors +# Verify: Script tags are properly placed +``` + +#### Git Commit: +```bash +git add templates/header.templ +git commit -m "refactor(header): separate wood paneling from color themes + +- Remove max-w-7xl constraint, use full-width layout +- Replace wood theme buttons with wood paneling section +- Add visual previews for wood textures in dropdown +- Section labeled \"Bookshelf Background\" for clarity +- Include woodPaneling.js and themeDropdown.js scripts" +``` + +--- + +### Phase 7: Apply Full-Width Layout to Dashboard + +**Goal:** Apply full-width layout and add inline script for immediate wood paneling application. + +#### File: `templates/dashboard.templ` + +**Change 1 - Line ~27: Library selector - Remove `max-w-7xl`:** ```templ @@ -481,7 +650,7 @@ npm run build:css
``` -**Line 67 - Collections container:** +**Change 2 - Line ~67: Collections container - Remove `max-w-7xl`:** ```templ @@ -491,62 +660,11 @@ npm run build:css
``` -**3. Other pages (remove `max-w-7xl mx-auto` from all content containers):** - -- `templates/collections.templ` -- `templates/progress.templ` -- `templates/queue.templ` -- `templates/devices.templ` -- `templates/analytics.templ` -- `templates/conflicts.templ` -- `templates/unlinked_books.templ` -- `templates/bookshelf.templ` -- `templates/profile.templ` -- `templates/admin.templ` (see note below) -- `templates/admin_library.templ` (see note below) -- `templates/admin_users.templ` (see note below) -- `templates/docs.templ` - -**Pattern:** Replace `class="max-w-7xl mx-auto px-4 ..."` with `class="w-full px-4 ..."` - -**Note:** Keep padding (`px-4`, `py-8`, etc.) for readability. - -**Special note for ALL admin templates (admin.templ, admin_library.templ, admin_users.templ):** -These files were already modified by ADMIN_SIDEBAR_PLAN.md to add sidebar layout wrappers. -The current structure for all three is: -```templ -
- @AdminSidebar(user, currentPath) -
-
- (or
in some cases) -``` - -To apply full-width layout, change the inner div in all three: -```templ - -
-(or
) - - -
-``` - -**Do NOT** modify the `main` element or the flex wrapper in any admin template - these are part of the admin sidebar layout. - ---- - -### Phase 7: Add Inline Script for Dashboard Initialization - -**Goal:** Ensure wood paneling is applied immediately on dashboard load - -#### File: `templates/dashboard.templ` - -**Add inline script after existing scripts (around line 20):** +**Change 3 - Before closing body tag: Add inline script:** ```templ