# 0066: The default accent is a deep purple anchored on `#210050` - Status: Accepted - Date: 2026-10-16 - Supersedes, in part: [0060](0060-light-dark-system-theme-and-motion.md) (the teal accent and the teal-tinted charcoal of its designed dark theme) - Extends: [0039](0039-shared-design-tokens-and-elements.md), [0060](0060-light-dark-system-theme-and-motion.md) ## Context Ekklesia's default theme was accented in teal. The light primary action was a pale teal (`#4fb3a8`) with dark text on it. ADR 0060's designed dark theme described "teal-tinted charcoal" backgrounds and "the same teal accent, slightly lifted". The neutrals carried the same teal tint, so did the selection and information washes, and the whole product read as teal. The maintainer chose a purple default anchored on `#210050`. Branding settings will later let an administrator choose the accent. This decision changes only the **default**. A single hex cannot serve every place the accent is used. `#210050` is very dark: it is 17.8:1 against white, but about 1.2:1 against a dark-theme page, where it would all but vanish. ## Decision ### The accent is set through the semantic tokens only The change is made in `@ekklesia/design-tokens`' registry, and nowhere else. No Dashboard component names a purple. The shared `@ekklesia/ui` elements and the shell already draw from `accent.*`, `state.selected-*`, and `status.info-*`, so they inherit the new values. Modules read the same `--ekklesia-*` custom properties (ADR 0040), so their token inheritance is unchanged. ### `#210050` is the light primary action; every other value is a variant on its hue Each variant keeps the anchor's OKLCH hue (≈291.5°). Lightness and chroma are chosen for contrast where the variant is used. | Token | Light | Dark | Used for | | --- | --- | --- | --- | | `accent.base` | **`#210050`** | `#ac9bf6` | primary button, tab underline, spinner, brand mark | | `accent.hover` | `#340e71` | `#bbacff` | hovered primary button | | `accent.active` | `#120033` | `#9a88e2` | pressed primary button | | `accent.foreground` | `#ffffff` | **`#210050`** | text on the accent | | `accent.strong` | `#4d2a99` | `#c8bcff` | accent text and icons; checked box and radio | | `accent.subtle` | `#f0eeff` | `#2e2849` | selected tab wash | | `accent.focus` | `#6a40c9` | `#bfb0ff` | focus ring | | `state.selected-background` | `#eceaff` | `#342b53` | the open page in navigation, selected option | | `state.selected-foreground` | `#48278e` | `#d7d0ff` | its label | | `status.info-background` | `#f1f0ff` | `#292440` | information notice and badge | | `status.info-border` | `#c7c0f2` | `#564b83` | its border | **The light theme turns around.** A pale accent with dark text becomes the deep anchor with white text: 17.8:1, or 14.5:1 hovered. **Light accent text and the focus ring stay off the anchor itself.** In body copy `#210050` is almost indistinguishable from near-black text, so accent text and icons use a brighter `#4d2a99` (10.0:1 on a surface). The focus ring uses a vivid `#6a40c9` (6.1:1 on the page). Next to a dark primary button, a ring in the anchor's own colour would merge into the button; this one is clearly distinct. **Dark keeps ADR 0060's principle: lifted, not glowing.** The accent is a lavender (`#ac9bf6`). The anchor is drawn on it as its foreground, at 7.4:1, and at 5.9:1 pressed. Selected and information washes are deep purple tints, never saturated fills. ### The neutrals lose their teal tint Every teal-tinted neutral moves to the anchor's hue at the same OKLab lightness and chroma. This covers the backgrounds, text, borders, hover and pressed washes, the placeholder, the shadows' colour, and the dark overlay. - **Light:** a faint violet-grey (page `#f6f5f9`, text `#201f28`). - **Dark:** a violet-grey charcoal (page `#141319`, text `#eaeaf1`). ADR 0060's other rules still hold: never pure black, never pure white, and an elevation ladder. Because lightness is kept, contrast is kept. The tightest pairings move by less than 0.1. For example, `border.control` on the light page goes from 3.24 to 3.28, and `text.muted` on the light page from 5.04 to 5.10. Success, warning, and danger keep their own hues. ### Contrast stays tested `packages/design-tokens/tests/contrast.test.ts` keeps all 41 pairings it already checked, in both schemes. It adds six pairings this accent depends on: - the accent as a non-text indicator on the page, the canvas, and a surface; - the selected tab's label on its wash; - accent text in a dialog; - the mark inside a checked box or radio. A test also pins the anchor: `accent.base` is `#210050` with white on it in light, and in dark it is lifted, with the anchor as its foreground. ## Alternatives - **The same hex everywhere.** Rejected: `#210050` fails as an indicator on dark surfaces at about 1.2:1. As light text, it is too close to the body copy to read as an accent. - **Purple accent tokens, teal-tinted neutrals.** Rejected: the teal stays visible in every surface and border, most of all in dark, and clashes with the accent. - **Hue-rotating every accent token at its old lightness and chroma.** Rejected for the accent tokens: teal's low chroma gives a dull grey-purple. It is used for the neutrals, where a faint tint is the point. - **Waiting for Branding settings.** Rejected by the maintainer: the default should be right before anyone configures it. ## Consequences - Every first-party surface turns purple from tokens alone: the Dashboard, the sign-in pages, and the shared elements. The display host stays light (ADR 0060) and takes the light values. - Modules that use the shared tokens, such as Signage, follow the new default with no change of their own. A module that hard-coded the old teal would not, which is why no module should. - A deployment that overrides tokens at its host root is unaffected. - When Branding settings arrive, the accent becomes an administrator's choice. That feature must derive the same set of variants and pass the same contrast tests. This decision is its default.