Implement complete custom CSS management system:
- Separate base CSS (readonly) and custom CSS (editable)
- Save custom CSS to Kirby backend per narrative
- Visual save button with state indicators (dirty/saving/success/error)
- CSRF-protected API endpoint for CSS operations
- Dual-editor StylesheetViewer (base + custom with edit mode toggle)
- Auto-format custom CSS with Prettier on edit mode exit
Backend changes:
- Add web2print Kirby plugin with POST/GET routes
- Add customCss field to narrative blueprint
- Add CSRF token meta tag in header
- Include customCss and modified timestamps in JSON template
- Install code-editor plugin for Kirby panel
Frontend changes:
- Refactor stylesheet store with baseCss/customCss refs
- Make content a computed property (baseCss + customCss)
- Add helper methods: replaceBlock, replaceInCustomCss, setCustomCss
- Update all components to use new store API
- Create SaveButton component with FAB design
- Redesign StylesheetViewer with collapsable sections
- Initialize store from narrative data on app mount
File changes:
- Rename stylesheet.css → stylesheet.print.css
- Update all references to new filename
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Preview now includes all field values, not filtering defaults
- Commented CSS shows what would be applied with current field values
- Applies to both ElementPopup and PagePopup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Unlocking now creates CSS block with current field values
- Locking removes CSS block to restore general styles
- Show commented CSS preview when inheritance is locked
- Preview displays what would be applied if unlocked
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Store unlock state in data-inheritance-unlocked attribute on DOM element
- Each element/page now remembers its own inheritance state
- Re-locking removes element-specific CSS block to restore inheritance
- Elements revert to general styles from TextSettings/PageSettings
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create useDebounce composable to avoid code duplication
- Apply debounce to TextSettings margin/padding inputs
- Harmonize debounce delay to 500ms across all components
- Fix input lag when typing values like "30mm"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add templateName extracted from data-page-type attribute
- When unlocked: edits create/update @page <templateName> block
- When re-locked: remove template block, preview returns to @page
- Fields retain their values when re-locking (for user convenience)
- Display dynamic template name in popup header
- Show template-specific CSS block when unlocked
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Use the same regex parsing logic as PageSettings to extract margin
and background values from the @page CSS block. This ensures
PagePopup displays the correct inherited values when the inheritance
is locked.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add --color-page-highlight CSS variable (#ff8a50)
- Change page edge highlight from blue to orange
- Keep border visible while PagePopup is open
- Highlight all pages using the same template (data-page-type)
- Display dynamic page count in PagePopup header
- Emit close event from PagePopup for proper cleanup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add usePopupPosition composable for smart popup positioning
(bottom-right → bottom-left → top-right → top-left fallback)
- Refactor ElementPopup with complete controls matching mockup
- Add stylesheet sync: popups initialize from and watch store changes
- Add click-to-close behavior: clicking another element closes popup
- Add CSS property tooltips on all form labels (editor panel + popups)
with dotted underline and monospace code tooltip on hover
- Add field--view-only class and disabled attribute on locked fields
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Toggle between locked/unlocked states
- Dynamic text: "Déverrouiller l'héritage" / "Verrouiller l'héritage"
- Show appropriate lock/unlock icon based on state
- Style as simple text button with icon (matching design)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace custom classes with global .field and .settings-subsection classes to ensure proper styling from _forms.scss.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add rem unit option to all margin controls
- Implement proper margin and background updates with debouncing
- Integrate Coloris properly like PageSettings
- Add highlight.js syntax highlighting for readonly CSS
- Add Prettier formatting when exiting edit mode
- Use global unit toggle styles instead of custom
- Sync isEditing state with stylesheet store
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements page edge hover detection and click handling:
- Hover near page edges (30px threshold) shows light outline
- Click on page edge opens PagePopup for template customization
- PagePopup component similar to ElementPopup but for @page rules
- Both popups coordinate to show only one at a time
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>