# Theme engine

## How it works

1. `ThemeService::resolveFor(User $user, Company $company)` picks the effective
   theme with this precedence:
   - Per-user preference (`users.theme`, `users.density`)
   - Per-company default (`companies.meta.theme.*` and `themes` table)
   - Global fallback (`config('decent.ui.themes.light')`)
2. It returns a `ResolvedTheme` value object with:
   - `mode`: `light` | `dark`
   - `density`: `comfortable` | `compact`
   - `cssVariablesString()`: string ready to drop inside `:root { … }`
3. `ViewServiceProvider` shares this as `$globalTheme` to every view.
4. Layout writes:
   ```html
   <html data-theme="{{ $globalTheme->mode }}" data-density="{{ $globalTheme->density }}">
   <style id="theme-vars">:root { {{ $globalTheme->cssVariablesString() }} }</style>
   ```
5. `resources/js/core/theme.js` allows live toggle without a page reload, then
   syncs to the server via `POST /settings/theme/quick`.

## Adding a new theme variable

1. Add a default value to `resources/sass/abstracts/_tokens.scss`.
2. Add a column to `themes` table (via migration) or key to
   `companies.meta.theme`.
3. Update `Theme::cssVariables()` to include the new key.
4. Update `ResolvedTheme::cssVariablesString()` if it needs custom formatting.

## Adding a new theme

Insert into `themes` table (or add to `ThemeSeeder`) with a `slug`, all
palette columns, `mode`, `density`, and `is_default`. Only one theme can be
`is_default = 1` per mode.
