> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Design Token Sync Policy

> Version: 1.1.0 Last Updated: 2026-04-18 Status: Active Target Audience: Platform Foundation, Design System maintainers, AI agents

**Version:** 1.1.0
**Last Updated:** 2026-04-18
**Status:** Active
**Target Audience:** Platform Foundation, Design System maintainers, AI agents

***

## Purpose

This document defines the source-of-truth policy and synchronization workflow for UI design tokens used by:

* Encore Health OS application runtime (`/workspace/src/index.css`)
* Encore design system site/library (`encoredesign-lovable`)
* Documentation and implementation guides

The goal is to prevent token drift and preserve visual parity across products.

> **What changed in v1.1.0 (2026-04-18):** Added the **Tri-Source Parity Contract** documenting the three independent palettes that must stay in sync (`src/index.css`, PF-95 `DEFAULT_THEME_COLORS`, edge `PLATFORM_DEFAULTS`). Added the **Deprecated / Reserved Tokens** table (encore brand, unused module short codes, legacy module aliases, `--duration-base`). Added the **Audit Scripts** section. Token catalog cross-references the new Token Catalog Reference in `SEMANTIC_COLORS.md` v1.4.1.

***

## Canonical Source of Truth

The canonical source for token values is the design system token contract in:

* `encoredesign-lovable/src/styles/theme.css`
* `encoredesign-lovable/src/app/utils/token-generator.ts`

Encore Health OS must consume and mirror these canonical values for agreed token families.

The **runtime authority** within this repository is [`src/index.css`](../../src/index.css) — when this document and runtime values diverge, treat `src/index.css` as ground truth and update both this document and the canonical design-system source.

