@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.83 → 2.0.0-next.84

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.
@@ -7,246 +7,513 @@
7
7
  width: 100%;
8
8
  }
9
9
 
10
+ /* ---------- Root / surface ----------
11
+ * `.root` is the touch target (a <button> when clickable, otherwise a <div>).
12
+ * `.surface` is the visible box that carries padding, corner radius, the
13
+ * data-quality background/border, and — when clickable — the flat interaction
14
+ * states. */
10
15
  .root {
16
+ display: block;
17
+ inline-size: 100%;
18
+ margin: 0;
19
+ /* Neutralise the native <button> chrome (default padding + appearance) when
20
+ `.root` is the clickable touch target, so clickable rows don't inset their
21
+ `.surface` and misalign with non-clickable `<div>` rows. */
22
+ padding: 0;
23
+ border: none;
24
+ background: none;
25
+ appearance: none;
26
+ font: inherit;
27
+ color: inherit;
28
+ text-align: inherit;
29
+ }
30
+
31
+ .root.clickable {
32
+ cursor: pointer;
33
+ /* prettier-ignore */
34
+ @mixin style style=flat visibleWrapperClass=.surface;
35
+ }
36
+
37
+ .root.clickable:focus {
38
+ outline: none;
39
+ }
40
+
41
+ /* Flip-flop: animate the value↔setpoint cap-height swap by forwarding obc-textbox's
42
+ opt-in size-transition var. 300ms matches the instrument setpoint marker
43
+ (svghelpers/setpoint.ts). Override via `--obc-readout-list-item-flip-flop-duration`. */
44
+ .root.flip-flop {
45
+ --obc-textbox-size-transition: var(
46
+ --obc-readout-list-item-flip-flop-duration,
47
+ 300ms
48
+ );
49
+ }
50
+
51
+ .surface {
52
+ display: block;
53
+ inline-size: 100%;
54
+ border-radius: var(--global-border-radius-border-radius-base);
55
+ }
56
+
57
+ /* Clickable corner variants. The `.clickable` qualifier is redundant for
58
+ matching (a `border-*` class is only ever set alongside `.clickable`) but
59
+ raises specificity to (0,4,0) so the interactive corner shape wins over the
60
+ data-quality rules below — which also target `.surface` at (0,3,0) — when a
61
+ row is both clickable and low-integrity/invalid. Standalone data-quality rows
62
+ keep their own radius. */
63
+ .root.clickable.border-squared .surface {
64
+ border-radius: 0;
65
+ }
66
+ .root.clickable.border-round-corners .surface {
67
+ border-radius: var(--global-border-radius-border-radius-floating);
68
+ }
69
+ .root.clickable.border-round .surface {
70
+ border-radius: var(--global-border-radius-border-radius-round);
71
+ }
72
+
73
+ /* ---------- Content row ----------
74
+ * Label on the left, value/unit cluster on the right, optional source after a
75
+ * trailing divider. All segments bottom-align so cap heights sit on a shared
76
+ * baseline. */
77
+ .content {
78
+ display: flex;
79
+ align-items: flex-end;
80
+ justify-content: space-between;
81
+ inline-size: 100%;
82
+ min-inline-size: 0;
83
+ }
84
+
85
+ /* Reserve the value cap-height per tier so the row height and the bottom
86
+ baseline stay constant regardless of which parts (label / value / unit / src /
87
+ setpoint / advice / icons) are present. */
88
+ .size-small .content {
89
+ min-block-size: var(
90
+ --global-typography-instrument-value-regular-container-height
91
+ );
92
+ }
93
+ .size-medium .content {
94
+ min-block-size: var(
95
+ --global-typography-instrument-value-medium-container-height
96
+ );
97
+ }
98
+ .size-large .content {
99
+ min-block-size: var(
100
+ --global-typography-instrument-value-large-container-height
101
+ );
102
+ }
103
+
104
+ /* The value is the primary data, so under width pressure the label side yields
105
+ first: the label-container shrinks (and clips a too-long label) while
106
+ `.value-area` keeps its intrinsic width. */
107
+ .label-container {
11
108
  display: inline-flex;
12
109
  align-items: flex-end;
13
- border-radius: var(--global-border-radius-border-radius-base);
14
- width: 100%;
110
+ gap: var(--global-size-spacing-target-padding);
111
+ flex: 1 1 auto;
112
+ min-inline-size: 0;
113
+ overflow: hidden;
114
+ }
115
+
116
+ .label-stack {
117
+ display: inline-flex;
118
+ flex-direction: column;
119
+ align-items: flex-start;
120
+ justify-content: flex-end;
121
+ min-inline-size: 0;
122
+ }
15
123
 
