@crewlethq/tokens 0.17.1 → 0.18.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.
package/README.md CHANGED
@@ -45,6 +45,19 @@ const accent = color.brand.accent;
45
45
  CSS variables follow Style Dictionary's `--{group}-{path}` convention,
46
46
  for example `var(--color-brand-accent)` or `var(--spacing-4)`.
47
47
 
48
+ ## Changed in 0.18.0: presence, change marks and the sheet row
49
+
50
+ Five tokens for the collaborative sheet and the presence marks. Nothing that existed moved.
51
+
52
+ | What changed | What to change | Details |
53
+ | --- | --- | --- |
54
+ | `--color-presence-flag-text` (`color.presence.flagText`) is new, in every palette of every theme: the ink of the name on a presence flag, which is filled with the collaborator's node hue. | Nothing. | [Presence](#presence) |
55
+ | `--color-change-mark` (`color.changeMark`) is new: an alias of `--color-brand-accent-soft-strong`, for the corner mark on a changed cell. | Nothing. | [Presence](#presence) |
56
+ | `--shadow-cursor` (`shadow.cursor`) is new: an alias of `--shadow-sm`, under a live cursor and its flag. | Nothing. | [Presence](#presence) |
57
+ | `--z-index-presence` (`zIndex.presence`, 20) is new: collaborators' marks over content, above sticky headers and below every menu and layer. | Nothing. | [Presence](#presence) |
58
+ | `--size-sheet-row` (`size.sheet.row`, 32px) is new and density-scaled, so its three density steps are 26.24px, 32px and 37.12px. | Nothing. | [Density](#density) |
59
+ | In `@crewlethq/tokens/test/palette`, the rules `a presence flag name clears 4.5:1 on every node hue` and `a presence hue clears 3:1 as a mark` are new, with the exports `PRESENCE_HUES` and `PRESENCE_FLAG_TEXT`. | Nothing. | [Presence](#presence) |
60
+
48
61
  ## Changed in 0.13.0: named themes
49
62
 
50
63
  Nine named themes ship beside the default, each with a dark and a light palette, for an application that offers a theme picker. A document that sets no `data-palette` attribute is painted exactly as before, and no default value moved.
@@ -284,6 +297,8 @@ The control steps are the approved design's control rhythm: `--size-control-md`
284
297
 
285
298
  `--size-target-min` (24px) is that same floor, named, for a component that DERIVES a height from a control step rather than taking one. Subtracting from a step subtracts from its floor too, so `calc(var(--size-control-md) - 6px)` is 18.6px at compact density; `max(var(--size-target-min), calc(var(--size-control-md) - 6px))` is the 24px a chip in a segmented well stands at density 1, and still a reachable target at every other.
286
299
 
300
+ `--size-sheet-row` (32px) is the height of a row in an editable data sheet, density-scaled like every row: 26.24px compact, 32px normal and 37.12px comfortable. A sheet measures the resolved height rather than restating the number, so its virtualised rows stay in step with the density.
301
+
287
302
  `--radius-chip` is `calc(var(--radius-md) - 1px)`, the corner of a chip lifted inside a well drawn at `--radius-md`. It is derived rather than written as a step of its own, so it follows the well.
288
303
 
289
304
  ### Changed in 0.5.0: the control steps
@@ -416,6 +431,19 @@ A phase is a category. The agent's phases (onboarding, execute, review, and what
416
431
 
417
432
  A `-soft` step is its own fill at alpha 0.12 and a `-line` step is the same fill at alpha 0.30. They are derived by the build from the fill, per palette, so a tint cannot come to belong to a hue the fill no longer is.
418
433
 
434
+ ### Presence
435
+
436
+ A collaborator's presence colour is the one narrow exception to "colour carries state, never identity". It is one of the six node hues (`--color-node-{purple,cyan,green,amber,rose,blue}`): an agent's chosen hue, or a hue a person is given for the session in join order. It is drawn on four marks only, a live cursor, a selection ring, a cell outline and a name flag, and always beside the name, never on chrome and never as a state.
437
+
438
+ | Token | Dark | Light | What it is |
439
+ | --- | --- | --- | --- |
440
+ | `--color-presence-flag-text` | `#07080d` | `#ffffff` | The name on a flag filled with a node hue. Every dark node hue is a mid tone that black clears and white does not, and every light one is a deep tone, so the ink flips with the mode. |
441
+ | `--color-change-mark` | the accent at 0.32 | the accent at 0.32 | The corner mark on a cell that changed since the reader last looked, an alias of `--color-brand-accent-soft-strong`. It is always paired with a tooltip that names who changed it and what it was. |
442
+ | `--shadow-cursor` | `--shadow-sm` | `--shadow-sm` | The lift under a live cursor and its flag. |
443
+ | `--z-index-presence` | 20 | 20 | Above sticky headers and frozen columns, below every menu, popover and dialog. |
444
+
445
+ The palette suite holds the flag's name at 4.5:1 on each of the six hues, and each hue at 3:1 as a mark on every rung, in every palette of every theme. The high-contrast theme keeps the same 4.5: the hue is the collaborator's identity rather than a palette's step, and the name is also said in words wherever presence is listed.
446
+
419
447
  ### The accent
420
448
 
421
449
  The accent is a violet, and it is **per palette**:
@@ -93,6 +93,7 @@
93
93
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
94
94
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
95
95
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
96
+ --color-presence-flag-text: #07080d;
96
97
  --color-scrollbar: rgba(255, 255, 255, 0.16);
97
98
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
98
99
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -199,6 +200,7 @@
199
200
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
200
201
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
201
202
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
203
+ --color-presence-flag-text: #ffffff;
202
204
  --color-scrollbar: rgba(7, 8, 13, 0.2);
203
205
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
204
206
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -305,6 +307,7 @@
305
307
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
306
308
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
307
309
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
310
+ --color-presence-flag-text: #ffffff;
308
311
  --color-scrollbar: rgba(7, 8, 13, 0.2);
309
312
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
310
313
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -95,6 +95,7 @@
95
95
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
96
96
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
97
97
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
98
+ --color-presence-flag-text: #07080d;
98
99
  --color-scrollbar: rgba(255, 255, 255, 0.16);
99
100
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
100
101
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -201,6 +202,7 @@
201
202
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
202
203
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
203
204
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
205
+ --color-presence-flag-text: #ffffff;
204
206
  --color-scrollbar: rgba(7, 8, 13, 0.2);
205
207
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
206
208
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -307,6 +309,7 @@
307
309
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
308
310
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
309
311
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
312
+ --color-presence-flag-text: #ffffff;
310
313
  --color-scrollbar: rgba(7, 8, 13, 0.2);
311
314
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
312
315
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -413,6 +416,7 @@
413
416
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
414
417
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
415
418
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
419
+ --color-presence-flag-text: #07080d;
416
420
  --color-scrollbar: rgba(255, 255, 255, 0.16);
417
421
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
418
422
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -519,6 +523,7 @@
519
523
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
520
524
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
521
525
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
526
+ --color-presence-flag-text: #ffffff;
522
527
  --color-scrollbar: rgba(7, 8, 13, 0.2);
523
528
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
524
529
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -625,6 +630,7 @@
625
630
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
626
631
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
627
632
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
633
+ --color-presence-flag-text: #ffffff;
628
634
  --color-scrollbar: rgba(7, 8, 13, 0.2);
629
635
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
630
636
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -731,6 +737,7 @@
731
737
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
732
738
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
733
739
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
740
+ --color-presence-flag-text: #07080d;
734
741
  --color-scrollbar: rgba(255, 255, 255, 0.16);
735
742
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
736
743
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -837,6 +844,7 @@
837
844
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
838
845
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
839
846
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
847
+ --color-presence-flag-text: #ffffff;
840
848
  --color-scrollbar: rgba(7, 8, 13, 0.2);
841
849
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
842
850
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -943,6 +951,7 @@
943
951
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
944
952
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
945
953
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
954
+ --color-presence-flag-text: #ffffff;
946
955
  --color-scrollbar: rgba(7, 8, 13, 0.2);
947
956
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
948
957
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -1049,6 +1058,7 @@
1049
1058
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
1050
1059
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
1051
1060
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
1061
+ --color-presence-flag-text: #07080d;
1052
1062
  --color-scrollbar: rgba(255, 255, 255, 0.16);
1053
1063
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
1054
1064
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -1155,6 +1165,7 @@
1155
1165
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
1156
1166
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
1157
1167
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
1168
+ --color-presence-flag-text: #ffffff;
1158
1169
  --color-scrollbar: rgba(7, 8, 13, 0.2);
1159
1170
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
1160
1171
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -1261,6 +1272,7 @@
1261
1272
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
1262
1273
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
1263
1274
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
1275
+ --color-presence-flag-text: #ffffff;
1264
1276
  --color-scrollbar: rgba(7, 8, 13, 0.2);
1265
1277
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
1266
1278
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -1367,6 +1379,7 @@
1367
1379
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
1368
1380
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
1369
1381
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
1382
+ --color-presence-flag-text: #07080d;
1370
1383
  --color-scrollbar: rgba(255, 255, 255, 0.16);
1371
1384
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
1372
1385
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -1473,6 +1486,7 @@
1473
1486
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
1474
1487
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
1475
1488
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
1489
+ --color-presence-flag-text: #ffffff;
1476
1490
  --color-scrollbar: rgba(7, 8, 13, 0.2);
1477
1491
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
1478
1492
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -1579,6 +1593,7 @@
1579
1593
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
1580
1594
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
1581
1595
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
1596
+ --color-presence-flag-text: #ffffff;
1582
1597
  --color-scrollbar: rgba(7, 8, 13, 0.2);
1583
1598
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
1584
1599
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -1685,6 +1700,7 @@
1685
1700
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
1686
1701
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
1687
1702
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
1703
+ --color-presence-flag-text: #07080d;
1688
1704
  --color-scrollbar: rgba(255, 255, 255, 0.16);
1689
1705
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
1690
1706
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -1791,6 +1807,7 @@
1791
1807
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
1792
1808
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
1793
1809
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
1810
+ --color-presence-flag-text: #ffffff;
1794
1811
  --color-scrollbar: rgba(7, 8, 13, 0.2);
1795
1812
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
1796
1813
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -1897,6 +1914,7 @@
1897
1914
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
1898
1915
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
1899
1916
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
1917
+ --color-presence-flag-text: #ffffff;
1900
1918
  --color-scrollbar: rgba(7, 8, 13, 0.2);
1901
1919
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
1902
1920
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -2003,6 +2021,7 @@
2003
2021
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
2004
2022
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
2005
2023
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
2024
+ --color-presence-flag-text: #07080d;
2006
2025
  --color-scrollbar: rgba(255, 255, 255, 0.16);
2007
2026
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
2008
2027
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -2109,6 +2128,7 @@
2109
2128
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
2110
2129
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
2111
2130
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
2131
+ --color-presence-flag-text: #ffffff;
2112
2132
  --color-scrollbar: rgba(7, 8, 13, 0.2);
2113
2133
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
2114
2134
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -2215,6 +2235,7 @@
2215
2235
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
2216
2236
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
2217
2237
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
2238
+ --color-presence-flag-text: #ffffff;
2218
2239
  --color-scrollbar: rgba(7, 8, 13, 0.2);
2219
2240
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
2220
2241
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -2321,6 +2342,7 @@
2321
2342
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
2322
2343
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
2323
2344
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
2345
+ --color-presence-flag-text: #07080d;
2324
2346
  --color-scrollbar: rgba(255, 255, 255, 0.16);
2325
2347
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
2326
2348
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -2427,6 +2449,7 @@
2427
2449
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
2428
2450
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
2429
2451
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
2452
+ --color-presence-flag-text: #ffffff;
2430
2453
  --color-scrollbar: rgba(7, 8, 13, 0.2);
2431
2454
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
2432
2455
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -2533,6 +2556,7 @@
2533
2556
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
2534
2557
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
2535
2558
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
2559
+ --color-presence-flag-text: #ffffff;
2536
2560
  --color-scrollbar: rgba(7, 8, 13, 0.2);
2537
2561
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
2538
2562
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -2639,6 +2663,7 @@
2639
2663
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
2640
2664
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
2641
2665
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
2666
+ --color-presence-flag-text: #07080d;
2642
2667
  --color-scrollbar: rgba(255, 255, 255, 0.16);
2643
2668
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
2644
2669
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -2745,6 +2770,7 @@
2745
2770
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
2746
2771
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
2747
2772
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
2773
+ --color-presence-flag-text: #ffffff;
2748
2774
  --color-scrollbar: rgba(7, 8, 13, 0.2);
2749
2775
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
2750
2776
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -2851,6 +2877,7 @@
2851
2877
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
2852
2878
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
2853
2879
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
2880
+ --color-presence-flag-text: #ffffff;
2854
2881
  --color-scrollbar: rgba(7, 8, 13, 0.2);
2855
2882
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
2856
2883
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -93,6 +93,7 @@
93
93
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
94
94
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
95
95
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
96
+ --color-presence-flag-text: #07080d;
96
97
  --color-scrollbar: rgba(255, 255, 255, 0.16);
97
98
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
98
99
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -199,6 +200,7 @@
199
200
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
200
201
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
201
202
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
203
+ --color-presence-flag-text: #ffffff;
202
204
  --color-scrollbar: rgba(7, 8, 13, 0.2);
203
205
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
204
206
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -305,6 +307,7 @@
305
307
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
306
308
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
307
309
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
310
+ --color-presence-flag-text: #ffffff;
308
311
  --color-scrollbar: rgba(7, 8, 13, 0.2);
309
312
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
310
313
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -93,6 +93,7 @@
93
93
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
94
94
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
95
95
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
96
+ --color-presence-flag-text: #07080d;
96
97
  --color-scrollbar: rgba(255, 255, 255, 0.16);
97
98
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
98
99
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -199,6 +200,7 @@
199
200
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
200
201
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
201
202
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
203
+ --color-presence-flag-text: #ffffff;
202
204
  --color-scrollbar: rgba(7, 8, 13, 0.2);
203
205
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
204
206
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -305,6 +307,7 @@
305
307
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
306
308
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
307
309
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
310
+ --color-presence-flag-text: #ffffff;
308
311
  --color-scrollbar: rgba(7, 8, 13, 0.2);
309
312
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
310
313
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -93,6 +93,7 @@
93
93
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
94
94
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
95
95
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
96
+ --color-presence-flag-text: #07080d;
96
97
  --color-scrollbar: rgba(255, 255, 255, 0.16);
97
98
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
98
99
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -199,6 +200,7 @@
199
200
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
200
201
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
201
202
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
203
+ --color-presence-flag-text: #ffffff;
202
204
  --color-scrollbar: rgba(7, 8, 13, 0.2);
203
205
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
204
206
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -305,6 +307,7 @@
305
307
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
306
308
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
307
309
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
310
+ --color-presence-flag-text: #ffffff;
308
311
  --color-scrollbar: rgba(7, 8, 13, 0.2);
309
312
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
310
313
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -93,6 +93,7 @@
93
93
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
94
94
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
95
95
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
96
+ --color-presence-flag-text: #07080d;
96
97
  --color-scrollbar: rgba(255, 255, 255, 0.16);
97
98
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
98
99
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -199,6 +200,7 @@
199
200
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
200
201
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
201
202
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
203
+ --color-presence-flag-text: #ffffff;
202
204
  --color-scrollbar: rgba(7, 8, 13, 0.2);
203
205
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
204
206
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -305,6 +307,7 @@
305
307
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
306
308
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
307
309
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
310
+ --color-presence-flag-text: #ffffff;
308
311
  --color-scrollbar: rgba(7, 8, 13, 0.2);
309
312
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
310
313
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -93,6 +93,7 @@
93
93
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
94
94
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
95
95
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
96
+ --color-presence-flag-text: #07080d;
96
97
  --color-scrollbar: rgba(255, 255, 255, 0.16);
97
98
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
98
99
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -199,6 +200,7 @@
199
200
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
200
201
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
201
202
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
203
+ --color-presence-flag-text: #ffffff;
202
204
  --color-scrollbar: rgba(7, 8, 13, 0.2);
203
205
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
204
206
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -305,6 +307,7 @@
305
307
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
306
308
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
307
309
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
310
+ --color-presence-flag-text: #ffffff;
308
311
  --color-scrollbar: rgba(7, 8, 13, 0.2);
309
312
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
310
313
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -93,6 +93,7 @@
93
93
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
94
94
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
95
95
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
96
+ --color-presence-flag-text: #07080d;
96
97
  --color-scrollbar: rgba(255, 255, 255, 0.16);
97
98
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
98
99
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -199,6 +200,7 @@
199
200
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
200
201
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
201
202
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
203
+ --color-presence-flag-text: #ffffff;
202
204
  --color-scrollbar: rgba(7, 8, 13, 0.2);
203
205
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
204
206
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -305,6 +307,7 @@
305
307
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
306
308
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
307
309
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
310
+ --color-presence-flag-text: #ffffff;
308
311
  --color-scrollbar: rgba(7, 8, 13, 0.2);
309
312
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
310
313
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -93,6 +93,7 @@
93
93
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
94
94
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
95
95
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
96
+ --color-presence-flag-text: #07080d;
96
97
  --color-scrollbar: rgba(255, 255, 255, 0.16);
97
98
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
98
99
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -199,6 +200,7 @@
199
200
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
200
201
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
201
202
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
203
+ --color-presence-flag-text: #ffffff;
202
204
  --color-scrollbar: rgba(7, 8, 13, 0.2);
203
205
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
204
206
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -305,6 +307,7 @@
305
307
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
306
308
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
307
309
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
310
+ --color-presence-flag-text: #ffffff;
308
311
  --color-scrollbar: rgba(7, 8, 13, 0.2);
309
312
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
310
313
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -93,6 +93,7 @@
93
93
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
94
94
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
95
95
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
96
+ --color-presence-flag-text: #07080d;
96
97
  --color-scrollbar: rgba(255, 255, 255, 0.16);
97
98
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
98
99
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -199,6 +200,7 @@
199
200
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
200
201
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
201
202
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
203
+ --color-presence-flag-text: #ffffff;
202
204
  --color-scrollbar: rgba(7, 8, 13, 0.2);
203
205
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
204
206
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -305,6 +307,7 @@
305
307
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
306
308
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
307
309
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
310
+ --color-presence-flag-text: #ffffff;
308
311
  --color-scrollbar: rgba(7, 8, 13, 0.2);
309
312
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
310
313
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -99,6 +99,7 @@
99
99
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
100
100
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
101
101
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
102
+ --color-presence-flag-text: #07080d;
102
103
  --color-scrollbar: rgba(255, 255, 255, 0.16);
103
104
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
104
105
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.2);
@@ -208,6 +209,7 @@
208
209
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
209
210
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
210
211
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
212
+ --color-presence-flag-text: #ffffff;
211
213
  --color-scrollbar: rgba(7, 8, 13, 0.2);
212
214
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
213
215
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -315,6 +317,7 @@
315
317
  --color-node-blue-fill: rgba(64, 98, 167, 0.12);
316
318
  --color-node-blue-line: rgba(64, 98, 167, 0.38);
317
319
  --color-node-blue-halo: rgba(64, 98, 167, 0.16);
320
+ --color-presence-flag-text: #ffffff;
318
321
  --color-scrollbar: rgba(7, 8, 13, 0.2);
319
322
  --color-scrollbar-hover: rgba(7, 8, 13, 0.32);
320
323
  --shadow-xs: 0 1px 2px rgba(7, 8, 13, 0.06);
@@ -116,6 +116,7 @@
116
116
  --color-node-blue-fill: rgba(91, 127, 199, 0.12);
117
117
  --color-node-blue-line: rgba(91, 127, 199, 0.38);
118
118
  --color-node-blue-halo: rgba(91, 127, 199, 0.16);
119
+ --color-presence-flag-text: #07080d; /** The name on a presence flag: the plate a collaborator's cursor, cell or selection is labelled with, filled with that collaborator's node hue. It is the one place a node hue is a ground for text rather than a tint, so its ink is a step of its own, per palette, and the palette suite holds it at 4.5:1 on each of the six hues in every theme. Presence colour is the narrow exception to colour carrying state: it ties a mark to a name, and the name is always on the flag. */
119
120
  --color-scrollbar: rgba(255, 255, 255, 0.16); /** Scrollbars belong to the palette. A bright system gutter down the side of a dark page is the most visible way an application admits it is a web page. */
120
121
  --color-scrollbar-hover: rgba(255, 255, 255, 0.26);
121
122
  --color-qr-dark: #000000; /** A QR code's dark modules. Part of the symbol a camera reads rather than a colour of the palette, so it is the same in every palette and theme and is never spent on anything else. A code is specified dark on light, and some authenticator apps do not read one inverted for a dark theme, which is why it is not themed. */
@@ -163,6 +164,7 @@
163
164
  --size-row-sm: max(24px, calc(28px * var(--density, 1))); /** The height of a list row, so every list in a product lines up with every other. The small step floors at 24px as the control step does. */
164
165
  --size-row-md: calc(36px * var(--density, 1));
165
166
  --size-row-lg: calc(48px * var(--density, 1));
167
+ --size-sheet-row: calc(32px * var(--density, 1)); /** The height of a row in an editable data sheet: a chip, a person badge and a status word each fit on one line in it. Density-scaled like every row, so the three density steps are 26.24px compact, 32px normal and 37.12px comfortable, all over the 24px target floor, and a sheet measures it rather than restating it, which is how its virtualised rows stay in step with the cells drawn in them. */
166
168
  --size-nav-gutter: calc(8px * var(--density, 1)); /** The rail's geometry in TWO parts, because a row's EDGE and a row's TEXT want different insets. The gutter insets the rail, which is where a row's background begins; the row pad insets the content inside the row. Splitting it is what lets the rows widen without moving a glyph: shrink the gutter, grow the pad by the same step, and the line every mark, group label and item text starts on does not move. */
167
169
  --size-nav-row-pad: calc(12px * var(--density, 1));
168
170
  --size-nav-row: calc(30px * var(--density, 1)); /** The height of a row in the rail: a destination, a project, a pinned view. The approved design draws it at 30px, the control rhythm's own height, and a rail row is a step of its own rather than size.row.md (36px, a list's row) because a rail holds fifteen destinations and more in a column the height of the window, where six pixels a row is the difference between the last one on screen and behind the foot. No floor is needed: 30 x 0.82 is 24.6px, over the 24px target at every density. */
@@ -218,6 +220,7 @@
218
220
  --z-index-base: 0;
219
221
  --z-index-raised: 1; /** Lifts an element above its siblings inside its own stacking context, such as a control layered over a card. */
220
222
  --z-index-sticky: 10; /** Sticky headers and pinned columns within the page flow. */
223
+ --z-index-presence: 20; /** Collaborators' marks drawn over content: live cursors, name flags and selection rings. Above sticky headers and frozen columns, so a flag on the first row is not hidden under the header, and below every in-flow menu and the whole layer band, so a menu or a dialog always covers a cursor. */
221
224
  --z-index-dropdown: 100; /** In-flow menus that stay inside their container rather than portaling to the body. */
222
225
  --z-index-overlay: 200; /** In-page overlays such as drawers and scrims that cover page chrome but not dialogs. */
223
226
  --z-index-layer-base: 9000; /** The bottom of the layer stack's own band. A portaled surface takes this plus its DEPTH in the live stack, clamped at layerMax, rather than a number from a counter that only grows: modal, popover and toast leave two free steps between them, so a counter would put the second dialog of a session at the popover level and the third at the toast level. */
@@ -225,6 +228,8 @@
225
228
  --z-index-modal: 9999; /** Dialog backdrop and frame. High enough to clear any page chrome an application stacks with its own numbers. */
226
229
  --z-index-popover: 10000; /** Floating panels portaled to the body (Select menus, Popover, date pickers). Above modal because they are routinely opened from inside a dialog, and a panel under the backdrop is hidden and swallows clicks. */
227
230
  --z-index-toast: 10001; /** Top of the stack. A toast reports the outcome of what somebody just did, often in a dialog or from a menu opened inside one, so it sits above both. */
231
+ --color-change-mark: var(--color-brand-accent-soft-strong); /** The corner mark on a cell or an element that changed since the reader last looked. An alias of the accent's strong soft step, so the meaning has a name of its own and follows the accent in every palette; the mark is always paired with a tooltip that says who changed it and what it was. */
228
232
  --radius-chip: calc(var(--radius-md) - 1px); /** The corner of a chip lifted INSIDE a well at --radius-md: one hairline tighter than the well around it, which is what reads as sitting in it. It sits between sm and md and is derived rather than written as 7px, so it follows --radius-md if that step ever moves. */
233
+ --shadow-cursor: var(--shadow-sm); /** The lift under a collaborator's live cursor and its name flag, so a pointer drawn over content reads as above it. An alias of the small step, so it repaints with the palette. */
229
234
  --font-family-display: var(--font-family-sans); /** Headings and other display type. An alias of the sans family, so a heading costs no extra download. Components keep reading this role token so a dedicated display face would land in one place. */
230
235
  }
package/dist/index.d.ts CHANGED
@@ -134,6 +134,10 @@ export declare const color: {
134
134
  readonly blueLine: "rgba(91, 127, 199, 0.38)";
135
135
  readonly blueHalo: "rgba(91, 127, 199, 0.16)";
136
136
  };
137
+ readonly presence: {
138
+ readonly flagText: "#07080d";
139
+ };
140
+ readonly changeMark: "rgba(124, 86, 255, 0.32)";
137
141
  readonly scrollbar: "rgba(255, 255, 255, 0.16)";
138
142
  readonly scrollbarHover: "rgba(255, 255, 255, 0.26)";
139
143
  readonly qr: {
@@ -189,6 +193,7 @@ export declare const shadow: {
189
193
  readonly hairline: "inset 0 1px 0 rgba(255, 255, 255, 0.04)";
190
194
  readonly focus: "0 0 0 2px var(--color-surface-background), 0 0 0 4px var(--color-focus)";
191
195
  readonly selection: "inset 0 0 0 2px var(--color-brand-accent)";
196
+ readonly cursor: "0 2px 8px rgba(0, 0, 0, 0.15)";
192
197
  readonly glow: "0 4px 24px rgba(var(--color-brand-accent-rgb), 0.3)";
193
198
  };
194
199
  export declare const size: {
@@ -202,6 +207,9 @@ export declare const size: {
202
207
  readonly md: "36px";
203
208
  readonly lg: "48px";
204
209
  };
210
+ readonly sheet: {
211
+ readonly row: "32px";
212
+ };
205
213
  readonly nav: {
206
214
  readonly gutter: "8px";
207
215
  readonly rowPad: "12px";
@@ -278,6 +286,7 @@ export declare const zIndex: {
278
286
  readonly base: "0";
279
287
  readonly raised: "1";
280
288
  readonly sticky: "10";
289
+ readonly presence: "20";
281
290
  readonly dropdown: "100";
282
291
  readonly overlay: "200";
283
292
  readonly layerBase: "9000";
package/dist/index.js CHANGED
@@ -135,6 +135,10 @@ export const color = {
135
135
  "blueLine": "rgba(91, 127, 199, 0.38)",
136
136
  "blueHalo": "rgba(91, 127, 199, 0.16)"
137
137
  },
138
+ "presence": {
139
+ "flagText": "#07080d"
140
+ },
141
+ "changeMark": "rgba(124, 86, 255, 0.32)",
138
142
  "scrollbar": "rgba(255, 255, 255, 0.16)",
139
143
  "scrollbarHover": "rgba(255, 255, 255, 0.26)",
140
144
  "qr": {
@@ -190,6 +194,7 @@ export const shadow = {
190
194
  "hairline": "inset 0 1px 0 rgba(255, 255, 255, 0.04)",
191
195
  "focus": "0 0 0 2px var(--color-surface-background), 0 0 0 4px var(--color-focus)",
192
196
  "selection": "inset 0 0 0 2px var(--color-brand-accent)",
197
+ "cursor": "0 2px 8px rgba(0, 0, 0, 0.15)",
193
198
  "glow": "0 4px 24px rgba(var(--color-brand-accent-rgb), 0.3)"
194
199
  };
195
200
  export const size = {
@@ -203,6 +208,9 @@ export const size = {
203
208
  "md": "36px",
204
209
  "lg": "48px"
205
210
  },
211
+ "sheet": {
212
+ "row": "32px"
213
+ },
206
214
  "nav": {
207
215
  "gutter": "8px",
208
216
  "rowPad": "12px",
@@ -279,6 +287,7 @@ export const zIndex = {
279
287
  "base": "0",
280
288
  "raised": "1",
281
289
  "sticky": "10",
290
+ "presence": "20",
282
291
  "dropdown": "100",
283
292
  "overlay": "200",
284
293
  "layerBase": "9000",
package/dist/themes.d.ts CHANGED
@@ -109,6 +109,9 @@ export declare const themes: {
109
109
  readonly blueLine: "rgba(64, 98, 167, 0.38)";
110
110
  readonly blueHalo: "rgba(64, 98, 167, 0.16)";
111
111
  };
112
+ readonly presence: {
113
+ readonly flagText: "#ffffff";
114
+ };
112
115
  readonly scrollbar: "rgba(7, 8, 13, 0.2)";
113
116
  readonly scrollbarHover: "rgba(7, 8, 13, 0.32)";
114
117
  };
@@ -229,6 +232,9 @@ export declare const themes: {
229
232
  readonly blueLine: "rgba(91, 127, 199, 0.38)";
230
233
  readonly blueHalo: "rgba(91, 127, 199, 0.16)";
231
234
  };
235
+ readonly presence: {
236
+ readonly flagText: "#07080d";
237
+ };
232
238
  readonly scrollbar: "rgba(255, 255, 255, 0.16)";
233
239
  readonly scrollbarHover: "rgba(255, 255, 255, 0.26)";
234
240
  };
package/dist/themes.js CHANGED
@@ -110,6 +110,9 @@ export const themes = {
110
110
  "blueLine": "rgba(64, 98, 167, 0.38)",
111
111
  "blueHalo": "rgba(64, 98, 167, 0.16)"
112
112
  },
113
+ "presence": {
114
+ "flagText": "#ffffff"
115
+ },
113
116
  "scrollbar": "rgba(7, 8, 13, 0.2)",
114
117
  "scrollbarHover": "rgba(7, 8, 13, 0.32)"
115
118
  },
@@ -230,6 +233,9 @@ export const themes = {
230
233
  "blueLine": "rgba(91, 127, 199, 0.38)",
231
234
  "blueHalo": "rgba(91, 127, 199, 0.16)"
232
235
  },
236
+ "presence": {
237
+ "flagText": "#07080d"
238
+ },
233
239
  "scrollbar": "rgba(255, 255, 255, 0.16)",
234
240
  "scrollbarHover": "rgba(255, 255, 255, 0.26)"
235
241
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewlethq/tokens",
3
- "version": "0.17.1",
3
+ "version": "0.18.0",
4
4
  "description": "Crewlet design tokens. Single JSON source compiled to CSS variables and typed JS modules.",
5
5
  "license": "MIT AND OFL-1.1",
6
6
  "repository": {
@@ -202,3 +202,9 @@ export const VEIL_BAND: readonly number[];
202
202
 
203
203
  /** The alpha the veil draws its own root's frame at. */
204
204
  export const VEIL_ALPHA: number;
205
+
206
+ /** The six node hues a collaborator's presence marks are drawn in, held to 3:1 as marks on every rung. */
207
+ export const PRESENCE_HUES: readonly string[];
208
+
209
+ /** The ink of the name on a presence flag, held to 4.5:1 on every presence hue. */
210
+ export const PRESENCE_FLAG_TEXT: string;
package/test/palette.mjs CHANGED
@@ -306,6 +306,27 @@ const labelOf = (step) => (step.startsWith('--color-feedback-danger') ? DESTRUCT
306
306
  /** The ten seeded avatar grounds, each carrying white initials. */
307
307
  export const AVATAR_TINTS = Array.from({ length: 10 }, (_, i) => `--color-avatar-tint-${i}`);
308
308
 
309
+ // ---------------------------------------------------------------------------
310
+ // Presence
311
+ // ---------------------------------------------------------------------------
312
+
313
+ /**
314
+ * The six node hues a collaborator's presence is drawn in, and the ink of the
315
+ * name flag filled with each.
316
+ *
317
+ * PRESENCE IS THE NARROW EXCEPTION to colour carrying state: a collaborator's
318
+ * hue ties their cursor, their selection ring, their cell outline and their
319
+ * name flag to their name, and is spent on nothing else. Two promises follow.
320
+ * The flag's name is TEXT on the hue, so it clears 4.5:1 there in every
321
+ * palette; and the ring and the cursor are MARKS on content, so the hue clears
322
+ * 3:1 on every rung a sheet or a page can stand on. The high-contrast theme is
323
+ * held to the same 4.5: the hue is the collaborator's identity rather than a
324
+ * palette's step, so it is not re-tuned per theme, and the name is also said
325
+ * in words wherever presence is listed.
326
+ */
327
+ export const PRESENCE_HUES = ['purple', 'cyan', 'green', 'amber', 'rose', 'blue'].map((hue) => `--color-node-${hue}`);
328
+ export const PRESENCE_FLAG_TEXT = '--color-presence-flag-text';
329
+
309
330
  // ---------------------------------------------------------------------------
310
331
  // The rail
311
332
  // ---------------------------------------------------------------------------
@@ -874,6 +895,17 @@ function checkState(state, values, profile, push, theme = { tint: null, contrast
874
895
  say('a glyph clears 3:1 on its own fill', low.ratio >= 3, `${ink} on ${fill}`, low.ratio, `${low.ratio.toFixed(2)}:1 (worst on ${low.name})`);
875
896
  }
876
897
 
898
+ // PRESENCE. See PRESENCE_HUES.
899
+ {
900
+ const ink = colour(PRESENCE_FLAG_TEXT);
901
+ const low = worst(ink, PRESENCE_HUES.map((name) => [name, colour(name)]));
902
+ say('a presence flag name clears 4.5:1 on every node hue', low.ratio >= 4.5, PRESENCE_FLAG_TEXT, low.ratio, `${low.ratio.toFixed(2)}:1 (worst on ${low.name})`);
903
+ for (const name of PRESENCE_HUES) {
904
+ const mark = worst(colour(name), opaque);
905
+ say('a presence hue clears 3:1 as a mark', mark.ratio >= 3, name, mark.ratio, `${mark.ratio.toFixed(2)}:1 (worst on ${mark.name})`);
906
+ }
907
+ }
908
+
877
909
  // THE PRIMARY ACTION'S STEPS. See ACTION_STEPS.
878
910
  for (const [rule, step, from] of ACTION_STEPS) {
879
911
  const name = labelOf(step);