@oods/component-styles 0.3.3 → 0.4.1

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.
@@ -1,5 +1,8 @@
1
1
  @import "@oods/tokens/css";
2
2
  @import "./statusables.css";
3
+ @import "./components-overlay.css";
4
+ @import "./components-combobox.css";
5
+ @import "./components-segmented-control.css";
3
6
 
4
7
  /* Legacy unprefixed geometry used by billing recipes. Values come from the
5
8
  * semantic layer; preserve these names until their authored callers migrate. */
@@ -12,159 +15,313 @@
12
15
  --radius-md: var(--sys-radius-control);
13
16
  }
14
17
 
18
+ /* s222-m01 (#2502 ruling 8): the document root and every brand scope carry the brand's sans and a line height, so no
19
+ * element falls back to the browser's font or its `normal` line height. */
20
+ :where(:root, [data-brand][data-theme]) {
21
+ font-family: var(--sys-font-sans);
22
+ line-height: var(--sys-text-line-height-root);
23
+ -webkit-font-smoothing: antialiased;
24
+ -moz-osx-font-smoothing: grayscale;
25
+ }
26
+
27
+ /* s222-m02 (#2502 ruling 8): a heading inside a component reads on the type scale, never at the browser's default (a
28
+ * bold 24px h2). A component's own rule places its title on a role; any other h1 or h2 is heading-md and h3 to h6
29
+ * heading-sm. The :where() keeps this below every component rule. */
30
+ :where([data-oods-component]) :where(h1, h2) {
31
+ font-size: var(--sys-text-scale-heading-md-font-size, 18px);
32
+ font-weight: var(--sys-text-scale-heading-md-font-weight, 600);
33
+ line-height: var(--sys-text-scale-heading-md-line-height, 24px);
34
+ }
35
+
36
+ :where([data-oods-component]) :where(h3, h4, h5, h6) {
37
+ font-size: var(--sys-text-scale-heading-sm-font-size, 16px);
38
+ font-weight: var(--sys-text-scale-heading-sm-font-weight, 600);
39
+ line-height: var(--sys-text-scale-heading-sm-line-height, 24px);
40
+ }
41
+
42
+ /* s222-m02 (#2502 ruling 11): a badge is a 20px pill, 12/500 with 2px 8px padding, tinted (the tone's step-3 surface
43
+ * and step-11 text) with no border. */
15
44
  :where(.oods-badge, [data-oods-component='Badge']) {
16
45
  display: inline-flex;
17
46
  align-items: center;
18
47
  gap: var(--cmp-badge-gap, 0.25rem);
19
48
  padding: var(--cmp-badge-padding-block, 0.125rem) var(--cmp-badge-padding-inline, 0.5rem);
20
- border: 1px solid var(--cmp-badge-border, var(--cmp-border-default, currentColor));
49
+ border: 0;
21
50
  border-radius: var(--cmp-badge-radius, 999px);
22
51
  background: var(--cmp-badge-background, var(--cmp-surface-subtle, transparent));
23
52
  color: var(--cmp-badge-text, var(--cmp-text-body, currentColor));
24
- font-size: var(--cmp-badge-font-size, 0.875rem);
25
- font-weight: var(--cmp-badge-font-weight, 600);
53
+ font-size: var(--cmp-badge-font-size, 12px);
54
+ font-weight: var(--cmp-badge-font-weight, 500);
26
55
  }
27
56
 
28
- /* Every governed Badge uses the same geometry, including React's legacy statusable class. */
57
+ /* Every governed Badge uses the same geometry, including React's legacy statusable class: the caption role's 16px line
58
+ * and the 2px block padding make the 20px height. */
29
59
  .oods-badge {
30
- min-block-size: var(--cmp-badge-height, 1.5rem);
60
+ min-block-size: var(--cmp-badge-height, 1.25rem);
31
61
  box-sizing: border-box;
32
- font-size: var(--cmp-badge-font-size, 0.875rem);
33
- line-height: var(--sys-text-line-height-tight, 1.2);
62
+ /* s222-m03: a badge hugs its label, also as the item of a stacked (column) layout, which would otherwise stretch it. */
63
+ inline-size: fit-content;
64
+ max-inline-size: 100%;
65
+ font-size: var(--cmp-badge-font-size, 12px);
66
+ line-height: var(--sys-text-scale-caption-line-height, 16px);
34
67
  letter-spacing: normal;
35
68
  text-transform: none;
69
+ white-space: nowrap;
36
70
  gap: var(--cmp-badge-gap, 0.25rem);
37
71
  }
38
72
  /* s221-m02 (#2482 ruling 2): React and Vue render one Badge markup, an icon slot and a label span, styled here; React's
39
- * former statusable-badge classes no longer apply. */
73
+ * former statusable-badge classes no longer apply. s222-m02: a status mark is an SVG drawn in the text colour at the
74
+ * text's size. */
40
75
  .oods-badge__label { display: inline-flex; align-items: center; line-height: inherit; }
41
- .oods-badge__icon { display: inline-flex; align-items: center; font-size: 0.85em; }
76
+ .oods-badge__icon { display: inline-flex; align-items: center; }
77
+ :where(.oods-badge__icon, .oods-banner__icon) > svg { display: block; inline-size: 1em; block-size: 1em; }
78
+
79
+ /* s222-m02 (#2502 ruling 11): a tone paints its tint (step-3 surface, step-11 text; a banner also its step-7 border) and,
80
+ * for emphasis, its solid fill (step 9, darkened until its text passes) with the graded text colour, for badges and banners
81
+ * alike. The tone names are the ones every renderer writes to data-tone, so HTML output needs no inline colours; React and
82
+ * Vue also write the same values inline. */
83
+ :where(.oods-badge, [data-oods-component='Badge'], .oods-banner, [data-oods-component='Banner'])[data-tone='neutral'] {
84
+ --cmp-badge-background: var(--sys-status-neutral-surface);
85
+ --cmp-badge-text: var(--sys-status-neutral-text);
86
+ --cmp-banner-background: var(--sys-status-neutral-surface);
87
+ --cmp-banner-border: var(--sys-status-neutral-border);
88
+ --cmp-banner-text: var(--sys-status-neutral-text);
89
+ --oods-tone-solid: var(--sys-status-neutral-solid);
90
+ --oods-tone-on-solid: var(--sys-status-neutral-on-solid);
91
+ }
92
+
93
+ :where(.oods-badge, [data-oods-component='Badge'], .oods-banner, [data-oods-component='Banner'])[data-tone='info'] {
94
+ --cmp-badge-background: var(--sys-status-info-surface);
95
+ --cmp-badge-text: var(--sys-status-info-text);
96
+ --cmp-banner-background: var(--sys-status-info-surface);
97
+ --cmp-banner-border: var(--sys-status-info-border);
98
+ --cmp-banner-text: var(--sys-status-info-text);
99
+ --oods-tone-solid: var(--sys-status-info-solid);
100
+ --oods-tone-on-solid: var(--sys-status-info-on-solid);
101
+ }
102
+
103
+ :where(.oods-badge, [data-oods-component='Badge'], .oods-banner, [data-oods-component='Banner'])[data-tone='accent'] {
104
+ --cmp-badge-background: var(--sys-status-accent-surface);
105
+ --cmp-badge-text: var(--sys-status-accent-text);
106
+ --cmp-banner-background: var(--sys-status-accent-surface);
107
+ --cmp-banner-border: var(--sys-status-accent-border);
108
+ --cmp-banner-text: var(--sys-status-accent-text);
109
+ --oods-tone-solid: var(--sys-status-accent-solid);
110
+ --oods-tone-on-solid: var(--sys-status-accent-on-solid);
111
+ }
112
+
113
+ :where(.oods-badge, [data-oods-component='Badge'], .oods-banner, [data-oods-component='Banner']):is([data-tone='success'], [data-tone='positive']) {
114
+ --cmp-badge-background: var(--sys-status-success-surface);
115
+ --cmp-badge-text: var(--sys-status-success-text);
116
+ --cmp-banner-background: var(--sys-status-success-surface);
117
+ --cmp-banner-border: var(--sys-status-success-border);
118
+ --cmp-banner-text: var(--sys-status-success-text);
119
+ --oods-tone-solid: var(--sys-status-success-solid);
120
+ --oods-tone-on-solid: var(--sys-status-success-on-solid);
121
+ }
122
+
123
+ :where(.oods-badge, [data-oods-component='Badge'], .oods-banner, [data-oods-component='Banner'])[data-tone='warning'] {
124
+ --cmp-badge-background: var(--sys-status-warning-surface);
125
+ --cmp-badge-text: var(--sys-status-warning-text);
126
+ --cmp-banner-background: var(--sys-status-warning-surface);
127
+ --cmp-banner-border: var(--sys-status-warning-border);
128
+ --cmp-banner-text: var(--sys-status-warning-text);
129
+ --oods-tone-solid: var(--sys-status-warning-solid);
130
+ --oods-tone-on-solid: var(--sys-status-warning-on-solid);
131
+ }
132
+
133
+ :where(.oods-badge, [data-oods-component='Badge'], .oods-banner, [data-oods-component='Banner']):is([data-tone='critical'], [data-tone='danger']) {
134
+ --cmp-badge-background: var(--sys-status-critical-surface);
135
+ --cmp-badge-text: var(--sys-status-critical-text);
136
+ --cmp-banner-background: var(--sys-status-critical-surface);
137
+ --cmp-banner-border: var(--sys-status-critical-border);
138
+ --cmp-banner-text: var(--sys-status-critical-text);
139
+ --oods-tone-solid: var(--sys-status-critical-solid);
140
+ --oods-tone-on-solid: var(--sys-status-critical-on-solid);
141
+ }
42
142
 
43
- /* Solid reverses the already contrast-checked status surface/text pair. */
44
143
  :where(.oods-badge, [data-oods-component='Badge'])[data-emphasis='solid'] {
45
- border-color: var(--cmp-badge-text, var(--sys-status-neutral-text, CanvasText));
46
- background: var(--cmp-badge-text, var(--sys-status-neutral-text, CanvasText));
47
- color: var(--cmp-badge-background, var(--sys-status-neutral-surface, Canvas));
144
+ background: var(--oods-tone-solid, var(--sys-status-neutral-solid, CanvasText));
145
+ color: var(--oods-tone-on-solid, var(--sys-status-neutral-on-solid, Canvas));
48
146
  }
49
147
 
50
148
  :where(.oods-banner, [data-oods-component='Banner'])[data-emphasis='solid'] {
51
- border-color: var(--cmp-banner-text, var(--sys-status-neutral-text, CanvasText));
52
- background: var(--cmp-banner-text, var(--sys-status-neutral-text, CanvasText));
53
- color: var(--cmp-banner-background, var(--sys-status-neutral-surface, Canvas));
149
+ border-color: transparent;
150
+ background: var(--oods-tone-solid, var(--sys-status-neutral-solid, CanvasText));
151
+ color: var(--oods-tone-on-solid, var(--sys-status-neutral-on-solid, Canvas));
54
152
  }
55
153
 
154
+ /* s222-m02 (#2502 ruling 11): a banner reads at the small body size (14/20) with 12px by 16px padding and the large
155
+ * control radius; the tone paints its surface, border and text. */
56
156
  :where(.oods-banner, [data-oods-component='Banner']) {
57
157
  display: grid;
58
158
  grid-template-columns: 1fr auto;
59
159
  gap: var(--cmp-spacing-inline-sm, 0.75rem);
60
- padding: var(--cmp-spacing-inset-default, 1rem);
160
+ padding: var(--sys-inset-sm, 0.75rem) var(--sys-inset-md, 1rem);
61
161
  border: 1px solid var(--cmp-banner-border, var(--cmp-border-default, currentColor));
62
- border-radius: var(--cmp-input-radius, 0.5rem);
162
+ border-radius: var(--sys-radius-control-lg, 8px);
63
163
  background: var(--cmp-banner-background, var(--cmp-surface-subtle, transparent));
64
164
  color: var(--cmp-banner-text, var(--cmp-text-body, currentColor));
165
+ font-size: var(--sys-text-scale-body-sm-font-size, 14px);
166
+ line-height: var(--sys-text-scale-body-sm-line-height, 20px);
65
167
  }
66
168
 
67
169
  /* s221-m02 (#2482 ruling 2): the one Banner markup React and Vue share. A status icon takes its own column; the content
68
170
  * stacks the title, detail, body and actions without paragraph margins. React's former statusable-banner classes, which
69
- * gave React alone a three-column grid, no longer apply. */
171
+ * gave React alone a three-column grid, no longer apply. s222-m02: the icon is a 16px SVG on the title's line. */
70
172
  :where(.oods-banner:has(> .oods-banner__icon)) { grid-template-columns: auto 1fr auto; }
71
- .oods-banner__icon { display: inline-flex; align-items: center; justify-content: center; font-size: 1.25em; }
173
+ .oods-banner__icon { display: inline-flex; align-items: center; justify-content: center; block-size: var(--sys-text-scale-body-sm-line-height, 20px); font-size: var(--sys-control-icon-size, 1rem); }
72
174
  .oods-banner__content { display: grid; align-content: start; gap: var(--sys-control-gap-compact, 0.25rem); min-inline-size: 0; }
73
- .oods-banner__title { font-weight: var(--ref-typography-weights-bold, 700); }
175
+ /* The title is the heading weight in both the current and the earlier Vue class names. */
176
+ :is(.oods-banner__title, .oods-banner-title) { font-weight: var(--sys-text-scale-heading-sm-font-weight, 600); }
74
177
  :is(.oods-banner__detail, .oods-banner__body) { margin: 0; }
75
178
  .oods-banner__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--cmp-spacing-inline-sm, 0.75rem); margin-block-start: var(--sys-control-gap-compact, 0.25rem); }
76
179
 
180
+ /* s222-m02 (#2502 rulings 9 and 11): a button is its control height at every size (xs 24, sm 28, md 32, lg 40), the same
181
+ * block size as the input, select and segmented control beside it, with 8/10/12/16px side padding and the label role's
182
+ * type (12/16 at xs, 14/20 at sm and md, 16/24 at lg; weight 500). The height centres the line, so no block padding sets
183
+ * it. */
77
184
  :where(.oods-button, [data-oods-component='Button']) {
78
- --oods-button-min-block-size: var(--cmp-button-height, 2.5rem);
79
- --oods-button-padding-block: var(--cmp-button-padding-block, 0.625rem);
80
- --oods-button-padding-inline: var(--cmp-button-padding-inline, 1rem);
81
- --oods-button-font-size: var(--sys-text-size-md, 1rem);
185
+ --oods-button-block-size: var(--cmp-button-height, 2rem);
186
+ --oods-button-padding-inline: var(--cmp-button-padding-inline, 0.75rem);
187
+ --oods-button-font-size: var(--sys-text-scale-label-font-size, 14px);
188
+ --oods-button-line-height: var(--sys-text-scale-label-line-height, 20px);
189
+ --oods-button-gap: var(--cmp-button-gap, 0.5rem);
82
190
  display: inline-flex;
83
- min-block-size: var(--oods-button-min-block-size);
191
+ min-block-size: var(--oods-button-block-size);
84
192
  box-sizing: border-box;
85
193
  align-items: center;
86
194
  justify-content: center;
87
- gap: var(--cmp-button-gap, 0.5rem);
88
- padding: var(--oods-button-padding-block) var(--oods-button-padding-inline);
195
+ gap: var(--oods-button-gap);
196
+ padding: var(--oods-button-padding-block, 0) var(--oods-button-padding-inline);
89
197
  border: 1px solid var(--oods-button-border, var(--cmp-button-border, transparent));
90
- border-radius: var(--cmp-button-radius, 0.5rem);
198
+ border-radius: var(--cmp-button-radius, 6px);
91
199
  background: var(--oods-button-background, var(--cmp-button-background, var(--cmp-surface-action, CanvasText)));
92
200
  color: var(--oods-button-text, var(--cmp-button-text, var(--cmp-text-on-action, Canvas)));
93
201
  font: inherit;
94
202
  font-size: var(--oods-button-font-size);
95
- font-weight: var(--cmp-button-font-weight, 600);
96
- line-height: var(--sys-text-line-height-tight, 1.2);
203
+ font-weight: var(--cmp-button-font-weight, 500);
204
+ line-height: var(--oods-button-line-height);
205
+ white-space: nowrap;
206
+ text-decoration: none;
97
207
  cursor: pointer;
98
208
  }
