@openwarelabs/ui 0.14.1 → 0.15.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 (33) hide show
  1. package/README.md +5 -5
  2. package/dist/components/InlineEdit/InlineEdit.d.cts +8 -0
  3. package/dist/components/InlineEdit/InlineEdit.d.ts +8 -0
  4. package/dist/components/InlineEdit/InlineEdit.types.d.cts +74 -0
  5. package/dist/components/InlineEdit/InlineEdit.types.d.ts +74 -0
  6. package/dist/components/NavigationMenu/NavigationMenu.d.cts +14 -0
  7. package/dist/components/NavigationMenu/NavigationMenu.d.ts +14 -0
  8. package/dist/components/NavigationMenu/NavigationMenu.types.d.cts +84 -0
  9. package/dist/components/NavigationMenu/NavigationMenu.types.d.ts +84 -0
  10. package/dist/components/SortableList/SortableList.d.cts +7 -0
  11. package/dist/components/SortableList/SortableList.d.ts +7 -0
  12. package/dist/components/SortableList/SortableList.types.d.cts +82 -0
  13. package/dist/components/SortableList/SortableList.types.d.ts +82 -0
  14. package/dist/components/TreeView/TreeView.d.cts +8 -0
  15. package/dist/components/TreeView/TreeView.d.ts +8 -0
  16. package/dist/components/TreeView/TreeView.types.d.cts +88 -0
  17. package/dist/components/TreeView/TreeView.types.d.ts +88 -0
  18. package/dist/components/VirtualList/VirtualList.d.cts +9 -0
  19. package/dist/components/VirtualList/VirtualList.d.ts +9 -0
  20. package/dist/components/VirtualList/VirtualList.types.d.cts +80 -0
  21. package/dist/components/VirtualList/VirtualList.types.d.ts +80 -0
  22. package/dist/components/VirtualList/useVirtualizer.d.cts +60 -0
  23. package/dist/components/VirtualList/useVirtualizer.d.ts +60 -0
  24. package/dist/components.css +637 -0
  25. package/dist/index.cjs +2732 -1328
  26. package/dist/index.cjs.map +4 -4
  27. package/dist/index.d.cts +12 -0
  28. package/dist/index.d.ts +12 -0
  29. package/dist/index.js +2695 -1267
  30. package/dist/index.js.map +4 -4
  31. package/dist/openware-ui.iife.js +9 -8
  32. package/dist/styles.css +637 -0
  33. 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 {
@@ -6572,6 +6774,125 @@
6572
6774
  font-size: 12px;
6573
6775
  }
6574
6776
 
