@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
@@ -1325,6 +1325,208 @@
1325
1325
  outline: 0;
1326
1326
  }
1327
1327
 
1328
+ /* components/InlineEdit/InlineEdit.css */
1329
+ /* InlineEdit: text that turns into a text box where it is. The button and the box share their font, padding and border,
1330
+ and pull back by them, so the text lines up with what's around it and doesn't move when the box opens. */
1331
+ .ow-inline-edit {
1332
+ --ow-inline-edit-x: 0.375em;
1333
+ --ow-inline-edit-y: 0.125em;
1334
+ --ow-inline-edit-icon: clamp(12px, 0.75em, 20px);
1335
+ display: inline-grid;
1336
+ max-width: 100%;
1337
+ grid-template-columns: minmax(0, 1fr);
1338
+ gap: var(--ow-space-2xs);
1339
+ }
1340
+
1341
+ .ow-inline-edit--multiline {
1342
+ display: grid;
1343
+ }
1344
+
1345
+ .ow-inline-edit__display,
1346
+ .ow-inline-edit__input,
1347
+ .ow-inline-edit__field::after {
1348
+ box-sizing: border-box;
1349
+ margin: 0;
1350
+ border: 1px solid transparent;
1351
+ border-radius: var(--ow-radius-sm);
1352
+ padding: var(--ow-inline-edit-y) var(--ow-inline-edit-x);
1353
+ color: inherit;
1354
+ font: inherit;
1355
+ letter-spacing: inherit;
1356
+ }
1357
+
1358
+ .ow-inline-edit__display,
1359
+ .ow-inline-edit__editor {
1360
+ margin-inline: calc(-1px - var(--ow-inline-edit-x));
1361
+ }
1362
+
1363
+ .ow-inline-edit__display {
1364
+ position: relative;
1365
+ display: inline-flex;
1366
+ min-width: 0;
1367
+ align-items: baseline;
1368
+ gap: 0.3em;
1369
+ background: transparent;
1370
+ cursor: pointer;
1371
+ text-align: start;
1372
+ }
1373
+
1374
+ .ow-inline-edit--multiline .ow-inline-edit__display {
1375
+ display: flex;
1376
+ }
1377
+
1378
+ .ow-inline-edit__display:hover:not(:disabled) {
1379
+ background: var(--ow-hover);
1380
+ }
1381
+
1382
+ .ow-inline-edit__display:focus-visible {
1383
+ outline: 2px solid var(--ow-focus-ring);
1384
+ outline-offset: 2px;
1385
+ }
1386
+
1387
+ .ow-inline-edit__display:disabled {
1388
+ cursor: not-allowed;
1389
+ opacity: 0.62;
1390
+ }
1391
+
1392
+ .ow-inline-edit__text {
1393
+ min-width: 0;
1394
+ overflow-wrap: anywhere;
1395
+ white-space: pre-wrap;
1396
+ }
1397
+
1398
+ .ow-inline-edit__text--empty {
1399
+ color: var(--ow-text-muted);
1400
+ }
1401
+
1402
+ /* The pencil shows on hover and focus; on touch screens, which can't hover, always. */
1403
+ .ow-inline-edit__icon {
1404
+ width: var(--ow-inline-edit-icon);
1405
+ height: var(--ow-inline-edit-icon);
1406
+ flex: none;
1407
+ align-self: center;
1408
+ color: var(--ow-icon);
1409
+ opacity: 0;
1410
+ }
1411
+
1412
+ .ow-inline-edit__display:hover .ow-inline-edit__icon,
1413
+ .ow-inline-edit__display:focus-visible .ow-inline-edit__icon {
1414
+ opacity: 1;
1415
+ }
1416
+
1417
+ @media (hover: none) {
1418
+ .ow-inline-edit__display:not(:disabled) .ow-inline-edit__icon {
1419
+ opacity: 1;
1420
+ }
1421
+ }
1422
+
1423
+ .ow-inline-edit__editor {
1424
+ display: flex;
1425
+ min-width: 0;
1426
+ align-items: center;
1427
+ gap: var(--ow-space-xs);
1428
+ }
1429
+
1430
+ /* The box is as wide as a hidden copy of its text, plus the pencil's room, in the same grid cell. */
1431
+ .ow-inline-edit__field {
1432
+ display: inline-grid;
1433
+ min-width: 0;
1434
+ grid-template-columns: minmax(0, 1fr);
1435
+ }
1436
+
1437
+ .ow-inline-edit__field::after {
1438
+ overflow: hidden;
1439
+ padding-inline-end: calc(var(--ow-inline-edit-x) + var(--ow-inline-edit-icon) + 0.3em);
1440
+ content: attr(data-value) " ";
1441
+ grid-area: 1 / 1;
1442
+ visibility: hidden;
1443
+ white-space: pre;
1444
+ }
1445
+
1446
+ .ow-inline-edit__input {
1447
+ display: block;
1448
+ width: 100%;
1449
+ min-width: 0;
1450
+ min-height: 0;
1451
+ flex: 1;
1452
+ grid-area: 1 / 1;
1453
+ border-color: var(--ow-border-strong);
1454
+ background: var(--ow-surface);
1455
+ outline: 0;
1456
+ }
1457
+
1458
+ .ow-inline-edit__input::placeholder {
1459
+ color: var(--ow-text-muted);
1460
+ opacity: 1;
1461
+ }
1462
+
1463
+ .ow-inline-edit__input:focus {
1464
+ border-color: var(--ow-focus-border);
1465
+ box-shadow: var(--ow-shadow-focus);
1466
+ }
1467
+
1468
+ .ow-inline-edit__input:focus-visible {
1469
+ outline: 2px solid var(--ow-focus-ring);
1470
+ outline-offset: 2px;
1471
+ }
1472
+
1473
+ .ow-inline-edit__input[aria-invalid="true"] {
1474
+ border-color: var(--ow-danger-solid);
1475
+ }
1476
+
1477
+ .ow-inline-edit__input[aria-invalid="true"]:focus {
1478
+ box-shadow: var(--ow-shadow-focus-danger);
1479
+ }
1480
+
1481
+ /* An auto-growing textarea is as tall as its scrollHeight, which leaves out the border, so it draws its border inside. */
1482
+ textarea.ow-inline-edit__input {
1483
+ border: 0;
1484
+ padding: calc(var(--ow-inline-edit-y) + 1px) calc(var(--ow-inline-edit-x) + 1px);
1485
+ box-shadow: inset 0 0 0 1px var(--ow-border-strong);
1486
+ }
1487
+
1488
+ textarea.ow-inline-edit__input:focus {
1489
+ box-shadow:
1490
+ inset 0 0 0 1px var(--ow-focus-border),
1491
+ var(--ow-shadow-focus);
1492
+ }
1493
+
1494
+ textarea.ow-inline-edit__input[aria-invalid="true"] {
1495
+ box-shadow: inset 0 0 0 1px var(--ow-danger-solid);
1496
+ }
1497
+
1498
+ textarea.ow-inline-edit__input[aria-invalid="true"]:focus {
1499
+ box-shadow:
1500
+ inset 0 0 0 1px var(--ow-danger-solid),
1501
+ var(--ow-shadow-focus-danger);
1502
+ }
1503
+
1504
+ .ow-inline-edit__actions {
1505
+ display: inline-flex;
1506
+ flex: none;
1507
+ gap: var(--ow-space-2xs);
1508
+ }
1509
+
1510
+ .ow-inline-edit__spinner {
1511
+ flex: none;
1512
+ }
1513
+
1514
+ .ow-inline-edit__error {
1515
+ color: var(--ow-danger-text);
1516
+ font: var(--ow-weight-regular) 14px / 1.4 var(--ow-font-sans);
1517
+ letter-spacing: normal;
1518
+ }
1519
+
1520
+ @media (prefers-reduced-motion: no-preference) {
1521
+ .ow-inline-edit__display,
1522
+ .ow-inline-edit__icon,
1523
+ .ow-inline-edit__input {
1524
+ transition-property: background-color, border-color, box-shadow, opacity;
1525
+ transition-duration: var(--ow-duration-fast);
1526
+ transition-timing-function: var(--ow-ease-standard);
1527
+ }
1528
+ }
1529
+
1328
1530
  /* components/Select/Select.css */
1329
1531
  /* Select: the trigger looks like a field; the listbox floats in the top layer. */
1330
1532
  .ow-select {
@@ -1588,6 +1790,99 @@
1588
1790
  }
1589
1791
  }
1590
1792
 
