# Theme Selection v1 ## 1. Doel Theme-selectie voegt nu waarde toe omdat de UI al een nette light/dark basis heeft, maar nog geen expliciet onderscheid maakt tussen: - `theme`: de stijlset - `mode`: light of dark binnen die stijlset Dat onderscheid maakt de UI uitbreidbaar zonder de dagelijkse snelle UX kwijt te raken. Dit past logisch in de bestaande Settings-structuur: - `General` voor functionele voorkeuren - `Interface` voor theme-keuze - `Logs` voor recente acties ## 2. Scope Theme Selection v1 omvat: - nieuw Settings-tabblad: `Interface` - daarin alleen een pulldown/select: `Theme` - bestaande snelle dark/light toggle blijft in de hoofdinterface bestaan - beide keuzes worden opgeslagen in bestaande SQLite settings-opslag - app leest beide waarden bij startup via backend en past die direct toe Niet in scope: - vrije CSS-bestandskeuze - padinvoer - upload van themes - custom theme editor - theme packs van externe bron ## 3. Theme-model Aanbevolen model voor v1: - werk met een whitelist van toegestane theme keys - werk daarnaast met een aparte whitelist van toegestane color modes - sla beide als strings op in settings Aanbevolen settings voor v1: - `selected_theme: string | null` - `selected_color_mode: string | null` Whitelist v1: - `selected_theme` - `default` - `selected_color_mode` - `dark` - `light` Waarom dit veiliger en eenvoudiger is dan bestandsselectie: - geen vrije filesystemtoegang nodig - geen risico op ongeldige of kwaadaardige CSS-inhoud - geen extra upload- of assetbeheer - duidelijke validatie in backend mogelijk - stabiel contract tussen backend setting en frontend rendering ## 4. Settings-opslag Nieuwe settings in bestaande settings-opslag: - `selected_theme` - `selected_color_mode` Semantiek: - `selected_theme = null` betekent: fallback naar veilige default `default` - `selected_color_mode = null` betekent: fallback naar veilige default `dark` - onbekende opgeslagen waarden betekenen: negeren en fallback toepassen Aanbevolen effectieve defaults: - theme -> `default` - mode -> `dark` ## 5. Settings UI Tabs in Settings worden: - `General` - `Interface` - `Logs` `Interface` bevat in v1 alleen: - label: `Theme` - een select/pulldown met toegestane themes Belangrijk: - geen dark/light selector in `Settings > Interface` - dark/light blijft een snelle hoofdinterface-actie Aanbevolen v1-UX: - select toont huidige theme-keuze - gebruiker kiest andere waarde - opslaan gebeurt via bestaande settings-saveflow - keuze wordt direct toegepast in de UI na succesvolle backend-save ## 6. Frontend-impact Frontend moet bij startup vroeg settings laden en daaruit beide waarden ophalen: - `selected_theme` - `selected_color_mode` Daarna bepaalt frontend het effectieve UI-theme. Aanbevolen intern model: - `data-theme="default-dark"` - `data-theme="default-light"` Aanbevolen volgorde: 1. `GET /api/settings` 2. bepaal effectief theme + mode 3. zet `document.documentElement.dataset.theme` 4. initialiseer de rest van de UI Relatie met bestaande light/dark toggle: - toggle blijft bestaan in de hoofdinterface - toggle wijzigt alleen `selected_color_mode` - toggle schrijft dus naar backend, niet naar localStorage Reden: - snelle dagelijkse UX blijft behouden - `Settings > Interface` blijft schoon en beperkt tot theme-keuze - theme en mode blijven conceptueel gescheiden ## 7. Backend-impact Bestaande settings-API wordt uitgebreid met: - `selected_theme` - `selected_color_mode` Benodigd: - whitelistvalidatie op backend - onbekende waarden blokkeren bij write - bestaande settings repository/service/API uitbreiden Niet nodig: - nieuwe dependency - vrije filesystemtoegang - nieuwe asset-uploadroute ## 8. Regressierisico Belangrijkste risico's: - startup-volgorde: theme moet vroeg genoeg worden toegepast om flicker te beperken - bestaande theme-toggle logica conflicteert nu nog met localStorage - onbekende opgeslagen theme/mode-waarden moeten veilig terugvallen - Settings-tabcomplexiteit mag niet onnodig toenemen Belangrijkste mitigaties: - één centrale frontendfunctie die theme en mode uit backend toepast - localStorage volledig verwijderen als leidende theme-bron - backend whitelistvalidatie - fallback naar `default-dark` ## 9. Teststrategie Backend golden tests: - default `selected_theme` - default `selected_color_mode` - geldige theme save (`default`) - geldige color mode save (`dark`, `light`) - ongeldige theme key wordt geblokkeerd - ongeldige color mode wordt geblokkeerd - settings response bevat beide velden UI smoke/regressietests: - `Settings` bevat tabs `General`, `Interface`, `Logs` - `Interface` tab bevat alleen theme select - hoofdinterface bevat nog steeds dark/light toggle - app leest beide settings via backend - fallback bij ontbrekende/ongeldige waarde breekt startup niet Handmatige validatie: - theme wijzigen in `Settings > Interface` - mode wisselen via toggle in de hoofdinterface - app herladen en controleren dat beide keuzes behouden blijven - controle dat light/dark correct doorwerken in modals, panelen en editor/viewers ## 10. Aanbeveling Aanbevolen v1-richting met laag regressierisico: - voeg `Interface` tab toe - voeg `selected_theme` en `selected_color_mode` toe aan bestaande settings-opslag - werk alleen met veilige whitelists - houd v1 beperkt tot: - theme: `default` - mode: `dark|light` - laat startup en toggle beide backendpersistente settings gebruiken - fallback altijd veilig naar `default-dark` Deze richting is: - simpel - veilig - onderhoudbaar - duidelijk uitbreidbaar naar extra themes, zonder de dagelijkse dark/light UX opnieuw te moeten ontwerpen