# Tokenized Inline Styles

## Objective

Allow styles computed at runtime without letting arbitrary values escape the design system.

A constrained path for dynamically computed styles, where every value is either a design token or a number clamped to an approved range.

## 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. Find every place the app already sets a style value at runtime — progress widths, chart bar heights, avatar colours, drag positions, user-chosen accent colours — and sort them into two groups: values that must come from the token set, and values that are genuinely continuous numbers.
2. For the first group, accept only token names and resolve them to values at the boundary. A caller passing a raw colour or a raw pixel value should be rejected loudly in development rather than quietly rendered.
3. For the second group, clamp to a documented minimum and maximum and round to a sensible precision, so a percentage of 4000 or a width of 0.3847291 pixels never reaches the DOM.
4. Treat any value that originated with a user or another tenant as untrusted. Strip anything that could terminate a declaration or introduce a new one, and never let a user-supplied string reach a URL-valued property.
5. Do not solve this by generating a new class per distinct value. A stylesheet that grows with your data is a memory and parse cost that shows up only at scale, and it defeats the caching the app already relies on.

## 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 caller that passes an arbitrary hex colour or a hand-written pixel value where a token is required must be rejected, not silently accepted — otherwise the token set stops describing the app within a release or two.
- Values that originated with a user or an external system must be sanitised before they are used, because a style value is a place markup can be smuggled in and a place a remote request can be triggered.
- Server-rendered and client-rendered output must agree exactly on the first paint. A value rounded differently on the two sides produces a hydration mismatch and a visible flash.
- The number of distinct generated rules must stay bounded. Styling a thousand rows with a thousand unique declarations is a cost that only appears on the largest accounts.
- A token that is removed or renamed later must fail visibly at the point of use rather than resolving to an empty value and rendering an unstyled element.
- Theme changes must flow through the same path. A runtime style that hardcodes a resolved colour will not follow the user into dark mode.
- Animated values updated every frame must not go through the token resolver on each tick; resolve once and interpolate.

## 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

- [ ] Every runtime style value is either a named token or a number clamped to a documented range.
- [ ] Passing an off-system value where a token is required fails visibly in development.
- [ ] User-supplied and third-party values are sanitised before they reach any style property.
- [ ] Server and client render identical style output on first paint, with no hydration mismatch.
- [ ] The count of distinct generated style rules does not grow with the number of records displayed.
- [ ] Runtime-styled elements follow theme changes without being re-mounted.
- [ ] 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.
