@openwarelabs/ui 0.14.1 → 0.16.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.
Files changed (81) hide show
  1. package/README.md +5 -5
  2. package/dist/components/ActivityHeatmap/ActivityHeatmap.d.cts +8 -0
  3. package/dist/components/ActivityHeatmap/ActivityHeatmap.d.ts +8 -0
  4. package/dist/components/ActivityHeatmap/ActivityHeatmap.types.d.cts +73 -0
  5. package/dist/components/ActivityHeatmap/ActivityHeatmap.types.d.ts +73 -0
  6. package/dist/components/DiffViewer/DiffViewer.d.cts +8 -0
  7. package/dist/components/DiffViewer/DiffViewer.d.ts +8 -0
  8. package/dist/components/DiffViewer/DiffViewer.types.d.cts +131 -0
  9. package/dist/components/DiffViewer/DiffViewer.types.d.ts +131 -0
  10. package/dist/components/DiffViewer/diff.d.cts +10 -0
  11. package/dist/components/DiffViewer/diff.d.ts +10 -0
  12. package/dist/components/InlineEdit/InlineEdit.d.cts +8 -0
  13. package/dist/components/InlineEdit/InlineEdit.d.ts +8 -0
  14. package/dist/components/InlineEdit/InlineEdit.types.d.cts +74 -0
  15. package/dist/components/InlineEdit/InlineEdit.types.d.ts +74 -0
  16. package/dist/components/Markdown/Markdown.d.cts +8 -0
  17. package/dist/components/Markdown/Markdown.d.ts +8 -0
  18. package/dist/components/Markdown/Markdown.types.d.cts +59 -0
  19. package/dist/components/Markdown/Markdown.types.d.ts +59 -0
  20. package/dist/components/MediaPlayer/MediaPlayer.d.cts +8 -0
  21. package/dist/components/MediaPlayer/MediaPlayer.d.ts +8 -0
  22. package/dist/components/MediaPlayer/MediaPlayer.types.d.cts +109 -0
  23. package/dist/components/MediaPlayer/MediaPlayer.types.d.ts +109 -0
  24. package/dist/components/MentionInput/MentionInput.d.cts +9 -0
  25. package/dist/components/MentionInput/MentionInput.d.ts +9 -0
  26. package/dist/components/MentionInput/MentionInput.types.d.cts +125 -0
  27. package/dist/components/MentionInput/MentionInput.types.d.ts +125 -0
  28. package/dist/components/MentionInput/useMentions.d.cts +8 -0
  29. package/dist/components/MentionInput/useMentions.d.ts +8 -0
  30. package/dist/components/NavigationMenu/NavigationMenu.d.cts +14 -0
  31. package/dist/components/NavigationMenu/NavigationMenu.d.ts +14 -0
  32. package/dist/components/NavigationMenu/NavigationMenu.types.d.cts +84 -0
  33. package/dist/components/NavigationMenu/NavigationMenu.types.d.ts +84 -0
  34. package/dist/components/NotificationCenter/NotificationCenter.d.cts +12 -0
  35. package/dist/components/NotificationCenter/NotificationCenter.d.ts +12 -0
  36. package/dist/components/NotificationCenter/NotificationCenter.types.d.cts +129 -0
  37. package/dist/components/NotificationCenter/NotificationCenter.types.d.ts +129 -0
  38. package/dist/components/QRCode/QRCode.d.cts +18 -0
  39. package/dist/components/QRCode/QRCode.d.ts +18 -0
  40. package/dist/components/QRCode/QRCode.types.d.cts +53 -0
  41. package/dist/components/QRCode/QRCode.types.d.ts +53 -0
  42. package/dist/components/QRCode/qr.d.cts +8 -0
  43. package/dist/components/QRCode/qr.d.ts +8 -0
  44. package/dist/components/SignaturePad/SignaturePad.d.cts +8 -0
  45. package/dist/components/SignaturePad/SignaturePad.d.ts +8 -0
  46. package/dist/components/SignaturePad/SignaturePad.types.d.cts +102 -0
  47. package/dist/components/SignaturePad/SignaturePad.types.d.ts +102 -0
  48. package/dist/components/SortableList/SortableList.d.cts +7 -0
  49. package/dist/components/SortableList/SortableList.d.ts +7 -0
  50. package/dist/components/SortableList/SortableList.types.d.cts +82 -0
  51. package/dist/components/SortableList/SortableList.types.d.ts +82 -0
  52. package/dist/components/TransferList/TransferList.d.cts +7 -0
  53. package/dist/components/TransferList/TransferList.d.ts +7 -0
  54. package/dist/components/TransferList/TransferList.types.d.cts +75 -0
  55. package/dist/components/TransferList/TransferList.types.d.ts +75 -0
  56. package/dist/components/TreeView/TreeView.d.cts +8 -0
  57. package/dist/components/TreeView/TreeView.d.ts +8 -0
  58. package/dist/components/TreeView/TreeView.types.d.cts +88 -0
  59. package/dist/components/TreeView/TreeView.types.d.ts +88 -0
  60. package/dist/components/UploadList/UploadList.d.cts +9 -0
  61. package/dist/components/UploadList/UploadList.d.ts +9 -0
  62. package/dist/components/UploadList/UploadList.types.d.cts +113 -0
  63. package/dist/components/UploadList/UploadList.types.d.ts +113 -0
  64. package/dist/components/UploadList/useUploadQueue.d.cts +8 -0
  65. package/dist/components/UploadList/useUploadQueue.d.ts +8 -0
  66. package/dist/components/VirtualList/VirtualList.d.cts +9 -0
  67. package/dist/components/VirtualList/VirtualList.d.ts +9 -0
  68. package/dist/components/VirtualList/VirtualList.types.d.cts +80 -0
  69. package/dist/components/VirtualList/VirtualList.types.d.ts +80 -0
  70. package/dist/components/VirtualList/useVirtualizer.d.cts +60 -0
  71. package/dist/components/VirtualList/useVirtualizer.d.ts +60 -0
  72. package/dist/components.css +1840 -113
  73. package/dist/index.cjs +6770 -2144
  74. package/dist/index.cjs.map +4 -4
  75. package/dist/index.d.cts +32 -0
  76. package/dist/index.d.ts +32 -0
  77. package/dist/index.js +6790 -2124
  78. package/dist/index.js.map +4 -4
  79. package/dist/openware-ui.iife.js +24 -8
  80. package/dist/styles.css +1840 -113
  81. package/package.json +1 -1
package/dist/styles.css CHANGED
@@ -1789,6 +1789,208 @@
1789
1789
  outline: 0;
1790
1790
  }
1791
1791
 
1792
+ /* components/InlineEdit/InlineEdit.css */
1793
+ /* InlineEdit: text that turns into a text box where it is. The button and the box share their font, padding and border,
1794
+ and pull back by them, so the text lines up with what's around it and doesn't move when the box opens. */
1795
+ .ow-inline-edit {
1796
+ --ow-inline-edit-x: 0.375em;
1797
+ --ow-inline-edit-y: 0.125em;
1798
+ --ow-inline-edit-icon: clamp(12px, 0.75em, 20px);
1799
+ display: inline-grid;
1800
+ max-width: 100%;
1801
+ grid-template-columns: minmax(0, 1fr);
1802
+ gap: var(--ow-space-2xs);
1803
+ }
1804
+
1805
+ .ow-inline-edit--multiline {
1806
+ display: grid;
1807
+ }
1808
+
1809
+ .ow-inline-edit__display,
1810
+ .ow-inline-edit__input,
1811
+ .ow-inline-edit__field::after {
1812
+ box-sizing: border-box;
1813
+ margin: 0;
1814
+ border: 1px solid transparent;
1815
+ border-radius: var(--ow-radius-sm);
1816
+ padding: var(--ow-inline-edit-y) var(--ow-inline-edit-x);
1817
+ color: inherit;
1818
+ font: inherit;
1819
+ letter-spacing: inherit;
1820
+ }
1821
+
1822
+ .ow-inline-edit__display,
1823
+ .ow-inline-edit__editor {
1824
+ margin-inline: calc(-1px - var(--ow-inline-edit-x));
1825
+ }
1826
+
1827
+ .ow-inline-edit__display {
1828
+ position: relative;
1829
+ display: inline-flex;
1830
+ min-width: 0;
1831
+ align-items: baseline;
1832
+ gap: 0.3em;
1833
+ background: transparent;
1834
+ cursor: pointer;
1835
+ text-align: start;
1836
+ }
1837
+
1838
+ .ow-inline-edit--multiline .ow-inline-edit__display {
1839
+ display: flex;
1840
+ }
1841
+
1842
+ .ow-inline-edit__display:hover:not(:disabled) {
1843
+ background: var(--ow-hover);
1844
+ }
1845
+
1846
+ .ow-inline-edit__display:focus-visible {
1847
+ outline: 2px solid var(--ow-focus-ring);
1848
+ outline-offset: 2px;
1849
+ }
1850
+
1851
+ .ow-inline-edit__display:disabled {
1852
+ cursor: not-allowed;
1853
+ opacity: 0.62;
1854
+ }
1855
+
1856
+ .ow-inline-edit__text {
1857
+ min-width: 0;
1858
+ overflow-wrap: anywhere;
1859
+ white-space: pre-wrap;
1860
+ }
1861
+
1862
+ .ow-inline-edit__text--empty {
1863
+ color: var(--ow-text-muted);
1864
+ }
1865
+
1866
+ /* The pencil shows on hover and focus; on touch screens, which can't hover, always. */
1867
+ .ow-inline-edit__icon {
1868
+ width: var(--ow-inline-edit-icon);
1869
+ height: var(--ow-inline-edit-icon);
1870
+ flex: none;
1871
+ align-self: center;
1872
+ color: var(--ow-icon);
1873
+ opacity: 0;
1874
+ }
1875
+
1876
+ .ow-inline-edit__display:hover .ow-inline-edit__icon,
1877
+ .ow-inline-edit__display:focus-visible .ow-inline-edit__icon {
1878
+ opacity: 1;
1879
+ }
1880
+
1881
+ @media (hover: none) {
1882
+ .ow-inline-edit__display:not(:disabled) .ow-inline-edit__icon {
1883
+ opacity: 1;
1884
+ }
1885
+ }
1886
+
1887
+ .ow-inline-edit__editor {
1888
+ display: flex;
1889
+ min-width: 0;
1890
+ align-items: center;
1891
+ gap: var(--ow-space-xs);
1892
+ }
1893
+
1894
+ /* The box is as wide as a hidden copy of its text, plus the pencil's room, in the same grid cell. */
1895
+ .ow-inline-edit__field {
1896
+ display: inline-grid;
1897
+ min-width: 0;
1898
+ grid-template-columns: minmax(0, 1fr);
1899
+ }
1900
+
1901
+ .ow-inline-edit__field::after {
1902
+ overflow: hidden;
1903
+ padding-inline-end: calc(var(--ow-inline-edit-x) + var(--ow-inline-edit-icon) + 0.3em);
1904
+ content: attr(data-value) " ";
1905
+ grid-area: 1 / 1;
1906
+ visibility: hidden;
1907
+ white-space: pre;
1908
+ }
1909
+
1910
+ .ow-inline-edit__input {
1911
+ display: block;
1912
+ width: 100%;
1913
+ min-width: 0;
1914
+ min-height: 0;
1915
+ flex: 1;
1916
+ grid-area: 1 / 1;
1917
+ border-color: var(--ow-border-strong);
1918
+ background: var(--ow-surface);
1919
+ outline: 0;
1920
+ }
1921
+
1922
+ .ow-inline-edit__input::placeholder {
1923
+ color: var(--ow-text-muted);
1924
+ opacity: 1;
1925
+ }
1926
+
1927
+ .ow-inline-edit__input:focus {
1928
+ border-color: var(--ow-focus-border);
1929
+ box-shadow: var(--ow-shadow-focus);
1930
+ }
1931
+
1932
+ .ow-inline-edit__input:focus-visible {
1933
+ outline: 2px solid var(--ow-focus-ring);
1934
+ outline-offset: 2px;
1935
+ }
1936
+
1937
+ .ow-inline-edit__input[aria-invalid="true"] {
1938
+ border-color: var(--ow-danger-solid);
1939
+ }
1940
+
1941
+ .ow-inline-edit__input[aria-invalid="true"]:focus {
1942
+ box-shadow: var(--ow-shadow-focus-danger);
1943
+ }
1944
+
1945
+ /* An auto-growing textarea is as tall as its scrollHeight, which leaves out the border, so it draws its border inside. */
1946
+ textarea.ow-inline-edit__input {
1947
+ border: 0;
1948
+ padding: calc(var(--ow-inline-edit-y) + 1px) calc(var(--ow-inline-edit-x) + 1px);
1949
+ box-shadow: inset 0 0 0 1px var(--ow-border-strong);
1950
+ }
1951
+
1952
+ textarea.ow-inline-edit__input:focus {
1953
+ box-shadow:
1954
+ inset 0 0 0 1px var(--ow-focus-border),
1955
+ var(--ow-shadow-focus);
1956
+ }
1957
+
1958
+ textarea.ow-inline-edit__input[aria-invalid="true"] {
1959
+ box-shadow: inset 0 0 0 1px var(--ow-danger-solid);
1960
+ }
1961
+
1962
+ textarea.ow-inline-edit__input[aria-invalid="true"]:focus {
1963
+ box-shadow:
1964
+ inset 0 0 0 1px var(--ow-danger-solid),
1965
+ var(--ow-shadow-focus-danger);
1966
+ }
1967
+
1968
+ .ow-inline-edit__actions {
1969
+ display: inline-flex;
1970
+ flex: none;
1971
+ gap: var(--ow-space-2xs);
1972
+ }
1973
+
1974
+ .ow-inline-edit__spinner {
1975
+ flex: none;
1976
+ }
1977
+
1978
+ .ow-inline-edit__error {
1979
+ color: var(--ow-danger-text);
1980
+ font: var(--ow-weight-regular) 14px / 1.4 var(--ow-font-sans);
1981
+ letter-spacing: normal;
1982
+ }
1983
+
1984
+ @media (prefers-reduced-motion: no-preference) {
1985
+ .ow-inline-edit__display,
1986
+ .ow-inline-edit__icon,
1987
+ .ow-inline-edit__input {
1988
+ transition-property: background-color, border-color, box-shadow, opacity;
1989
+ transition-duration: var(--ow-duration-fast);
1990
+ transition-timing-function: var(--ow-ease-standard);
1991
+ }
1992
+ }
1993
+
1792
1994
  /* components/Select/Select.css */