16
- .content {
17
- display: inline-flex;
18
- align-items: flex-end;
19
- justify-content: space-between;
20
- flex: 1 1 auto;
21
- min-width: 0;
22
- max-width: none;
23
- width: 100%;
24
- }
25
-
26
- .label-container {
27
- display: inline-flex;
28
- align-items: flex-end;
29
- gap: var(--global-size-spacing-target-padding);
30
- flex: none;
31
- }
32
-
33
- .leading-icon {
34
- display: inline-flex;
35
- align-items: center;
36
- justify-content: center;
37
- color: var(--element-neutral-color);
38
- }
39
-
40
- .label-stack {
41
- display: inline-flex;
42
- flex-direction: column;
43
- align-items: flex-start;
44
- justify-content: flex-end;
45
- }
46
-
47
- .label-inline {
48
- display: inline-flex;
49
- align-items: center;
50
- gap: var(--global-size-spacing-target-padding);
51
- }
52
-
53
- .label {
54
- @mixin font-instrument-label;
55
- @mixin font-instrument-label-box;
56
- font-size: var(--global-typography-instrument-label-font-size);
57
- line-height: var(--global-typography-instrument-label-line-height);
58
- color: var(--element-inactive-color);
59
- }
60
-
61
- .unit,
62
- .source {
63
- @mixin font-instrument-unit;
64
- @mixin font-instrument-unit-box;
65
- font-size: var(--global-typography-instrument-unit-font-size);
66
- line-height: var(--global-typography-instrument-unit-line-height);
67
- }
68
-
69
- .unit {
70
- color: var(--element-inactive-color);
71
- }
72
-
73
- .source {
74
- color: var(--element-neutral-color);
75
- }
76
-
77
- .value-container {
78
- display: inline-flex;
79
- align-items: flex-end;
80
- justify-content: flex-end;
81
- flex: 1 1 auto;
82
- min-width: 0;
83
- }
84
-
85
- .value-wrap {
86
- display: inline-flex;
87
- align-items: flex-end;
88
- justify-content: flex-end;
89
- }
90
-
91
- .value-cluster {
92
- display: inline-flex;
93
- align-items: flex-end;
94
- justify-content: flex-end;
95
- gap: var(
96
- --instrument-components-readout-new-list-item-medium-value-container-gap
97
- );
98
- }
99
-
100
- .value-icon {
101
- display: inline-flex;
102
- align-items: center;
103
- justify-content: center;
104
- color: inherit;
105
- }
106
-
107
- .divider {
108
- flex: none;
109
- inline-size: 1px;
110
- background-color: var(--border-outline-color);
111
- align-self: stretch;
112
- }
113
-
114
- .unit-trailing {
115
- display: inline-flex;
116
- align-items: flex-end;
117
- }
118
-
119
- .source-trailing {
120
- display: inline-flex;
121
- align-items: center;
122
- justify-content: flex-end;
123
- padding-inline: calc(var(--global-size-spacing-target-padding) / 2);
124
- }
125
-
126
- &.size-base {
127
- padding-inline: var(
128
- --instrument-components-readout-new-list-item-regular-container-padding-horizontal
129
- );
130
- padding-block: 0;
131
-
132
- .content {
133
- gap: var(
134
- --instrument-components-readout-new-list-item-regular-content-container-gap
135
- );
136
- }
137
-
138
- .value-cluster {
139
- gap: var(
140
- --instrument-components-readout-new-list-item-regular-value-container-gap
141
- );
142
- }
143
-
144
- &.stacking-leading-src .content {
145
- gap: var(--global-size-spacing-target-padding);
146
- }
147
-
148
- .divider {
149
- block-size: var(
150
- --global-typography-instrument-value-regular-container-height
151
- );
152
- }
153
- }
154
-
155
- &.size-priority {
156
- padding-inline: var(
157
- --instrument-components-readout-new-list-item-medium-container-padding-horizontal
158
- );
159
- padding-block: var(
160
- --instrument-components-readout-new-list-item-medium-container-padding-vertical
161
- );
162
-
163
- .content {
164
- gap: var(
165
- --instrument-components-readout-new-list-item-medium-content-container-gap
166
- );
167
- }
168
-
169
- .divider {
170
- block-size: var(
171
- --global-typography-instrument-value-medium-container-height
172
- );
173
- }
174
- }
175
-
176
- &.size-enhanced {
177
- padding-inline: var(
178
- --instrument-components-readout-new-list-item-large-container-padding-horizontal
179
- );
180
- padding-block: var(
181
- --instrument-components-readout-new-list-item-large-container-padding-vertical
182
- );
183
-
184
- .content {
185
- gap: var(--instrument-components-readout-new-list-item-large-content-gap);
186
- }
187
-
188
- .value-cluster {
189
- gap: var(--instrument-components-readout-new-list-item-large-value-gap);
190
- }
191
-
192
- .divider {
193
- block-size: var(
194
- --global-typography-instrument-value-large-container-height
195
- );
196
- }
197
- }
198
-
199
- &.size-enhanced.stacking-leading-unit {
200
- .label-container {
201
- align-items: center;
202
- }
203
-
204
- .label-stack {
205
- justify-content: flex-end;
206
- }
207
-
208
- .unit-leading {
209
- margin-top: 0;
210
- }
211
- }
212
-
213
- &.stacking-leading-unit {
214
- .unit-trailing {
215
- display: none;
216
- }
217
- }
218
-
219
- &.stacking-leading-src {
220
- .source-inline {
221
- display: inline-flex;
222
- align-items: center;
223
- justify-content: flex-end;
224
- }
225
-
226
- :is(.divider, .source-trailing) {
227
- display: none;
228
- }
229
- }
230
-
231
- &:is(.data-low-integrity, .data-invalid) {
232
- background: var(--_obc-readout-list-item-data-background);
233
- border: 1px solid var(--_obc-readout-list-item-data-border);
234
- border-radius: 4px;
235
- }
236
-
237
- &.data-low-integrity {
238
- --_obc-readout-list-item-data-background: var(
239
- --alert-low-integrity-background-color
240
- );
241
- --_obc-readout-list-item-data-border: var(
242
- --alert-low-integrity-border-color
243
- );
244
- }
245
-
246
- &.data-invalid {
247
- --_obc-readout-list-item-data-background: var(
248
- --alert-invalid-background-color
249
- );
250
- --_obc-readout-list-item-data-border: var(--alert-invalid-border-color);
251
- }
124
+ .value-area {
125
+ display: inline-flex;
126
+ align-items: flex-end;
127
+ justify-content: flex-end;
128
+ flex: 0 0 auto;
129
+ min-inline-size: 0;
130
+ }
131
+
132
+ .value-cluster {
133
+ display: inline-flex;
134
+ align-items: flex-end;
135
+ justify-content: flex-end;
136
+ }
137
+
138
+ .unit-area {
139
+ display: inline-flex;
140
+ align-items: flex-end;
141
+ }
142
+
143
+ /* ---------- Readout building block (advice / setpoint / value) ---------- */
144
+ .block {
145
+ display: inline-flex;
146
+ align-items: flex-end;
147
+ }
148
+
149
+ /* Number + its (setpoint/advice) degree glyph, hugging with no gap — the
150
+ `.block` gap only separates the icon from this group. */
151
+ .block-content {
152
+ display: inline-flex;
153
+ align-items: flex-end;
154
+ }
155
+
156
+ .block-icon {
157
+ display: inline-flex;
158
+ align-items: center;
159
+ justify-content: center;
160
+ flex: none;
161
+ color: inherit;
162
+ /* Centre the icon against the block's text rather than bottom-aligning it (the
163
+ block is flex-end). Matters for the value block, whose text is taller than
164
+ the icon, so the value icon lines up with the number like the smaller
165
+ setpoint/advice icons do. */
166
+ align-self: center;
167
+ }
168
+
169
+ .block-icon obi-input-right,
170
+ .block-icon obi-notification-advice,
171
+ .block-icon ::slotted(*) {
172
+ display: block;
173
+ inline-size: 100%;
174
+ block-size: 100%;
175
+ }
176
+
177
+ .hinted-zero {
178
+ color: var(
179
+ --obc-readout-list-item-hinted-color,
180
+ var(--element-inactive-color)
181
+ );
182
+ }
183
+
184
+ /* ---------- Text colours (overridable via custom properties) ----------
185
+ * obc-textbox does not set its own colour, so it inherits these. */
186
+ .block-value {
187
+ color: var(--obc-readout-list-item-value-color, var(--element-neutral-color));
188
+ }
189
+ .block-value.tone-enhanced {
190
+ color: var(
191
+ --obc-readout-list-item-value-enhanced-color,
192
+ var(--element-neutral-enhanced-color)
193
+ );
194
+ }
195
+ /* The setpoint shares the value's colour state: neutral by default, enhanced
196
+ (blue) only when the row is enhanced — never a blue setpoint next to a grey
197
+ value. `--instrument-enhanced-secondary-color` is the same #2d548b as the
198
+ value's `--element-neutral-enhanced-color`. */
199
+ .block-setpoint {
200
+ color: var(
201
+ --obc-readout-list-item-setpoint-color,
202
+ var(--element-neutral-color)
203
+ );
204
+ /* Flip-flop emphasis + pop-up fade animate at 100ms. */
205
+ transition:
206
+ opacity 100ms ease,
207
+ color 100ms ease;
208
+ }
209
+ .block-setpoint.tone-enhanced {
210
+ color: var(
211
+ --obc-readout-list-item-setpoint-enhanced-color,
212
+ var(--instrument-enhanced-secondary-color)
213
+ );
214
+ }
215
+ /* Pop-up: fade the setpoint out once value === setpoint, keeping its space so
216
+ the value stays column-aligned. */
217
+ .block-setpoint.is-hiding {
218
+ opacity: 0;
219
+ }
220
+ .block-setpoint.is-hidden {
221
+ opacity: 0;
222
+ visibility: hidden;
223
+ }
224
+ /* Touching / focus state: the setpoint triangle takes the marker's focus look — a
225
+ pale fill (--base-blue-100) with a dark 1px edge (--element-neutral-enhanced),
226
+ mirroring `svghelpers/setpoint.ts` focus (fill base-blue-100 + 2px stroke).
227
+ The glyph icon is `fill: currentColor` and can't take a CSS `stroke`, so the
228
+ edge is layered drop-shadows. The setpoint number keeps its normal, readable
229
+ colour. */
230
+ .block-setpoint.touching {
231
+ --_touching-outline: var(
232
+ --obc-readout-list-item-setpoint-touching-outline-color,
233
+ var(--element-neutral-enhanced-color)
234
+ );
235
+ }
236
+ .block-setpoint.touching .block-icon {
237
+ color: var(
238
+ --obc-readout-list-item-setpoint-touching-color,
239
+ var(--base-blue-100)
240
+ );
241
+ filter: drop-shadow(1px 0 0 var(--_touching-outline))
242
+ drop-shadow(-1px 0 0 var(--_touching-outline))
243
+ drop-shadow(0 1px 0 var(--_touching-outline))
244
+ drop-shadow(0 -1px 0 var(--_touching-outline));
245
+ }
246
+ .block-advice {
247
+ color: var(
248
+ --obc-readout-list-item-advice-color,
249
+ var(--element-neutral-color)
250
+ );
251
+ }
252
+
253
+ .label {
254
+ color: var(
255
+ --obc-readout-list-item-label-color,
256
+ var(--element-inactive-color)
257
+ );
258
+ }
259
+ .unit {
260
+ color: var(--obc-readout-list-item-unit-color, var(--element-inactive-color));
261
+ }
262
+ .source {
263
+ color: var(
264
+ --obc-readout-list-item-source-color,
265
+ var(--element-neutral-color)
266
+ );
267
+ }
268
+
269
+ /* ---------- Per-block data quality ----------
270
+ * Independent of (and nests inside) the row-level data-quality frame. Uses
271
+ * `outline` (not `border`) so the chip never shifts the block's width — the
272
+ * value stays column-aligned across rows. */
273
+ .block.data-low-integrity,
274
+ .block.data-invalid,
275
+ .source.data-low-integrity,
276
+ .source.data-invalid {
277
+ outline: 1px solid;
278
+ border-radius: var(--global-border-radius-border-radius-check);
279
+ }
280
+ .block.data-low-integrity,
281
+ .source.data-low-integrity {
282
+ background: var(--alert-low-integrity-background-color);
283
+ outline-color: var(--alert-low-integrity-border-color);
284
+ }
285
+ .block.data-invalid,
286
+ .source.data-invalid {
287
+ background: var(--alert-invalid-background-color);
288
+ outline-color: var(--alert-invalid-border-color);
289
+ }
290
+
291
+ .leading-icon {
292
+ display: inline-flex;
293
+ align-items: center;
294
+ justify-content: center;
295
+ flex: none;
296
+ color: var(--element-neutral-color);
297
+ }
298
+ .leading-icon ::slotted(*) {
299
+ display: block;
300
+ inline-size: 100%;
301
+ block-size: 100%;
302
+ }
303
+
304
+ .divider {
305
+ flex: none;
306
+ inline-size: 1px;
307
+ background-color: var(--border-outline-color);
308
+ align-self: stretch;
309
+ }
310
+
311
+ /* ---------- Value↔unit gap & degree column ----------
312
+ * Default 2px between the value digits and the unit. A degree (or a
313
+ * hasDegreeSpacer reserve) replaces the 2px with a cap-height degree column
314
+ * whose width scales with the value size, so value digits + units align across
315
+ * degree / no-degree rows of the same value size. */
316
+ .value-unit-gap {
317
+ flex: none;
318
+ inline-size: var(
319
+ --instrument-components-readout-new-general-horizontal-trim-padding
320
+ );
321
+ }
322
+
323
+ .degree-column {
324
+ flex: none;
325
+ display: inline-flex;
326
+ align-items: flex-end;
327
+ justify-content: center;
328
+ inline-size: var(--_obc-readout-list-item-degree-width, 0);
329
+ overflow: clip;
330
+ color: var(--obc-readout-list-item-value-color, var(--element-neutral-color));
331
+ }
332
+ .degree-column.tone-enhanced {
333
+ color: var(
334
+ --obc-readout-list-item-value-enhanced-color,
335
+ var(--element-neutral-enhanced-color)
336
+ );
337
+ }
338
+ /* Setpoint/advice degree glyphs inherit their block's colour. */
339
+ .degree-column.degree-inherit {
340
+ color: inherit;
341
+ }
342
+ .degree-column.degree-xs {
343
+ --_obc-readout-list-item-degree-width: var(
344
+ --global-typography-instrument-value-small-degree-unit-width
345
+ );
346
+ }
347
+ .degree-column.degree-s {
348
+ --_obc-readout-list-item-degree-width: var(
349
+ --global-typography-instrument-value-regular-degree-unit-width
350
+ );
351
+ }
352
+ .degree-column.degree-m {
353
+ --_obc-readout-list-item-degree-width: var(
354
+ --global-typography-instrument-value-medium-degree-unit-width
355
+ );
356
+ }
357
+ .degree-column.degree-l,
358
+ .degree-column.degree-xl {
359
+ --_obc-readout-list-item-degree-width: var(
360
+ --global-typography-instrument-value-large-degree-unit-width
361
+ );
362
+ }
363
+
364
+ /* Degree spacer: rendered AFTER the unit on a non-degree row that sets
365
+ hasDegreeSpacer. Its width (degree-compensation-padding = degree-column width
366
+ minus the 2px value↔unit gap) shifts the unit left so the row's value digits
367
+ stay aligned with degree rows in the same column. */
368
+ .degree-spacer {
369
+ flex: none;
370
+ align-self: stretch;
371
+ inline-size: var(--_obc-readout-list-item-degree-spacer-width, 0);
372
+ }
373
+ .size-small .degree-spacer {
374
+ --_obc-readout-list-item-degree-spacer-width: var(
375
+ --instrument-components-readout-new-list-item-regular-degree-compensation-padding
376
+ );
377
+ }
378
+ .size-medium .degree-spacer {
379
+ --_obc-readout-list-item-degree-spacer-width: var(
380
+ --instrument-components-readout-new-list-item-medium-degree-compensation-padding
381
+ );
382
+ }
383
+ .size-large .degree-spacer {
384
+ --_obc-readout-list-item-degree-spacer-width: var(
385
+ --instrument-components-readout-new-list-item-large-degree-compensation-padding
386
+ );
387
+ }
388
+
389
+ /* ---------- Size tiers ----------
390
+ * Public small/medium/large map to the design token regular/medium/large
391
+ * tiers. */
392
+ .size-small .surface {
393
+ padding-inline: var(
394
+ --instrument-components-readout-new-list-item-regular-container-padding-horizontal
395
+ );
396
+ padding-block: var(
397
+ --instrument-components-readout-new-list-item-regular-container-padding-vertical
398
+ );
399
+ }
400
+ .size-small .content {
401
+ gap: var(
402
+ --instrument-components-readout-new-list-item-regular-content-container-gap
403
+ );
404
+ }
405
+ .size-small .value-cluster {
406
+ gap: var(
407
+ --instrument-components-readout-new-list-item-regular-value-container-gap
408
+ );
409
+ }
410
+ .size-small .block {
411
+ gap: var(--instrument-components-readout-new-general-regular-icon-gap);
412
+ }
413
+ .size-small .block-icon,
414
+ .size-small .leading-icon {
415
+ inline-size: var(
416
+ --instrument-components-readout-new-general-regular-icon-size
417
+ );
418
+ block-size: var(
419
+ --instrument-components-readout-new-general-regular-icon-size
420
+ );
421
+ }
422
+ .size-small .divider {
423
+ block-size: var(
424
+ --global-typography-instrument-value-regular-container-height
425
+ );
426
+ }
427
+
428
+ .size-medium .surface {
429
+ padding-inline: var(
430
+ --instrument-components-readout-new-list-item-medium-container-padding-horizontal
431
+ );
432
+ padding-block: var(
433
+ --instrument-components-readout-new-list-item-medium-container-padding-vertical
434
+ );
435
+ }
436
+ .size-medium .content {
437
+ gap: var(
438
+ --instrument-components-readout-new-list-item-medium-content-container-gap
439
+ );
440
+ }
441
+ .size-medium .value-cluster {
442
+ gap: var(
443
+ --instrument-components-readout-new-list-item-medium-value-container-gap
444
+ );
445
+ }
446
+ .size-medium .block {
447
+ gap: var(--instrument-components-readout-new-general-medium-icon-gap);
448
+ }
449
+ .size-medium .block-icon,
450
+ .size-medium .leading-icon {
451
+ inline-size: var(
452
+ --instrument-components-readout-new-general-medium-icon-size
453
+ );
454
+ block-size: var(--instrument-components-readout-new-general-medium-icon-size);
455
+ }
456
+ .size-medium .divider {
457
+ block-size: var(--global-typography-instrument-value-medium-container-height);
458
+ }
459
+
460
+ .size-large .surface {
461
+ padding-inline: var(
462
+ --instrument-components-readout-new-list-item-large-container-padding-horizontal
463
+ );
464
+ padding-block: var(
465
+ --instrument-components-readout-new-list-item-large-container-padding-vertical
466
+ );
467
+ min-block-size: var(
468
+ --instrument-components-readout-new-list-item-large-min-height
469
+ );
470
+ }
471
+ .size-large .content {
472
+ gap: var(--instrument-components-readout-new-list-item-large-content-gap);
473
+ }
474
+ .size-large .value-cluster {
475
+ gap: var(--instrument-components-readout-new-list-item-large-value-gap);
476
+ }
477
+ .size-large .block {
478
+ gap: var(--instrument-components-readout-new-general-large-icon-gap);
479
+ }
480
+ .size-large .block-icon,
481
+ .size-large .leading-icon {
482
+ inline-size: var(--instrument-components-readout-new-general-large-icon-size);
483
+ block-size: var(--instrument-components-readout-new-general-large-icon-size);
484
+ }
485
+ .size-large .divider {
486
+ block-size: var(--global-typography-instrument-value-large-container-height);
487
+ }
488
+
489
+ /* ---------- Stacking ----------
490
+ * leading-unit / leading-src move the unit / source up beside the label and
491
+ * suppress the trailing variant. (Handled in markup; these rules tighten the
492
+ * label-stack gap.) */
493
+ .stacking-leading-src .content {
494
+ gap: var(--global-size-spacing-target-padding);
495
+ }
496
+
497
+ /* ---------- Data quality ----------
498
+ * Orthogonal to the alert frame — both can apply at once. */
499
+ .root.data-low-integrity .surface,
500
+ .root.data-invalid .surface {
501
+ /* `outline` (not `border`) so the data-quality frame does not inset the
502
+ content by 1px — keeps the row's value column-aligned with unframed rows.
503
+ Matches the per-block data-quality rules. */
504
+ outline: 1px solid var(--_obc-readout-list-item-data-border);
505
+ background: var(--_obc-readout-list-item-data-background);
506
+ border-radius: var(--global-border-radius-border-radius-check);
507
+ }
508
+ .root.data-low-integrity {
509
+ --_obc-readout-list-item-data-background: var(
510
+ --alert-low-integrity-background-color
511
+ );
512
+ --_obc-readout-list-item-data-border: var(--alert-low-integrity-border-color);
513
+ }
514
+ .root.data-invalid {
515
+ --_obc-readout-list-item-data-background: var(
516
+ --alert-invalid-background-color
517
+ );
518
+ --_obc-readout-list-item-data-border: var(--alert-invalid-border-color);
252
519
  }