1793
+ /* components/TransferList/TransferList.css */
1794
+ /* TransferList: two standalone ListBoxes (ListBox.css) with a column of Buttons between them. Its own width decides
1795
+ the layout (a container query): side by side, or stacked with the buttons turned to point down and up. */
1796
+ .ow-transfer-list {
1797
+ container: ow-transfer-list / inline-size;
1798
+ color: var(--ow-text);
1799
+ font-family: var(--ow-font-sans);
1800
+ }
1801
+
1802
+ .ow-transfer-list__body {
1803
+ display: grid;
1804
+ grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
1805
+ gap: var(--ow-space-lg);
1806
+ }
1807
+
1808
+ .ow-transfer-list__pane {
1809
+ display: grid;
1810
+ min-width: 0;
1811
+ align-content: start;
1812
+ gap: var(--ow-space-sm);
1813
+ }
1814
+
1815
+ .ow-transfer-list__header {
1816
+ display: flex;
1817
+ align-items: baseline;
1818
+ justify-content: space-between;
1819
+ gap: var(--ow-space-sm);
1820
+ }
1821
+
1822
+ .ow-transfer-list__label {
1823
+ font-size: 14px;
1824
+ font-weight: var(--ow-weight-emphasis);
1825
+ line-height: 1.4;
1826
+ }
1827
+
1828
+ .ow-transfer-list__count {
1829
+ color: var(--ow-text-muted);
1830
+ font-size: 12px;
1831
+ font-variant-numeric: tabular-nums;
1832
+ white-space: nowrap;
1833
+ }
1834
+
1835
+ .ow-transfer-list .ow-transfer-list__list {
1836
+ height: var(--ow-transfer-list-height);
1837
+ }
1838
+
1839
+ .ow-transfer-list__actions {
1840
+ display: flex;
1841
+ flex-direction: column;
1842
+ align-self: center;
1843
+ gap: var(--ow-space-xs);
1844
+ }
1845
+
1846
+ .ow-transfer-list__icon {
1847
+ display: flex;
1848
+ }
1849
+
1850
+ /* The arrows point the way the items go, so they turn round right to left. */
1851
+ .ow-transfer-list__icon--back,
1852
+ .ow-transfer-list:dir(rtl) .ow-transfer-list__icon {
1853
+ transform: scaleX(-1);
1854
+ }
1855
+
1856
+ .ow-transfer-list:dir(rtl) .ow-transfer-list__icon--back {
1857
+ transform: none;
1858
+ }
1859
+
1860
+ .ow-transfer-list__order {
1861
+ display: flex;
1862
+ justify-content: flex-end;
1863
+ gap: var(--ow-space-2xs);
1864
+ }
1865
+
1866
+ @container ow-transfer-list (max-width: 519px) {
1867
+ .ow-transfer-list__body {
1868
+ grid-template-columns: minmax(0, 1fr);
1869
+ }
1870
+
1871
+ .ow-transfer-list__actions {
1872
+ flex-direction: row;
1873
+ justify-content: center;
1874
+ }
1875
+
1876
+ /* Across becomes down: → turns to ↓ and ← to ↑, whichever way the text runs. */
1877
+ .ow-transfer-list .ow-transfer-list__actions .ow-transfer-list__icon {
1878
+ transform: rotate(90deg);
1879
+ }
1880
+
1881
+ .ow-transfer-list .ow-transfer-list__actions .ow-transfer-list__icon--back {
1882
+ transform: rotate(-90deg);
1883
+ }
1884
+ }
1885
+
1591
1886
  /* components/Combobox/Combobox.css */
1592
1887
  /* Combobox: a grouped field (Input.css) with a chevron, over Select's listbox. */
1593
1888
  .ow-combobox {
@@ -1676,6 +1971,20 @@
1676
1971
  padding-left: var(--ow-space-2xs);
1677
1972
  }
1678
1973
 
1974
+ /* components/MentionInput/MentionInput.css */
1975
+ /* MentionInput: an Input or a Textarea, with Select's listbox (Select.css) under the trigger character. */
1976
+ .ow-mention-list {
1977
+ width: max-content;
1978
+ min-width: 224px;
1979
+ max-width: min(360px, calc(100vw - 16px));
1980
+ }
1981
+
1982
+ .ow-mention-list__empty {
1983
+ display: flex;
1984
+ align-items: center;
1985
+ gap: var(--ow-space-xs);
1986
+ }
1987
+
1679
1988
  /* components/Checkbox/Checkbox.css */
1680
1989
  /* Checkbox: a native input with its look replaced. */
1681
1990
  .ow-checkbox {
@@ -2301,6 +2610,99 @@
2301
2610
  }
2302
2611
  }
2303
2612
 
2613
+ /* components/SignaturePad/SignaturePad.css */
2614
+ /* SignaturePad: a field-like box to sign in, on a signing line, with its buttons underneath. */
2615
+ .ow-signature-pad {
2616
+ position: relative;
2617
+ display: grid;
2618
+ width: 100%;
2619
+ min-width: 0;
2620
+ gap: var(--ow-space-sm);
2621
+ }
2622
+
2623
+ .ow-signature-pad__surface {
2624
+ position: relative;
2625
+ height: var(--ow-signature-pad-height, 160px);
2626
+ overflow: hidden;
2627
+ border: 1px solid var(--ow-border-strong);
2628
+ border-radius: var(--ow-radius-form);
2629
+ background: var(--ow-surface);
2630
+ transition-property: border-color, box-shadow;
2631
+ transition-duration: var(--ow-duration-base);
2632
+ transition-timing-function: var(--ow-ease-standard);
2633
+ }
2634
+
2635
+ /* The ink is this colour (a penColor replaces it); the script reads it from CSS, so it follows the theme. */
2636
+ .ow-signature-pad__canvas {
2637
+ display: block;
2638
+ width: 100%;
2639
+ height: 100%;
2640
+ color: var(--ow-text);
2641
+ cursor: crosshair;
2642
+ touch-action: none;
2643
+ }
2644
+
2645
+ .ow-signature-pad--typing .ow-signature-pad__canvas,
2646
+ .ow-signature-pad--readonly .ow-signature-pad__canvas,
2647
+ .ow-signature-pad--disabled .ow-signature-pad__canvas {
2648
+ cursor: default;
2649
+ }
2650
+
2651
+ .ow-signature-pad:not(.ow-signature-pad--typing, .ow-signature-pad--readonly, .ow-signature-pad--disabled) .ow-signature-pad__surface:hover {
2652
+ border-color: var(--ow-border-hover);
2653
+ }
2654
+
2655
+ .ow-signature-pad--drawing .ow-signature-pad__surface {
2656
+ border-color: var(--ow-focus-border);
2657
+ box-shadow: var(--ow-shadow-focus);
2658
+ }
2659
+
2660
+ .ow-signature-pad--invalid .ow-signature-pad__surface {
2661
+ border-color: var(--ow-danger-line);
2662
+ }
2663
+
2664
+ /* At 72% of the height, where the script sets a typed name. */
2665
+ .ow-signature-pad__line {
2666
+ position: absolute;
2667
+ top: 72%;
2668
+ inset-inline: var(--ow-space-2xl);
2669
+ border-top: 1px dashed var(--ow-border-strong);
2670
+ pointer-events: none;
2671
+ }
2672
+
2673
+ .ow-signature-pad__prompt {
2674
+ position: absolute;
2675
+ bottom: calc(28% + var(--ow-space-xs));
2676
+ inset-inline-start: var(--ow-space-2xl);
2677
+ color: var(--ow-text-muted);
2678
+ font-size: 14px;
2679
+ line-height: 1.4;
2680
+ pointer-events: none;
2681
+ }
2682
+
2683
+ .ow-signature-pad__actions {
2684
+ display: flex;
2685
+ flex-wrap: wrap;
2686
+ align-items: center;
2687
+ gap: var(--ow-space-xs);
2688
+ }
2689
+
2690
+ .ow-signature-pad__edit {
2691
+ display: inline-flex;
2692
+ gap: var(--ow-space-xs);
2693
+ margin-inline-start: auto;
2694
+ }
2695
+
2696
+ .ow-signature-pad--disabled .ow-signature-pad__surface {
2697
+ opacity: 0.62;
2698
+ }
2699
+
2700
+ @media (prefers-reduced-motion: reduce) {
2701
+ .ow-signature-pad__surface {
2702
+ transition: none;
2703
+ }
2704
+ }
2705
+
2304
2706
  /* components/NumberField/NumberField.css */
2305
2707
  /* NumberField: − value + in one field. */
2306
2708
  .ow-number-field {
@@ -2498,68 +2900,260 @@
2498
2900
  transition-timing-function: var(--ow-ease-standard);
2499
2901
  }
2500
2902
 
