@threadlabs/looma 0.25.4 → 0.25.5

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 (58) hide show
  1. package/components/ui-card/ui-card.html +27 -2
  2. package/components/ui-cluster/ui-cluster.html +30 -0
  3. package/components/ui-editor-surface/ui-editor-surface.html +23 -0
  4. package/components/ui-scroll-area/ui-scroll-area.html +5 -0
  5. package/components/ui-stack/ui-stack.html +17 -1
  6. package/components/ui-text/ui-text.html +5 -0
  7. package/components/ui-textarea/ui-textarea.html +7 -0
  8. package/dist/index.js +1 -1
  9. package/package.json +1 -1
  10. package/styles/ui-card.css +24 -0
  11. package/styles/ui-cluster.css +25 -0
  12. package/styles/ui-editor-surface.css +19 -0
  13. package/styles/ui-scroll-area.css +4 -0
  14. package/styles/ui-stack.css +13 -0
  15. package/styles/ui-text.css +4 -0
  16. package/styles/ui-textarea.css +4 -0
  17. package/vanilla/UiCard.d.ts +1 -1
  18. package/vanilla/UiCard.js +1 -1
  19. package/vanilla/UiCluster.d.ts +3 -0
  20. package/vanilla/UiCluster.js +9 -3
  21. package/vanilla/UiEditorSurface.d.ts +14 -0
  22. package/vanilla/UiEditorSurface.js +27 -0
  23. package/vanilla/UiScrollArea.d.ts +1 -0
  24. package/vanilla/UiScrollArea.js +1 -1
  25. package/vanilla/UiStack.d.ts +2 -0
  26. package/vanilla/UiStack.js +8 -9
  27. package/vanilla/UiText.d.ts +1 -0
  28. package/vanilla/UiText.js +1 -1
  29. package/vanilla/UiTextarea.d.ts +1 -0
  30. package/vanilla/UiTextarea.js +4 -1
  31. package/vanilla/index.js +1 -0
  32. package/vue/UiCard.d.ts +3 -3
  33. package/vue/UiCard.vue +34 -5
  34. package/vue/UiCluster.d.ts +27 -0
  35. package/vue/UiCluster.vue +95 -1
  36. package/vue/UiEditorSurface.d.ts +26 -0
  37. package/vue/UiEditorSurface.js +2 -0
  38. package/vue/UiEditorSurface.vue +129 -0
  39. package/vue/UiScrollArea.d.ts +9 -0
  40. package/vue/UiScrollArea.vue +28 -2
  41. package/vue/UiStack.d.ts +18 -0
  42. package/vue/UiStack.vue +58 -1
  43. package/vue/UiText.d.ts +9 -0
  44. package/vue/UiText.vue +33 -0
  45. package/vue/UiTextarea.d.ts +9 -0
  46. package/vue/UiTextarea.vue +37 -2
  47. package/vue/chunks/UiCard.js +10 -3
  48. package/vue/chunks/UiCluster.js +82 -1
  49. package/vue/chunks/UiEditorSurface.js +71 -0
  50. package/vue/chunks/UiScrollArea.js +28 -2
  51. package/vue/chunks/UiStack.js +46 -1
  52. package/vue/chunks/UiText.js +43 -1
  53. package/vue/chunks/UiTextarea.js +28 -2
  54. package/vue/components.css +188 -104
  55. package/vue/editor/LoomaEditor.d.ts +12 -0
  56. package/vue/editor/index.js +7 -2
  57. package/vue/index.d.ts +1 -0
  58. package/vue/index.js +2 -1
@@ -1331,7 +1331,7 @@ html[data-ui-input-modality="touch"]
1331
1331
 
1332
1332
  /* A surface that groups content. Its children stack with even space between them, so a card
1333
1333
  needs no layout of its own. */
