@oods/component-styles 0.3.3 → 0.4.0

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