2501
- .ow-dropzone:hover {
2502
- border-color: var(--ow-border-hover);
2903
+ .ow-dropzone:hover {
2904
+ border-color: var(--ow-border-hover);
2905
+ }
2906
+
2907
+ .ow-dropzone:focus-within:has(:focus-visible) {
2908
+ outline: 2px solid var(--ow-focus-ring);
2909
+ outline-offset: 2px;
2910
+ }
2911
+
2912
+ .ow-dropzone--dragging,
2913
+ .ow-dropzone--dragging:hover {
2914
+ border-color: var(--ow-primary-text);
2915
+ background: var(--ow-primary-subtle);
2916
+ }
2917
+
2918
+ .ow-dropzone--invalid {
2919
+ border-color: var(--ow-danger-line);
2920
+ }
2921
+
2922
+ .ow-dropzone--disabled {
2923
+ cursor: not-allowed;
2924
+ opacity: 0.62;
2925
+ }
2926
+
2927
+ .ow-dropzone__icon {
2928
+ display: inline-flex;
2929
+ width: 40px;
2930
+ height: 40px;
2931
+ align-items: center;
2932
+ justify-content: center;
2933
+ border: 1px solid var(--ow-border);
2934
+ border-radius: var(--ow-radius-md);
2935
+ background: var(--ow-surface);
2936
+ color: var(--ow-text-muted);
2937
+ transition-property: color, border-color;
2938
+ transition-duration: var(--ow-duration-base);
2939
+ transition-timing-function: var(--ow-ease-standard);
2940
+ }
2941
+
2942
+ .ow-dropzone--dragging .ow-dropzone__icon {
2943
+ border-color: var(--ow-primary-border);
2944
+ color: var(--ow-primary-text);
2945
+ }
2946
+
2947
+ .ow-dropzone__label {
2948
+ font-size: 14px;
2949
+ font-weight: var(--ow-weight-emphasis);
2950
+ line-height: 1.3;
2951
+ }
2952
+
2953
+ .ow-dropzone--dragging .ow-dropzone__label {
2954
+ color: var(--ow-primary-text);
2955
+ }
2956
+
2957
+ .ow-dropzone__hint {
2958
+ color: var(--ow-text-muted);
2959
+ font-size: 12px;
2960
+ line-height: 1.35;
2961
+ }
2962
+
2963
+ .ow-dropzone--invalid .ow-dropzone__hint {
2964
+ color: var(--ow-danger-text);
2965
+ }
2966
+
2967
+ /* components/UploadList/UploadList.css */
2968
+ /* UploadList: a row (or a tile) per file being uploaded, with its progress, status and buttons. */
2969
+ .ow-upload-list {
2970
+ width: 100%;
2971
+ min-width: 0;
2972
+ }
2973
+
2974
+ .ow-upload-list__items {
2975
+ display: grid;
2976
+ gap: var(--ow-space-sm);
2977
+ margin: 0;
2978
+ padding: 0;
2979
+ list-style: none;
2980
+ border-radius: var(--ow-radius-container);
2981
+ }
2982
+
2983
+ .ow-upload-list__items:focus-visible {
2984
+ outline: 2px solid var(--ow-focus-ring);
2985
+ outline-offset: 2px;
2986
+ }
2987
+
2988
+ .ow-upload-list__item {
2989
+ position: relative;
2990
+ display: flex;
2991
+ min-width: 0;
2992
+ align-items: center;
2993
+ gap: var(--ow-space-md);
2994
+ border: 1px solid var(--ow-border);
2995
+ border-radius: var(--ow-radius-container);
2996
+ background: var(--ow-surface);
2997
+ padding: var(--ow-space-sm);
2998
+ padding-inline-start: var(--ow-space-md);
2999
+ }
3000
+
3001
+ .ow-upload-list__item--error {
3002
+ border-color: var(--ow-danger-line);
3003
+ }
3004
+
3005
+ .ow-upload-list__thumb {
3006
+ position: relative;
3007
+ display: inline-flex;
3008
+ width: 40px;
3009
+ height: 40px;
3010
+ flex-shrink: 0;
3011
+ align-items: center;
3012
+ justify-content: center;
3013
+ overflow: hidden;
3014
+ border-radius: var(--ow-radius-md);
3015
+ background: var(--ow-surface-muted);
3016
+ color: var(--ow-text-muted);
3017
+ }
3018
+
3019
+ .ow-upload-list__thumb img {
3020
+ position: absolute;
3021
+ inset: 0;
3022
+ width: 100%;
3023
+ height: 100%;
3024
+ object-fit: cover;
3025
+ }
3026
+
3027
+ .ow-upload-list__body {
3028
+ display: grid;
3029
+ min-width: 0;
3030
+ flex: 1;
3031
+ gap: 2px;
3032
+ }
3033
+
3034
+ .ow-upload-list__name {
3035
+ overflow: hidden;
3036
+ color: var(--ow-text);
3037
+ font-size: 14px;
3038
+ font-weight: var(--ow-weight-emphasis);
3039
+ line-height: 1.35;
3040
+ text-overflow: ellipsis;
3041
+ white-space: nowrap;
3042
+ }
3043
+
3044
+ .ow-upload-list__detail {
3045
+ display: flex;
3046
+ min-width: 0;
3047
+ align-items: center;
3048
+ gap: var(--ow-space-xs);
3049
+ color: var(--ow-text-muted);
3050
+ font-size: 12px;
3051
+ line-height: 1.35;
3052
+ font-variant-numeric: tabular-nums;
3053
+ }
3054
+
3055
+ .ow-upload-list__detail > span {
3056
+ overflow: hidden;
3057
+ text-overflow: ellipsis;
3058
+ white-space: nowrap;
3059
+ }
3060
+
3061
+ .ow-upload-list__icon {
3062
+ flex-shrink: 0;
3063
+ }
3064
+
3065
+ .ow-upload-list__item--done .ow-upload-list__icon {
3066
+ color: var(--ow-success-text);
3067
+ }
3068
+
3069
+ .ow-upload-list__item--error .ow-upload-list__detail {
3070
+ color: var(--ow-danger-text);
3071
+ }
3072
+
3073
+ .ow-upload-list__progress {
3074
+ margin-top: var(--ow-space-xs);
2503
3075
  }
2504
3076
 
2505
- .ow-dropzone:focus-within:has(:focus-visible) {
2506
- outline: 2px solid var(--ow-focus-ring);
2507
- outline-offset: 2px;
3077
+ .ow-upload-list__actions {
3078
+ display: flex;
3079
+ flex-shrink: 0;
3080
+ gap: var(--ow-space-2xs);
2508
3081
  }
2509
3082
 
2510
- .ow-dropzone--dragging,
2511
- .ow-dropzone--dragging:hover {
2512
- border-color: var(--ow-primary-text);
2513
- background: var(--ow-primary-subtle);
3083
+ .ow-upload-list__actions:empty {
3084
+ display: none;
2514
3085
  }
2515
3086
 
2516
- .ow-dropzone--invalid {
2517
- border-color: var(--ow-danger-line);
3087
+ /* Compact: one short line per file, its progress a hairline along the bottom. */
3088
+ .ow-upload-list--compact .ow-upload-list__items {
3089
+ gap: var(--ow-space-xs);
2518
3090
  }
2519
3091
 
2520
- .ow-dropzone--disabled {
2521
- cursor: not-allowed;
2522
- opacity: 0.62;
3092
+ .ow-upload-list--compact .ow-upload-list__item {
3093
+ gap: var(--ow-space-sm);
3094
+ padding-block: var(--ow-space-2xs);
2523
3095
  }
2524
3096
 
2525
- .ow-dropzone__icon {
2526
- display: inline-flex;
2527
- width: 40px;
2528
- height: 40px;
2529
- align-items: center;
2530
- justify-content: center;
2531
- border: 1px solid var(--ow-border);
2532
- border-radius: var(--ow-radius-md);
2533
- background: var(--ow-surface);
2534
- color: var(--ow-text-muted);
2535
- transition-property: color, border-color;
2536
- transition-duration: var(--ow-duration-base);
2537
- transition-timing-function: var(--ow-ease-standard);
3097
+ .ow-upload-list--compact .ow-upload-list__thumb {
3098
+ width: auto;
3099
+ height: auto;
3100
+ background: none;
2538
3101
  }
2539
3102
 
2540
- .ow-dropzone--dragging .ow-dropzone__icon {
2541
- border-color: var(--ow-primary-border);
2542
- color: var(--ow-primary-text);
3103
+ .ow-upload-list--compact .ow-upload-list__body {
3104
+ display: flex;
3105
+ align-items: baseline;
3106
+ gap: var(--ow-space-sm);
2543
3107
  }
2544
3108
 
2545
- .ow-dropzone__label {
2546
- font-size: 14px;
2547
- font-weight: var(--ow-weight-emphasis);
2548
- line-height: 1.3;
3109
+ .ow-upload-list--compact .ow-upload-list__name {
3110
+ min-width: 4em;
3111
+ flex: 1 1 auto;
3112
+ font-size: 13px;
2549
3113
  }
2550
3114
 
2551
- .ow-dropzone--dragging .ow-dropzone__label {
2552
- color: var(--ow-primary-text);
3115
+ .ow-upload-list--compact .ow-upload-list__progress {
3116
+ position: absolute;
3117
+ inset: auto var(--ow-space-md) 2px;
3118
+ margin: 0;
2553
3119
  }
2554
3120
 
2555
- .ow-dropzone__hint {
2556
- color: var(--ow-text-muted);
2557
- font-size: 12px;
2558
- line-height: 1.35;
3121
+ /* Grid: a tile per file, the thumbnail on top and the buttons over its corner. */
3122
+ .ow-upload-list--grid .ow-upload-list__items {
3123
+ grid-template-columns: repeat(auto-fill, minmax(144px, 1fr));
3124
+ gap: var(--ow-space-md);
2559
3125
  }
2560
3126
 
2561
- .ow-dropzone--invalid .ow-dropzone__hint {
2562
- color: var(--ow-danger-text);
3127
+ .ow-upload-list--grid .ow-upload-list__item {
3128
+ flex-direction: column;
3129
+ align-items: stretch;
3130
+ gap: var(--ow-space-sm);
3131
+ padding: var(--ow-space-xs) var(--ow-space-xs) var(--ow-space-sm);
3132
+ }
3133
+
3134
+ .ow-upload-list--grid .ow-upload-list__thumb {
3135
+ width: auto;
3136
+ height: auto;
3137
+ aspect-ratio: 1;
3138
+ border-radius: calc(var(--ow-radius-container) - 4px);
3139
+ }
3140
+
3141
+ .ow-upload-list--grid .ow-upload-list__thumb svg {
3142
+ width: 28px;
3143
+ height: 28px;
3144
+ }
3145
+
3146
+ .ow-upload-list--grid .ow-upload-list__body {
3147
+ padding-inline: var(--ow-space-xs);
3148
+ }
3149
+
3150
+ .ow-upload-list--grid .ow-upload-list__actions {
3151
+ position: absolute;
3152
+ inset-block-start: var(--ow-space-sm);
3153
+ inset-inline-end: var(--ow-space-sm);
3154
+ border-radius: var(--ow-radius-md);
3155
+ background: var(--ow-surface);
3156
+ box-shadow: 0 0 0 1px var(--ow-border);
2563
3157
  }
2564
3158
 
2565
3159
  /* components/Field/Field.css */
@@ -3831,38 +4425,255 @@
3831
4425
  }
3832
4426
  }
3833
4427
 
3834
- /* components/Popover/Popover.css */
3835
- /* Popover: a surface card with the menu shadow, attached to its trigger. */
3836
- .ow-popover-anchor {
3837
- display: inline-flex;
4428
+ /* components/Popover/Popover.css */
4429
+ /* Popover: a surface card with the menu shadow, attached to its trigger. */
4430
+ .ow-popover-anchor {
4431
+ display: inline-flex;
4432
+ }
4433
+
4434
+ .ow-popover {
4435
+ z-index: 60;
4436
+ display: grid;
4437
+ gap: var(--ow-space-md);
4438
+ overflow: auto;
4439
+ border: 1px solid var(--ow-border);
4440
+ border-radius: var(--ow-radius-container);
4441
+ background: var(--ow-surface);
4442
+ padding: var(--ow-space-xl);
4443
+ color: var(--ow-text);
4444
+ font-family: var(--ow-font-sans);
4445
+ font-size: 14px;
4446
+ line-height: 1.45;
4447
+ box-shadow: var(--ow-shadow-menu);
4448
+ outline: none;
4449
+ }
4450
+
4451
+ /* Children may shrink to the popover's width instead of pushing past it. */
4452
+ .ow-popover > * {
4453
+ min-width: 0;
4454
+ }
4455
+
4456
+ .ow-popover__title {
4457
+ font-size: 14px;
4458
+ font-weight: var(--ow-weight-emphasis);
4459
+ line-height: 1.3;
4460
+ }
4461
+
4462
+ /* components/NotificationCenter/NotificationCenter.css */
4463
+ /* NotificationCenter: a bell with a count, opening a popover inbox. NotificationList: the rows inside it. */
4464
+ .ow-notification-center {
4465
+ display: inline-flex;
4466
+ }
4467
+
4468
+ .ow-notification-center__bell {
4469
+ position: relative;
4470
+ }
4471
+
4472
+ /* The count sits on the bell's corner, cut out of whatever is behind it. */
4473
+ .ow-notification-center__count.ow-badge {
4474
+ position: absolute;
4475
+ top: 0;
4476
+ inset-inline-end: -2px;
4477
+ min-width: 18px;
4478
+ min-height: 18px;
4479
+ border: 2px solid var(--ow-surface);
4480
+ background: var(--ow-primary);
4481
+ padding: 0 4px;
4482
+ color: var(--ow-on-primary);
4483
+ font-size: 10.5px;
4484
+ font-variant-numeric: tabular-nums;
4485
+ pointer-events: none;
4486
+ }
4487
+
4488
+ /* Edge-to-edge rows, so the popover's own padding goes; only the list scrolls when the window is short. */
4489
+ .ow-notification-center__popover.ow-popover {
4490
+ display: flex;
4491
+ flex-direction: column;
4492
+ padding: 0;
4493
+ overflow: hidden;
4494
+ }
4495
+
4496
+ .ow-notification-center__head,
4497
+ .ow-notification-center__foot {
4498
+ display: flex;
4499
+ align-items: center;
4500
+ justify-content: space-between;
4501
+ gap: var(--ow-space-md);
4502
+ padding: var(--ow-space-md) var(--ow-space-md) var(--ow-space-xs);
4503
+ padding-inline-start: var(--ow-space-2xl);
4504
+ }
4505
+
4506
+ .ow-notification-center__title {
4507
+ font-weight: var(--ow-weight-emphasis);
4508
+ }
4509
+
4510
+ .ow-notification-center__tabs.ow-tabs {
4511
+ display: flex;
4512
+ min-height: 0;
4513
+ flex-direction: column;
4514
+ gap: 0;
4515
+ }
4516
+
4517
+ .ow-notification-center__tabs .ow-tabs__list {
4518
+ padding: 0 var(--ow-space-2xl);
4519
+ }
4520
+
4521
+ .ow-notification-center__tab-count {
4522
+ border-radius: var(--ow-radius-pill);
4523
+ background: var(--ow-surface-muted);
4524
+ padding: 1px 6px;
4525
+ font-size: 11px;
4526
+ font-variant-numeric: tabular-nums;
4527
+ }
4528
+
4529
+ .ow-notification-center__body {
4530
+ min-height: 0;
4531
+ max-height: min(420px, 60dvh);
4532
+ overflow-y: auto;
4533
+ padding: var(--ow-space-xs);
4534
+ outline: none;
4535
+ }
4536
+
4537
+ .ow-notification-center__body:focus-visible {
4538
+ box-shadow: inset 0 0 0 2px var(--ow-focus-ring);
4539
+ }
4540
+
4541
+ .ow-notification-center__foot {
4542
+ border-top: 1px solid var(--ow-border);
4543
+ padding-block: var(--ow-space-md);
4544
+ }
4545
+
4546
+ /* The list. */
4547
+ .ow-notification-list__heading {
4548
+ margin: 0;
4549
+ padding: var(--ow-space-lg) var(--ow-space-lg) var(--ow-space-xs);
4550
+ color: var(--ow-text-muted);
4551
+ font-size: 12px;
4552
+ font-weight: var(--ow-weight-strong);
4553
+ }
4554
+
4555
+ .ow-notification-list__items {
4556
+ margin: 0;
4557
+ padding: 0;
4558
+ list-style: none;
4559
+ }
4560
+
4561
+ /* One row: the whole of it opens the item, through the link stretched over it. */
4562
+ .ow-notification {
4563
+ position: relative;
4564
+ display: flex;
4565
+ align-items: flex-start;
4566
+ gap: var(--ow-space-lg);
4567
+ border-radius: var(--ow-radius-form);
4568
+ padding-block: var(--ow-space-lg);
4569
+ padding-inline: 22px var(--ow-space-md);
4570
+ color: var(--ow-text-soft);
4571
+ transition: background-color var(--ow-duration-fast) var(--ow-ease-standard);
4572
+ }
4573
+
4574
+ .ow-notification:hover {
4575
+ background: var(--ow-hover);
4576
+ }
4577
+
4578
+ .ow-notification__dot {
4579
+ position: absolute;
4580
+ top: 20px;
4581
+ inset-inline-start: 8px;
4582
+ width: 8px;
4583
+ height: 8px;
4584
+ border-radius: 50%;
4585
+ background: var(--ow-primary);
4586
+ }
4587
+
4588
+ .ow-notification__media {
4589
+ display: inline-flex;
4590
+ flex-shrink: 0;
4591
+ }
4592
+
4593
+ .ow-notification__icon {
4594
+ display: inline-flex;
4595
+ width: 28px;
4596
+ height: 28px;
4597
+ align-items: center;
4598
+ justify-content: center;
4599
+ border: 1px solid var(--ow-border);
4600
+ border-radius: 50%;
4601
+ background: var(--ow-surface-muted);
4602
+ color: var(--ow-text-soft);
4603
+ }
4604
+
4605
+ .ow-notification__body {
4606
+ display: grid;
4607
+ min-width: 0;
4608
+ flex: 1;
4609
+ gap: var(--ow-space-md);
4610
+ }
4611
+
4612
+ .ow-notification__main {
4613
+ display: grid;
4614
+ gap: 2px;
4615
+ border: 0;
4616
+ background: none;
4617
+ padding: 0;
4618
+ color: inherit;
4619
+ font: inherit;
4620
+ text-align: start;
4621
+ text-decoration: none;
4622
+ cursor: pointer;
4623
+ outline: none;
4624
+ }
4625
+
4626
+ .ow-notification__main::after {
4627
+ content: "";
4628
+ position: absolute;
4629
+ inset: 0;
4630
+ border-radius: inherit;
4631
+ }
4632
+
4633
+ .ow-notification__main:focus-visible::after {
4634
+ outline: 2px solid var(--ow-focus-ring);
4635
+ outline-offset: -2px;
4636
+ }
4637
+
4638
+ .ow-notification--unread .ow-notification__title {
4639
+ color: var(--ow-text);
4640
+ font-weight: var(--ow-weight-strong);
4641
+ }
4642
+
4643
+ .ow-notification__description {
4644
+ display: -webkit-box;
4645
+ overflow: hidden;
4646
+ -webkit-box-orient: vertical;
4647
+ -webkit-line-clamp: 2;
4648
+ }
4649
+
4650
+ .ow-notification__time {
4651
+ color: var(--ow-text-muted);
4652
+ font-size: 12px;
3838
4653
  }
3839
4654
 
3840
- .ow-popover {
3841
- z-index: 60;
3842
- display: grid;
3843
- gap: var(--ow-space-md);
3844
- overflow: auto;
3845
- border: 1px solid var(--ow-border);
3846
- border-radius: var(--ow-radius-container);
3847
- background: var(--ow-surface);
3848
- padding: var(--ow-space-xl);
3849
- color: var(--ow-text);
3850
- font-family: var(--ow-font-sans);
3851
- font-size: 14px;
3852
- line-height: 1.45;
3853
- box-shadow: var(--ow-shadow-menu);
3854
- outline: none;
4655
+ /* Actions and the ✕ sit above the stretched link, so they take their own clicks. */
4656
+ .ow-notification__actions,
4657
+ .ow-notification__dismiss {
4658
+ position: relative;
4659
+ z-index: 1;
3855
4660
  }
3856
4661
 
3857
- /* Children may shrink to the popover's width instead of pushing past it. */
3858
- .ow-popover > * {
3859
- min-width: 0;
4662
+ .ow-notification__actions {
4663
+ display: flex;
4664
+ flex-wrap: wrap;
4665
+ gap: var(--ow-space-sm);
3860
4666
  }
3861
4667
 
3862
- .ow-popover__title {
3863
- font-size: 14px;
3864
- font-weight: var(--ow-weight-emphasis);
3865
- line-height: 1.3;
4668
+ .ow-notification__dismiss {
4669
+ flex-shrink: 0;
4670
+ margin: -4px 0;
4671
+ }
4672
+
4673
+ @media (prefers-reduced-motion: reduce) {
4674
+ .ow-notification {
4675
+ transition: none;
4676
+ }
3866
4677
  }
3867
4678
 
3868
4679
  /* components/Tour/Tour.css */
@@ -6117,6 +6928,25 @@
6117
6928
  white-space: nowrap;
6118
6929
  }
6119
6930
 
6931
+ /* components/QRCode/QRCode.css */
6932
+ /* QRCode: near black on near white in both themes, since scanners need a light ground and strong contrast. */
6933
+ .ow-qr-code {
6934
+ display: block;
6935
+ flex: none;
6936
+ max-width: 100%;
6937
+ height: auto;
6938
+ forced-color-adjust: none;
6939
+ print-color-adjust: exact;
6940
+ }
6941
+
6942
+ .ow-qr-code__ground {
6943
+ fill: var(--ow-gray-50);
6944
+ }
6945
+
6946
+ .ow-qr-code__modules {
6947
+ fill: var(--ow-gray-950);
6948
+ }
6949
+
6120
6950
  /* components/Image/Image.css */
6121
6951
  /* 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
6122
6952
  AspectRatio and the image fills it. */
@@ -6197,6 +7027,170 @@
6197
7027
  line-height: 1.4;
6198
7028
  }
6199
7029
 
7030
+ /* components/MediaPlayer/MediaPlayer.css */
7031
+ /* MediaPlayer: audio is a bar of controls; video is the picture, with the same bar floating over its foot. */
7032
+ .ow-media {
7033
+ position: relative;
7034
+ container-type: inline-size;
7035
+ border-radius: var(--ow-radius-container);
7036
+ color: var(--ow-text);
7037
+ font-family: var(--ow-font-sans);
7038
+ }
7039
+
7040
+ .ow-media:focus-visible {
7041
+ outline: 2px solid var(--ow-focus-ring);
7042
+ outline-offset: 2px;
7043
+ }
7044
+
7045
+ .ow-media--audio {
7046
+ display: grid;
7047
+ gap: var(--ow-space-2xs);
7048
+ border: 1px solid var(--ow-border);
7049
+ background: var(--ow-surface);
7050
+ padding: var(--ow-space-xs);
7051
+ }
7052
+
7053
+ .ow-media--audio .ow-media__element {
7054
+ display: none;
7055
+ }
7056
+
7057
+ .ow-media__title {
7058
+ overflow: hidden;
7059
+ padding: var(--ow-space-2xs) var(--ow-space-xs) 0;
7060
+ font-size: 14px;
7061
+ font-weight: var(--ow-weight-emphasis);
7062
+ text-overflow: ellipsis;
7063
+ white-space: nowrap;
7064
+ }
7065
+
7066
+ .ow-media--video {
7067
+ overflow: hidden;
7068
+ background: var(--ow-gray-950);
7069
+ }
7070
+
7071
+ /* Letterboxed, never cropped. */
7072
+ .ow-media__screen > .ow-media__element {
7073
+ object-fit: contain;
7074
+ cursor: pointer;
7075
+ }
7076
+
7077
+ .ow-media__controls {
7078
+ display: flex;
7079
+ align-items: center;
7080
+ gap: var(--ow-space-2xs);
7081
+ min-width: 0;
7082
+ }
7083
+
7084
+ .ow-media--video .ow-media__controls {
7085
+ position: absolute;
7086
+ inset-inline: var(--ow-space-sm);
7087
+ bottom: var(--ow-space-sm);
7088
+ border: 1px solid var(--ow-border);
7089
+ border-radius: var(--ow-radius-lg);
7090
+ background: var(--ow-surface);
7091
+ padding: var(--ow-space-2xs);
7092
+ box-shadow: var(--ow-shadow-menu);
7093
+ transition: opacity var(--ow-duration-base) var(--ow-ease-standard);
7094
+ }
7095
+
7096
+ /* Playing and left alone: the controls fade out (still reachable with Tab, which brings them back) and so does the pointer. */
7097
+ .ow-media--idle {
7098
+ cursor: none;
7099
+ }
7100
+
7101
+ .ow-media--idle .ow-media__controls {
7102
+ opacity: 0;
7103
+ pointer-events: none;
7104
+ }
7105
+
7106
+ /* Captions rise above the controls while they show (Chromium and Safari let the page move them). */
7107
+ .ow-media__element::-webkit-media-text-track-container {
7108
+ transition: transform var(--ow-duration-base) var(--ow-ease-standard);
7109
+ }
7110
+
7111
+ .ow-media--video:not(.ow-media--idle) .ow-media__element::-webkit-media-text-track-container {
7112
+ transform: translateY(-56px);
7113
+ }
7114
+
7115
+ /* The timeline reads left to right in every language, as players do; the loaded part is a shade darker than the rest. */
7116
+ .ow-media__seek {
7117
+ flex: 1;
7118
+ min-width: 48px;
7119
+ direction: ltr;
7120
+ }
7121
+
7122
+ .ow-media__seek .ow-slider__track {
7123
+ background: linear-gradient(to right, var(--ow-border-strong) var(--ow-media-buffered), var(--ow-meter-track) 0);
7124
+ }
7125
+
7126
+ .ow-media__volume {
7127
+ width: 72px;
7128
+ }
7129
+
7130
+ .ow-media__time {
7131
+ padding-inline: var(--ow-space-2xs);
7132
+ color: var(--ow-text-muted);
7133
+ font-size: 12px;
7134
+ font-variant-numeric: tabular-nums;
7135
+ white-space: nowrap;
7136
+ }
7137
+
7138
+ .ow-media__rate {
7139
+ min-width: 44px;
7140
+ font-variant-numeric: tabular-nums;
7141
+ }
7142
+
7143
+ .ow-media__controls [aria-pressed="true"],
7144
+ .ow-media__on {
7145
+ background: var(--ow-surface-muted);
7146
+ color: var(--ow-primary-text);
7147
+ }
7148
+
7149
+ .ow-media__blank {
7150
+ display: block;
7151
+ width: 15px;
7152
+ height: 15px;
7153
+ }
7154
+
7155
+ .ow-media--fullscreen {
7156
+ display: flex;
7157
+ align-items: center;
7158
+ border-radius: 0;
7159
+ }
7160
+
7161
+ /* AspectRatio sets its ratio inline; full screen, the picture takes the whole screen instead. */
7162
+ .ow-media--fullscreen .ow-media__screen {
7163
+ height: 100%;
7164
+ aspect-ratio: auto !important;
7165
+ }
7166
+
7167
+ @container (max-width: 440px) {
7168
+ .ow-media__volume,
7169
+ .ow-media__pip {
7170
+ display: none;
7171
+ }
7172
+ }
7173
+
7174
+ /* On a phone the device's buttons set the volume; M still mutes. */
7175
+ @container (max-width: 360px) {
7176
+ .ow-media--video .ow-media__mute {
7177
+ display: none;
7178
+ }
7179
+ }
7180
+
7181
+ @container (max-width: 240px) {
7182
+ .ow-media__time {
7183
+ display: none;
7184
+ }
7185
+ }
7186
+
7187
+ @media (prefers-reduced-motion: reduce) {
7188
+ .ow-media__controls,
7189
+ .ow-media__element::-webkit-media-text-track-container {
7190
+ transition: none !important;
7191
+ }
7192
+ }
7193
+
6200
7194
  /* components/Kbd/Kbd.css */
6201
7195
  /* Kbd and inline Code, both in the mono face. */
6202
7196
  .ow-kbd {
@@ -6426,6 +7420,159 @@
6426
7420
  transform: none;
6427
7421
  }
6428
7422
 
7423
+ /* components/DiffViewer/DiffViewer.css */
7424
+ /* DiffViewer: a code block's ground and header (it uses CodeBlock's classes), with a table of lines tinted from the
7425
+ success and danger colours. The code block is dark in both themes, so the tints are too. */
7426
+ .ow-diff {
7427
+ --ow-diff-add: var(--ow-success-solid);
7428
+ --ow-diff-del: var(--ow-danger-solid);
7429
+ display: grid;
7430
+ min-width: 0;
7431
+ gap: var(--ow-space-md);
7432
+ }
7433
+
7434
+ .ow-diff__counts {
7435
+ font-family: var(--ow-font-mono);
7436
+ font-size: 12px;
7437
+ white-space: nowrap;
7438
+ }
7439
+
7440
+ /* Signs and counts are lifted toward the text colour so they read on the tints. */
7441
+ .ow-diff__added,
7442
+ .ow-diff__add > .ow-diff__sign {
7443
+ color: color-mix(in srgb, var(--ow-diff-add) 60%, var(--ow-on-code-block));
7444
+ }
7445
+
7446
+ .ow-diff__removed,
7447
+ .ow-diff__del > .ow-diff__sign {
7448
+ color: color-mix(in srgb, var(--ow-diff-del) 60%, var(--ow-on-code-block));
7449
+ }
7450
+
7451
+ .ow-diff__scroll {
7452
+ overflow: auto;
7453
+ }
7454
+
7455
+ .ow-diff__scroll:focus-visible {
7456
+ outline: 2px solid var(--ow-brand-300);
7457
+ outline-offset: -2px;
7458
+ }
7459
+
7460
+ .ow-diff__table {
7461
+ min-width: 100%;
7462
+ border-collapse: collapse;
7463
+ font-family: var(--ow-font-mono);
7464
+ font-size: 13px;
7465
+ line-height: 1.6;
7466
+ tab-size: 4;
7467
+ }
7468
+
7469
+ .ow-diff__table--wrap {
7470
+ width: 100%;
7471
+ table-layout: fixed;
7472
+ }
7473
+
7474
+ /* Cells have no padding of their own; the classes below add it. */
7475
+ :where(.ow-diff__table td) {
7476
+ padding: 0;
7477
+ vertical-align: top;
7478
+ }
7479
+
7480
+ .ow-diff__num-col {
7481
+ width: calc(var(--ow-diff-digits) * 1ch + 20px);
7482
+ }
7483
+
7484
+ .ow-diff__num {
7485
+ padding-inline: 10px;
7486
+ color: var(--ow-on-code-block-muted);
7487
+ text-align: right;
7488
+ user-select: none;
7489
+ }
7490
+
7491
+ /* The sign hangs in the margin, so wrapped lines line up under the code. */
7492
+ .ow-diff__code {
7493
+ padding: 0 var(--ow-space-lg) 0 calc(var(--ow-space-sm) + 2ch);
7494
+ text-indent: -2ch;
7495
+ white-space: pre;
7496
+ }
7497
+
7498
+ .ow-diff__table--wrap .ow-diff__code {
7499
+ overflow-wrap: anywhere;
7500
+ white-space: pre-wrap;
7501
+ }
7502
+
7503
+ .ow-diff__code:focus {
7504
+ outline: none;
7505
+ }
7506
+
7507
+ .ow-diff__sign {
7508
+ display: inline-block;
7509
+ width: 2ch;
7510
+ text-indent: 0;
7511
+ user-select: none;
7512
+ }
7513
+
7514
+ .ow-diff__add {
7515
+ background: color-mix(in srgb, var(--ow-diff-add) 14%, transparent);
7516
+ }
7517
+
7518
+ .ow-diff__del {
7519
+ background: color-mix(in srgb, var(--ow-diff-del) 14%, transparent);
7520
+ }
7521
+
7522
+ .ow-diff__word {
7523
+ border-radius: 2px;
7524
+ background: color-mix(in srgb, var(--ow-diff-add) 34%, transparent);
7525
+ }
7526
+
7527
+ .ow-diff__del .ow-diff__word {
7528
+ background: color-mix(in srgb, var(--ow-diff-del) 34%, transparent);
7529
+ }
7530
+
7531
+ .ow-diff__empty {
7532
+ background: color-mix(in srgb, var(--ow-on-code-block) 3%, transparent);
7533
+ }
7534
+
7535
+ .ow-diff__table--split .ow-diff__num:nth-child(3) {
7536
+ border-left: 1px solid color-mix(in srgb, var(--ow-on-code-block) 8%, transparent);
7537
+ }
7538
+
7539
+ .ow-diff__hunk > td,
7540
+ .ow-diff__gap > td {
7541
+ background: color-mix(in srgb, var(--ow-on-code-block) 5%, transparent);
7542
+ color: var(--ow-on-code-block-muted);
7543
+ }
7544
+
7545
+ .ow-diff__hunk > td {
7546
+ padding: 2px var(--ow-space-lg);
7547
+ white-space: pre;
7548
+ }
7549
+
7550
+ .ow-diff__expand {
7551
+ display: flex;
7552
+ width: 100%;
7553
+ min-height: 28px;
7554
+ align-items: center;
7555
+ gap: var(--ow-space-sm);
7556
+ border: 0;
7557
+ background: transparent;
7558
+ padding: 0 var(--ow-space-lg);
7559
+ color: inherit;
7560
+ font: inherit;
7561
+ font-family: var(--ow-font-sans);
7562
+ font-size: 12px;
7563
+ cursor: pointer;
7564
+ }
7565
+
7566
+ .ow-diff__expand:hover {
7567
+ background: color-mix(in srgb, var(--ow-on-code-block) 6%, transparent);
7568
+ color: var(--ow-on-code-block);
7569
+ }
7570
+
7571
+ .ow-diff__expand:focus-visible {
7572
+ outline: 2px solid var(--ow-brand-300);
7573
+ outline-offset: -2px;
7574
+ }
7575
+
6429
7576
  /* components/Tag/Tag.css */
6430
7577
  /* Tag, TagGroup and ColorSwatch. */
6431
7578
  .ow-tag-group {
@@ -6572,6 +7719,125 @@
6572
7719
  font-size: 12px;
6573
7720
  }
6574
7721
 
7722
+ /* components/SortableList/SortableList.css */
7723
+ /* SortableList: rows (or chips, in a row) people put in order. The picked-up one lifts; the others slide aside. */
7724
+ .ow-sortable {
7725
+ display: flex;
7726
+ flex-direction: column;
7727
+ gap: var(--ow-space-xs);
7728
+ margin: 0;
7729
+ padding: 0;
7730
+ list-style: none;
7731
+ }
7732
+
7733
+ .ow-sortable--horizontal {
7734
+ flex-direction: row;
7735
+ overflow-x: auto;
7736
+ padding-block: var(--ow-space-2xs);
7737
+ }
7738
+
7739
+ .ow-sortable__item {
7740
+ position: relative;
7741
+ display: flex;
7742
+ flex: none;
7743
+ min-height: 40px;
7744
+ align-items: center;
7745
+ gap: var(--ow-space-xs);
7746
+ padding: var(--ow-space-xs) var(--ow-space-lg);
7747
+ border: 1px solid var(--ow-border);
7748
+ border-radius: var(--ow-radius-md);
7749
+ background: var(--ow-surface);
7750
+ color: var(--ow-text);
7751
+ font-size: 14px;
7752
+ outline: none;
7753
+ }
7754
+
7755
+ .ow-sortable--horizontal .ow-sortable__item {
7756
+ min-height: 32px;
7757
+ padding-block: var(--ow-space-2xs);
7758
+ }
7759
+
7760
+ .ow-sortable__content {
7761
+ flex: 1;
7762
+ min-width: 0;
7763
+ }
7764
+
7765
+ /* Whatever picks it up: the row, or its grip. Touch drags it rather than scrolling the page. */
7766
+ .ow-sortable__item--row,
7767
+ .ow-sortable__handle {
7768
+ cursor: grab;
7769
+ touch-action: none;
7770
+ user-select: none;
7771
+ -webkit-user-select: none;
7772
+ }
7773
+
7774
+ .ow-sortable__handle {
7775
+ display: inline-flex;
7776
+ width: 24px;
7777
+ height: 28px;
7778
+ flex: none;
7779
+ align-items: center;
7780
+ justify-content: center;
7781
+ margin-inline-start: calc(var(--ow-space-xs) * -1);
7782
+ padding: 0;
7783
+ border: 0;
7784
+ border-radius: var(--ow-radius-md);
7785
+ background: none;
7786
+ color: var(--ow-icon);
7787
+ }
7788
+
7789
+ .ow-sortable__handle:hover {
7790
+ background: var(--ow-hover);
7791
+ color: var(--ow-text-muted);
7792
+ }
7793
+
7794
+ .ow-sortable--horizontal .ow-sortable__grip {
7795
+ rotate: 90deg;
7796
+ }
7797
+
7798
+ .ow-sortable__item--row:focus-visible,
7799
+ .ow-sortable__handle:focus-visible {
7800
+ outline: 2px solid var(--ow-focus-ring);
7801
+ outline-offset: 1px;
7802
+ }
7803
+
7804
+ /* While one is picked up, the others slide to make room. */
7805
+ .ow-sortable--dragging .ow-sortable__item {
7806
+ transition: transform var(--ow-duration-base) var(--ow-ease-standard);
7807
+ }
7808
+
7809
+ .ow-sortable .ow-sortable__item--dragging {
7810
+ z-index: 1;
7811
+ border-color: var(--ow-border-strong);
7812
+ box-shadow: var(--ow-shadow-menu);
7813
+ transition: none;
7814
+ }
7815
+
7816
+ :root[data-ow-sortable-drag],
7817
+ :root[data-ow-sortable-drag] * {
7818
+ cursor: grabbing !important;
7819
+ user-select: none;
7820
+ -webkit-user-select: none;
7821
+ }
7822
+
7823
+ .ow-sortable--disabled .ow-sortable__item {
7824
+ background: var(--ow-surface-muted);
7825
+ color: var(--ow-text-muted);
7826
+ cursor: default;
7827
+ }
7828
+
7829
+ .ow-sortable--disabled .ow-sortable__handle {
7830
+ background: none;
7831
+ color: var(--ow-text-disabled);
7832
+ cursor: not-allowed;
7833
+ }
7834
+
7835
+ @media (prefers-reduced-motion: reduce) {
7836
+ .ow-sortable--dragging .ow-sortable__item {
7837
+ transition: none;
7838
+ }
7839
+ }
7840
+
6575
7841
  /* components/Table/Table.css */
6576
7842
  /* Table: a bordered card with a quiet header row and hairlines between rows. */
6577
7843
  .ow-table-wrap {
@@ -7433,111 +8699,346 @@
7433
8699
  }
7434
8700
  }
7435
8701
 
7436
- @media (forced-colors: active) {
7437
- .ow-chart__line,
7438
- .ow-sparkline__line {
7439
- stroke: CanvasText;
7440
- }
8702
+ @media (forced-colors: active) {
8703
+ .ow-chart__line,
8704
+ .ow-sparkline__line {
8705
+ stroke: CanvasText;
8706
+ }
8707
+ }
8708
+
8709
+ /* components/ActivityHeatmap/ActivityHeatmap.css */
8710
+ /* ActivityHeatmap: a square per day, shaded from the empty track to one chart colour, so the shades follow the theme. */
8711
+ .ow-heatmap {
8712
+ --ow-heatmap-cell: 12px;
8713
+ display: grid;
8714
+ min-width: 0;
8715
+ gap: var(--ow-space-xs);
8716
+ color: var(--ow-text-muted);
8717
+ font-size: 11.5px;
8718
+ line-height: 1;
8719
+ }
8720
+
8721
+ /* It scrolls sideways inside itself on a narrow screen, never the page. */
8722
+ .ow-heatmap__scroll {
8723
+ min-width: 0;
8724
+ overflow-x: auto;
8725
+ overscroll-behavior-x: contain;
8726
+ }
8727
+
8728
+ /* The spacing round the edge leaves room for the focus ring. */
8729
+ .ow-heatmap__grid {
8730
+ border-collapse: separate;
8731
+ border-spacing: max(3px, calc(var(--ow-heatmap-cell) / 4));
8732
+ }
8733
+
8734
+ .ow-heatmap__grid th,
8735
+ .ow-heatmap__grid td {
8736
+ padding: 0;
8737
+ }
8738
+
8739
+ .ow-heatmap__grid th {
8740
+ font-weight: var(--ow-weight-regular);
8741
+ text-align: start;
8742
+ white-space: nowrap;
8743
+ }
8744
+
8745
+ /* A month's name starts over its first week and runs on over the next, without widening the columns. */
8746
+ .ow-heatmap__month {
8747
+ position: relative;
8748
+ height: 1.3em;
8749
+ }
8750
+
8751
+ .ow-heatmap__month span {
8752
+ position: absolute;
8753
+ inset-inline-start: 0;
8754
+ top: 0;
8755
+ }
8756
+
8757
+ .ow-heatmap__grid .ow-heatmap__weekday {
8758
+ padding-inline-end: 4px;
8759
+ font-size: 11px;
8760
+ }
8761
+
8762
+ .ow-heatmap__cell {
8763
+ width: var(--ow-heatmap-cell);
8764
+ height: var(--ow-heatmap-cell);
8765
+ border-radius: 3px;
8766
+ }
8767
+
8768
+ .ow-heatmap__day {
8769
+ display: block;
8770
+ width: var(--ow-heatmap-cell);
8771
+ height: var(--ow-heatmap-cell);
8772
+ border: 0;
8773
+ border-radius: 3px;
8774
+ background: color-mix(in oklab, var(--ow-heatmap-color) var(--ow-heatmap-mix, 0%), var(--ow-meter-track));
8775
+ padding: 0;
8776
+ }
8777
+
8778
+ button.ow-heatmap__day {
8779
+ cursor: pointer;
8780
+ }
8781
+
8782
+ .ow-heatmap__cell:hover > .ow-heatmap__day {
8783
+ box-shadow: inset 0 0 0 1px var(--ow-text-muted);
8784
+ }
8785
+
8786
+ .ow-heatmap [data-date]:focus {
8787
+ outline: none;
8788
+ }
8789
+
8790
+ .ow-heatmap [data-date]:focus-visible {
8791
+ outline: 2px solid var(--ow-focus-ring);
8792
+ outline-offset: 1px;
8793
+ }
8794
+
8795
+ .ow-heatmap__legend {
8796
+ display: flex;
8797
+ align-items: center;
8798
+ justify-content: flex-end;
8799
+ gap: calc(var(--ow-heatmap-cell) / 4);
8800
+ }
8801
+
8802
+ .ow-heatmap__legend > :first-child {
8803
+ margin-inline-start: 4px;
8804
+ }
8805
+
8806
+ .ow-heatmap__legend > :last-child {
8807
+ margin-inline-end: 4px;
8808
+ }
8809
+
8810
+ @media (forced-colors: active) {
8811
+ .ow-heatmap__day {
8812
+ forced-color-adjust: none;
8813
+ }
8814
+ }
8815
+
8816
+ /* components/FileTree/FileTree.css */
8817
+ /* FileTree: a project structure explorer. Monospace names, hairline guides, a tinted selected file. */
8818
+ .ow-tree,
8819
+ .ow-tree__group {
8820
+ margin: 0;
8821
+ padding: 0;
8822
+ list-style: none;
8823
+ }
8824
+
8825
+ .ow-tree {
8826
+ display: grid;
8827
+ gap: 1px;
8828
+ color: var(--ow-text);
8829
+ }
8830
+
8831
+ .ow-tree__group {
8832
+ display: grid;
8833
+ gap: 1px;
8834
+ margin-left: 15px;
8835
+ border-left: 1px solid var(--ow-border);
8836
+ padding-left: var(--ow-space-sm);
8837
+ }
8838
+
8839
+ .ow-tree__item {
8840
+ outline: none;
8841
+ }
8842
+
8843
+ .ow-tree__row {
8844
+ display: flex;
8845
+ min-height: 32px;
8846
+ align-items: center;
8847
+ gap: var(--ow-space-xs);
8848
+ border-radius: var(--ow-radius-form);
8849
+ padding: var(--ow-space-2xs) var(--ow-space-sm);
8850
+ cursor: pointer;
8851
+ transition: background-color var(--ow-duration-fast) var(--ow-ease-standard);
8852
+ }
8853
+
8854
+ .ow-tree__row:hover {
8855
+ background: var(--ow-surface-muted);
8856
+ }
8857
+
8858
+ .ow-tree__item:focus-visible > .ow-tree__row {
8859
+ box-shadow: 0 0 0 2px var(--ow-focus-ring);
8860
+ }
8861
+
8862
+ .ow-tree__row--selected,
8863
+ .ow-tree__row--selected:hover {
8864
+ background: var(--ow-primary-subtle);
8865
+ color: var(--ow-primary-text);
8866
+ }
8867
+
8868
+ .ow-tree__chevron {
8869
+ flex-shrink: 0;
8870
+ color: var(--ow-text-muted);
8871
+ transition: transform var(--ow-duration-base) var(--ow-ease-standard);
8872
+ }
8873
+
8874
+ .ow-tree__chevron--open {
8875
+ transform: rotate(90deg);
8876
+ }
8877
+
8878
+ .ow-tree__spacer {
8879
+ width: 14px;
8880
+ flex-shrink: 0;
8881
+ }
8882
+
8883
+ .ow-tree__icon {
8884
+ display: inline-flex;
8885
+ flex-shrink: 0;
8886
+ color: var(--ow-text-muted);
8887
+ }
8888
+
8889
+ .ow-tree__icon--folder {
8890
+ color: var(--ow-primary-text);
8891
+ }
8892
+
8893
+ .ow-tree__row--selected .ow-tree__icon {
8894
+ color: inherit;
8895
+ }
8896
+
8897
+ .ow-tree__name {
8898
+ min-width: 0;
8899
+ flex: 1;
8900
+ overflow: hidden;
8901
+ font-family: var(--ow-font-mono);
8902
+ font-size: 13px;
8903
+ text-overflow: ellipsis;
8904
+ white-space: nowrap;
8905
+ }
8906
+
8907
+ .ow-tree__meta {
8908
+ flex-shrink: 0;
8909
+ color: var(--ow-text-muted);
8910
+ font-family: var(--ow-font-mono);
8911
+ font-size: 12px;
7441
8912
  }
7442
8913
 
7443
- /* components/FileTree/FileTree.css */
7444
- /* FileTree: a project structure explorer. Monospace names, hairline guides, a tinted selected file. */
7445
- .ow-tree,
7446
- .ow-tree__group {
8914
+ /* components/TreeView/TreeView.css */
8915
+ /* TreeView: rows that open, select and check. FileTree's hairline guides, NavList's 14px text. */
8916
+ .ow-treeview,
8917
+ .ow-treeview__group {
8918
+ display: grid;
8919
+ gap: 1px;
7447
8920
  margin: 0;
7448
8921
  padding: 0;
7449
8922
  list-style: none;
7450
8923
  }
7451
8924
 
7452
- .ow-tree {
7453
- display: grid;
7454
- gap: 1px;
8925
+ .ow-treeview {
7455
8926
  color: var(--ow-text);
8927
+ font-size: 14px;
7456
8928
  }
7457
8929
 
7458
- .ow-tree__group {
7459
- display: grid;
7460
- gap: 1px;
7461
- margin-left: 15px;
7462
- border-left: 1px solid var(--ow-border);
7463
- padding-left: var(--ow-space-sm);
8930
+ /* The guide runs under the parent's chevron. */
8931
+ .ow-treeview__group {
8932
+ margin-inline-start: 14px;
8933
+ border-inline-start: 1px solid var(--ow-border);
8934
+ padding-inline-start: var(--ow-space-2xs);
7464
8935
  }
7465
8936
 
7466
- .ow-tree__item {
8937
+ .ow-treeview__item {
7467
8938
  outline: none;
7468
8939
  }
7469
8940
 
7470
- .ow-tree__row {
8941
+ .ow-treeview__row {
7471
8942
  display: flex;
7472
8943
  min-height: 32px;
7473
8944
  align-items: center;
7474
8945
  gap: var(--ow-space-xs);
7475
8946
  border-radius: var(--ow-radius-form);
7476
- padding: var(--ow-space-2xs) var(--ow-space-sm);
8947
+ padding-block: var(--ow-space-2xs);
8948
+ padding-inline: var(--ow-space-2xs) var(--ow-space-sm);
7477
8949
  cursor: pointer;
8950
+ user-select: none;
7478
8951
  transition: background-color var(--ow-duration-fast) var(--ow-ease-standard);
7479
8952
  }
7480
8953
 
7481
- .ow-tree__row:hover {
8954
+ .ow-treeview__row:hover {
7482
8955
  background: var(--ow-surface-muted);
7483
8956
  }
7484
8957
 
7485
- .ow-tree__item:focus-visible > .ow-tree__row {
8958
+ .ow-treeview__item:focus-visible > .ow-treeview__row {
7486
8959
  box-shadow: 0 0 0 2px var(--ow-focus-ring);
7487
8960
  }
7488
8961
 
7489
- .ow-tree__row--selected,
7490
- .ow-tree__row--selected:hover {
8962
+ .ow-treeview__row--selected,
8963
+ .ow-treeview__row--selected:hover {
7491
8964
  background: var(--ow-primary-subtle);
7492
8965
  color: var(--ow-primary-text);
7493
8966
  }
7494
8967
 
7495
- .ow-tree__chevron {
8968
+ .ow-treeview__row--disabled,
8969
+ .ow-treeview__row--loading {
8970
+ color: var(--ow-text-muted);
8971
+ cursor: default;
8972
+ }
8973
+
8974
+ .ow-treeview__toggle {
8975
+ display: inline-flex;
8976
+ width: 20px;
8977
+ height: 24px;
7496
8978
  flex-shrink: 0;
8979
+ align-items: center;
8980
+ justify-content: center;
7497
8981
  color: var(--ow-text-muted);
8982
+ }
8983
+
8984
+ .ow-treeview__toggle svg {
7498
8985
  transition: transform var(--ow-duration-base) var(--ow-ease-standard);
7499
8986
  }
7500
8987
 
7501
- .ow-tree__chevron--open {
8988
+ .ow-treeview__toggle:dir(rtl) svg {
8989
+ transform: scaleX(-1);
8990
+ }
8991
+
8992
+ [aria-expanded="true"] > .ow-treeview__row .ow-treeview__toggle svg {
7502
8993
  transform: rotate(90deg);
7503
8994
  }
7504
8995
 
7505
- .ow-tree__spacer {
7506
- width: 14px;
7507
- flex-shrink: 0;
8996
+ .ow-treeview .ow-checkbox__input {
8997
+ pointer-events: none;
7508
8998
  }
7509
8999
 
7510
- .ow-tree__icon {
9000
+ .ow-treeview__icon {
7511
9001
  display: inline-flex;
7512
9002
  flex-shrink: 0;
7513
9003
  color: var(--ow-text-muted);
7514
9004
  }
7515
9005
 
7516
- .ow-tree__icon--folder {
7517
- color: var(--ow-primary-text);
7518
- }
7519
-
7520
- .ow-tree__row--selected .ow-tree__icon {
7521
- color: inherit;
7522
- }
7523
-
7524
- .ow-tree__name {
9006
+ .ow-treeview__text {
9007
+ display: grid;
7525
9008
  min-width: 0;
7526
9009
  flex: 1;
9010
+ }
9011
+
9012
+ .ow-treeview__label,
9013
+ .ow-treeview__description {
7527
9014
  overflow: hidden;
7528
- font-family: var(--ow-font-mono);
7529
- font-size: 13px;
7530
9015
  text-overflow: ellipsis;
7531
9016
  white-space: nowrap;
7532
9017
  }
7533
9018
 
7534
- .ow-tree__meta {
7535
- flex-shrink: 0;
9019
+ .ow-treeview__description,
9020
+ .ow-treeview__end {
7536
9021
  color: var(--ow-text-muted);
7537
- font-family: var(--ow-font-mono);
7538
9022
  font-size: 12px;
7539
9023
  }
7540
9024
 
9025
+ .ow-treeview__end {
9026
+ flex-shrink: 0;
9027
+ }
9028
+
9029
+ .ow-treeview__row--selected :is(.ow-treeview__icon, .ow-treeview__description, .ow-treeview__end) {
9030
+ color: inherit;
9031
+ }
9032
+
9033
+ .ow-treeview__row--error {
9034
+ color: var(--ow-danger-text);
9035
+ }
9036
+
9037
+ .ow-treeview__retry {
9038
+ font-weight: var(--ow-weight-emphasis);
9039
+ text-decoration: underline;
9040
+ }
9041
+
7541
9042
  /* components/EmptyState/EmptyState.css */
7542
9043
  /* EmptyState: centred, at most 360px of text, an icon tile above. */
7543
9044
  .ow-empty {
@@ -7748,6 +9249,148 @@
7748
9249
  font-weight: var(--ow-weight-regular);
7749
9250
  }
7750
9251
 
9252
+ /* components/NavigationMenu/NavigationMenu.css */
9253
+ /* NavigationMenu: a site's top links, with panels of links on Popover's surface. Rules are scoped under
9254
+ .ow-navigation-menu so SiteHeader's `nav a` colours don't reach into the panels. */
9255
+ .ow-navigation-menu {
9256
+ min-width: 0;
9257
+ font-family: var(--ow-font-sans);
9258
+ }
9259
+
9260
+ .ow-navigation-menu__list {
9261
+ display: flex;
9262
+ flex-wrap: wrap;
9263
+ align-items: center;
9264
+ gap: var(--ow-space-2xs);
9265
+ margin: 0;
9266
+ padding: 0;
9267
+ list-style: none;
9268
+ }
9269
+
9270
+ .ow-navigation-menu .ow-navigation-menu__trigger {
9271
+ display: inline-flex;
9272
+ min-height: 32px;
9273
+ align-items: center;
9274
+ gap: var(--ow-space-3xs);
9275
+ border: 0;
9276
+ border-radius: var(--ow-radius-pill);
9277
+ background: transparent;
9278
+ padding: 0 var(--ow-space-sm);
9279
+ color: var(--ow-text-soft);
9280
+ font: inherit;
9281
+ font-size: 14px;
9282
+ font-weight: var(--ow-weight-control);
9283
+ text-decoration: none;
9284
+ cursor: pointer;
9285
+ transition-property: color, background-color;
9286
+ transition-duration: var(--ow-duration-base);
9287
+ transition-timing-function: var(--ow-ease-standard);
9288
+ }
9289
+
9290
+ .ow-navigation-menu .ow-navigation-menu__trigger:hover,
9291
+ .ow-navigation-menu__trigger[aria-expanded="true"] {
9292
+ background: var(--ow-hover);
9293
+ color: var(--ow-text);
9294
+ }
9295
+
9296
+ .ow-navigation-menu__trigger[aria-current="page"],
9297
+ .ow-navigation-menu__trigger[data-active] {
9298
+ color: var(--ow-text);
9299
+ }
9300
+
9301
+ .ow-navigation-menu .ow-navigation-menu__trigger:focus-visible,
9302
+ .ow-navigation-menu .ow-navigation-menu__link:focus-visible {
9303
+ outline: 2px solid var(--ow-focus-ring);
9304
+ outline-offset: -2px;
9305
+ }
9306
+
9307
+ .ow-navigation-menu__chevron {
9308
+ color: var(--ow-text-muted);
9309
+ transition: transform var(--ow-duration-base) var(--ow-ease-standard);
9310
+ }
9311
+
9312
+ [aria-expanded="true"] > .ow-navigation-menu__chevron {
9313
+ transform: rotate(180deg);
9314
+ }
9315
+
9316
+ .ow-navigation-menu__panel {
9317
+ grid-template-columns: repeat(var(--ow-navigation-menu-columns), minmax(0, 15rem));
9318
+ max-width: calc(100vw - 16px);
9319
+ padding: var(--ow-space-sm);
9320
+ gap: var(--ow-space-sm);
9321
+ }
9322
+
9323
+ .ow-navigation-menu__panel--full {
9324
+ grid-template-columns: repeat(var(--ow-navigation-menu-columns), minmax(0, 1fr));
9325
+ }
9326
+
9327
+ .ow-navigation-menu__group {
9328
+ display: grid;
9329
+ align-content: start;
9330
+ gap: var(--ow-space-3xs);
9331
+ }
9332
+
9333
+ .ow-navigation-menu__group-title {
9334
+ padding: var(--ow-space-xs) var(--ow-space-sm) var(--ow-space-2xs);
9335
+ color: var(--ow-text-muted);
9336
+ font-size: 12px;
9337
+ font-weight: var(--ow-weight-label);
9338
+ }
9339
+
9340
+ .ow-navigation-menu .ow-navigation-menu__link {
9341
+ display: flex;
9342
+ align-items: flex-start;
9343
+ gap: var(--ow-space-sm);
9344
+ border-radius: var(--ow-radius-lg);
9345
+ padding: var(--ow-space-sm);
9346
+ color: var(--ow-text);
9347
+ text-decoration: none;
9348
+ transition: background-color var(--ow-duration-base) var(--ow-ease-standard);
9349
+ }
9350
+
9351
+ .ow-navigation-menu .ow-navigation-menu__link:hover,
9352
+ .ow-navigation-menu__link[aria-current="page"] {
9353
+ background: var(--ow-surface-muted);
9354
+ }
9355
+
9356
+ .ow-navigation-menu__icon {
9357
+ display: inline-flex;
9358
+ flex-shrink: 0;
9359
+ color: var(--ow-text-muted);
9360
+ }
9361
+
9362
+ .ow-navigation-menu__text {
9363
+ display: grid;
9364
+ min-width: 0;
9365
+ gap: 2px;
9366
+ }
9367
+
9368
+ .ow-navigation-menu__title {
9369
+ font-weight: var(--ow-weight-emphasis);
9370
+ line-height: 1.3;
9371
+ }
9372
+
9373
+ .ow-navigation-menu__description {
9374
+ color: var(--ow-text-muted);
9375
+ font-size: 13px;
9376
+ line-height: 1.4;
9377
+ }
9378
+
9379
+ .ow-navigation-menu .ow-navigation-menu__link--featured,
9380
+ .ow-navigation-menu .ow-navigation-menu__link--featured:hover {
9381
+ flex-direction: column;
9382
+ justify-content: flex-end;
9383
+ min-height: 9rem;
9384
+ background: var(--ow-primary-subtle);
9385
+ padding: var(--ow-space-lg);
9386
+ }
9387
+
9388
+ @media (max-width: 640px) {
9389
+ .ow-navigation-menu__panel {
9390
+ grid-template-columns: minmax(0, 1fr);
9391
+ }
9392
+ }
9393
+
7751
9394
  /* components/AppShell/AppShell.css */
7752
9395
  /* AppShell: a sidebar down the left and the page beside it. It measures its own width (a container query), so it
7753
9396
  folds into a drawer under its breakpoint (900px by default) whether it fills the window or sits in a smaller frame. */
@@ -8263,6 +9906,52 @@
8263
9906
  }
8264
9907
  }
8265
9908
 
9909
+ /* components/VirtualList/VirtualList.css */
9910
+ /* VirtualList: a scrolling list that renders only the rows in view, each placed by its offset from the top. */
9911
+ .ow-virtual-list {
9912
+ position: relative;
9913
+ display: flex;
9914
+ flex-direction: column;
9915
+ height: 100%;
9916
+ min-height: 0;
9917
+ }
9918
+
9919
+ .ow-virtual-list__scroll {
9920
+ flex: 1 1 auto;
9921
+ min-height: 0;
9922
+ overflow-x: hidden;
9923
+ overflow-y: auto;
9924
+ overscroll-behavior: contain;
9925
+ /* The list keeps its own place as rows are measured or added above; the browser's anchoring would double it. */
9926
+ overflow-anchor: none;
9927
+ border-radius: inherit;
9928
+ }
9929
+
9930
+ .ow-virtual-list__scroll:focus-visible,
9931
+ .ow-virtual-list__item:focus-visible {
9932
+ outline: 2px solid var(--ow-focus-ring);
9933
+ outline-offset: -2px;
9934
+ }
9935
+
9936
+ .ow-virtual-list__inner {
9937
+ position: relative;
9938
+ flex-shrink: 0;
9939
+ width: 100%;
9940
+ }
9941
+
9942
+ .ow-virtual-list__item {
9943
+ position: absolute;
9944
+ top: 0;
9945
+ inset-inline: 0;
9946
+ border-radius: var(--ow-radius-md);
9947
+ }
9948
+
9949
+ .ow-virtual-list__footer {
9950
+ display: flex;
9951
+ justify-content: center;
9952
+ padding: var(--ow-space-md);
9953
+ }
9954
+
8266
9955
  /* components/AspectRatio/AspectRatio.css */
8267
9956
  /* AspectRatio: a box that keeps its shape, with whatever is inside filling it. The hidden overflow keeps the ratio
8268
9957
  when the content is taller than the box would be. */
@@ -9104,6 +10793,44 @@
9104
10793
  }
9105
10794
  }
9106
10795
 
10796
+ /* components/Markdown/Markdown.css */
10797
+ /* Markdown: Prose does the typography; this is only the caret that follows a streaming answer's last character. */
10798
+ .ow-markdown__caret {
10799
+ display: inline-block;
10800
+ width: 2px;
10801
+ height: 1.15em;
10802
+ margin-inline-start: 2px;
10803
+ border-radius: 1px;
10804
+ background: currentColor;
10805
+ vertical-align: -0.2em;
10806
+ animation: ow-markdown-caret 1s var(--ow-ease-standard) infinite;
10807
+ }
10808
+
10809
+ @keyframes ow-markdown-caret {
10810
+ 0%,
10811
+ 100% {
10812
+ opacity: 0.9;
10813
+ }
10814
+ 50% {
10815
+ opacity: 0.15;
10816
+ }
10817
+ }
10818
+
10819
+ @media (prefers-reduced-motion: reduce) {
10820
+ .ow-markdown__caret {
10821
+ opacity: 0.6;
10822
+ animation: none;
10823
+ }
10824
+ }
10825
+
10826
+ /* Forced colours drop backgrounds: draw the caret in the text colour. */
10827
+ @media (forced-colors: active) {
10828
+ .ow-markdown__caret {
10829
+ forced-color-adjust: none;
10830
+ background: CanvasText;
10831
+ }
10832
+ }
10833
+
9107
10834
  /* components/TextShimmer/TextShimmer.css */
9108
10835
  /* TextShimmer: muted text with a band of full-strength text sweeping across it. */
9109
10836
  .ow-shimmer {