6777
+ /* components/SortableList/SortableList.css */
6778
+ /* SortableList: rows (or chips, in a row) people put in order. The picked-up one lifts; the others slide aside. */
6779
+ .ow-sortable {
6780
+ display: flex;
6781
+ flex-direction: column;
6782
+ gap: var(--ow-space-xs);
6783
+ margin: 0;
6784
+ padding: 0;
6785
+ list-style: none;
6786
+ }
6787
+
6788
+ .ow-sortable--horizontal {
6789
+ flex-direction: row;
6790
+ overflow-x: auto;
6791
+ padding-block: var(--ow-space-2xs);
6792
+ }
6793
+
6794
+ .ow-sortable__item {
6795
+ position: relative;
6796
+ display: flex;
6797
+ flex: none;
6798
+ min-height: 40px;
6799
+ align-items: center;
6800
+ gap: var(--ow-space-xs);
6801
+ padding: var(--ow-space-xs) var(--ow-space-lg);
6802
+ border: 1px solid var(--ow-border);
6803
+ border-radius: var(--ow-radius-md);
6804
+ background: var(--ow-surface);
6805
+ color: var(--ow-text);
6806
+ font-size: 14px;
6807
+ outline: none;
6808
+ }
6809
+
6810
+ .ow-sortable--horizontal .ow-sortable__item {
6811
+ min-height: 32px;
6812
+ padding-block: var(--ow-space-2xs);
6813
+ }
6814
+
6815
+ .ow-sortable__content {
6816
+ flex: 1;
6817
+ min-width: 0;
6818
+ }
6819
+
6820
+ /* Whatever picks it up: the row, or its grip. Touch drags it rather than scrolling the page. */
6821
+ .ow-sortable__item--row,
6822
+ .ow-sortable__handle {
6823
+ cursor: grab;
6824
+ touch-action: none;
6825
+ user-select: none;
6826
+ -webkit-user-select: none;
6827
+ }
6828
+
6829
+ .ow-sortable__handle {
6830
+ display: inline-flex;
6831
+ width: 24px;
6832
+ height: 28px;
6833
+ flex: none;
6834
+ align-items: center;
6835
+ justify-content: center;
6836
+ margin-inline-start: calc(var(--ow-space-xs) * -1);
6837
+ padding: 0;
6838
+ border: 0;
6839
+ border-radius: var(--ow-radius-md);
6840
+ background: none;
6841
+ color: var(--ow-icon);
6842
+ }
6843
+
6844
+ .ow-sortable__handle:hover {
6845
+ background: var(--ow-hover);
6846
+ color: var(--ow-text-muted);
6847
+ }
6848
+
6849
+ .ow-sortable--horizontal .ow-sortable__grip {
6850
+ rotate: 90deg;
6851
+ }
6852
+
6853
+ .ow-sortable__item--row:focus-visible,
6854
+ .ow-sortable__handle:focus-visible {
6855
+ outline: 2px solid var(--ow-focus-ring);
6856
+ outline-offset: 1px;
6857
+ }
6858
+
6859
+ /* While one is picked up, the others slide to make room. */
6860
+ .ow-sortable--dragging .ow-sortable__item {
6861
+ transition: transform var(--ow-duration-base) var(--ow-ease-standard);
6862
+ }
6863
+
6864
+ .ow-sortable .ow-sortable__item--dragging {
6865
+ z-index: 1;
6866
+ border-color: var(--ow-border-strong);
6867
+ box-shadow: var(--ow-shadow-menu);
6868
+ transition: none;
6869
+ }
6870
+
6871
+ :root[data-ow-sortable-drag],
6872
+ :root[data-ow-sortable-drag] * {
6873
+ cursor: grabbing !important;
6874
+ user-select: none;
6875
+ -webkit-user-select: none;
6876
+ }
6877
+
6878
+ .ow-sortable--disabled .ow-sortable__item {
6879
+ background: var(--ow-surface-muted);
6880
+ color: var(--ow-text-muted);
6881
+ cursor: default;
6882
+ }
6883
+
6884
+ .ow-sortable--disabled .ow-sortable__handle {
6885
+ background: none;
6886
+ color: var(--ow-text-disabled);
6887
+ cursor: not-allowed;
6888
+ }
6889
+
6890
+ @media (prefers-reduced-motion: reduce) {
6891
+ .ow-sortable--dragging .ow-sortable__item {
6892
+ transition: none;
6893
+ }
6894
+ }
6895
+
6575
6896
  /* components/Table/Table.css */
6576
6897
  /* Table: a bordered card with a quiet header row and hairlines between rows. */
6577
6898
  .ow-table-wrap {
@@ -7538,6 +7859,134 @@
7538
7859
  font-size: 12px;
7539
7860
  }
7540
7861
 
