@ponchia/ui 0.6.9 → 0.6.11

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.
Files changed (145) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/README.md +38 -25
  3. package/annotations/index.d.ts +15 -15
  4. package/annotations/index.d.ts.map +1 -1
  5. package/annotations/index.js +52 -34
  6. package/behaviors/carousel.d.ts +7 -3
  7. package/behaviors/carousel.d.ts.map +1 -1
  8. package/behaviors/carousel.js +157 -27
  9. package/behaviors/combobox.d.ts +1 -1
  10. package/behaviors/combobox.d.ts.map +1 -1
  11. package/behaviors/combobox.js +46 -23
  12. package/behaviors/command.d.ts +1 -1
  13. package/behaviors/command.d.ts.map +1 -1
  14. package/behaviors/command.js +63 -23
  15. package/behaviors/connectors.d.ts.map +1 -1
  16. package/behaviors/connectors.js +126 -19
  17. package/behaviors/crosshair.d.ts.map +1 -1
  18. package/behaviors/crosshair.js +71 -8
  19. package/behaviors/dialog.d.ts.map +1 -1
  20. package/behaviors/dialog.js +20 -3
  21. package/behaviors/disclosure.d.ts.map +1 -1
  22. package/behaviors/disclosure.js +35 -6
  23. package/behaviors/dismissible.js +1 -1
  24. package/behaviors/forms.d.ts +23 -2
  25. package/behaviors/forms.d.ts.map +1 -1
  26. package/behaviors/forms.js +97 -9
  27. package/behaviors/glyph.d.ts.map +1 -1
  28. package/behaviors/glyph.js +56 -5
  29. package/behaviors/internal.d.ts.map +1 -1
  30. package/behaviors/internal.js +52 -5
  31. package/behaviors/menu.d.ts.map +1 -1
  32. package/behaviors/menu.js +2 -1
  33. package/behaviors/modal.d.ts.map +1 -1
  34. package/behaviors/modal.js +25 -9
  35. package/behaviors/popover.d.ts.map +1 -1
  36. package/behaviors/popover.js +8 -6
  37. package/behaviors/sources.d.ts.map +1 -1
  38. package/behaviors/sources.js +24 -3
  39. package/behaviors/splitter.d.ts.map +1 -1
  40. package/behaviors/splitter.js +27 -6
  41. package/behaviors/table.d.ts.map +1 -1
  42. package/behaviors/table.js +44 -7
  43. package/behaviors/tabs.d.ts.map +1 -1
  44. package/behaviors/tabs.js +51 -14
  45. package/behaviors/theme.d.ts.map +1 -1
  46. package/behaviors/theme.js +64 -4
  47. package/behaviors/toast.d.ts +6 -1
  48. package/behaviors/toast.d.ts.map +1 -1
  49. package/behaviors/toast.js +48 -12
  50. package/classes/classes.json +57 -2
  51. package/classes/index.d.ts +13 -2
  52. package/classes/index.js +88 -40
  53. package/connectors/index.d.ts +4 -4
  54. package/connectors/index.d.ts.map +1 -1
  55. package/connectors/index.js +14 -12
  56. package/css/annotations.css +1 -0
  57. package/css/app.css +7 -0
  58. package/css/base.css +3 -0
  59. package/css/bullet.css +41 -7
  60. package/css/code.css +14 -0
  61. package/css/command.css +10 -0
  62. package/css/dataviz.css +27 -0
  63. package/css/diff.css +2 -0
  64. package/css/disclosure.css +8 -0
  65. package/css/dots.css +1 -1
  66. package/css/feedback.css +9 -0
  67. package/css/interval.css +20 -2
  68. package/css/legend.css +10 -9
  69. package/css/marks.css +1 -0
  70. package/css/motion.css +2 -0
  71. package/css/overlay.css +14 -2
  72. package/css/primitives.css +1 -1
  73. package/css/report.css +3 -0
  74. package/css/sources.css +4 -4
  75. package/css/spotlight.css +6 -0
  76. package/css/table.css +19 -0
  77. package/css/term.css +4 -1
  78. package/css/tokens.css +8 -13
  79. package/css/workbench.css +128 -0
  80. package/dist/bronto.css +1 -1
  81. package/dist/css/analytical.css +1 -1
  82. package/dist/css/app.css +1 -1
  83. package/dist/css/bullet.css +1 -1
  84. package/dist/css/code.css +1 -1
  85. package/dist/css/command.css +1 -1
  86. package/dist/css/dataviz.css +1 -1
  87. package/dist/css/diff.css +1 -1
  88. package/dist/css/disclosure.css +1 -1
  89. package/dist/css/dots.css +1 -1
  90. package/dist/css/feedback.css +1 -1
  91. package/dist/css/interval.css +1 -1
  92. package/dist/css/legend.css +1 -1
  93. package/dist/css/marks.css +1 -1
  94. package/dist/css/overlay.css +1 -1
  95. package/dist/css/primitives.css +1 -1
  96. package/dist/css/report-kit.css +1 -1
  97. package/dist/css/sources.css +1 -1
  98. package/dist/css/spotlight.css +1 -1
  99. package/dist/css/table.css +1 -1
  100. package/dist/css/term.css +1 -1
  101. package/dist/css/tokens.css +1 -1
  102. package/dist/css/workbench.css +1 -1
  103. package/docs/annotations.md +27 -0
  104. package/docs/architecture.md +5 -3
  105. package/docs/bullet.md +6 -1
  106. package/docs/clamp.md +5 -0
  107. package/docs/command.md +3 -2
  108. package/docs/contrast.md +3 -3
  109. package/docs/crosshair.md +6 -0
  110. package/docs/dots.md +10 -3
  111. package/docs/figure.md +7 -0
  112. package/docs/glyphs.md +14 -2
  113. package/docs/highlights.md +9 -0
  114. package/docs/interval.md +6 -0
  115. package/docs/mermaid.md +5 -3
  116. package/docs/package-contract.md +24 -1
  117. package/docs/reference.md +21 -1
  118. package/docs/reporting.md +8 -8
  119. package/docs/selection.md +9 -0
  120. package/docs/sources.md +5 -0
  121. package/docs/state.md +6 -0
  122. package/docs/textref.md +18 -13
  123. package/docs/theming.md +18 -8
  124. package/docs/toc.md +6 -0
  125. package/docs/tree.md +9 -2
  126. package/docs/usage.md +2 -2
  127. package/docs/vega.md +5 -3
  128. package/docs/workbench.md +56 -9
  129. package/glyphs/glyphs.js +62 -8
  130. package/index.d.ts +1 -0
  131. package/llms.txt +18 -14
  132. package/package.json +98 -6
  133. package/qwik/index.d.ts +4 -3
  134. package/qwik/index.d.ts.map +1 -1
  135. package/qwik/index.js +7 -5
  136. package/react/index.d.ts +4 -3
  137. package/react/index.d.ts.map +1 -1
  138. package/react/index.js +3 -2
  139. package/solid/index.d.ts +7 -5
  140. package/solid/index.d.ts.map +1 -1
  141. package/solid/index.js +11 -7
  142. package/tokens/vega.d.ts +1 -1
  143. package/tokens/vega.js +3 -2
  144. package/vue/index.d.ts.map +1 -1
  145. package/vue/index.js +37 -3