1793
1995
  /* Select: the trigger looks like a field; the listbox floats in the top layer. */
1794
1996
  .ow-select {
@@ -2052,6 +2254,99 @@
2052
2254
  }
2053
2255
  }
2054
2256
 
2257
+ /* components/TransferList/TransferList.css */
2258
+ /* TransferList: two standalone ListBoxes (ListBox.css) with a column of Buttons between them. Its own width decides
2259
+ the layout (a container query): side by side, or stacked with the buttons turned to point down and up. */
2260
+ .ow-transfer-list {
2261
+ container: ow-transfer-list / inline-size;
2262
+ color: var(--ow-text);
2263
+ font-family: var(--ow-font-sans);
2264
+ }
2265
+
2266
+ .ow-transfer-list__body {
2267
+ display: grid;
2268
+ grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
2269
+ gap: var(--ow-space-lg);
2270
+ }
2271
+
2272
+ .ow-transfer-list__pane {
2273
+ display: grid;
2274
+ min-width: 0;
2275
+ align-content: start;
2276
+ gap: var(--ow-space-sm);
2277
+ }
2278
+
2279
+ .ow-transfer-list__header {
2280
+ display: flex;
2281
+ align-items: baseline;
2282
+ justify-content: space-between;
2283
+ gap: var(--ow-space-sm);
2284
+ }
2285
+
2286
+ .ow-transfer-list__label {
2287
+ font-size: 14px;
2288
+ font-weight: var(--ow-weight-emphasis);
2289
+ line-height: 1.4;
2290
+ }
2291
+
2292
+ .ow-transfer-list__count {
2293
+ color: var(--ow-text-muted);
2294
+ font-size: 12px;
2295
+ font-variant-numeric: tabular-nums;
2296
+ white-space: nowrap;
2297
+ }
2298
+
2299
+ .ow-transfer-list .ow-transfer-list__list {
2300
+ height: var(--ow-transfer-list-height);
2301
+ }
2302
+
2303
+ .ow-transfer-list__actions {
2304
+ display: flex;
2305
+ flex-direction: column;
2306
+ align-self: center;
2307
+ gap: var(--ow-space-xs);
2308
+ }
2309
+
2310
+ .ow-transfer-list__icon {
2311
+ display: flex;
2312
+ }
2313
+
2314
+ /* The arrows point the way the items go, so they turn round right to left. */
2315
+ .ow-transfer-list__icon--back,
2316
+ .ow-transfer-list:dir(rtl) .ow-transfer-list__icon {
2317
+ transform: scaleX(-1);
2318
+ }
2319
+
2320
+ .ow-transfer-list:dir(rtl) .ow-transfer-list__icon--back {
2321
+ transform: none;
2322
+ }
2323
+
2324
+ .ow-transfer-list__order {
2325
+ display: flex;
2326
+ justify-content: flex-end;
2327
+ gap: var(--ow-space-2xs);
2328
+ }
2329
+
2330
+ @container ow-transfer-list (max-width: 519px) {
2331
+ .ow-transfer-list__body {
2332
+ grid-template-columns: minmax(0, 1fr);
2333
+ }
2334
+
2335
+ .ow-transfer-list__actions {
2336
+ flex-direction: row;
2337
+ justify-content: center;
2338
+ }
2339
+
2340
+ /* Across becomes down: → turns to ↓ and ← to ↑, whichever way the text runs. */
2341
+ .ow-transfer-list .ow-transfer-list__actions .ow-transfer-list__icon {
2342
+ transform: rotate(90deg);
2343
+ }
2344
+
2345
+ .ow-transfer-list .ow-transfer-list__actions .ow-transfer-list__icon--back {
2346
+ transform: rotate(-90deg);
2347
+ }
2348
+ }
2349
+
2055
2350
  /* components/Combobox/Combobox.css */
2056
2351
  /* Combobox: a grouped field (Input.css) with a chevron, over Select's listbox. */
2057
2352
  .ow-combobox {
@@ -2140,6 +2435,20 @@
2140
2435
  padding-left: var(--ow-space-2xs);
2141
2436
  }
2142
2437
 
2438
+ /* components/MentionInput/MentionInput.css */
2439
+ /* MentionInput: an Input or a Textarea, with Select's listbox (Select.css) under the trigger character. */
2440
+ .ow-mention-list {
2441
+ width: max-content;
2442
+ min-width: 224px;
2443
+ max-width: min(360px, calc(100vw - 16px));
2444
+ }
2445
+
2446
+ .ow-mention-list__empty {
2447
+ display: flex;
2448
+ align-items: center;
2449
+ gap: var(--ow-space-xs);
2450
+ }
2451
+
2143
2452
  /* components/Checkbox/Checkbox.css */
2144
2453
  /* Checkbox: a native input with its look replaced. */
2145
2454
  .ow-checkbox {
@@ -2765,6 +3074,99 @@
2765
3074
  }
2766
3075
  }
2767
3076
 
3077
+ /* components/SignaturePad/SignaturePad.css */
3078
+ /* SignaturePad: a field-like box to sign in, on a signing line, with its buttons underneath. */
3079
+ .ow-signature-pad {
3080
+ position: relative;
3081
+ display: grid;
3082
+ width: 100%;
3083
+ min-width: 0;
3084
+ gap: var(--ow-space-sm);
3085
+ }
3086
+
3087
+ .ow-signature-pad__surface {
3088
+ position: relative;
3089
+ height: var(--ow-signature-pad-height, 160px);
3090
+ overflow: hidden;
3091
+ border: 1px solid var(--ow-border-strong);
3092
+ border-radius: var(--ow-radius-form);
3093
+ background: var(--ow-surface);
3094
+ transition-property: border-color, box-shadow;
3095
+ transition-duration: var(--ow-duration-base);
3096
+ transition-timing-function: var(--ow-ease-standard);
3097
+ }
3098
+
3099
+ /* The ink is this colour (a penColor replaces it); the script reads it from CSS, so it follows the theme. */
3100
+ .ow-signature-pad__canvas {
3101
+ display: block;
3102
+ width: 100%;
3103
+ height: 100%;
3104
+ color: var(--ow-text);
3105
+ cursor: crosshair;
3106
+ touch-action: none;
3107
+ }
3108
+
3109
+ .ow-signature-pad--typing .ow-signature-pad__canvas,
3110
+ .ow-signature-pad--readonly .ow-signature-pad__canvas,
3111
+ .ow-signature-pad--disabled .ow-signature-pad__canvas {
3112
+ cursor: default;
3113
+ }
3114
+
3115
+ .ow-signature-pad:not(.ow-signature-pad--typing, .ow-signature-pad--readonly, .ow-signature-pad--disabled) .ow-signature-pad__surface:hover {
3116
+ border-color: var(--ow-border-hover);
3117
+ }
3118
+
3119
+ .ow-signature-pad--drawing .ow-signature-pad__surface {
3120
+ border-color: var(--ow-focus-border);
3121
+ box-shadow: var(--ow-shadow-focus);
3122
+ }
3123
+
3124
+ .ow-signature-pad--invalid .ow-signature-pad__surface {
3125
+ border-color: var(--ow-danger-line);
3126
+ }
3127
+
3128
+ /* At 72% of the height, where the script sets a typed name. */
3129
+ .ow-signature-pad__line {
3130
+ position: absolute;
3131
+ top: 72%;
3132
+ inset-inline: var(--ow-space-2xl);
3133
+ border-top: 1px dashed var(--ow-border-strong);
3134
+ pointer-events: none;
3135
+ }
3136
+
3137
+ .ow-signature-pad__prompt {
3138
+ position: absolute;
3139
+ bottom: calc(28% + var(--ow-space-xs));
3140
+ inset-inline-start: var(--ow-space-2xl);
3141
+ color: var(--ow-text-muted);
3142
+ font-size: 14px;
3143
+ line-height: 1.4;
3144
+ pointer-events: none;
3145
+ }
3146
+
3147
+ .ow-signature-pad__actions {
3148
+ display: flex;
3149
+ flex-wrap: wrap;
3150
+ align-items: center;
3151
+ gap: var(--ow-space-xs);
3152
+ }
3153
+
3154
+ .ow-signature-pad__edit {
3155
+ display: inline-flex;
3156
+ gap: var(--ow-space-xs);
3157
+ margin-inline-start: auto;
3158
+ }
3159
+
3160
+ .ow-signature-pad--disabled .ow-signature-pad__surface {
3161
+ opacity: 0.62;
3162
+ }
3163
+
3164
+ @media (prefers-reduced-motion: reduce) {
3165
+ .ow-signature-pad__surface {
3166
+ transition: none;
3167
+ }
3168
+ }
3169
+
2768
3170
  /* components/NumberField/NumberField.css */