7862
+ /* components/TreeView/TreeView.css */
7863
+ /* TreeView: rows that open, select and check. FileTree's hairline guides, NavList's 14px text. */
7864
+ .ow-treeview,
7865
+ .ow-treeview__group {
7866
+ display: grid;
7867
+ gap: 1px;
7868
+ margin: 0;
7869
+ padding: 0;
7870
+ list-style: none;
7871
+ }
7872
+
7873
+ .ow-treeview {
7874
+ color: var(--ow-text);
7875
+ font-size: 14px;
7876
+ }
7877
+
7878
+ /* The guide runs under the parent's chevron. */
7879
+ .ow-treeview__group {
7880
+ margin-inline-start: 14px;
7881
+ border-inline-start: 1px solid var(--ow-border);
7882
+ padding-inline-start: var(--ow-space-2xs);
7883
+ }
7884
+
7885
+ .ow-treeview__item {
7886
+ outline: none;
7887
+ }
7888
+
7889
+ .ow-treeview__row {
7890
+ display: flex;
7891
+ min-height: 32px;
7892
+ align-items: center;
7893
+ gap: var(--ow-space-xs);
7894
+ border-radius: var(--ow-radius-form);
7895
+ padding-block: var(--ow-space-2xs);
7896
+ padding-inline: var(--ow-space-2xs) var(--ow-space-sm);
7897
+ cursor: pointer;
7898
+ user-select: none;
7899
+ transition: background-color var(--ow-duration-fast) var(--ow-ease-standard);
7900
+ }
7901
+
7902
+ .ow-treeview__row:hover {
7903
+ background: var(--ow-surface-muted);
7904
+ }
7905
+
7906
+ .ow-treeview__item:focus-visible > .ow-treeview__row {
7907
+ box-shadow: 0 0 0 2px var(--ow-focus-ring);
7908
+ }
7909
+
7910
+ .ow-treeview__row--selected,
7911
+ .ow-treeview__row--selected:hover {
7912
+ background: var(--ow-primary-subtle);
7913
+ color: var(--ow-primary-text);
7914
+ }
7915
+
7916
+ .ow-treeview__row--disabled,
7917
+ .ow-treeview__row--loading {
7918
+ color: var(--ow-text-muted);
7919
+ cursor: default;
7920
+ }
7921
+
7922
+ .ow-treeview__toggle {
7923
+ display: inline-flex;
7924
+ width: 20px;
7925
+ height: 24px;
7926
+ flex-shrink: 0;
7927
+ align-items: center;
7928
+ justify-content: center;
7929
+ color: var(--ow-text-muted);
7930
+ }
7931
+
7932
+ .ow-treeview__toggle svg {
7933
+ transition: transform var(--ow-duration-base) var(--ow-ease-standard);
7934
+ }
7935
+
7936
+ .ow-treeview__toggle:dir(rtl) svg {
7937
+ transform: scaleX(-1);
7938
+ }
7939
+
7940
+ [aria-expanded="true"] > .ow-treeview__row .ow-treeview__toggle svg {
7941
+ transform: rotate(90deg);
7942
+ }
7943
+
7944
+ .ow-treeview .ow-checkbox__input {
7945
+ pointer-events: none;
7946
+ }
7947
+
7948
+ .ow-treeview__icon {
7949
+ display: inline-flex;
7950
+ flex-shrink: 0;
7951
+ color: var(--ow-text-muted);
7952
+ }
7953
+
7954
+ .ow-treeview__text {
7955
+ display: grid;
7956
+ min-width: 0;
7957
+ flex: 1;
7958
+ }
7959
+
7960
+ .ow-treeview__label,
7961
+ .ow-treeview__description {
7962
+ overflow: hidden;
7963
+ text-overflow: ellipsis;
7964
+ white-space: nowrap;
7965
+ }
7966
+
7967
+ .ow-treeview__description,
7968
+ .ow-treeview__end {
7969
+ color: var(--ow-text-muted);
7970
+ font-size: 12px;
7971
+ }
7972
+
7973
+ .ow-treeview__end {
7974
+ flex-shrink: 0;
7975
+ }
7976
+
7977
+ .ow-treeview__row--selected :is(.ow-treeview__icon, .ow-treeview__description, .ow-treeview__end) {
7978
+ color: inherit;
7979
+ }
7980
+
7981
+ .ow-treeview__row--error {
7982
+ color: var(--ow-danger-text);
7983
+ }
7984
+
7985
+ .ow-treeview__retry {
7986
+ font-weight: var(--ow-weight-emphasis);
7987
+ text-decoration: underline;
7988
+ }
7989
+
7541
7990
  /* components/EmptyState/EmptyState.css */
7542
7991
  /* EmptyState: centred, at most 360px of text, an icon tile above. */
7543
7992
  .ow-empty {
@@ -7748,6 +8197,148 @@
7748
8197
  font-weight: var(--ow-weight-regular);
7749
8198
  }
7750
8199
 