99
209
 
100
- :where(.oods-button, [data-oods-component='Button'])[data-intent='neutral'] {
101
- --oods-button-background: var(--sys-surface-inverse, CanvasText);
102
- --oods-button-background-hover: var(--sys-surface-inverse, CanvasText);
103
- --oods-button-border: var(--sys-surface-inverse, CanvasText);
104
- --oods-button-text: var(--sys-text-inverse, Canvas);
210
+ :where(.oods-button, [data-oods-component='Button']) > svg {
211
+ flex: none;
212
+ inline-size: var(--sys-control-icon-size, 1rem);
213
+ block-size: var(--sys-control-icon-size, 1rem);
214
+ }
215
+
216
+ /* s222-m02 (#2502 ruling 11): the variants. neutral, which a button without an intent also gets, is the outline look, so a
217
+ * screen's primary action is its one solid fill; secondary is the subtle fill (neutral steps 3 to 5); ghost and link carry
218
+ * no fill until hovered; destructive and danger share the destructive fill with its graded text; success and warning keep
219
+ * their status solids. */
220
+ :where(.oods-button, [data-oods-component='Button']):is([data-intent='neutral'], [data-intent='outline'], :not([data-intent])) {
221
+ --oods-button-background: var(--sys-surface-raised, Canvas);
222
+ --oods-button-background-hover: var(--sys-surface-interactive-secondary-default, Canvas);
223
+ --oods-button-background-pressed: var(--sys-surface-interactive-secondary-hover, Canvas);
224
+ --oods-button-border: var(--sys-border-strong, CanvasText);
225
+ --oods-button-text: var(--sys-text-primary, CanvasText);
105
226
  }
106
227
 
107
228
  :where(.oods-button, [data-oods-component='Button'])[data-intent='primary'] {
108
229
  --oods-button-background: var(--sys-surface-interactive-primary-default, CanvasText);
109
230
  --oods-button-background-hover: var(--sys-surface-interactive-primary-hover, CanvasText);
110
- --oods-button-border: var(--sys-surface-interactive-primary-default, CanvasText);
231
+ --oods-button-background-pressed: var(--sys-surface-interactive-primary-pressed, CanvasText);
232
+ --oods-button-border: transparent;
111
233
  --oods-button-text: var(--sys-text-on-interactive, Canvas);
112
234
  }
113
235
 
114
236
  :where(.oods-button, [data-oods-component='Button'])[data-intent='secondary'] {
115
- --oods-button-background: var(--sys-surface-subtle, Canvas);
116
- --oods-button-background-hover: var(--sys-surface-canvas, Canvas);
117
- --oods-button-border: var(--sys-border-strong, CanvasText);
237
+ --oods-button-background: var(--sys-surface-interactive-secondary-default, Canvas);
238
+ --oods-button-background-hover: var(--sys-surface-interactive-secondary-hover, Canvas);
239
+ --oods-button-background-pressed: var(--sys-surface-interactive-secondary-pressed, Canvas);
240
+ --oods-button-border: transparent;
118
241
  --oods-button-text: var(--sys-text-primary, CanvasText);
119
242
  }
120
243
 
121
- :where(.oods-button, [data-oods-component='Button'])[data-intent='success'] {
122
- --oods-button-background: var(--sys-status-success-text, CanvasText);
123
- --oods-button-background-hover: var(--sys-status-success-text, CanvasText);
124
- --oods-button-border: var(--sys-status-success-text, CanvasText);
125
- --oods-button-text: var(--sys-status-success-surface, Canvas);
244
+ :where(.oods-button, [data-oods-component='Button'])[data-intent='ghost'] {
245
+ --oods-button-background: transparent;
246
+ --oods-button-background-hover: var(--sys-surface-interactive-secondary-default, Canvas);
247
+ --oods-button-background-pressed: var(--sys-surface-interactive-secondary-hover, Canvas);
248
+ --oods-button-border: transparent;
249
+ --oods-button-text: var(--sys-text-primary, CanvasText);
126
250
  }
127
251
 
128
- :where(.oods-button, [data-oods-component='Button'])[data-intent='warning'] {
129
- --oods-button-background: var(--sys-status-warning-text, CanvasText);
130
- --oods-button-background-hover: var(--sys-status-warning-text, CanvasText);
131
- --oods-button-border: var(--sys-status-warning-text, CanvasText);
132
- --oods-button-text: var(--sys-status-warning-surface, Canvas);
252
+ :where(.oods-button, [data-oods-component='Button'])[data-intent='link'] {
253
+ --oods-button-background: transparent;
254
+ --oods-button-background-hover: transparent;
255
+ --oods-button-background-pressed: transparent;
256
+ --oods-button-border: transparent;
257
+ --oods-button-text: var(--sys-text-accent, LinkText);
258
+ text-underline-offset: 0.25em;
133
259
  }
134
260
 
135
- :where(.oods-button, [data-oods-component='Button'])[data-intent='danger'] {
136
- --oods-button-background: var(--sys-status-critical-text, CanvasText);
137
- --oods-button-background-hover: var(--sys-status-critical-text, CanvasText);
138
- --oods-button-border: var(--sys-status-critical-text, CanvasText);
139
- --oods-button-text: var(--sys-status-critical-surface, Canvas);
261
+ :where(.oods-button, [data-oods-component='Button'])[data-intent='link']:hover:not(:disabled) { text-decoration: underline; }
262
+
263
+ :where(.oods-button, [data-oods-component='Button']):is([data-intent='destructive'], [data-intent='danger']) {
264
+ --oods-button-background: var(--sys-surface-interactive-destructive-default, CanvasText);
265
+ --oods-button-background-hover: var(--sys-surface-interactive-destructive-hover, CanvasText);
266
+ --oods-button-background-pressed: var(--sys-surface-interactive-destructive-pressed, CanvasText);
267
+ --oods-button-border: transparent;
268
+ --oods-button-text: var(--sys-text-on-destructive, Canvas);
269
+ }
270
+
271
+ :where(.oods-button, [data-oods-component='Button'])[data-intent='success'] {
272
+ --oods-button-background: var(--sys-status-success-solid, CanvasText);
273
+ --oods-button-border: transparent;
274
+ --oods-button-text: var(--sys-status-success-on-solid, Canvas);
275
+ }
276
+
277
+ :where(.oods-button, [data-oods-component='Button'])[data-intent='warning'] {
278
+ --oods-button-background: var(--sys-status-warning-solid, CanvasText);
279
+ --oods-button-border: transparent;
280
+ --oods-button-text: var(--sys-status-warning-on-solid, Canvas);
281
+ }
282
+
283
+ /* Each size rule also sets the type, so a page's own reset (button { font: inherit }, at element specificity) cannot undo
284
+ * the size's label role; the base rule's declarations sit at zero specificity. */
285
+ :where(.oods-button, [data-oods-component='Button'])[data-size='xs'] {
286
+ --oods-button-block-size: var(--sys-control-height-xs, 1.5rem);
287
+ --oods-button-padding-inline: var(--sys-control-padding-inline-xs, 0.5rem);
288
+ --oods-button-font-size: var(--sys-text-scale-caption-font-size, 12px);
289
+ --oods-button-line-height: var(--sys-text-scale-caption-line-height, 16px);
290
+ --oods-button-gap: var(--sys-control-icon-gap-sm, 0.375rem);
291
+ font-size: var(--oods-button-font-size);
292
+ line-height: var(--oods-button-line-height);
140
293
  }
141
294
 
142
295
  :where(.oods-button, [data-oods-component='Button'])[data-size='sm'] {
143
- --oods-button-min-block-size: var(--cmp-button-height-sm, 2rem);
144
- --oods-button-padding-block: var(--cmp-button-padding-block-sm, 0.375rem);
145
- --oods-button-padding-inline: var(--cmp-button-padding-inline-sm, 0.75rem);
146
- --oods-button-font-size: var(--sys-text-size-sm, 0.875rem);
296
+ --oods-button-block-size: var(--cmp-button-height-sm, 1.75rem);
297
+ --oods-button-padding-inline: var(--cmp-button-padding-inline-sm, 0.625rem);
298
+ --oods-button-gap: var(--sys-control-icon-gap-sm, 0.375rem);
147
299
  font-size: var(--oods-button-font-size);
300
+ line-height: var(--oods-button-line-height);
148
301
  }
149
302
 
150
303
  :where(.oods-button, [data-oods-component='Button'])[data-size='md'] {
151
- --oods-button-min-block-size: var(--cmp-button-height, 2.5rem);
152
- --oods-button-padding-block: var(--cmp-button-padding-block, 0.625rem);
153
- --oods-button-padding-inline: var(--cmp-button-padding-inline, 1rem);
154
- --oods-button-font-size: var(--sys-text-size-md, 1rem);
304
+ --oods-button-block-size: var(--cmp-button-height, 2rem);
305
+ --oods-button-padding-inline: var(--cmp-button-padding-inline, 0.75rem);
155
306
  font-size: var(--oods-button-font-size);
307
+ line-height: var(--oods-button-line-height);
156
308
  }
157
309
 
158
310
  :where(.oods-button, [data-oods-component='Button'])[data-size='lg'] {
159
- --oods-button-min-block-size: var(--cmp-button-height-lg, 3rem);
160
- --oods-button-padding-block: var(--cmp-button-padding-block-lg, 0.75rem);
161
- --oods-button-padding-inline: var(--cmp-button-padding-inline-lg, 1.5rem);
162
- --oods-button-font-size: var(--sys-text-size-lg, 1.25rem);
311
+ --oods-button-block-size: var(--cmp-button-height-lg, 2.5rem);
312
+ --oods-button-padding-inline: var(--cmp-button-padding-inline-lg, 1rem);
313
+ --oods-button-font-size: var(--sys-text-scale-body-md-font-size, 16px);
314
+ --oods-button-line-height: var(--sys-text-scale-body-md-line-height, 24px);
163
315
  font-size: var(--oods-button-font-size);
316
+ line-height: var(--oods-button-line-height);
164
317
  }
165
318
 
166
319
  :where(.oods-button, [data-oods-component='Button']):hover:not(:disabled) {
167
- background: var(--oods-button-background-hover, var(--cmp-button-background-hover, var(--cmp-surface-action-hover, CanvasText)));
320
+ background: var(--oods-button-background-hover, var(--oods-button-background, var(--cmp-button-background-hover, CanvasText)));
321
+ }
322
+
323
+ :where(.oods-button, [data-oods-component='Button']):active:not(:disabled) {
324
+ background: var(--oods-button-background-pressed, var(--oods-button-background-hover, var(--oods-button-background, var(--cmp-button-background-hover, CanvasText))));
168
325
  }
169
326
 
170
327
  :where(.oods-button, [data-oods-component='Button']):disabled {
@@ -174,6 +331,12 @@
174
331
  cursor: not-allowed;
175
332
  }
176
333
 
334
+ /* A disabled ghost or link button keeps no fill, as it has none at rest. */
335
+ :where(.oods-button, [data-oods-component='Button']):is([data-intent='ghost'], [data-intent='link']):disabled {
336
+ border-color: transparent;
337
+ background: transparent;
338
+ }
339
+
177
340
  /* One focus treatment for every interactive element, native controls included:
178
341
  * token width, colour and offset. Nothing else in this stylesheet paints focus. */
179
342
  :where(.oods-button, [data-oods-component='Button'], .oods-field-control, .oods-tab, .oods-table-row-action, .oods-collection-row,
@@ -185,16 +348,23 @@
185
348
  outline-offset: var(--cmp-focus-offset, 2px);
186
349
  }
187
350
 
351
+ /* s222-m02 (#2502 rulings 9 and 10): a card is border-only on the raised surface with the card radius and 24px padding;
352
+ * its children stack 16px apart with no browser margins, so its header, body and actions sit on the card's own rhythm. */
188
353
  :where(.oods-card, [data-oods-component='Card']) {
189
- padding: var(--cmp-spacing-inset-default, 1rem);
354
+ display: grid;
355
+ align-content: start;
356
+ gap: var(--sys-stack-md, 1rem);
357
+ padding: var(--sys-card-padding, 1.5rem);
190
358
  border: 1px solid var(--cmp-border-default, var(--sys-border-subtle));
191
359
  border-radius: var(--cmp-card-radius, 0.75rem);
192
360
  background: var(--cmp-surface-panel, var(--sys-surface-raised));
193
361
  color: var(--cmp-text-body, var(--sys-text-primary));
194
362
  }
195
363
 
364
+ :where(.oods-card, [data-oods-component='Card']) > :where(p, h1, h2, h3, h4, h5, h6, ul, ol, dl) { margin: 0; }
365
+
196
366
  :where(.oods-card[data-elevated='true'], [data-oods-component='Card'][data-elevated='true']) {
197
- box-shadow: var(--cmp-card-shadow-offset-x, 0px) var(--cmp-card-shadow-offset-y, 16px) var(--cmp-card-shadow-blur, 40px) var(--cmp-card-shadow-spread, -12px) var(--cmp-card-shadow-color, rgba(15, 23, 42, 0.12));
367
+ box-shadow: var(--cmp-card-shadow-offset-x, 0px) var(--cmp-card-shadow-offset-y, 4px) var(--cmp-card-shadow-blur, 8px) var(--cmp-card-shadow-spread, -4px) var(--cmp-card-shadow-color, rgba(15, 23, 42, 0.12));
198
368
  }
199
369
 
200
370
  /* The tokens build scopes colour per brand and theme; the dark elevation tokens are
@@ -212,38 +382,58 @@
212
382
  --cmp-shadow-overlay-color: var(--theme-dark-shadow-elevation-overlay-color);
213
383
  }
214
384
 
385
+ /* s222-m02 (#2502 ruling 8): headings sit on the type roles. A detail header's title is the page title (heading-xl,
386
+ * 30/36 600) over a 16/24 subtitle and 14/20 metadata; a card header's title is heading-sm (16/24 600) over 14/20
387
+ * supporting text. */
215
388
  :where([data-oods-component='DetailHeader'], [data-oods-component='CardHeader']) {
216
389
  --cmp-header-title: var(--sys-text-primary);
217
390
  --cmp-header-subtitle: var(--sys-text-secondary);
218
391
  --cmp-header-metadata: var(--sys-text-muted);
219
392
  display: grid;
220
- gap: var(--sys-spacing-stack-compact, 0.75rem);
393
+ gap: var(--sys-control-gap-compact, 0.25rem);
221
394
  }
222
395
 
396
+ :where([data-oods-component='DetailHeader']) { gap: var(--sys-stack-xs, 0.5rem); }
397
+
223
398
  :where([data-oods-component='DetailHeader'], [data-oods-component='CardHeader']) > :is(h1, h2, h3, h4, h5, h6) {
224
399
  margin: 0;
225
400
  color: var(--cmp-header-title, CanvasText);
226
- font-weight: var(--ref-typography-weights-semibold, 600);
227
- line-height: var(--sys-text-line-height-standard, 1.4);
228
401
  }
229
402
 
230
403
  :where([data-oods-component='DetailHeader']) > :is(h1, h2, h3, h4, h5, h6) {
231
- font-size: var(--sys-text-scale-heading-lg-font-size, 1.5rem);
232
- line-height: var(--sys-text-scale-heading-lg-line-height, 1.2);
404
+ font-size: var(--sys-text-scale-heading-xl-font-size, 30px);
405
+ font-weight: var(--sys-text-scale-heading-xl-font-weight, 600);
406
+ line-height: var(--sys-text-scale-heading-xl-line-height, 36px);
407
+ letter-spacing: var(--sys-text-scale-heading-xl-letter-spacing);
233
408
  }
234
409
 
235
410
  :where([data-oods-component='CardHeader']) > :is(h1, h2, h3, h4, h5, h6) {
236
- font-size: var(--sys-text-size-lg, 1.25rem);
411
+ font-size: var(--sys-text-scale-heading-sm-font-size, 16px);
412
+ font-weight: var(--sys-text-scale-heading-sm-font-weight, 600);
413
+ line-height: var(--sys-text-scale-heading-sm-line-height, 24px);
237
414
  }
238
415
 
239
416
  :where([data-oods-component='DetailHeader']) > [data-oods-subtitle],
240
417
  :where([data-oods-component='CardHeader']) > [data-oods-supporting] {
418
+ margin: 0;
241
419
  color: var(--cmp-header-subtitle, CanvasText);
242
420
  }
243
421
 
422
+ :where([data-oods-component='DetailHeader']) > [data-oods-subtitle] {
423
+ font-size: var(--sys-text-scale-body-md-font-size, 16px);
424
+ line-height: var(--sys-text-scale-body-md-line-height, 24px);
425
+ }
426
+
427
+ :where([data-oods-component='CardHeader']) > [data-oods-supporting] {
428
+ font-size: var(--sys-text-scale-body-sm-font-size, 14px);
429
+ line-height: var(--sys-text-scale-body-sm-line-height, 20px);
430
+ }
431
+
244
432
  :where([data-oods-component='DetailHeader']) > [data-oods-metadata] {
433
+ margin: 0;
245
434
  color: var(--cmp-header-metadata, CanvasText);
246
- font-size: var(--sys-text-size-sm, 0.875rem);
435
+ font-size: var(--sys-text-scale-body-sm-font-size, 14px);
436
+ line-height: var(--sys-text-scale-body-sm-line-height, 20px);
247
437
  }
248
438
 
249
439
  :where([data-oods-component='ColorSwatch']) {
@@ -261,7 +451,7 @@
261
451
  inline-size: 1.25rem;
262
452
  block-size: 1.25rem;
263
453
  border: 1px solid var(--cmp-swatch-border, CanvasText);
264
- border-radius: var(--cmp-input-radius, 0.5rem);
454
+ border-radius: var(--cmp-input-radius, 6px);
265
455
  background: var(--oods-swatch-color, var(--cmp-swatch-chip, CanvasText));
266
456
  }
267
457
 
@@ -274,19 +464,22 @@
274
464
  display: inline-flex;
275
465
  align-items: center;
276
466
  gap: var(--cmp-badge-gap, 0.25rem);
467
+ min-block-size: var(--cmp-badge-height, 1.25rem);
468
+ box-sizing: border-box;
277
469
  padding: var(--cmp-badge-padding-block, 0.125rem) var(--cmp-badge-padding-inline, 0.5rem);
278
- border: 1px solid var(--cmp-badge-border, CanvasText);
470
+ border: 0;
279
471
  border-radius: var(--cmp-badge-radius, 999px);
280
472
  background: var(--cmp-badge-background, Canvas);
281
473
  color: var(--cmp-badge-text, CanvasText);
282
- font-size: var(--cmp-badge-font-size, 0.875rem);
283
- font-weight: var(--cmp-badge-font-weight, 600);
474
+ font-size: var(--cmp-badge-font-size, 12px);
475
+ font-weight: var(--cmp-badge-font-weight, 500);
476
+ line-height: var(--sys-text-scale-caption-line-height, 16px);
477
+ white-space: nowrap;
284
478
  }
285
479
 
286
480
  :where([data-oods-component='ColorizedBadge'])[data-emphasis='solid'] {
287
- border-color: var(--cmp-badge-text, CanvasText);
288
- background: var(--cmp-badge-text, CanvasText);
289
- color: var(--cmp-badge-background, Canvas);
481
+ background: var(--oods-tone-solid, var(--sys-status-neutral-solid, CanvasText));
482
+ color: var(--oods-tone-on-solid, var(--sys-status-neutral-on-solid, Canvas));
290
483
  }
291
484
 
292
485
  :where([data-oods-component='ColorizedBadge']) [data-oods-badge-marker] {
@@ -318,7 +511,7 @@
318
511
  min-block-size: var(--oods-viz-height, 360px);
319
512
  padding: var(--cmp-spacing-inset-default, 1rem);
320
513
  border: 1px dashed var(--cmp-preview-frame, CanvasText);
321
- border-radius: var(--cmp-input-radius, 0.5rem);
514
+ border-radius: var(--cmp-input-radius, 6px);
322
515
  background: var(--sys-surface-canvas, Canvas);
323
516
  }
324
517
 
@@ -335,9 +528,12 @@
335
528
  border: 0;
336
529
  place-items: stretch;
337
530
  }
531
+ /* s222-m02 (#2502 ruling 8): a placed chart's caption is heading-sm (16/24 600). It was an undocumented min() with a
532
+ * 1.25rem literal. */
338
533
  :where([data-viz-rendered='true']) > figcaption {
339
- font-size: min(var(--sys-text-scale-heading-md-font-size, 1.25rem), 1.25rem);
340
- font-weight: var(--ref-typography-weights-semibold, 600);
534
+ font-size: var(--sys-text-scale-heading-sm-font-size, 16px);
535
+ font-weight: var(--sys-text-scale-heading-sm-font-weight, 600);
536
+ line-height: var(--sys-text-scale-heading-sm-line-height, 24px);
341
537
  }
342
538
  :where([data-viz-svg]) { min-inline-size: 0; }
343
539
  :where([data-viz-svg]) > svg { display: block; inline-size: 100%; max-inline-size: var(--oods-viz-width, 100%); block-size: auto; }
@@ -373,18 +569,18 @@
373
569
  --cmp-timeline-marker: var(--sys-border-strong);
374
570
  display: grid;
375
571
  gap: var(--cmp-spacing-stack-sm, 0.75rem);
376
- padding: var(--cmp-spacing-inset-default, 1rem);
572
+ padding: var(--sys-card-padding, 1.5rem);
377
573
  border: 1px solid var(--cmp-timeline-border, CanvasText);
378
- border-radius: var(--cmp-input-radius, 0.5rem);
574
+ border-radius: var(--cmp-card-radius, 0.75rem);
379
575
  background: var(--cmp-timeline-background, Canvas);
380
576
  color: var(--cmp-timeline-text, CanvasText);
381
577
  }
382
578
 
383
579
  :where([data-oods-component='AddressValidationTimeline'], [data-oods-component='MembershipAuditTimeline'], [data-oods-component='MessageEventTimeline'], [data-oods-component='PreferenceTimeline']) > [data-timeline-title] {
384
580
  margin: 0;
385
- font-size: var(--sys-text-size-lg, 1.25rem);
386
- font-weight: var(--ref-typography-weights-semibold, 600);
387
- line-height: var(--sys-text-line-height-standard, 1.4);
581
+ font-size: var(--sys-text-scale-heading-md-font-size, 18px);
582
+ font-weight: var(--sys-text-scale-heading-md-font-weight, 600);
583
+ line-height: var(--sys-text-scale-heading-md-line-height, 24px);
388
584
  }
389
585
 
390
586
  :where([data-oods-component='AddressValidationTimeline'], [data-oods-component='MembershipAuditTimeline'], [data-oods-component='MessageEventTimeline'], [data-oods-component='PreferenceTimeline']) > [data-timeline-events] {
@@ -419,7 +615,7 @@
419
615
  gap: var(--sys-spacing-stack-compact, 0.75rem);
420
616
  padding: var(--cmp-spacing-inset-sm, 0.75rem);
421
617
  border: 1px solid var(--cmp-event-border, CanvasText);
422
- border-radius: var(--cmp-input-radius, 0.5rem);
618
+ border-radius: var(--cmp-input-radius, 6px);
423
619
  background: var(--cmp-event-background, Canvas);
424
620
  color: var(--cmp-event-text, CanvasText);
425
621
  }
@@ -447,19 +643,22 @@
447
643
  display: inline-flex;
448
644
  align-items: center;
449
645
  gap: var(--cmp-badge-gap, 0.25rem);
646
+ min-block-size: var(--cmp-badge-height, 1.25rem);
647
+ box-sizing: border-box;
450
648
  padding: var(--cmp-badge-padding-block, 0.125rem) var(--cmp-badge-padding-inline, 0.5rem);
451
- border: 1px solid var(--cmp-badge-border, CanvasText);
649
+ border: 0;
452
650
  border-radius: var(--cmp-badge-radius, 999px);
453
651
  background: var(--cmp-badge-background, Canvas);
454
652
  color: var(--cmp-badge-text, CanvasText);
455
- font-size: var(--cmp-badge-font-size, 0.875rem);
456
- font-weight: var(--cmp-badge-font-weight, 600);
653
+ font-size: var(--cmp-badge-font-size, 12px);
654
+ font-weight: var(--cmp-badge-font-weight, 500);
655
+ line-height: var(--sys-text-scale-caption-line-height, 16px);
656
+ white-space: nowrap;
457
657
  }
