@mlola-ui/tokens 1.2.2 → 1.3.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,15 +1,8 @@
1
- /* Library recipes — owned by Mlola, no utility framework. */
2
-
3
- /* engine/base */
4
- /* `hidden` must win over any display a recipe sets (display: grid on a
5
- collapsible body would otherwise keep it open). */
1
+ /* @mlola-ui/engine recipes.css, generated. The sources keep the comments. */
6
2
  :where([hidden]:not([hidden="until-found"])) {
7
3
  display: none !important;
8
4
  }
9
5
 
10
- /* Icons sit on the text's optical center and keep their size inside flex
11
- rows; a squeezed row shrinks text, not glyphs. The same rules ship in
12
- @mlola-ui/icons/glyphs.css for apps that use the icons without the engine. */
13
6
  :where(.mlola-glyph) {
14
7
  display: inline-block;
15
8
  flex-shrink: 0;
@@ -29,7 +22,6 @@
29
22
  --mlola-glyph-optical-scale: 1.03;
30
23
  }
31
24
 
32
- /* The mark after a link to another site, which opens in a new tab. */
33
25
  .ml-link-external {
34
26
  margin-inline-start: var(--ml-space-1);
35
27
  vertical-align: -.125em;
@@ -52,7 +44,6 @@
52
44
  z-index: var(--ml-layer-overlay);
53
45
  }
54
46
 
55
- /* A glyph inside a link flows with the text instead of breaking the line. */
56
47
  .ml-link > .mlola-glyph {
57
48
  display: inline;
58
49
  margin-inline-start: 0.15em;
@@ -151,7 +142,6 @@
151
142
  gap: var(--ml-space-2);
152
143
  }
153
144
 
154
- /* A list of benefits, each after a check. Pricing tiers and feature rows share it. */
155
145
  .ml-check-list {
156
146
  margin: 0;
157
147
  padding: 0;
@@ -176,12 +166,10 @@
176
166
 
177
167
  .ml-section {
178
168
  padding-block: var(--ml-space-fluid-xl);
179
- /* A section is a grid or flex item in a page shell; without this, a wide
180
- table inside it widens the whole page instead of scrolling in place. */
169
+
181
170
  min-width: 0;
182
171
  }
183
172
 
184
- /* A section a link jumps to clears the sticky navigation bar. */
185
173
  .ml-section[id] {
186
174
  scroll-margin-block-start: calc(var(--ml-control-md) + var(--ml-space-6));
187
175
  }
@@ -189,8 +177,7 @@
189
177
  .ml-section-shell {
190
178
  width: min(100% - 2rem,72rem);
191
179
  margin-inline: auto;
192
- /* A grid or flex item defaults to min-width: auto, which lets a wide
193
- table push the whole page sideways. */
180
+
194
181
  min-width: 0;
195
182
  }
196
183
 
@@ -207,8 +194,6 @@
207
194
  justify-items: center;
208
195
  }
209
196
 
210
- /* Its width is stated: centered by auto margins alone, a flex or grid item
211
- takes its text's width instead of its measure. */
212
197
  .ml-section-header-centered .ml-section-description {
213
198
  width: 100%;
214
199
  margin-inline: auto;
@@ -294,7 +279,6 @@
294
279
  }
295
280
  }
296
281
 
297
- /* Tablets keep two columns; only phones stack to one. */
298
282
  @media(max-width:48rem) {
299
283
  .ml-grid[data-columns="3"],
300
284
  .ml-grid[data-columns="4"],
@@ -383,7 +367,6 @@
383
367
  font-weight: 800;
384
368
  }
385
369
 
386
- /* A brand's own logo takes the mark's place: no chip, the text color, the mark's size. */
387
370
  .ml-brand-mark[data-kind="logo"] {
388
371
  background: none;
389
372
  color: var(--ml-text);
@@ -594,7 +577,6 @@
594
577
  font-size: var(--ml-type-base);
595
578
  }
596
579
 
597
- /* A full page: header, main and footer stacked on the page background. */
598
580
  .ml-page-shell {
599
581
  display: grid;
600
582
  grid-template-rows: auto 1fr auto;
@@ -603,13 +585,10 @@
603
585
  color: var(--ml-text);
604
586
  }
605
587
 
606
- /* The navigation, main and footer are grid items; they may be narrower than
607
- their widest content (a table that scrolls), so the page never does. */
608
588
  .ml-page-shell > * {
609
589
  min-width: 0;
610
590
  }
611
591
 
612
- /* components/accordion */
613
592
  .ml-accordion {
614
593
  width: 100%;
615
594
  }
@@ -678,7 +657,6 @@
678
657
  line-height: 1.55;
679
658
  }
680
659
 
681
- /* components/activity-heatmap */
682
660
  .ml-heatmap {
683
661
  --ml-heatmap-color: var(--ml-primary);
684
662
  --ml-heatmap-gap: var(--ml-space-1);
@@ -703,7 +681,6 @@
703
681
  --ml-heatmap-color: var(--ml-warning);
704
682
  }
705
683
 
706
- /* Weeks share the width, so the heatmap fills any container without scrolling. */
707
684
  .ml-heatmap-grid {
708
685
  display: grid;
709
686
  grid-template-columns: auto repeat(var(--ml-heatmap-weeks), minmax(0, 1fr));
@@ -775,8 +752,6 @@
775
752
  box-shadow: 0 0 0 2px var(--ml-focus);
776
753
  }
777
754
 
778
- /* A layer on <body> placed above its cell by script (useFloating), so no
779
- card or panel around the heatmap can cover or cut it. */
780
755
  .ml-heatmap-tooltip {
781
756
  position: fixed;
782
757
  z-index: var(--ml-layer-tooltip);
@@ -822,10 +797,6 @@
822
797
  font-variant-numeric: tabular-nums;
823
798
  }
824
799
 
825
- /* components/alert */
826
- /* A card like Card and Toast. The tone lives in one place, a solid icon
827
- mark, so a stack of alerts stays calm and each one still reads at a glance.
828
- `soft` tints the whole alert instead, for a banner across a page. */
829
800
  .ml-alert {
830
801
  --ml-alert-tone: var(--ml-text-muted);
831
802
  --ml-alert-on-tone: var(--ml-surface);
@@ -871,7 +842,6 @@
871
842
  --ml-alert-tone-text: var(--ml-danger-text);
872
843
  }
873
844
 
874
- /* soft: one even tint, a matching edge, and the title in the tone. */
875
845
  .ml-alert[data-variant="soft"] {
876
846
  border-color: color-mix(in oklab, var(--ml-alert-tone) 24%, transparent);
877
847
  background: color-mix(in oklab, var(--ml-alert-tone) 8%, var(--ml-surface));
@@ -900,7 +870,6 @@
900
870
  transition: opacity var(--ml-duration-fast) var(--ml-ease-standard), transform var(--ml-duration-normal) var(--ml-ease-standard);
901
871
  }
902
872
 
903
- /* A solid mark in the tone, centered on the first line of text. */
904
873
  .ml-alert-icon {
905
874
  position: relative;
906
875
  display: inline-grid;
@@ -932,8 +901,6 @@
932
901
  font-size: var(--ml-type-base);
933
902
  }
934
903
 
935
- /* Warnings and errors ask for attention as they arrive: a ring swells out
936
- of the mark and fades, twice. */
937
904
  .ml-alert[data-tone="warning"] .ml-alert-icon::after,
938
905
  .ml-alert[data-tone="danger"] .ml-alert-icon::after {
939
906
  position: absolute;
@@ -1021,7 +988,6 @@
1021
988
  }
1022
989
  }
1023
990
 
1024
- /* components/app-shell */
1025
991
  .ml-app-shell {
1026
992
  display: grid;
1027
993
  height: 100%;
@@ -1044,7 +1010,6 @@
1044
1010
  min-height: 0;
1045
1011
  }
1046
1012
 
1047
- /* Phones: the sidebar's track closes and its pane hides; the drawer takes over. */
1048
1013
  .ml-app-shell[data-narrow] .ml-app-shell-frame.ml-resizable[data-direction] {
1049
1014
  grid-template-columns: 0 0 minmax(0, 1fr);
1050
1015
  }
@@ -1229,7 +1194,6 @@
1229
1194
  opacity: 1;
1230
1195
  }
1231
1196
 
1232
- /* components/avatar */
1233
1197
  .ml-avatar-root {
1234
1198
  position: relative;
1235
1199
  display: inline-flex;
@@ -1339,7 +1303,6 @@
1339
1303
  font-weight: 600;
1340
1304
  }
1341
1305
 
1342
- /* components/badge */
1343
1306
  .ml-badge {
1344
1307
  display: inline-flex;
1345
1308
  align-items: center;
@@ -1380,7 +1343,6 @@
1380
1343
  font-size: var(--ml-type-sm);
1381
1344
  }
1382
1345
 
1383
- /* Tone picks the color role; variant decides how it is worn. */
1384
1346
  .ml-badge[data-tone="primary"] {
1385
1347
  --ml-badge-tone: var(--ml-primary);
1386
1348
  --ml-badge-text: var(--ml-primary-text);
@@ -1411,11 +1373,9 @@
1411
1373
  --ml-badge-on: var(--ml-danger-foreground);
1412
1374
  }
1413
1375
 
1414
- /* Soft is the default, so plain markup with only data-tone is tinted too. */
1415
1376
  .ml-badge:where([data-tone]:not([data-tone="neutral"])) {
1416
1377
  background: color-mix(in oklab,var(--ml-badge-tone) 12%,transparent);
1417
- /* The -text roles clear 4.5:1 on a plain surface; on a tint they lean toward
1418
- the body text just enough to keep clearing it at badge size. */
1378
+
1419
1379
  color: color-mix(in oklab,var(--ml-badge-text) 78%,var(--ml-text));
1420
1380
  }