8200
+ /* components/NavigationMenu/NavigationMenu.css */
8201
+ /* NavigationMenu: a site's top links, with panels of links on Popover's surface. Rules are scoped under
8202
+ .ow-navigation-menu so SiteHeader's `nav a` colours don't reach into the panels. */
8203
+ .ow-navigation-menu {
8204
+ min-width: 0;
8205
+ font-family: var(--ow-font-sans);
8206
+ }
8207
+
8208
+ .ow-navigation-menu__list {
8209
+ display: flex;
8210
+ flex-wrap: wrap;
8211
+ align-items: center;
8212
+ gap: var(--ow-space-2xs);
8213
+ margin: 0;
8214
+ padding: 0;
8215
+ list-style: none;
8216
+ }
8217
+
8218
+ .ow-navigation-menu .ow-navigation-menu__trigger {
8219
+ display: inline-flex;
8220
+ min-height: 32px;
8221
+ align-items: center;
8222
+ gap: var(--ow-space-3xs);
8223
+ border: 0;
8224
+ border-radius: var(--ow-radius-pill);
8225
+ background: transparent;
8226
+ padding: 0 var(--ow-space-sm);
8227
+ color: var(--ow-text-soft);
8228
+ font: inherit;
8229
+ font-size: 14px;
8230
+ font-weight: var(--ow-weight-control);
8231
+ text-decoration: none;
8232
+ cursor: pointer;
8233
+ transition-property: color, background-color;
8234
+ transition-duration: var(--ow-duration-base);
8235
+ transition-timing-function: var(--ow-ease-standard);
8236
+ }
8237
+
8238
+ .ow-navigation-menu .ow-navigation-menu__trigger:hover,
8239
+ .ow-navigation-menu__trigger[aria-expanded="true"] {
8240
+ background: var(--ow-hover);
8241
+ color: var(--ow-text);
8242
+ }
8243
+
8244
+ .ow-navigation-menu__trigger[aria-current="page"],
8245
+ .ow-navigation-menu__trigger[data-active] {
8246
+ color: var(--ow-text);
8247
+ }
8248
+
8249
+ .ow-navigation-menu .ow-navigation-menu__trigger:focus-visible,
8250
+ .ow-navigation-menu .ow-navigation-menu__link:focus-visible {
8251
+ outline: 2px solid var(--ow-focus-ring);
8252
+ outline-offset: -2px;
8253
+ }
8254
+
8255
+ .ow-navigation-menu__chevron {
8256
+ color: var(--ow-text-muted);
8257
+ transition: transform var(--ow-duration-base) var(--ow-ease-standard);
8258
+ }
8259
+
8260
+ [aria-expanded="true"] > .ow-navigation-menu__chevron {
8261
+ transform: rotate(180deg);
8262
+ }
8263
+
8264
+ .ow-navigation-menu__panel {
8265
+ grid-template-columns: repeat(var(--ow-navigation-menu-columns), minmax(0, 15rem));
8266
+ max-width: calc(100vw - 16px);
8267
+ padding: var(--ow-space-sm);
8268
+ gap: var(--ow-space-sm);
8269
+ }
8270
+
8271
+ .ow-navigation-menu__panel--full {
8272
+ grid-template-columns: repeat(var(--ow-navigation-menu-columns), minmax(0, 1fr));
8273
+ }
8274
+
8275
+ .ow-navigation-menu__group {
8276
+ display: grid;
8277
+ align-content: start;
8278
+ gap: var(--ow-space-3xs);
8279
+ }
8280
+
8281
+ .ow-navigation-menu__group-title {
8282
+ padding: var(--ow-space-xs) var(--ow-space-sm) var(--ow-space-2xs);
8283
+ color: var(--ow-text-muted);
8284
+ font-size: 12px;
8285
+ font-weight: var(--ow-weight-label);
8286
+ }
8287
+
8288
+ .ow-navigation-menu .ow-navigation-menu__link {
8289
+ display: flex;
8290
+ align-items: flex-start;
8291
+ gap: var(--ow-space-sm);
8292
+ border-radius: var(--ow-radius-lg);
8293
+ padding: var(--ow-space-sm);
8294
+ color: var(--ow-text);
8295
+ text-decoration: none;
8296
+ transition: background-color var(--ow-duration-base) var(--ow-ease-standard);
8297
+ }
8298
+
8299
+ .ow-navigation-menu .ow-navigation-menu__link:hover,
8300
+ .ow-navigation-menu__link[aria-current="page"] {
8301
+ background: var(--ow-surface-muted);
8302
+ }
8303
+
8304
+ .ow-navigation-menu__icon {
8305
+ display: inline-flex;
8306
+ flex-shrink: 0;
8307
+ color: var(--ow-text-muted);
8308
+ }
8309
+
8310
+ .ow-navigation-menu__text {
8311
+ display: grid;
8312
+ min-width: 0;
8313
+ gap: 2px;
8314
+ }
8315
+
8316
+ .ow-navigation-menu__title {
8317
+ font-weight: var(--ow-weight-emphasis);
8318
+ line-height: 1.3;
8319
+ }
8320
+
8321
+ .ow-navigation-menu__description {
8322
+ color: var(--ow-text-muted);
8323
+ font-size: 13px;
8324
+ line-height: 1.4;
8325
+ }
8326
+
8327
+ .ow-navigation-menu .ow-navigation-menu__link--featured,
8328
+ .ow-navigation-menu .ow-navigation-menu__link--featured:hover {
8329
+ flex-direction: column;
8330
+ justify-content: flex-end;
8331
+ min-height: 9rem;
8332
+ background: var(--ow-primary-subtle);
8333
+ padding: var(--ow-space-lg);
8334
+ }
8335
+
8336
+ @media (max-width: 640px) {
8337
+ .ow-navigation-menu__panel {
8338
+ grid-template-columns: minmax(0, 1fr);
8339
+ }
8340
+ }
8341
+
7751
8342
  /* components/AppShell/AppShell.css */