458
658
 
459
659
  :where([data-oods-component='ArchivePill'], [data-oods-component='CancellationBadge'], [data-oods-component='OwnerBadge'], [data-oods-component='ClassificationBadge'], [data-oods-component='AddressSummaryBadge'], [data-oods-component='MessageStatusBadge'], [data-oods-component='PreferenceSummaryBadge'])[data-emphasis='solid'] {
460
- border-color: var(--cmp-badge-text, CanvasText);
461
- background: var(--cmp-badge-text, CanvasText);
462
- color: var(--cmp-badge-background, Canvas);
660
+ background: var(--oods-tone-solid, var(--sys-status-neutral-solid, CanvasText));
661
+ color: var(--oods-tone-on-solid, var(--sys-status-neutral-on-solid, Canvas));
463
662
  }
464
663
 
465
664
  :where([data-oods-component='ArchivePill'], [data-oods-component='CancellationBadge'], [data-oods-component='OwnerBadge'], [data-oods-component='ClassificationBadge'], [data-oods-component='AddressSummaryBadge'], [data-oods-component='MessageStatusBadge'], [data-oods-component='PreferenceSummaryBadge']) [data-oods-badge-label] {
@@ -484,13 +683,17 @@
484
683
  :where([data-oods-component='TagPills']) [data-tag-overflow] {
485
684
  display: inline-flex;
486
685
  align-items: center;
686
+ min-block-size: var(--cmp-badge-height, 1.25rem);
687
+ box-sizing: border-box;
487
688
  padding: var(--cmp-badge-padding-block, 0.125rem) var(--cmp-badge-padding-inline, 0.5rem);
488
- border: 1px solid var(--cmp-badge-border, CanvasText);
689
+ border: 0;
489
690
  border-radius: var(--cmp-badge-radius, 999px);
490
691
  background: var(--cmp-badge-background, Canvas);
491
692
  color: var(--cmp-badge-text, CanvasText);
492
- font-size: var(--cmp-badge-font-size, 0.875rem);
493
- font-weight: var(--cmp-badge-font-weight, 600);
693
+ font-size: var(--cmp-badge-font-size, 12px);
694
+ font-weight: var(--cmp-badge-font-weight, 500);
695
+ line-height: var(--sys-text-scale-caption-line-height, 16px);
696
+ white-space: nowrap;
494
697
  }
495
698
 
496
699
  /* Panel, filter and summary sections mirror their HTML renderers; controls stay unwired. */
@@ -501,9 +704,9 @@
501
704
  --cmp-panel-subtitle: var(--sys-text-secondary);
502
705
  display: grid;
503
706
  gap: var(--cmp-spacing-stack-sm, 0.75rem);
504
- padding: var(--cmp-spacing-inset-default, 1rem);
707
+ padding: var(--sys-card-padding, 1.5rem);
505
708
  border: 1px solid var(--cmp-panel-border, CanvasText);
506
- border-radius: var(--cmp-input-radius, 0.5rem);
709
+ border-radius: var(--cmp-card-radius, 0.75rem);
507
710
  background: var(--cmp-panel-background, Canvas);
508
711
  color: var(--cmp-panel-title, CanvasText);
509
712
  }
@@ -516,9 +719,9 @@
516
719
  :where([data-oods-component='AddressCollectionPanel'], [data-oods-component='ClassificationPanel'], [data-oods-component='MembershipPanel'], [data-oods-component='PreferencePanel']) > [data-panel-header] > h2 {
517
720
  margin: 0;
518
721
  color: var(--cmp-panel-title, CanvasText);
519
- font-size: var(--sys-text-size-lg, 1.25rem);
520
- font-weight: var(--ref-typography-weights-semibold, 600);
521
- line-height: var(--sys-text-line-height-standard, 1.4);
722
+ font-size: var(--sys-text-scale-heading-md-font-size, 18px);
723
+ font-weight: var(--sys-text-scale-heading-md-font-weight, 600);
724
+ line-height: var(--sys-text-scale-heading-md-line-height, 24px);
522
725
  }
523
726
 
524
727
  :where([data-oods-component='AddressCollectionPanel'], [data-oods-component='ClassificationPanel'], [data-oods-component='MembershipPanel'], [data-oods-component='PreferencePanel']) > [data-panel-header] > [data-panel-subtitle] {
@@ -537,9 +740,9 @@
537
740
  --cmp-filter-legend: var(--sys-text-secondary);
538
741
  display: grid;
539
742
  gap: var(--cmp-spacing-stack-sm, 0.75rem);
540
- padding: var(--cmp-spacing-inset-default, 1rem);
743
+ padding: var(--sys-card-padding, 1.5rem);
541
744
  border: 1px solid var(--cmp-filter-border, CanvasText);
542
- border-radius: var(--cmp-input-radius, 0.5rem);
745
+ border-radius: var(--cmp-card-radius, 0.75rem);
543
746
  background: var(--cmp-filter-background, Canvas);
544
747
  color: var(--cmp-filter-text, CanvasText);
545
748
  }
@@ -548,7 +751,7 @@
548
751
  margin: 0;
549
752
  padding: var(--cmp-spacing-inset-sm, 0.75rem);
550
753
  border: 1px solid var(--cmp-filter-border, CanvasText);
551
- border-radius: var(--cmp-input-radius, 0.5rem);
754
+ border-radius: var(--cmp-input-radius, 6px);
552
755
  }
553
756
 
554
757
  :where([data-oods-component='FilterPanel']) > [data-filter-section] > legend {
@@ -563,13 +766,19 @@
563
766
  gap: var(--cmp-spacing-inline-sm, 0.75rem);
564
767
  }
565
768
 
769
+ /* s222-m02 (#2502 ruling 11): a filter's button is the small outline button. */
566
770
  :where([data-oods-component='FilterPanel']) button {
567
- padding: var(--cmp-button-padding-block-sm, 0.375rem) var(--cmp-button-padding-inline-sm, 0.75rem);
568
- border: 1px solid var(--cmp-filter-border, CanvasText);
569
- border-radius: var(--cmp-input-radius, 0.5rem);
570
- background: transparent;
771
+ box-sizing: border-box;
772
+ min-block-size: var(--cmp-button-height-sm, 1.75rem);
773
+ padding: 0 var(--cmp-button-padding-inline-sm, 0.625rem);
774
+ border: 1px solid var(--sys-border-strong, CanvasText);
775
+ border-radius: var(--cmp-button-radius, 6px);
776
+ background: var(--sys-surface-raised, Canvas);
571
777
  color: var(--cmp-filter-text, CanvasText);
572
778
  font: inherit;
779
+ font-size: var(--sys-text-scale-label-font-size, 14px);
780
+ font-weight: var(--sys-text-scale-label-font-weight, 500);
781
+ line-height: var(--sys-text-scale-label-line-height, 20px);
573
782
  }
574
783
 
