@epa-wg/custom-element-dist 0.0.33 → 0.0.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +18 -0
- package/.gitattributes +4 -0
- package/.github/workflows/deploy.yml +59 -0
- package/.idea/copilot.data.migration.agent.xml +6 -0
- package/.idea/copilot.data.migration.ask.xml +6 -0
- package/.idea/copilot.data.migration.ask2agent.xml +6 -0
- package/.idea/copilot.data.migration.edit.xml +6 -0
- package/.idea/custom-element-dist.iml +2 -0
- package/.storybook/main.ts +20 -17
- package/.storybook/preview.ts +23 -23
- package/.yarn/install-state.gz +0 -0
- package/.yarnrc.yml +1 -0
- package/README.md +6 -4
- package/coverage/block-navigation.js +1 -1
- package/coverage/coverage-final.json +4 -3
- package/coverage/index.html +34 -19
- package/coverage/sorter.js +21 -7
- package/coverage/src/custom-element/coverage.svg +1 -1
- package/coverage/src/custom-element/custom-element.js/coverage.svg +1 -1
- package/coverage/src/custom-element/custom-element.js.html +448 -391
- package/coverage/src/custom-element/http-request.js/coverage.svg +1 -1
- package/coverage/src/custom-element/http-request.js.html +38 -17
- package/coverage/src/custom-element/index.html +26 -26
- package/coverage/src/custom-element/local-storage.js.html +1 -1
- package/coverage/src/custom-element/location-element.js.html +1 -1
- package/coverage/src/custom-element/module-url.js.html +1 -1
- package/coverage/src/index.html +1 -1
- package/coverage/src/material/theme/colors.js/coverage.svg +10 -0
- package/coverage/src/material/theme/colors.js.html +217 -0
- package/coverage/src/material/theme/coverage.svg +10 -0
- package/coverage/src/material/theme/index.html +116 -0
- package/coverage/src/mocks/handlers.ts.html +1 -1
- package/coverage/src/mocks/index.html +1 -1
- package/coverage/src/stories/frame.canvas.ts.html +1 -1
- package/coverage/src/stories/http-request.stories.ts.html +1 -1
- package/coverage/src/stories/index.html +1 -1
- package/coverage/src/stories/testStoryBook.ts.html +12 -12
- package/coverage/src/sum.ts.html +1 -1
- package/dist/custom-element-Bssk9jRy.cjs +97 -0
- package/dist/{custom-element-WnOqmEOe.js → custom-element-BzDjIYMe.js} +193 -183
- package/dist/custom-element-bundle.cjs +1 -1
- package/dist/custom-element-bundle.js +3 -3
- package/dist/demo/a.html +10 -3
- package/dist/demo/a.svg +26 -26
- package/dist/demo/html-template.html +4 -3
- package/dist/demo/s.xml +1 -75
- package/dist/demo/s.xslt +351 -72
- package/dist/demo/s1.xml +3706 -0
- package/dist/http-request-DSaowcG1.cjs +1 -0
- package/dist/{http-request-BOvP4KTl.js → http-request-DTCzZ1gc.js} +15 -9
- package/dist/mockServiceWorker.js +105 -63
- package/package.json +5 -4
- package/public/demo/a.html +10 -3
- package/public/demo/a.svg +26 -26
- package/public/demo/html-template.html +4 -3
- package/public/demo/s.xml +1 -75
- package/public/demo/s.xslt +351 -72
- package/public/demo/s1.xml +3706 -0
- package/public/mockServiceWorker.js +105 -63
- package/src/custom-element/custom-element.js +28 -9
- package/src/custom-element/demo/a.html +10 -3
- package/src/custom-element/demo/a.svg +26 -26
- package/src/custom-element/demo/html-template.html +4 -3
- package/src/custom-element/demo/s.xml +1 -75
- package/src/custom-element/demo/s.xslt +351 -72
- package/src/custom-element/demo/s1.xml +3706 -0
- package/src/custom-element/http-request.js +7 -0
- package/src/custom-element/ide/customData-dce.json +123 -0
- package/src/custom-element/ide/web-types-dce.json +128 -1
- package/src/custom-element/ide/web-types-xsl.json +1 -1
- package/src/material/angular.css +987 -987
- package/src/material/components/action.html +262 -0
- package/src/material/components/autocomplete.html +167 -239
- package/src/material/components/badge.html +238 -239
- package/src/material/components/dropdown.html +0 -1
- package/src/material/components/icon-link.html +160 -161
- package/src/material/components/icon.html +251 -252
- package/src/material/components/input.html +569 -570
- package/src/material/components/menu.html +235 -236
- package/src/material/components.html +157 -158
- package/src/material/demo.css +36 -36
- package/src/material/index.html +109 -110
- package/src/material/material.css +356 -356
- package/src/material/theme/Base-Principles.md +339 -0
- package/src/material/theme/README.md +298 -18
- package/src/material/theme/UI Domain Model in web applications.svg +1 -0
- package/src/material/theme/User Semantic Theme tokens.svg +1 -0
- package/src/material/theme/action-pending-poc.html +62 -0
- package/src/material/theme/actions-color.html +141 -0
- package/src/material/theme/colors-light.html +631 -0
- package/src/material/theme/colors-native.html +51 -0
- package/src/material/theme/colors-poc.html +66 -0
- package/src/material/theme/colors.html +297 -0
- package/src/material/theme/colors.js +44 -0
- package/src/material/theme/consumer-theme.css +745 -0
- package/src/material/theme/semantic.css +132 -132
- package/src/material/theme/style-bug.html +123 -0
- package/src/material/theme/theme-data.css +43 -0
- package/src/material/theme/theme-data.xhtml +2926 -0
- package/src/material/theme/todo.md +274 -0
- package/src/material/theme/tokens/action-colors.png +0 -0
- package/src/material/theme/tokens/cem-article-illustration-4x1-letterbox-2000x500.png +0 -0
- package/src/material/theme/tokens/cem-breakpoints.md +519 -0
- package/src/material/theme/tokens/cem-colors.md +715 -0
- package/src/material/theme/tokens/cem-consumerflow-typography-matrix.svg +198 -0
- package/src/material/theme/tokens/cem-coupling.md +372 -0
- package/src/material/theme/tokens/cem-data-vs-reading-numerals.svg +164 -0
- package/src/material/theme/tokens/cem-dimension.md +625 -0
- package/src/material/theme/tokens/cem-layering.md +562 -0
- package/src/material/theme/tokens/cem-m3-parity.md +343 -0
- package/src/material/theme/tokens/cem-responsive.md +238 -0
- package/src/material/theme/tokens/cem-shape.md +691 -0
- package/src/material/theme/tokens/cem-stroke-density-illustration-4to1-v3.svg +102 -0
- package/src/material/theme/tokens/cem-stroke.md +480 -0
- package/src/material/theme/tokens/cem-timing.md +198 -0
- package/src/material/theme/tokens/cem-typography-model-stack.svg +64 -0
- package/src/material/theme/tokens/cem-voice-fonts-typography.md +718 -0
- package/src/material/theme/tokens/cem-voice-ladder.svg +91 -0
- package/src/material/theme/tokens/chips.png +0 -0
- package/src/material/theme/tokens/columns-page.png +0 -0
- package/src/material/theme/tokens/initials.png +0 -0
- package/src/material/theme/tokens/nav-buttons.png +0 -0
- package/src/material/theme/tokens/script.png +0 -0
- package/src/material/theme/tokens/sufler.png +0 -0
- package/src/material/theme/tokens/typography-icons.png +0 -0
- package/src/mocks/versions.mock.ts +1 -1
- package/src/stories/__screenshots__/dom-merge.test.stories.ts/dom-merge-dom-merge-OrderPreservingOn2ndTransform-1.png +0 -0
- package/src/stories/__screenshots__/xslt-conditionals.test.stories.ts/xslt-conditionals-xslt-conditionals-MultipleIfOrderingWorkaround-1.png +0 -0
- package/src/stories/dom-merge.test.stories.ts +25 -1
- package/src/stories/xslt-conditionals.test.stories.ts +492 -0
- package/src/stories/xslt-for-each.test.stories.ts +336 -0
- package/src/stories/xslt-if.test.stories.ts +89 -0
- package/storybook-static/assets/{Color-F6OSRLHC-Cbp293x2.js → Color-F6OSRLHC-DeDlDLjU.js} +1 -1
- package/storybook-static/assets/{Configure-BrFr4SLE.js → Configure-CH_tIP5N.js} +1 -1
- package/storybook-static/assets/{DocsRenderer-CFRXHY34-DhHzJiIO.js → DocsRenderer-CFRXHY34-Bc9EPsUI.js} +2 -2
- package/storybook-static/assets/{attributes.test.stories-Gg9LQTEK.js → attributes.test.stories-BtamFQkF.js} +1 -1
- package/storybook-static/assets/{css.test.stories-B_3ltOrx.js → css.test.stories-BfNxLgwr.js} +1 -1
- package/storybook-static/assets/{custom-element-CPnvJnn8.js → custom-element-CnmjNo0g.js} +6 -6
- package/storybook-static/assets/{dom-merge.test.stories-nQxcgLoM.js → dom-merge.test.stories-DxnitrLK.js} +47 -6
- package/storybook-static/assets/entry-preview-BNCt9WBs.js +26 -0
- package/storybook-static/assets/{entry-preview-docs-Dwczwtsc.js → entry-preview-docs-CbF8-81D.js} +2 -2
- package/storybook-static/assets/{external-template.test.stories-DZ-rjnfd.js → external-template.test.stories-BTsww7B0.js} +1 -1
- package/storybook-static/assets/{form.test.stories-DQhPYtMj.js → form.test.stories-DNJFtPJb.js} +1 -1
- package/storybook-static/assets/{frame.canvas-ClTqYyMN.js → frame.canvas-E5n9h6j1.js} +1 -1
- package/storybook-static/assets/{handlers-CLkps6Nz.js → handlers-Dvg8CAeR.js} +1 -1
- package/storybook-static/assets/http-request-BWeEEBkP.js +1 -0
- package/storybook-static/assets/{http-request.stories-jo0f73nw.js → http-request.stories-DgrBNle8.js} +1 -1
- package/storybook-static/assets/{iframe-CZwRpnn9.js → iframe-DiVWehoI.js} +11 -11
- package/storybook-static/assets/{index-Dr4PwNfd.js → index-CGuyH0k-.js} +87 -87
- package/storybook-static/assets/{index-CJQtnF9V.js → index-CdEbhcV9.js} +1 -1
- package/storybook-static/assets/index-DO1nmyvI.js +11 -0
- package/storybook-static/assets/{index-B68YUdzy.js → index-w6iX3YlR.js} +3 -3
- package/storybook-static/assets/{local-storage.test.stories-uA5EKRPf.js → local-storage.test.stories-Hwq80yUr.js} +1 -1
- package/storybook-static/assets/{location-element.test.stories-Cu-6Elcg.js → location-element.test.stories-mEhZzm7x.js} +1 -1
- package/storybook-static/assets/{module-url.test.stories-CD_wusXQ.js → module-url.test.stories-Bj46iT0V.js} +1 -1
- package/storybook-static/assets/{preview-CuCH40jj.js → preview-BjbXcJci.js} +2 -2
- package/storybook-static/assets/{preview-BFlNN3Wj.js → preview-Bn8igYMp.js} +1 -1
- package/storybook-static/assets/{preview-Cm4PPhHS.js → preview-CfuT8gak.js} +1 -1
- package/storybook-static/assets/{set-url.test.stories-CY7B9BVZ.js → set-url.test.stories-hzxLcqmm.js} +1 -1
- package/storybook-static/assets/{slice-events.test.stories-BVnPXm6e.js → slice-events.test.stories-DVyXFRU1.js} +1 -1
- package/storybook-static/assets/{slots.test.stories-Dxsa9KdA.js → slots.test.stories-CS544nS4.js} +1 -1
- package/storybook-static/assets/{version-select.test.stories-Buga1PAa.js → version-select.test.stories-D36nfYBq.js} +1 -1
- package/storybook-static/assets/xslt-conditionals.test.stories-BS1PTIHe.js +633 -0
- package/storybook-static/assets/xslt-for-each.test.stories-CtPS20RK.js +329 -0
- package/storybook-static/assets/xslt-if.test.stories-DcHrAMSY.js +71 -0
- package/storybook-static/demo/a.html +10 -3
- package/storybook-static/demo/a.svg +26 -26
- package/storybook-static/demo/html-template.html +4 -3
- package/storybook-static/demo/s.xml +1 -75
- package/storybook-static/demo/s.xslt +351 -72
- package/storybook-static/demo/s1.xml +3706 -0
- package/storybook-static/iframe.html +2 -2
- package/storybook-static/index.json +1 -1
- package/storybook-static/mockServiceWorker.js +105 -63
- package/storybook-static/project.json +1 -1
- package/storybook-static/sb-addons/essentials-controls-1/manager-bundle.js +69 -66
- package/storybook-static/sb-addons/essentials-docs-3/manager-bundle.js +62 -59
- package/dist/custom-element-6slVaFEs.cjs +0 -97
- package/dist/http-request-DPrY7mGh.cjs +0 -1
- package/storybook-static/assets/attributes.test.stories-CzWkKw0e.js +0 -1
- package/storybook-static/assets/entry-preview-DHVXbf3x.js +0 -26
- package/storybook-static/assets/external-template.test.stories-BivZqBTp.js +0 -1
- package/storybook-static/assets/http-request-DNq59pnj.js +0 -1
- package/storybook-static/assets/index-BwkS7JH_.js +0 -8
- package/storybook-static/assets/module-url.test.stories-CTjUAk3J.js +0 -1
|
@@ -0,0 +1,715 @@
|
|
|
1
|
+
# Semantic Palettes and Action States
|
|
2
|
+
|
|
3
|
+
**Status:** Canonical (v1.0)
|
|
4
|
+
**Last updated:** 2025-12-21
|
|
5
|
+
**Taxonomy placement:** D0. Color (Emotional Palette)
|
|
6
|
+
**Audience:** Design Systems, Product Design, Front-End Engineering
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
CEM uses **color** as the primary channel for communicating, using a **branded palette** to express:
|
|
11
|
+
|
|
12
|
+
- using **branded palette** express
|
|
13
|
+
- **Emotional intent:** what the interface wants the user to feel (trust, danger, creativity, etc.)
|
|
14
|
+
- **Interaction meaning:** what an action will do (primary, destructive, alternate, etc.)
|
|
15
|
+
- **State progression:** how an element's condition changes (default → hover → active → pending)
|
|
16
|
+
|
|
17
|
+
**Companion specs:**
|
|
18
|
+
- **D1. Space & Rhythm** ([`cem-dimension.md`](./cem-dimension.md)) — spacing scale, density modes, and layout gaps
|
|
19
|
+
- **D2. Coupling & Compactness** ([`cem-coupling.md`](./cem-coupling.md)) — density affects perceived color intensity and separability
|
|
20
|
+
- **D3. Shape — Bend** ([`cem-shape.md`](./cem-shape.md)) — rounded shapes soften color impact
|
|
21
|
+
- **D4. Layering** ([`cem-layering.md`](./cem-layering.md)) — tonal shifts for depth perception (recess/lift)
|
|
22
|
+
- **D5. Stroke & Separation** ([`cem-stroke.md`](./cem-stroke.md)) — focus/selection colors; D0 defines hue, D5 defines geometry
|
|
23
|
+
- **D6. Typography** ([`cem-voice-fonts-typography.md`](./cem-voice-fonts-typography.md)) — text contrast requirements
|
|
24
|
+
- **D7. Time & Motion** ([`cem-timing.md`](./cem-timing.md)) — color transition timing
|
|
25
|
+
|
|
26
|
+
## Table of contents
|
|
27
|
+
|
|
28
|
+
1. [Scope](#1-scope)
|
|
29
|
+
2. [Design principles](#2-design-principles)
|
|
30
|
+
3. [Token taxonomy](#3-token-taxonomy)
|
|
31
|
+
4. [Base branded color family](#4-base-branded-color-family)
|
|
32
|
+
5. [Emotional palette](#5-emotional-palette)
|
|
33
|
+
6. [Theme modes](#6-theme-modes)
|
|
34
|
+
7. [Action intent and state tokens](#7-action-intent-and-state-tokens)
|
|
35
|
+
8. [Zebra outline colors](#8-zebra-outline-colors)
|
|
36
|
+
9. [System colors and forced-colors](#9-system-colors-and-forced-colors)
|
|
37
|
+
10. [Component mapping checklist](#10-component-mapping-checklist)
|
|
38
|
+
11. [Accessibility and QA](#11-accessibility-and-qa)
|
|
39
|
+
12. [Implementation guidance](#12-implementation-guidance)
|
|
40
|
+
13. [Governance and versioning](#13-governance-and-versioning)
|
|
41
|
+
14. [Canonical token summary](#14-canonical-token-summary)
|
|
42
|
+
15. [References](#15-references)
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 1. Scope
|
|
47
|
+
|
|
48
|
+
### 1.1 What D0 controls (and what it does not define)
|
|
49
|
+
|
|
50
|
+
D0 (Color) defines:
|
|
51
|
+
|
|
52
|
+
- The **semantic meaning** of color: emotional palette, action intent colors, and state colors.
|
|
53
|
+
- **System/forced-colors mapping** for survivable theming in high-contrast environments.
|
|
54
|
+
- The **color endpoints** used by other dimensions (e.g., zebra stripe *colors*).
|
|
55
|
+
|
|
56
|
+
D0 (Color) does **not** define:
|
|
57
|
+
|
|
58
|
+
- Stroke geometry (ring widths, stripe layout, offsets): see **D5 Stroke**.
|
|
59
|
+
- Spacing/density and hit targets: see **D1 Space & Rhythm**.
|
|
60
|
+
- Layer depth/physical appearance (shadows, blur): see **D4 Layering**.
|
|
61
|
+
- Motion durations/easing: see **D7 Motion**.
|
|
62
|
+
|
|
63
|
+
This spec defines **consumer-semantic color tokens** for CEM:
|
|
64
|
+
|
|
65
|
+
- A compact **branded color family** (`--cem-color-*`) used as implementation substrate.
|
|
66
|
+
- An **emotional palette** (`--cem-palette-*`) that expresses *meaning* in user language (comfort, trust, danger, etc.).
|
|
67
|
+
- **Action intent and state tokens** (`--cem-action-*`) for buttons/steps and other “do something” controls.
|
|
68
|
+
- **Zebra outline colors** (`--cem-zebra-*`) used with D5 Stroke to express selection/focus/target without relying on
|
|
69
|
+
fill.
|
|
70
|
+
- **System/forced-colors integration** so CEM remains accessible and compatible with platform theming.
|
|
71
|
+
|
|
72
|
+
Non-goals:
|
|
73
|
+
|
|
74
|
+
- This document does not define shape/stroke/spacing metrics (see D5 Stroke, D1 Space, etc.).
|
|
75
|
+
- This document does not prescribe a single brand palette; it specifies semantic endpoints and default reference
|
|
76
|
+
mappings.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 2. Design principles
|
|
81
|
+
|
|
82
|
+
### 2.1 Consumer-semantic meaning first
|
|
83
|
+
|
|
84
|
+
Tokens are named for **what the user experiences** (comfort, danger, trust) and for **flow semantics** (primary,
|
|
85
|
+
destructive, selected, pending), rather than for RGB/hex values.
|
|
86
|
+
|
|
87
|
+
### 2.2 State separation is multi-channel
|
|
88
|
+
|
|
89
|
+
CEM intentionally separates meaning across channels:
|
|
90
|
+
|
|
91
|
+
- **Background/fill** for “background-driven” states (default/hover/active/pending/disabled).
|
|
92
|
+
- **Zebra outline** (D5 + `--cem-zebra-*`) for high-salience but non-fill states (focus/target/selected).
|
|
93
|
+
- **Marker/text** for required/indeterminate and other information-bearing states.
|
|
94
|
+
|
|
95
|
+
This avoids overloading color fill and improves accessibility in compact/dense UIs.
|
|
96
|
+
|
|
97
|
+
### 2.3 Forced-colors is first-class
|
|
98
|
+
|
|
99
|
+
### 2.4 Bounded variation (governance by design)
|
|
100
|
+
|
|
101
|
+
To avoid “palette explosion”, D0 constrains variation intentionally:
|
|
102
|
+
|
|
103
|
+
- **Stable semantic set:** emotions and action intents are a fixed vocabulary.
|
|
104
|
+
- **Fixed brightness variants:** branded hues use a small set of variants (`xl`, `l`, `d`, `xd`), not per-component
|
|
105
|
+
shades.
|
|
106
|
+
- **Formulaic state progression:** hover/active/pending are derived via `color-mix()` rather than hand-picked colors.
|
|
107
|
+
- **Theme modes are adapters:** theme modes remap the same semantics; they do not introduce new semantics.
|
|
108
|
+
|
|
109
|
+
### 2.5 Cross-dimension coupling (informative)
|
|
110
|
+
|
|
111
|
+
- **D0 → D4 (Layering):** surface/overlay colors must preserve legibility as layers change.
|
|
112
|
+
- **D0 → D5 (Stroke):** focus/selection meaning is primarily expressed via **outline channels** (zebra) where fill must
|
|
113
|
+
not be relied upon.
|
|
114
|
+
- **D0 → D6 (Typography):** text tokens and weight strategies exist to preserve contrast when fills collapse.
|
|
115
|
+
- **D0 → D7 (Motion):** color changes should align with feedback timing (e.g., hover is immediate; pending is
|
|
116
|
+
persistent).
|
|
117
|
+
|
|
118
|
+
When forced-colors is active, **system colors win**. CEM must preserve semantics using `Canvas`, `CanvasText`,
|
|
119
|
+
`Highlight`, `SelectedItem`, etc., and avoid losing meaning when shadows/glows are dropped by the UA.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 3. Token taxonomy
|
|
124
|
+
|
|
125
|
+
### 3.1 Consumer color vocabulary (informative)
|
|
126
|
+
|
|
127
|
+
**Emotional terms** (what the interface wants the user to feel):
|
|
128
|
+
|
|
129
|
+
| Term | Primary palette token | Typical usage |
|
|
130
|
+
|--------------|------------------------------|-------------------------------------------|
|
|
131
|
+
| comfort | `--cem-palette-comfort` | canvas/surfaces, low-salience backgrounds |
|
|
132
|
+
| calm | `--cem-palette-calm` | subtle affordances, secondary emphasis |
|
|
133
|
+
| trust | `--cem-palette-trust` | primary emphasis, highlights |
|
|
134
|
+
| enthusiasm | `--cem-palette-enthusiasm` | alternate emphasis, “positive energy” |
|
|
135
|
+
| creativity | `--cem-palette-creativity` | exploration, novelty |
|
|
136
|
+
| danger | `--cem-palette-danger` | errors, destructive affordances |
|
|
137
|
+
| conservative | `--cem-palette-conservative` | neutral/disabled, “quiet UI” |
|
|
138
|
+
|
|
139
|
+
**Action terms** (what an action will do):
|
|
140
|
+
|
|
141
|
+
| Term | Intent token prefix | Typical usage |
|
|
142
|
+
|-------------|------------------------------|-------------------------------|
|
|
143
|
+
| primary | `--cem-action-primary-*` | default “go forward” action |
|
|
144
|
+
| explicit | `--cem-action-explicit-*` | strong call-to-action |
|
|
145
|
+
| contextual | `--cem-action-contextual-*` | within-context action |
|
|
146
|
+
| alternate | `--cem-action-alternate-*` | secondary/alternate action |
|
|
147
|
+
| destructive | `--cem-action-destructive-*` | deletion, irreversible change |
|
|
148
|
+
|
|
149
|
+
**State terms** (how condition changes):
|
|
150
|
+
|
|
151
|
+
| State | Channel | Notes |
|
|
152
|
+
|----------------------------|-------------------|------------------------------------------------|
|
|
153
|
+
| disabled/readonly/editable | background + text | subdued progression (see §7.2) |
|
|
154
|
+
| hover/active/pending | background + text | formulaic `color-mix()` progression (see §7.2) |
|
|
155
|
+
| focus/selected/target | outline (zebra) | do not rely on fill alone (see §8) |
|
|
156
|
+
|
|
157
|
+
### 3.2 Token model: branded → emotional → action
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
Branded hues (implementation substrate)
|
|
161
|
+
--cem-color-{hue}-{variant}
|
|
162
|
+
│
|
|
163
|
+
▼
|
|
164
|
+
Emotional palette (semantic contract)
|
|
165
|
+
--cem-palette-{emotion} (+ -x / -text / -text-x)
|
|
166
|
+
│
|
|
167
|
+
▼
|
|
168
|
+
Action intents (consumer-facing API)
|
|
169
|
+
--cem-action-{intent}-{state}-{attribute}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 3.3 Why three layers?
|
|
173
|
+
|
|
174
|
+
- **Brand control:** adjust the branded family without breaking product semantics.
|
|
175
|
+
- **Semantic stability:** emotions/intents remain stable across themes.
|
|
176
|
+
- **Implementation clarity:** components consume action/state endpoints; they do not depend on raw hues.
|
|
177
|
+
|
|
178
|
+
CEM color endpoints are layered:
|
|
179
|
+
|
|
180
|
+
1. **Base branded family (implementation):** `--cem-color-{hue}-{variant}`
|
|
181
|
+
2. **Emotional palette (semantic):** `--cem-palette-{emotion}` and `--cem-palette-{emotion}-text`
|
|
182
|
+
3. **Action tokens (flow semantic):** `--cem-action-{intent}-{state}-{attribute}`
|
|
183
|
+
4. **Zebra outline colors (state channel):** `--cem-zebra-color-0..3` + strip size
|
|
184
|
+
|
|
185
|
+
**Rule:** consumers should theme primarily by adjusting **palette** and (optionally) **base colors**; product code
|
|
186
|
+
should depend on palette/action/zebra endpoints.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 4. Base branded color family
|
|
191
|
+
|
|
192
|
+
### 4.1 Brightness variants (selection guidance)
|
|
193
|
+
|
|
194
|
+
Branded hues are provided in a small, repeatable set of brightness variants:
|
|
195
|
+
|
|
196
|
+
| Variant | Meaning (relative) | Typical role |
|
|
197
|
+
|---------|--------------------|------------------------------------------------------------------------|
|
|
198
|
+
| `xl` | lightest | large surface fills in light schemes; extreme contrast partner in dark |
|
|
199
|
+
| `l` | light | standard surface/intent fill in light schemes |
|
|
200
|
+
| `d` | dark | standard surface/intent fill in dark schemes |
|
|
201
|
+
| `xd` | darkest | extreme contrast partner in light schemes; deep surfaces in dark |
|
|
202
|
+
|
|
203
|
+
### 4.2 Contrast pairing rule of thumb
|
|
204
|
+
|
|
205
|
+
When selecting a safe pairing (especially for text and outlines), prefer **opposite ends**:
|
|
206
|
+
|
|
207
|
+
- On **light** backgrounds (`xl`/`l`): pair with `d` or `xd` for text/outline.
|
|
208
|
+
- On **dark** backgrounds (`d`/`xd`): pair with `l` or `xl` for text/outline.
|
|
209
|
+
|
|
210
|
+
### 4.3 Neutral (grey) exception
|
|
211
|
+
|
|
212
|
+
The neutral/grey family is intentionally smaller (typically `l` + `d`) and is used primarily via the **conservative**
|
|
213
|
+
palette.
|
|
214
|
+
|
|
215
|
+
The base family is a small set of named hues with a few variants. These are **reference values** (from
|
|
216
|
+
`theme-data.xhtml`) and may be overridden by a brand, as long as the semantic palette mappings remain coherent.
|
|
217
|
+
|
|
218
|
+
| Token | Hue | Variant | Hex | Label | Intended use |
|
|
219
|
+
|-------------------------|--------|---------|-----------|--------------------|--------------------------------------------|
|
|
220
|
+
| `--cem-color-blue-xl` | blue | xl | `#faf9fd` | Lightest blue | Comfort/trust emotion (light scene) |
|
|
221
|
+
| `--cem-color-blue-l` | blue | l | `#d7e3ff` | Light blue | Trust palette, attention semantic |
|
|
222
|
+
| `--cem-color-blue-d` | blue | d | `#002f65` | Dark blue | Trust palette (dark theme) |
|
|
223
|
+
| `--cem-color-blue-xd` | blue | xd | `#1a1b1f` | Darkest blue | Comfort/trust emotion (dark scene) |
|
|
224
|
+
| `--cem-color-brown-xl` | brown | xl | `#d7ccc8` | Extra light brown | Conservative palette (light theme) |
|
|
225
|
+
| `--cem-color-brown-l` | brown | l | `#a1887f` | Light brown | Conservative emotion, brand-3 |
|
|
226
|
+
| `--cem-color-brown-d` | brown | d | `#4e342e` | Dark brown | Conservative palette (dark theme) |
|
|
227
|
+
| `--cem-color-brown-xd` | brown | xd | `#3e2723` | Extra dark brown | Conservative palette (dark theme, extreme) |
|
|
228
|
+
| `--cem-color-cyan-xl` | cyan | xl | `#f1fefe` | Extra light cyan | Used for comfort palette (light scenes) |
|
|
229
|
+
| `--cem-color-cyan-l` | cyan | l | `#00fbfb` | Light cyan | Calm palette, creativity accent |
|
|
230
|
+
| `--cem-color-cyan-d` | cyan | d | `#006a6a` | Dark cyan | Calm palette (dark theme) |
|
|
231
|
+
| `--cem-color-cyan-xd` | cyan | xd | `#001010` | Extra dark cyan | Used for comfort palette (dark scenes) |
|
|
232
|
+
| `--cem-color-grey-l` | grey | l | `#f1f1eb` | Light grey | Conservative palette, neutral backgrounds |
|
|
233
|
+
| `--cem-color-grey-d` | grey | d | `#1a1c18` | Dark grey | Conservative palette (dark theme) |
|
|
234
|
+
| `--cem-color-orange-xl` | orange | xl | `#f0f070` | Extra light yellow | Enthusiasm palette (light theme) |
|
|
235
|
+
| `--cem-color-orange-l` | orange | l | `#ffe082` | Light orange | Enthusiasm emotion, brand-2 |
|
|
236
|
+
| `--cem-color-orange-d` | orange | d | `#723600` | Dark orange | Enthusiasm hype (dark theme) |
|
|
237
|
+
| `--cem-color-orange-xd` | orange | xd | `#502400` | Extra dark orange | Enthusiasm palette (dark theme, extreme) |
|
|
238
|
+
| `--cem-color-purple-xl` | purple | xl | `#f3e5f5` | Extra light purple | Creativity palette (light theme) |
|
|
239
|
+
| `--cem-color-purple-l` | purple | l | `#e1bee7` | Light purple | Creativity emotion, brand-1 |
|
|
240
|
+
| `--cem-color-purple-d` | purple | d | `#6a1b9a` | Dark purple | Creativity palette (dark theme) |
|
|
241
|
+
| `--cem-color-purple-xd` | purple | xd | `#4a148c` | Extra dark purple | Creativity palette (dark theme, extreme) |
|
|
242
|
+
| `--cem-color-red-xl` | red | xl | `#ffb4ab` | Extra light red | Danger palette (light theme) |
|
|
243
|
+
| `--cem-color-red-l` | red | l | `#ba1a1a` | Light red | Danger emotion, alert semantic |
|
|
244
|
+
| `--cem-color-red-d` | red | d | `#690005` | Dark red | Danger palette (dark theme) |
|
|
245
|
+
| `--cem-color-red-xd` | red | xd | `#410002` | Extra dark red | Danger palette (dark theme, extreme) |
|
|
246
|
+
|
|
247
|
+
Variant semantics:
|
|
248
|
+
|
|
249
|
+
- `xl` / `l`: light-scene support (surfaces, containers, accents)
|
|
250
|
+
- `d` / `xd`: dark-scene support (surfaces, ink-safe accents)
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## 5. Emotional palette
|
|
255
|
+
|
|
256
|
+
The emotional palette is the **primary semantic contract** for color.
|
|
257
|
+
|
|
258
|
+
Reference mappings (from `theme-data.xhtml`) use `light-dark()` so a single token resolves appropriately for light vs dark schemes.
|
|
259
|
+
|
|
260
|
+
| Token | Role | Light / Dark mapping (reference) | Usage |
|
|
261
|
+
|-------------------------------------|------------------------------|-------------------------------------------|--------------------------------------------------|
|
|
262
|
+
| `--cem-palette-comfort` | Base comfort color | cyan-xl (#f1fefe) / cyan-xd (#001010) | Main canvas/background |
|
|
263
|
+
| `--cem-palette-comfort-x` | Comfort extreme variant | cyan-xd (#001010) / cyan-xl (#f1fefe) | Used in color-mix for state variations |
|
|
264
|
+
| `--cem-palette-comfort-text` | Comfort text color | cyan-xd (#001010) / cyan-xl (#f1fefe) | Primary text on comfort backgrounds |
|
|
265
|
+
| `--cem-palette-comfort-text-x` | Comfort extreme text | cyan-xl (#f1fefe) / cyan-xd (#001010) | Text on extreme variant backgrounds |
|
|
266
|
+
| `--cem-palette-calm` | Base calm color | cyan-l (#00fbfb) / cyan-d (#006a6a) | Foreground elements |
|
|
267
|
+
| `--cem-palette-calm-x` | Calm extreme variant | cyan-d (#006a6a) / cyan-l (#00fbfb) | Inverted calm color |
|
|
268
|
+
| `--cem-palette-calm-text` | Calm text color | Uses comfort-text | Text on calm backgrounds |
|
|
269
|
+
| `--cem-palette-calm-text-x` | Calm extreme text | Uses comfort-text-x | Text on extreme calm backgrounds |
|
|
270
|
+
| `--cem-palette-trust` | Base trust color | blue-l (#d7e3ff) / blue-d (#002f65) | Primary actions, highlights |
|
|
271
|
+
| `--cem-palette-trust-x` | Trust extreme variant | blue-d (#002f65) / blue-l (#d7e3ff) | Darker/lighter trust variation |
|
|
272
|
+
| `--cem-palette-trust-text` | Trust text color | comfort-text / white | Text on trust backgrounds |
|
|
273
|
+
| `--cem-palette-trust-text-x` | Trust extreme text | Uses comfort-text-x | Text on extreme trust backgrounds |
|
|
274
|
+
| `--cem-palette-enthusiasm` | Base enthusiasm color | orange-l (#ffe082) / orange-d (#723600) | Brand-2, alternate actions |
|
|
275
|
+
| `--cem-palette-enthusiasm-x` | Enthusiasm extreme variant | orange-xd (#502400) / orange-xl (#f0f070) | Darker/lighter enthusiasm variation |
|
|
276
|
+
| `--cem-palette-enthusiasm-text` | Enthusiasm text color | comfort-text / white | Text on enthusiasm backgrounds |
|
|
277
|
+
| `--cem-palette-enthusiasm-text-x` | Enthusiasm extreme text | Uses comfort-text-x | Text on extreme enthusiasm backgrounds |
|
|
278
|
+
| `--cem-palette-creativity` | Base creativity color | purple-l (#e1bee7) / purple-d (#6a1b9a) | Brand-1, explicit actions |
|
|
279
|
+
| `--cem-palette-creativity-x` | Creativity extreme variant | purple-d (#6a1b9a) / purple-l (#e1bee7) | Darker/lighter creativity variation |
|
|
280
|
+
| `--cem-palette-creativity-text` | Creativity text color | Uses comfort-text | Text on creativity backgrounds |
|
|
281
|
+
| `--cem-palette-creativity-text-x` | Creativity extreme text | Uses comfort-text-x | Text on extreme creativity backgrounds |
|
|
282
|
+
| `--cem-palette-danger` | Base danger color | red-l (#ba1a1a) / red-d (#690005) | Error messages, destructive actions |
|
|
283
|
+
| `--cem-palette-danger-x` | Danger extreme variant | red-d (#690005) / red-l (#ba1a1a) | Darker/lighter danger variation |
|
|
284
|
+
| `--cem-palette-danger-text` | Danger text color | comfort-text-x / comfort-text | Text on danger backgrounds |
|
|
285
|
+
| `--cem-palette-danger-text-x` | Danger extreme text | Uses orange-xl | High contrast text on extreme danger backgrounds |
|
|
286
|
+
| `--cem-palette-conservative` | Base conservative color | grey-l (#f1f1eb) / grey-d (#1a1c18) | Brand-3, disabled states |
|
|
287
|
+
| `--cem-palette-conservative-x` | Conservative extreme variant | grey-d (#1a1c18) / grey-l (#f1f1eb) | Darker/lighter conservative variation |
|
|
288
|
+
| `--cem-palette-conservative-text` | Conservative text color | Uses comfort-text | Text on conservative backgrounds |
|
|
289
|
+
| `--cem-palette-conservative-text-x` | Conservative extreme text | Uses comfort-text-x | Text on extreme conservative backgrounds |
|
|
290
|
+
|
|
291
|
+
### 5.1 Semantics of the core emotions
|
|
292
|
+
|
|
293
|
+
- **comfort:** neutral surface/canvas
|
|
294
|
+
- **calm:** low-salience affordances, calm emphasis
|
|
295
|
+
- **trust:** primary emphasis, highlight, “go forward”
|
|
296
|
+
- **enthusiasm:** alternate/secondary positive emphasis
|
|
297
|
+
- **creativity:** explicit action affordance (the button you press)
|
|
298
|
+
- **danger:** errors and destructive actions
|
|
299
|
+
- **conservative:** low-emphasis/disabled/brand-3 support
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## 6. Theme modes
|
|
304
|
+
|
|
305
|
+
CEM defines 5 operational modes for color behavior:
|
|
306
|
+
|
|
307
|
+
- `native`: rely on system colors (`Canvas`, `CanvasText`, etc.)
|
|
308
|
+
- `light`: branded palette in light scheme
|
|
309
|
+
- `dark`: branded palette in dark scheme
|
|
310
|
+
- `contrast-light`: minimize fill differences; emphasize outlines/markers
|
|
311
|
+
- `contrast-dark`: same, in dark scheme
|
|
312
|
+
|
|
313
|
+
**Normative expectations:**
|
|
314
|
+
|
|
315
|
+
- `native` MUST preserve meaning using system semantic colors (no hard-coded hex assumptions).
|
|
316
|
+
- `contrast-*` MUST NOT encode state primarily via background darkness; state must remain legible via zebra outline and
|
|
317
|
+
markers.
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## 7. Action intent and state tokens
|
|
322
|
+
|
|
323
|
+
Action tokens encode **user-flow intent** (primary, explicit, destructive, etc.) and **interaction/state**.
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
### 7.0 Visual reference: emotional palette gradations (light theme)
|
|
327
|
+
|
|
328
|
+

|
|
329
|
+
|
|
330
|
+
**Supplemental title:** Light theme — Emotional palette gradations across interaction states (action intents).
|
|
331
|
+
|
|
332
|
+
Notes (interpretation):
|
|
333
|
+
- The base color aligns with the `default` state row.
|
|
334
|
+
- As interaction escalates (hover → active → pending), tones shift toward the extreme variant (`*-x`) for higher salience.
|
|
335
|
+
- The upward direction ends in neutral/gray for `disabled`, preserving “less available” semantics.
|
|
336
|
+
|
|
337
|
+
### 7.1 Action intent mapping (reference)
|
|
338
|
+
|
|
339
|
+
| Action intent | Emotional palette | Branded (light) | Branded (dark) | Primary token |
|
|
340
|
+
|---------------|-------------------|--------------------|--------------------|-----------------------------------------------|
|
|
341
|
+
| `explicit` | `creativity` | purple-l (#e1bee7) | purple-d (#6a1b9a) | `--cem-action-explicit-default-background` |
|
|
342
|
+
| `primary` | `trust` | blue-l (#d7e3ff) | blue-d (#002f65) | `--cem-action-primary-default-background` |
|
|
343
|
+
| `contextual` | `comfort` | cyan-xl (#f1fefe) | cyan-xd (#001010) | `--cem-action-contextual-default-background` |
|
|
344
|
+
| `alternate` | `enthusiasm` | orange-l (#ffe082) | orange-d (#723600) | `--cem-action-alternate-default-background` |
|
|
345
|
+
| `destructive` | `danger` | red-l (#ba1a1a) | red-d (#690005) | `--cem-action-destructive-default-background` |
|
|
346
|
+
|
|
347
|
+
### 7.2 Canonical state model
|
|
348
|
+
|
|
349
|
+
CEM action states (union of form/action semantics and interaction semantics):
|
|
350
|
+
|
|
351
|
+
- `disabled`
|
|
352
|
+
- `readonly`
|
|
353
|
+
- `editable`
|
|
354
|
+
- `required`
|
|
355
|
+
- `default`
|
|
356
|
+
- `indeterminate`
|
|
357
|
+
- `target`
|
|
358
|
+
- `focus`
|
|
359
|
+
- `hover`
|
|
360
|
+
- `selected`
|
|
361
|
+
- `active`
|
|
362
|
+
- `pending`
|
|
363
|
+
|
|
364
|
+
State progression is defined as a **formulaic** movement from “least emphasized” to “most emphasized”, using
|
|
365
|
+
`color-mix()` against the emotion’s extreme variant (`--cem-palette-{emotion}-x`).
|
|
366
|
+
|
|
367
|
+
#### 7.2.1 Background-driven states
|
|
368
|
+
|
|
369
|
+
```
|
|
370
|
+
disabled → readonly → editable → default → indeterminate → hover → active → pending
|
|
371
|
+
(30%) (80%) (90%) (base) (90%) (60%) (25%) (5%)
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
- Percentages are **weights of the base emotion** mixed toward an “extreme” anchor.
|
|
375
|
+
- For **disabled**, the anchor is the conservative extreme (`--cem-palette-conservative-x`) to desaturate and quiet the
|
|
376
|
+
UI.
|
|
377
|
+
|
|
378
|
+
#### 7.2.2 State formulas (normative)
|
|
379
|
+
|
|
380
|
+
| State | Background formula (palette-level) | Text token |
|
|
381
|
+
|---------------|-------------------------------------------------------------------------------------------|-------------------------------------|
|
|
382
|
+
| disabled | `color-mix(in srgb, var(--cem-palette-{emotion}) 30%, var(--cem-palette-conservative-x))` | `--cem-palette-conservative-text-x` |
|
|
383
|
+
| readonly | `color-mix(in srgb, var(--cem-palette-{emotion}) 80%, var(--cem-palette-{emotion}-x))` | `--cem-palette-{emotion}-text` |
|
|
384
|
+
| editable | `color-mix(in srgb, var(--cem-palette-{emotion}) 90%, var(--cem-palette-{emotion}-x))` | `--cem-palette-{emotion}-text` |
|
|
385
|
+
| default | `var(--cem-palette-{emotion})` | `--cem-palette-{emotion}-text` |
|
|
386
|
+
| indeterminate | `color-mix(in srgb, var(--cem-palette-{emotion}) 90%, var(--cem-palette-{emotion}-x))` | `--cem-palette-{emotion}-text` |
|
|
387
|
+
| hover | `color-mix(in srgb, var(--cem-palette-{emotion}) 60%, var(--cem-palette-{emotion}-x))` | `--cem-palette-{emotion}-text` |
|
|
388
|
+
| active | `color-mix(in srgb, var(--cem-palette-{emotion}) 25%, var(--cem-palette-{emotion}-x))` | `--cem-palette-{emotion}-text-x` |
|
|
389
|
+
| pending | `color-mix(in srgb, var(--cem-palette-{emotion}) 5%, var(--cem-palette-{emotion}-x))` | `--cem-palette-{emotion}-text-x` |
|
|
390
|
+
|
|
391
|
+
**Applying this to action intents:** substitute `{emotion}` with the emotional palette mapped by the intent (see §7.1).
|
|
392
|
+
The resulting values populate `--cem-action-{intent}-{state}-background` and `--cem-action-{intent}-{state}-text`.
|
|
393
|
+
|
|
394
|
+
#### 7.2.3 Outline-driven states
|
|
395
|
+
|
|
396
|
+
`focus`, `selected`, and `target` are primarily expressed through the **zebra outline channel** (§8). Background tokens
|
|
397
|
+
MAY remain at `default` for these states; do not rely on fill alone.
|
|
398
|
+
|
|
399
|
+
### 7.3 Attribute channels
|
|
400
|
+
|
|
401
|
+
Action state can affect these channels (the set varies by state):
|
|
402
|
+
|
|
403
|
+
- `background` (fill)
|
|
404
|
+
- `text` (ink on fill)
|
|
405
|
+
- `outline` (via zebra / stroke tokens)
|
|
406
|
+
- `marker` (required star, etc.)
|
|
407
|
+
- `font` (weight/face, see Typography spec)
|
|
408
|
+
|
|
409
|
+
### 7.4 Minimal required action endpoints
|
|
410
|
+
|
|
411
|
+
To render functional UIs, the following endpoints are REQUIRED per action intent:
|
|
412
|
+
|
|
413
|
+
- `--cem-action-{intent}-default-background`
|
|
414
|
+
- `--cem-action-{intent}-default-text`
|
|
415
|
+
- `--cem-action-{intent}-hover-background`
|
|
416
|
+
- `--cem-action-{intent}-hover-text`
|
|
417
|
+
- `--cem-action-{intent}-active-background`
|
|
418
|
+
- `--cem-action-{intent}-active-text`
|
|
419
|
+
- `--cem-action-{intent}-disabled-background`
|
|
420
|
+
- `--cem-action-{intent}-disabled-text`
|
|
421
|
+
- `--cem-action-{intent}-selected-background`
|
|
422
|
+
- `--cem-action-{intent}-selected-text`
|
|
423
|
+
|
|
424
|
+
Other states (`focus`, `target`, `pending`, `required`, `indeterminate`, `readonly`, `editable`) are RECOMMENDED, and
|
|
425
|
+
may be implemented through zebra/markers rather than fill.
|
|
426
|
+
|
|
427
|
+
### 7.5 Contrast themes: collapse fills, keep semantics
|
|
428
|
+
|
|
429
|
+
In `contrast-light` and `contrast-dark`, background tokens SHOULD converge on the base surface (
|
|
430
|
+
`--cem-palette-comfort`), with state primarily expressed via:
|
|
431
|
+
|
|
432
|
+
- zebra outline strip colors (`--cem-zebra-color-*`)
|
|
433
|
+
- markers (required/indeterminate)
|
|
434
|
+
- typography deltas (weight/decoration), if needed
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
### 7.6 Implementation guidance (non-normative)
|
|
439
|
+
|
|
440
|
+
**Deriving state backgrounds from palette (example):**
|
|
441
|
+
|
|
442
|
+
```css
|
|
443
|
+
/* Example: primary intent is mapped to trust */
|
|
444
|
+
:root {
|
|
445
|
+
--cem-action-primary-default-background: var(--cem-palette-trust);
|
|
446
|
+
--cem-action-primary-default-text: var(--cem-palette-trust-text);
|
|
447
|
+
|
|
448
|
+
--cem-action-primary-hover-background: color-mix(in srgb, var(--cem-palette-trust) 60%, var(--cem-palette-trust-x));
|
|
449
|
+
--cem-action-primary-hover-text: var(--cem-palette-trust-text);
|
|
450
|
+
|
|
451
|
+
--cem-action-primary-active-background: color-mix(in srgb, var(--cem-palette-trust) 25%, var(--cem-palette-trust-x));
|
|
452
|
+
--cem-action-primary-active-text: var(--cem-palette-trust-text-x);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/* Focus should be expressed via zebra outlines (D5), not by fill alone */
|
|
456
|
+
.button:focus-visible { outline-color: var(--cem-zebra-color-1); }
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
**Framework adapters (illustrative, not normative):**
|
|
460
|
+
|
|
461
|
+
| CEM semantic | MUI (conceptual) | Angular Material (conceptual) |
|
|
462
|
+
|------------------------------|-----------------------------------|-----------------------------------------|
|
|
463
|
+
| `--cem-action-primary-*` | `palette.primary.*` | `primary` |
|
|
464
|
+
| `--cem-action-destructive-*` | `palette.error.*` | `warn` |
|
|
465
|
+
| `--cem-action-alternate-*` | `palette.secondary.*` (or custom) | `accent` (or custom) |
|
|
466
|
+
| zebra focus/selected/target | focus ring / outline styles | focus indicator / ripple-outline styles |
|
|
467
|
+
|
|
468
|
+
## 8. Zebra outline colors
|
|
469
|
+
|
|
470
|
+
### 8.1 Outline-driven state mapping (zebra)
|
|
471
|
+
|
|
472
|
+
| State | Zebra stripe | Recommended meaning |
|
|
473
|
+
|----------|-----------------------|--------------------------------------|
|
|
474
|
+
| focus | `--cem-zebra-color-1` | keyboard focus visibility |
|
|
475
|
+
| selected | `--cem-zebra-color-2` | selection / checked / chosen |
|
|
476
|
+
| target | `--cem-zebra-color-3` | navigation target / guided attention |
|
|
477
|
+
|
|
478
|
+
See D5 Stroke for zebra geometry (stripe order, offsets, and ring widths).
|
|
479
|
+
|
|
480
|
+
Zebra is a **striped outline** (implemented in D5 Stroke) with four semantic strips.
|
|
481
|
+
|
|
482
|
+
Color endpoints:
|
|
483
|
+
|
|
484
|
+
- `--cem-zebra-color-0`: innermost stripe (base surface)
|
|
485
|
+
- `--cem-zebra-color-1`: focus stripe
|
|
486
|
+
- `--cem-zebra-color-2`: selection stripe
|
|
487
|
+
- `--cem-zebra-color-3`: target stripe
|
|
488
|
+
- `--cem-zebra-strip-size`: stripe thickness basis (pairs with D5 stroke widths)
|
|
489
|
+
|
|
490
|
+
Rules:
|
|
491
|
+
|
|
492
|
+
- Zebra colors MUST remain distinguishable from the adjacent surface in all modes.
|
|
493
|
+
- Zebra MUST remain meaningful in forced-colors; in `native` this is achieved by mapping to system colors.
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## 9. System colors and forced-colors
|
|
498
|
+
|
|
499
|
+
### 9.1 Native/system palette mapping
|
|
500
|
+
|
|
501
|
+
In `native` mode, palette endpoints SHOULD map to system colors:
|
|
502
|
+
|
|
503
|
+
- `--cem-palette-comfort`: `Canvas`
|
|
504
|
+
- `--cem-palette-comfort-text`: `CanvasText`
|
|
505
|
+
- `--cem-palette-trust`: `Highlight`
|
|
506
|
+
- `--cem-palette-trust-text`: `HighlightText`
|
|
507
|
+
- `--cem-zebra-color-2`: `SelectedItem` (or fallback to trust)
|
|
508
|
+
|
|
509
|
+
### 9.2 Forced colors
|
|
510
|
+
|
|
511
|
+
When `@media (forced-colors: active)` is true:
|
|
512
|
+
|
|
513
|
+
- Prefer system colors (`Canvas`, `CanvasText`, `Highlight`, `SelectedItem`) over authored colors.
|
|
514
|
+
- Avoid relying on `box-shadow`/glow as a sole state indicator (UAs commonly drop or adjust it).
|
|
515
|
+
- Use outline/zebra and semantic system colors to preserve state visibility.
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
## 10. Component mapping checklist
|
|
520
|
+
|
|
521
|
+
Use this as a quick “did we wire tokens correctly?” checklist.
|
|
522
|
+
|
|
523
|
+
### 10.1 Actions
|
|
524
|
+
|
|
525
|
+
- [ ] Buttons (primary): `--cem-action-primary-*`
|
|
526
|
+
- [ ] Buttons (explicit): `--cem-action-explicit-*`
|
|
527
|
+
- [ ] Toolbar/menu actions (contextual): `--cem-action-contextual-*`
|
|
528
|
+
- [ ] Secondary actions (alternate): `--cem-action-alternate-*`
|
|
529
|
+
- [ ] Destructive: `--cem-action-destructive-*`
|
|
530
|
+
|
|
531
|
+
### 10.2 Inputs and selection controls
|
|
532
|
+
|
|
533
|
+
- [ ] Text fields use comfort surface; state uses zebra/underline + `readonly/editable/required`
|
|
534
|
+
- [ ] Checkboxes/radios reflect `selected` and `indeterminate` distinctly
|
|
535
|
+
- [ ] Targeted elements (`:target`) use target zebra strip
|
|
536
|
+
|
|
537
|
+
### 10.3 Informational semantics
|
|
538
|
+
|
|
539
|
+
- [ ] Errors use `--cem-palette-danger` + `--cem-palette-danger-text`
|
|
540
|
+
- [ ] Highlights use `--cem-palette-trust`
|
|
541
|
+
- [ ] Low-emphasis/disabled uses `--cem-palette-conservative`
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
545
|
+
## 11. Accessibility and QA
|
|
546
|
+
|
|
547
|
+
### 11.1 Contrast requirements (normative)
|
|
548
|
+
|
|
549
|
+
| Element | Minimum ratio |
|
|
550
|
+
|-------------------------------------|------------------------------|
|
|
551
|
+
| Body text on background | ≥4.5:1 |
|
|
552
|
+
| Large text (≥18pt or ≥14pt bold) | ≥3:1 |
|
|
553
|
+
| UI components and graphical objects | ≥3:1 |
|
|
554
|
+
| Focus indicators | ≥3:1 against adjacent colors |
|
|
555
|
+
|
|
556
|
+
### 11.2 QA checklist (done-ness)
|
|
557
|
+
|
|
558
|
+
- Verify **theme switching** (light/dark/contrast/native) does not change semantics (only mappings).
|
|
559
|
+
- Verify all **action intents** have complete state endpoints (default/hover/active/disabled/selected).
|
|
560
|
+
- Verify **zebra focus/selection/target** remains visible across surfaces and in forced-colors.
|
|
561
|
+
- Verify **pending** is perceivable without relying on hue alone (may require motion per D7).
|
|
562
|
+
- Verify **color-blind resilience**: state remains distinguishable via outline/pattern/label/shape.
|
|
563
|
+
|
|
564
|
+
Minimum QA expectations:
|
|
565
|
+
|
|
566
|
+
- Contrast: text-on-background combinations MUST meet your target WCAG level for the corresponding text size.
|
|
567
|
+
- Focus visibility: keyboard focus MUST be detectable without color-fill changes (zebra/outline required).
|
|
568
|
+
- Forced-colors: verify key flows with forced-colors enabled (Windows High Contrast / similar).
|
|
569
|
+
- Color-blindness: verify that state is still perceivable via non-hue channels (outline thickness, pattern, marker).
|
|
570
|
+
|
|
571
|
+
---
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
### 11.3 Color-blind resilience and redundancy (normative)
|
|
575
|
+
|
|
576
|
+
- Meaning MUST NOT rely on hue alone. Any state with user impact (error, destructive, focus, selection, pending) MUST also be conveyed via at least one of:
|
|
577
|
+
- text (label or status copy)
|
|
578
|
+
- iconography
|
|
579
|
+
- outline/pattern (e.g., zebra ring), or
|
|
580
|
+
- shape/position change (where appropriate).
|
|
581
|
+
- Implementations SHOULD test common color-vision deficiencies (e.g., deuteranopia and protanopia) and verify that state progression remains distinguishable.
|
|
582
|
+
|
|
583
|
+
### 11.4 Motion sensitivity (normative)
|
|
584
|
+
|
|
585
|
+
- Theme transitions and state transitions SHOULD respect `prefers-reduced-motion` (see D7).
|
|
586
|
+
- Instant color changes are acceptable; animated gradients and long “breathing” color loops SHOULD NOT be required to understand state.
|
|
587
|
+
## 12. Implementation guidance
|
|
588
|
+
|
|
589
|
+
### 12.1 Recommended layering: branded → emotional → action
|
|
590
|
+
|
|
591
|
+
Implementations SHOULD preserve the three-layer model:
|
|
592
|
+
|
|
593
|
+
1) **Branded hues** (`--cem-color-*`) — implementation substrate (brand-controlled)
|
|
594
|
+
2) **Emotional palette** (`--cem-palette-*`) — semantic contract (theme-adaptive via `light-dark()`)
|
|
595
|
+
3) **Action intents** (`--cem-action-*`) — product-facing API (derived state progression via `color-mix()`)
|
|
596
|
+
|
|
597
|
+
### 12.2 Derivation pattern (illustrative CSS)
|
|
598
|
+
|
|
599
|
+
```css
|
|
600
|
+
:root {
|
|
601
|
+
/* Emotional palette (example) */
|
|
602
|
+
--cem-palette-trust: light-dark(var(--cem-color-blue-l), var(--cem-color-blue-d));
|
|
603
|
+
--cem-palette-trust-x: light-dark(var(--cem-color-blue-d), var(--cem-color-blue-l));
|
|
604
|
+
--cem-palette-trust-text: light-dark(var(--cem-color-blue-d), white);
|
|
605
|
+
--cem-palette-trust-text-x: light-dark(var(--cem-color-blue-xl), var(--cem-color-blue-xl));
|
|
606
|
+
|
|
607
|
+
/* Primary intent mapped to trust */
|
|
608
|
+
--cem-action-primary-default-background: var(--cem-palette-trust);
|
|
609
|
+
--cem-action-primary-default-text: var(--cem-palette-trust-text);
|
|
610
|
+
|
|
611
|
+
--cem-action-primary-hover-background: color-mix(in srgb, var(--cem-palette-trust) 60%, var(--cem-palette-trust-x));
|
|
612
|
+
--cem-action-primary-hover-text: var(--cem-palette-trust-text);
|
|
613
|
+
|
|
614
|
+
--cem-action-primary-active-background: color-mix(in srgb, var(--cem-palette-trust) 25%, var(--cem-palette-trust-x));
|
|
615
|
+
--cem-action-primary-active-text: var(--cem-palette-trust-text-x);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
@media (forced-colors: active) {
|
|
619
|
+
:root {
|
|
620
|
+
--cem-palette-comfort: Canvas;
|
|
621
|
+
--cem-palette-comfort-text: CanvasText;
|
|
622
|
+
--cem-palette-trust: Highlight;
|
|
623
|
+
--cem-palette-trust-text: HighlightText;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### 12.3 Framework mapping (conceptual)
|
|
629
|
+
|
|
630
|
+
| CEM semantic | Material Design 3 (concept) | Angular Material (concept) | MUI (concept) |
|
|
631
|
+
|------------------------------|-------------------------------|-----------------------------|------------------------------------|
|
|
632
|
+
| `--cem-palette-comfort` | `md-sys-color-surface` | `--mat-sys-surface` | `theme.palette.background.default` |
|
|
633
|
+
| `--cem-palette-comfort-text` | `md-sys-color-on-surface` | `--mat-sys-on-surface` | `theme.palette.text.primary` |
|
|
634
|
+
| `--cem-palette-trust` | `md-sys-color-primary` | `--mat-sys-primary` | `theme.palette.primary.main` |
|
|
635
|
+
| `--cem-palette-danger` | `md-sys-color-error` | `--mat-sys-error` | `theme.palette.error.main` |
|
|
636
|
+
| zebra focus/selected/target | focus indicator guidance | focus indicator styles | focus ring / outline styles |
|
|
637
|
+
|
|
638
|
+
### 12.4 Test focus: “semantic survives adapters”
|
|
639
|
+
|
|
640
|
+
In addition to contrast, validate that **semantic meaning remains stable** across:
|
|
641
|
+
|
|
642
|
+
- light/dark
|
|
643
|
+
- contrast-light/contrast-dark
|
|
644
|
+
- `forced-colors: active`
|
|
645
|
+
- density modes (D2), where reduced whitespace increases the importance of outlines/markers.
|
|
646
|
+
|
|
647
|
+
## 13. Governance and versioning
|
|
648
|
+
|
|
649
|
+
Treat as **breaking** (major):
|
|
650
|
+
|
|
651
|
+
- Renaming/removing any `--cem-palette-*`, `--cem-action-*`, or `--cem-zebra-*` canonical endpoint.
|
|
652
|
+
- Changing the semantic meaning of any endpoint (e.g., swapping “trust” and “danger”).
|
|
653
|
+
- Changing the intent↔emotion mapping used for action defaults (e.g., `primary` no longer mapping to `trust`).
|
|
654
|
+
- Changing the meaning or ordering of canonical states (e.g., redefining `active` to be less emphasized than `hover`).
|
|
655
|
+
- Reducing contrast below the normative thresholds stated in §11.1.
|
|
656
|
+
|
|
657
|
+
Treat as **non-breaking** (minor/patch):
|
|
658
|
+
|
|
659
|
+
- Adjusting reference hex values of `--cem-color-*` while preserving semantics.
|
|
660
|
+
- Adding new optional endpoints with clear scope.
|
|
661
|
+
- Clarifying mapping guidance.
|
|
662
|
+
|
|
663
|
+
---
|
|
664
|
+
|
|
665
|
+
## 14. Canonical token summary
|
|
666
|
+
|
|
667
|
+
### 14.1 Required (product contract)
|
|
668
|
+
|
|
669
|
+
**Emotional palette (minimum set):**
|
|
670
|
+
|
|
671
|
+
- `--cem-palette-comfort`, `--cem-palette-comfort-text`
|
|
672
|
+
- `--cem-palette-trust`, `--cem-palette-trust-text`
|
|
673
|
+
- `--cem-palette-danger`, `--cem-palette-danger-text`
|
|
674
|
+
- `--cem-palette-conservative`, `--cem-palette-conservative-text`
|
|
675
|
+
|
|
676
|
+
**Zebra (outline/pattern channel):**
|
|
677
|
+
|
|
678
|
+
- `--cem-zebra-color-0`, `--cem-zebra-color-1`, `--cem-zebra-color-2`, `--cem-zebra-color-3`
|
|
679
|
+
- `--cem-zebra-strip-size`
|
|
680
|
+
|
|
681
|
+
**Actions (per shipped intent):**
|
|
682
|
+
|
|
683
|
+
For each shipped intent (`primary`, `explicit`, `contextual`, `alternate`, `destructive`), the implementation MUST provide at least:
|
|
684
|
+
|
|
685
|
+
- `--cem-action-{intent}-default-background`, `--cem-action-{intent}-default-text`
|
|
686
|
+
- `--cem-action-{intent}-hover-background`, `--cem-action-{intent}-hover-text`
|
|
687
|
+
- `--cem-action-{intent}-active-background`, `--cem-action-{intent}-active-text`
|
|
688
|
+
- `--cem-action-{intent}-disabled-background`, `--cem-action-{intent}-disabled-text`
|
|
689
|
+
- `--cem-action-{intent}-selected-background`, `--cem-action-{intent}-selected-text`
|
|
690
|
+
|
|
691
|
+
### 14.2 Recommended (implementation substrate)
|
|
692
|
+
|
|
693
|
+
- Branded hues: `--cem-color-*` (brand-controlled; used to derive palette tokens)
|
|
694
|
+
- Palette extremes: `--cem-palette-*-x`, `--cem-palette-*-text-x` (required if using formulaic `color-mix()` state progression)
|
|
695
|
+
- Additional emotions: `--cem-palette-calm`, `--cem-palette-enthusiasm`, `--cem-palette-creativity` (recommended where the product uses the corresponding semantics)
|
|
696
|
+
- Additional action states (recommended where applicable): `readonly`, `editable`, `required`, `indeterminate`, `focus`, `target`, `pending`
|
|
697
|
+
|
|
698
|
+
## 15. References
|
|
699
|
+
|
|
700
|
+
### Internal
|
|
701
|
+
|
|
702
|
+
- Action states and visual priority order (EPA-WG `custom-element-dist` discussion #14): https://github.com/EPA-WG/custom-element-dist/discussions/14
|
|
703
|
+
|
|
704
|
+
### External
|
|
705
|
+
|
|
706
|
+
- WCAG 2.2 — Focus Appearance (Minimum): https://www.w3.org/WAI/WCAG22/Understanding/focus-appearance.html
|
|
707
|
+
- WCAG 2.1 — Contrast (Minimum): https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html
|
|
708
|
+
- MDN: `color-mix()`: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color-mix
|
|
709
|
+
- MDN: `light-dark()`: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark
|
|
710
|
+
- MDN: `forced-colors`: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/forced-colors
|
|
711
|
+
- Material Design 3 — Color system overview: https://m3.material.io/styles/color/overview
|
|
712
|
+
|
|
713
|
+
---
|
|
714
|
+
|
|
715
|
+
*This spec is the canonical D0 contract for CEM color semantics.*
|