7752
8343
  /* AppShell: a sidebar down the left and the page beside it. It measures its own width (a container query), so it
7753
8344
  folds into a drawer under its breakpoint (900px by default) whether it fills the window or sits in a smaller frame. */
@@ -8263,6 +8854,52 @@
8263
8854
  }
8264
8855
  }
8265
8856
 
8857
+ /* components/VirtualList/VirtualList.css */
8858
+ /* VirtualList: a scrolling list that renders only the rows in view, each placed by its offset from the top. */
8859
+ .ow-virtual-list {
8860
+ position: relative;
8861
+ display: flex;
8862
+ flex-direction: column;
8863
+ height: 100%;
8864
+ min-height: 0;
8865
+ }
8866
+
8867
+ .ow-virtual-list__scroll {
8868
+ flex: 1 1 auto;
8869
+ min-height: 0;
8870
+ overflow-x: hidden;
8871
+ overflow-y: auto;
8872
+ overscroll-behavior: contain;
8873
+ /* The list keeps its own place as rows are measured or added above; the browser's anchoring would double it. */
8874
+ overflow-anchor: none;
8875
+ border-radius: inherit;
8876
+ }
8877
+
8878
+ .ow-virtual-list__scroll:focus-visible,
8879
+ .ow-virtual-list__item:focus-visible {
8880
+ outline: 2px solid var(--ow-focus-ring);
8881
+ outline-offset: -2px;
8882
+ }
8883
+
8884
+ .ow-virtual-list__inner {
8885
+ position: relative;
8886
+ flex-shrink: 0;
8887
+ width: 100%;
8888
+ }
8889
+
8890
+ .ow-virtual-list__item {
8891
+ position: absolute;
8892
+ top: 0;
8893
+ inset-inline: 0;
8894
+ border-radius: var(--ow-radius-md);
8895
+ }
8896
+
8897
+ .ow-virtual-list__footer {
8898
+ display: flex;
8899
+ justify-content: center;
8900
+ padding: var(--ow-space-md);
8901
+ }
8902
+
8266
8903
  /* components/AspectRatio/AspectRatio.css */
8267
8904
  /* AspectRatio: a box that keeps its shape, with whatever is inside filling it. The hidden overflow keeps the ratio
8268
8905
  when the content is taller than the box would be. */