575
784
  :where([data-oods-component='AddressEditor'], [data-oods-component='CancellationForm'], [data-oods-component='ClassificationEditor'], [data-oods-component='PreferenceEditor'], [data-oods-component='RoleAssignmentForm'], [data-oods-component='TagInput'], [data-oods-component='TagManager'], [data-oods-component='TemplatePicker']) {
@@ -580,9 +789,9 @@
580
789
  display: grid;
581
790
  gap: var(--cmp-spacing-stack-sm, 0.75rem);
582
791
  margin: 0;
583
- padding: var(--cmp-spacing-inset-default, 1rem);
792
+ padding: var(--sys-card-padding, 1.5rem);
584
793
  border: 1px solid var(--cmp-form-border, CanvasText);
585
- border-radius: var(--cmp-input-radius, 0.5rem);
794
+ border-radius: var(--cmp-card-radius, 0.75rem);
586
795
  background: var(--cmp-form-background, Canvas);
587
796
  color: var(--cmp-form-text, CanvasText);
588
797
  }
@@ -595,9 +804,9 @@
595
804
  :where([data-oods-component='AddressEditor'], [data-oods-component='CancellationForm'], [data-oods-component='ClassificationEditor'], [data-oods-component='PreferenceEditor'], [data-oods-component='RoleAssignmentForm'], [data-oods-component='TagInput'], [data-oods-component='TagManager'], [data-oods-component='TemplatePicker']) > [data-form-header] > h2 {
596
805
  margin: 0;
597
806
  color: var(--cmp-form-text, CanvasText);
598
- font-size: var(--sys-text-size-lg, 1.25rem);
599
- font-weight: var(--ref-typography-weights-semibold, 600);
600
- line-height: var(--sys-text-line-height-standard, 1.4);
807
+ font-size: var(--sys-text-scale-heading-md-font-size, 18px);
808
+ font-weight: var(--sys-text-scale-heading-md-font-weight, 600);
809
+ line-height: var(--sys-text-scale-heading-md-line-height, 24px);
601
810
  }
602
811
 
603
812
  :where([data-oods-component='AddressEditor'], [data-oods-component='CancellationForm'], [data-oods-component='ClassificationEditor'], [data-oods-component='PreferenceEditor'], [data-oods-component='RoleAssignmentForm'], [data-oods-component='TagInput'], [data-oods-component='TagManager'], [data-oods-component='TemplatePicker']) > [data-form-header] > [data-form-subtitle] {
@@ -612,9 +821,18 @@
612
821
  }
613
822
 
614
823
  :where([data-oods-component='AddressEditor'], [data-oods-component='CancellationForm'], [data-oods-component='ClassificationEditor'], [data-oods-component='PreferenceEditor'], [data-oods-component='RoleAssignmentForm'], [data-oods-component='TagInput'], [data-oods-component='TagManager'], [data-oods-component='TemplatePicker']) [data-tag-item] {
824
+ display: inline-flex;
825
+ align-items: center;
826
+ min-block-size: var(--cmp-badge-height, 1.25rem);
827
+ box-sizing: border-box;
615
828
  padding: var(--cmp-badge-padding-block, 0.125rem) var(--cmp-badge-padding-inline, 0.5rem);
616
- border: 1px solid var(--cmp-form-border, CanvasText);
829
+ border: 0;
617
830
  border-radius: var(--cmp-badge-radius, 999px);
831
+ background: var(--sys-status-neutral-surface, Canvas);
832
+ color: var(--sys-status-neutral-text, CanvasText);
833
+ font-size: var(--cmp-badge-font-size, 12px);
834
+ font-weight: var(--cmp-badge-font-weight, 500);
835
+ line-height: var(--sys-text-scale-caption-line-height, 16px);
618
836
  }
619
837
 
620
838
  :where([data-oods-component='AddressEditor'], [data-oods-component='CancellationForm'], [data-oods-component='ClassificationEditor'], [data-oods-component='PreferenceEditor'], [data-oods-component='RoleAssignmentForm'], [data-oods-component='TagInput'], [data-oods-component='TagManager'], [data-oods-component='TemplatePicker']) [data-form-control='input'] {
@@ -627,19 +845,24 @@
627
845
  font-size: var(--sys-text-size-sm, 0.875rem);
628
846
  }
629
847
 
