@epa-wg/custom-element-dist 0.0.33 → 0.0.34
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/.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.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/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 +435 -378
- 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-WnOqmEOe.js → custom-element-BoYMoUtP.js} +193 -183
- package/dist/custom-element-BqtjrCRF.cjs +97 -0
- 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 +3856 -67
- package/dist/demo/s.xslt +13 -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/package.json +2 -2
- 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 +3856 -67
- package/public/demo/s.xslt +13 -72
- package/public/demo/s1.xml +3706 -0
- 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 +3856 -67
- package/src/custom-element/demo/s.xslt +13 -72
- package/src/custom-element/demo/s1.xml +3706 -0
- package/src/custom-element/http-request.js +7 -0
- package/src/custom-element/ide/web-types-dce.json +1 -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-if.test.stories.ts +89 -0
- package/storybook-static/assets/{Color-F6OSRLHC-Cbp293x2.js → Color-F6OSRLHC-CzTOSlqB.js} +1 -1
- package/storybook-static/assets/{Configure-BrFr4SLE.js → Configure-7GqRsAoJ.js} +1 -1
- package/storybook-static/assets/{DocsRenderer-CFRXHY34-DhHzJiIO.js → DocsRenderer-CFRXHY34-Duc5rSIm.js} +2 -2
- package/storybook-static/assets/{attributes.test.stories-Gg9LQTEK.js → attributes.test.stories-DYuxF8h1.js} +1 -1
- package/storybook-static/assets/{css.test.stories-B_3ltOrx.js → css.test.stories-LOmvINyb.js} +1 -1
- package/storybook-static/assets/{custom-element-CPnvJnn8.js → custom-element-Bwx7otrT.js} +6 -6
- package/storybook-static/assets/{dom-merge.test.stories-nQxcgLoM.js → dom-merge.test.stories-CEKhWjaS.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-jHu0wsJ-.js} +1 -1
- package/storybook-static/assets/{form.test.stories-DQhPYtMj.js → form.test.stories-CUyUnmwP.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-F7GUfMqr.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-wyX5-QOv.js} +1 -1
- package/storybook-static/assets/{iframe-CZwRpnn9.js → iframe-BS_DPWl0.js} +11 -11
- package/storybook-static/assets/{index-Dr4PwNfd.js → index-CGuyH0k-.js} +87 -87
- package/storybook-static/assets/{index-CJQtnF9V.js → index-DB7LLObI.js} +1 -1
- package/storybook-static/assets/index-DO1nmyvI.js +11 -0
- package/storybook-static/assets/{index-B68YUdzy.js → index-V1EGs-wm.js} +3 -3
- package/storybook-static/assets/{local-storage.test.stories-uA5EKRPf.js → local-storage.test.stories-BxOhsf1k.js} +1 -1
- package/storybook-static/assets/{location-element.test.stories-Cu-6Elcg.js → location-element.test.stories-DqhvvUoa.js} +1 -1
- package/storybook-static/assets/{module-url.test.stories-CD_wusXQ.js → module-url.test.stories-C1gG9G7Y.js} +1 -1
- package/storybook-static/assets/{preview-BFlNN3Wj.js → preview-Bn8igYMp.js} +1 -1
- package/storybook-static/assets/{preview-CuCH40jj.js → preview-Cwy1XFu2.js} +2 -2
- package/storybook-static/assets/{preview-Cm4PPhHS.js → preview-D6sehqkw.js} +1 -1
- package/storybook-static/assets/{set-url.test.stories-CY7B9BVZ.js → set-url.test.stories-BKQNdknJ.js} +1 -1
- package/storybook-static/assets/{slice-events.test.stories-BVnPXm6e.js → slice-events.test.stories-ChqULCeA.js} +1 -1
- package/storybook-static/assets/{slots.test.stories-Dxsa9KdA.js → slots.test.stories-BlyLoCRe.js} +1 -1
- package/storybook-static/assets/{version-select.test.stories-Buga1PAa.js → version-select.test.stories-CPGSh1tR.js} +1 -1
- package/storybook-static/assets/xslt-conditionals.test.stories-YC6QPqWZ.js +633 -0
- package/storybook-static/assets/xslt-if.test.stories-BRSWy2-x.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 +3856 -67
- package/storybook-static/demo/s.xslt +13 -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/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,343 @@
|
|
|
1
|
+
# CEM ↔ Material Design 3 / Angular Material / MUI Token Parity
|
|
2
|
+
|
|
3
|
+
**Status:** Canonical
|
|
4
|
+
**Last updated:** 2025-12-23
|
|
5
|
+
**Audience:** Design Systems, Product Design, Front-End Engineering
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Intent and positioning
|
|
10
|
+
|
|
11
|
+
CEM is **not** designed to be an in-place replacement for Material Design 3 (M3), Angular Material, or MUI token systems. Instead, CEM defines **consumer-semantic** system endpoints across a **7+3 dimensional framework** (D0–D7 plus D1x/D1y extensions) that are sufficient to build a **functional UI** grounded in CEM principles, while allowing selective adoption of M3/Angular Material/MUI values and conventions via a **mapping/alias layer**.
|
|
12
|
+
|
|
13
|
+
This document records a comprehensive coverage review of the complete CEM spec set:
|
|
14
|
+
|
|
15
|
+
| Dimension | Spec file | Coverage area |
|
|
16
|
+
|-----------|-----------|---------------|
|
|
17
|
+
| D0 | [`cem-colors.md`](./cem-colors.md) | Color — emotional palettes, action intents, state progression, zebra outlines |
|
|
18
|
+
| D1 | [`cem-dimension.md`](./cem-dimension.md) | Space & Rhythm — spacing scale, gaps, insets, gutters, layout rhythm |
|
|
19
|
+
| D1x | [`cem-breakpoints.md`](./cem-breakpoints.md) | Breakpoints — window size classes (compact/medium/expanded/large/xlarge) |
|
|
20
|
+
| D1y | [`cem-responsive.md`](./cem-responsive.md) | Responsiveness — strategy vocabulary (intrinsic/container/breakpoint/hybrid) |
|
|
21
|
+
| D2 | [`cem-coupling.md`](./cem-coupling.md) | Coupling & Compactness — zone/guard/halo, control geometry, density modes |
|
|
22
|
+
| D3 | [`cem-shape.md`](./cem-shape.md) | Shape & Bend — corner radius, bend tokens, semantic endpoints |
|
|
23
|
+
| D4 | [`cem-layering.md`](./cem-layering.md) | Layering — signed 7-tier depth ladder, semantic planes, representation channels |
|
|
24
|
+
| D5 | [`cem-stroke.md`](./cem-stroke.md) | Stroke & Separation — boundaries, dividers, focus/selection/target indicators |
|
|
25
|
+
| D6 | [`cem-voice-fonts-typography.md`](./cem-voice-fonts-typography.md) | Typography — fontography, voice (ink/speech), semantic roles |
|
|
26
|
+
| D7 | [`cem-timing.md`](./cem-timing.md) | Timing & Motion — durations, easings, spring presets |
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 2. M3 coverage matrix
|
|
31
|
+
|
|
32
|
+
Material Design 3 exposes **system tokens** (color/typescale/shape/motion) and **state guidance** (state-layer behaviors, opacities). This section provides a detailed coverage analysis.
|
|
33
|
+
|
|
34
|
+
### 2.1 Color system
|
|
35
|
+
|
|
36
|
+
| M3 token surface | CEM coverage | CEM spec | Notes |
|
|
37
|
+
|------------------|--------------|----------|-------|
|
|
38
|
+
| `md-sys-color-primary` / `-on-primary` | ✓ **Covered** | D0 | `--cem-palette-trust` / `--cem-palette-trust-text` |
|
|
39
|
+
| `md-sys-color-secondary` / `-on-secondary` | ✓ **Covered** | D0 | `--cem-palette-enthusiasm` or `--cem-palette-calm` |
|
|
40
|
+
| `md-sys-color-tertiary` / `-on-tertiary` | ✓ **Covered** | D0 | `--cem-palette-creativity` |
|
|
41
|
+
| `md-sys-color-error` / `-on-error` | ✓ **Covered** | D0 | `--cem-palette-danger` / `--cem-palette-danger-text` |
|
|
42
|
+
| `md-sys-color-surface` / `-on-surface` | ✓ **Covered** | D0 | `--cem-palette-comfort` / `--cem-palette-comfort-text` |
|
|
43
|
+
| `md-sys-color-surface-container-*` (levels) | ✓ **Covered** | D0 + D4 | Surface containers via layering tonal shifts |
|
|
44
|
+
| `md-sys-color-inverse-*` | ✓ **Covered** | D0 | Via `--cem-palette-*-x` extreme variants |
|
|
45
|
+
| State layer opacities (hover/focus/pressed/drag) | ✓ **Covered** | D0 | Formulaic `color-mix()` state progression (§7.2) |
|
|
46
|
+
|
|
47
|
+
**Crosswalk example:**
|
|
48
|
+
```css
|
|
49
|
+
--md-sys-color-primary: var(--cem-palette-trust);
|
|
50
|
+
--md-sys-color-on-primary: var(--cem-palette-trust-text);
|
|
51
|
+
--md-sys-color-error: var(--cem-palette-danger);
|
|
52
|
+
--md-sys-color-surface: var(--cem-palette-comfort);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 2.2 Typography system
|
|
56
|
+
|
|
57
|
+
| M3 token surface | CEM coverage | CEM spec | Notes |
|
|
58
|
+
|------------------|--------------|----------|-------|
|
|
59
|
+
| `md-sys-typescale-display-*` (L/M/S) | ✓ **Covered** | D6 | `--cem-typography-brand-*` semantic role |
|
|
60
|
+
| `md-sys-typescale-headline-*` (L/M/S) | ✓ **Covered** | D6 | Mapped via D6 size scale + voice semantics |
|
|
61
|
+
| `md-sys-typescale-title-*` (L/M/S) | ✓ **Covered** | D6 | `--cem-typography-ui-*` role |
|
|
62
|
+
| `md-sys-typescale-label-*` (L/M/S) | ✓ **Covered** | D6 | `--cem-typography-tag-*` role |
|
|
63
|
+
| `md-sys-typescale-body-*` (L/M/S) | ✓ **Covered** | D6 | `--cem-typography-reading-*` role |
|
|
64
|
+
| Font weight / optical sizing | ✓ **Covered** | D6 | Voice → ink thickness projection |
|
|
65
|
+
| Letter spacing policies | ✓ **Covered** | D6 | `--cem-typography-letter-spacing-*` |
|
|
66
|
+
| Numeric/ligature features | ✓ **Covered** | D6 | `--cem-typography-feature-*` tokens |
|
|
67
|
+
|
|
68
|
+
**CEM differentiation:** CEM defines typography by **semantic role** (reading/ui/tag/data/script/initialism/iconized/brand) rather than M3's size-ladder taxonomy. This provides stronger consumer semantics while supporting M3 value mapping.
|
|
69
|
+
|
|
70
|
+
### 2.3 Shape system
|
|
71
|
+
|
|
72
|
+
| M3 token surface | CEM coverage | CEM spec | Notes |
|
|
73
|
+
|------------------|--------------|----------|-------|
|
|
74
|
+
| `md-sys-shape-corner-none` | ✓ **Covered** | D3 | `--cem-bend-sharp` (0) |
|
|
75
|
+
| `md-sys-shape-corner-extra-small` (4dp) | ✓ **Covered** | D3 | `var(--cem-dim-xx-small)` via adapter |
|
|
76
|
+
| `md-sys-shape-corner-small` (8dp) | ✓ **Covered** | D3 | `--cem-bend-smooth` |
|
|
77
|
+
| `md-sys-shape-corner-medium` (12dp) | ✓ **Covered** | D3 | `--cem-bend-surface` |
|
|
78
|
+
| `md-sys-shape-corner-large` (16dp) | ✓ **Covered** | D3 | `var(--cem-dim-medium)` via adapter |
|
|
79
|
+
| `md-sys-shape-corner-extra-large` (28dp) | ✓ **Covered** | D3 | `--cem-bend-modal` |
|
|
80
|
+
| `md-sys-shape-corner-full` (pill/50%) | ✓ **Covered** | D3 | `--cem-bend-round` (capsule) / `--cem-bend-circle` |
|
|
81
|
+
|
|
82
|
+
**Crosswalk (adapter layer):**
|
|
83
|
+
```css
|
|
84
|
+
--md-sys-shape-corner-none: var(--cem-bend-sharp);
|
|
85
|
+
--md-sys-shape-corner-small: var(--cem-bend-smooth);
|
|
86
|
+
--md-sys-shape-corner-medium: var(--cem-bend-surface);
|
|
87
|
+
--md-sys-shape-corner-extra-large: var(--cem-bend-modal);
|
|
88
|
+
--md-sys-shape-corner-full: var(--cem-bend-round);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 2.4 Elevation / Layering
|
|
92
|
+
|
|
93
|
+
| M3 token surface | CEM coverage | CEM spec | Notes |
|
|
94
|
+
|------------------|--------------|----------|-------|
|
|
95
|
+
| Elevation levels 0–5 | ✓ **Covered** | D4 | Signed 7-tier ladder (recess-2 to elevation-4) |
|
|
96
|
+
| Tonal surface elevation | ✓ **Covered** | D4 | Tone as primary representation channel |
|
|
97
|
+
| Shadow elevation | ✓ **Covered** | D4 | Shadow as secondary representation channel |
|
|
98
|
+
| Surface container tiers | ✓ **Covered** | D4 | `--cem-layer-*` semantic endpoints |
|
|
99
|
+
|
|
100
|
+
**CEM differentiation:** CEM extends M3 elevation with **signed depth** (recess tiers for "behind" semantics) and explicit **representation channels** (tone, contour, shadow, material, space, motion).
|
|
101
|
+
|
|
102
|
+
### 2.5 Motion system
|
|
103
|
+
|
|
104
|
+
| M3 token surface | CEM coverage | CEM spec | Notes |
|
|
105
|
+
|------------------|--------------|----------|-------|
|
|
106
|
+
| Easing: standard | ✓ **Covered** | D7 | `--cem-easing-smooth` (ease-in-out) |
|
|
107
|
+
| Easing: accelerate (ease-in) | ✓ **Covered** | D7 | `--cem-easing-start-smooth` |
|
|
108
|
+
| Easing: decelerate (ease-out) | ✓ **Covered** | D7 | `--cem-easing-end-smooth` |
|
|
109
|
+
| Easing: emphasized | ✓ **Covered** | D7 | `--cem-easing-highlighted*` variants |
|
|
110
|
+
| Duration: short (50-150ms) | ✓ **Covered** | D7 | `--cem-duration-instant` (50ms) |
|
|
111
|
+
| Duration: medium (200-300ms) | ✓ **Covered** | D7 | `--cem-duration-noticeable` (250ms) |
|
|
112
|
+
| Duration: long (300-500ms) | ✓ **Covered** | D7 | `--cem-duration-lingering` (300ms) |
|
|
113
|
+
|
|
114
|
+
**Crosswalk:**
|
|
115
|
+
```css
|
|
116
|
+
--md-sys-motion-easing-standard: var(--cem-easing-smooth);
|
|
117
|
+
--md-sys-motion-easing-emphasized: var(--cem-easing-highlighted);
|
|
118
|
+
--md-sys-motion-duration-short: var(--cem-duration-instant);
|
|
119
|
+
--md-sys-motion-duration-medium: var(--cem-duration-noticeable);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 2.6 State layers
|
|
123
|
+
|
|
124
|
+
| M3 state | Opacity guidance | CEM coverage | CEM mechanism |
|
|
125
|
+
|----------|------------------|--------------|---------------|
|
|
126
|
+
| Hover | 8–16% | ✓ **Covered** | `color-mix()` 60% toward extreme variant (D0 §7.2) |
|
|
127
|
+
| Focus | 12% | ✓ **Covered** | `color-mix()` + zebra outline (D0 + D5) |
|
|
128
|
+
| Pressed | 12–16% | ✓ **Covered** | `color-mix()` 25% toward extreme variant |
|
|
129
|
+
| Drag | 16% | ✓ **Covered** | Pending state (5% toward extreme) |
|
|
130
|
+
| Disabled | 38%/12% | ✓ **Covered** | `color-mix()` 30% toward conservative-x |
|
|
131
|
+
|
|
132
|
+
**CEM differentiation:** CEM uses **formulaic derivation** via `color-mix()` rather than explicit per-state opacity tokens, reducing token surface while maintaining semantic consistency.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 3. Angular Material coverage matrix
|
|
137
|
+
|
|
138
|
+
Angular Material exposes `--mat-sys-*` CSS custom properties that align with M3 tokens.
|
|
139
|
+
|
|
140
|
+
| Angular Material token area | CEM coverage | CEM spec | Notes |
|
|
141
|
+
|----------------------------|--------------|----------|-------|
|
|
142
|
+
| `--mat-sys-primary` / `-on-primary` | ✓ **Covered** | D0 | `--cem-palette-trust` / `-text` |
|
|
143
|
+
| `--mat-sys-surface` / `-on-surface` | ✓ **Covered** | D0 | `--cem-palette-comfort` / `-text` |
|
|
144
|
+
| `--mat-sys-error` / `-on-error` | ✓ **Covered** | D0 | `--cem-palette-danger` / `-text` |
|
|
145
|
+
| `--mat-sys-surface-container-*` | ✓ **Covered** | D0 + D4 | Layering + tonal shift |
|
|
146
|
+
| `--mat-sys-corner-*` | ✓ **Covered** | D3 | `--cem-bend-*` tokens |
|
|
147
|
+
| `--mat-sys-level*` (shadows) | ✓ **Covered** | D4 | Layering shadow channel |
|
|
148
|
+
| `--mat-sys-*-state-layer-opacity` | ✓ **Covered** | D0 | Formulaic `color-mix()` progression |
|
|
149
|
+
| Typography scale (`display/headline/body/label`) | ✓ **Covered** | D6 | Semantic typography roles |
|
|
150
|
+
|
|
151
|
+
**Adapter pattern:**
|
|
152
|
+
```css
|
|
153
|
+
/* Angular Material → CEM mapping */
|
|
154
|
+
--mat-sys-primary: var(--cem-palette-trust);
|
|
155
|
+
--mat-sys-surface: var(--cem-palette-comfort);
|
|
156
|
+
--mat-sys-corner-small: var(--cem-bend-smooth);
|
|
157
|
+
--mat-sys-corner-extra-large: var(--cem-bend-modal);
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## 4. MUI (Material UI) coverage matrix
|
|
163
|
+
|
|
164
|
+
MUI's token surface is primarily the **theme object** with categories including `palette`, `spacing`, `shape`, `typography`, `transitions`, `zIndex`, `breakpoints`, and `shadows`.
|
|
165
|
+
|
|
166
|
+
| MUI area | MUI token surface | CEM coverage | CEM spec | Notes |
|
|
167
|
+
|----------|-------------------|--------------|----------|-------|
|
|
168
|
+
| Palette | `theme.palette.*` + action states | ✓ **Covered** | D0 | Emotional palette + action tokens |
|
|
169
|
+
| Spacing | `theme.spacing()` / 8px unit | ✓ **Covered** | D1 | Dimension scale (4dp increments) |
|
|
170
|
+
| Shape | `theme.shape.borderRadius` | ✓ **Covered** | D3 | `--cem-bend-*` endpoints |
|
|
171
|
+
| Transitions | `theme.transitions.duration/easing` | ✓ **Covered** | D7 | Duration + easing tokens |
|
|
172
|
+
| zIndex | `theme.zIndex.*` ladder | ✓ **Covered** | D4 | Semantic planes (not raw z-index) |
|
|
173
|
+
| Density | component props + spacing | ✓ **Covered** | D2 | Coupling modes (forgiving/balanced/compact) |
|
|
174
|
+
| Typography | `theme.typography.*` variants | ✓ **Covered** | D6 | Semantic roles (reading/ui/tag/data/script) |
|
|
175
|
+
| Shadows | `theme.shadows[]` (25 levels) | ✓ **Covered** | D4 | Layering shadow representation channel |
|
|
176
|
+
| Breakpoints | `theme.breakpoints.*` | ✓ **Covered** | D1x | Window size classes (compact→xlarge) |
|
|
177
|
+
|
|
178
|
+
### 4.1 MUI breakpoint mapping
|
|
179
|
+
|
|
180
|
+
| MUI key | MUI default | CEM range | CEM boundary |
|
|
181
|
+
|---------|-------------|-----------|--------------|
|
|
182
|
+
| `xs` | 0px | `compact` | 0px |
|
|
183
|
+
| `sm` | 600px | `medium` | 600px |
|
|
184
|
+
| `md` | 900px → **840px** | `expanded` | 840px (M3-aligned) |
|
|
185
|
+
| `lg` | 1200px | `large` | 1200px |
|
|
186
|
+
| `xl` | 1536px → **1600px** | `xlarge` | 1600px (M3-aligned) |
|
|
187
|
+
|
|
188
|
+
**Recommended MUI → CEM adapter:**
|
|
189
|
+
```ts
|
|
190
|
+
const theme = createTheme({
|
|
191
|
+
breakpoints: {
|
|
192
|
+
values: {
|
|
193
|
+
xs: 0,
|
|
194
|
+
sm: 600,
|
|
195
|
+
md: 840, // aligned to M3/CEM expanded
|
|
196
|
+
lg: 1200,
|
|
197
|
+
xl: 1600, // aligned to M3/CEM xlarge
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 4.2 MUI z-index → CEM layering
|
|
204
|
+
|
|
205
|
+
| MUI zIndex | MUI value | CEM semantic plane | CEM tier |
|
|
206
|
+
|------------|-----------|-------------------|----------|
|
|
207
|
+
| `mobileStepper` | 1000 | Work | `--cem-elevation-1` |
|
|
208
|
+
| `fab` | 1050 | Floating | `--cem-elevation-2` |
|
|
209
|
+
| `appBar` | 1100 | Work | `--cem-elevation-1` |
|
|
210
|
+
| `drawer` | 1200 | Overlay | `--cem-elevation-3` |
|
|
211
|
+
| `modal` | 1300 | Command | `--cem-elevation-4` |
|
|
212
|
+
| `snackbar` | 1400 | Overlay | `--cem-elevation-3` |
|
|
213
|
+
| `tooltip` | 1500 | Overlay | `--cem-elevation-3` |
|
|
214
|
+
|
|
215
|
+
**CEM note:** D4 defines semantic planes (`back/base/work/overlay/command`) rather than raw z-index values. Implementations create z-index mappings in their adapter layer.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## 5. Coverage summary
|
|
220
|
+
|
|
221
|
+
### 5.1 Full coverage (no gaps)
|
|
222
|
+
|
|
223
|
+
| M3/MUI area | CEM dimension | Status |
|
|
224
|
+
|-------------|---------------|--------|
|
|
225
|
+
| Color system (primary/secondary/tertiary/error/surface) | D0 Color | ✓ Full |
|
|
226
|
+
| State layers (hover/focus/pressed/drag opacities) | D0 Color | ✓ Full (formulaic) |
|
|
227
|
+
| Typography system (typescale roles) | D6 Typography | ✓ Full |
|
|
228
|
+
| Shape system (corner radius scale) | D3 Shape | ✓ Full |
|
|
229
|
+
| Elevation / Layering | D4 Layering | ✓ Full (extended) |
|
|
230
|
+
| Motion (easing + duration) | D7 Timing | ✓ Full |
|
|
231
|
+
| Spacing / Rhythm | D1 Space | ✓ Full |
|
|
232
|
+
| Breakpoints / Responsive | D1x Breakpoints | ✓ Full |
|
|
233
|
+
| Density / Compactness | D2 Coupling | ✓ Full |
|
|
234
|
+
| Focus/Selection indicators | D5 Stroke | ✓ Full |
|
|
235
|
+
|
|
236
|
+
### 5.2 CEM extensions (beyond M3/MUI)
|
|
237
|
+
|
|
238
|
+
CEM provides capabilities not present in standard M3/MUI token systems:
|
|
239
|
+
|
|
240
|
+
| CEM extension | Dimension | Description |
|
|
241
|
+
|---------------|-----------|-------------|
|
|
242
|
+
| **Signed depth (recess)** | D4 | Negative elevation for "behind base" semantics |
|
|
243
|
+
| **Emotional palette semantics** | D0 | Intent-driven colors (comfort/trust/danger/etc.) |
|
|
244
|
+
| **Voice → ink/speech projection** | D6 | Cross-modal typography prominence |
|
|
245
|
+
| **Responsiveness strategy** | D1y | Explicit intrinsic/container/breakpoint/hybrid taxonomy |
|
|
246
|
+
| **Coupling invariants** | D2 | Modality-neutral zone/guard/halo contracts |
|
|
247
|
+
| **Zebra indicator system** | D5 | Multi-stripe focus/selection/target rings |
|
|
248
|
+
| **Formulaic state progression** | D0 | `color-mix()` derivation vs explicit per-state tokens |
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## 6. Practical recommendation (compatibility without diluting CEM)
|
|
253
|
+
|
|
254
|
+
Use a **two-layer approach**:
|
|
255
|
+
|
|
256
|
+
### 6.1 CEM canonical layer
|
|
257
|
+
|
|
258
|
+
CEM tokens remain the normative contract (consumer-semantic endpoints). Product code depends on these.
|
|
259
|
+
|
|
260
|
+
```css
|
|
261
|
+
:root {
|
|
262
|
+
/* Product code uses CEM tokens */
|
|
263
|
+
--button-bg: var(--cem-action-primary-default-background);
|
|
264
|
+
--card-radius: var(--cem-bend-surface);
|
|
265
|
+
--transition: var(--cem-duration-noticeable) var(--cem-easing-smooth);
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### 6.2 Compatibility / alias layer (optional)
|
|
270
|
+
|
|
271
|
+
Provide aliases that map M3/Angular Material/MUI token surfaces to CEM endpoints (or vice versa):
|
|
272
|
+
|
|
273
|
+
```css
|
|
274
|
+
:root {
|
|
275
|
+
/* M3 → CEM aliases */
|
|
276
|
+
--md-sys-color-primary: var(--cem-palette-trust);
|
|
277
|
+
--md-sys-color-on-primary: var(--cem-palette-trust-text);
|
|
278
|
+
--md-sys-color-surface: var(--cem-palette-comfort);
|
|
279
|
+
--md-sys-shape-corner-small: var(--cem-bend-smooth);
|
|
280
|
+
--md-sys-shape-corner-extra-large: var(--cem-bend-modal);
|
|
281
|
+
|
|
282
|
+
/* Angular Material → CEM aliases */
|
|
283
|
+
--mat-sys-primary: var(--cem-palette-trust);
|
|
284
|
+
--mat-sys-corner-small: var(--cem-bend-smooth);
|
|
285
|
+
|
|
286
|
+
/* MUI → CEM mapping in theme */
|
|
287
|
+
/* theme.transitions.duration.shortest = --cem-duration-instant */
|
|
288
|
+
/* theme.shape.borderRadius = --cem-bend-smooth */
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
This approach preserves CEM's semantic guarantees while enabling selective adoption of M3/MUI values and ecosystem integration.
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## 7. Quick adoption checklist
|
|
297
|
+
|
|
298
|
+
1. **Verify D0 color mapping:** emotional palette covers M3 color roles
|
|
299
|
+
2. **Verify D3 shape mapping:** bend endpoints map to M3 corner scale
|
|
300
|
+
3. **Verify D4 layering:** semantic planes cover M3/MUI elevation needs
|
|
301
|
+
4. **Verify D6 typography:** semantic roles cover M3 typescale taxonomy
|
|
302
|
+
5. **Verify D7 timing:** duration/easing tokens map to M3 motion
|
|
303
|
+
6. **Verify D1x breakpoints:** window size classes align with M3/MUI
|
|
304
|
+
7. **Verify D2 coupling:** density modes preserve operability invariants
|
|
305
|
+
8. **Verify D5 stroke:** focus indicators meet WCAG and M3 guidance
|
|
306
|
+
9. **Create adapter layer:** map framework tokens to CEM endpoints
|
|
307
|
+
10. **Validate in forced-colors:** system colors preserve semantics
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## 8. References
|
|
312
|
+
|
|
313
|
+
### Internal CEM specs
|
|
314
|
+
|
|
315
|
+
- [D0. Color (Emotional Palette)](./cem-colors.md)
|
|
316
|
+
- [D1. Space & Rhythm](./cem-dimension.md)
|
|
317
|
+
- [D1x. Breakpoints](./cem-breakpoints.md)
|
|
318
|
+
- [D1y. Responsiveness Strategy](./cem-responsive.md)
|
|
319
|
+
- [D2. Coupling & Compactness](./cem-coupling.md)
|
|
320
|
+
- [D3. Shape & Bend](./cem-shape.md)
|
|
321
|
+
- [D4. Layering](./cem-layering.md)
|
|
322
|
+
- [D5. Stroke & Separation](./cem-stroke.md)
|
|
323
|
+
- [D6. Typography (Voice & Fonts)](./cem-voice-fonts-typography.md)
|
|
324
|
+
- [D7. Timing & Motion](./cem-timing.md)
|
|
325
|
+
|
|
326
|
+
### External references
|
|
327
|
+
|
|
328
|
+
- [Material Design 3 — Design tokens overview](https://m3.material.io/foundations/design-tokens/overview)
|
|
329
|
+
- [Material Design 3 — Color system](https://m3.material.io/styles/color/system/overview)
|
|
330
|
+
- [Material Design 3 — Typography](https://m3.material.io/styles/typography/overview)
|
|
331
|
+
- [Material Design 3 — Shape](https://m3.material.io/styles/shape/shape-scale-tokens)
|
|
332
|
+
- [Material Design 3 — Elevation](https://m3.material.io/styles/elevation/overview)
|
|
333
|
+
- [Material Design 3 — Motion](https://m3.material.io/styles/motion/overview)
|
|
334
|
+
- [Material Design 3 — State layers](https://m3.material.io/foundations/interaction/states/state-layers)
|
|
335
|
+
- [Material Design 3 — Window size classes](https://m3.material.io/foundations/layout/applying-layout/window-size-classes)
|
|
336
|
+
- [Material Web — Theming](https://material-web.dev/theming/material-theming/)
|
|
337
|
+
- [Angular Material — Theming guide](https://material.angular.dev/guide/theming)
|
|
338
|
+
- [MUI — Theming](https://mui.com/material-ui/customization/theming/)
|
|
339
|
+
- [MUI — Breakpoints](https://mui.com/material-ui/customization/breakpoints/)
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
*This spec documents the canonical CEM ↔ M3/Angular Material/MUI parity analysis and adapter guidance.*
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# CEM D1y Responsiveness Strategy — Intrinsic, Container, Breakpoint, Hybrid
|
|
2
|
+
**Status:** Canonical (v1.0)
|
|
3
|
+
**Last updated:** 2025-12-23
|
|
4
|
+
**Taxonomy placement:** D1y. Layout Adaptation Method (orthogonal to D1x Breakpoints)
|
|
5
|
+
**Audience:** Design Systems, Product Design, Front-End Engineering
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
**CEM first rule:** Responsiveness strategy is a **method contract**, not a device contract. Choose the method that best preserves the consumer semantics (readability, separability, coupling invariants) across unpredictable containers and aspect ratios.
|
|
10
|
+
|
|
11
|
+
D1y defines a small vocabulary for *how* a layout adapts:
|
|
12
|
+
- **Intrinsic** (continuous, content-driven)
|
|
13
|
+
- **Container** (component adapts to the space it is placed in)
|
|
14
|
+
- **Breakpoint** (window size class / viewport step changes)
|
|
15
|
+
- **Hybrid** (intrinsic-first + targeted steps)
|
|
16
|
+
|
|
17
|
+
**Companion specs:**
|
|
18
|
+
- **D1x. Breakpoints** ([`cem-breakpoints.md`](./cem-breakpoints.md)) — semantic ranges of available space (compact/medium/expanded/…)
|
|
19
|
+
- **D1. Space & Rhythm** (`cem-dimension.md`) — spacing scale and density modes
|
|
20
|
+
- **D2. Coupling & Compactness** (`cem-coupling.md`) — zone/guard/halo invariants
|
|
21
|
+
- **D5. Stroke & Separation** (`cem-stroke.md`) — separability reinforcement patterns
|
|
22
|
+
- **D6. Typography (Voice & Reading)** (`cem-voice-fonts-typography.md`) — line length and reading constraints
|
|
23
|
+
|
|
24
|
+
## Table of contents
|
|
25
|
+
|
|
26
|
+
1. [Scope](#1-scope)
|
|
27
|
+
2. [Design principles](#2-design-principles)
|
|
28
|
+
3. [Strategy vocabulary](#3-strategy-vocabulary)
|
|
29
|
+
4. [Decision rules](#4-decision-rules)
|
|
30
|
+
5. [Component mapping](#5-component-mapping)
|
|
31
|
+
6. [Implementation patterns](#6-implementation-patterns)
|
|
32
|
+
7. [Governance](#7-governance)
|
|
33
|
+
8. [References](#8-references)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 1. Scope
|
|
38
|
+
|
|
39
|
+
### 1.1 What D1y controls
|
|
40
|
+
|
|
41
|
+
D1y defines:
|
|
42
|
+
|
|
43
|
+
- A **small, stable strategy vocabulary** for layout adaptation.
|
|
44
|
+
- A **decision contract** for when to prefer intrinsic/container-driven behavior vs viewport breakpoints.
|
|
45
|
+
- **Component recipe annotations** (non-CSS) that document the intended strategy.
|
|
46
|
+
|
|
47
|
+
### 1.2 What D1y does not define
|
|
48
|
+
|
|
49
|
+
D1y does **not** define:
|
|
50
|
+
|
|
51
|
+
- Breakpoint boundaries (see **D1x**).
|
|
52
|
+
- Exact grid column counts, track sizing, or spacing (see **D1**).
|
|
53
|
+
- Density minimums (see **D2**).
|
|
54
|
+
- Layering/overlay rules (see **D4**, if present in your system).
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 2. Design principles
|
|
59
|
+
|
|
60
|
+
### 2.1 Orthogonal axes: space vs method
|
|
61
|
+
|
|
62
|
+
- **D1x Breakpoints** classify **available space** (semantic ranges).
|
|
63
|
+
- **D1y Strategy** classifies **adaptation method** (intrinsic/container/breakpoint/hybrid).
|
|
64
|
+
|
|
65
|
+
Do not encode method as a breakpoint value (for example, avoid “responsive” as a breakpoint range).
|
|
66
|
+
|
|
67
|
+
### 2.2 Intrinsic-first posture
|
|
68
|
+
|
|
69
|
+
Prefer **intrinsic** layouts that scale smoothly across widths:
|
|
70
|
+
- Flexbox with wrapping
|
|
71
|
+
- Grid with auto-placement and minimum item sizes
|
|
72
|
+
- Fluid constraints (`min()`, `max()`, `clamp()`)
|
|
73
|
+
|
|
74
|
+
Reserve breakpoints for **meaningful layout archetype changes** (e.g., adding a second pane).
|
|
75
|
+
|
|
76
|
+
### 2.3 Container-first for portable components
|
|
77
|
+
|
|
78
|
+
If a component can appear in multiple regions (cards, sidebars, split panes, embedded widgets), its responsiveness should primarily be **container-driven**, not viewport-driven.
|
|
79
|
+
|
|
80
|
+
### 2.4 Preserve CEM invariants
|
|
81
|
+
|
|
82
|
+
A chosen strategy MUST preserve:
|
|
83
|
+
- **D2 coupling minimums** (targets and guard/halo logic)
|
|
84
|
+
- **D6 readability constraints** (line length and reading rhythm)
|
|
85
|
+
- **D5 separability** under density pressure
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 3. Strategy vocabulary
|
|
90
|
+
|
|
91
|
+
| Strategy | Core idea | Best for | Not ideal for |
|
|
92
|
+
|---|---|---|---|
|
|
93
|
+
| `intrinsic` | Continuous, content-driven adaptation using layout rules | Listings, cards, flowing forms, “works anywhere” components | Major IA shifts requiring explicit pane structure |
|
|
94
|
+
| `container` | Adapt based on container size (`@container`) | Component libraries, split panes, nested layouts | Global navigation shifts that depend on the whole window |
|
|
95
|
+
| `breakpoint` | Adapt based on window size class / viewport | App shell navigation, primary pane topology | Reusable components placed into unknown containers |
|
|
96
|
+
| `hybrid` | Intrinsic-first + targeted steps (viewport or container) | List–detail, data tables, complex dashboards | When either pure intrinsic or pure breakpoint would suffice |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 4. Decision rules
|
|
101
|
+
|
|
102
|
+
### 4.1 Choose `intrinsic` when constraints are sufficient
|
|
103
|
+
|
|
104
|
+
If you can express the behavior as “items have a minimum usable width; layout wraps/reflows automatically,” choose `intrinsic`.
|
|
105
|
+
|
|
106
|
+
A practical indicator: if you are tempted to specify “N columns,” you likely want `intrinsic` with a minimum item size instead.
|
|
107
|
+
|
|
108
|
+
### 4.2 Choose `container` when the host region is the variable
|
|
109
|
+
|
|
110
|
+
If the component’s width depends on placement (sidebar vs main content vs dialog), choose `container`.
|
|
111
|
+
|
|
112
|
+
### 4.3 Choose `breakpoint` when the meaning of layout changes
|
|
113
|
+
|
|
114
|
+
If the layout change is primarily about **information architecture** (pane count, navigation model), choose `breakpoint`.
|
|
115
|
+
|
|
116
|
+
### 4.4 Choose `hybrid` for step-changes inside an intrinsic layout
|
|
117
|
+
|
|
118
|
+
If most of the layout is intrinsic, but there is a clear semantic step (e.g., “show detail pane only when it fits”), choose `hybrid`:
|
|
119
|
+
- `breakpoint` decides when the pane exists
|
|
120
|
+
- intrinsic rules decide how content fills within panes
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 5. Component mapping
|
|
125
|
+
|
|
126
|
+
Use this as a normative annotation target for component recipes.
|
|
127
|
+
|
|
128
|
+
| Component family | Default D1y strategy | Typical query context | Notes |
|
|
129
|
+
|---|---|---|---|
|
|
130
|
+
| App shell navigation | `breakpoint` | Viewport/window | Breakpoint chooses bottom bar vs rail vs drawer. |
|
|
131
|
+
| Split view (master–detail) | `hybrid` | Viewport/window (sometimes container) | Breakpoint decides pane existence; intrinsic rules govern within panes. |
|
|
132
|
+
| Card collections / galleries | `intrinsic` | Container first | Avoid fixed column counts; wrap/auto-place. |
|
|
133
|
+
| Forms and settings pages | `intrinsic` | Container first | Prefer flowing groups; breakpoints only for major regrouping. |
|
|
134
|
+
| Data tables / comparisons | `container` / `hybrid` | Container first | Column visibility/stacking often depends on region size. |
|
|
135
|
+
| Filters / inspector side panels | `container` / `hybrid` | Container first | Region width is the meaningful driver. |
|
|
136
|
+
| Overlays (dialogs/popovers/tooltips) | `intrinsic` | Anchor/container | Size to content and coupling; avoid viewport breakpoints. |
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 6. Implementation patterns
|
|
141
|
+
|
|
142
|
+
### 6.1 Intrinsic Flex wrapping (example)
|
|
143
|
+
|
|
144
|
+
```css
|
|
145
|
+
.listing {
|
|
146
|
+
display: flex;
|
|
147
|
+
flex-wrap: wrap;
|
|
148
|
+
gap: var(--cem-gap-related);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.card {
|
|
152
|
+
flex: 1 1 18rem; /* min usable width */
|
|
153
|
+
max-width: 28rem;
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### 6.2 Intrinsic Grid auto-placement (example)
|
|
158
|
+
|
|
159
|
+
```css
|
|
160
|
+
.gallery {
|
|
161
|
+
display: grid;
|
|
162
|
+
gap: var(--cem-gap-related);
|
|
163
|
+
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 6.3 Container query adaptation (example)
|
|
168
|
+
|
|
169
|
+
```css
|
|
170
|
+
.panel {
|
|
171
|
+
container-type: inline-size;
|
|
172
|
+
container-name: panel;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@container panel (min-width: 42rem) {
|
|
176
|
+
.panel__filters { display: block; }
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### 6.4 Breakpoint / window size class adaptation (example)
|
|
181
|
+
|
|
182
|
+
Use D1x to define when an archetype changes (for example, introducing a second pane). Keep the internal layout intrinsic where possible.
|
|
183
|
+
|
|
184
|
+
### 6.5 Strategy annotation (recommended, non-CSS)
|
|
185
|
+
|
|
186
|
+
Because CSS custom properties are not suitable for expressing enumerated strategies, record strategy as **component-recipe metadata**:
|
|
187
|
+
|
|
188
|
+
```yaml
|
|
189
|
+
component: CardGallery
|
|
190
|
+
cem:
|
|
191
|
+
responsiveStrategy: intrinsic
|
|
192
|
+
queryContext: container
|
|
193
|
+
minItemInlineSize: 14rem
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Adapters MAY use these annotations to:
|
|
197
|
+
- lint against accidental viewport-based rules in container-first components
|
|
198
|
+
- generate documentation
|
|
199
|
+
- enforce consistent strategy use across a library
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 7. Governance
|
|
204
|
+
|
|
205
|
+
### 7.1 Breaking changes (major)
|
|
206
|
+
|
|
207
|
+
Treat as breaking if you:
|
|
208
|
+
|
|
209
|
+
- Rename/remove strategy values (`intrinsic`, `container`, `breakpoint`, `hybrid`).
|
|
210
|
+
- Change the semantics of a strategy value.
|
|
211
|
+
- Require a strategy in places where it was previously advisory (or vice versa), without a migration plan.
|
|
212
|
+
|
|
213
|
+
### 7.2 Non-breaking changes (minor/patch)
|
|
214
|
+
|
|
215
|
+
Treat as non-breaking if you:
|
|
216
|
+
|
|
217
|
+
- Add examples, recipes, or guidance.
|
|
218
|
+
- Add optional annotation fields (for example, `minItemInlineSize`).
|
|
219
|
+
- Clarify decision rules without changing semantics.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## 8. References
|
|
224
|
+
|
|
225
|
+
### External
|
|
226
|
+
|
|
227
|
+
- Material Design 3 — Window size classes: https://m3.material.io/foundations/layout/applying-layout/window-size-classes
|
|
228
|
+
- Android Developers — Use window size classes: https://developer.android.com/develop/ui/compose/layouts/adaptive/use-window-size-classes
|
|
229
|
+
- MDN — CSS container queries: https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Containment/Container_queries
|
|
230
|
+
- MDN — Common grid layouts (responsive without media queries): https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Grid_layout/Common_grid_layouts
|
|
231
|
+
- web.dev — The new responsive (component-driven responsive design): https://web.dev/articles/new-responsive
|
|
232
|
+
- web.dev — Responsive web design basics: https://web.dev/articles/responsive-web-design-basics
|
|
233
|
+
- Material UI — Breakpoints: https://mui.com/material-ui/customization/breakpoints/
|
|
234
|
+
- Material UI — Container queries: https://mui.com/material-ui/customization/container-queries/
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
*This spec defines the canonical CEM vocabulary for responsiveness strategy as an orthogonal axis to breakpoint ranges.*
|