@@ -230,14 +230,15 @@ export function curvePath(from, to, opts = {}) {
230
230
 
231
231
  /**
232
232
  * Build a path between two points by `shape` (`straight` | `elbow` | `curve`).
233
- * @param {ConnectorPathOptions} [opts]
233
+ * @param {ConnectorPathOptions} opts
234
234
  * @returns {string}
235
235
  */
236
- export function connectorPath(opts = {}) {
237
- const { from, to } = opts;
238
- const shape = connectorShape(opts.shape);
239
- if (shape === 'elbow') return elbowPath(from, to, opts);
240
- if (shape === 'curve') return curvePath(from, to, opts);
236
+ export function connectorPath(opts) {
237
+ const options = opts ?? {};
238
+ const { from, to } = options;
239
+ const shape = connectorShape(options.shape);
240
+ if (shape === 'elbow') return elbowPath(from, to, options);
241
+ if (shape === 'curve') return curvePath(from, to, options);
241
242
  return straightPath(from, to);
242
243
  }
243
244
 
@@ -332,17 +333,18 @@ export function endTangentAngle(from, to, shape = 'straight') {
332
333
  * Connect two rects. Resolves anchor points (explicit `fromSide`/`toSide`, else
333
334
  * auto), builds the path, and returns `{ d, from, to, angle }` so the caller can
334
335
  * place an arrowhead/dot at `to` rotated by `angle`.
335
- * @param {ConnectRectsOptions} [opts]
336
+ * @param {ConnectRectsOptions} opts
336
337
  * @returns {ConnectRectsResult}
337
338
  */
338
- export function connectRects(opts = {}) {
339
- const { fromRect, toRect, curvature, mid } = opts;
340
- const shape = connectorShape(opts.shape);
339
+ export function connectRects(opts) {
340
+ const options = opts ?? {};
341
+ const { fromRect, toRect, curvature, mid } = options;
342
+ const shape = connectorShape(options.shape);
341
343
  // Honor each side override independently; auto-pick whichever is unset.
342
344
  const auto = autoSides(fromRect, toRect);
343
345
  const sides = {
344
- from: opts.fromSide == null ? auto.from : sideValue(opts.fromSide),
345
- to: opts.toSide == null ? auto.to : sideValue(opts.toSide),
346
+ from: options.fromSide == null ? auto.from : sideValue(options.fromSide),
347
+ to: options.toSide == null ? auto.to : sideValue(options.toSide),
346
348
  };
347
349
  const from = anchorPoint(fromRect, sides.from);
348
350
  const to = anchorPoint(toRect, sides.to);
@@ -275,6 +275,7 @@
275
275
  .ui-annotation__note,
276
276
  .ui-annotation__note-line,
277
277
  .ui-annotation__badge {
278
+ /* Intentional !important: print must freeze opt-in draw/reveal animations. */
278
279
  animation: none !important;
279
280
  opacity: 1;
280
281
  stroke-dashoffset: 0;
package/css/app.css CHANGED
@@ -184,6 +184,13 @@
184
184
  z-index: var(--z-raised);
185
185
  }
186
186
 
187
+ @media (prefers-reduced-transparency: reduce) {
188
+ .ui-app-topbar {
189
+ backdrop-filter: none;
190
+ background: var(--surface-1);
191
+ }
192
+ }
193
+
187
194
  .ui-app-topbar__title {
188
195
  color: var(--text);
189
196
  font-family: var(--display);
package/css/base.css CHANGED
@@ -267,6 +267,7 @@ textarea:focus-visible,
267
267
  .ui-dotloader,
268
268
  .ui-dotspinner,
269
269
  dialog.ui-modal::backdrop {
270
+ /* Intentional !important: print chrome must stay hidden across component display rules. */
270
271
  display: none !important;
271
272
  }
272
273
 
@@ -274,6 +275,7 @@ textarea:focus-visible,
274
275
  *,
275
276
  *::before,
276
277
  *::after {
278
+ /* Intentional !important: print output drops decorative shadows globally. */
277
279
  box-shadow: none !important;
278
280
  text-shadow: none !important;
279
281
  }
@@ -291,6 +293,7 @@ textarea:focus-visible,
291
293
  .ui-prose table,
292
294
  .ui-tabs__list,
293
295
  pre {
296
+ /* Intentional !important: print must spill scroll containers even if component rules clip. */
294
297
  overflow: visible !important;
295
298
  }
296
299
 
package/css/bullet.css CHANGED
@@ -10,14 +10,35 @@
10
10
  SSR-static, print-survivable. Not imported by core.css.
11
11
 
12
12
  Boundary: the HOST normalises EVERY value to 0..1 and sets custom props —
13
- `--v` (measure), `--t` (target), `--b1`/`--b2` (the band boundaries). Bronto
14
- only paints geometry; it refuses raw values and min/max/scale computation —
15
- the same contract as `ui-spark`. A bare bullet is opaque to assistive tech, so
16
- `.ui-bullet` MUST carry a host-written `role="img"` + `aria-label` text
17
- equivalent (e.g. "uptime 99.62%, inside target 99.9%, in the warning band").
18
- Colour is never the only channel — the reading lives in that label.
13
+ `--v` (measure), `--t` (target), `--band-lo`/`--band-hi` (the band
14
+ boundaries). Bronto only paints geometry; it refuses raw values and
15
+ min/max/scale computation — the same contract as `ui-spark`. A bare bullet is
16
+ opaque to assistive tech, so `.ui-bullet` MUST carry a host-written
17
+ `role="img"` + `aria-label` text equivalent (e.g. "uptime 99.62%, inside
18
+ target 99.9%, in the warning band"). Colour is never the only channel — the
19
+ reading lives in that label.
19
20
  ========================================================================== */
20
21
 
22
+ /* Register only bullet-specific numeric geometry plus the target. Generic
23
+ `--v` stays unregistered because interval/spark/dot fallbacks depend on it. */
24
+ @property --band-lo {
25
+ syntax: '<number>';
26
+ inherits: true;
27
+ initial-value: 0.5;
28
+ }
29
+
30
+ @property --band-hi {
31
+ syntax: '<number>';
32
+ inherits: true;
33
+ initial-value: 0.8;
34
+ }
35
+
36
+ @property --t {
37
+ syntax: '<number>';
38
+ inherits: true;
39
+ initial-value: 0;
40
+ }
41
+
21
42
  .ui-bullet {
22
43
  --band-lo: 0.5;
23
44
  --band-hi: 0.8;
@@ -34,12 +55,21 @@
34
55
  position: relative;
35
56
  }
36
57
 
58
+ .ui-bullet:dir(rtl) {
59
+ background: linear-gradient(
60
+ to left,
61
+ var(--surface-4) 0 calc(var(--band-lo) * 100%),
62
+ var(--surface-3) calc(var(--band-lo) * 100%) calc(var(--band-hi) * 100%),
63
+ var(--surface-2) calc(var(--band-hi) * 100%) 100%
64
+ );
65
+ }
66
+
37
67
  /* The measure bar — a thinner dark bar centred in the track, the primary value.
38
68
  `--v` is the normalised reading; with none it collapses to a hairline. */
39
69
  .ui-bullet__measure {
40
70
  background: var(--text);
41
71
  border-radius: var(--radius-sm);
42
- inline-size: max(2px, calc(var(--v, 0) * 100%));
72
+ inline-size: max(calc(sign(var(--v, 1)) * 2px), calc(var(--v, 0) * 100%));
43
73
  inset-block: 30%;
44
74
  inset-inline-start: 0;
45
75
  position: absolute;
@@ -70,6 +100,10 @@
70
100
  transform: translateX(-50%);
71
101
  }
72
102
 
103
+ .ui-bullet:dir(rtl) .ui-bullet__target {
104
+ transform: translateX(50%);
105
+ }
106
+
73
107
  /* Optional caption row beneath the track — label + reading in mono, matching
74
108
  the report meter's value treatment. */
75
109
  .ui-bullet__label {
package/css/code.css CHANGED
@@ -28,7 +28,21 @@
28
28
  display: flex;
29
29
  gap: var(--space-sm);
30
30
  justify-content: space-between;
31
+ min-inline-size: 0;
32
+ overflow: hidden;
31
33
  padding: var(--space-2xs) var(--space-sm);
34
+ text-overflow: ellipsis;
35
+ white-space: nowrap;
36
+ }
37
+
38
+ .ui-code__head > * {
39
+ min-inline-size: 0;
40
+ overflow: hidden;
41
+ text-overflow: ellipsis;
42
+ }
43
+
44
+ .ui-code__head > :last-child {
45
+ flex-shrink: 0;
32
46
  }
33
47
 
34
48
  .ui-code__body {
package/css/command.css CHANGED
@@ -57,9 +57,17 @@
57
57
  cursor: pointer;
58
58
  display: flex;
59
59
  gap: 0.6rem;
60
+ min-inline-size: 0;
60
61
  padding: 0.5rem 0.6rem;
61
62
  }
62
63
 
64
+ .ui-command__item > :not(.ui-command__shortcut, .ui-command__meta) {
65
+ min-inline-size: 0;
66
+ overflow: hidden;
67
+ text-overflow: ellipsis;
68
+ white-space: nowrap;
69
+ }
70
+
63
71
  /* `display: flex` would otherwise beat the UA `[hidden]` rule, so a
64
72
  filtered-out item stays visible — re-assert none for hidden items/groups. */
65
73
  .ui-command__item[hidden],
@@ -74,11 +82,13 @@
74
82
 
75
83
  .ui-command__shortcut {
76
84
  color: var(--text-dim);
85
+ flex-shrink: 0;
77
86
  margin-inline-start: auto;
78
87
  }
79
88
 
80
89
  .ui-command__meta {
81
90
  color: var(--text-dim);
91
+ flex-shrink: 0;
82
92
  font-family: var(--mono);
83
93
  font-size: var(--text-2xs);
84
94
  margin-inline-start: auto;
package/css/dataviz.css CHANGED
@@ -98,3 +98,30 @@
98
98
  --chart-div-7: oklch(80% 0.12 55deg);
99
99
  --chart-pattern-ink: rgb(255 255 255 / 0.42);
100
100
  }
101
+
102
+ @media print {
103
+ :root:not([data-theme='light']) {
104
+ --chart-1: var(--accent);
105
+ --chart-2: #e69f00;
106
+ --chart-3: #56b4e9;
107
+ --chart-4: #009e73;
108
+ --chart-5: #f0e442;
109
+ --chart-6: #0072b2;
110
+ --chart-7: #cc79a7;
111
+ --chart-8: #4d5358;
112
+ --chart-seq-1: oklch(94% 0.03 25deg);
113
+ --chart-seq-2: oklch(85% 0.07 25deg);
114
+ --chart-seq-3: oklch(74% 0.12 25deg);
115
+ --chart-seq-4: oklch(62% 0.16 25deg);
116
+ --chart-seq-5: oklch(50% 0.16 25deg);
117
+ --chart-seq-6: oklch(38% 0.13 25deg);
118
+ --chart-div-1: oklch(45% 0.14 255deg);
119
+ --chart-div-2: oklch(62% 0.1 250deg);
120
+ --chart-div-3: oklch(82% 0.05 245deg);
121
+ --chart-div-4: oklch(90% 0.01 250deg);
122
+ --chart-div-5: oklch(80% 0.07 60deg);
123
+ --chart-div-6: oklch(66% 0.13 55deg);
124
+ --chart-div-7: oklch(56% 0.15 45deg);
125
+ --chart-pattern-ink: rgb(0 0 0 / 0.34);
126
+ }
127
+ }
package/css/diff.css CHANGED
@@ -72,6 +72,8 @@
72
72
  background: var(--surface-2);
73
73
  color: var(--text-dim);
74
74
  grid-column: 1 / -1;
75
+ min-inline-size: 0;
76
+ overflow-wrap: anywhere;
75
77
  padding: var(--space-2xs) var(--space-sm);
76
78
  }
77
79
 
@@ -527,6 +527,14 @@
527
527
  position: absolute;
528
528
  }
529
529
 
530
+ @media (prefers-reduced-transparency: reduce) {
531
+ .ui-carousel__prev,
532
+ .ui-carousel__next,
533
+ .ui-carousel__status {
534
+ background: var(--surface-3);
535
+ }
536
+ }
537
+
530
538
  /* Thumbnail strip — clicking a thumb jumps the track; active = accent. */
531
539
  .ui-carousel__thumbs {
532
540
  display: flex;
package/css/dots.css CHANGED
@@ -505,7 +505,7 @@
505
505
  container: dotfit / inline-size;
506
506
  }
507
507
 
508
- @container dotfit (width < 18rem) {
508
+ @container dotfit (inline-size < 18rem) {
509
509
  .ui-dotfit .ui-dotgrid {
510
510
  --dot-gap: 8px;
511
511
  }
package/css/feedback.css CHANGED
@@ -345,6 +345,15 @@
345
345
  transform: translate(-50%, 0);
346
346
  }
347
347
 
348
+ .ui-tooltip:dir(rtl) .ui-tooltip__bubble {
349
+ transform: translate(50%, 4px);
350
+ }
351
+
352
+ .ui-tooltip:dir(rtl):hover .ui-tooltip__bubble,
353
+ .ui-tooltip:dir(rtl):focus-within .ui-tooltip__bubble {
354
+ transform: translate(50%, 0);
355
+ }
356
+
348
357
  /* Popover surface — a top-layer panel positioned by initPopover (JS
349
358
  collision-aware, dependency-free). Uses the native [popover] top
350
359
  layer when available so it never clips; the class styles it either
package/css/interval.css CHANGED
@@ -8,6 +8,20 @@
8
8
  core.css.
9
9
  ========================================================================== */
10
10
 
11
+ /* `--lo` / `--hi` are inherited 0..1 endpoints for range geometry. The optional
12
+ `--v` stays unregistered so its `var(--v, var(--lo))` fallback remains intact. */
13
+ @property --lo {
14
+ syntax: '<number>';
15
+ inherits: true;
16
+ initial-value: 0;
17
+ }
18
+
19
+ @property --hi {
20
+ syntax: '<number>';
21
+ inherits: true;
22
+ initial-value: 1;
23
+ }
24
+
11
25
  .ui-interval {
12
26
  --lo: 0;
13
27
  --hi: 1;
@@ -31,9 +45,9 @@
31
45
  background: color-mix(in srgb, var(--accent) 26%, transparent);
32
46
  border: 1px solid color-mix(in srgb, var(--accent) 58%, var(--line));
33
47
  border-radius: var(--radius-pill);
34
- inline-size: max(2px, calc((var(--hi) - var(--lo)) * 100%));
48
+ inline-size: max(2px, calc((max(var(--lo), var(--hi)) - min(var(--lo), var(--hi))) * 100%));
35
49
  inset-block: 18%;
36
- inset-inline-start: calc(var(--lo) * 100%);
50
+ inset-inline-start: calc(min(var(--lo), var(--hi)) * 100%);
37
51
  position: absolute;
38
52
  }
39
53
 
@@ -50,6 +64,10 @@
50
64
  transform: translate(-50%, -50%);
51
65
  }
52
66
 
67
+ .ui-interval:dir(rtl) .ui-interval__point {
68
+ transform: translate(50%, -50%);
69
+ }
70
+
53
71
  .ui-interval__label,
54
72
  .ui-interval__bounds {
55
73
  color: var(--text-dim);
package/css/legend.css CHANGED
@@ -104,37 +104,38 @@
104
104
  /* Categorical index helpers: exactly one per palette series (gated against
105
105
  tokens/charts.js by check-legend). They set only the colour, so a swatch
106
106
  stays a faithful key — add `--chart-pattern` (inline, or from dataviz.css)
107
- only where the chart mark itself is patterned. */
107
+ only where the chart mark itself is patterned. The accent fallback keeps the
108
+ live custom property resolvable when dataviz.css is not present. */
108
109
  .ui-legend__swatch--1 {
109
- --chart-color: var(--chart-1);
110
+ --chart-color: var(--chart-1, var(--accent));
110
111
  }
111
112
 
112
113
  .ui-legend__swatch--2 {
113
- --chart-color: var(--chart-2);
114
+ --chart-color: var(--chart-2, var(--accent));
114
115
  }
115
116
 
116
117
  .ui-legend__swatch--3 {
117
- --chart-color: var(--chart-3);
118
+ --chart-color: var(--chart-3, var(--accent));
118
119
  }
119
120
 
120
121
  .ui-legend__swatch--4 {
121
- --chart-color: var(--chart-4);
122
+ --chart-color: var(--chart-4, var(--accent));
122
123
  }
123
124
 
124
125
  .ui-legend__swatch--5 {
125
- --chart-color: var(--chart-5);
126
+ --chart-color: var(--chart-5, var(--accent));
126
127
  }
127
128
 
128
129
  .ui-legend__swatch--6 {
129
- --chart-color: var(--chart-6);
130
+ --chart-color: var(--chart-6, var(--accent));
130
131
  }
131
132
 
132
133
  .ui-legend__swatch--7 {
133
- --chart-color: var(--chart-7);
134
+ --chart-color: var(--chart-7, var(--accent));
134
135
  }
135
136
 
136
137
  .ui-legend__swatch--8 {
137
- --chart-color: var(--chart-8);
138
+ --chart-color: var(--chart-8, var(--accent));
138
139
  }
139
140
 
140
141
  /* Continuous colour ramp. Author supplies the min/mid/max tick *text*; the
package/css/marks.css CHANGED
@@ -30,6 +30,7 @@
30
30
  background-repeat: no-repeat;
31
31
  background-size: 100% 100%;
32
32
  border-radius: 0.12em;
33
+ -webkit-box-decoration-break: clone; /* stylelint-disable-line property-no-vendor-prefix -- Safari/WebKit keeps wrapped mark backgrounds continuous. */
33
34
  box-decoration-break: clone;
34
35
  color: inherit;
35
36
  padding-block: 0.05em;
package/css/motion.css CHANGED
@@ -384,6 +384,7 @@
384
384
  ::view-transition-group(*),
385
385
  ::view-transition-old(*),
386
386
  ::view-transition-new(*) {
387
+ /* Intentional !important: view-transition pseudos sit outside the global reset. */
387
388
  animation: none !important;
388
389
  }
389
390
  }
@@ -419,6 +420,7 @@
419
420
  }
420
421
 
421
422
  .ui-reveal {
423
+ /* Intentional !important: reveal content must not remain hidden for reduced-motion users. */
422
424
  opacity: 1 !important;
423
425
  transform: none !important;
424
426
  }
package/css/overlay.css CHANGED
@@ -425,8 +425,9 @@ html:has(.ui-modal.is-open) {
425
425
  }
426
426
 
427
427
  .ui-menu {
428
- inset-inline: 0;
429
- min-inline-size: 0;
428
+ inline-size: max-content;
429
+ max-inline-size: calc(100vw - (2 * var(--space-sm)));
430
+ min-inline-size: min(11rem, calc(100vw - (2 * var(--space-sm))));
430
431
  }
431
432
 
432
433
  /* Let the combobox shed its 14rem floor and span the viewport so the input
@@ -450,6 +451,17 @@ html:has(.ui-modal.is-open) {
450
451
  }
451
452
  }
452
453
 
454
+ @media (prefers-reduced-transparency: reduce) {
455
+ .ui-modal::backdrop {
456
+ backdrop-filter: none;
457
+ background: var(--surface-1);
458
+ }
459
+
460
+ .ui-lightbox::backdrop {
461
+ background: var(--surface-1);
462
+ }
463
+ }
464
+
453
465
  /* Forced-colors drops both `backdrop-filter: blur()` and the `color-mix()`
454
466
  scrim, so the dialog/lightbox would float over an undimmed page with no
455
467
  separation. Re-assert a translucent scrim with `forced-color-adjust: none`
@@ -543,7 +543,7 @@
543
543
  @media (pointer: coarse) {
544
544
  .ui-link--arrow,
545
545
  .ui-link--cta {
546
- min-block-size: 1.5rem;
546
+ min-block-size: max(24px, 1.6rem);
547
547
  }
548
548
  }
549
549
 
package/css/report.css CHANGED
@@ -665,6 +665,7 @@
665
665
  `.ui-report__figure` with a `.ui-report__caption` + a `.ui-legend` key. */
666
666
 
667
667
  .ui-print-only {
668
+ /* Intentional !important: keep print-only utilities hidden from screen styles. */
668
669
  display: none !important;
669
670
  }
670
671
 
@@ -758,10 +759,12 @@
758
759
  }
759
760
 
760
761
  .ui-print-only {
762
+ /* Intentional !important: this must override the screen-only utility value. */
761
763
  display: var(--print-display, block) !important;
762
764
  }
763
765
 
764
766
  .ui-screen-only {
767
+ /* Intentional !important: print output must not leak screen-only chrome. */
765
768
  display: none !important;
766
769
  }
767
770
 
package/css/sources.css CHANGED
@@ -229,12 +229,12 @@
229
229
  }
230
230
 
231
231
  /* Print: an inline citation marker points into the references list, so never
232
- expand its href inline. base.css expands `.ui-prose a[href^="http"]` with a
233
- trailing "(url)"; on a superscript marker that dumps a full URL mid-sentence.
234
- !important + print-scoped because base's rule is more specific. */
232
+ expand its href inline. Match base's `.ui-prose a[href^="http"]` specificity
233
+ without `!important`. */
235
234
  @media print {
235
+ .ui-prose .ui-citation[href]::after,
236
236
  .ui-citation[href]::after {
237
- content: none !important;
237
+ content: none;
238
238
  }
239
239
 
240
240
  .ui-source-card,
package/css/spotlight.css CHANGED
@@ -51,6 +51,12 @@
51
51
  }
52
52
  }
53
53
 
54
+ @media (prefers-reduced-transparency: reduce) {
55
+ .ui-spotlight {
56
+ --spot-backdrop: var(--surface-1);
57
+ }
58
+ }
59
+
54
60
  .ui-spotlight--ring .ui-spotlight__hole {
55
61
  outline: 2px solid var(--accent);
56
62
  outline-offset: 0;
package/css/table.css CHANGED
@@ -132,6 +132,25 @@
132
132
  inline-size: 100%;
133
133
  }
134
134
 
135
+ @media (pointer: coarse) {
136
+ .ui-table__sort {
137
+ box-sizing: border-box;
138
+ margin-block: -0.7rem;
139
+ min-block-size: 24px;
140
+ padding-block: 0.7rem;
141
+ }
142
+
143
+ .ui-table--dense .ui-table__sort {
144
+ margin-block: -0.42rem;
145
+ padding-block: 0.42rem;
146
+ }
147
+
148
+ .ui-table--comfortable .ui-table__sort {
149
+ margin-block: -0.95rem;
150
+ padding-block: 0.95rem;
151
+ }
152
+ }
153
+
135
154
  .ui-table__sort::after {
136
155
  content: '↕';
137
156
  opacity: 0.4;
package/css/term.css CHANGED
@@ -78,7 +78,7 @@
78
78
  border-block-start: 1px solid var(--line);
79
79
  display: grid;
80
80
  gap: var(--space-2xs) var(--space-md);
81
- grid-template-columns: minmax(6rem, max-content) 1fr;
81
+ grid-template-columns: fit-content(45%) minmax(0, 1fr);
82
82
  margin: 0;
83
83
  padding-block-start: var(--space-md);
84
84
  }
@@ -89,12 +89,15 @@
89
89
  font-size: var(--text-xs);
90
90
  font-weight: 600;
91
91
  letter-spacing: var(--tracking-wide);
92
+ min-inline-size: 0;
93
+ overflow-wrap: anywhere;
92
94
  }