630
- :where([data-oods-component='AddressEditor'], [data-oods-component='CancellationForm'], [data-oods-component='ClassificationEditor'], [data-oods-component='PreferenceEditor'], [data-oods-component='RoleAssignmentForm'], [data-oods-component='TagInput'], [data-oods-component='TagManager'], [data-oods-component='TemplatePicker']) input {
631
- padding: var(--cmp-input-padding-block-compact, 0.375rem) var(--cmp-input-padding-inline-compact, 0.5rem);
632
- border: 1px solid var(--cmp-form-border, CanvasText);
633
- border-radius: var(--cmp-input-radius, 0.5rem);
634
- background: transparent;
635
- color: inherit;
848
+ :where([data-oods-component='AddressEditor'], [data-oods-component='CancellationForm'], [data-oods-component='ClassificationEditor'], [data-oods-component='PreferenceEditor'], [data-oods-component='RoleAssignmentForm'], [data-oods-component='TagInput'], [data-oods-component='TagManager'], [data-oods-component='TemplatePicker']) input:not([type='checkbox'], [type='radio']) {
849
+ box-sizing: border-box;
850
+ min-block-size: var(--sys-control-height-md, 2rem);
851
+ padding: 0 var(--cmp-input-padding-inline, 0.75rem);
852
+ border: 1px solid var(--cmp-input-border, CanvasText);
853
+ border-radius: var(--cmp-input-radius, 6px);
854
+ background: var(--cmp-input-background, Canvas);
855
+ color: var(--cmp-input-text, CanvasText);
636
856
  font: inherit;
857
+ font-size: var(--sys-text-scale-body-sm-font-size, 14px);
858
+ line-height: var(--sys-text-scale-body-sm-line-height, 20px);
637
859
  }
638
860
 
639
861
  :where([data-oods-component='AddressEditor'], [data-oods-component='CancellationForm'], [data-oods-component='ClassificationEditor'], [data-oods-component='PreferenceEditor'], [data-oods-component='RoleAssignmentForm'], [data-oods-component='TagInput'], [data-oods-component='TagManager'], [data-oods-component='TemplatePicker']) > legend {
640
862
  padding-inline: var(--sys-control-gap-compact, 0.25rem);
641
- font-size: var(--sys-text-size-lg, 1.25rem);
642
- font-weight: var(--ref-typography-weights-semibold, 600);
863
+ font-size: var(--sys-text-scale-heading-md-font-size, 18px);
864
+ font-weight: var(--sys-text-scale-heading-md-font-weight, 600);
865
+ line-height: var(--sys-text-scale-heading-md-line-height, 24px);
643
866
  }
644
867
 
645
868
  :where([data-oods-component='AddressEditor'], [data-oods-component='CancellationForm'], [data-oods-component='ClassificationEditor'], [data-oods-component='PreferenceEditor'], [data-oods-component='RoleAssignmentForm'], [data-oods-component='TagInput'], [data-oods-component='TagManager'], [data-oods-component='TemplatePicker']) > [data-form-subtitle] {
@@ -664,19 +887,25 @@
664
887
 
665
888
  :where([data-oods-component='AddressEditor'], [data-oods-component='CancellationForm'], [data-oods-component='ClassificationEditor'], [data-oods-component='PreferenceEditor'], [data-oods-component='RoleAssignmentForm'], [data-oods-component='TagInput'], [data-oods-component='TagManager'], [data-oods-component='TemplatePicker']) select,
666
889
  :where([data-oods-component='AddressEditor'], [data-oods-component='CancellationForm'], [data-oods-component='ClassificationEditor'], [data-oods-component='PreferenceEditor'], [data-oods-component='RoleAssignmentForm'], [data-oods-component='TagInput'], [data-oods-component='TagManager'], [data-oods-component='TemplatePicker']) textarea {
667
- padding: var(--cmp-input-padding-block-compact, 0.375rem) var(--cmp-input-padding-inline-compact, 0.5rem);
668
- border: 1px solid var(--cmp-form-border, CanvasText);
669
- border-radius: var(--cmp-input-radius, 0.5rem);
670
- background: transparent;
671
- color: inherit;
890
+ box-sizing: border-box;
891
+ min-block-size: var(--sys-control-height-md, 2rem);
892
+ padding: 0 var(--cmp-input-padding-inline, 0.75rem);
893
+ border: 1px solid var(--cmp-input-border, CanvasText);
894
+ border-radius: var(--cmp-input-radius, 6px);
895
+ background: var(--cmp-input-background, Canvas);
896
+ color: var(--cmp-input-text, CanvasText);
672
897
  font: inherit;
898
+ font-size: var(--sys-text-scale-body-sm-font-size, 14px);
899
+ line-height: var(--sys-text-scale-body-sm-line-height, 20px);
673
900
  }
674
901
 
902
+ :where([data-oods-component='AddressEditor'], [data-oods-component='CancellationForm'], [data-oods-component='ClassificationEditor'], [data-oods-component='PreferenceEditor'], [data-oods-component='RoleAssignmentForm'], [data-oods-component='TagInput'], [data-oods-component='TagManager'], [data-oods-component='TemplatePicker']) textarea { padding-block: var(--sys-control-padding-block-lg, 0.5rem); }
903
+
675
904
  :where([data-oods-component='StatusSelector']) {
676
905
  --cmp-input-background: var(--sys-surface-raised);
677
- --cmp-input-border: var(--sys-border-subtle);
906
+ --cmp-input-border: var(--sys-border-interactive);
678
907
  --cmp-input-text: var(--sys-text-primary);
679
- --cmp-input-focus: var(--sys-border-strong);
908
+ --cmp-input-focus: var(--sys-border-interactive-hover);
680
909
  display: grid;
681
910
  gap: var(--sys-control-gap-compact, 0.25rem);
682
911
  color: var(--cmp-input-text, CanvasText);
@@ -688,12 +917,16 @@
688
917
  }
689
918
 
690
919
  :where([data-oods-component='StatusSelector']) select {
691
- padding: var(--cmp-input-padding-block-compact, 0.375rem) var(--cmp-input-padding-inline-compact, 0.5rem);
920
+ box-sizing: border-box;
921
+ min-block-size: var(--sys-control-height-md, 2rem);
922
+ padding: 0 var(--cmp-input-padding-inline, 0.75rem);
692
923
  border: 1px solid var(--cmp-input-border, CanvasText);
693
- border-radius: var(--cmp-input-radius, 0.5rem);
924
+ border-radius: var(--cmp-input-radius, 6px);
694
925
  background: var(--cmp-input-background, Canvas);
695
926
  color: var(--cmp-input-text, CanvasText);
696
927
  font: inherit;
928
+ font-size: var(--sys-text-scale-body-sm-font-size, 14px);
929
+ line-height: var(--sys-text-scale-body-sm-line-height, 20px);
697
930
  }
698
931
 
699
932
  /* The focus ring is the shared rule above; the focused field also takes the input focus colour on its border. */
@@ -709,18 +942,18 @@
709
942
  --cmp-summary-label: var(--sys-text-secondary);
710
943
  display: grid;
711
944
  gap: var(--cmp-spacing-stack-sm, 0.75rem);
712
- padding: var(--cmp-spacing-inset-default, 1rem);
945
+ padding: var(--sys-card-padding, 1.5rem);
713
946
  border: 1px solid var(--cmp-summary-border, CanvasText);
714
- border-radius: var(--cmp-input-radius, 0.5rem);
947
+ border-radius: var(--cmp-card-radius, 0.75rem);
715
948
  background: var(--cmp-summary-background, Canvas);
716
949
  color: var(--cmp-summary-text, CanvasText);
717
950
  }
718
951
 
719
952
  :where([data-oods-component='ArchiveSummary'], [data-oods-component='OwnershipSummary'], [data-oods-component='TagSummary'], [data-oods-component='PriceSummary']) > [data-summary-title] {
720
953
  margin: 0;
721
- font-size: var(--sys-text-size-lg, 1.25rem);
722
- font-weight: var(--ref-typography-weights-semibold, 600);
723
- line-height: var(--sys-text-line-height-standard, 1.4);
954
+ font-size: var(--sys-text-scale-heading-md-font-size, 18px);
955
+ font-weight: var(--sys-text-scale-heading-md-font-weight, 600);
956
+ line-height: var(--sys-text-scale-heading-md-line-height, 24px);
724
957
  }
725
958
 
726
959
  :where([data-oods-component='ArchiveSummary'], [data-oods-component='OwnershipSummary'], [data-oods-component='TagSummary'], [data-oods-component='PriceSummary']) > dl {
@@ -748,13 +981,23 @@
748
981
  color: var(--cmp-summary-label, CanvasText);
749
982
  }
750
983
 
984
+ /* s222-m02 (#2502 rulings 9 and 11): a field's label is the label role (14/20 500); its control sits on the raised
985
+ * surface with the 3:1 control border and the md control height (32), the same as the button beside it; help text is
986
+ * muted and an error takes the critical text colour, both at 14/20. A textarea grows by its rows. */
751
987
  .oods-field {
752
988
  display: grid;
989
+ /* A field stretched by its row keeps its label on its control instead of spreading the rows apart. */
990
+ align-content: start;
753
991
  gap: var(--cmp-input-gap, 0.375rem);
754
992
  color: var(--cmp-text-body, CanvasText);
755
993
  }
756
994
 
757
- .oods-field-label { font-weight: var(--ref-typography-weights-semibold, 600); }
995
+ .oods-field-label {
996
+ color: var(--sys-text-primary, CanvasText);
997
+ font-size: var(--sys-text-scale-label-font-size, 14px);
998
+ font-weight: var(--sys-text-scale-label-font-weight, 500);
999
+ line-height: var(--sys-text-scale-label-line-height, 20px);
1000
+ }
758
1001
 
759
1002
  .oods-field-control,
760
1003
  :where(
@@ -765,35 +1008,51 @@
765
1008
  ) {
766
1009
  inline-size: 100%;
767
1010
  box-sizing: border-box;
768
- padding: var(--cmp-input-padding-block, 0.625rem) var(--cmp-input-padding-inline, 0.75rem);
1011
+ min-block-size: var(--sys-control-height-md, 2rem);
1012
+ padding: 0 var(--cmp-input-padding-inline, 0.75rem);
769
1013
  border: 1px solid var(--cmp-input-border, var(--cmp-border-default, currentColor));
770
- border-radius: var(--cmp-input-radius, 0.5rem);
1014
+ border-radius: var(--cmp-input-radius, 6px);
771
1015
  background: var(--cmp-input-background, Canvas);
772
1016
  color: var(--cmp-input-text, CanvasText);
773
1017
  font: inherit;
1018
+ font-size: var(--sys-text-scale-body-sm-font-size, 14px);
1019
+ line-height: var(--sys-text-scale-body-sm-line-height, 20px);
774
1020
  }
775
1021
 
1022
+ /* A compact field's control is the sm control height (28), the small button's. */
1023
+ .oods-field[data-density='compact'] .oods-field-control { min-block-size: var(--sys-control-height-sm, 1.75rem); }
1024
+ :is(textarea.oods-field-control, textarea[data-oods-component='Textarea']) { padding-block: var(--sys-control-padding-block-lg, 0.5rem); }
1025
+ .oods-field-control:hover:not(:disabled, [aria-invalid='true']) { border-color: var(--sys-border-interactive-hover, CanvasText); }
1026
+ .oods-field-control:disabled { background: var(--sys-surface-disabled, Canvas); color: var(--sys-text-disabled, GrayText); cursor: not-allowed; }
776
1027
  .oods-field-control::placeholder { color: var(--cmp-input-placeholder, GrayText); }
777
- .oods-field-control[aria-invalid='true'] { border-color: var(--cmp-input-message-border, Mark); }
1028
+ /* An invalid control's border takes the critical icon role, the status step that reaches 3:1 on the surface. */
1029
+ .oods-field-control[aria-invalid='true'] { border-color: var(--sys-status-critical-icon, Mark); }
778
1030
  .oods-field-help { color: var(--cmp-input-support-text, var(--cmp-text-muted, GrayText)); }
779
- .oods-field-error { color: var(--cmp-input-message-text, MarkText); }
1031
+ .oods-field-error { color: var(--cmp-input-message-text, MarkText); font-size: var(--sys-text-scale-body-sm-font-size, 14px); line-height: var(--sys-text-scale-body-sm-line-height, 20px); margin: 0; }
780
1032
 
1033
+ /* s222-m02 (#2502 ruling 11): the banner's dismiss is a ghost icon button, square at the small control height, centred
1034
+ * on the title's line; its hover tints the banner's own text colour. */
781
1035
  .oods-banner-dismiss {
782
1036
  display: inline-flex;
783
- inline-size: var(--cmp-button-height, 2.5rem);
784
- block-size: var(--cmp-button-height, 2.5rem);
1037
+ inline-size: var(--cmp-button-height-sm, 1.75rem);
1038
+ block-size: var(--cmp-button-height-sm, 1.75rem);
785
1039
  align-items: center;
786
1040
  justify-content: center;
787
1041
  align-self: start;
1042
+ box-sizing: border-box;
1043
+ margin-block: calc(-1 * var(--sys-control-gap-compact, 0.25rem));
788
1044
  padding: 0;
789
- border: 1px solid currentColor;
790
- border-radius: var(--cmp-button-radius, 0.5rem);
1045
+ border: 1px solid transparent;
1046
+ border-radius: var(--cmp-button-radius, 6px);
791
1047
  background: transparent;
792
1048
  color: inherit;
793
1049
  font: inherit;
794
1050
  cursor: pointer;
795
1051
  }
796
1052
 
1053
+ .oods-banner-dismiss:hover { background: color-mix(in oklab, currentColor 12%, transparent); }
1054
+ .oods-banner-dismiss > svg { inline-size: var(--sys-control-icon-size, 1rem); block-size: var(--sys-control-icon-size, 1rem); }
1055
+
797
1056
  :where(.oods-checkbox, [data-oods-component='Checkbox']) {
798
1057
  display: inline-grid;
799
1058
  grid-template-columns: auto 1fr;
@@ -832,57 +1091,110 @@
832
1091
  justify-content: var(--oods-layout-justify, flex-start);
833
1092
  }
834
1093
 
1094
+ /* s222-m02 (#2502 rulings 9 and 11): a table sits in a bordered container with the large control radius on the raised
1095
+ * surface. Rows are 44px (36 dense) with 12px (8) cell padding at the small body size (14/20); the header is 500 in the
1096
+ * muted colour; numbers align at the end in tabular figures; the caption is left-aligned above the header, or visually
1097
+ * hidden when its table asks. */
1098
+ .oods-table__container {
1099
+ box-sizing: border-box;
1100
+ max-inline-size: 100%;
1101
+ overflow-x: auto;
1102
+ border: 1px solid var(--sys-border-subtle, CanvasText);
1103
+ border-radius: var(--sys-radius-control-lg, 8px);
1104
+ background: var(--sys-surface-raised, Canvas);
1105
+ }
1106
+
835
1107
  :where(.oods-table, [data-oods-component='Table']) {
1108
+ --oods-table-row-height: var(--sys-table-row-height, 2.75rem);
1109
+ --oods-table-cell-padding-inline: var(--sys-table-cell-padding-inline, 0.75rem);
836
1110
  inline-size: 100%;
837
1111
  border-collapse: collapse;
838
1112
  background: var(--cmp-surface-panel, Canvas);
839
1113
  color: var(--cmp-text-body, CanvasText);
1114
+ font-size: var(--sys-text-scale-body-sm-font-size, 14px);
1115
+ line-height: var(--sys-text-scale-body-sm-line-height, 20px);
840
1116
  }
841
1117
 
842
1118
  :where(.oods-table, [data-oods-component='Table'])[data-density='compact'] {
843
- --oods-table-cell-padding-block: var(--sys-space-inset-compact, 0.5rem);
844
- --oods-table-cell-padding-inline: var(--sys-space-inline-sm, 0.875rem);
845
- font-size: var(--sys-text-size-sm, 0.875rem);
1119
+ --oods-table-row-height: var(--sys-table-row-height-compact, 2.25rem);
1120
+ --oods-table-cell-padding-inline: var(--sys-table-cell-padding-inline-compact, 0.5rem);
846
1121
  }
847
1122
 
848
1123
  :where(.oods-table, [data-oods-component='Table'])[data-density='default'],
849
1124
  :where(.oods-table, [data-oods-component='Table'])[data-density='comfortable'] {
850
- --oods-table-cell-padding-block: var(--cmp-spacing-inset-sm, 0.75rem);
851
- --oods-table-cell-padding-inline: var(--sys-space-inset-default, 1.5rem);
852
- font-size: var(--sys-text-size-md, 1rem);
1125
+ --oods-table-row-height: var(--sys-table-row-height, 2.75rem);
1126
+ --oods-table-cell-padding-inline: var(--sys-table-cell-padding-inline, 0.75rem);
853
1127
  }
854
1128
 
855
1129
  :where(.oods-table, [data-oods-component='Table']) :is(th, td) {
856
- padding: var(--oods-table-cell-padding-block, var(--cmp-spacing-inset-compact, 0.75rem))
857
- var(--oods-table-cell-padding-inline, var(--cmp-spacing-inset-default, 1rem));
1130
+ box-sizing: border-box;
1131
+ block-size: var(--oods-table-row-height);
1132
+ padding: 0 var(--oods-table-cell-padding-inline);
858
1133
  border-block-end: 1px solid var(--cmp-border-default, currentColor);
859
1134
  text-align: start;
1135
+ vertical-align: middle;
1136
+ }
1137
+
1138
+ :where(.oods-table, [data-oods-component='Table']) th {
1139
+ color: var(--sys-text-muted, GrayText);
1140
+ font-weight: var(--sys-text-scale-label-font-weight, 500);
860
1141
  }
861
1142
 
862
- /* A row's action is the browser's own button, which otherwise takes the platform's font. */
863
- :where(.oods-table-row-action) { font: inherit; }
1143
+ :where(.oods-table, [data-oods-component='Table']) :is(th, td)[data-numeric='true'] { text-align: end; font-variant-numeric: tabular-nums; }
1144
+ :where(.oods-table, [data-oods-component='Table']) tbody > tr:last-child > :is(th, td) { border-block-end: 0; }
1145
+ :where(.oods-table, [data-oods-component='Table']) tbody > tr[data-selectable='true']:hover { background: var(--sys-surface-subtle, Canvas); }
1146
+
1147
+ /* A caption hidden on request stays the table's accessible name. */
1148
+ :where(.oods-table, [data-oods-component='Table']) > caption[data-visually-hidden='true'] { position: absolute; inline-size: 1px; block-size: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
1149
+
1150
+ :where(.oods-table, [data-oods-component='Table']) > caption {
1151
+ padding: var(--sys-inset-sm, 0.75rem) var(--oods-table-cell-padding-inline);
1152
+ border-block-end: 1px solid var(--cmp-border-default, currentColor);
1153
+ color: var(--sys-text-primary, CanvasText);
1154
+ font-weight: var(--sys-text-scale-heading-sm-font-weight, 600);
1155
+ text-align: start;
1156
+ }
864
1157
 
1158
+ /* A row's action is its first cell's text as a ghost button: no fill and no border, 500 weight, underlined on hover; the
1159
+ * shared rule paints its focus. */
1160
+ :where(.oods-table-row-action) {
1161
+ padding: 0;
1162
+ border: 0;
1163
+ border-radius: var(--sys-radius-control-sm, 4px);
1164
+ background: transparent;
1165
+ color: inherit;
1166
+ font: inherit;
1167
+ font-weight: var(--sys-text-scale-label-font-weight, 500);
1168
+ text-align: start;
1169
+ text-underline-offset: 0.25em;
1170
+ cursor: pointer;
1171
+ }
1172
+
1173
+ :where(.oods-table-row-action):hover { text-decoration: underline; }
1174
+
1175
+ /* s222-m02 (#2502 rulings 8 and 11): a tab is the label role (14/20 500; 16/24 at lg) in the secondary text colour; the
1176
+ * selected tab takes the primary text and a 2px indicator in the brand's primary fill, laid over the list's hairline. */
865
1177
  :where(.oods-tabs, [data-oods-component='Tabs']) {
866
- --oods-tabs-font-size: var(--sys-text-size-md, 1rem);
1178
+ --oods-tabs-font-size: var(--sys-text-scale-label-font-size, 14px);
1179
+ --oods-tabs-line-height: var(--sys-text-scale-label-line-height, 20px);
867
1180
  --oods-tabs-padding-block: var(--cmp-tabs-padding-block, 0.625rem);
868
1181
  --oods-tabs-padding-inline: var(--cmp-tabs-padding-inline, 0.75rem);
869
1182
  color: var(--cmp-text-body, CanvasText);
870
1183
  }
871
1184
 
872
1185
  :where(.oods-tabs, [data-oods-component='Tabs'])[data-size='sm'] {
873
- --oods-tabs-font-size: var(--sys-text-size-sm, 0.875rem);
874
1186
  --oods-tabs-padding-block: var(--cmp-tabs-padding-block-sm, 0.5rem);
875
1187
  --oods-tabs-padding-inline: var(--cmp-tabs-padding-inline-sm, 0.625rem);
876
1188
  }
877
1189
 
878
1190
  :where(.oods-tabs, [data-oods-component='Tabs'])[data-size='md'] {
879
- --oods-tabs-font-size: var(--sys-text-size-md, 1rem);
880
1191
  --oods-tabs-padding-block: var(--cmp-tabs-padding-block, 0.625rem);
881
1192
  --oods-tabs-padding-inline: var(--cmp-tabs-padding-inline, 0.75rem);
882
1193
  }
883
1194
 
884
1195
  :where(.oods-tabs, [data-oods-component='Tabs'])[data-size='lg'] {
885
- --oods-tabs-font-size: var(--sys-text-size-lg, 1.25rem);
1196
+ --oods-tabs-font-size: var(--sys-text-scale-body-md-font-size, 16px);
1197
+ --oods-tabs-line-height: var(--sys-text-scale-body-md-line-height, 24px);
886
1198
  --oods-tabs-padding-block: var(--cmp-tabs-padding-block-lg, 0.75rem);
887
1199
  --oods-tabs-padding-inline: var(--cmp-tabs-padding-inline-lg, 1rem);
888
1200
  }
@@ -892,15 +1204,17 @@
892
1204
  gap: var(--sys-control-gap-compact, 0.25rem);
893
1205
  padding: var(--sys-control-gap-compact, 0.25rem);
894
1206
  border: 1px solid var(--cmp-border-default, currentColor);
895
- border-radius: var(--cmp-button-radius, 0.5rem);
1207
+ border-radius: var(--sys-radius-control-lg, 8px);
896
1208
  background: var(--cmp-surface-panel, Canvas);
897
- box-shadow: var(--cmp-shadow-overlay-offset-x, 0px) var(--cmp-shadow-overlay-offset-y, 24px) var(--cmp-shadow-overlay-blur, 56px) var(--cmp-shadow-overlay-spread, -16px) var(--cmp-shadow-overlay-color, rgba(15, 23, 42, 0.24));
1209
+ box-shadow: var(--cmp-shadow-overlay-offset-x, 0px) var(--cmp-shadow-overlay-offset-y, 8px) var(--cmp-shadow-overlay-blur, 16px) var(--cmp-shadow-overlay-spread, -4px) var(--cmp-shadow-overlay-color, rgba(15, 23, 42, 0.24));
898
1210
  }
899
1211
 
900
- .oods-tab-list { display: flex; gap: var(--cmp-spacing-inline-xs, 0.5rem); overflow-x: auto; border-block-end: 1px solid var(--cmp-border-default, currentColor); }
901
- .oods-tab { padding: var(--oods-tabs-padding-block) var(--oods-tabs-padding-inline); border: 0; border-block-end: var(--cmp-tabs-indicator-width, 0.1875rem) solid transparent; background: transparent; color: inherit; font: inherit; font-size: var(--oods-tabs-font-size); line-height: var(--sys-text-line-height-standard, 1.4); }
902
- :where(.oods-tabs-overflow-trigger, .tabs__overflow-trigger) { padding: var(--oods-tabs-padding-block) var(--oods-tabs-padding-inline); font: inherit; font-size: var(--oods-tabs-font-size); line-height: var(--sys-text-line-height-standard, 1.4); }
903
- .oods-tab[aria-selected='true'] { border-block-end-color: var(--cmp-text-accent, Highlight); font-weight: var(--ref-typography-weights-semibold, 600); }
1212
+ .oods-tab-list { display: flex; gap: 0; overflow-x: auto; border-block-end: 1px solid var(--cmp-border-default, currentColor); }
1213
+ .oods-tab { margin-block-end: -1px; padding: var(--oods-tabs-padding-block) var(--oods-tabs-padding-inline); border: 0; border-block-end: var(--cmp-tabs-indicator-width, 0.125rem) solid transparent; background: transparent; color: var(--sys-text-secondary, CanvasText); font: inherit; font-size: var(--oods-tabs-font-size); font-weight: var(--sys-text-scale-label-font-weight, 500); line-height: var(--oods-tabs-line-height); cursor: pointer; }
1214
+ .oods-tab:hover:not(:disabled) { color: var(--sys-text-primary, CanvasText); }
1215
+ .oods-tab:disabled { color: var(--sys-text-disabled, GrayText); cursor: not-allowed; }
1216
+ :where(.oods-tabs-overflow-trigger, .tabs__overflow-trigger) { padding: var(--oods-tabs-padding-block) var(--oods-tabs-padding-inline); font: inherit; font-size: var(--oods-tabs-font-size); font-weight: var(--sys-text-scale-label-font-weight, 500); line-height: var(--oods-tabs-line-height); }
1217
+ .oods-tab[aria-selected='true'] { border-block-end-color: var(--sys-surface-interactive-primary-default, Highlight); color: var(--sys-text-primary, CanvasText); }
904
1218
  .oods-tab-panel { padding-block: var(--cmp-spacing-stack-default, 1rem); }
905
1219
 
906
1220
  :where(.oods-text, [data-oods-component='Text']) {
@@ -908,18 +1222,19 @@
908
1222
  font: inherit;
909
1223
  }
910
1224
 
1225
+ /* s222-m02 (#2502 ruling 8): the small and medium text sizes are the body roles, 14/20 and 16/24. */
911
1226
  :where(.oods-text, [data-oods-component='Text'])[data-size='sm'] {
912
- font-size: var(--sys-text-size-sm, 0.875rem);
913
- line-height: var(--sys-text-line-height-relaxed, 1.5);
1227
+ font-size: var(--sys-text-scale-body-sm-font-size, 14px);
1228
+ line-height: var(--sys-text-scale-body-sm-line-height, 20px);
914
1229
  }
915
1230
 
916
1231
  :where(.oods-text, [data-oods-component='Text'])[data-size='md'] {
917
- font-size: var(--sys-text-size-md, 1rem);
918
- line-height: var(--sys-text-line-height-relaxed, 1.5);
1232
+ font-size: var(--sys-text-scale-body-md-font-size, 16px);
1233
+ line-height: var(--sys-text-scale-body-md-line-height, 24px);
919
1234
  }
920
1235
 
921
1236
  :where(.oods-text, [data-oods-component='Text'])[data-size='lg'] {
922
- font-size: var(--sys-text-size-lg, 1.25rem);
1237
+ font-size: var(--sys-text-size-lg, 18px);
923
1238
  line-height: var(--sys-text-line-height-standard, 1.4);
924
1239
  }
925
1240
 
@@ -960,6 +1275,10 @@
960
1275
  border-color: CanvasText;
961
1276
  background: CanvasText;
962
1277
  }