2769
3171
  /* NumberField: − value + in one field. */
2770
3172
  .ow-number-field {
@@ -2962,68 +3364,260 @@
2962
3364
  transition-timing-function: var(--ow-ease-standard);
2963
3365
  }
2964
3366
 
2965
- .ow-dropzone:hover {
2966
- border-color: var(--ow-border-hover);
3367
+ .ow-dropzone:hover {
3368
+ border-color: var(--ow-border-hover);
3369
+ }
3370
+
3371
+ .ow-dropzone:focus-within:has(:focus-visible) {
3372
+ outline: 2px solid var(--ow-focus-ring);
3373
+ outline-offset: 2px;
3374
+ }
3375
+
3376
+ .ow-dropzone--dragging,
3377
+ .ow-dropzone--dragging:hover {
3378
+ border-color: var(--ow-primary-text);
3379
+ background: var(--ow-primary-subtle);
3380
+ }
3381
+
3382
+ .ow-dropzone--invalid {
3383
+ border-color: var(--ow-danger-line);
3384
+ }
3385
+
3386
+ .ow-dropzone--disabled {
3387
+ cursor: not-allowed;
3388
+ opacity: 0.62;
3389
+ }
3390
+
3391
+ .ow-dropzone__icon {
3392
+ display: inline-flex;
3393
+ width: 40px;
3394
+ height: 40px;
3395
+ align-items: center;
3396
+ justify-content: center;
3397
+ border: 1px solid var(--ow-border);
3398
+ border-radius: var(--ow-radius-md);
3399
+ background: var(--ow-surface);
3400
+ color: var(--ow-text-muted);
3401
+ transition-property: color, border-color;
3402
+ transition-duration: var(--ow-duration-base);
3403
+ transition-timing-function: var(--ow-ease-standard);
3404
+ }
3405
+
3406
+ .ow-dropzone--dragging .ow-dropzone__icon {
3407
+ border-color: var(--ow-primary-border);
3408
+ color: var(--ow-primary-text);
3409
+ }
3410
+
3411
+ .ow-dropzone__label {
3412
+ font-size: 14px;
3413
+ font-weight: var(--ow-weight-emphasis);
3414
+ line-height: 1.3;
3415
+ }
3416
+
3417
+ .ow-dropzone--dragging .ow-dropzone__label {
3418
+ color: var(--ow-primary-text);
3419
+ }
3420
+
3421
+ .ow-dropzone__hint {
3422
+ color: var(--ow-text-muted);
3423
+ font-size: 12px;
3424
+ line-height: 1.35;
3425
+ }
3426
+
3427
+ .ow-dropzone--invalid .ow-dropzone__hint {
3428
+ color: var(--ow-danger-text);
3429
+ }
3430
+
3431
+ /* components/UploadList/UploadList.css */
3432
+ /* UploadList: a row (or a tile) per file being uploaded, with its progress, status and buttons. */
3433
+ .ow-upload-list {
3434
+ width: 100%;
3435
+ min-width: 0;
3436
+ }
3437
+
3438
+ .ow-upload-list__items {
3439
+ display: grid;
3440
+ gap: var(--ow-space-sm);
3441
+ margin: 0;
3442
+ padding: 0;
3443
+ list-style: none;
3444
+ border-radius: var(--ow-radius-container);
3445
+ }
3446
+
3447
+ .ow-upload-list__items:focus-visible {
3448
+ outline: 2px solid var(--ow-focus-ring);
3449
+ outline-offset: 2px;
3450
+ }
3451
+
3452
+ .ow-upload-list__item {
3453
+ position: relative;
3454
+ display: flex;
3455
+ min-width: 0;
3456
+ align-items: center;
3457
+ gap: var(--ow-space-md);
3458
+ border: 1px solid var(--ow-border);
3459
+ border-radius: var(--ow-radius-container);
3460
+ background: var(--ow-surface);
3461
+ padding: var(--ow-space-sm);
3462
+ padding-inline-start: var(--ow-space-md);
3463
+ }
3464
+
3465
+ .ow-upload-list__item--error {
3466
+ border-color: var(--ow-danger-line);
3467
+ }
3468
+
3469
+ .ow-upload-list__thumb {
3470
+ position: relative;
3471
+ display: inline-flex;
3472
+ width: 40px;
3473
+ height: 40px;
3474
+ flex-shrink: 0;
3475
+ align-items: center;
3476
+ justify-content: center;
3477
+ overflow: hidden;
3478
+ border-radius: var(--ow-radius-md);
3479
+ background: var(--ow-surface-muted);
3480
+ color: var(--ow-text-muted);
3481
+ }
3482
+
3483
+ .ow-upload-list__thumb img {
3484
+ position: absolute;
3485
+ inset: 0;
3486
+ width: 100%;
3487
+ height: 100%;
3488
+ object-fit: cover;
3489
+ }
3490
+
3491
+ .ow-upload-list__body {
3492
+ display: grid;
3493
+ min-width: 0;
3494
+ flex: 1;
3495
+ gap: 2px;
3496
+ }
3497
+
3498
+ .ow-upload-list__name {
3499
+ overflow: hidden;
3500
+ color: var(--ow-text);
3501
+ font-size: 14px;
3502
+ font-weight: var(--ow-weight-emphasis);
3503
+ line-height: 1.35;
3504
+ text-overflow: ellipsis;
3505
+ white-space: nowrap;
3506
+ }
3507
+
3508
+ .ow-upload-list__detail {
3509
+ display: flex;
3510
+ min-width: 0;
3511
+ align-items: center;
3512
+ gap: var(--ow-space-xs);
3513
+ color: var(--ow-text-muted);
3514
+ font-size: 12px;
3515
+ line-height: 1.35;
3516
+ font-variant-numeric: tabular-nums;
3517
+ }
3518
+
3519
+ .ow-upload-list__detail > span {
3520
+ overflow: hidden;
3521
+ text-overflow: ellipsis;
3522
+ white-space: nowrap;
3523
+ }
3524
+
3525
+ .ow-upload-list__icon {
3526
+ flex-shrink: 0;
3527
+ }
3528
+
3529
+ .ow-upload-list__item--done .ow-upload-list__icon {
3530
+ color: var(--ow-success-text);
3531
+ }
3532
+
3533
+ .ow-upload-list__item--error .ow-upload-list__detail {
3534
+ color: var(--ow-danger-text);
3535
+ }
3536
+
3537
+ .ow-upload-list__progress {
3538
+ margin-top: var(--ow-space-xs);
2967
3539
  }
2968
3540
 
2969
- .ow-dropzone:focus-within:has(:focus-visible) {
2970
- outline: 2px solid var(--ow-focus-ring);
2971
- outline-offset: 2px;
3541
+ .ow-upload-list__actions {
3542
+ display: flex;
3543
+ flex-shrink: 0;
3544
+ gap: var(--ow-space-2xs);
2972
3545
  }
2973
3546
 
2974
- .ow-dropzone--dragging,
2975
- .ow-dropzone--dragging:hover {
2976
- border-color: var(--ow-primary-text);
2977
- background: var(--ow-primary-subtle);
3547
+ .ow-upload-list__actions:empty {
3548
+ display: none;
2978
3549
  }
2979
3550
 
2980
- .ow-dropzone--invalid {
2981
- border-color: var(--ow-danger-line);
3551
+ /* Compact: one short line per file, its progress a hairline along the bottom. */
3552
+ .ow-upload-list--compact .ow-upload-list__items {
3553
+ gap: var(--ow-space-xs);
2982
3554
  }
2983
3555
 
2984
- .ow-dropzone--disabled {
2985
- cursor: not-allowed;
2986
- opacity: 0.62;
3556
+ .ow-upload-list--compact .ow-upload-list__item {
3557
+ gap: var(--ow-space-sm);
3558
+ padding-block: var(--ow-space-2xs);
2987
3559
  }
2988
3560
 
2989
- .ow-dropzone__icon {
2990
- display: inline-flex;
2991
- width: 40px;
2992
- height: 40px;
2993
- align-items: center;
2994
- justify-content: center;
2995
- border: 1px solid var(--ow-border);
2996
- border-radius: var(--ow-radius-md);
2997
- background: var(--ow-surface);
2998
- color: var(--ow-text-muted);
2999
- transition-property: color, border-color;
3000
- transition-duration: var(--ow-duration-base);
3001
- transition-timing-function: var(--ow-ease-standard);
3561
+ .ow-upload-list--compact .ow-upload-list__thumb {
3562
+ width: auto;
3563
+ height: auto;
3564
+ background: none;
3002
3565
  }
3003
3566
 
3004
- .ow-dropzone--dragging .ow-dropzone__icon {
3005
- border-color: var(--ow-primary-border);
3006
- color: var(--ow-primary-text);
3567
+ .ow-upload-list--compact .ow-upload-list__body {
3568
+ display: flex;
3569
+ align-items: baseline;
3570
+ gap: var(--ow-space-sm);
3007
3571
  }
3008
3572
 
3009
- .ow-dropzone__label {
3010
- font-size: 14px;
3011
- font-weight: var(--ow-weight-emphasis);
3012
- line-height: 1.3;
3573
+ .ow-upload-list--compact .ow-upload-list__name {
3574
+ min-width: 4em;
3575
+ flex: 1 1 auto;
3576
+ font-size: 13px;
3013
3577
  }
3014
3578
 
3015
- .ow-dropzone--dragging .ow-dropzone__label {
3016
- color: var(--ow-primary-text);
3579
+ .ow-upload-list--compact .ow-upload-list__progress {
3580
+ position: absolute;
3581
+ inset: auto var(--ow-space-md) 2px;
3582
+ margin: 0;
3017
3583
  }
3018
3584
 
3019
- .ow-dropzone__hint {
3020
- color: var(--ow-text-muted);
3021
- font-size: 12px;
3022
- line-height: 1.35;
3585
+ /* Grid: a tile per file, the thumbnail on top and the buttons over its corner. */
3586
+ .ow-upload-list--grid .ow-upload-list__items {
3587
+ grid-template-columns: repeat(auto-fill, minmax(144px, 1fr));
3588
+ gap: var(--ow-space-md);
3023
3589
  }
3024
3590
 
3025
- .ow-dropzone--invalid .ow-dropzone__hint {
3026
- color: var(--ow-danger-text);
3591
+ .ow-upload-list--grid .ow-upload-list__item {
3592
+ flex-direction: column;
3593
+ align-items: stretch;
3594
+ gap: var(--ow-space-sm);
3595
+ padding: var(--ow-space-xs) var(--ow-space-xs) var(--ow-space-sm);
3596
+ }
3597
+
3598
+ .ow-upload-list--grid .ow-upload-list__thumb {
3599
+ width: auto;
3600
+ height: auto;
3601
+ aspect-ratio: 1;
3602
+ border-radius: calc(var(--ow-radius-container) - 4px);
3603
+ }
3604
+
3605
+ .ow-upload-list--grid .ow-upload-list__thumb svg {
3606
+ width: 28px;
3607
+ height: 28px;
3608
+ }
3609
+
3610
+ .ow-upload-list--grid .ow-upload-list__body {
3611
+ padding-inline: var(--ow-space-xs);
3612
+ }
3613
+
3614
+ .ow-upload-list--grid .ow-upload-list__actions {
3615
+ position: absolute;
3616
+ inset-block-start: var(--ow-space-sm);
3617
+ inset-inline-end: var(--ow-space-sm);
3618
+ border-radius: var(--ow-radius-md);
3619
+ background: var(--ow-surface);
3620
+ box-shadow: 0 0 0 1px var(--ow-border);
3027
3621
  }
3028
3622
 
3029
3623
  /* components/Field/Field.css */
@@ -4295,38 +4889,255 @@
4295
4889
  }
4296
4890
  }
4297
4891
 
4298
- /* components/Popover/Popover.css */
4299
- /* Popover: a surface card with the menu shadow, attached to its trigger. */
4300
- .ow-popover-anchor {
4301
- display: inline-flex;
4892
+ /* components/Popover/Popover.css */
4893
+ /* Popover: a surface card with the menu shadow, attached to its trigger. */
4894
+ .ow-popover-anchor {
4895
+ display: inline-flex;
4896
+ }
4897
+
4898
+ .ow-popover {
4899
+ z-index: 60;
4900
+ display: grid;
4901
+ gap: var(--ow-space-md);
4902
+ overflow: auto;
4903
+ border: 1px solid var(--ow-border);
4904
+ border-radius: var(--ow-radius-container);
4905
+ background: var(--ow-surface);
4906
+ padding: var(--ow-space-xl);
4907
+ color: var(--ow-text);
4908
+ font-family: var(--ow-font-sans);
4909
+ font-size: 14px;
4910
+ line-height: 1.45;
4911
+ box-shadow: var(--ow-shadow-menu);
4912
+ outline: none;
4913
+ }
4914
+
4915
+ /* Children may shrink to the popover's width instead of pushing past it. */
4916
+ .ow-popover > * {
4917
+ min-width: 0;
4918
+ }
4919
+
4920
+ .ow-popover__title {
4921
+ font-size: 14px;
4922
+ font-weight: var(--ow-weight-emphasis);
4923
+ line-height: 1.3;
4924
+ }
4925
+
4926
+ /* components/NotificationCenter/NotificationCenter.css */
4927
+ /* NotificationCenter: a bell with a count, opening a popover inbox. NotificationList: the rows inside it. */
4928
+ .ow-notification-center {
4929
+ display: inline-flex;
4930
+ }
4931
+
4932
+ .ow-notification-center__bell {
4933
+ position: relative;
4934
+ }
4935
+
4936
+ /* The count sits on the bell's corner, cut out of whatever is behind it. */
4937
+ .ow-notification-center__count.ow-badge {
4938
+ position: absolute;
4939
+ top: 0;
4940
+ inset-inline-end: -2px;
4941
+ min-width: 18px;
4942
+ min-height: 18px;
4943
+ border: 2px solid var(--ow-surface);
4944
+ background: var(--ow-primary);
4945
+ padding: 0 4px;
4946
+ color: var(--ow-on-primary);
4947
+ font-size: 10.5px;
4948
+ font-variant-numeric: tabular-nums;
4949
+ pointer-events: none;
4950
+ }
4951
+
4952
+ /* Edge-to-edge rows, so the popover's own padding goes; only the list scrolls when the window is short. */
4953
+ .ow-notification-center__popover.ow-popover {
4954
+ display: flex;
4955
+ flex-direction: column;
4956
+ padding: 0;
4957
+ overflow: hidden;
4958
+ }
4959
+
4960
+ .ow-notification-center__head,
4961
+ .ow-notification-center__foot {
4962
+ display: flex;
4963
+ align-items: center;
4964
+ justify-content: space-between;
4965
+ gap: var(--ow-space-md);
4966
+ padding: var(--ow-space-md) var(--ow-space-md) var(--ow-space-xs);
4967
+ padding-inline-start: var(--ow-space-2xl);
4968
+ }
4969
+
4970
+ .ow-notification-center__title {
4971
+ font-weight: var(--ow-weight-emphasis);
4972
+ }
4973
+
4974
+ .ow-notification-center__tabs.ow-tabs {
4975
+ display: flex;
4976
+ min-height: 0;
4977
+ flex-direction: column;
4978
+ gap: 0;
4979
+ }
4980
+
4981
+ .ow-notification-center__tabs .ow-tabs__list {
4982
+ padding: 0 var(--ow-space-2xl);
4983
+ }
4984
+
4985
+ .ow-notification-center__tab-count {
4986
+ border-radius: var(--ow-radius-pill);
4987
+ background: var(--ow-surface-muted);
4988
+ padding: 1px 6px;
4989
+ font-size: 11px;
4990
+ font-variant-numeric: tabular-nums;
4991
+ }
4992
+
4993
+ .ow-notification-center__body {
4994
+ min-height: 0;
4995
+ max-height: min(420px, 60dvh);
4996
+ overflow-y: auto;
4997
+ padding: var(--ow-space-xs);
4998
+ outline: none;
4999
+ }
5000
+
5001
+ .ow-notification-center__body:focus-visible {
5002
+ box-shadow: inset 0 0 0 2px var(--ow-focus-ring);
5003
+ }
5004
+
5005
+ .ow-notification-center__foot {
5006
+ border-top: 1px solid var(--ow-border);
5007
+ padding-block: var(--ow-space-md);
5008
+ }
5009
+
5010
+ /* The list. */
5011
+ .ow-notification-list__heading {
5012
+ margin: 0;
5013
+ padding: var(--ow-space-lg) var(--ow-space-lg) var(--ow-space-xs);
5014
+ color: var(--ow-text-muted);
5015
+ font-size: 12px;
5016
+ font-weight: var(--ow-weight-strong);
5017
+ }
5018
+
5019
+ .ow-notification-list__items {
5020
+ margin: 0;
5021
+ padding: 0;
5022
+ list-style: none;
5023
+ }
5024
+
5025
+ /* One row: the whole of it opens the item, through the link stretched over it. */
5026
+ .ow-notification {
5027
+ position: relative;
5028
+ display: flex;
5029
+ align-items: flex-start;
5030
+ gap: var(--ow-space-lg);
5031
+ border-radius: var(--ow-radius-form);
5032
+ padding-block: var(--ow-space-lg);
5033
+ padding-inline: 22px var(--ow-space-md);
5034
+ color: var(--ow-text-soft);
5035
+ transition: background-color var(--ow-duration-fast) var(--ow-ease-standard);
5036
+ }
5037
+
5038
+ .ow-notification:hover {
5039
+ background: var(--ow-hover);
5040
+ }
5041
+
5042
+ .ow-notification__dot {
5043
+ position: absolute;
5044
+ top: 20px;
5045
+ inset-inline-start: 8px;
5046
+ width: 8px;
5047
+ height: 8px;
5048
+ border-radius: 50%;
5049
+ background: var(--ow-primary);
5050
+ }
5051
+
5052
+ .ow-notification__media {
5053
+ display: inline-flex;
5054
+ flex-shrink: 0;
5055
+ }
5056
+
5057
+ .ow-notification__icon {
5058
+ display: inline-flex;
5059
+ width: 28px;
5060
+ height: 28px;
5061
+ align-items: center;
5062
+ justify-content: center;
5063
+ border: 1px solid var(--ow-border);
5064
+ border-radius: 50%;
5065
+ background: var(--ow-surface-muted);
5066
+ color: var(--ow-text-soft);
5067
+ }
5068
+
5069
+ .ow-notification__body {
5070
+ display: grid;
5071
+ min-width: 0;
5072
+ flex: 1;
5073
+ gap: var(--ow-space-md);
5074
+ }
5075
+
5076
+ .ow-notification__main {
5077
+ display: grid;
5078
+ gap: 2px;
5079
+ border: 0;
5080
+ background: none;
5081
+ padding: 0;
5082
+ color: inherit;
5083
+ font: inherit;
5084
+ text-align: start;
5085
+ text-decoration: none;
5086
+ cursor: pointer;
5087
+ outline: none;
5088
+ }
5089
+
5090
+ .ow-notification__main::after {
5091
+ content: "";
5092
+ position: absolute;
5093
+ inset: 0;
5094
+ border-radius: inherit;
5095
+ }
5096
+
5097
+ .ow-notification__main:focus-visible::after {
5098
+ outline: 2px solid var(--ow-focus-ring);
5099
+ outline-offset: -2px;
5100
+ }
5101
+
5102
+ .ow-notification--unread .ow-notification__title {
5103
+ color: var(--ow-text);
5104
+ font-weight: var(--ow-weight-strong);
5105
+ }
5106
+
5107
+ .ow-notification__description {
5108
+ display: -webkit-box;
5109
+ overflow: hidden;
5110
+ -webkit-box-orient: vertical;
5111
+ -webkit-line-clamp: 2;
5112
+ }
5113
+
5114
+ .ow-notification__time {
5115
+ color: var(--ow-text-muted);
5116
+ font-size: 12px;
4302
5117
  }
4303
5118
 
4304
- .ow-popover {
4305
- z-index: 60;
4306
- display: grid;
4307
- gap: var(--ow-space-md);
4308
- overflow: auto;
4309
- border: 1px solid var(--ow-border);
4310
- border-radius: var(--ow-radius-container);
4311
- background: var(--ow-surface);
4312
- padding: var(--ow-space-xl);
4313
- color: var(--ow-text);
4314
- font-family: var(--ow-font-sans);
4315
- font-size: 14px;
4316
- line-height: 1.45;
4317
- box-shadow: var(--ow-shadow-menu);
4318
- outline: none;
5119
+ /* Actions and the ✕ sit above the stretched link, so they take their own clicks. */
5120
+ .ow-notification__actions,
5121
+ .ow-notification__dismiss {
5122
+ position: relative;
5123
+ z-index: 1;
4319
5124
  }
4320
5125
 
4321
- /* Children may shrink to the popover's width instead of pushing past it. */
4322
- .ow-popover > * {
4323
- min-width: 0;
5126
+ .ow-notification__actions {
5127
+ display: flex;
5128
+ flex-wrap: wrap;
5129
+ gap: var(--ow-space-sm);
4324
5130
  }
4325
5131
 
4326
- .ow-popover__title {
4327
- font-size: 14px;
4328
- font-weight: var(--ow-weight-emphasis);
4329
- line-height: 1.3;
5132
+ .ow-notification__dismiss {
5133
+ flex-shrink: 0;
5134
+ margin: -4px 0;
5135
+ }
5136
+
5137
+ @media (prefers-reduced-motion: reduce) {
5138
+ .ow-notification {
5139
+ transition: none;
5140
+ }
4330
5141
  }
4331
5142
 
4332
5143
  /* components/Tour/Tour.css */
@@ -6581,6 +7392,25 @@
6581
7392
  white-space: nowrap;
6582
7393
  }
6583
7394
 
7395
+ /* components/QRCode/QRCode.css */
7396
+ /* QRCode: near black on near white in both themes, since scanners need a light ground and strong contrast. */
7397
+ .ow-qr-code {
7398
+ display: block;
7399
+ flex: none;
7400
+ max-width: 100%;
7401
+ height: auto;
7402
+ forced-color-adjust: none;
7403
+ print-color-adjust: exact;
7404
+ }
7405
+
7406
+ .ow-qr-code__ground {
7407
+ fill: var(--ow-gray-50);
7408
+ }
7409
+
7410
+ .ow-qr-code__modules {
7411
+ fill: var(--ow-gray-950);
7412
+ }
7413
+
6584
7414
  /* components/Image/Image.css */
6585
7415
  /* Image: an <img> in a box that pulses while it loads and shows a fallback if it fails. With a ratio, the box is an
6586
7416
  AspectRatio and the image fills it. */
@@ -6661,6 +7491,170 @@
6661
7491
  line-height: 1.4;
6662
7492
  }
6663
7493
 
7494
+ /* components/MediaPlayer/MediaPlayer.css */
7495
+ /* MediaPlayer: audio is a bar of controls; video is the picture, with the same bar floating over its foot. */
7496
+ .ow-media {
7497
+ position: relative;
7498
+ container-type: inline-size;
7499
+ border-radius: var(--ow-radius-container);
7500
+ color: var(--ow-text);
7501
+ font-family: var(--ow-font-sans);
7502
+ }
7503
+
7504
+ .ow-media:focus-visible {
7505
+ outline: 2px solid var(--ow-focus-ring);
7506
+ outline-offset: 2px;
7507
+ }
7508
+
7509
+ .ow-media--audio {
7510
+ display: grid;
7511
+ gap: var(--ow-space-2xs);
7512
+ border: 1px solid var(--ow-border);
7513
+ background: var(--ow-surface);
7514
+ padding: var(--ow-space-xs);
7515
+ }
7516
+
7517
+ .ow-media--audio .ow-media__element {
7518
+ display: none;
7519
+ }
7520
+
7521
+ .ow-media__title {
7522
+ overflow: hidden;
7523
+ padding: var(--ow-space-2xs) var(--ow-space-xs) 0;
7524
+ font-size: 14px;
7525
+ font-weight: var(--ow-weight-emphasis);
7526
+ text-overflow: ellipsis;
7527
+ white-space: nowrap;
7528
+ }
7529
+
7530
+ .ow-media--video {
7531
+ overflow: hidden;
7532
+ background: var(--ow-gray-950);
7533
+ }
7534
+
7535
+ /* Letterboxed, never cropped. */
7536
+ .ow-media__screen > .ow-media__element {
7537
+ object-fit: contain;
7538
+ cursor: pointer;
7539
+ }
7540
+
7541
+ .ow-media__controls {
7542
+ display: flex;
7543
+ align-items: center;
7544
+ gap: var(--ow-space-2xs);
7545
+ min-width: 0;
7546
+ }
7547
+
7548
+ .ow-media--video .ow-media__controls {
7549
+ position: absolute;
7550
+ inset-inline: var(--ow-space-sm);
7551
+ bottom: var(--ow-space-sm);
7552
+ border: 1px solid var(--ow-border);
7553
+ border-radius: var(--ow-radius-lg);
7554
+ background: var(--ow-surface);
7555
+ padding: var(--ow-space-2xs);
7556
+ box-shadow: var(--ow-shadow-menu);
7557
+ transition: opacity var(--ow-duration-base) var(--ow-ease-standard);
7558
+ }
7559
+
7560
+ /* Playing and left alone: the controls fade out (still reachable with Tab, which brings them back) and so does the pointer. */
7561
+ .ow-media--idle {
7562
+ cursor: none;
7563
+ }
7564
+
7565
+ .ow-media--idle .ow-media__controls {
7566
+ opacity: 0;
7567
+ pointer-events: none;
7568
+ }
7569
+
7570
+ /* Captions rise above the controls while they show (Chromium and Safari let the page move them). */
7571
+ .ow-media__element::-webkit-media-text-track-container {
7572
+ transition: transform var(--ow-duration-base) var(--ow-ease-standard);
7573
+ }
7574
+
7575
+ .ow-media--video:not(.ow-media--idle) .ow-media__element::-webkit-media-text-track-container {
7576
+ transform: translateY(-56px);
7577
+ }
7578
+
7579
+ /* The timeline reads left to right in every language, as players do; the loaded part is a shade darker than the rest. */
7580
+ .ow-media__seek {
7581
+ flex: 1;
7582
+ min-width: 48px;
7583
+ direction: ltr;
7584
+ }
7585
+
7586
+ .ow-media__seek .ow-slider__track {
7587
+ background: linear-gradient(to right, var(--ow-border-strong) var(--ow-media-buffered), var(--ow-meter-track) 0);
7588
+ }
7589
+
7590
+ .ow-media__volume {
7591
+ width: 72px;
7592
+ }
7593
+
7594
+ .ow-media__time {
7595
+ padding-inline: var(--ow-space-2xs);
7596
+ color: var(--ow-text-muted);
7597
+ font-size: 12px;
7598
+ font-variant-numeric: tabular-nums;
7599
+ white-space: nowrap;
7600
+ }
7601
+
7602
+ .ow-media__rate {
7603
+ min-width: 44px;
7604
+ font-variant-numeric: tabular-nums;
7605
+ }
7606
+
7607
+ .ow-media__controls [aria-pressed="true"],
7608
+ .ow-media__on {
7609
+ background: var(--ow-surface-muted);
7610
+ color: var(--ow-primary-text);
7611
+ }
7612
+
7613
+ .ow-media__blank {
7614
+ display: block;
7615
+ width: 15px;
7616
+ height: 15px;
7617
+ }
7618
+
7619
+ .ow-media--fullscreen {
7620
+ display: flex;
7621
+ align-items: center;
7622
+ border-radius: 0;
7623
+ }
7624
+
7625
+ /* AspectRatio sets its ratio inline; full screen, the picture takes the whole screen instead. */
7626
+ .ow-media--fullscreen .ow-media__screen {
7627
+ height: 100%;
7628
+ aspect-ratio: auto !important;
7629
+ }
7630
+
7631
+ @container (max-width: 440px) {
7632
+ .ow-media__volume,
7633
+ .ow-media__pip {
7634
+ display: none;
7635
+ }
7636
+ }
7637
+
7638
+ /* On a phone the device's buttons set the volume; M still mutes. */
7639
+ @container (max-width: 360px) {
7640
+ .ow-media--video .ow-media__mute {
7641
+ display: none;
7642
+ }
7643
+ }
7644
+
7645
+ @container (max-width: 240px) {
7646
+ .ow-media__time {
7647
+ display: none;
7648
+ }
7649
+ }
7650
+
7651
+ @media (prefers-reduced-motion: reduce) {
7652
+ .ow-media__controls,
7653
+ .ow-media__element::-webkit-media-text-track-container {
7654
+ transition: none !important;
7655
+ }
7656
+ }
7657
+
6664
7658
  /* components/Kbd/Kbd.css */
6665
7659
  /* Kbd and inline Code, both in the mono face. */
6666
7660
  .ow-kbd {
@@ -6890,6 +7884,159 @@
6890
7884
  transform: none;
6891
7885
  }
6892
7886
 
7887
+ /* components/DiffViewer/DiffViewer.css */
7888
+ /* DiffViewer: a code block's ground and header (it uses CodeBlock's classes), with a table of lines tinted from the
7889
+ success and danger colours. The code block is dark in both themes, so the tints are too. */
7890
+ .ow-diff {
7891
+ --ow-diff-add: var(--ow-success-solid);
7892
+ --ow-diff-del: var(--ow-danger-solid);
7893
+ display: grid;
7894
+ min-width: 0;
7895
+ gap: var(--ow-space-md);
7896
+ }
7897
+
7898
+ .ow-diff__counts {
7899
+ font-family: var(--ow-font-mono);
7900
+ font-size: 12px;
7901
+ white-space: nowrap;
7902
+ }
7903
+
7904
+ /* Signs and counts are lifted toward the text colour so they read on the tints. */
7905
+ .ow-diff__added,
7906
+ .ow-diff__add > .ow-diff__sign {
7907
+ color: color-mix(in srgb, var(--ow-diff-add) 60%, var(--ow-on-code-block));
7908
+ }
7909
+
7910
+ .ow-diff__removed,
7911
+ .ow-diff__del > .ow-diff__sign {
7912
+ color: color-mix(in srgb, var(--ow-diff-del) 60%, var(--ow-on-code-block));
7913
+ }
7914
+
7915
+ .ow-diff__scroll {
7916
+ overflow: auto;
7917
+ }
7918
+
7919
+ .ow-diff__scroll:focus-visible {
7920
+ outline: 2px solid var(--ow-brand-300);
7921
+ outline-offset: -2px;
7922
+ }
7923
+
7924
+ .ow-diff__table {
7925
+ min-width: 100%;
7926
+ border-collapse: collapse;
7927
+ font-family: var(--ow-font-mono);
7928
+ font-size: 13px;
7929
+ line-height: 1.6;
7930
+ tab-size: 4;
7931
+ }
7932
+
7933
+ .ow-diff__table--wrap {
7934
+ width: 100%;
7935
+ table-layout: fixed;
7936
+ }
7937
+
7938
+ /* Cells have no padding of their own; the classes below add it. */
7939
+ :where(.ow-diff__table td) {
7940
+ padding: 0;
7941
+ vertical-align: top;
7942
+ }
7943
+
7944
+ .ow-diff__num-col {
7945
+ width: calc(var(--ow-diff-digits) * 1ch + 20px);
7946
+ }
7947
+
7948
+ .ow-diff__num {
7949
+ padding-inline: 10px;
7950
+ color: var(--ow-on-code-block-muted);
7951
+ text-align: right;
7952
+ user-select: none;
7953
+ }
7954
+
7955
+ /* The sign hangs in the margin, so wrapped lines line up under the code. */
7956
+ .ow-diff__code {
7957
+ padding: 0 var(--ow-space-lg) 0 calc(var(--ow-space-sm) + 2ch);
7958
+ text-indent: -2ch;
7959
+ white-space: pre;
7960
+ }
7961
+
7962
+ .ow-diff__table--wrap .ow-diff__code {
7963
+ overflow-wrap: anywhere;
7964
+ white-space: pre-wrap;
7965
+ }
7966
+
7967
+ .ow-diff__code:focus {
7968
+ outline: none;
7969
+ }
7970
+
7971
+ .ow-diff__sign {
7972
+ display: inline-block;
7973
+ width: 2ch;
7974
+ text-indent: 0;
7975
+ user-select: none;
7976
+ }
7977
+
7978
+ .ow-diff__add {
7979
+ background: color-mix(in srgb, var(--ow-diff-add) 14%, transparent);
7980
+ }
7981
+
7982
+ .ow-diff__del {
7983
+ background: color-mix(in srgb, var(--ow-diff-del) 14%, transparent);
7984
+ }
7985
+
7986
+ .ow-diff__word {
7987
+ border-radius: 2px;
7988
+ background: color-mix(in srgb, var(--ow-diff-add) 34%, transparent);
7989
+ }
7990
+
7991
+ .ow-diff__del .ow-diff__word {
7992
+ background: color-mix(in srgb, var(--ow-diff-del) 34%, transparent);
7993
+ }
7994
+
7995
+ .ow-diff__empty {
7996
+ background: color-mix(in srgb, var(--ow-on-code-block) 3%, transparent);
7997
+ }
7998
+
7999
+ .ow-diff__table--split .ow-diff__num:nth-child(3) {
8000
+ border-left: 1px solid color-mix(in srgb, var(--ow-on-code-block) 8%, transparent);
8001
+ }
8002
+
8003
+ .ow-diff__hunk > td,
8004
+ .ow-diff__gap > td {
8005
+ background: color-mix(in srgb, var(--ow-on-code-block) 5%, transparent);
8006
+ color: var(--ow-on-code-block-muted);
8007
+ }
8008
+
8009
+ .ow-diff__hunk > td {
8010
+ padding: 2px var(--ow-space-lg);
8011
+ white-space: pre;
8012
+ }
8013
+
8014
+ .ow-diff__expand {
8015
+ display: flex;
8016
+ width: 100%;
8017
+ min-height: 28px;
8018
+ align-items: center;
8019
+ gap: var(--ow-space-sm);
8020
+ border: 0;
8021
+ background: transparent;
8022
+ padding: 0 var(--ow-space-lg);
8023
+ color: inherit;
8024
+ font: inherit;
8025
+ font-family: var(--ow-font-sans);
8026
+ font-size: 12px;
8027
+ cursor: pointer;
8028
+ }
8029
+
8030
+ .ow-diff__expand:hover {
8031
+ background: color-mix(in srgb, var(--ow-on-code-block) 6%, transparent);
8032
+ color: var(--ow-on-code-block);
8033
+ }
8034
+
8035
+ .ow-diff__expand:focus-visible {
8036
+ outline: 2px solid var(--ow-brand-300);
8037
+ outline-offset: -2px;
8038
+ }
8039
+
6893
8040
  /* components/Tag/Tag.css */
6894
8041
  /* Tag, TagGroup and ColorSwatch. */
6895
8042
  .ow-tag-group {
@@ -7036,6 +8183,125 @@
7036
8183
  font-size: 12px;
7037
8184
  }
7038
8185
 
8186
+ /* components/SortableList/SortableList.css */
8187
+ /* SortableList: rows (or chips, in a row) people put in order. The picked-up one lifts; the others slide aside. */
8188
+ .ow-sortable {
8189
+ display: flex;
8190
+ flex-direction: column;
8191
+ gap: var(--ow-space-xs);
8192
+ margin: 0;
8193
+ padding: 0;
8194
+ list-style: none;
8195
+ }
8196
+
8197
+ .ow-sortable--horizontal {
8198
+ flex-direction: row;
8199
+ overflow-x: auto;
8200
+ padding-block: var(--ow-space-2xs);
8201
+ }
8202
+
8203
+ .ow-sortable__item {
8204
+ position: relative;
8205
+ display: flex;
8206
+ flex: none;
8207
+ min-height: 40px;
8208
+ align-items: center;
8209
+ gap: var(--ow-space-xs);
8210
+ padding: var(--ow-space-xs) var(--ow-space-lg);
8211
+ border: 1px solid var(--ow-border);
8212
+ border-radius: var(--ow-radius-md);
8213
+ background: var(--ow-surface);
8214
+ color: var(--ow-text);
8215
+ font-size: 14px;
8216
+ outline: none;
8217
+ }
8218
+
8219
+ .ow-sortable--horizontal .ow-sortable__item {
8220
+ min-height: 32px;
8221
+ padding-block: var(--ow-space-2xs);
8222
+ }
8223
+
8224
+ .ow-sortable__content {
8225
+ flex: 1;
8226
+ min-width: 0;
8227
+ }
8228
+
8229
+ /* Whatever picks it up: the row, or its grip. Touch drags it rather than scrolling the page. */
8230
+ .ow-sortable__item--row,
8231
+ .ow-sortable__handle {
8232
+ cursor: grab;
8233
+ touch-action: none;
8234
+ user-select: none;
8235
+ -webkit-user-select: none;
8236
+ }
8237
+
8238
+ .ow-sortable__handle {
8239
+ display: inline-flex;
8240
+ width: 24px;
8241
+ height: 28px;
8242
+ flex: none;
8243
+ align-items: center;
8244
+ justify-content: center;
8245
+ margin-inline-start: calc(var(--ow-space-xs) * -1);
8246
+ padding: 0;
8247
+ border: 0;
8248
+ border-radius: var(--ow-radius-md);
8249
+ background: none;
8250
+ color: var(--ow-icon);
8251
+ }
8252
+
8253
+ .ow-sortable__handle:hover {
8254
+ background: var(--ow-hover);
8255
+ color: var(--ow-text-muted);
8256
+ }
8257
+
8258
+ .ow-sortable--horizontal .ow-sortable__grip {
8259
+ rotate: 90deg;
8260
+ }
8261
+
8262
+ .ow-sortable__item--row:focus-visible,
8263
+ .ow-sortable__handle:focus-visible {
8264
+ outline: 2px solid var(--ow-focus-ring);
8265
+ outline-offset: 1px;
8266
+ }
8267
+
8268
+ /* While one is picked up, the others slide to make room. */
8269
+ .ow-sortable--dragging .ow-sortable__item {
8270
+ transition: transform var(--ow-duration-base) var(--ow-ease-standard);
8271
+ }
8272
+
8273
+ .ow-sortable .ow-sortable__item--dragging {
8274
+ z-index: 1;
8275
+ border-color: var(--ow-border-strong);
8276
+ box-shadow: var(--ow-shadow-menu);
8277
+ transition: none;
8278
+ }
8279
+
8280
+ :root[data-ow-sortable-drag],
8281
+ :root[data-ow-sortable-drag] * {
8282
+ cursor: grabbing !important;
8283
+ user-select: none;
8284
+ -webkit-user-select: none;
8285
+ }
8286
+
8287
+ .ow-sortable--disabled .ow-sortable__item {
8288
+ background: var(--ow-surface-muted);
8289
+ color: var(--ow-text-muted);
8290
+ cursor: default;
8291
+ }
8292
+
8293
+ .ow-sortable--disabled .ow-sortable__handle {
8294
+ background: none;
8295
+ color: var(--ow-text-disabled);
8296
+ cursor: not-allowed;
8297
+ }
8298
+
8299
+ @media (prefers-reduced-motion: reduce) {
8300
+ .ow-sortable--dragging .ow-sortable__item {
8301
+ transition: none;
8302
+ }
8303
+ }
8304
+
7039
8305
  /* components/Table/Table.css */
7040
8306
  /* Table: a bordered card with a quiet header row and hairlines between rows. */
7041
8307
  .ow-table-wrap {
@@ -7897,111 +9163,346 @@
7897
9163
  }
7898
9164
  }
7899
9165
 
7900
- @media (forced-colors: active) {
7901
- .ow-chart__line,
7902
- .ow-sparkline__line {
7903
- stroke: CanvasText;
7904
- }
9166
+ @media (forced-colors: active) {
9167
+ .ow-chart__line,
9168
+ .ow-sparkline__line {
9169
+ stroke: CanvasText;
9170
+ }
9171
+ }
9172
+
9173
+ /* components/ActivityHeatmap/ActivityHeatmap.css */
9174
+ /* ActivityHeatmap: a square per day, shaded from the empty track to one chart colour, so the shades follow the theme. */
9175
+ .ow-heatmap {
9176
+ --ow-heatmap-cell: 12px;
9177
+ display: grid;
9178
+ min-width: 0;
9179
+ gap: var(--ow-space-xs);
9180
+ color: var(--ow-text-muted);
9181
+ font-size: 11.5px;
9182
+ line-height: 1;
9183
+ }
9184
+
9185
+ /* It scrolls sideways inside itself on a narrow screen, never the page. */
9186
+ .ow-heatmap__scroll {
9187
+ min-width: 0;
9188
+ overflow-x: auto;
9189
+ overscroll-behavior-x: contain;
9190
+ }
9191
+
9192
+ /* The spacing round the edge leaves room for the focus ring. */
9193
+ .ow-heatmap__grid {
9194
+ border-collapse: separate;
9195
+ border-spacing: max(3px, calc(var(--ow-heatmap-cell) / 4));
9196
+ }
9197
+
9198
+ .ow-heatmap__grid th,
9199
+ .ow-heatmap__grid td {
9200
+ padding: 0;
9201
+ }
9202
+
9203
+ .ow-heatmap__grid th {
9204
+ font-weight: var(--ow-weight-regular);
9205
+ text-align: start;
9206
+ white-space: nowrap;
9207
+ }
9208
+
9209
+ /* A month's name starts over its first week and runs on over the next, without widening the columns. */
9210
+ .ow-heatmap__month {
9211
+ position: relative;
9212
+ height: 1.3em;
9213
+ }
9214
+
9215
+ .ow-heatmap__month span {
9216
+ position: absolute;
9217
+ inset-inline-start: 0;
9218
+ top: 0;
9219
+ }
9220
+
9221
+ .ow-heatmap__grid .ow-heatmap__weekday {
9222
+ padding-inline-end: 4px;
9223
+ font-size: 11px;
9224
+ }
9225
+
9226
+ .ow-heatmap__cell {
9227
+ width: var(--ow-heatmap-cell);
9228
+ height: var(--ow-heatmap-cell);
9229
+ border-radius: 3px;
9230
+ }
9231
+
9232
+ .ow-heatmap__day {
9233
+ display: block;
9234
+ width: var(--ow-heatmap-cell);
9235
+ height: var(--ow-heatmap-cell);
9236
+ border: 0;
9237
+ border-radius: 3px;
9238
+ background: color-mix(in oklab, var(--ow-heatmap-color) var(--ow-heatmap-mix, 0%), var(--ow-meter-track));
9239
+ padding: 0;
9240
+ }
9241
+
9242
+ button.ow-heatmap__day {
9243
+ cursor: pointer;
9244
+ }
9245
+
9246
+ .ow-heatmap__cell:hover > .ow-heatmap__day {
9247
+ box-shadow: inset 0 0 0 1px var(--ow-text-muted);
9248
+ }
9249
+
9250
+ .ow-heatmap [data-date]:focus {
9251
+ outline: none;
9252
+ }
9253
+
9254
+ .ow-heatmap [data-date]:focus-visible {
9255
+ outline: 2px solid var(--ow-focus-ring);
9256
+ outline-offset: 1px;
9257
+ }
9258
+
9259
+ .ow-heatmap__legend {
9260
+ display: flex;
9261
+ align-items: center;
9262
+ justify-content: flex-end;
9263
+ gap: calc(var(--ow-heatmap-cell) / 4);
9264
+ }
9265
+
9266
+ .ow-heatmap__legend > :first-child {
9267
+ margin-inline-start: 4px;
9268
+ }
9269
+
9270
+ .ow-heatmap__legend > :last-child {
9271
+ margin-inline-end: 4px;
9272
+ }
9273
+
9274
+ @media (forced-colors: active) {
9275
+ .ow-heatmap__day {
9276
+ forced-color-adjust: none;
9277
+ }
9278
+ }
9279
+
9280
+ /* components/FileTree/FileTree.css */
9281
+ /* FileTree: a project structure explorer. Monospace names, hairline guides, a tinted selected file. */
9282
+ .ow-tree,
9283
+ .ow-tree__group {
9284
+ margin: 0;
9285
+ padding: 0;
9286
+ list-style: none;
9287
+ }
9288
+
9289
+ .ow-tree {
9290
+ display: grid;
9291
+ gap: 1px;
9292
+ color: var(--ow-text);
9293
+ }
9294
+
9295
+ .ow-tree__group {
9296
+ display: grid;
9297
+ gap: 1px;
9298
+ margin-left: 15px;
9299
+ border-left: 1px solid var(--ow-border);
9300
+ padding-left: var(--ow-space-sm);
9301
+ }
9302
+
9303
+ .ow-tree__item {
9304
+ outline: none;
9305
+ }
9306
+
9307
+ .ow-tree__row {
9308
+ display: flex;
9309
+ min-height: 32px;
9310
+ align-items: center;
9311
+ gap: var(--ow-space-xs);
9312
+ border-radius: var(--ow-radius-form);
9313
+ padding: var(--ow-space-2xs) var(--ow-space-sm);
9314
+ cursor: pointer;
9315
+ transition: background-color var(--ow-duration-fast) var(--ow-ease-standard);
9316
+ }
9317
+
9318
+ .ow-tree__row:hover {
9319
+ background: var(--ow-surface-muted);
9320
+ }
9321
+
9322
+ .ow-tree__item:focus-visible > .ow-tree__row {
9323
+ box-shadow: 0 0 0 2px var(--ow-focus-ring);
9324
+ }
9325
+
9326
+ .ow-tree__row--selected,
9327
+ .ow-tree__row--selected:hover {
9328
+ background: var(--ow-primary-subtle);
9329
+ color: var(--ow-primary-text);
9330
+ }
9331
+
9332
+ .ow-tree__chevron {
9333
+ flex-shrink: 0;
9334
+ color: var(--ow-text-muted);
9335
+ transition: transform var(--ow-duration-base) var(--ow-ease-standard);
9336
+ }
9337
+
9338
+ .ow-tree__chevron--open {
9339
+ transform: rotate(90deg);
9340
+ }
9341
+
9342
+ .ow-tree__spacer {
9343
+ width: 14px;
9344
+ flex-shrink: 0;
9345
+ }
9346
+
9347
+ .ow-tree__icon {
9348
+ display: inline-flex;
9349
+ flex-shrink: 0;
9350
+ color: var(--ow-text-muted);
9351
+ }
9352
+
9353
+ .ow-tree__icon--folder {
9354
+ color: var(--ow-primary-text);
9355
+ }
9356
+
9357
+ .ow-tree__row--selected .ow-tree__icon {
9358
+ color: inherit;
9359
+ }
9360
+
9361
+ .ow-tree__name {
9362
+ min-width: 0;
9363
+ flex: 1;
9364
+ overflow: hidden;
9365
+ font-family: var(--ow-font-mono);
9366
+ font-size: 13px;
9367
+ text-overflow: ellipsis;
9368
+ white-space: nowrap;
9369
+ }
9370
+
9371
+ .ow-tree__meta {
9372
+ flex-shrink: 0;
9373
+ color: var(--ow-text-muted);
9374
+ font-family: var(--ow-font-mono);
9375
+ font-size: 12px;
7905
9376
  }
7906
9377
 
7907
- /* components/FileTree/FileTree.css */
7908
- /* FileTree: a project structure explorer. Monospace names, hairline guides, a tinted selected file. */
7909
- .ow-tree,
7910
- .ow-tree__group {
9378
+ /* components/TreeView/TreeView.css */
9379
+ /* TreeView: rows that open, select and check. FileTree's hairline guides, NavList's 14px text. */
9380
+ .ow-treeview,
9381
+ .ow-treeview__group {
9382
+ display: grid;
9383
+ gap: 1px;
7911
9384
  margin: 0;
7912
9385
  padding: 0;
7913
9386
  list-style: none;
7914
9387
  }
7915
9388
 
7916
- .ow-tree {
7917
- display: grid;
7918
- gap: 1px;
9389
+ .ow-treeview {
7919
9390
  color: var(--ow-text);
9391
+ font-size: 14px;
7920
9392
  }
7921
9393
 
7922
- .ow-tree__group {
7923
- display: grid;
7924
- gap: 1px;
7925
- margin-left: 15px;
7926
- border-left: 1px solid var(--ow-border);
7927
- padding-left: var(--ow-space-sm);
9394
+ /* The guide runs under the parent's chevron. */
9395
+ .ow-treeview__group {
9396
+ margin-inline-start: 14px;
9397
+ border-inline-start: 1px solid var(--ow-border);
9398
+ padding-inline-start: var(--ow-space-2xs);
7928
9399
  }
7929
9400
 
7930
- .ow-tree__item {
9401
+ .ow-treeview__item {
7931
9402
  outline: none;
7932
9403
  }
7933
9404
 
7934
- .ow-tree__row {
9405
+ .ow-treeview__row {
7935
9406
  display: flex;
7936
9407
  min-height: 32px;
7937
9408
  align-items: center;
7938
9409
  gap: var(--ow-space-xs);
7939
9410
  border-radius: var(--ow-radius-form);
7940
- padding: var(--ow-space-2xs) var(--ow-space-sm);
9411
+ padding-block: var(--ow-space-2xs);
9412
+ padding-inline: var(--ow-space-2xs) var(--ow-space-sm);
7941
9413
  cursor: pointer;
9414
+ user-select: none;
7942
9415
  transition: background-color var(--ow-duration-fast) var(--ow-ease-standard);
7943
9416
  }
7944
9417
 
7945
- .ow-tree__row:hover {
9418
+ .ow-treeview__row:hover {
7946
9419
  background: var(--ow-surface-muted);
7947
9420
  }
7948
9421
 
7949
- .ow-tree__item:focus-visible > .ow-tree__row {
9422
+ .ow-treeview__item:focus-visible > .ow-treeview__row {
7950
9423
  box-shadow: 0 0 0 2px var(--ow-focus-ring);
7951
9424
  }
7952
9425
 
7953
- .ow-tree__row--selected,
7954
- .ow-tree__row--selected:hover {
9426
+ .ow-treeview__row--selected,
9427
+ .ow-treeview__row--selected:hover {
7955
9428
  background: var(--ow-primary-subtle);
7956
9429
  color: var(--ow-primary-text);
7957
9430
  }
7958
9431
 
7959
- .ow-tree__chevron {
9432
+ .ow-treeview__row--disabled,
9433
+ .ow-treeview__row--loading {
9434
+ color: var(--ow-text-muted);
9435
+ cursor: default;
9436
+ }
9437
+
9438
+ .ow-treeview__toggle {
9439
+ display: inline-flex;
9440
+ width: 20px;
9441
+ height: 24px;
7960
9442
  flex-shrink: 0;
9443
+ align-items: center;
9444
+ justify-content: center;
7961
9445
  color: var(--ow-text-muted);
9446
+ }
9447
+
9448
+ .ow-treeview__toggle svg {
7962
9449
  transition: transform var(--ow-duration-base) var(--ow-ease-standard);
7963
9450
  }
7964
9451
 
7965
- .ow-tree__chevron--open {
9452
+ .ow-treeview__toggle:dir(rtl) svg {
9453
+ transform: scaleX(-1);
9454
+ }
9455
+
9456
+ [aria-expanded="true"] > .ow-treeview__row .ow-treeview__toggle svg {
7966
9457
  transform: rotate(90deg);
7967
9458
  }
7968
9459
 
7969
- .ow-tree__spacer {
7970
- width: 14px;
7971
- flex-shrink: 0;
9460
+ .ow-treeview .ow-checkbox__input {
9461
+ pointer-events: none;
7972
9462
  }
7973
9463
 
7974
- .ow-tree__icon {
9464
+ .ow-treeview__icon {
7975
9465
  display: inline-flex;
7976
9466
  flex-shrink: 0;
7977
9467
  color: var(--ow-text-muted);
7978
9468
  }
7979
9469
 
7980
- .ow-tree__icon--folder {
7981
- color: var(--ow-primary-text);
7982
- }
7983
-
7984
- .ow-tree__row--selected .ow-tree__icon {
7985
- color: inherit;
7986
- }
7987
-
7988
- .ow-tree__name {
9470
+ .ow-treeview__text {
9471
+ display: grid;
7989
9472
  min-width: 0;
7990
9473
  flex: 1;
9474
+ }
9475
+
9476
+ .ow-treeview__label,
9477
+ .ow-treeview__description {
7991
9478
  overflow: hidden;
7992
- font-family: var(--ow-font-mono);
7993
- font-size: 13px;
7994
9479
  text-overflow: ellipsis;
7995
9480
  white-space: nowrap;
7996
9481
  }
7997
9482
 
7998
- .ow-tree__meta {
7999
- flex-shrink: 0;
9483
+ .ow-treeview__description,
9484
+ .ow-treeview__end {
8000
9485
  color: var(--ow-text-muted);
8001
- font-family: var(--ow-font-mono);
8002
9486
  font-size: 12px;
8003
9487
  }
8004
9488
 
9489
+ .ow-treeview__end {
9490
+ flex-shrink: 0;
9491
+ }
9492
+
9493
+ .ow-treeview__row--selected :is(.ow-treeview__icon, .ow-treeview__description, .ow-treeview__end) {
9494
+ color: inherit;
9495
+ }
9496
+
9497
+ .ow-treeview__row--error {
9498
+ color: var(--ow-danger-text);
9499
+ }
9500
+
9501
+ .ow-treeview__retry {
9502
+ font-weight: var(--ow-weight-emphasis);
9503
+ text-decoration: underline;
9504
+ }
9505
+
8005
9506
  /* components/EmptyState/EmptyState.css */
8006
9507
  /* EmptyState: centred, at most 360px of text, an icon tile above. */
8007
9508
  .ow-empty {
@@ -8212,6 +9713,148 @@
8212
9713
  font-weight: var(--ow-weight-regular);
8213
9714
  }
8214
9715
 
9716
+ /* components/NavigationMenu/NavigationMenu.css */
9717
+ /* NavigationMenu: a site's top links, with panels of links on Popover's surface. Rules are scoped under
9718
+ .ow-navigation-menu so SiteHeader's `nav a` colours don't reach into the panels. */
9719
+ .ow-navigation-menu {
9720
+ min-width: 0;
9721
+ font-family: var(--ow-font-sans);
9722
+ }
9723
+
9724
+ .ow-navigation-menu__list {
9725
+ display: flex;
9726
+ flex-wrap: wrap;
9727
+ align-items: center;
9728
+ gap: var(--ow-space-2xs);
9729
+ margin: 0;
9730
+ padding: 0;
9731
+ list-style: none;
9732
+ }
9733
+
9734
+ .ow-navigation-menu .ow-navigation-menu__trigger {
9735
+ display: inline-flex;
9736
+ min-height: 32px;
9737
+ align-items: center;
9738
+ gap: var(--ow-space-3xs);
9739
+ border: 0;
9740
+ border-radius: var(--ow-radius-pill);
9741
+ background: transparent;
9742
+ padding: 0 var(--ow-space-sm);
9743
+ color: var(--ow-text-soft);
9744
+ font: inherit;
9745
+ font-size: 14px;
9746
+ font-weight: var(--ow-weight-control);
9747
+ text-decoration: none;
9748
+ cursor: pointer;
9749
+ transition-property: color, background-color;
9750
+ transition-duration: var(--ow-duration-base);
9751
+ transition-timing-function: var(--ow-ease-standard);
9752
+ }
9753
+
9754
+ .ow-navigation-menu .ow-navigation-menu__trigger:hover,
9755
+ .ow-navigation-menu__trigger[aria-expanded="true"] {
9756
+ background: var(--ow-hover);
9757
+ color: var(--ow-text);
9758
+ }
9759
+
9760
+ .ow-navigation-menu__trigger[aria-current="page"],
9761
+ .ow-navigation-menu__trigger[data-active] {
9762
+ color: var(--ow-text);
9763
+ }
9764
+
9765
+ .ow-navigation-menu .ow-navigation-menu__trigger:focus-visible,
9766
+ .ow-navigation-menu .ow-navigation-menu__link:focus-visible {
9767
+ outline: 2px solid var(--ow-focus-ring);
9768
+ outline-offset: -2px;
9769
+ }
9770
+
9771
+ .ow-navigation-menu__chevron {
9772
+ color: var(--ow-text-muted);
9773
+ transition: transform var(--ow-duration-base) var(--ow-ease-standard);
9774
+ }
9775
+
9776
+ [aria-expanded="true"] > .ow-navigation-menu__chevron {
9777
+ transform: rotate(180deg);
9778
+ }
9779
+
9780
+ .ow-navigation-menu__panel {
9781
+ grid-template-columns: repeat(var(--ow-navigation-menu-columns), minmax(0, 15rem));
9782
+ max-width: calc(100vw - 16px);
9783
+ padding: var(--ow-space-sm);
9784
+ gap: var(--ow-space-sm);
9785
+ }
9786
+
9787
+ .ow-navigation-menu__panel--full {
9788
+ grid-template-columns: repeat(var(--ow-navigation-menu-columns), minmax(0, 1fr));
9789
+ }
9790
+
9791
+ .ow-navigation-menu__group {
9792
+ display: grid;
9793
+ align-content: start;
9794
+ gap: var(--ow-space-3xs);
9795
+ }
9796
+
9797
+ .ow-navigation-menu__group-title {
9798
+ padding: var(--ow-space-xs) var(--ow-space-sm) var(--ow-space-2xs);
9799
+ color: var(--ow-text-muted);
9800
+ font-size: 12px;
9801
+ font-weight: var(--ow-weight-label);
9802
+ }
9803
+
9804
+ .ow-navigation-menu .ow-navigation-menu__link {
9805
+ display: flex;
9806
+ align-items: flex-start;
9807
+ gap: var(--ow-space-sm);
9808
+ border-radius: var(--ow-radius-lg);
9809
+ padding: var(--ow-space-sm);
9810
+ color: var(--ow-text);
9811
+ text-decoration: none;
9812
+ transition: background-color var(--ow-duration-base) var(--ow-ease-standard);
9813
+ }
9814
+
9815
+ .ow-navigation-menu .ow-navigation-menu__link:hover,
9816
+ .ow-navigation-menu__link[aria-current="page"] {
9817
+ background: var(--ow-surface-muted);
9818
+ }
9819
+
9820
+ .ow-navigation-menu__icon {
9821
+ display: inline-flex;
9822
+ flex-shrink: 0;
9823
+ color: var(--ow-text-muted);
9824
+ }
9825
+
9826
+ .ow-navigation-menu__text {
9827
+ display: grid;
9828
+ min-width: 0;
9829
+ gap: 2px;
9830
+ }
9831
+
9832
+ .ow-navigation-menu__title {
9833
+ font-weight: var(--ow-weight-emphasis);
9834
+ line-height: 1.3;
9835
+ }
9836
+
9837
+ .ow-navigation-menu__description {
9838
+ color: var(--ow-text-muted);
9839
+ font-size: 13px;
9840
+ line-height: 1.4;
9841
+ }
9842
+
9843
+ .ow-navigation-menu .ow-navigation-menu__link--featured,
9844
+ .ow-navigation-menu .ow-navigation-menu__link--featured:hover {
9845
+ flex-direction: column;
9846
+ justify-content: flex-end;
9847
+ min-height: 9rem;
9848
+ background: var(--ow-primary-subtle);
9849
+ padding: var(--ow-space-lg);
9850
+ }
9851
+
9852
+ @media (max-width: 640px) {
9853
+ .ow-navigation-menu__panel {
9854
+ grid-template-columns: minmax(0, 1fr);
9855
+ }
9856
+ }
9857
+
8215
9858
  /* components/AppShell/AppShell.css */
8216
9859
  /* AppShell: a sidebar down the left and the page beside it. It measures its own width (a container query), so it
8217
9860
  folds into a drawer under its breakpoint (900px by default) whether it fills the window or sits in a smaller frame. */
@@ -8727,6 +10370,52 @@
8727
10370
  }
8728
10371
  }
8729
10372
 
10373
+ /* components/VirtualList/VirtualList.css */
10374
+ /* VirtualList: a scrolling list that renders only the rows in view, each placed by its offset from the top. */
10375
+ .ow-virtual-list {
10376
+ position: relative;
10377
+ display: flex;
10378
+ flex-direction: column;
10379
+ height: 100%;
10380
+ min-height: 0;
10381
+ }
10382
+
10383
+ .ow-virtual-list__scroll {
10384
+ flex: 1 1 auto;
10385
+ min-height: 0;
10386
+ overflow-x: hidden;
10387
+ overflow-y: auto;
10388
+ overscroll-behavior: contain;
10389
+ /* The list keeps its own place as rows are measured or added above; the browser's anchoring would double it. */
10390
+ overflow-anchor: none;
10391
+ border-radius: inherit;
10392
+ }
10393
+
10394
+ .ow-virtual-list__scroll:focus-visible,
10395
+ .ow-virtual-list__item:focus-visible {
10396
+ outline: 2px solid var(--ow-focus-ring);
10397
+ outline-offset: -2px;
10398
+ }
10399
+
10400
+ .ow-virtual-list__inner {
10401
+ position: relative;
10402
+ flex-shrink: 0;
10403
+ width: 100%;
10404
+ }
10405
+
10406
+ .ow-virtual-list__item {
10407
+ position: absolute;
10408
+ top: 0;
10409
+ inset-inline: 0;
10410
+ border-radius: var(--ow-radius-md);
10411
+ }
10412
+
10413
+ .ow-virtual-list__footer {
10414
+ display: flex;
10415
+ justify-content: center;
10416
+ padding: var(--ow-space-md);
10417
+ }
10418
+
8730
10419
  /* components/AspectRatio/AspectRatio.css */
8731
10420
  /* AspectRatio: a box that keeps its shape, with whatever is inside filling it. The hidden overflow keeps the ratio
8732
10421
  when the content is taller than the box would be. */
@@ -9568,6 +11257,44 @@
9568
11257
  }
9569
11258
  }
9570
11259
 
11260
+ /* components/Markdown/Markdown.css */
11261
+ /* Markdown: Prose does the typography; this is only the caret that follows a streaming answer's last character. */
11262
+ .ow-markdown__caret {
11263
+ display: inline-block;
11264
+ width: 2px;
11265
+ height: 1.15em;
11266
+ margin-inline-start: 2px;
11267
+ border-radius: 1px;
11268
+ background: currentColor;
11269
+ vertical-align: -0.2em;
11270
+ animation: ow-markdown-caret 1s var(--ow-ease-standard) infinite;
11271
+ }
11272
+
11273
+ @keyframes ow-markdown-caret {
11274
+ 0%,
11275
+ 100% {
11276
+ opacity: 0.9;
11277
+ }
11278
+ 50% {
11279
+ opacity: 0.15;
11280
+ }
11281
+ }
11282
+
11283
+ @media (prefers-reduced-motion: reduce) {
11284
+ .ow-markdown__caret {
11285
+ opacity: 0.6;
11286
+ animation: none;
11287
+ }
11288
+ }
11289
+
11290
+ /* Forced colours drop backgrounds: draw the caret in the text colour. */
11291
+ @media (forced-colors: active) {
11292
+ .ow-markdown__caret {
11293
+ forced-color-adjust: none;
11294
+ background: CanvasText;
11295
+ }
11296
+ }
11297
+
9571
11298
  /* components/TextShimmer/TextShimmer.css */
9572
11299
  /* TextShimmer: muted text with a band of full-strength text sweeping across it. */
9573
11300
  .ow-shimmer {