1334
- [data-component~="ui-card"][data-v-fa2ae386] {
1334
+ [data-component~="ui-card"][data-v-c589f774] {
1335
1335
  display: flex;
1336
1336
  flex-direction: column;
1337
1337
  gap: var(--ui-space-4);
@@ -1343,45 +1343,64 @@ html[data-ui-input-modality="touch"]
1343
1343
  background: var(--ui-surface-raised);
1344
1344
  color: var(--ui-text-primary);
1345
1345
  }
1346
- [data-component~="ui-card"][data-ui-card-state~="padding=xs"][data-v-fa2ae386] {
1346
+ [data-component~="ui-card"][data-ui-card-state~="padding=xs"][data-v-c589f774] {
1347
1347
  gap: var(--ui-space-1);
1348
1348
  padding: var(--ui-space-2);
1349
1349
  }
1350
- [data-component~="ui-card"][data-ui-card-state~="padding=sm"][data-v-fa2ae386] {
1350
+ [data-component~="ui-card"][data-ui-card-state~="padding=sm"][data-v-c589f774] {
1351
1351
  gap: var(--ui-space-2);
1352
1352
  padding: var(--ui-space-3);
1353
1353
  }
1354
- [data-component~="ui-card"][data-ui-card-state~="padding=lg"][data-v-fa2ae386] {
1354
+ [data-component~="ui-card"][data-ui-card-state~="padding=lg"][data-v-c589f774] {
1355
1355
  padding: var(--ui-space-6);
1356
1356
  }
1357
- [data-component~="ui-card"][data-ui-card-state~="variant=subtle"][data-v-fa2ae386] {
1357
+ [data-component~="ui-card"][data-ui-card-state~="variant=subtle"][data-v-c589f774] {
1358
1358
  border-color: transparent;
1359
1359
  background: var(--ui-surface-muted);
1360
1360
  }
1361
- [data-component~="ui-card"][data-ui-card-state~="variant=elevated"][data-v-fa2ae386] {
1361
+ [data-component~="ui-card"][data-ui-card-state~="variant=elevated"][data-v-c589f774] {
1362
1362
  border-color: var(--ui-border-subtle);
1363
1363
  box-shadow: var(--ui-shadow-lg);
1364
1364
  }
1365
- [data-component~="ui-card"][data-ui-card-state~="tone=danger"][data-v-fa2ae386] {
1365
+ [data-component~="ui-card"][data-ui-card-state~="tone=accent"][data-v-c589f774] {
1366
+ border-color: color-mix(in srgb, var(--ui-accent) 25%, var(--ui-border-default));
1367
+ background: color-mix(in srgb, var(--ui-accent) 6%, var(--ui-surface-default));
1368
+ }
1369
+ [data-component~="ui-card"][data-ui-card-state~="tone=info"][data-v-c589f774] {
1370
+ border-color: color-mix(in srgb, var(--ui-info) 25%, var(--ui-border-default));
1371
+ background: color-mix(in srgb, var(--ui-info) 6%, var(--ui-surface-default));
1372
+ }
1373
+ [data-component~="ui-card"][data-ui-card-state~="tone=success"][data-v-c589f774] {
1374
+ border-color: color-mix(in srgb, var(--ui-success) 25%, var(--ui-border-default));
1375
+ background: color-mix(in srgb, var(--ui-success) 6%, var(--ui-surface-default));
1376
+ }
1377
+ [data-component~="ui-card"][data-ui-card-state~="tone=warning"][data-v-c589f774] {
1378
+ border-color: color-mix(in srgb, var(--ui-warning) 25%, var(--ui-border-default));
1379
+ background: color-mix(in srgb, var(--ui-warning) 6%, var(--ui-surface-default));
1380
+ }
1381
+ [data-component~="ui-card"][data-ui-card-state~="variant=subtle"][data-v-c589f774]:is([data-ui-card-state~="tone=accent"], [data-ui-card-state~="tone=info"], [data-ui-card-state~="tone=success"], [data-ui-card-state~="tone=warning"]) {
1382
+ border-color: transparent;
1383
+ }
1384
+ [data-component~="ui-card"][data-ui-card-state~="tone=danger"][data-v-c589f774] {
1366
1385
  border-color: color-mix(in srgb, var(--ui-danger) 45%, var(--ui-border-default));
1367
1386
  border-inline-start: var(--ui-accent-line-width) solid var(--ui-danger);
1368
1387
  background: var(--ui-danger-soft);
1369
1388
  }
1370
- [data-component~="ui-card"][data-ui-card-state~="size=sm"][data-v-fa2ae386] {
1389
+ [data-component~="ui-card"][data-ui-card-state~="size=sm"][data-v-c589f774] {
1371
1390
  inline-size: min(22rem, calc(100vw - var(--ui-space-2) * 2));
1372
1391
  max-inline-size: min(22rem, calc(100vw - var(--ui-space-2) * 2));
1373
1392
  }
1374
- [data-component~="ui-card"][data-ui-card-state~="size=md"][data-v-fa2ae386] {
1393
+ [data-component~="ui-card"][data-ui-card-state~="size=md"][data-v-c589f774] {
1375
1394
  inline-size: min(28rem, calc(100vw - var(--ui-space-2) * 2));
1376
1395
  max-inline-size: min(28rem, calc(100vw - var(--ui-space-2) * 2));
1377
1396
  }
1378
- [data-component~="ui-card"][data-ui-card-state~="size=lg"][data-v-fa2ae386] {
1397
+ [data-component~="ui-card"][data-ui-card-state~="size=lg"][data-v-c589f774] {
1379
1398
  inline-size: min(36rem, calc(100vw - var(--ui-space-2) * 2));
1380
1399
  max-inline-size: min(36rem, calc(100vw - var(--ui-space-2) * 2));
1381
1400
  }
1382
1401
 
1383
1402
  /* A component that sets its display still honours the hidden attribute on its root. */
1384
- [data-component~="ui-card"][hidden][data-v-fa2ae386] {
1403
+ [data-component~="ui-card"][hidden][data-v-c589f774] {
1385
1404
  display: none;
1386
1405
  }
1387
1406
 
@@ -1568,7 +1587,7 @@ input[data-v-ce204e6e]:focus-visible {
1568
1587
  syntax: "*";
1569
1588
  inherits: false;
1570
1589
  }
1571
- [data-component~="ui-cluster"][data-v-fafdad21] {
1590
+ [data-component~="ui-cluster"][data-v-e3a64464] {
1572
1591
  --_layout-gap: var(--ui-space-3);
1573
1592
  display: flex;
1574
1593
  flex-wrap: wrap;
@@ -1578,45 +1597,69 @@ input[data-v-ce204e6e]:focus-visible {
1578
1597
  max-inline-size: 100%;
1579
1598
  margin: 0;
1580
1599
  }
1581
- [data-component~="ui-cluster"][data-ui-cluster-state~="gap=xs"][data-v-fafdad21] {
1600
+ [data-component~="ui-cluster"][data-ui-cluster-state~="fixed"][data-v-e3a64464] {
1601
+ flex: none;
1602
+ }
1603
+ [data-component~="ui-cluster"][data-ui-cluster-state~="padding=s"][data-v-e3a64464] {
1604
+ padding: var(--ui-space-2);
1605
+ }
1606
+ [data-component~="ui-cluster"][data-ui-cluster-state~="padding=m"][data-v-e3a64464] {
1607
+ padding: var(--ui-space-3);
1608
+ }
1609
+ [data-component~="ui-cluster"][data-ui-cluster-state~="padding=l"][data-v-e3a64464] {
1610
+ padding: var(--ui-space-4);
1611
+ }
1612
+ [data-component~="ui-cluster"][data-ui-cluster-state~="paddingEnd=s"][data-v-e3a64464] {
1613
+ padding-inline-end: var(--ui-space-2);
1614
+ }
1615
+ [data-component~="ui-cluster"][data-ui-cluster-state~="paddingEnd=m"][data-v-e3a64464] {
1616
+ padding-inline-end: var(--ui-space-3);
1617
+ }
1618
+ [data-component~="ui-cluster"][data-ui-cluster-state~="paddingEnd=l"][data-v-e3a64464] {
1619
+ padding-inline-end: var(--ui-space-4);
1620
+ }
1621
+ [data-component~="ui-cluster"][data-ui-cluster-state~="paddingEnd=xl"][data-v-e3a64464] {
1622
+ padding-inline-end: calc(var(--ui-space-4) * 4);
1623
+ }
1624
+ [data-component~="ui-cluster"][data-ui-cluster-state~="gap=xs"][data-v-e3a64464] {
1582
1625
  --_layout-gap: var(--ui-space-2);
1583
1626
  }
1584
- [data-component~="ui-cluster"][data-ui-cluster-state~="gap=s"][data-v-fafdad21] {
1627
+ [data-component~="ui-cluster"][data-ui-cluster-state~="gap=s"][data-v-e3a64464] {
1585
1628
  --_layout-gap: var(--ui-space-3);
1586
1629
  }
1587
- [data-component~="ui-cluster"][data-ui-cluster-state~="gap=m"][data-v-fafdad21] {
1630
+ [data-component~="ui-cluster"][data-ui-cluster-state~="gap=m"][data-v-e3a64464] {
1588
1631
  --_layout-gap: var(--ui-space-4);
1589
1632
  }
1590
- [data-component~="ui-cluster"][data-ui-cluster-state~="gap=l"][data-v-fafdad21] {
1633
+ [data-component~="ui-cluster"][data-ui-cluster-state~="gap=l"][data-v-e3a64464] {
1591
1634
  --_layout-gap: var(--ui-space-5);
1592
1635
  }
1593
- [data-component~="ui-cluster"][data-ui-cluster-state~="gap=xl"][data-v-fafdad21] {
1636
+ [data-component~="ui-cluster"][data-ui-cluster-state~="gap=xl"][data-v-e3a64464] {
1594
1637
  --_layout-gap: var(--ui-space-6);
1595
1638
  }
1596
- [data-component~="ui-cluster"][data-ui-cluster-state~="align=start"][data-v-fafdad21] {
1639
+ [data-component~="ui-cluster"][data-ui-cluster-state~="align=start"][data-v-e3a64464] {
1597
1640
  align-items: flex-start;
1598
1641
  }
1599
- [data-component~="ui-cluster"][data-ui-cluster-state~="align=end"][data-v-fafdad21] {
1642
+ [data-component~="ui-cluster"][data-ui-cluster-state~="align=end"][data-v-e3a64464] {
1600
1643
  align-items: flex-end;
1601
1644
  }
1602
- [data-component~="ui-cluster"][data-ui-cluster-state~="align=stretch"][data-v-fafdad21] {
1645
+ [data-component~="ui-cluster"][data-ui-cluster-state~="align=stretch"][data-v-e3a64464] {
1603
1646
  align-items: stretch;
1604
1647
  }
1605
- [data-component~="ui-cluster"][data-ui-cluster-state~="justify=center"][data-v-fafdad21] {
1648
+ [data-component~="ui-cluster"][data-ui-cluster-state~="justify=center"][data-v-e3a64464] {
1606
1649
  justify-content: center;
1607
1650
  }
1608
- [data-component~="ui-cluster"][data-ui-cluster-state~="justify=end"][data-v-fafdad21] {
1651
+ [data-component~="ui-cluster"][data-ui-cluster-state~="justify=end"][data-v-e3a64464] {
1609
1652
  justify-content: flex-end;
1610
1653
  }
1611
- [data-component~="ui-cluster"][data-ui-cluster-state~="justify=between"][data-v-fafdad21] {
1654
+ [data-component~="ui-cluster"][data-ui-cluster-state~="justify=between"][data-v-e3a64464] {
1612
1655
  justify-content: space-between;
1613
1656
  }
1614
- [data-component~="ui-cluster"][data-ui-cluster-state~="wrap=nowrap"][data-v-fafdad21] {
1657
+ [data-component~="ui-cluster"][data-ui-cluster-state~="wrap=nowrap"][data-v-e3a64464] {
1615
1658
  flex-wrap: nowrap;
1616
1659
  }
1617
1660
 
1618
1661
  /* A component that sets its display still honours the hidden attribute on its root. */
1619
- [data-component~="ui-cluster"][hidden][data-v-fafdad21] {
1662
+ [data-component~="ui-cluster"][hidden][data-v-e3a64464] {
1620
1663
  display: none;
1621
1664
  }
1622
1665
 
@@ -2492,7 +2535,10 @@ dd[data-v-cc61fece] {
2492
2535
  /* The controller sets each fade length from overflow and scroll position. The mask blends
2493
2536
  into whatever is behind the area without needing to know its colour. Before upgrade, its
2494
2537
  zero-length defaults leave the authored scroll area fully visible. */
2495
- [data-component~="ui-scroll-area"][data-v-7357ecdb] {
2538
+ [data-component~="ui-scroll-area"][data-ui-scroll-area-state~="fill"][data-v-1f6366dd] {
2539
+ flex: 1;
2540
+ }
2541
+ [data-component~="ui-scroll-area"][data-v-1f6366dd] {
2496
2542
  display: block;
2497
2543
  box-sizing: border-box;
2498
2544
  min-block-size: 0;
@@ -2511,29 +2557,29 @@ dd[data-v-cc61fece] {
2511
2557
  transparent
2512
2558
  );
2513
2559
  }
2514
- .content[data-v-7357ecdb] {
2560
+ .content[data-v-1f6366dd] {
2515
2561
  display: flow-root;
2516
2562
  }
2517
- [data-component~="ui-scroll-area"][data-ui-scroll-area-state~="orientation=horizontal"][data-v-7357ecdb] {
2563
+ [data-component~="ui-scroll-area"][data-ui-scroll-area-state~="orientation=horizontal"][data-v-1f6366dd] {
2518
2564
  overflow-x: auto;
2519
2565
  overflow-y: hidden;
2520
2566
  --_ui-scroll-fade-direction: var(--_ui-scroll-fade-inline);
2521
2567
  }
2522
- [data-component~="ui-scroll-area"][data-v-7357ecdb]:dir(rtl) {
2568
+ [data-component~="ui-scroll-area"][data-v-1f6366dd]:dir(rtl) {
2523
2569
  --_ui-scroll-fade-inline: to left;
2524
2570
  }
2525
- [data-component~="ui-scroll-area"][data-ui-scroll-area-state~="size=sm"][data-v-7357ecdb] {
2571
+ [data-component~="ui-scroll-area"][data-ui-scroll-area-state~="size=sm"][data-v-1f6366dd] {
2526
2572
  max-block-size: calc(9.375rem + var(--ui-scroll-fade-size, 24px));
2527
2573
  }
2528
- [data-component~="ui-scroll-area"][data-ui-scroll-area-state~="size=md"][data-v-7357ecdb] {
2574
+ [data-component~="ui-scroll-area"][data-ui-scroll-area-state~="size=md"][data-v-1f6366dd] {
2529
2575
  max-block-size: 20rem;
2530
2576
  }
2531
- [data-component~="ui-scroll-area"][data-ui-scroll-area-state~="size=lg"][data-v-7357ecdb] {
2577
+ [data-component~="ui-scroll-area"][data-ui-scroll-area-state~="size=lg"][data-v-1f6366dd] {
2532
2578
  max-block-size: 30rem;
2533
2579
  }
2534
2580
 
2535
2581
  /* A component that sets its display still honours the hidden attribute on its root. */
2536
- [data-component~="ui-scroll-area"][hidden][data-v-7357ecdb] {
2582
+ [data-component~="ui-scroll-area"][hidden][data-v-1f6366dd] {
2537
2583
  display: none;
2538
2584
  }
2539
2585
 
@@ -3581,6 +3627,20 @@ ul[data-v-d78f0cb3] {
3581
3627
  display: none;
3582
3628
  }
3583
3629
 
3630
+ [data-component~="ui-editor-surface"][data-v-7e72ed22] {
3631
+ display: flex;
3632
+ flex-direction: column;
3633
+ min-inline-size: 0;
3634
+ max-inline-size: 100%;
3635
+ }
3636
+ /* The document renderer consumes these inherited surface settings. They do not style controls. */
3637
+ [data-component~="ui-editor-surface"][data-ui-editor-surface-state~="density=compact"][data-v-7e72ed22] {
3638
+ --_ui-editor-content-min-height: 0px;
3639
+ --_ui-editor-content-padding-block: 0px;
3640
+ --_ui-editor-content-padding-inline: 0px;
3641
+ --_ui-editor-mobile-bottom-space: 0px;
3642
+ }
3643
+
3584
3644
  [data-component~="ui-editor-table-context-menu"][data-v-27797f18] {
3585
3645
  /* The max-width is a promise about the menu's footprint, so it counts padding and border. */
3586
3646
  box-sizing: border-box;
@@ -7564,11 +7624,15 @@ dialog[data-v-a7c1863a] {
7564
7624
  }
7565
7625
 
7566
7626
  /* This component's hooks style the element they are set on, and never a nested one. */
7627
+ @property --ui-stack-height {
7628
+ syntax: "*";
7629
+ inherits: false;
7630
+ }
7567
7631
  @property --ui-stack-gap {
7568
7632
  syntax: "*";
7569
7633
  inherits: false;
7570
7634
  }
7571
- [data-component~="ui-stack"][data-v-8129c161] {
7635
+ [data-component~="ui-stack"][data-v-bdf63b20] {
7572
7636
  --_layout-gap: var(--ui-space-4);
7573
7637
  display: flex;
7574
7638
  flex-direction: column;
@@ -7578,45 +7642,53 @@ dialog[data-v-a7c1863a] {
7578
7642
  max-inline-size: 100%;
7579
7643
  margin: 0;
7580
7644
  }
7581
- [data-component~="ui-stack"][data-ui-stack-state~="gap=none"][data-v-8129c161] {
7645
+ [data-component~="ui-stack"][data-ui-stack-state~="fill"][data-v-bdf63b20] {
7646
+ flex: 1;
7647
+ min-block-size: 0;
7648
+ }
7649
+ [data-component~="ui-stack"][data-ui-stack-state~="height"][data-v-bdf63b20] {
7650
+ block-size: calc(var(--ui-stack-height, 0) * 1px);
7651
+ min-block-size: 0;
7652
+ }
7653
+ [data-component~="ui-stack"][data-ui-stack-state~="gap=none"][data-v-bdf63b20] {
7582
7654
  --_layout-gap: 0px;
7583
7655
  }
7584
- [data-component~="ui-stack"][data-ui-stack-state~="gap=xs"][data-v-8129c161] {
7656
+ [data-component~="ui-stack"][data-ui-stack-state~="gap=xs"][data-v-bdf63b20] {
7585
7657
  --_layout-gap: var(--ui-space-2);
7586
7658
  }
7587
- [data-component~="ui-stack"][data-ui-stack-state~="gap=s"][data-v-8129c161] {
7659
+ [data-component~="ui-stack"][data-ui-stack-state~="gap=s"][data-v-bdf63b20] {
7588
7660
  --_layout-gap: var(--ui-space-3);
7589
7661
  }
7590
- [data-component~="ui-stack"][data-ui-stack-state~="gap=m"][data-v-8129c161] {
7662
+ [data-component~="ui-stack"][data-ui-stack-state~="gap=m"][data-v-bdf63b20] {
7591
7663
  --_layout-gap: var(--ui-space-4);
7592
7664
  }
7593
- [data-component~="ui-stack"][data-ui-stack-state~="gap=l"][data-v-8129c161] {
7665
+ [data-component~="ui-stack"][data-ui-stack-state~="gap=l"][data-v-bdf63b20] {
7594
7666
  --_layout-gap: var(--ui-space-5);
7595
7667
  }
7596
- [data-component~="ui-stack"][data-ui-stack-state~="gap=xl"][data-v-8129c161] {
7668
+ [data-component~="ui-stack"][data-ui-stack-state~="gap=xl"][data-v-bdf63b20] {
7597
7669
  --_layout-gap: var(--ui-space-6);
7598
7670
  }
7599
- [data-component~="ui-stack"][data-ui-stack-state~="align=start"][data-v-8129c161] {
7671
+ [data-component~="ui-stack"][data-ui-stack-state~="align=start"][data-v-bdf63b20] {
7600
7672
  align-items: flex-start;
7601
7673
  }
7602
- [data-component~="ui-stack"][data-ui-stack-state~="align=center"][data-v-8129c161] {
7674
+ [data-component~="ui-stack"][data-ui-stack-state~="align=center"][data-v-bdf63b20] {
7603
7675
  align-items: center;
7604
7676
  }
7605
- [data-component~="ui-stack"][data-ui-stack-state~="align=end"][data-v-8129c161] {
7677
+ [data-component~="ui-stack"][data-ui-stack-state~="align=end"][data-v-bdf63b20] {
7606
7678
  align-items: flex-end;
7607
7679
  }
7608
- [data-component~="ui-stack"][data-ui-stack-state~="justify=center"][data-v-8129c161] {
7680
+ [data-component~="ui-stack"][data-ui-stack-state~="justify=center"][data-v-bdf63b20] {
7609
7681
  justify-content: center;
7610
7682
  }
7611
- [data-component~="ui-stack"][data-ui-stack-state~="justify=end"][data-v-8129c161] {
7683
+ [data-component~="ui-stack"][data-ui-stack-state~="justify=end"][data-v-bdf63b20] {
7612
7684
  justify-content: flex-end;
7613
7685
  }
7614
- [data-component~="ui-stack"][data-ui-stack-state~="justify=between"][data-v-8129c161] {
7686
+ [data-component~="ui-stack"][data-ui-stack-state~="justify=between"][data-v-bdf63b20] {
7615
7687
  justify-content: space-between;
7616
7688
  }
7617
7689
 
7618
7690
  /* A component that sets its display still honours the hidden attribute on its root. */
7619
- [data-component~="ui-stack"][hidden][data-v-8129c161] {
7691
+ [data-component~="ui-stack"][hidden][data-v-bdf63b20] {
7620
7692
  display: none;
7621
7693
  }
7622
7694
 
@@ -8159,7 +8231,10 @@ tbody tr[data-v-93c9ac9c-s]:last-child > * {
8159
8231
  /* Running text, set on the type scale and in a tone that says what it is, so a view never styles
8160
8232
  text of its own. The root is a paragraph unless as= names a span, div, small, strong, label, or
8161
8233
  heading. */
8162
- [data-component~="ui-text"][data-v-d830471c] {
8234
+ [data-component~="ui-text"][data-ui-text-state~="grow"][data-v-2c821f7e] {
8235
+ flex: 1;
8236
+ }
8237
+ [data-component~="ui-text"][data-v-2c821f7e] {
8163
8238
  margin: 0;
8164
8239
  min-inline-size: 0;
8165
8240
  color: var(--ui-text-primary);
@@ -8168,93 +8243,93 @@ tbody tr[data-v-93c9ac9c-s]:last-child > * {
8168
8243
 
8169
8244
  /* A heading drops the browser's heading size and weight, so size and weight set it as they set
8170
8245
  any text, and inherit keeps the text around it. */
8171
- [data-component~="ui-text"][data-v-d830471c]:is(h2, h3, h4, h5, h6) {
8246
+ [data-component~="ui-text"][data-v-2c821f7e]:is(h2, h3, h4, h5, h6) {
8172
8247
  font-size: inherit;
8173
8248
  font-weight: inherit;
8174
8249
  }
8175
- [data-component~="ui-text"][data-ui-text-state~="size=xs"][data-v-d830471c] {
8250
+ [data-component~="ui-text"][data-ui-text-state~="size=xs"][data-v-2c821f7e] {
8176
8251
  font-size: var(--ui-font-size-xs);
8177
8252
  line-height: var(--ui-line-height);
8178
8253
  }
8179
- [data-component~="ui-text"][data-ui-text-state~="size=sm"][data-v-d830471c] {
8254
+ [data-component~="ui-text"][data-ui-text-state~="size=sm"][data-v-2c821f7e] {
8180
8255
  font-size: var(--ui-font-size-sm);
8181
8256
  line-height: var(--ui-line-height);
8182
8257
  }
8183
- [data-component~="ui-text"][data-ui-text-state~="size=md"][data-v-d830471c] {
8258
+ [data-component~="ui-text"][data-ui-text-state~="size=md"][data-v-2c821f7e] {
8184
8259
  font-size: var(--ui-font-size-md);
8185
8260
  line-height: var(--ui-line-height);
8186
8261
  }
8187
- [data-component~="ui-text"][data-ui-text-state~="size=lg"][data-v-d830471c] {
8262
+ [data-component~="ui-text"][data-ui-text-state~="size=lg"][data-v-2c821f7e] {
8188
8263
  font-size: var(--ui-font-size-lg);
8189
8264
  line-height: var(--ui-line-height-relaxed);
8190
8265
  }
8191
- [data-component~="ui-text"][data-ui-text-state~="tone=secondary"][data-v-d830471c] {
8266
+ [data-component~="ui-text"][data-ui-text-state~="tone=secondary"][data-v-2c821f7e] {
8192
8267
  color: var(--ui-text-secondary);
8193
8268
  }
8194
- [data-component~="ui-text"][data-ui-text-state~="tone=muted"][data-v-d830471c] {
8269
+ [data-component~="ui-text"][data-ui-text-state~="tone=muted"][data-v-2c821f7e] {
8195
8270
  color: var(--ui-text-muted);
8196
8271
  }
8197
- [data-component~="ui-text"][data-ui-text-state~="tone=accent"][data-v-d830471c] {
8272
+ [data-component~="ui-text"][data-ui-text-state~="tone=accent"][data-v-2c821f7e] {
8198
8273
  color: var(--ui-accent-active);
8199
8274
  }
8200
8275
  /* Every status tone uses the text-safe token a subtle badge sets its words in, so text and badges
8201
8276
  in one tone match, and each holds 4.5:1 on sunken surfaces where some base colours fall short. */
8202
- [data-component~="ui-text"][data-ui-text-state~="tone=danger"][data-v-d830471c] {
8277
+ [data-component~="ui-text"][data-ui-text-state~="tone=danger"][data-v-2c821f7e] {
8203
8278
  color: var(--ui-danger-subtle-text);
8204
8279
  }
8205
- [data-component~="ui-text"][data-ui-text-state~="tone=success"][data-v-d830471c] {
8280
+ [data-component~="ui-text"][data-ui-text-state~="tone=success"][data-v-2c821f7e] {
8206
8281
  color: var(--ui-success-subtle-text);
8207
8282
  }
8208
- [data-component~="ui-text"][data-ui-text-state~="tone=info"][data-v-d830471c] {
8283
+ [data-component~="ui-text"][data-ui-text-state~="tone=info"][data-v-2c821f7e] {
8209
8284
  color: var(--ui-info-subtle-text);
8210
8285
  }
8211
- [data-component~="ui-text"][data-ui-text-state~="tone=warning"][data-v-d830471c] {
8286
+ [data-component~="ui-text"][data-ui-text-state~="tone=warning"][data-v-2c821f7e] {
8212
8287
  color: var(--ui-warning-subtle-text);
8213
8288
  }
8214
- [data-component~="ui-text"][data-ui-text-state~="weight=normal"][data-v-d830471c] {
8289
+ [data-component~="ui-text"][data-ui-text-state~="weight=normal"][data-v-2c821f7e] {
8215
8290
  font-weight: var(--ui-font-normal);
8216
8291
  }
8217
- [data-component~="ui-text"][data-ui-text-state~="weight=medium"][data-v-d830471c] {
8292
+ [data-component~="ui-text"][data-ui-text-state~="weight=medium"][data-v-2c821f7e] {
8218
8293
  font-weight: var(--ui-font-medium);
8219
8294
  }
8220
- [data-component~="ui-text"][data-ui-text-state~="weight=semibold"][data-v-d830471c] {
8295
+ [data-component~="ui-text"][data-ui-text-state~="weight=semibold"][data-v-2c821f7e] {
8221
8296
  font-weight: var(--ui-font-semibold);
8222
8297
  }
8223
- [data-component~="ui-text"][data-ui-text-state~="variant=eyebrow"][data-v-d830471c] {
8298
+ [data-component~="ui-text"][data-ui-text-state~="variant=eyebrow"][data-v-2c821f7e] {
8224
8299
  font-size: var(--ui-font-size-xs);
8225
8300
  font-weight: var(--ui-font-semibold);
8226
8301
  letter-spacing: 0.06em;
8227
8302
  text-transform: uppercase;
8228
8303
  }
8229
- [data-component~="ui-text"][data-ui-text-state~="variant=code"][data-v-d830471c] {
8304
+ [data-component~="ui-text"][data-ui-text-state~="variant=code"][data-v-2c821f7e] {
8230
8305
  font-family: var(--ui-font-family-mono);
8231
8306
  }
8232
8307
 
8233
8308
  /* A link in running text is underlined, so it stands apart from the words around it by more than
8234
8309
  colour. */
8235
- [data-component~="ui-text"] a[data-v-d830471c-s] {
8310
+ [data-component~="ui-text"] a[data-v-2c821f7e-s] {
8236
8311
  color: var(--ui-accent-active);
8237
8312
  text-decoration: underline;
8238
8313
  text-decoration-thickness: 0.06em;
8239
8314
  text-underline-offset: 0.18em;
8240
8315
  }
8241
- [data-component~="ui-text"][data-ui-text-state~="truncate"][data-v-d830471c] {
8316
+ [data-component~="ui-text"][data-ui-text-state~="truncate"][data-v-2c821f7e] {
8242
8317
  overflow: hidden;
8243
8318
  text-overflow: ellipsis;
8244
8319
  white-space: nowrap;
8245
8320
  }
8246
- [data-component~="ui-text"][data-ui-text-state~="align=center"][data-v-d830471c] {
8321
+ [data-component~="ui-text"][data-ui-text-state~="align=center"][data-v-2c821f7e] {
8247
8322
  text-align: center;
8248
8323
  }
8249
- [data-component~="ui-text"][data-ui-text-state~="font=sans"][data-v-d830471c] {
8324
+ [data-component~="ui-text"][data-ui-text-state~="font=sans"][data-v-2c821f7e] {
8250
8325
  font-family: var(--ui-font-family-sans, sans-serif);
8251
8326
  }
8252
- [data-component~="ui-text"][data-ui-text-state~="wrap=anywhere"][data-v-d830471c] {
8327
+ [data-component~="ui-text"][data-ui-text-state~="wrap=anywhere"][data-v-2c821f7e] {
8253
8328
  overflow-wrap: anywhere;
8254
8329
  }
8255
8330
 
8256
8331
  /* A component that sets its display still honours the hidden attribute on its root. */
8257
- [data-component~="ui-text"][hidden][data-v-d830471c] {
8332
+ [data-component~="ui-text"][hidden][data-v-2c821f7e] {
8258
8333
  display: none;
8259
8334
  }
8260
8335
 
@@ -8307,7 +8382,7 @@ tbody tr[data-v-93c9ac9c-s]:last-child > * {
8307
8382
  syntax: "*";
8308
8383
  inherits: false;
8309
8384
  }
8310
- [data-component~="ui-textarea"][data-v-f5b6ae17] {
8385
+ [data-component~="ui-textarea"][data-v-4fc6e397] {
8311
8386
  box-sizing: border-box;
8312
8387
  display: inline-block;
8313
8388
  inline-size: 100%;
@@ -8352,15 +8427,15 @@ tbody tr[data-v-93c9ac9c-s]:last-child > * {
8352
8427
  }
8353
8428
 
8354
8429
  /* Tabbing into a field selects its text; tint that selection softly instead of the page highlight. */
8355
- [data-component~="ui-textarea"][data-v-f5b6ae17]::selection {
8430
+ [data-component~="ui-textarea"][data-v-4fc6e397]::selection {
8356
8431
  background: color-mix(in srgb, var(--ui-accent-solid) 20%, transparent);
8357
8432
  color: inherit;
8358
8433
  }
8359
- [data-component~="ui-textarea"][data-v-f5b6ae17]::placeholder {
8434
+ [data-component~="ui-textarea"][data-v-4fc6e397]::placeholder {
8360
8435
  color: var(--ui-control-placeholder, var(--ui-text-secondary));
8361
8436
  opacity: 1;
8362
8437
  }
8363
- [data-component~="ui-textarea"][data-v-f5b6ae17]:hover:not(:focus):not(:disabled):not(:read-only):not([aria-invalid="true"]):not(:is(:user-invalid, [data-user-invalid])) {
8438
+ [data-component~="ui-textarea"][data-v-4fc6e397]:hover:not(:focus):not(:disabled):not(:read-only):not([aria-invalid="true"]):not(:is(:user-invalid, [data-user-invalid])) {
8364
8439
  border-color: var(
8365
8440
  --ui-textarea-border-hover,
8366
8441
  var(
@@ -8369,7 +8444,7 @@ tbody tr[data-v-93c9ac9c-s]:last-child > * {
8369
8444
  )
8370
8445
  );
8371
8446
  }
8372
- [data-component~="ui-textarea"][data-v-f5b6ae17]:focus-visible {
8447
+ [data-component~="ui-textarea"][data-v-4fc6e397]:focus-visible {
8373
8448
  border-color: var(
8374
8449
  --ui-textarea-focus-border,
8375
8450
  var(--_ui-default-textarea-focus-border, var(--ui-control-focus, var(--ui-accent-solid)))
@@ -8386,14 +8461,14 @@ tbody tr[data-v-93c9ac9c-s]:last-child > * {
8386
8461
  }
8387
8462
 
8388
8463
  /* The app's invalid flag, or the browser's own verdict once the user has left an invalid field. */
8389
- [data-component~="ui-textarea"][aria-invalid="true"][data-v-f5b6ae17],
8390
- [data-component~="ui-textarea"][data-v-f5b6ae17]:is(:user-invalid, [data-user-invalid]) {
8464
+ [data-component~="ui-textarea"][aria-invalid="true"][data-v-4fc6e397],
8465
+ [data-component~="ui-textarea"][data-v-4fc6e397]:is(:user-invalid, [data-user-invalid]) {
8391
8466
  border-color: var(
8392
8467
  --ui-textarea-invalid-border,
8393
8468
  var(--_ui-default-textarea-invalid-border, var(--ui-field-danger, var(--ui-danger-solid)))
8394
8469
  );
8395
8470
  }
8396
- [data-component~="ui-textarea"][data-v-f5b6ae17]:is([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])):focus-visible {
8471
+ [data-component~="ui-textarea"][data-v-4fc6e397]:is([aria-invalid="true"], :is(:user-invalid, [data-user-invalid])):focus-visible {
8397
8472
  box-shadow: var(
8398
8473
  --ui-textarea-invalid-focus-shadow,
8399
8474
  var(
@@ -8410,13 +8485,13 @@ tbody tr[data-v-93c9ac9c-s]:last-child > * {
8410
8485
  )
8411
8486
  );
8412
8487
  }
8413
- [data-component~="ui-textarea"][data-v-f5b6ae17]:disabled {
8488
+ [data-component~="ui-textarea"][data-v-4fc6e397]:disabled {
8414
8489
  background: var(--ui-control-surface-disabled, var(--ui-surface-muted));
8415
8490
  color: var(--ui-disabled-text);
8416
8491
  box-shadow: none;
8417
8492
  cursor: not-allowed;
8418
8493
  }
8419
- [data-component~="ui-textarea"][data-ui-textarea-state~="size=sm"][data-v-f5b6ae17] {
8494
+ [data-component~="ui-textarea"][data-ui-textarea-state~="size=sm"][data-v-4fc6e397] {
8420
8495
  --_padding-block: var(--ui-space-1);
8421
8496
  padding: var(--ui-space-1) var(--ui-space-2);
8422
8497
  padding-inline-end: var(
@@ -8425,7 +8500,7 @@ tbody tr[data-v-93c9ac9c-s]:last-child > * {
8425
8500
  );
8426
8501
  font-size: var(--ui-font-size-sm);
8427
8502
  }
8428
- [data-component~="ui-textarea"][data-ui-textarea-state~="size=lg"][data-v-f5b6ae17] {
8503
+ [data-component~="ui-textarea"][data-ui-textarea-state~="size=lg"][data-v-4fc6e397] {
8429
8504
  --_padding-block: var(--ui-space-3);
8430
8505
  padding: var(--ui-space-3) var(--ui-space-4);
8431
8506
  padding-inline-end: var(
@@ -8434,8 +8509,13 @@ tbody tr[data-v-93c9ac9c-s]:last-child > * {
8434
8509
  );
8435
8510
  font-size: var(--ui-font-size-md);
8436
8511
  }
8512
+ [data-component~="ui-textarea"][data-ui-textarea-state~="maxRows"][data-v-4fc6e397] {
8513
+ max-block-size: calc(
8514
+ max(var(--_rows), var(--_max-rows)) * 1lh + var(--_padding-block) + var(--_padding-block) + 2px
8515
+ );
8516
+ }
8437
8517
  @supports (field-sizing: content) {
8438
- [data-component~="ui-textarea"][data-ui-textarea-state~="autosize"][data-v-f5b6ae17] {
8518
+ [data-component~="ui-textarea"][data-ui-textarea-state~="autosize"][data-v-4fc6e397] {
8439
8519
  field-sizing: content;
8440
8520
  min-block-size: calc(var(--_rows) * 1lh + var(--_padding-block) + var(--_padding-block) + 2px);
8441
8521
  }
@@ -8443,13 +8523,13 @@ tbody tr[data-v-93c9ac9c-s]:last-child > * {
8443
8523
 
8444
8524
  /* Below 16px, iOS zooms the page into the focused field, so touch keeps body-size text. */
8445
8525
  @media (pointer: coarse) {
8446
- [data-component~="ui-textarea"][data-ui-textarea-state~="size=sm"][data-v-f5b6ae17] {
8526
+ [data-component~="ui-textarea"][data-ui-textarea-state~="size=sm"][data-v-4fc6e397] {
8447
8527
  font-size: inherit;
8448
8528
  }
8449
8529
  }
8450
8530
 
8451
8531
  /* A component that sets its display still honours the hidden attribute on its root. */
8452
- [data-component~="ui-textarea"][hidden][data-v-f5b6ae17] {
8532
+ [data-component~="ui-textarea"][hidden][data-v-4fc6e397] {
8453
8533
  display: none;
8454
8534
  }
8455
8535
 
@@ -9410,24 +9490,12 @@ html[data-ui-input-modality="touch"]
9410
9490
  [data-component~="ui-tree-item"][hidden][data-v-f2ec0a81] {
9411
9491
  display: none;
9412
9492
  }
9413
- /**
9414
- * Looma editor styles (tokens-based).
9415
- * Tables, context menu, insert-table grid, slash menu. Use with ProseMirror/Tiptap content.
9416
- */
9417
-
9418
- /* Turnkey editor */
9419
- .looma-editor {
9420
- position: relative;
9421
- min-width: 0;
9422
- color: var(--ui-text-primary);
9423
- font-family: var(--ui-font-family-sans);
9424
- }
9425
-
9426
- .looma-editor .ProseMirror {
9427
- min-height: var(--ui-editor-content-min-height, 300px);
9493
+ /* The editor surface owns its renderer canvas. Existing hooks retain their defaults. */
9494
+ [data-component~="ui-editor-surface"] .ProseMirror {
9495
+ min-height: var(--ui-editor-content-min-height, var(--_ui-editor-content-min-height, 300px));
9428
9496
  padding:
9429
- var(--ui-editor-content-padding-block, var(--ui-space-4))
9430
- var(--ui-editor-content-padding-inline, var(--ui-space-6));
9497
+ var(--ui-editor-content-padding-block, var(--_ui-editor-content-padding-block, var(--ui-space-4)))
9498
+ var(--ui-editor-content-padding-inline, var(--_ui-editor-content-padding-inline, var(--ui-space-6)));
9431
9499
  outline: none;
9432
9500
  color: var(--ui-editor-content-color, var(--ui-text-primary));
9433
9501
  caret-color: var(--ui-editor-caret-color, var(--ui-accent-solid));
@@ -9437,11 +9505,27 @@ html[data-ui-input-modality="touch"]
9437
9505
  }
9438
9506
 
9439
9507
  @media (max-width: 767px) {
9440
- .looma-editor .ProseMirror {
9441
- padding-bottom: var(--ui-editor-mobile-bottom-space, 80px);
9508
+ [data-component~="ui-editor-surface"] .ProseMirror {
9509
+ padding-bottom: var(--ui-editor-mobile-bottom-space, var(--_ui-editor-mobile-bottom-space, 80px));
9442
9510
  }
9443
9511
  }
9444
9512
 
9513
+
9514
+ [data-component~="ui-editor-surface"][data-density="compact"] .ProseMirror > :first-child { margin-block-start: 0; }
9515
+ [data-component~="ui-editor-surface"][data-density="compact"] .ProseMirror > :last-child { margin-block-end: 0; }
9516
+ /**
9517
+ * Looma editor styles (tokens-based).
9518
+ * Tables, context menu, insert-table grid, slash menu. Use with ProseMirror/Tiptap content.
9519
+ */
9520
+
9521
+ /* Turnkey editor */
9522
+ .looma-editor {
9523
+ position: relative;
9524
+ min-width: 0;
9525
+ color: var(--ui-text-primary);
9526
+ font-family: var(--ui-font-family-sans);
9527
+ }
9528
+
9445
9529
  /*
9446
9530
  * Marker for the block being edited, drawn in the gutter beside the text rather
9447
9531
  * than around it: a border or fill on the reading column reads as a form field.
@@ -1,3 +1,4 @@
1
+ import "../../components/ui-editor-surface/ui-editor-surface.css";
1
2
  import "./looma-editor.css";
2
3
  import { type AnyExtension, type Editor, type JSONContent } from "@tiptap/core";
3
4
  import { type PropType, type VNode } from "vue";
@@ -85,6 +86,11 @@ export declare const LoomaEditor: import("vue").DefineComponent<import("vue").Ex
85
86
  type: BooleanConstructor;
86
87
  default: boolean;
87
88
  };
89
+ /** Compact read-only excerpts fit their content; editable documents retain the standard canvas. */
90
+ contentDensity: {
91
+ type: PropType<"comfortable" | "compact">;
92
+ default: string;
93
+ };
88
94
  placeholder: {
89
95
  type: StringConstructor;
90
96
  default: string;
@@ -201,6 +207,11 @@ export declare const LoomaEditor: import("vue").DefineComponent<import("vue").Ex
201
207
  type: BooleanConstructor;
202
208
  default: boolean;
203
209
  };
210
+ /** Compact read-only excerpts fit their content; editable documents retain the standard canvas. */
211
+ contentDensity: {
212
+ type: PropType<"comfortable" | "compact">;
213
+ default: string;
214
+ };
204
215
  placeholder: {
205
216
  type: StringConstructor;
206
217
  default: string;
@@ -303,6 +314,7 @@ export declare const LoomaEditor: import("vue").DefineComponent<import("vue").Ex
303
314
  codeLanguages: Readonly<Record<string, import("highlight.js").LanguageFn>> | null;
304
315
  modelValue: JSONContent;
305
316
  editable: boolean;
317
+ contentDensity: "compact" | "comfortable";
306
318
  extensions: AnyExtension[];
307
319
  slashCommands: LoomaEditorSlashCommands;
308
320
  mentionItems: LoomaMentionItem[];