1278
+
1279
+ :where([data-oods-component='ColorizedBadge'], [data-oods-component='ArchivePill'], [data-oods-component='CancellationBadge'], [data-oods-component='OwnerBadge'], [data-oods-component='ClassificationBadge'], [data-oods-component='AddressSummaryBadge'], [data-oods-component='MessageStatusBadge'], [data-oods-component='PreferenceSummaryBadge'], .oods-badge, [data-oods-component='RoleBadgeList'] [data-role-badge], [data-oods-component='TagPills'] :is([data-tag-pill], [data-tag-overflow])) {
1280
+ box-shadow: inset 0 0 0 1px CanvasText;
1281
+ }
963
1282
  }
964
1283
 
965
1284
  /* s221-m02 (#2482 ruling 4): a theme works in any element, so an hc rule reaches only what hc themes most closely:
@@ -970,6 +1289,12 @@
970
1289
  color: CanvasText;
971
1290
  }
972
1291
 
1292
+ /* s222-m02 (#2502 ruling 11): the badge families have no border, so their high-contrast outline is drawn inside the
1293
+ * pill, as the Badge's is. */
1294
+ [data-theme='hc'] :where([data-oods-component='ColorizedBadge'], [data-oods-component='ArchivePill'], [data-oods-component='CancellationBadge'], [data-oods-component='OwnerBadge'], [data-oods-component='ClassificationBadge'], [data-oods-component='AddressSummaryBadge'], [data-oods-component='MessageStatusBadge'], [data-oods-component='PreferenceSummaryBadge'], [data-oods-component='RoleBadgeList'] [data-role-badge], [data-oods-component='TagPills'] :is([data-tag-pill], [data-tag-overflow]), [data-oods-component='StatusBadge'], [data-oods-component='PriceBadge']):not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *)) {
1295
+ box-shadow: inset 0 0 0 1px CanvasText;
1296
+ }
1297
+
973
1298
  [data-theme='hc'] :where([data-oods-component='ColorSwatch']) > [data-oods-swatch-chip]:not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *)),
974
1299
  [data-theme='hc'] :where([data-oods-component='ColorizedBadge']) [data-oods-badge-marker]:not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *)) {
975
1300
  border-color: CanvasText;
@@ -982,21 +1307,41 @@
982
1307
  * HighlightText (which is only guaranteed against a Highlight background).
983
1308
  */
984
1309
  [data-theme='hc'] :where(
985
- .oods-badge,
986
- [data-oods-component='Badge'],
987
1310
  .oods-banner,
988
1311
  [data-oods-component='Banner']
989
1312
  ):not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *)) {
990
- border-color: Highlight;
1313
+ border-color: CanvasText;
991
1314
  background: Canvas;
992
1315
  color: CanvasText;
993
1316
  }
994
1317
 
1318
+ /* s222-m02 (#2502 rulings 6 and 11): a badge has no border, so in high contrast its outline is drawn inside its box and
1319
+ * the 20px height holds; subtle and solid both read CanvasText on Canvas. */
1320
+ [data-theme='hc'] :where(
1321
+ .oods-badge,
1322
+ [data-oods-component='Badge']
1323
+ ):not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *)) {
1324
+ background: Canvas;
1325
+ color: CanvasText;
1326
+ box-shadow: inset 0 0 0 1px CanvasText;
1327
+ }
1328
+
995
1329
  [data-theme='hc'] .oods-field-error:not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *)) {
996
1330
  color: CanvasText;
997
1331
  }
998
1332
 
1333
+ /* s222-m02: the banner's ghost dismiss takes the CanvasText outline every non-primary action has in high contrast. */
1334
+ [data-theme='hc'] .oods-banner-dismiss:not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *)) { border-color: CanvasText; }
1335
+
1336
+ /* s222-m01 (#2502 ruling 6): in high contrast only the primary action is Highlight on HighlightText; every other intent is
1337
+ * Canvas and CanvasText with a 1px CanvasText border, so the intents stay apart. */
999
1338
  [data-theme='hc'] :where(.oods-button, [data-oods-component='Button']):not(:disabled):not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *)) {
1339
+ border-color: CanvasText;
1340
+ background: Canvas;
1341
+ color: CanvasText;
1342
+ }
1343
+
1344
+ [data-theme='hc'] :where(.oods-button, [data-oods-component='Button'])[data-intent='primary']:not(:disabled):not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *)) {
1000
1345
  border-color: Highlight;
1001
1346
  background: Highlight;
1002
1347
  color: HighlightText;
@@ -1031,34 +1376,35 @@
1031
1376
  display: inline-flex;
1032
1377
  align-items: center;
1033
1378
  gap: var(--cmp-badge-gap, 0.25rem);
1034
- min-block-size: var(--cmp-badge-height, 1.5rem);
1379
+ min-block-size: var(--cmp-badge-height, 1.25rem);
1035
1380
  box-sizing: border-box;
1036
1381
  padding: var(--cmp-badge-padding-block, 0.125rem) var(--cmp-badge-padding-inline, 0.5rem);
1037
- border: 1px solid var(--cmp-badge-border, var(--cmp-border-default, currentColor));
1382
+ border: 0;
1038
1383
  border-radius: var(--cmp-badge-radius, 999px);
1039
1384
  background: var(--cmp-badge-background, var(--cmp-surface-subtle, transparent));
1040
1385
  color: var(--cmp-badge-text, var(--cmp-text-body, currentColor));
1041
- font-size: var(--cmp-badge-font-size, 0.875rem);
1042
- font-weight: var(--cmp-badge-font-weight, 600);
1043
- line-height: var(--sys-text-line-height-tight, 1.2);
1386
+ font-size: var(--cmp-badge-font-size, 12px);
1387
+ font-weight: var(--cmp-badge-font-weight, 500);
1388
+ line-height: var(--sys-text-scale-caption-line-height, 16px);
1389
+ white-space: nowrap;
1044
1390
  }
1045
1391
 