The **complete token inventory** lives in [`SEMANTIC_COLORS.md` § Token Catalog Reference](SEMANTIC_COLORS.md#token-catalog-reference). Avoid re-listing every token here; this document defines governance.

***

## Token Families and Lock Levels

### Hard-Locked (must match canonical exactly)

* **Core surfaces:** `--background`, `--card`, `--card-elevated`, `--border`, `--popover`
* **Brand & action:** `--primary`, `--primary-hover`, `--primary-foreground`, `--accent`, `--accent-hover`, `--accent-foreground`
* **Status:** `--success`, `--success-subtle`, `--success-foreground`; `--warning`, `--warning-subtle`, `--warning-foreground`; `--info`, `--info-subtle`, `--info-foreground`; `--destructive`, `--destructive-hover`, `--destructive-foreground`
* **Typography:** `--font-display`, `--font-body`, `--font-mono`
* **Radius base:** `--radius`
* **Motion durations/easings:** `--duration-*`, `--ease-*`
* **Module colors (active 12 short codes):** `--module-pf`, `--module-cl`, `--module-pm`, `--module-fm`, `--module-rh`, `--module-it`, `--module-hr`, `--module-lo`, `--module-ce`, `--module-fa`, `--module-gr`, `--module-fw` (each with `-hover` and `-subtle`)

### App-Local (can diverge with explicit justification)

* **Product-specific chart palettes:** `--chart-1` … `--chart-8` (light + dark)
* **Sidebar slot:** `--sidebar-*` (PF currently owns these; PF-95 v2 may expose them)
* **Device/safe-area/layout sizing tokens:** `--mobile-*`, `--safe-area-*`, `--app-header-height`, `--mobile-header-height`, `--mobile-nav-height`, `--dock-height`
* **Component-specific tokens:** `--overlay-scrim`, `--shimmer-highlight`, `--ai-accent`, `--glass-bg`, `--glass-border`, `--glow-opacity`, `--focus-ring-offset-color`
* **Reserved module short codes:** `--module-th`, `--module-qo`, `--module-da`, `--module-rpt` (pre-allocated; not in canonical until activated)
* **Encore brand tokens:** `--encore-navy`, `--encore-slate`, `--encore-teal`, `--encore-teal-light`, `--encore-teal-mid`, `--encore-gray`, `--encore-light`, `--encore-gold` (marketing surfaces)

Any app-local divergence from canonical for a hard-locked family must be documented in the "Local Overrides" section of this file.

***

## Token Aliases

The following semantic tokens intentionally alias to another token's value. They serve different semantic roles but share the same visual output for design cohesion.

| Token               | Resolves To                 | Rationale                                                                                      |
| ------------------- | --------------------------- | ---------------------------------------------------------------------------------------------- |
| `--color-secondary` | `hsl(var(--card-elevated))` | Secondary surfaces use the elevated card color for subtle visual hierarchy                     |
| `--color-muted`     | `hsl(var(--muted))`         | Muted backgrounds use the `--muted` scale (slightly distinct from elevated card in light mode) |

`--color-secondary` follows `--card-elevated` (near-white in light mode, elevated slate in dark). `--color-muted` follows `--muted` (cool gray in light, darker slate band in dark) so de-emphasized chrome reads differently from secondary interactive surfaces. Tailwind mappings live in `src/index.css` `@theme inline`.

> **Known limitation:** PF-95's `colorSecondary` field writes to the raw `--secondary` HSL var, but the Tailwind utility `bg-secondary` resolves to `--card-elevated` via the alias above. Tenants who customize `colorSecondary` will not see `bg-secondary` consumers update. This is documented in [SEMANTIC\_COLORS.md § Tenant Theming Mapping Table](SEMANTIC_COLORS.md#tenant-theming-pf-95-mapping-table). A future PF-95 v2 will reconcile this.

***

## Tri-Source Parity Contract

The same semantic palette is duplicated across three sources for different runtime contexts. **They MUST stay in sync.**

| Source                                   | File                                                                                                                                 | Format                  | Used by                                                                                                |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | ------------------------------------------------------------------------------------------------------ |
| **Runtime** (browser)                    | [`src/index.css`](../../src/index.css) — `:root` and `.dark` blocks                                                                  | HSL strings (`H S% L%`) | All app code via Tailwind v4 `@theme inline`                                                           |
| **Tenant theming UI default** (PF-95)    | [`src/platform/theming/types.ts`](../../src/platform/theming/types.ts) — `DEFAULT_THEME_COLORS`                                      | HEX (`#RRGGBB`)         | `BrandingSettingsPage`, `ColorsTab`, `pf_tenant_themes` row defaults                                   |
| **Edge function fallback** (PF-91-EN-01) | [`supabase/functions/_shared/compliance-contrast.ts`](../../supabase/functions/_shared/compliance-contrast.ts) — `PLATFORM_DEFAULTS` | HEX (`#RRGGBB`)         | `generate-compliance-evidence` and other Deno functions that need to render branded compliance exports |

### Parity rules

1. **Same semantic palette:** All three sources MUST resolve to the same color for each semantic role: `colorPrimary` ≡ `--primary`, `colorAccent` ≡ `--accent`, `colorBackground` ≡ `--background`, `colorSurface` ≡ `--card-elevated`, `colorText` ≡ `--text-main`, `colorTextMuted` ≡ `--text-muted`, `colorDestructive` ≡ `--destructive`, `colorSuccess` ≡ `--success`, `colorWarning` ≡ `--warning` (HSL→HEX conversion permitted with ΔE-CIE76 tolerance ≤ 3 for rounding).
2. **HEX must match exactly** between `DEFAULT_THEME_COLORS` and `PLATFORM_DEFAULTS` for the same field.
3. **Validated by:** `npm run audit:token-parity` (planned, see [Audit Scripts](#audit-scripts) below).
4. **Update workflow (any change to a hard-locked token):** update `src/index.css` first, then update both HEX copies in the same PR, then run `npm run audit:token-parity --strict` and `npm run validate`.

***

## Synchronization Workflow

1. **Update canonical tokens** in `encoredesign-lovable`.
2. **Generate/export token artifacts** via design system generator utilities if changed.
3. **Mirror into app** in one scoped PR:
   * update `src/index.css` `:root` and `.dark` values (HSL),
   * mirror the change into `DEFAULT_THEME_COLORS` (HEX) in `src/platform/theming/types.ts`,
   * mirror the change into `PLATFORM_DEFAULTS` (HEX) in `supabase/functions/_shared/compliance-contrast.ts`,
   * preserve alias compatibility where needed.
4. **Run validation**:
   * `npm run typecheck`
   * `npm run lint`
   * `npm run build`
   * `npm run audit:hardcoded-colors`
   * `npm run audit:token-parity` (planned)
   * targeted browser visual regression (light/dark, desktop/mobile)
5. **Update docs/version metadata**:
   * `docs/development/SEMANTIC_COLORS.md` (re-run any embedded HSL examples)
   * `docs/development/UI_UX_STANDARDS.md` (only if semantic-status section changes)
   * `docs/VERSIONS.md`
6. **Record evidence** in spec/task logs when part of a scoped initiative.

***

## Backward Compatibility and Deprecation

* Introduce aliases first, then migrate consumers.
* Maintain aliases for at least one release cycle when feasible.
* Remove deprecated aliases only after:
  * consumer sweep confirms no references remain (`rg` against `src/`),
  * visual regression pass is complete,
  * docs are updated.

***

## Deprecated / Reserved Tokens

Tokens that are declared but not actively consumed by product UI today. Consult before removing or repurposing.

| Token family                                                                                                                                       | Status                    | Notes                                                                                                                                                                                                                                                                 |
| -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--encore-navy`, `--encore-slate`, `--encore-teal`, `--encore-teal-light`, `--encore-teal-mid`, `--encore-gray`, `--encore-light`, `--encore-gold` | Reserved (marketing only) | Currently 0 consumers in `src/` outside `index.css`. Reserved for marketing surfaces (login chrome, brand splash, PDF letterheads, marketing emails). Do not use in product UI without DS owner approval.                                                             |
| `--module-th`, `--module-qo`, `--module-da`, `--module-rpt` (each with `-hover`, `-subtle`)                                                        | Reserved (future modules) | Pre-allocated for future modules. 0 consumers today. Adding a consumer requires (a) confirming the short code maps to a real module in `MODULE_REGISTRY`, and (b) updating [SEMANTIC\_COLORS.md § Module Identity Tokens](SEMANTIC_COLORS.md#module-identity-tokens). |
| `--module-clinical`, `--module-finance`, `--module-operations`, `--module-people` (each with `-hover`, `-subtle`)                                  | Deprecated alias          | Use the short-code form (`--module-cl`, `--module-fa`, `--module-fw`, `--module-hr`). 0 consumers today. Will be removed in next DS major release.                                                                                                                    |
| `--duration-base`                                                                                                                                  | Deprecated alias          | Use `--duration-normal` (300ms). Kept for backward compatibility during the DS v3.0 transition.                                                                                                                                                                       |

### Removal procedure

To remove any token in this table:

1. Re-grep to confirm 0 consumers: `rg --no-heading -F "module-clinical" -- src/` (or token name).
2. Remove from `:root`, `.dark`, and `@theme inline` blocks of `src/index.css`.
3. Remove from canonical `encoredesign-lovable` source if present.
4. Update this section noting removal date and PR.
5. Bump `DESIGN_TOKEN_SYNC_POLICY.md` minor version.

***

## Audit Scripts

| Script                           | Purpose                                                                                                                    | Status                                     | Wired into                                                                              |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------- |
| `npm run audit:hardcoded-colors` | Flags Tailwind palette literals (`text-red-500`), `bg-black/text-white` escapes, and hex literals outside legitimate paths | ✅ Active                                   | Already gated in CI via `validate:governance` → `npm run audit:hardcoded-colors:strict` |
| `npm run audit:token-parity`     | Verifies `:root` HSL values in `src/index.css` match the HEX defaults in `DEFAULT_THEME_COLORS` and `PLATFORM_DEFAULTS`    | 🔨 Planned (color-system review Phase 4.1) | Will gate CI under `validate:governance`                                                |
| `npm run audit:dead-tokens`      | Reports CSS vars declared in `:root` with 0 consumers in `src/`                                                            | 🔨 Planned (color-system review Phase 4.3) | Informational only                                                                      |

The hardcoded-colors auditor reads an allowlist (`scripts/utils/.audit-color-allowlist.json`) for legitimate exceptions (PDF generators, picklist hex presets, chart fallbacks). Add new exceptions there with a reason and owner — do not relax the audit script itself.

***

## Local Overrides

Current approved local overrides:

* None.

If a local override is added, document:

* token name,
* reason,
* owner,
* expected removal/reconciliation date.

***

## Ownership

* **Canonical owner:** Design system maintainers (`encoredesign-lovable`)
* **App mirror owner:** Platform Foundation (`/workspace/src/index.css`)
* **Tenant theming owner:** Platform Foundation (PF-95 — `src/platform/theming/`)
* **Compliance theming owner:** Platform Foundation (PF-91-EN-01 — `src/platform/compliance/`, `_shared/compliance-contrast.ts`)
* **Documentation owner:** Platform Foundation docs maintainers

***

## References

* [`SEMANTIC_COLORS.md`](SEMANTIC_COLORS.md) — Token catalog, badge/icon/alert patterns, module/chart/sidebar reference, PF-95 + PF-91-EN-01 mapping
* [`UI_UX_STANDARDS.md`](UI_UX_STANDARDS.md) — Quick-reference and design-system overview
* [`docs/VERSIONS.md`](../VERSIONS.md) — Document version index
* [`src/index.css`](../../src/index.css) — Runtime token authority
* [`src/platform/theming/types.ts`](../../src/platform/theming/types.ts) — PF-95 default theme colors (HEX)
* [`supabase/functions/_shared/compliance-contrast.ts`](../../supabase/functions/_shared/compliance-contrast.ts) — Edge `PLATFORM_DEFAULTS` (HEX)
* [`scripts/utils/audit-hardcoded-colors.ts`](../../scripts/utils/audit-hardcoded-colors.ts) — Hardcoded color audit