1421
1381
 
@@ -1451,7 +1411,6 @@
1451
1411
  background: color-mix(in srgb,currentColor 12%,transparent);
1452
1412
  }
1453
1413
 
1454
- /* components/breadcrumb */
1455
1414
  .ml-breadcrumb {
1456
1415
  display: block;
1457
1416
  color: var(--ml-text-muted);
@@ -1475,7 +1434,6 @@
1475
1434
  gap: var(--ml-space-1-5);
1476
1435
  }
1477
1436
 
1478
- /* Links, in-app buttons and the current page share one shape; a long title shortens instead of breaking the bar. */
1479
1437
  .ml-breadcrumb-link,
1480
1438
  .ml-breadcrumb-page {
1481
1439
  display: inline-flex;
@@ -1492,9 +1450,6 @@
1492
1450
  text-decoration: none;
1493
1451
  }
1494
1452
 
1495
- /* A fingertip's target. The link clips its own text for the ellipsis, which
1496
- would clip the invisible target data-hit="expand" draws around it, so on a
1497
- touch screen the link itself grows instead, without moving the bar. */
1498
1453
  @media (pointer: coarse) {
1499
1454
  .ml-breadcrumb-link {
1500
1455
  padding-block: var(--ml-space-2);
@@ -1547,7 +1502,6 @@ button.ml-breadcrumb-link {
1547
1502
  }
1548
1503
  }
1549
1504
 
1550
- /* components/button */
1551
1505
  .ml-button {
1552
1506
  position: relative;
1553
1507
  display: inline-flex;
@@ -1630,10 +1584,6 @@ button.ml-breadcrumb-link {
1630
1584
  background: color-mix(in oklab,var(--ml-surface) 100%,var(--ml-text) 4%);
1631
1585
  }
1632
1586
 
1633
- /* A toggle button that is on reads as filled ink, so its state is visible
1634
- without relying on color alone. It stays ink under the pointer, a shade
1635
- lighter: a variant's own hover fill under this ink-colored text would
1636
- leave the label unreadable. After the variants' hovers, and above them. */
1637
1587
  .ml-button:is([data-variant="secondary"], [data-variant="subtle"], [data-variant="outline"])[aria-pressed="true"] {
1638
1588
  border-color: transparent;
1639
1589
  background: var(--ml-text);
@@ -1672,9 +1622,6 @@ button.ml-breadcrumb-link {
1672
1622
  color: var(--ml-primary-text);
1673
1623
  }
1674
1624
 
1675
- /* A link button is drawn as text, a line tall. On touch it keeps that look
1676
- and gains an invisible target around it, as a control marked
1677
- data-hit="expand" does, so a finger reaches it (WCAG 2.5.8). */
1678
1625
  @media (pointer: coarse) {
1679
1626
  .ml-button[data-variant="link"]::after {
1680
1627
  position: absolute;
@@ -1702,9 +1649,6 @@ button.ml-breadcrumb-link {
1702
1649
  padding: 0;
1703
1650
  }
1704
1651
 
1705
- /* A label too long for the space wraps onto balanced lines instead of
1706
- spilling out. The taller line height is taken back by the margins, so a
1707
- one-line button is exactly as tall as before. */
1708
1652
  .ml-button-label {
1709
1653
  display: inline-flex;
1710
1654
  align-items: center;
@@ -1726,16 +1670,11 @@ button.ml-breadcrumb-link {
1726
1670
  color: var(--ml-success-foreground);
1727
1671
  }
1728
1672
 
1729
- /* A busy button keeps its color: the spinner says it is working, and its
1730
- label ("Saving…") stays readable. Only a disabled button fades, so the two
1731
- never look alike. */
1732
1673
  .ml-button[data-loading] {
1733
1674
  pointer-events: none;
1734
1675
  opacity: 1;
1735
1676
  }
1736
1677
 
1737
- /* A shortcut inside a filled button takes the button's own ink: an outline
1738
- of the text color, no fill of its own, so it reads on any variant. */
1739
1678
  .ml-button .ml-kbd {
1740
1679
  border-color: color-mix(in oklab, currentColor 40%, transparent);
1741
1680
  background: transparent;
@@ -1743,12 +1682,10 @@ button.ml-breadcrumb-link {
1743
1682
  color: inherit;
1744
1683
  }
1745
1684
 
1746
- /* components/calendar */
1747
1685
  .ml-calendar {
1748
1686
  --ml-calendar-day: 2.25rem;
1749
1687
  display: inline-grid;
1750
- /* One column no wider than the calendar, so two months wrap into a stack
1751
- when the space is narrower than both side by side. */
1688
+
1752
1689
  grid-template-columns: minmax(0, 1fr);
1753
1690
  width: max-content;
1754
1691
  max-width: 100%;
@@ -1762,7 +1699,6 @@ button.ml-breadcrumb-link {
1762
1699
  gap: var(--ml-space-2);
1763
1700
  }
1764
1701
 
1765
- /* Each month has its own caption; the arrows sit on the outer ones. */
1766
1702
  .ml-calendar-caption {
1767
1703
  display: grid;
1768
1704
  grid-template-columns: 2rem minmax(0, 1fr) 2rem;
@@ -1835,7 +1771,6 @@ button.ml-breadcrumb-link {
1835
1771
  place-items: center;
1836
1772
  }
1837
1773
 
1838
- /* A range reads as one band: filled between its ends, rounded at them. */
1839
1774
  .ml-calendar-cell[data-range] {
1840
1775
  background: color-mix(in oklab, var(--ml-primary) 12%, transparent);
1841
1776
  }
@@ -1882,7 +1817,6 @@ button.ml-breadcrumb-link {
1882
1817
  color: var(--ml-text-faint);
1883
1818
  }
1884
1819
 
1885
- /* Today is marked with a dot, so it never competes with the selection. */
1886
1820
  .ml-calendar-day[data-today]::after {
1887
1821
  position: absolute;
1888
1822
  bottom: var(--ml-space-1);
@@ -1909,7 +1843,6 @@ button.ml-breadcrumb-link {
1909
1843
  background: var(--ml-primary-foreground);
1910
1844
  }
1911
1845
 
1912
- /* Out of reach for the range being drawn: still clickable, to start a new one. */
1913
1846
  .ml-calendar-day[data-unreachable] {
1914
1847
  color: var(--ml-text-faint);
1915
1848
  }
@@ -1927,7 +1860,6 @@ button.ml-breadcrumb-link {
1927
1860
  }
1928
1861
  }
1929
1862
 
1930
- /* components/card */
1931
1863
  .ml-card {
1932
1864
  color: var(--ml-text);
1933
1865
  border: var(--ml-border-width) solid var(--ml-border-subtle);
@@ -2014,7 +1946,6 @@ button.ml-breadcrumb-link {
2014
1946
  margin-block-start: var(--ml-space-6);
2015
1947
  }
2016
1948
 
2017
- /* components/carousel */
2018
1949
  .ml-carousel {
2019
1950
  --ml-carousel-gap: var(--ml-space-4);
2020
1951
  display: grid;
@@ -2027,8 +1958,6 @@ button.ml-breadcrumb-link {
2027
1958
  min-width: 0;
2028
1959
  }
2029
1960
 
2030
- /* A native scroll-snap track: swipe, trackpad and wheel all work, and each
2031
- slide takes an equal share of the width left after gaps and the peek. */
2032
1961
  .ml-carousel-track {
2033
1962
  position: relative;
2034
1963
  display: grid;
@@ -2061,9 +1990,6 @@ button.ml-breadcrumb-link {
2061
1990
  height: 100%;
2062
1991
  }
2063
1992
 
2064
- /* With a pointer that hovers, the arrows sit in a gutter beside the slides,
2065
- never over them. On touch the reader swipes, the arrows stay hidden until
2066
- focused, and the slides keep the full width. */
2067
1993
  @media (hover: hover) and (pointer: fine) {
2068
1994
  .ml-carousel[data-arrows] .ml-carousel-viewport {
2069
1995
  padding-inline: calc(var(--ml-control-md) + var(--ml-space-3));
@@ -2078,7 +2004,6 @@ button.ml-breadcrumb-link {
2078
2004
  }
2079
2005
  }
2080
2006
 
2081
- /* The arrows come forward when the reader is near. */
2082
2007
  .ml-carousel-arrow {
2083
2008
  position: absolute;
2084
2009
  top: 50%;
@@ -2127,7 +2052,6 @@ button.ml-breadcrumb-link {
2127
2052
  outline-offset: 2px;
2128
2053
  }
2129
2054
 
2130
- /* Touch screens swipe; the arrows would only cover the slide. */
2131
2055
  @media (hover: none) {
2132
2056
  .ml-carousel-arrow {
2133
2057
  display: none;
@@ -2155,7 +2079,6 @@ button.ml-breadcrumb-link {
2155
2079
  transition: width var(--ml-duration-normal) var(--ml-ease-spring), background-color var(--ml-duration-fast) var(--ml-ease-standard);
2156
2080
  }
2157
2081
 
2158
- /* A comfortable target around a small mark. */
2159
2082
  .ml-carousel-dot::before {
2160
2083
  position: absolute;
2161
2084
  inset: calc(-1 * var(--ml-space-2)) calc(-1 * var(--ml-space-0-5));
@@ -2171,7 +2094,6 @@ button.ml-breadcrumb-link {
2171
2094
  background: var(--ml-primary);
2172
2095
  }
2173
2096
 
2174
- /* While autoplay runs, the active dot fills over the slide's time. */
2175
2097
  .ml-carousel[data-playing] .ml-carousel-dot[aria-current="true"] {
2176
2098
  background: var(--ml-track);
2177
2099
  }
@@ -2211,7 +2133,6 @@ button.ml-breadcrumb-link {
2211
2133
  }
2212
2134
  }
2213
2135
 
2214
- /* components/checkbox */
2215
2136
  .ml-checkbox-field {
2216
2137
  display: grid;
2217
2138
  grid-template-columns: auto 1fr;
@@ -2278,7 +2199,6 @@ button.ml-breadcrumb-link {
2278
2199
  min-width: 0;
2279
2200
  }
2280
2201
 
2281
-
2282
2202
  .ml-checkbox-copy {
2283
2203
  display: grid;
2284
2204
  gap: var(--ml-space-1);
@@ -2294,8 +2214,6 @@ button.ml-breadcrumb-link {
2294
2214
  color: var(--ml-danger-text);
2295
2215
  }
2296
2216
 
2297
- /* components/color-picker */
2298
- /* A swatch and a value in any format. */
2299
2217
  .ml-color-picker {
2300
2218
  min-inline-size: 10rem;
2301
2219
  }
@@ -2308,7 +2226,6 @@ button.ml-breadcrumb-link {
2308
2226
  cursor: pointer;
2309
2227
  }
2310
2228
 
2311
- /* Swatches sit on a checkerboard, so transparency reads as transparency. */
2312
2229
  .ml-color-picker-swatch,
2313
2230
  .ml-color-picker-preset,
2314
2231
  .ml-color-picker-sample {
@@ -2343,12 +2260,11 @@ button.ml-breadcrumb-link {
2343
2260
  gap: var(--ml-space-3);
2344
2261
  }
2345
2262
 
2346
- /* Saturation left to right, brightness bottom to top, over the current hue. */
2347
2263
  .ml-color-picker-area {
2348
2264
  position: relative;
2349
2265
  height: 9.5rem;
2350
2266
  border-radius: var(--ml-radius-md);
2351
- /* audit-allow: color.literal — this is the color model itself: value falls to black, saturation to white. */
2267
+
2352
2268
  background: linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, transparent), var(--ml-color-hue);
2353
2269
  cursor: crosshair;
2354
2270
  outline: none;
@@ -2364,9 +2280,6 @@ button.ml-breadcrumb-link {
2364
2280
  display: grid;
2365
2281
  }
2366
2282
 
2367
- /* A slider is a row a fingertip can land on (24 px, as the Slider's), with
2368
- its thin stripe drawn inside. A finger moving up and down still scrolls;
2369
- sideways it moves the value. */
2370
2283
  .ml-color-picker-track {
2371
2284
  position: relative;
2372
2285
  height: var(--ml-space-6);
@@ -2508,7 +2421,7 @@ button.ml-breadcrumb-link {
2508
2421
 
2509
2422
  .ml-color-picker-sample {
2510
2423
  display: grid;
2511
- /* White or black, whichever reads better on the picked color (set by the component). */
2424
+
2512
2425
  color: var(--ml-color-ink);
2513
2426
  width: 2.25rem;
2514
2427
  height: 2.25rem;
@@ -2529,8 +2442,6 @@ button.ml-breadcrumb-link {
2529
2442
  color: var(--ml-success-text);
2530
2443
  }
2531
2444
 
2532
- /* components/combobox */
2533
- /* Wide enough to read a choice and type a search. */
2534
2445
  .ml-combobox {
2535
2446
  min-inline-size: 12rem;
2536
2447
  }
@@ -2541,7 +2452,6 @@ button.ml-breadcrumb-link {
2541
2452
  grid-template-columns: minmax(0, 1fr);
2542
2453
  }
2543
2454
 
2544
- /* The input keeps the field's surface; room at the end for clear and chevron. */
2545
2455
  .ml-combobox-input.ml-combobox-input {
2546
2456
  padding-inline-end: var(--ml-space-9);
2547
2457
  }
@@ -2599,9 +2509,6 @@ button.ml-breadcrumb-link {
2599
2509
  color: var(--ml-text);
2600
2510
  }
2601
2511
 
2602
- /* The list: the same floating surface as Select's, a layer on <body>
2603
- placed beside the field by script (useFloating), so no card, panel or
2604
- scroll area around the field can cover or cut it. */
2605
2512
  .ml-combobox-popover {
2606
2513
  position: fixed;
2607
2514
  z-index: var(--ml-layer-popover);
@@ -2609,8 +2516,7 @@ button.ml-breadcrumb-link {
2609
2516
  left: 0;
2610
2517
  display: flex;
2611
2518
  flex-direction: column;
2612
- /* No taller than the room on the side it opened (--ml-floating-room, from
2613
- useFloating), so it fits beside its trigger, even with a phone's keyboard up. */
2519
+
2614
2520
  max-height: var(--ml-floating-room, none);
2615
2521
  padding: var(--ml-space-1);
2616
2522
  border: var(--ml-border-width) solid var(--ml-border-subtle);
@@ -2717,7 +2623,6 @@ button.ml-breadcrumb-link {
2717
2623
  font-size: var(--ml-type-sm);
2718
2624
  }
2719
2625
 
2720
- /* components/command-menu */
2721
2626
  .ml-command.ml-modal {
2722
2627
  top: clamp(var(--ml-space-8), 18vh, var(--ml-space-16));
2723
2628
  grid-template-rows: auto minmax(0, 1fr) auto;
@@ -2747,7 +2652,7 @@ button.ml-breadcrumb-link {
2747
2652
  flex: 1;
2748
2653
  min-width: 0;
2749
2654
  border: 0;
2750
- /* audit-allow: focus.removed — the search field is the open dialog's only field; its caret shows focus. */
2655
+
2751
2656
  outline: none;
2752
2657
  background: transparent;
2753
2658
  color: var(--ml-text);
@@ -2851,12 +2756,10 @@ button.ml-breadcrumb-link {
2851
2756
  gap: var(--ml-space-1);
2852
2757
  }
2853
2758
 
2854
- /* components/context-menu */
2855
2759
  .ml-context-menu-area {
2856
2760
  min-width: 0;
2857
2761
  }
2858
2762
 
2859
- /* The same floating surface as the dropdown menu, placed at the pointer. */
2860
2763
  .ml-context-menu {
2861
2764
  position: fixed;
2862
2765
  z-index: var(--ml-layer-toast);
@@ -2867,7 +2770,7 @@ button.ml-breadcrumb-link {
2867
2770
  border-radius: var(--ml-radius-lg);
2868
2771
  box-shadow: var(--ml-surface-highlight), var(--ml-shadow-lg);
2869
2772
  color: var(--ml-text);
2870
- /* audit-allow: focus.removed — a menu container, focused only by script (tabindex -1); its items carry the focus style. */
2773
+
2871
2774
  outline: none;
2872
2775
  background-color: color-mix(in oklab, var(--ml-surface-elevated) var(--ml-surface-alpha), transparent);
2873
2776
  background-image: var(--ml-surface-grain);
@@ -2941,15 +2844,10 @@ button.ml-breadcrumb-link {
2941
2844
  background: var(--ml-border-subtle);
2942
2845
  }
2943
2846
 
2944
- /* components/copy-button */
2945
- /* A copy the browser refused reads as a problem, not as a success. On a
2946
- filled button the label keeps its own ink; the spoken message carries it. */
2947
2847
  .ml-copy-button[data-status="error"]:not([data-variant="primary"], [data-variant="danger"]) {
2948
2848
  color: var(--ml-danger-text);
2949
2849
  }
2950
2850
 
2951
- /* components/date-picker */
2952
- /* Wide enough for a range in the reader's format. */
2953
2851
  .ml-date-picker {
2954
2852
  min-inline-size: 13rem;
2955
2853
  }
@@ -2959,8 +2857,6 @@ button.ml-breadcrumb-link {
2959
2857
  display: grid;
2960
2858
  }
2961
2859
 
2962
- /* The trigger wears the input's surface, so date fields line up with text fields.
2963
- The doubled class outranks the input's padding, keeping room for the clear button. */
2964
2860
  .ml-date-picker-trigger.ml-date-picker-trigger {
2965
2861
  padding-inline-end: var(--ml-space-8);
2966
2862
  }
@@ -3016,7 +2912,6 @@ button.ml-breadcrumb-link {
3016
2912
  outline-offset: -1px;
3017
2913
  }
3018
2914
 
3019
- /* The popover grows to the calendars it holds, never past the screen. */
3020
2915
  .ml-popover.ml-date-picker-popover {
3021
2916
  max-width: calc(100vw - 2 * var(--ml-space-4));
3022
2917
  }
@@ -3064,7 +2959,6 @@ button.ml-breadcrumb-link {
3064
2959
  outline-offset: -1px;
3065
2960
  }
3066
2961
 
3067
- /* Phones: presets become a row above the calendar. */
3068
2962
  @media (max-width: 40rem) {
3069
2963
  .ml-date-picker-panel[data-presets] {
3070
2964
  flex-direction: column;
@@ -3083,7 +2977,203 @@ button.ml-breadcrumb-link {
3083
2977
  }
3084
2978
  }
3085
2979
 
3086
- /* components/dropdown-menu */
2980
+ .ml-dial-field {
2981
+ --ml-dial-size: 10rem;
2982
+ --ml-dial-tone: var(--ml-primary-text);
2983
+ display: inline-grid;
2984
+ justify-items: center;
2985
+ align-content: start;
2986
+ gap: var(--ml-space-2);
2987
+ }
2988
+
2989
+ .ml-dial-field[data-size="sm"] {
2990
+ --ml-dial-size: 6rem;
2991
+ }
2992
+
2993
+ .ml-dial-field[data-size="lg"] {
2994
+ --ml-dial-size: 14rem;
2995
+ }
2996
+
2997
+ .ml-dial-field[data-tone="info"] {
2998
+ --ml-dial-tone: var(--ml-info-text);
2999
+ }
3000
+
3001
+ .ml-dial-field[data-tone="success"] {
3002
+ --ml-dial-tone: var(--ml-success-text);
3003
+ }
3004
+
3005
+ .ml-dial-field[data-tone="warning"] {
3006
+ --ml-dial-tone: var(--ml-warning-text);
3007
+ }
3008
+
3009
+ .ml-dial-field[data-tone="danger"] {
3010
+ --ml-dial-tone: var(--ml-danger-text);
3011
+ }
3012
+
3013
+ .ml-dial-label {
3014
+ font-size: var(--ml-type-sm);
3015
+ font-weight: 500;
3016
+ text-align: center;
3017
+ }
3018
+
3019
+ .ml-dial-caption {
3020
+ max-width: var(--ml-dial-size);
3021
+ color: var(--ml-text-muted);
3022
+ font-size: var(--ml-type-xs);
3023
+ line-height: var(--ml-leading-snug);
3024
+ text-align: center;
3025
+ }
3026
+
3027
+ .ml-dial {
3028
+ position: relative;
3029
+ width: var(--ml-dial-size);
3030
+ aspect-ratio: 1;
3031
+ border-radius: 50%;
3032
+ cursor: grab;
3033
+ -webkit-touch-callout: none;
3034
+ -webkit-user-select: none;
3035
+ user-select: none;
3036
+ }
3037
+
3038
+ .ml-dial[data-turning] {
3039
+ cursor: grabbing;
3040
+ }
3041
+
3042
+ .ml-dial:focus-visible {
3043
+ outline: 2px solid var(--ml-focus);
3044
+ outline-offset: 2px;
3045
+ }
3046
+
3047
+ .ml-dial-arc {
3048
+ position: absolute;
3049
+ inset: 0;
3050
+ width: 100%;
3051
+ height: 100%;
3052
+ overflow: visible;
3053
+ }
3054
+
3055
+ .ml-dial-ticks,
3056
+ .ml-dial-track,
3057
+ .ml-dial-range {
3058
+ fill: none;
3059
+ stroke-linecap: round;
3060
+ }
3061
+
3062
+ .ml-dial-ticks {
3063
+ stroke: var(--ml-border);
3064
+ stroke-width: 0.8;
3065
+ }
3066
+
3067
+ .ml-dial-field[data-size="sm"] .ml-dial-ticks {
3068
+ display: none;
3069
+ }
3070
+
3071
+ .ml-dial-track {
3072
+ stroke: var(--ml-track);
3073
+ stroke-width: 5;
3074
+ }
3075
+
3076
+ .ml-dial-range {
3077
+ stroke: var(--ml-dial-tone);
3078
+ stroke-width: 5;
3079
+ }
3080
+
3081
+ .ml-dial-knob {
3082
+ position: absolute;
3083
+ inset: 16%;
3084
+ border-radius: 50%;
3085
+ background:
3086
+ var(--ml-sheen),
3087
+ radial-gradient(circle at 50% 28%, color-mix(in oklab, var(--ml-surface-elevated) var(--ml-surface-alpha), transparent), color-mix(in oklab, var(--ml-background-subtle) var(--ml-surface-alpha), transparent) 78%);
3088
+ box-shadow:
3089
+ var(--ml-surface-highlight),
3090
+ inset 0 0 0 var(--ml-border-width) var(--ml-border-subtle),
3091
+ var(--ml-shadow-md);
3092
+ -webkit-backdrop-filter: var(--ml-surface-blur);
3093
+ backdrop-filter: var(--ml-surface-blur);
3094
+ rotate: var(--ml-dial-angle, 0deg);
3095
+ transition: rotate var(--ml-duration-normal) var(--ml-ease-spring);
3096
+ }
3097
+
3098
+ .ml-dial-knob::before {
3099
+ content: "";
3100
+ position: absolute;
3101
+ inset: 0;
3102
+ border-radius: inherit;
3103
+ background-image: var(--ml-surface-grain);
3104
+ background-size: 4px 4px;
3105
+ }
3106
+
3107
+ .ml-dial-knob::after {
3108
+ content: "";
3109
+ position: absolute;
3110
+ top: 6%;
3111
+ left: 50%;
3112
+ width: 5%;
3113
+ height: 13%;
3114
+ border-radius: var(--ml-radius-pill);
3115
+ background: var(--ml-dial-tone);
3116
+ translate: -50% 0;
3117
+ }
3118
+
3119
+ .ml-dial[data-turning] .ml-dial-knob {
3120
+ transition: none;
3121
+ }
3122
+
3123
+ .ml-dial-readout {
3124
+ position: absolute;
3125
+ inset: 0;
3126
+ display: grid;
3127
+ place-items: center;
3128
+ pointer-events: none;
3129
+ }
3130
+
3131
+ .ml-dial-value {
3132
+ color: var(--ml-text);
3133
+ font-family: var(--ml-font-display);
3134
+ font-size: var(--ml-type-2xl);
3135
+ font-variant-numeric: tabular-nums;
3136
+ font-weight: 600;
3137
+ letter-spacing: -0.02em;
3138
+ line-height: 1;
3139
+ white-space: nowrap;
3140
+ }
3141
+
3142
+ .ml-dial-field[data-size="sm"] .ml-dial-value {
3143
+ font-size: var(--ml-type-md);
3144
+ }
3145
+
3146
+ .ml-dial-field[data-size="lg"] .ml-dial-value {
3147
+ font-size: var(--ml-type-display-sm);
3148
+ }
3149
+
3150
+ .ml-dial-field[data-disabled] .ml-dial {
3151
+ cursor: not-allowed;
3152
+ opacity: 0.48;
3153
+ }
3154
+
3155
+ @media (prefers-reduced-motion: reduce) {
3156
+ .ml-dial-knob {
3157
+ transition: none;
3158
+ }
3159
+ }
3160
+
3161
+ @media (forced-colors: active) {
3162
+ .ml-dial-track {
3163
+ stroke: GrayText;
3164
+ }
3165
+
3166
+ .ml-dial-range,
3167
+ .ml-dial-knob::after {
3168
+ stroke: Highlight;
3169
+ background: Highlight;
3170
+ }
3171
+
3172
+ .ml-dial-knob {
3173
+ border: 1px solid CanvasText;
3174
+ }
3175
+ }
3176
+
3087
3177
  .ml-dropdown {
3088
3178
  position: relative;
3089
3179
  display: inline-block;
@@ -3113,7 +3203,6 @@ button.ml-breadcrumb-link {
3113
3203
  background: color-mix(in oklab,var(--ml-surface) 100%,var(--ml-text) 4%);
3114
3204
  }
3115
3205
 
3116
- /* An icon-only trigger: a small quiet button, named by its label. */
3117
3206
  .ml-dropdown-trigger[data-variant="icon"] {
3118
3207
  min-height: var(--ml-control-sm);
3119
3208
  min-width: var(--ml-control-sm);
@@ -3142,11 +3231,6 @@ button.ml-breadcrumb-link {
3142
3231
  color: var(--ml-text-muted);
3143
3232
  }
3144
3233
 
3145
- /* A layer above the page, placed beside its trigger by script (React's
3146
- useFloating, the runtime's floatingLayer), so no card, panel or modal
3147
- around the trigger can cut it off. It sits above a modal it opens from.
3148
- In the top layer (the Popover API) the browser's own popover styles are
3149
- set back: no centering margin, no stretching inset, the theme's ink. */
3150
3234
  .ml-dropdown-menu {
3151
3235
  position: fixed;
3152
3236
  z-index: var(--ml-layer-popover);
@@ -3155,8 +3239,7 @@ button.ml-breadcrumb-link {
3155
3239
  left: 0;
3156
3240
  margin: 0;
3157
3241
  min-width: 14rem;
3158
- /* No taller than the room on the side it opened (--ml-floating-room, from
3159
- useFloating), so it fits beside its trigger, even with a phone's keyboard up. */
3242
+
3160
3243
  max-height: var(--ml-floating-room, none);
3161
3244
  overflow-y: auto;
3162
3245
  overscroll-behavior: contain;
@@ -3257,7 +3340,6 @@ button.ml-breadcrumb-link {
3257
3340
  color: var(--ml-text-muted);
3258
3341
  }
3259
3342
 
3260
- /* components/dropzone */
3261
3343
  .ml-dropzone-root {
3262
3344
  display: grid;
3263
3345
  gap: var(--ml-space-2);
@@ -3405,7 +3487,6 @@ button.ml-breadcrumb-link {
3405
3487
  transition: width var(--ml-duration-normal) var(--ml-ease-standard);
3406
3488
  }
3407
3489
 
3408
- /* components/empty-state */
3409
3490
  .ml-empty {
3410
3491
  display: grid;
3411
3492
  justify-items: center;
@@ -3459,7 +3540,6 @@ button.ml-breadcrumb-link {
3459
3540
  margin-block-start: var(--ml-space-2);
3460
3541
  }
3461
3542
 
3462
- /* components/hover-card */
3463
3543
  .ml-hover-card {
3464
3544
  position: fixed;
3465
3545
  z-index: var(--ml-layer-popover);
@@ -3494,13 +3574,12 @@ button.ml-breadcrumb-link {
3494
3574
  }
3495
3575
  }
3496
3576
 
3497
- /* components/input */
3498
3577
  .ml-input-field {
3499
3578
  display: grid;
3500
3579
  grid-template-columns: minmax(0, 1fr);
3501
3580
  gap: var(--ml-space-1-5);
3502
3581
  width: 100%;
3503
- /* In a form row taller than itself, a field keeps its own height instead of stretching its label and control apart. */
3582
+
3504
3583
  align-content: start;
3505
3584
  }
3506
3585
 
@@ -3522,9 +3601,6 @@ button.ml-breadcrumb-link {
3522
3601
  transition: border-color var(--ml-duration-fast),box-shadow var(--ml-duration-fast);
3523
3602
  }
3524
3603
 
3525
- /* A single-line field is exactly its size's control height, like the button
3526
- beside it: the height comes from density, and the text sits centered in
3527
- it, instead of padding around the text setting a height of its own. */
3528
3604
  .ml-input {
3529
3605
  padding-block: 0;
3530
3606
  }
@@ -3619,7 +3695,6 @@ button.ml-breadcrumb-link {
3619
3695
  font-size: var(--ml-type-md);
3620
3696
  }
3621
3697
 
3622
- /* A field that is a button or a group says it is invalid with data-invalid: aria-invalid belongs to inputs. */
3623
3698
  .ml-input-field[data-invalid] .ml-input,
3624
3699
  .ml-input[aria-invalid="true"],
3625
3700
  .ml-input[data-invalid] {
@@ -3662,14 +3737,12 @@ button.ml-breadcrumb-link {
3662
3737
  pointer-events: none;
3663
3738
  }
3664
3739
 
3665
- /* A text affix ("https://", a domain, a unit) reads at the size of what is typed beside it. */
3666
3740
  .ml-input-leading,
3667
3741
  .ml-input-trailing {
3668
3742
  font-size: var(--ml-type-base);
3669
3743
  line-height: var(--ml-leading-snug);
3670
3744
  }
3671
3745
 
3672
- /* components/kbd */
3673
3746
  .ml-kbd {
3674
3747
  display: inline-grid;
3675
3748
  min-width: 1.5em;
@@ -3695,7 +3768,6 @@ button.ml-breadcrumb-link {
3695
3768
  font: inherit;
3696
3769
  }
3697
3770
 
3698
- /* components/modal */
3699
3771
  .ml-modal-overlay {
3700
3772
  position: fixed;
3701
3773
  inset: 0;
@@ -3798,13 +3870,10 @@ button.ml-breadcrumb-link {
3798
3870
  padding: var(--ml-space-4) var(--ml-space-6) var(--ml-space-6);
3799
3871
  }
3800
3872
 
3801
- /* components/number-input */
3802
- /* A number and its steppers, never squeezed below readable. */
3803
3873
  .ml-number-input {
3804
3874
  min-inline-size: 9rem;
3805
3875
  }
3806
3876
 
3807
- /* The input's surface, with the steppers inside its right edge. */
3808
3877
  .ml-number-input-control {
3809
3878
  display: flex;
3810
3879
  min-height: var(--ml-control-md);
@@ -3837,7 +3906,7 @@ button.ml-breadcrumb-link {
3837
3906
  .ml-number-input-field {
3838
3907
  flex: 1;
3839
3908
  min-width: 0;
3840
- /* The control's height comes from density, like a text field's. */
3909
+
3841
3910
  padding: 0 var(--ml-space-3);
3842
3911
  border: 0;
3843
3912
  background: transparent;
@@ -3858,9 +3927,6 @@ button.ml-breadcrumb-link {
3858
3927
  border-inline-start: var(--ml-border-width) solid var(--ml-border-subtle);
3859
3928
  }
3860
3929
 
3861
- /* Square at any height: where touch sizing makes the field taller, the steps
3862
- grow with it instead of stretching into tall slivers. They sit inside the
3863
- control's border, so their side is the height within it. */
3864
3930
  .ml-number-input-step {
3865
3931
  display: inline-grid;
3866
3932
  min-width: calc(var(--ml-control-md) - 2 * var(--ml-border-width));
@@ -3894,7 +3960,6 @@ button.ml-breadcrumb-link {
3894
3960
  opacity: 0.5;
3895
3961
  }
3896
3962
 
3897
- /* components/otp-input */
3898
3963
  .ml-otp {
3899
3964
  display: flex;
3900
3965
  max-width: 100%;
@@ -3902,7 +3967,6 @@ button.ml-breadcrumb-link {
3902
3967
  gap: var(--ml-space-2);
3903
3968
  }
3904
3969
 
3905
- /* Boxes give a little way on the narrowest phones instead of running past the edge. */
3906
3970
  .ml-otp-box {
3907
3971
  flex: 0 1 var(--ml-control-lg);
3908
3972
  width: var(--ml-control-lg);
@@ -3944,7 +4008,6 @@ button.ml-breadcrumb-link {
3944
4008
  background: var(--ml-border);
3945
4009
  }
3946
4010
 
3947
- /* components/pagination */
3948
4011
  .ml-pagination {
3949
4012
  display: flex;
3950
4013
  align-items: center;
@@ -4009,14 +4072,11 @@ button.ml-breadcrumb-link {
4009
4072
  color: var(--ml-text-muted);
4010
4073
  }
4011
4074
 
4012
- /* components/password-input */
4013
4075
  .ml-password-input {
4014
4076
  display: grid;
4015
4077
  gap: var(--ml-space-2);
4016
4078
  }
4017
4079
 
4018
- /* While the password shows, the toggle takes full ink: its state is seen,
4019
- not only announced. */
4020
4080
  .ml-password-input-toggle[aria-pressed="true"] {
4021
4081
  color: var(--ml-text);
4022
4082
  }
@@ -4037,8 +4097,6 @@ button.ml-breadcrumb-link {
4037
4097
  font-weight: 600;
4038
4098
  }
4039
4099
 
4040
- /* Three segments light up as the password grows. They are marks on the page,
4041
- so they take the -text roles, which clear 3:1 against it. */
4042
4100
  .ml-password-input-meter {
4043
4101
  display: grid;
4044
4102
  grid-template-columns: repeat(3, 1fr);
@@ -4085,7 +4143,6 @@ button.ml-breadcrumb-link {
4085
4143
  }
4086
4144
  }
4087
4145
 
4088
- /* components/popover */
4089
4146
  .ml-popover {
4090
4147
  position: fixed;
4091
4148
  z-index: var(--ml-layer-popover);
@@ -4093,8 +4150,7 @@ button.ml-breadcrumb-link {
4093
4150
  left: 0;
4094
4151
  min-width: 12rem;
4095
4152
  max-width: min(22rem, calc(100vw - 1rem));
4096
- /* No taller than the room on the side it opened (--ml-floating-room, from
4097
- useFloating), so it fits beside its trigger, even with a phone's keyboard up. */
4153
+
4098
4154
  max-height: var(--ml-floating-room, none);
4099
4155
  overflow-y: auto;
4100
4156
  overscroll-behavior: contain;
@@ -4116,7 +4172,6 @@ button.ml-breadcrumb-link {
4116
4172
  outline: none;
4117
4173
  }
4118
4174
 
4119
- /* It grows out of the side it opened from. */
4120
4175
  .ml-popover[data-side="bottom"] {
4121
4176
  --ml-popover-from: translateY(-4px);
4122
4177
  }
@@ -4140,7 +4195,6 @@ button.ml-breadcrumb-link {
4140
4195
  }
4141
4196
  }
4142
4197
 
4143
- /* components/priority-icon */
4144
4198
  .ml-priority-icon {
4145
4199
  --ml-priority-mark: var(--ml-danger-foreground);
4146
4200
  flex: none;
@@ -4160,7 +4214,6 @@ button.ml-breadcrumb-link {
4160
4214
  color: var(--ml-text);
4161
4215
  }
4162
4216
 
4163
- /* components/progress */
4164
4217
  .ml-progress-root {
4165
4218
  --ml-progress-tone: var(--ml-primary);
4166
4219
  --ml-progress-height: var(--ml-space-1-5);
@@ -4221,15 +4274,13 @@ button.ml-breadcrumb-link {
4221
4274
  box-shadow: inset 0 1px 1px color-mix(in oklab, var(--ml-text) 6%, transparent);
4222
4275
  }
4223
4276
 
4224
- /* The fill deepens towards its leading edge, so the bar reads as moving forward. */
4225
4277
  .ml-progress-fill {
4226
4278
  position: relative;
4227
4279
  height: 100%;
4228
4280
  overflow: hidden;
4229
4281
  border-radius: inherit;
4230
4282
  background: linear-gradient(90deg, color-mix(in oklab, var(--ml-progress-tone) 72%, var(--ml-surface)), var(--ml-progress-tone));
4231
- /* A steady chase toward each new value: frequent updates blend into one
4232
- motion instead of restarting a spring every time. */
4283
+
4233
4284
  transition: width var(--ml-duration-slow) var(--ml-ease-standard);
4234
4285
  animation: ml-progress-grow var(--ml-duration-reveal) var(--ml-ease-spring) both;
4235
4286
  }
@@ -4240,7 +4291,6 @@ button.ml-breadcrumb-link {
4240
4291
  }
4241
4292
  }
4242
4293
 
4243
- /* While work runs, a soft light sweeps along the fill. */
4244
4294
  .ml-progress-root[data-active] .ml-progress-fill::after {
4245
4295
  position: absolute;
4246
4296
  inset: 0;
@@ -4256,7 +4306,6 @@ button.ml-breadcrumb-link {
4256
4306
  }
4257
4307
  }
4258
4308
 
4259
- /* Done: one glow around the finished bar. */
4260
4309
  .ml-progress-root[data-state="complete"] .ml-progress-track {
4261
4310
  animation: ml-progress-done var(--ml-duration-reveal) var(--ml-ease-standard) var(--ml-duration-slow) both;
4262
4311
  }
@@ -4270,7 +4319,6 @@ button.ml-breadcrumb-link {
4270
4319
  }
4271
4320
  }
4272
4321
 
4273
- /* Unknown length: a segment glides across and loops. */
4274
4322
  .ml-progress-root[data-state="indeterminate"] .ml-progress-fill {
4275
4323
  position: absolute;
4276
4324
  inset-block: 0;
@@ -4423,7 +4471,6 @@ button.ml-breadcrumb-link {
4423
4471
  }
4424
4472
  }
4425
4473
 
4426
- /* components/radio-group */
4427
4474
  .ml-radio-item {
4428
4475
  display: grid;
4429
4476
  grid-template-columns: auto 1fr;
@@ -4540,7 +4587,6 @@ button.ml-breadcrumb-link {
4540
4587
  align-content: start;
4541
4588
  }
4542
4589
 
4543
- /* components/rating */
4544
4590
  .ml-rating {
4545
4591
  display: inline-flex;
4546
4592
  align-items: center;
@@ -4574,10 +4620,6 @@ button.ml-breadcrumb-link {
4574
4620
  font-variant-numeric: tabular-nums;
4575
4621
  }
4576
4622
 
4577
- /* components/resizable */
4578
- /* The handle's width is a setting (an app shell draws a hairline): its
4579
- default weighs nothing, so one class on the same element sets it, in any
4580
- stylesheet order. */
4581
4623
  :where(.ml-resizable) {
4582
4624
  --ml-resizable-handle: var(--ml-space-2);
4583
4625
  }
@@ -4587,13 +4629,12 @@ button.ml-breadcrumb-link {
4587
4629
  height: 100%;
4588
4630
  min-width: 0;
4589
4631
  min-height: 0;
4590
- /* A folded or zero-width pane keeps its content mounted; nothing of it may widen the page. */
4632
+
4591
4633
  overflow: clip;
4592
- /* The handle's layer stays inside the component. */
4634
+
4593
4635
  isolation: isolate;
4594
4636
  }
4595
4637
 
4596
- /* The anchored pane takes the size; the other takes the rest. */
4597
4638
  .ml-resizable[data-direction="horizontal"] {
4598
4639
  grid-template-columns: minmax(0, var(--ml-resizable-size)) var(--ml-resizable-handle) minmax(0, 1fr);
4599
4640
  }
@@ -4610,28 +4651,23 @@ button.ml-breadcrumb-link {
4610
4651
  grid-template-rows: minmax(0, 1fr) var(--ml-resizable-handle) minmax(0, var(--ml-resizable-size));
4611
4652
  }
4612
4653
 
4613
- /* Each pane is a containing block, so absolutely placed content (visually
4614
- hidden labels, popover anchors) is clipped with it instead of escaping. */
4615
4654
  .ml-resizable-pane {
4616
4655
  position: relative;
4617
- /* A pane's own layers (sticky headers, raised rows) stay inside it, so they
4618
- never paint over the handle's line or its grab area. */
4656
+
4619
4657
  isolation: isolate;
4620
4658
  min-width: 0;
4621
4659
  min-height: 0;
4622
4660
  overflow: auto;
4623
4661
  }
4624
4662
 
4625
- /* A folded pane keeps its content mounted but out of reach. */
4626
4663
  .ml-resizable-pane[data-folded] {
4627
4664
  visibility: hidden;
4628
4665
  overflow: clip;
4629
4666
  }
4630
4667
 
4631
- /* A hairline that thickens into a grip on hover, focus or drag. */
4632
4668
  .ml-resizable-handle {
4633
4669
  position: relative;
4634
- /* The line and its grab area are wider than a hairline handle, so they sit above both panes. */
4670
+
4635
4671
  z-index: var(--ml-layer-raised);
4636
4672
  display: grid;
4637
4673
  place-items: center;
@@ -4675,7 +4711,6 @@ button.ml-breadcrumb-link {
4675
4711
  outline: none;
4676
4712
  }
4677
4713
 
4678
- /* The grab area is wider than the line, so a 1px handle in an app shell is still easy to catch. */
4679
4714
  .ml-resizable-handle::after {
4680
4715
  position: absolute;
4681
4716
  inset: 0 calc(-1 * var(--ml-space-1));
@@ -4687,7 +4722,6 @@ button.ml-breadcrumb-link {
4687
4722
  inset: calc(-1 * var(--ml-space-1)) 0;
4688
4723
  }
4689
4724
 
4690
- /* A finger needs more: 24 px of grab area on a touch screen. */
4691
4725
  @media (pointer: coarse) {
4692
4726
  .ml-resizable-handle::after {
4693
4727
  inset: 0 calc(-1 * var(--ml-space-2));
@@ -4698,8 +4732,6 @@ button.ml-breadcrumb-link {
4698
4732
  }
4699
4733
  }
4700
4734
 
4701
- /* components/segmented-control */
4702
- /* In a narrow container the options wrap onto a second row instead of spilling out. */
4703
4735
  .ml-segmented-control {
4704
4736
  display: inline-flex;
4705
4737
  flex-wrap: wrap;
@@ -4712,8 +4744,6 @@ button.ml-breadcrumb-link {
4712
4744
  gap: var(--ml-space-0-5);
4713
4745
  }
4714
4746
 
4715
- /* Each option is a small control inside the track, so the whole control is
4716
- as tall as a medium one and sits level with the fields beside it. */
4717
4747
  .ml-segmented-control-item {
4718
4748
  min-height: var(--ml-control-sm);
4719
4749
  padding: 0 var(--ml-space-3);
@@ -4738,14 +4768,11 @@ button.ml-breadcrumb-link {
4738
4768
  box-shadow: var(--ml-shadow-sm);
4739
4769
  }
4740
4770
 
4741
- /* components/select */
4742
- /* minmax(0, 1fr) and min-width: 0 let a long value truncate instead of
4743
- widening the select past its container. */
4744
4771
  .ml-select-root {
4745
4772
  position: relative;
4746
4773
  display: grid;
4747
4774
  grid-template-columns: minmax(0, 1fr);
4748
- /* In a form row taller than itself, the trigger keeps a field's height instead of stretching. */
4775
+
4749
4776
  align-content: start;
4750
4777
  gap: var(--ml-space-1-5);
4751
4778
  width: 100%;
@@ -4765,14 +4792,14 @@ button.ml-breadcrumb-link {
4765
4792
  align-items: center;
4766
4793
  justify-content: space-between;
4767
4794
  gap: var(--ml-space-2);
4768
- /* As tall as its size's control height, level with an input or a button. */
4795
+
4769
4796
  padding: 0 var(--ml-space-3);
4770
4797
  color: var(--ml-text);
4771
4798
  background: var(--ml-surface);
4772
4799
  border: var(--ml-border-width) solid var(--ml-border);
4773
4800
  border-radius: var(--ml-radius-md);
4774
4801
  box-shadow: var(--ml-shadow-xs);
4775
- /* The same type as a text field, so a select and an input sit level in a row. */
4802
+
4776
4803
  font-family: var(--ml-font-sans);
4777
4804
  font-size: var(--ml-type-base);
4778
4805
  line-height: var(--ml-leading-snug);
@@ -4864,8 +4891,6 @@ button.ml-breadcrumb-link {
4864
4891
  color: var(--ml-text);
4865
4892
  }
4866
4893
 
4867
- /* In the top layer (the Popover API) the browser's own popover styles are
4868
- set back: no centering margin, no stretching inset, the theme's ink. */
4869
4894
  .ml-select-popover {
4870
4895
  position: fixed;
4871
4896
  z-index: var(--ml-layer-top);
@@ -4876,8 +4901,7 @@ button.ml-breadcrumb-link {
4876
4901
  color: var(--ml-text);
4877
4902
  display: flex;
4878
4903
  flex-direction: column;
4879
- /* No taller than the room on the side it opened (--ml-floating-room, from
4880
- useFloating), so it fits beside its trigger, even with a phone's keyboard up. */
4904
+
4881
4905
  max-height: var(--ml-floating-room, none);
4882
4906
  max-width: calc(100vw - var(--ml-space-4));
4883
4907
  padding: var(--ml-space-1);
@@ -4911,7 +4935,7 @@ button.ml-breadcrumb-link {
4911
4935
  border-radius: var(--ml-radius-sm);
4912
4936
  background: transparent;
4913
4937
  font-size: var(--ml-type-sm);
4914
- /* audit-allow: focus.removed — the search field inside an open listbox; its caret shows focus. */
4938
+
4915
4939
  outline: none;
4916
4940
  }
4917
4941
 
@@ -5021,7 +5045,6 @@ button.ml-breadcrumb-link {
5021
5045
  color: var(--ml-danger-text);
5022
5046
  }
5023
5047
 
5024
- /* components/sheet */
5025
5048
  .ml-sheet-overlay {
5026
5049
  position: fixed;
5027
5050
  inset: 0;
@@ -5058,8 +5081,6 @@ button.ml-breadcrumb-link {
5058
5081
  z-index: var(--ml-layer-overlay);
5059
5082
  }
5060
5083
 
5061
- /* The panel floats a hairline in from its edge, rounded like every other
5062
- surface, instead of being glued to the viewport. */
5063
5084
  .ml-sheet-panel {
5064
5085
  --ml-sheet-inset: var(--ml-space-2);
5065
5086
  --ml-sheet-radius: calc(var(--ml-radius-lg) + 2px);
@@ -5161,10 +5182,6 @@ button.ml-breadcrumb-link {
5161
5182
  padding: var(--ml-space-4) var(--ml-space-6) var(--ml-space-6);
5162
5183
  }
5163
5184
 
5164
- /* components/skeleton */
5165
- /* One light band sweeps the whole viewport, so every placeholder on the page
5166
- glints in unison instead of each shimmering at its own speed. Where fixed
5167
- backgrounds are ignored (iOS), each shape still shimmers on its own. */
5168
5185
  .ml-skeleton {
5169
5186
  --ml-skeleton-base: color-mix(in oklab, var(--ml-text) 8%, transparent);
5170
5187
  --ml-skeleton-glint: color-mix(in oklab, var(--ml-text) 3%, transparent);
@@ -5176,7 +5193,7 @@ button.ml-breadcrumb-link {
5176
5193
  var(--ml-skeleton-base) 60%
5177
5194
  )
5178
5195
  0 0 / 200vw 100% fixed;
5179
- /* Quick loads never flash a placeholder: it appears only after a beat. */
5196
+
5180
5197
  animation:
5181
5198
  ml-skeleton-appear 240ms var(--ml-ease-standard) 160ms both,
5182
5199
  ml-skeleton-sweep 1.6s linear infinite;
@@ -5206,8 +5223,6 @@ button.ml-breadcrumb-link {
5206
5223
  width: 100%;
5207
5224
  }
5208
5225
 
5209
- /* Each line is one line box of the surrounding text: a bar about the height
5210
- of lowercase letters, centered in 1lh. */
5211
5226
  .ml-skeleton-line {
5212
5227
  height: 0.62em;
5213
5228
  margin-block: calc((1lh - 0.62em) / 2);
@@ -5263,7 +5278,6 @@ button.ml-breadcrumb-link {
5263
5278
  }
5264
5279
  }
5265
5280
 
5266
- /* components/slider */
5267
5281
  .ml-slider-field {
5268
5282
  display: grid;
5269
5283
  gap: var(--ml-space-2-5);
@@ -5294,7 +5308,7 @@ button.ml-breadcrumb-link {
5294
5308
  width: 100%;
5295
5309
  align-items: center;
5296
5310
  min-height: var(--ml-space-6);
5297
- /* A finger scrolls the page up and down; sideways it moves the value. */
5311
+
5298
5312
  touch-action: pan-y;
5299
5313
  cursor: pointer;
5300
5314
  }
@@ -5343,8 +5357,7 @@ button.ml-breadcrumb-link {
5343
5357
  }
5344
5358
 
5345
5359
  .ml-slider-thumb:hover,
5346
- /* Focus lands on the slider (it carries role="slider"); the ring is drawn
5347
- on the thumb, where the eye already is. */
5360
+
5348
5361
  .ml-slider:focus-visible {
5349
5362
  outline: none;
5350
5363
  }
@@ -5354,10 +5367,6 @@ button.ml-breadcrumb-link {
5354
5367
  outline-offset: 2px;
5355
5368
  }
5356
5369
 
5357
- /* components/spinner */
5358
- /* A ring of the current text color with one bright arc. It is drawn from
5359
- currentColor alone, so it matches the label beside it in a button, a
5360
- toast or a line of text, in every theme and mode. */
5361
5370
  .ml-spinner {
5362
5371
  display: inline-block;
5363
5372
  flex: none;
@@ -5382,8 +5391,6 @@ button.ml-breadcrumb-link {
5382
5391
  border-width: 2.5px;
5383
5392
  }
5384
5393
 
5385
- /* Under forced colors the ring is the system's text color, and the arc is
5386
- a real border that stays visible. */
5387
5394
  @media (forced-colors: active) {
5388
5395
  .ml-spinner {
5389
5396
  border-color: CanvasText;
@@ -5391,8 +5398,6 @@ button.ml-breadcrumb-link {
5391
5398
  }
5392
5399
  }
5393
5400
 
5394
- /* components/status-icon */
5395
- /* Color carries the stage; the glyph carries it without color too. */
5396
5401
  .ml-status-icon {
5397
5402
  --ml-status-mark: var(--ml-surface);
5398
5403
  flex: none;
@@ -5412,9 +5417,8 @@ button.ml-breadcrumb-link {
5412
5417
  color: var(--ml-success-text);
5413
5418
  }
5414
5419
 
5415
- /* Done is a filled disc carrying its check in the foreground: a fill and its pair. */
5416
5420
  .ml-status-icon[data-status="done"] {
5417
- /* audit-allow: color.role — the disc is a fill; its mark takes --ml-primary-foreground. */
5421
+
5418
5422
  color: var(--ml-primary);
5419
5423
  --ml-status-mark: var(--ml-primary-foreground);
5420
5424
  }
@@ -5423,8 +5427,6 @@ button.ml-breadcrumb-link {
5423
5427
  color: var(--ml-text-faint);
5424
5428
  }
5425
5429
 
5426
- /* components/stepper */
5427
- /* The container, not the screen, decides when the row condenses. */
5428
5430
  .ml-stepper {
5429
5431
  --ml-stepper-marker: 1.75rem;
5430
5432
  container: ml-stepper / inline-size;
@@ -5454,8 +5456,6 @@ button.ml-breadcrumb-link {
5454
5456
  flex: none;
5455
5457
  }
5456
5458
 
5457
- /* Horizontal: the connector is a flex item after the step, level with the
5458
- marker's center, and fills once the step is done. */
5459
5459
  .ml-stepper[data-orientation="horizontal"] .ml-stepper-step:not(:last-child)::after {
5460
5460
  min-width: var(--ml-space-4);
5461
5461
  height: 2px;
@@ -5584,7 +5584,6 @@ button.ml-stepper-target:focus-visible {
5584
5584
  font-size: var(--ml-type-xs);
5585
5585
  }
5586
5586
 
5587
- /* Compact: one line with the current step and a meter. */
5588
5587
  .ml-stepper-summary {
5589
5588
  display: none;
5590
5589
  grid-template-columns: auto 1fr;
@@ -5616,10 +5615,8 @@ button.ml-stepper-target:focus-visible {
5616
5615
  }
5617
5616
  }
5618
5617
 
5619
- /* components/table */
5620
5618
  .ml-table-container {
5621
- /* The containing block for anything positioned inside, such as visually
5622
- hidden cell text, so it scrolls with the table instead of widening the page. */
5619
+
5623
5620
  position: relative;
5624
5621
  width: 100%;
5625
5622
  overflow-x: auto;
@@ -5629,7 +5626,6 @@ button.ml-stepper-target:focus-visible {
5629
5626
  box-shadow: var(--ml-shadow-xs);
5630
5627
  }
5631
5628
 
5632
- /* Focusable only while it scrolls; the ring sits inside, where it cannot be clipped. */
5633
5629
  .ml-table-container:focus-visible {
5634
5630
  outline: 2px solid var(--ml-focus);
5635
5631
  outline-offset: -2px;
@@ -5665,8 +5661,6 @@ button.ml-stepper-target:focus-visible {
5665
5661
  background: transparent;
5666
5662
  }
5667
5663
 
5668
- /* A header cell lines up with its column. Browsers center th by default, which
5669
- a table's own text-align does not reach. */
5670
5664
  .ml-table th,
5671
5665
  .ml-table-header th,
5672
5666
  .ml-table-head {
@@ -5786,7 +5780,6 @@ button.ml-stepper-target:focus-visible {
5786
5780
  color: var(--ml-text-faint);
5787
5781
  }
5788
5782
 
5789
- /* components/tabs */
5790
5783
  .ml-tabs {
5791
5784
  display: grid;
5792
5785
  grid-template-columns: minmax(0, 1fr);
@@ -5907,13 +5900,10 @@ button.ml-stepper-target:focus-visible {
5907
5900
  display: none;
5908
5901
  }
5909
5902
 
5910
- /* components/tag-input */
5911
- /* Room for a couple of tags beside the caret. */
5912
5903
  .ml-tag-input {
5913
5904
  min-inline-size: 14rem;
5914
5905
  }
5915
5906
 
5916
- /* The control wears the input's surface, with tags flowing before the caret. */
5917
5907
  .ml-tag-input-control {
5918
5908
  position: relative;
5919
5909
  display: flex;
@@ -5974,7 +5964,6 @@ button.ml-stepper-target:focus-visible {
5974
5964
  transition: background-color var(--ml-duration-fast), border-color var(--ml-duration-fast);
5975
5965
  }
5976
5966
 
5977
- /* Marked by Backspace or the arrows: the next Backspace removes it. */
5978
5967
  .ml-tag-input-tag[data-armed] {
5979
5968
  border-color: var(--ml-danger);
5980
5969
  background: color-mix(in oklab, var(--ml-danger) 12%, var(--ml-surface));
@@ -6029,9 +6018,6 @@ button.ml-stepper-target:focus-visible {
6029
6018
  font-variant-numeric: tabular-nums;
6030
6019
  }
6031
6020
 
6032
- /* components/textarea */
6033
- /* Shares its surface with Input (input.css); this file adds only growth and
6034
- the counter. */
6035
6021
  .ml-textarea {
6036
6022
  max-height: calc(var(--ml-textarea-max-rows, 12) * 1lh + 2 * var(--ml-space-2));
6037
6023
  field-sizing: content;
@@ -6050,13 +6036,10 @@ button.ml-stepper-target:focus-visible {
6050
6036
  color: var(--ml-danger-text);
6051
6037
  }
6052
6038
 
6053
- /* components/time-picker */
6054
- /* Room for hours, minutes and AM/PM without the field collapsing. */
6055
6039
  .ml-time-picker {
6056
6040
  min-inline-size: 8rem;
6057
6041
  }
6058
6042
 
6059
- /* The control wears the input's surface; its segments are the fields inside. */
6060
6043
  .ml-time-picker-control {
6061
6044
  display: flex;
6062
6045
  align-items: center;
@@ -6177,15 +6160,10 @@ button.ml-stepper-target:focus-visible {
6177
6160
  outline-offset: -1px;
6178
6161
  }
6179
6162
 
6180
- /* A typed time the rules refuse reads as an error until focus leaves and it snaps. */
6181
6163
  .ml-time-picker-control[data-unavailable] .ml-time-picker-segment {
6182
6164
  color: var(--ml-danger-text);
6183
6165
  }
6184
6166
 
6185
- /* components/timeline */
6186
- /* A rail of markers and a column of text. Each item draws the segment of
6187
- rail below its own marker, so the line always runs through the centers,
6188
- whatever each item holds, and fills in as the sequence progresses. */
6189
6167
  .ml-timeline {
6190
6168
  --ml-timeline-marker: 1.5rem;
6191
6169
  --ml-timeline-rail: 2px;
@@ -6219,7 +6197,6 @@ button.ml-stepper-target:focus-visible {
6219
6197
  content: "";
6220
6198
  }
6221
6199
 
6222
- /* Done: the rail is drawn in; from the current step it fades toward what is next. */
6223
6200
  .ml-timeline-item[data-status="complete"]:not(:last-child)::before {
6224
6201
  background: var(--ml-primary);
6225
6202
  }
@@ -6274,7 +6251,6 @@ button.ml-stepper-target:focus-visible {
6274
6251
  }
6275
6252
  }
6276
6253
 
6277
- /* Event tones for activity feeds; they win over the status fill. */
6278
6254
  .ml-timeline-marker[data-tone] {
6279
6255
  --ml-timeline-tone: var(--ml-text);
6280
6256
  --ml-timeline-tone-text: var(--ml-text);
@@ -6313,7 +6289,6 @@ button.ml-stepper-target:focus-visible {
6313
6289
  min-width: 0;
6314
6290
  }
6315
6291
 
6316
- /* The heading row is as tall as the marker, so a one-line title sits on its center. */
6317
6292
  .ml-timeline-heading {
6318
6293
  display: flex;
6319
6294
  flex-wrap: wrap;
@@ -6361,14 +6336,11 @@ button.ml-stepper-target:focus-visible {
6361
6336
  }
6362
6337
  }
6363
6338
 
6364
- /* components/toast */
6365
- /* The stack sits a set distance from the viewport edges. Apps with a sticky
6366
- header move top stacks below it with --ml-toaster-offset-top. */
6367
6339
  .ml-toaster {
6368
6340
  --ml-toaster-offset: var(--ml-space-4);
6369
6341
  position: fixed;
6370
6342
  z-index: var(--ml-layer-toast);
6371
- /* In the top layer (the Popover API, framework-free) the browser's own popover styles are set back. */
6343
+
6372
6344
  inset: auto;
6373
6345
  margin: 0;
6374
6346
  padding: 0;
@@ -6392,8 +6364,6 @@ button.ml-stepper-target:focus-visible {
6392
6364
  bottom: var(--ml-toaster-offset-bottom, var(--ml-toaster-offset));
6393
6365
  }
6394
6366
 
6395
- /* --ml-scroll-lock-offset is the padding a scroll lock adds, so a toast
6396
- stays put when an overlay opens. */
6397
6367
  .ml-toaster[data-position="top-right"],
6398
6368
  .ml-toaster[data-position="bottom-right"] {
6399
6369
  right: calc(var(--ml-toaster-offset) + var(--ml-scroll-lock-offset, 0px));
@@ -6405,7 +6375,6 @@ button.ml-stepper-target:focus-visible {
6405
6375
  translate: -50% 0;
6406
6376
  }
6407
6377
 
6408
- /* On a phone the stack spans the screen with even margins. */
6409
6378
  @media (max-width: 30rem) {
6410
6379
  .ml-toaster {
6411
6380
  left: var(--ml-toaster-offset);
@@ -6415,8 +6384,6 @@ button.ml-stepper-target:focus-visible {
6415
6384
  }
6416
6385
  }
6417
6386
 
6418
- /* Each toast lives in a slot that can fold to nothing, so when one leaves
6419
- the others glide into its place instead of jumping. */
6420
6387
  .ml-toast-slot {
6421
6388
  display: grid;
6422
6389
  grid-template-rows: 1fr;
@@ -6485,7 +6452,6 @@ button.ml-stepper-target:focus-visible {
6485
6452
  transition: none;
6486
6453
  }
6487
6454
 
6488
- /* With a description the icon and actions sit on the first line, not the middle. */
6489
6455
  .ml-toast[data-has-description] {
6490
6456
  align-items: flex-start;
6491
6457
  }
@@ -6588,7 +6554,6 @@ button.ml-stepper-target:focus-visible {
6588
6554
  }
6589
6555
  }
6590
6556
 
6591
- /* components/toggle */
6592
6557
  .ml-switch-field {
6593
6558
  display: inline-flex;
6594
6559
  align-items: center;
@@ -6698,16 +6663,11 @@ button.ml-stepper-target:focus-visible {
6698
6663
  color: var(--ml-text);
6699
6664
  }
6700
6665
 
6701
- /* components/tooltip */
6702
6666
  .ml-tooltip-root {
6703
6667
  position: relative;
6704
6668
  display: inline-flex;
6705
6669
  }
6706
6670
 
6707
- /* A layer above the page, placed beside its trigger by script (React's
6708
- useFloating, the runtime's floatingLayer), so no panel, card or scroll
6709
- area around the trigger can cover or cut it. In the top layer (the
6710
- Popover API) the browser's own popover styles are set back. */
6711
6671
  .ml-tooltip {
6712
6672
  position: fixed;
6713
6673
  z-index: var(--ml-layer-tooltip);
@@ -6725,7 +6685,7 @@ button.ml-stepper-target:focus-visible {
6725
6685
  font-size: var(--ml-type-xs);
6726
6686
  font-weight: 500;
6727
6687
  line-height: 1.4;
6728
- /* One line when it fits; a long tip wraps within the window instead of running past it. */
6688
+
6729
6689
  width: max-content;
6730
6690
  max-width: min(20rem, calc(100vw - 2 * var(--ml-space-2)));
6731
6691
  white-space: normal;
@@ -6741,7 +6701,6 @@ button.ml-stepper-target:focus-visible {
6741
6701
  transform: rotate(45deg);
6742
6702
  }
6743
6703
 
6744
- /* The arrow slides back by the tooltip's shift, so it keeps pointing at the trigger. */
6745
6704
  .ml-tooltip[data-side="top"] .ml-tooltip-arrow,
6746
6705
  .ml-tooltip:not([data-side]) .ml-tooltip-arrow {
6747
6706
  bottom: -.2rem;
@@ -6767,14 +6726,12 @@ button.ml-stepper-target:focus-visible {
6767
6726
  margin-top: calc(var(--ml-space-1) * -1 - var(--ml-floating-shift, 0px));
6768
6727
  }
6769
6728
 
6770
- /* components/tour */
6771
6729
  .ml-tour {
6772
6730
  position: fixed;
6773
6731
  inset: 0;
6774
6732
  z-index: var(--ml-layer-top);
6775
6733
  }
6776
6734
 
6777
- /* Without a target the whole page dims; with one, the spotlight casts the dimming. */
6778
6735
  .ml-tour-scrim {
6779
6736
  position: absolute;
6780
6737
  inset: 0;
@@ -6806,7 +6763,7 @@ button.ml-stepper-target:focus-visible {
6806
6763
  background: var(--ml-surface-elevated);
6807
6764
  box-shadow: var(--ml-shadow-xl);
6808
6765
  color: var(--ml-text);
6809
- /* audit-allow: focus.removed — the tour card is focused by script (tabindex -1); its buttons carry the focus style. */
6766
+
6810
6767
  outline: none;
6811
6768
  animation: ml-pop-in var(--ml-duration-fast) var(--ml-ease-spring);
6812
6769
  }
@@ -6915,7 +6872,6 @@ button.ml-stepper-target:focus-visible {
6915
6872
  }
6916
6873
  }
6917
6874
 
6918
- /* components/virtual-list */
6919
6875
  .ml-virtual-list {
6920
6876
  position: relative;
6921
6877
  overflow-y: auto;
@@ -6928,7 +6884,6 @@ button.ml-stepper-target:focus-visible {
6928
6884
  box-shadow: inset 0 0 0 2px var(--ml-focus);
6929
6885
  }
6930
6886
 
6931
- /* The full height of every row, so the scrollbar tells the truth. */
6932
6887
  .ml-virtual-list-space {
6933
6888
  position: relative;
6934
6889
  width: 100%;