93
95
 
94
96
  .ui-glossary__def {
95
97
  color: var(--text-dim);
96
98
  font-size: var(--text-sm);
97
99
  margin: 0;
100
+ min-inline-size: 0;
98
101
  }
99
102
 
100
103
  /* Narrow viewports: stack each term over its definition. */
package/css/tokens.css CHANGED
@@ -275,13 +275,7 @@
275
275
  /* High contrast — manual opt-in and the OS `prefers-contrast` signal.
276
276
  Both collapse the soft greys toward the strong end; theme-agnostic
277
277
  because they reference the per-theme *-strong / -soft tokens. */
278
- [data-contrast='high'] {
279
- --line: var(--line-strong);
280
- --text-dim: var(--text-soft);
281
- --focus-ring: var(--accent);
282
- --shadow-raised: 0 0 0 1px var(--text);
283
- }
284
-
278
+ [data-contrast='high'],
285
279
  :root[data-contrast='high'] {
286
280
  --line: var(--line-strong);
287
281
  --text-dim: var(--text-soft);
@@ -335,18 +329,19 @@
335
329
  Lives here, in the exempt tier-definition file, because it is a token-value
336
330
  override (ADR-0001), not component styling. CSS-only, like the presets above.
337
331
 
338
- Selector is `:root:root:root` (specificity 0,3,0), not a bare `:root`: a media
332
+ Selector is `:root:root:root:root` (specificity 0,4,0), not a bare `:root`: a media
339
333
  query adds NO specificity, so a bare `:root` (0,1,0) loses the cascade to the
340
334
  on-screen dark palette at `:root[data-theme='dark']` (0,2,0) and the OLED
341
335
  surface at `:root[data-theme='dark'][data-surface='oled']` (0,3,0) — i.e. a
342
336
  dark-mode user would print a near-black `.ui-card` on white paper, the exact
343
- opposite of what this block promises. Tripling `:root` matches the OLED rule's
344
- specificity and wins on source order (this block is last), so the remap also
345
- beats the `prefers-color-scheme: dark` blocks. Neutralise the OLED-only dark
346
- surfaces (--bg / --bg-elevated / --panel-strong) too, or they'd leak through.
337
+ opposite of what this block promises. Quadrupling `:root` also beats later
338
+ opt-in skin selectors at 0,3,0 when css/skins.css is loaded after the default
339
+ bundle, so the print-safe accent survives colorways. Neutralise the OLED-only
340
+ dark surfaces (--bg / --bg-elevated / --panel-strong) too, or they'd leak
341
+ through.
347
342
  -------------------------------------------------------------------------- */
348
343
  @media print {
349
- :root:root:root {
344
+ :root:root:root:root {
350
345
  color-scheme: light;
351
346
 
352
347
  --text: #111;