Say Remove for displays, and make the default accent purple (#210050)
CI / verify (pull_request) Successful in 1m14s
CI / infrastructure-smoke (pull_request) Successful in 42s
CI / package-release (pull_request) Successful in 49s
CI / migration-smoke (pull_request) Successful in 2m30s
CI / image-build (pull_request) Successful in 1m8s
CI / deploy-smoke (same-origin) (pull_request) Successful in 45s
CI / package-publication (pull_request) Successful in 56s
CI / deploy-smoke (split) (pull_request) Successful in 8m55s
CI / verify (pull_request) Successful in 1m14s
CI / infrastructure-smoke (pull_request) Successful in 42s
CI / package-release (pull_request) Successful in 49s
CI / migration-smoke (pull_request) Successful in 2m30s
CI / image-build (pull_request) Successful in 1m8s
CI / deploy-smoke (same-origin) (pull_request) Successful in 45s
CI / package-publication (pull_request) Successful in 56s
CI / deploy-smoke (split) (pull_request) Successful in 8m55s
Administrators now remove a display: the card's Remove, "Remove display?", and "Display removed". The platform still revokes the device's credential; the endpoint, fields, and security history keep revoke/revoked (ADR 0065). The default accent is a deep purple anchored on #210050, set in the shared design tokens only (ADR 0066, superseding ADR 0060's teal in part). The anchor is the light primary action with white on it; the light accent text, focus ring, and selection, and the dark theme's lavender accent, are variants on its hue chosen for contrast. The teal-tinted neutrals move to a faint violet-grey at the same lightness, so every contrast pairing holds. The contrast test gains six pairings the accent depends on, and pins the anchor. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d9dafcb0f7
commit
0009f62fbd
@@ -0,0 +1,112 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user