1046
- :where([data-oods-component='StatusBadge'])[data-status='active'],
1047
- :where([data-oods-component='StatusBadge'])[data-status='success'] {
1392
+ :where([data-oods-component='StatusBadge'])[data-status='active']:not([data-tone]),
1393
+ :where([data-oods-component='StatusBadge'])[data-status='success']:not([data-tone]) {
1048
1394
  --cmp-badge-background: var(--sys-status-success-surface, Canvas);
1049
1395
  --cmp-badge-border: var(--sys-status-success-border, currentColor);
1050
1396
  --cmp-badge-text: var(--sys-status-success-text, CanvasText);
1051
1397
  }
1052
1398
 
1053
- :where([data-oods-component='StatusBadge'])[data-status='past_due'],
1054
- :where([data-oods-component='StatusBadge'])[data-status='warning'] {
1399
+ :where([data-oods-component='StatusBadge'])[data-status='past_due']:not([data-tone]),
1400
+ :where([data-oods-component='StatusBadge'])[data-status='warning']:not([data-tone]) {
1055
1401
  --cmp-badge-background: var(--sys-status-warning-surface, Canvas);
1056
1402
  --cmp-badge-border: var(--sys-status-warning-border, currentColor);
1057
1403
  --cmp-badge-text: var(--sys-status-warning-text, CanvasText);
1058
1404
  }
1059
1405
 
1060
- :where([data-oods-component='StatusBadge'])[data-status='cancelled'],
1061
- :where([data-oods-component='StatusBadge'])[data-status='error'] {
1406
+ :where([data-oods-component='StatusBadge'])[data-status='cancelled']:not([data-tone]),
1407
+ :where([data-oods-component='StatusBadge'])[data-status='error']:not([data-tone]) {
1062
1408
  --cmp-badge-background: var(--sys-status-critical-surface, Canvas);
1063
1409
  --cmp-badge-border: var(--sys-status-critical-border, currentColor);
1064
1410
  --cmp-badge-text: var(--sys-status-critical-text, CanvasText);
@@ -1094,9 +1440,9 @@
1094
1440
  :where([data-oods-component='CancellationSummary']) {
1095
1441
  display: grid;
1096
1442
  gap: var(--cmp-spacing-stack-sm, 0.75rem);
1097
- padding: var(--cmp-spacing-inset-default, 1rem);
1443
+ padding: var(--sys-card-padding, 1.5rem);
1098
1444
  border: 1px solid var(--cmp-border-default, currentColor);
1099
- border-radius: var(--cmp-input-radius, 0.5rem);
1445
+ border-radius: var(--cmp-card-radius, 0.75rem);
1100
1446
  background: var(--cmp-surface-panel, Canvas);
1101
1447
  color: var(--cmp-text-body, CanvasText);
1102
1448
  }
@@ -1125,26 +1471,45 @@
1125
1471
  :where([data-oods-component='SearchInput']) input[type='search'] {
1126
1472
  inline-size: 100%;
1127
1473
  box-sizing: border-box;
1128
- padding: var(--cmp-input-padding-block, 0.625rem) var(--cmp-input-padding-inline, 0.75rem);
1474
+ min-block-size: var(--sys-control-height-md, 2rem);
1475
+ padding: 0 var(--cmp-input-padding-inline, 0.75rem);
1129
1476
  border: 1px solid var(--cmp-input-border, var(--cmp-border-default, currentColor));
1130
- border-radius: var(--cmp-input-radius, 0.5rem);
1477
+ border-radius: var(--cmp-input-radius, 6px);
1131
1478
  background: var(--cmp-input-background, Canvas);
1132
1479
  color: var(--cmp-input-text, CanvasText);
1133
1480
  font: inherit;
1481
+ font-size: var(--sys-text-scale-body-sm-font-size, 14px);
1482
+ line-height: var(--sys-text-scale-body-sm-line-height, 20px);
1134
1483
  }
1135
1484
 
1485
+ /* s222-m02 (#2502 ruling 11): search and pagination buttons are the outline button at the control height; a page
1486
+ * number is square. */
1136
1487
  :where([data-oods-component='SearchInput']) button,
1137
1488
  :where([data-oods-component='PaginationBar']) button {
1138
1489
  display: inline-flex;
1139
- min-inline-size: var(--cmp-button-height, 2.5rem);
1140
- min-block-size: var(--cmp-button-height, 2.5rem);
1490
+ box-sizing: border-box;
1491
+ min-inline-size: var(--cmp-button-height, 2rem);
1492
+ min-block-size: var(--cmp-button-height, 2rem);
1141
1493
  align-items: center;
1142
1494
  justify-content: center;
1143
- border: 1px solid var(--cmp-button-border, var(--cmp-border-default, currentColor));
1144
- border-radius: var(--cmp-button-radius, 0.5rem);
1145
- background: var(--cmp-button-background, Canvas);
1146
- color: var(--cmp-button-text, CanvasText);
1495
+ padding: 0 var(--cmp-button-padding-inline-sm, 0.625rem);
1496
+ border: 1px solid var(--sys-border-strong, CanvasText);
1497
+ border-radius: var(--cmp-button-radius, 6px);
1498
+ background: var(--sys-surface-raised, Canvas);
1499
+ color: var(--sys-text-primary, CanvasText);
1147
1500
  font: inherit;
1501
+ font-size: var(--sys-text-scale-label-font-size, 14px);
1502
+ font-weight: var(--sys-text-scale-label-font-weight, 500);
1503
+ line-height: var(--sys-text-scale-label-line-height, 20px);
1504
+ cursor: pointer;
1505
+ }
1506
+
1507
+ :where([data-oods-component='SearchInput'], [data-oods-component='PaginationBar']) button:hover:not(:disabled) { background: var(--sys-surface-interactive-secondary-default, Canvas); }
1508
+ :where([data-oods-component='SearchInput'], [data-oods-component='PaginationBar']) button > svg { flex: none; inline-size: var(--sys-control-icon-size, 1rem); block-size: var(--sys-control-icon-size, 1rem); }
1509
+ :where([data-oods-component='PaginationBar']) button[aria-current='page'] {
1510
+ border-color: transparent;
1511
+ background: var(--sys-surface-interactive-primary-default, Highlight);
1512
+ color: var(--sys-text-on-interactive, HighlightText);
1148
1513
  }
1149
1514
 
1150
1515
  :where([data-oods-component='PaginationBar']) {
@@ -1156,6 +1521,8 @@
1156
1521
  }
1157
1522
 
1158
1523
  :where([data-oods-component='PaginationBar']) button:disabled {
1524
+ border-color: var(--sys-border-subtle, GrayText);
1525
+ background: var(--sys-surface-disabled, Canvas);
1159
1526
  color: var(--cmp-button-text-disabled, GrayText);
1160
1527
  cursor: not-allowed;
1161
1528
  }
@@ -1257,18 +1624,21 @@
1257
1624
  width: 100%;
1258
1625
  min-width: 0;
1259
1626
  box-sizing: border-box;
1260
- padding: var(--space-2) var(--space-3);
1627
+ min-block-size: var(--sys-control-height-md);
1628
+ padding: 0 var(--space-3);
1261
1629
  font: inherit;
1630
+ font-size: var(--sys-text-scale-body-sm-font-size);
1631
+ line-height: var(--sys-text-scale-body-sm-line-height);
1262
1632
  color: inherit;
1263
- background: var(--sys-surface-default);
1264
- border: 1px solid var(--sys-border-default);
1633
+ background: var(--sys-surface-raised);
1634
+ border: 1px solid var(--sys-border-interactive);
1265
1635
  border-radius: var(--radius-md);
1266
1636
  }
1267
1637
  :where([data-oods-component='BillingAmountInput'], [data-oods-component='BillingIntervalSelector']) > select {
1268
1638
  color: var(--cmp-billing-interval-text, var(--sys-text-subtle));
1269
1639
  }
1270
1640
  :where([data-oods-component='BillingAmountInput'], [data-oods-component='BillingIntervalSelector']) > [aria-invalid='true'] {
1271
- border-color: var(--sys-status-critical-border);
1641
+ border-color: var(--sys-status-critical-icon);
1272
1642
  }
1273
1643
  :where([data-oods-component='BillingAmountInput'], [data-oods-component='BillingIntervalSelector']) > [role='alert'] {
1274
1644
  color: var(--sys-status-critical-text);
@@ -1279,30 +1649,31 @@
1279
1649
  [data-oods-component='CycleProgressCard'],
1280
1650
  :where([data-oods-component='PaymentTimeline'], [data-oods-component='PaymentEventTimeline']) {
1281
1651
  min-width: 0;
1282
- padding: var(--space-4, 1rem);
1652
+ padding: var(--sys-card-padding, 1.5rem);
1283
1653
  border: 1px solid var(--sys-border-default, GrayText);
1284
- border-radius: var(--radius-md, 0.5rem);
1654
+ border-radius: var(--cmp-card-radius, 0.75rem);
1285
1655
  background: var(--sys-surface-default, Canvas);
1286
1656
  color: var(--cmp-billing-timeline-text, var(--sys-text-default, CanvasText));
1287
1657
  }
1288
1658
  [data-oods-component='CycleProgressCard'] h2,
1289
- :where([data-oods-component='PaymentTimeline'], [data-oods-component='PaymentEventTimeline']) h2 { margin: 0 0 var(--space-3, 0.75rem); }
1659
+ :where([data-oods-component='PaymentTimeline'], [data-oods-component='PaymentEventTimeline']) h2 { margin: 0 0 var(--space-3, 0.75rem); font-size: var(--sys-text-scale-heading-md-font-size, 18px); font-weight: var(--sys-text-scale-heading-md-font-weight, 600); line-height: var(--sys-text-scale-heading-md-line-height, 24px); }
1290
1660
  [data-oods-component='CycleProgressCard'] p,
1291
1661
  :where([data-oods-component='PaymentTimeline'], [data-oods-component='PaymentEventTimeline']) p { margin: var(--space-2, 0.5rem) 0; }
1292
1662
  /* s213-m01: the track takes the border role, so the whole cycle reads against the card in both themes (raised surface
1293
- was whiter than the light card, 1.04:1) while the accent fill keeps at least 3:1 against it. */
1663
+ was whiter than the light card, 1.04:1) while the accent fill keeps at least 3:1 against it. s222-m01: the strong
1664
+ border, since the neutral-first subtle border (#e5e5e5) is 1.26:1 on a white card. */
1294
1665
  [data-oods-component='CycleProgressCard'] progress {
1295
1666
  width: 100%;
1296
1667
  height: var(--cmp-billing-cycle-progress-height, 0.5rem);
1297
1668
  appearance: none;
1298
1669
  border: 0;
1299
- border-radius: var(--sys-radius-control, 0.5rem);
1670
+ border-radius: var(--sys-radius-control, 6px);
1300
1671
  overflow: hidden;
1301
- background: var(--sys-border-default, Canvas);
1672
+ background: var(--sys-border-strong, Canvas);
1302
1673
  color: var(--cmp-billing-cycle-progress-fill, var(--sys-text-accent, Highlight));
1303
1674
  }
1304
1675
  [data-oods-component='CycleProgressCard'] progress::-webkit-progress-bar {
1305
- background: var(--sys-border-default, Canvas);
1676
+ background: var(--sys-border-strong, Canvas);
1306
1677
  }
1307
1678
  [data-oods-component='CycleProgressCard'] progress::-webkit-progress-value {
1308
1679
  background: var(--cmp-billing-cycle-progress-fill, var(--sys-text-accent, Highlight));
@@ -1338,17 +1709,24 @@
1338
1709
  [data-oods-component='ArchivedRowOverlay'][data-archived='true']:has(> .oods-collection-row) {
1339
1710
  box-sizing: border-box;
1340
1711
  border: 1px solid var(--sys-border-strong, CanvasText);
1341
- border-radius: var(--cmp-button-radius, 0.5rem);
1712
+ border-radius: var(--cmp-button-radius, 6px);
1342
1713
  background: var(--sys-surface-raised, Canvas);
1343
1714
  padding-inline-end: var(--space-4, 1rem);
1344
1715
  }
1345
1716
  [data-oods-component='ArchivedRowOverlay'][data-archived='true'] > .oods-collection-row { border: 0; background: transparent; }
1717
+ /* s222-m02 (#2502 ruling 11): the archive mark is a badge: a 20px pill at 12/500. */
1346
1718
  .oods-archive-badge {
1347
- display: inline-block;
1719
+ display: inline-flex;
1720
+ align-items: center;
1721
+ box-sizing: border-box;
1722
+ min-block-size: var(--cmp-badge-height, 1.25rem);
1348
1723
  white-space: nowrap;
1349
1724
  flex-shrink: 0;
1350
- padding: var(--space-1, 0.25rem) var(--space-2, 0.5rem);
1351
- border-radius: var(--radius-sm, 0.5rem);
1725
+ padding: var(--cmp-badge-padding-block, 0.125rem) var(--cmp-badge-padding-inline, 0.5rem);
1726
+ border-radius: var(--cmp-badge-radius, 999px);
1727
+ font-size: var(--cmp-badge-font-size, 12px);
1728
+ font-weight: var(--cmp-badge-font-weight, 500);
1729
+ line-height: var(--sys-text-scale-caption-line-height, 16px);
1352
1730
  color: var(--status-archive-text, var(--sys-text-primary));
1353
1731
  background: var(--status-archive-bg, var(--sys-surface-raised));
1354
1732
  }
@@ -1360,7 +1738,8 @@
1360
1738
  }
1361
1739
  [data-oods-component='CancellationSummary'] [data-summary-item] { min-width: 0; }
1362
1740
  [data-oods-component='CancellationSummary'] dd { margin: 0; overflow-wrap: break-word; }
1363
- .oods-field-help { display: block; margin: var(--cmp-input-gap, 0.375rem) 0 var(--cmp-spacing-stack-md, 1rem); font-size: var(--sys-text-size-sm, 0.875rem); color: var(--sys-text-subtle, GrayText); }
1741
+ /* s222-m02 (#2502 ruling 11): help text is muted at 14/20 and spaced by its field's gap, not by margins of its own. */
1742
+ .oods-field-help { display: block; margin: 0; font-size: var(--sys-text-scale-body-sm-font-size, 14px); line-height: var(--sys-text-scale-body-sm-line-height, 20px); color: var(--sys-text-muted, GrayText); }
1364
1743
  .oods-cancellation-form { margin: 0; min-width: 0; }
1365
1744
  .oods-field:has(input[type='checkbox']) { display: block; }
1366
1745
  .oods-field label:has(input[type='checkbox']) { display: flex; flex-direction: row; align-items: center; gap: var(--cmp-checkbox-gap, 0.5rem); }
@@ -1375,8 +1754,9 @@
1375
1754
  .workflow-content [data-oods-collection-toolbar] > [data-oods-component='Select'],
1376
1755
  .workflow-content [data-oods-collection-toolbar] > .oods-field:has(select) { flex: 1 1 180px; min-width: min(180px, 100%); }
1377
1756
  [data-oods-collection-toolbar] select { width: 100%; box-sizing: border-box; }
1378
- [data-oods-component='Stack']:has(> [data-oods-collection-toolbar]) { font-family: var(--ref-typography-families-sans, system-ui, sans-serif); }
1379
- .oods-collection-row { --oods-button-background: var(--sys-surface-raised); --oods-button-background-hover: var(--sys-surface-subtle); --oods-button-border: var(--sys-border-subtle); --oods-button-text: var(--sys-text-primary); width: 100%; display: flex; flex-wrap: wrap; align-items: center; gap: var(--cmp-spacing-inline-sm, 0.75rem); text-align: left; padding: var(--cmp-spacing-inset-default, 1rem); }
1757
+ /* s222-m02: the toolbar's stack reads in the brand's own sans (it named the shared reference family, which is not brand B's). */
1758
+ [data-oods-component='Stack']:has(> [data-oods-collection-toolbar]) { font-family: var(--sys-font-sans); }
1759
+ .oods-collection-row { --oods-button-background: var(--sys-surface-raised); --oods-button-background-hover: var(--sys-surface-subtle); --oods-button-border: var(--sys-border-subtle); --oods-button-text: var(--sys-text-primary); width: 100%; display: flex; flex-wrap: wrap; white-space: normal; align-items: center; gap: var(--cmp-spacing-inline-sm, 0.75rem); text-align: left; padding: var(--cmp-spacing-inset-default, 1rem); }
1380
1760
  [data-theme='hc'] .oods-collection-row:not(:disabled):not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *)) { background: var(--sys-surface-raised); color: var(--sys-text-primary); }
1381
1761
  .oods-collection-row > :first-child { min-width: 0; flex: 1 1 140px; font-weight: var(--ref-typography-weights-semibold, 600); }
1382
1762
  .oods-collection-row .oods-badge { max-width: 100%; width: fit-content; flex: 0 0 auto; text-transform: none; letter-spacing: normal; }
@@ -1384,16 +1764,16 @@
1384
1764
  .oods-pagination-bar__pages { display: flex; gap: var(--sys-control-gap-tight, 0.375rem); list-style: none; margin: 0; padding: 0; }
1385
1765
  @media (max-width: 600px) { .oods-collection-row { flex-direction: column; align-items: flex-start; } .oods-collection-row > :first-child { flex-basis: auto; width: 100%; } }
1386
1766
 
1387
- :where(.oods-audit-summary, [data-oods-component='AuditSummaryCard']) { padding: var(--cmp-spacing-inset-default); border: 1px solid var(--cmp-border-default); border-radius: var(--cmp-input-radius); background: var(--cmp-surface-panel); color: var(--cmp-text-body); }
1388
- .oods-audit-summary h2 { margin-top: 0; }
1767
+ :where(.oods-audit-summary, [data-oods-component='AuditSummaryCard']) { padding: var(--sys-card-padding); border: 1px solid var(--cmp-border-default); border-radius: var(--cmp-card-radius); background: var(--cmp-surface-panel); color: var(--cmp-text-body); }
1768
+ .oods-audit-summary h2 { margin-top: 0; font-size: var(--sys-text-scale-heading-md-font-size); font-weight: var(--sys-text-scale-heading-md-font-weight); line-height: var(--sys-text-scale-heading-md-line-height); }
1389
1769
  .oods-audit-summary dl { display: grid; grid-template-columns: auto 1fr; gap: var(--cmp-spacing-inline-sm); }
1390
1770
  .oods-audit-summary dd { margin: 0; }
1391
1771
  :where(.oods-sort-indicator, [data-oods-component='SortIndicator']) { border-collapse: collapse; color: var(--cmp-text-body); }
1392
- .oods-sort-indicator button { padding: var(--cmp-spacing-inline-sm); background: var(--cmp-surface-panel); color: var(--cmp-text-body); border: 1px solid var(--cmp-border-default); border-radius: var(--cmp-input-radius); font: inherit; cursor: pointer; }
1772
+ .oods-sort-indicator button { box-sizing: border-box; min-block-size: var(--cmp-button-height-sm); padding: 0 var(--cmp-button-padding-inline-sm); background: var(--sys-surface-raised); color: var(--cmp-text-body); border: 1px solid var(--sys-border-strong); border-radius: var(--cmp-button-radius); font: inherit; font-size: var(--sys-text-scale-label-font-size); font-weight: var(--sys-text-scale-label-font-weight); line-height: var(--sys-text-scale-label-line-height); cursor: pointer; }
1393
1773
  [data-oods-component='TimelineEntryLabel'] { color: var(--cmp-text-body); }
1394
1774
 
1395
- .oods-trait-recipe, :where([data-oods-component='ArchiveEvent'], [data-oods-component='CancellationEvent'], [data-oods-component='ColorStatePicker'], [data-oods-component='CommunicationDetailPanel'], [data-oods-component='GeoFieldMappingForm'], [data-oods-component='GeocodablePreview'], [data-oods-component='StateTransitionEvent'], [data-oods-component='StatusColorLegend'], [data-oods-component='VizAreaControls'], [data-oods-component='VizAxisControls'], [data-oods-component='VizAxisSummary'], [data-oods-component='VizColorControls'], [data-oods-component='VizColorLegendConfig'], [data-oods-component='VizHeatmapControls'], [data-oods-component='VizLineControls'], [data-oods-component='VizMarkControls'], [data-oods-component='VizOpacityControls'], [data-oods-component='VizOpacitySummary'], [data-oods-component='VizPointControls'], [data-oods-component='VizScaleControls'], [data-oods-component='VizScaleSummary'], [data-oods-component='VizScatterControls'], [data-oods-component='VizShapeControls'], [data-oods-component='VizShapeLegend'], [data-oods-component='VizSizeControls'], [data-oods-component='VizSizeSummary']) { min-width: 0; margin: 0; padding: var(--cmp-spacing-inset-default); border: 1px solid var(--cmp-border-default); border-radius: var(--cmp-input-radius); background: var(--cmp-surface-panel); color: var(--cmp-text-body); overflow-wrap: anywhere; }
1396
- .oods-trait-recipe h2 { margin-top: 0; }
1775
+ .oods-trait-recipe, :where([data-oods-component='ArchiveEvent'], [data-oods-component='CancellationEvent'], [data-oods-component='ColorStatePicker'], [data-oods-component='CommunicationDetailPanel'], [data-oods-component='GeoFieldMappingForm'], [data-oods-component='GeocodablePreview'], [data-oods-component='StateTransitionEvent'], [data-oods-component='StatusColorLegend'], [data-oods-component='VizAreaControls'], [data-oods-component='VizAxisControls'], [data-oods-component='VizAxisSummary'], [data-oods-component='VizColorControls'], [data-oods-component='VizColorLegendConfig'], [data-oods-component='VizHeatmapControls'], [data-oods-component='VizLineControls'], [data-oods-component='VizMarkControls'], [data-oods-component='VizOpacityControls'], [data-oods-component='VizOpacitySummary'], [data-oods-component='VizPointControls'], [data-oods-component='VizScaleControls'], [data-oods-component='VizScaleSummary'], [data-oods-component='VizScatterControls'], [data-oods-component='VizShapeControls'], [data-oods-component='VizShapeLegend'], [data-oods-component='VizSizeControls'], [data-oods-component='VizSizeSummary']) { min-width: 0; margin: 0; padding: var(--sys-card-padding); border: 1px solid var(--cmp-border-default); border-radius: var(--cmp-card-radius); background: var(--cmp-surface-panel); color: var(--cmp-text-body); overflow-wrap: anywhere; }
1776
+ .oods-trait-recipe h2 { margin-top: 0; font-size: var(--sys-text-scale-heading-md-font-size); font-weight: var(--sys-text-scale-heading-md-font-weight); line-height: var(--sys-text-scale-heading-md-line-height); }
1397
1777
  .oods-trait-recipe dd { margin: 0 0 var(--cmp-spacing-inline-sm); }
1398
1778
  .oods-trait-recipe dt { font-weight: var(--ref-typography-weights-semibold, 600); }
1399
1779
  .oods-trait-recipe .oods-field { margin-block: var(--cmp-spacing-inline-sm); }
@@ -1403,7 +1783,7 @@
1403
1783
 
1404
1784
  /* Producer-owned read fields stay labelled and readable in every context. */
1405
1785
  [data-oods-component='Stack'][id$='-read-field'] { gap: var(--sys-control-gap-compact, 0.25rem); min-width: 0; }
1406
- [data-oods-component='Stack'][id$='-read-fields'] { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); gap: var(--sys-space-scale-lg, 1.25rem); }
1786
+ [data-oods-component='Stack'][id$='-read-fields'] { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); gap: var(--sys-space-scale-lg, 24px); }
1407
1787
  [data-oods-component='Stack'][id$='-read-fields'] > :not([id$='-read-field']) { grid-column: 1 / -1; }
1408
1788
  [data-oods-component='Stack'][id$='-read-field'] > :first-child { color: var(--sys-text-secondary); }
1409
1789
  [data-oods-component='Stack'][id$='-read-field'] > :last-child { overflow-wrap: anywhere; align-self: flex-start; max-width: 100%; }
@@ -1427,9 +1807,9 @@
1427
1807
  :where([data-oods-component='CancellationSummary']) {
1428
1808
  display: grid;
1429
1809
  gap: var(--cmp-spacing-stack-sm, 0.75rem);
1430
- padding: var(--cmp-spacing-inset-default, 1rem);
1810
+ padding: var(--sys-card-padding, 1.5rem);
1431
1811
  border: 1px solid var(--cmp-border-default, var(--sys-border-subtle));
1432
- border-radius: var(--cmp-input-radius, 0.5rem);
1812
+ border-radius: var(--cmp-card-radius, 0.75rem);
1433
1813
  background: var(--cmp-surface-panel, var(--sys-surface-raised));
1434
1814
  color: var(--cmp-text-body, var(--sys-text-primary));
1435
1815
  }
@@ -1445,7 +1825,17 @@
1445
1825
  div.oods-field[data-oods-component='Checkbox'] { display: grid; grid-template-columns: minmax(0, 1fr); }
1446
1826
  .oods-field.oods-checkbox > label,
1447
1827
  .oods-field > label.oods-checkbox { display: flex; align-items: center; gap: var(--cmp-checkbox-gap, 0.5rem); }
