# Medora token migration (old green tokens to Medora blue)

Status: transition in progress. Source of truth for the full plan is
`medora-design-system/05-implementation/implementation-guidelines.md` sections 2.6 and 2.7.

## How the two systems coexist today

- `styles/tokens.generated.css` (Medora, generated) is imported by `app/globals.css` **before** the legacy
  `@theme` blocks. Names that exist in both resolve to the **legacy** value, so no un-redesigned page changes.
  Every other Medora name is new and additive (`bg-action-primary-default`, `text-fg-primary`, `text-body-md`,
  `shadow-overlay`, `--density-*`, `--z-*`, ...).
- Medora primitives are `--mdr-<hue>-<step>` plain variables. They are not in Tailwind's `--color-*`
  namespace, so no `bg-blue-700`-style utility exists for them and Tailwind's default palette (about 3,250
  uses in existing pages) is untouched.
- The shadcn variables (`--primary`, `--ring`, `--background`, `--radius`, `--chart-*`, `.dark`) are **not
  re-pointed yet**. Re-pointing `--primary` / `--ring` / `--radius` re-skins every `Button` and `Input` and
  changes 371 `rounded-*` uses on existing pages, so it ships with the login rebuild (guideline 2.7 step 2).

## Names defined in both (legacy wins until the legacy block is deleted)

`tests/tokens.test.ts` fails if this list changes without the test being updated.

| Name | Legacy value | Medora value | Consequence for new components in the app (outside the pages already redesigned) |
|---|---|---|---|
| `--color-bg-surface` | #FFFFFF | white | none (same) |
| `--color-bg-selected` | #C1FCF8 | blue-50 | `bg-bg-selected` shows teal in the app until switched |
| `--color-border-subtle` | #D9E2E1 | gray-200 | slightly greener grey |
| `--color-border-strong` | #AABDBB | steel-500 | much paler than intended |
| `--color-brand-primary` | #004542 | blue-700 | green, not blue |
| `--color-brand-accent` | #D99B26 | lime-300 | amber, not lime |
| `--font-sans`, `--font-display` | shorter stack | longer stack | none visible |
| `--radius-sm/md/lg` | derived from `--radius` 10px (6/8/10 px) | 6/8/12 px | `rounded-lg` is 10 px, not 12 px |

Until the switch, new components should avoid these names (use `action-*`, `fg-*`, `border-input-*`,
`status-*`) or accept the legacy value. **To switch**: delete the legacy `@theme` / `@theme inline` / `:root`
/ `.dark` blocks in `app/globals.css` (step 5 of the rollout), after the grep in guideline 2.7.1 is clean.

## Old to new map

| Old variable (`--color-*`) | New |
|---|---|
| `brand-primary` | `action-primary-default` (buttons, links) |
| `brand-primary-dark` | `action-primary-hover` |
| `brand-primary-light` | `bg-selected` |
| `brand-accent`, `brand-teal`, `brand-teal-hover` | remove (warning: `status-warning-*`) |
| `brand-highlight` | `action-accent-default` on the Pay button only, else remove |
| `bg-main` | `bg-canvas` |
| `bg-surface` | `bg-surface` |
| `bg-subtle` | `bg-surface-subtle` |
| `bg-input`, `bg-input-hover` | remove (white input, `border-input-default`; disabled: `bg-input-disabled`) |
| `bg-selected` | `bg-selected` |
| `border-subtle` | `border-subtle` |
| `border-hover` | `border-input-hover` (inputs), else remove |
| `border-strong` | `border-strong` (active tab, selected card) or `border-panel` (card outline) |
| `focus-ring` | `border-focus` via `--focus-ring-*` |
| `backdrop` | `overlay-backdrop` |
| `text-primary` | `fg-primary` |
| `text-secondary` | `fg-secondary` (on white), `fg-secondary-strong` (on grey) or `fg-tertiary` |
| `text-placeholder`, `-focus` | `fg-tertiary` (focus variant removed) |
| `state-error`, `-light`, `-dark` | `status-error-text` / `-fill`, `status-error-bg` |
| `state-success`, `-light` | `status-success-text`, `status-success-bg` (old value was a grey, a latent bug) |
| `state-warning`, `-light` | `status-warning-text`, `status-warning-bg` |
| `state-info`, `-light` | `status-info-text`, `status-info-bg` |
| `state-neutral`, `-light` | `fg-secondary-strong`, `bg-surface-subtle` |
| `avatar-01..10` | no equivalent; keep until the Avatar spec (C45) |
| `primary`, `primary-light`, `primary-hover`, `active-bg`, `active-text`, `badge-green(-bg)`, `sidebar(-border)`, `card`, `muted` | `action-primary-*`, `bg-selected`, `status-success-*`, `bg-surface`, `border-subtle`, `fg-secondary` |
| shadcn `--primary`, `--ring`, `--destructive`, `--muted-foreground`, `--border`, `--background`, `--foreground` | re-point to Medora semantics at step 2 (`--primary: var(--color-action-primary-default)`, `--ring: var(--color-border-focus)`, ...) |
| shadcn `--chart-*`, `--sidebar-*`, `.dark`, `--radius` | delete when nothing reads them |

## Tooling

- `npm run tokens:build` regenerates `styles/tokens.generated.css` (also runs as `predev` / `prebuild`);
  `npm run tokens:check` fails when the committed file is stale.
- `design/design-tokens.json` is a **committed copy** of
  `medora-design-system/04-design-system/design-tokens.json`. `npm run tokens:sync` copies the master over it
  (path from `MEDORA_TOKENS_SOURCE`, default `../medora-design-system/...`) and lists what changed; it does
  nothing when the master is absent. Edit the master, never the copy.
