# Theme Customizer

## Objective

Let a customer restyle their own space and watch the change happen as they make it.

A settings surface where a customer adjusts colours, typography, spacing and corner radius for their workspace, with a live preview.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Build this on top of the app's existing theme tokens rather than beside them. If the library already includes Semantic Color Tokens, OKLCH Theme Tokens or Theme Surface Map, the customizer edits those token values and nothing else; a second styling path will drift out of sync within a release.
2. Group the controls the way a customer thinks: brand colour, text and surfaces, typography, spacing, corners. Keep each group small enough that someone can change one thing and see what moved.
3. Show the preview inside the real interface, not a mock swatch panel. If Theme Preview Sandbox exists, render the customizer's preview through it.
4. Derive the full palette from one or two brand inputs and let advanced users override individual tokens afterwards. Asking a non-designer to pick fourteen colours produces fourteen bad colours.
5. Do not let customer input reach the page as raw style text. Parse every value into a known type, reject anything that is not a valid colour, length or font choice, and never concatenate the input into a style declaration.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- A customer will pick a brand colour that leaves text unreadable on it. Check the contrast of every generated foreground and background pair, and either refuse the combination with a plain explanation or correct the derived foreground automatically. If Colour Contrast Guardrails already exists, call into it rather than re-deriving the maths.
- Both light and dark appearances must come out of a single brand colour. A palette that only works in one mode leaves half the customer's users with white text on white cards.
- The preview must not persist. Changes stay local until the customer confirms, and abandoning the screen or losing the connection leaves the live workspace exactly as it was.
- Reset must work per group as well as globally. A customer who wants their spacing back should not have to throw away the colour work they just finished.
- Injected values must not escape their token. A colour field that accepts a full declaration, a URL, or a closing brace lets one customer alter the layout of a page for everyone in their workspace.
- A font choice that fails to load must fall back to a readable stack without shifting the layout, and the customizer should say the font did not load rather than silently showing something else.
- A theme saved under an older token set must be migrated or discarded on upgrade, never applied partially. Half a theme looks worse than none.
- Custom themes must not override states that carry meaning. Destructive, error and warning treatments stay distinguishable no matter what the customer picks.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] The customizer writes to the app's existing theme tokens and introduces no parallel styling path.
- [ ] Changes preview live inside the real interface and are discarded unless the customer confirms.
- [ ] A single brand colour produces a coherent light and dark palette.
- [ ] Every generated text and surface pair meets the app's contrast minimum, or the combination is refused with an explanation.
- [ ] Each control group has its own reset alongside a global reset.
- [ ] No customer-supplied value reaches the page as unparsed style text.
- [ ] Themes stored against a previous token set are migrated or cleared on upgrade.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