1448
- input[data-oods-component='Checkbox'], .oods-field input[type='checkbox'] { margin: 0; flex: 0 0 auto; inline-size: var(--cmp-input-height, 3rem); block-size: var(--cmp-input-height, 3rem); }
1828
+ /* s222-m02 (#2502 ruling 9): a checkbox or radio is 16px, the control icon size, in every component; its help text lines up
1829
+ * with its label. (It read an undefined --cmp-input-height and fell back to 48px.) */
1830
+ :is(input[data-oods-component='Checkbox'], [data-oods-component] input:is([type='checkbox'], [type='radio']), .oods-field input:is([type='checkbox'], [type='radio'])) {
1831
+ margin: 0;
1832
+ flex: 0 0 auto;
1833
+ inline-size: var(--sys-control-icon-size, 1rem);
1834
+ block-size: var(--sys-control-icon-size, 1rem);
1835
+ accent-color: var(--cmp-checkbox-background-checked, Highlight);
1836
+ }
1837
+ .oods-field.oods-checkbox > .oods-field-help,
1838
+ .oods-field.oods-checkbox > .oods-field-error { padding-inline-start: calc(var(--sys-control-icon-size, 1rem) + var(--cmp-checkbox-gap, 0.5rem)); }
1449
1839
  .workflow-field > input { width: 100%; min-width: 0; box-sizing: border-box; font: inherit; }
1450
1840
 
1451
1841
  /* Catalog choices may have long labels; form grids must shrink with their screen. */
@@ -1457,11 +1847,13 @@ input[data-oods-component='Checkbox'], .oods-field input[type='checkbox'] { marg
1457
1847
  * places by the page gutter, and the composer's page-level regions carry no side padding of their own, so a heading,
1458
1848
  * the controls under it and the cards below share one edge. The page's own heading reads as a detail page's does. */
1459
1849
  [data-oods-shell] { display: block; box-sizing: border-box; padding: var(--sys-page-gutter, 1.5rem); }
1850
+ /* s222-m02 (#2502 ruling 8): the page title is heading-xl (30/36 600), as a detail page's is. */
1460
1851
  [data-oods-shell-heading] {
1461
- margin: 0 0 var(--sys-stack-md, 1rem);
1462
- font-size: var(--sys-text-scale-heading-lg-font-size, 1.5rem);
1463
- font-weight: var(--ref-typography-weights-semibold, 600);
1464
- line-height: var(--sys-text-scale-heading-lg-line-height, 1.2);
1852
+ margin: 0 0 var(--sys-stack-lg, 1.5rem);
1853
+ font-size: var(--sys-text-scale-heading-xl-font-size, 30px);
1854
+ font-weight: var(--sys-text-scale-heading-xl-font-weight, 600);
1855
+ line-height: var(--sys-text-scale-heading-xl-line-height, 36px);
1856
+ letter-spacing: var(--sys-text-scale-heading-xl-letter-spacing);
1465
1857
  }
1466
1858
 
1467
1859
  /* s211-m02: a tab label never breaks inside a word ("Ru/n" at 390); a list with more tabs than fit scrolls instead, and
@@ -1473,6 +1865,7 @@ input[data-oods-component='Checkbox'], .oods-field input[type='checkbox'] { marg
1473
1865
  * event (on the event, not also on its list item) and a quieter time under its label. The frozen block above stays. */
1474
1866
  :where([data-oods-component='StatusTimeline'], [data-oods-component='AuditTimeline']) { gap: var(--sys-stack-sm, 0.75rem); }
1475
1867
  :where([data-oods-component='StatusTimeline'], [data-oods-component='AuditTimeline']) > :is(h2, p) { margin: 0; }
1868
+ :where([data-oods-component='StatusTimeline'], [data-oods-component='AuditTimeline']) > h2 { font-size: var(--sys-text-scale-heading-md-font-size, 18px); font-weight: var(--sys-text-scale-heading-md-font-weight, 600); line-height: var(--sys-text-scale-heading-md-line-height, 24px); }
1476
1869
  :where([data-oods-component='StatusTimeline'], [data-oods-component='AuditTimeline']) ol { list-style: none; padding-inline-start: 0; }
1477
1870
  :where([data-oods-component='StatusTimeline'], [data-oods-component='AuditTimeline']) li { border-inline-start: 0; padding-inline-start: 0; }
1478
1871
  :where([data-oods-component='StatusTimeline'], [data-oods-component='AuditTimeline']) article {
@@ -1502,12 +1895,125 @@ input[data-oods-component='Checkbox'], .oods-field input[type='checkbox'] { marg
1502
1895
  [data-oods-reference-inspection] code { overflow-wrap: anywhere; }
1503
1896
 
1504
1897
  /* A destructive action remains distinguishable when every action uses the
1505
- * user's HC system colors: shape and a warning glyph carry the distinction. */
1506
- [data-theme='hc'] :where(.oods-button, [data-oods-component='Button'])[data-intent='danger']:not(:disabled):not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *)) {
1507
- border: 3px double CanvasText;
1898
+ * user's HC system colors: a warning glyph carries the distinction (s222-m01: with the 1px CanvasText border every
1899
+ * non-primary intent has; s222-m02: the destructive variant too, which shares danger's fill). */
1900
+ [data-theme='hc'] :where(.oods-button, [data-oods-component='Button']):is([data-intent='danger'], [data-intent='destructive']):not(:disabled):not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *)) {
1901
+ border: 1px solid CanvasText;
1508
1902
  background: Canvas;
1509
1903
  color: CanvasText;
1510
1904
  }
1511
- [data-theme='hc'] :where(.oods-button, [data-oods-component='Button'])[data-intent='danger']:not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *))::before {
1905
+ [data-theme='hc'] :where(.oods-button, [data-oods-component='Button']):is([data-intent='danger'], [data-intent='destructive']):not(:where([data-theme='hc'] [data-theme]:not([data-theme='hc']) *))::before {
1512
1906
  content: "⚠" / "";
1513
1907
  }
1908
+
1909
+ /* ─── s222-m02 F7 (#2502 ruling 12): a placed chart follows the theme ─────────────────────────────────────────────────
1910
+ * A placed chart carries its renders in each theme, each set in a [data-viz-theme] wrapper (vizPreviewLayers in
1911
+ * @oods/component-contracts; the wrapper repeats data-viz-narrow and data-viz-wide, so the size rules above apply inside
1912
+ * it). Each [data-theme] names its theme for the charts under it, and custom properties inherit, so the nearest
1913
+ * [data-theme] decides: dark shows the dark renders, hc the hc ones, any other theme the light ones. With no [data-theme]
1914
+ * on the page the light renders show. A chart without dark or hc renders has no wrapper and shows in every theme. */
1915
+ :where([data-theme]) { --oods-viz-show-light: block; --oods-viz-show-dark: none; --oods-viz-show-hc: none; }
1916
+ :where([data-theme='dark']) { --oods-viz-show-light: none; --oods-viz-show-dark: block; }
1917
+ :where([data-theme='hc']) { --oods-viz-show-light: none; --oods-viz-show-hc: block; }
1918
+ :where([data-viz-theme]) { min-inline-size: 0; }
1919
+ :where([data-viz-theme='light']) { display: var(--oods-viz-show-light, block); }
1920
+ :where([data-viz-theme='dark']) { display: var(--oods-viz-show-dark, none); }
1921
+ :where([data-viz-theme='hc']) { display: var(--oods-viz-show-hc, none); }
1922
+ /* ─── end s222-m02 F7 ──────────────────────────────────────────────────────────────────────────────────────────────── */
1923
+
1924
+ /* ─── s222-m03 (#2502 ruling 13): screens read as a product ──────────────────────────────────────────────────────────
1925
+ * A detail page's header: the record's title and its summary (status and key meta) on the left and the screen's actions
1926
+ * on the right, on one row from 48rem; the sections below it take the full width. The generated stack sets its own
1927
+ * display inline, so the grid is set here with !important, as the read-only rows' columns are (s221-m02). */
1928
+ @media (min-width: 48rem) {
1929
+ [data-oods-component='Stack']:has(> [data-oods-component='DetailHeader']):has(> .oods-action-bar) {
1930
+ display: grid !important;
1931
+ grid-template-columns: minmax(0, 1fr) auto;
1932
+ align-items: start;
1933
+ }
1934
+ [data-oods-component='Stack']:has(> [data-oods-component='DetailHeader']):has(> .oods-action-bar) > * { grid-column: 1 / -1; }
1935
+ [data-oods-component='Stack']:has(> [data-oods-component='DetailHeader']):has(> .oods-action-bar) > [data-oods-component='DetailHeader'] { grid-column: 1; grid-row: 1; }
1936
+ [data-oods-component='Stack']:has(> [data-oods-component='DetailHeader']):has(> .oods-action-bar) > [data-oods-component='Stack'][id$='-record-summary'] { grid-column: 1; grid-row: 2; }
1937
+ [data-oods-component='Stack']:has(> [data-oods-component='DetailHeader']):has(> .oods-action-bar) > .oods-action-bar { grid-column: 2; grid-row: 1 / span 2; justify-self: end; }
1938
+ }
1939
+
1940
+ /* Never a card inside a card: a panel placed inside a card (a tab panel's billing cycle or payments, a summary in a
1941
+ * card's body) is a section of that card. It keeps its heading and content and drops its own border, fill, radius and
1942
+ * inset; the card's gap separates it from its neighbours. */
1943
+ :where(.oods-card, [data-oods-component='Card']) :is(.oods-card, [data-oods-component='Card'], [data-oods-component='AddressCollectionPanel'], [data-oods-component='ClassificationPanel'], [data-oods-component='MembershipPanel'], [data-oods-component='PreferencePanel'], [data-oods-component='FilterPanel'], [data-oods-component='ArchiveSummary'], [data-oods-component='OwnershipSummary'], [data-oods-component='TagSummary'], [data-oods-component='PriceSummary'], [data-oods-component='CancellationSummary'], [data-oods-component='AuditSummaryCard'], [data-oods-component='CycleProgressCard'], [data-oods-component='PaymentTimeline'], [data-oods-component='PaymentEventTimeline'], [data-oods-component='AddressValidationTimeline'], [data-oods-component='MembershipAuditTimeline'], [data-oods-component='MessageEventTimeline'], [data-oods-component='PreferenceTimeline'], .oods-trait-recipe) {
1944
+ padding: 0;
1945
+ border: 0;
1946
+ border-radius: 0;
1947
+ background: transparent;
1948
+ box-shadow: none;
1949
+ }
1950
+
1951
+ /* A list reads as one list: its rows sit in one bordered container on the raised surface, divided by hairlines. A row
1952
+ * is the record's title (500) over its muted secondary line on the left, then its status, meta and time, which the
1953
+ * title's growth pushes to the right. */
1954
+ [data-oods-collection='rows'] > .oods-collection {
1955
+ gap: 0;
1956
+ border: 1px solid var(--sys-border-subtle, CanvasText);
1957
+ border-radius: var(--sys-radius-control-lg, 8px);
1958
+ background: var(--sys-surface-raised, Canvas);
1959
+ overflow: hidden;
1960
+ }
1961
+ [data-oods-collection='rows'] > .oods-collection > li:not(:last-child) { border-block-end: 1px solid var(--sys-border-subtle, CanvasText); }
1962
+ [data-oods-collection='rows'] > .oods-collection .oods-collection-row {
1963
+ --oods-button-border: transparent;
1964
+ --oods-button-background: transparent;
1965
+ --oods-button-background-hover: var(--sys-surface-subtle, Canvas);
1966
+ --oods-button-background-pressed: var(--sys-surface-interactive-secondary-default, Canvas);
1967
+ justify-content: flex-start;
1968
+ padding: var(--sys-inset-sm, 0.75rem) var(--sys-inset-md, 1rem);
1969
+ border-radius: 0;
1970
+ font-weight: var(--sys-text-scale-body-sm-font-weight, 400);
1971
+ }
1972
+ [data-oods-collection='rows'] > .oods-collection .oods-collection-row > :first-child {
1973
+ gap: var(--sys-control-gap-compact, 0.25rem);
1974
+ font-size: var(--sys-text-scale-body-sm-font-size, 14px);
1975
+ line-height: var(--sys-text-scale-body-sm-line-height, 20px);
1976
+ font-weight: var(--sys-text-scale-label-font-weight, 500);
1977
+ }
1978
+ [data-oods-collection='rows'] > .oods-collection .oods-collection-row > :first-child > * { margin: 0; font-size: inherit; line-height: inherit; }
1979
+ /* Money in a row reads as text beside the status, as the time does, not as a tag. */
1980
+ [data-oods-collection='rows'] > .oods-collection .oods-collection-row > :is([data-oods-component='PriceBadge'], [data-oods-component='BillingSummaryBadge']) {
1981
+ padding: 0;
1982
+ background: transparent;
1983
+ color: var(--sys-text-primary, CanvasText);
1984
+ font-size: var(--sys-text-scale-body-sm-font-size, 14px);
1985
+ line-height: var(--sys-text-scale-body-sm-line-height, 20px);
1986
+ font-variant-numeric: tabular-nums;
1987
+ }
1988
+ [data-oods-collection='rows'] > .oods-collection .oods-collection-row > :first-child :is([data-size='sm'], [data-oods-component='Text'] + [data-oods-component='Text']) { color: var(--sys-text-muted, GrayText); font-weight: var(--sys-text-scale-body-sm-font-weight, 400); }
1989
+ [data-oods-collection='rows'] > .oods-collection .oods-collection-row :is(time, [data-oods-component='RelativeTimestamp']) { color: var(--sys-text-muted, GrayText); font-size: var(--sys-text-scale-body-sm-font-size, 14px); }
1990
+ /* The time reads last, after the status and meta. On a phone the title takes the first line and the status, meta and time
1991
+ * wrap together under it, instead of one line each. */
1992
+ [data-oods-collection='rows'] > .oods-collection .oods-collection-row > :is(time, [data-oods-component='RelativeTimestamp']) { order: 1; }
1993
+ @media (max-width: 600px) {
1994
+ [data-oods-collection='rows'] > .oods-collection .oods-collection-row { flex-direction: row; align-items: center; column-gap: var(--sys-control-gap, 0.5rem); row-gap: var(--sys-control-gap-compact, 0.25rem); }
1995
+ [data-oods-collection='rows'] > .oods-collection .oods-collection-row > :first-child { flex: none; inline-size: 100%; }
1996
+ }
1997
+ /* An archived row inside the list keeps its dimming and badge; the list's container and dividers are its border. */
1998
+ [data-oods-collection='rows'] > .oods-collection [data-oods-component='ArchivedRowOverlay'][data-archived='true']:has(> .oods-collection-row) { border: 0; border-radius: 0; background: transparent; }
1999
+ /* A section of a card that holds nothing (an unfilled body slot) takes no room, so the card's own spacing is all there is
2000
+ * between its header and footer. */
2001
+ :where(.oods-card, [data-oods-component='Card']) [data-oods-component='Stack']:not(:has(:not([data-oods-component='Stack']))) { display: none !important; }
2002
+
2003
+ /* A record's events read as one timeline: each event sits on a rail at the left instead of in a card of its own. */
2004
+ [data-oods-collection='events'] > .oods-collection { gap: 0; }
2005
+ [data-oods-collection='events'] > .oods-collection > li > :is(.oods-card, [data-oods-component='Card']) {
2006
+ gap: var(--sys-control-gap-compact, 0.25rem);
2007
+ padding: 0 0 var(--sys-stack-md, 1rem) var(--sys-inset-md, 1rem);
2008
+ border: 0;
2009
+ border-inline-start: var(--ref-border-width-bold, 2px) solid var(--sys-border-strong, CanvasText);
2010
+ border-radius: 0;
2011
+ background: transparent;
2012
+ }
2013
+ [data-oods-collection='events'] > .oods-collection > li:last-child > :is(.oods-card, [data-oods-component='Card']) { padding-block-end: 0; }
2014
+ [data-oods-collection='events'] > .oods-collection time { color: var(--sys-text-muted, GrayText); font-size: var(--sys-text-scale-body-sm-font-size, 14px); }
2015
+ /* An event's title reads at the list title's weight in every renderer (React and Vue write a plain strong; HTML's Text
2016
+ * inherits its weight). */
2017
+ [data-oods-collection='events'] > .oods-collection > li > :is(.oods-card, [data-oods-component='Card']) > strong { font-weight: var(--sys-text-scale-label-font-weight, 500); }
2018
+
2019
+ /* ─── end s222-m03 ──────────────────────────────────────────────────────────────────────────────────────────────── */