@dxos/ui-theme 0.8.4-staging.ac66bdf99f → 0.9.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 (169) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/browser/index.mjs +89 -867
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/node-esm/index.mjs +89 -867
  7. package/dist/lib/node-esm/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/meta.json +1 -1
  9. package/dist/plugin/node-cjs/main.css +252 -119
  10. package/dist/plugin/node-cjs/main.css.map +3 -3
  11. package/dist/plugin/node-cjs/meta.json +1 -1
  12. package/dist/plugin/node-cjs/plugins/ThemePlugin.cjs +82 -10
  13. package/dist/plugin/node-cjs/plugins/ThemePlugin.cjs.map +3 -3
  14. package/dist/plugin/node-esm/main.css +252 -119
  15. package/dist/plugin/node-esm/main.css.map +3 -3
  16. package/dist/plugin/node-esm/meta.json +1 -1
  17. package/dist/plugin/node-esm/plugins/ThemePlugin.mjs +84 -12
  18. package/dist/plugin/node-esm/plugins/ThemePlugin.mjs.map +3 -3
  19. package/dist/types/src/Theme.stories.d.ts.map +1 -1
  20. package/dist/types/src/defs.d.ts +1 -1
  21. package/dist/types/src/defs.d.ts.map +1 -1
  22. package/dist/types/src/fragments/density.d.ts +2 -2
  23. package/dist/types/src/fragments/density.d.ts.map +1 -1
  24. package/dist/types/src/fragments/hover.d.ts +0 -1
  25. package/dist/types/src/fragments/hover.d.ts.map +1 -1
  26. package/dist/types/src/index.d.ts +0 -1
  27. package/dist/types/src/index.d.ts.map +1 -1
  28. package/dist/types/src/plugins/ThemePlugin.d.ts +3 -2
  29. package/dist/types/src/plugins/ThemePlugin.d.ts.map +1 -1
  30. package/dist/types/src/util/hash-styles.d.ts +12 -2
  31. package/dist/types/src/util/hash-styles.d.ts.map +1 -1
  32. package/dist/types/src/util/mx.d.ts +0 -36
  33. package/dist/types/src/util/mx.d.ts.map +1 -1
  34. package/dist/types/src/util/size.d.ts.map +1 -1
  35. package/dist/types/src/util/valence.d.ts +8 -2
  36. package/dist/types/src/util/valence.d.ts.map +1 -1
  37. package/dist/types/tsconfig.tsbuildinfo +1 -1
  38. package/package.json +14 -21
  39. package/src/Theme.stories.tsx +94 -27
  40. package/src/css/DESIGN_SYSTEM.md +187 -0
  41. package/src/css/base/base.css +2 -2
  42. package/src/css/components/button.css +63 -13
  43. package/src/css/components/card.css +14 -0
  44. package/src/css/components/checkbox.css +3 -3
  45. package/src/css/components/focus.css +12 -12
  46. package/src/css/components/link.css +4 -1
  47. package/src/css/components/panel.css +45 -45
  48. package/src/css/components/state.css +99 -0
  49. package/src/css/components/state.md +101 -0
  50. package/src/css/components/surface.css +33 -11
  51. package/src/css/components/tag.css +25 -24
  52. package/src/css/integrations/codemirror.css +4 -3
  53. package/src/css/integrations/tldraw.css +1 -1
  54. package/src/css/layout/main.css +6 -0
  55. package/src/css/layout/size.css +16 -3
  56. package/src/css/theme/animation.css +31 -0
  57. package/src/css/theme/palette.css +34 -0
  58. package/src/css/theme/semantic.css +101 -60
  59. package/src/css/theme/spacing.css +29 -12
  60. package/src/css/theme/styles.css +172 -119
  61. package/src/css/utilities.css +42 -0
  62. package/src/defs.ts +3 -1
  63. package/src/fragments/AUDIT.md +0 -2
  64. package/src/fragments/density.ts +34 -7
  65. package/src/fragments/hover.ts +0 -2
  66. package/src/index.ts +1 -1
  67. package/src/main.css +68 -9
  68. package/src/plugins/ThemePlugin.ts +102 -14
  69. package/src/plugins/main.css +10 -7
  70. package/src/util/hash-styles.ts +54 -42
  71. package/src/util/mx.ts +1 -126
  72. package/src/util/valence.ts +15 -5
  73. package/dist/types/src/theme/components/avatar.d.ts +0 -21
  74. package/dist/types/src/theme/components/avatar.d.ts.map +0 -1
  75. package/dist/types/src/theme/components/breadcrumb.d.ts +0 -9
  76. package/dist/types/src/theme/components/breadcrumb.d.ts.map +0 -1
  77. package/dist/types/src/theme/components/button.d.ts +0 -15
  78. package/dist/types/src/theme/components/button.d.ts.map +0 -1
  79. package/dist/types/src/theme/components/card.d.ts +0 -12
  80. package/dist/types/src/theme/components/card.d.ts.map +0 -1
  81. package/dist/types/src/theme/components/dialog.d.ts +0 -17
  82. package/dist/types/src/theme/components/dialog.d.ts.map +0 -1
  83. package/dist/types/src/theme/components/focus.d.ts +0 -6
  84. package/dist/types/src/theme/components/focus.d.ts.map +0 -1
  85. package/dist/types/src/theme/components/icon-button.d.ts +0 -8
  86. package/dist/types/src/theme/components/icon-button.d.ts.map +0 -1
  87. package/dist/types/src/theme/components/icon.d.ts +0 -10
  88. package/dist/types/src/theme/components/icon.d.ts.map +0 -1
  89. package/dist/types/src/theme/components/index.d.ts +0 -27
  90. package/dist/types/src/theme/components/index.d.ts.map +0 -1
  91. package/dist/types/src/theme/components/input.d.ts +0 -115
  92. package/dist/types/src/theme/components/input.d.ts.map +0 -1
  93. package/dist/types/src/theme/components/link.d.ts +0 -7
  94. package/dist/types/src/theme/components/link.d.ts.map +0 -1
  95. package/dist/types/src/theme/components/list.d.ts +0 -14
  96. package/dist/types/src/theme/components/list.d.ts.map +0 -1
  97. package/dist/types/src/theme/components/main.d.ts +0 -28
  98. package/dist/types/src/theme/components/main.d.ts.map +0 -1
  99. package/dist/types/src/theme/components/menu.d.ts +0 -13
  100. package/dist/types/src/theme/components/menu.d.ts.map +0 -1
  101. package/dist/types/src/theme/components/message.d.ts +0 -12
  102. package/dist/types/src/theme/components/message.d.ts.map +0 -1
  103. package/dist/types/src/theme/components/popover.d.ts +0 -11
  104. package/dist/types/src/theme/components/popover.d.ts.map +0 -1
  105. package/dist/types/src/theme/components/scroll-area.d.ts +0 -32
  106. package/dist/types/src/theme/components/scroll-area.d.ts.map +0 -1
  107. package/dist/types/src/theme/components/select.d.ts +0 -13
  108. package/dist/types/src/theme/components/select.d.ts.map +0 -1
  109. package/dist/types/src/theme/components/separator.d.ts +0 -8
  110. package/dist/types/src/theme/components/separator.d.ts.map +0 -1
  111. package/dist/types/src/theme/components/skeleton.d.ts +0 -7
  112. package/dist/types/src/theme/components/skeleton.d.ts.map +0 -1
  113. package/dist/types/src/theme/components/splitter.d.ts +0 -4
  114. package/dist/types/src/theme/components/splitter.d.ts.map +0 -1
  115. package/dist/types/src/theme/components/status.d.ts +0 -9
  116. package/dist/types/src/theme/components/status.d.ts.map +0 -1
  117. package/dist/types/src/theme/components/tag.d.ts +0 -7
  118. package/dist/types/src/theme/components/tag.d.ts.map +0 -1
  119. package/dist/types/src/theme/components/toast.d.ts +0 -12
  120. package/dist/types/src/theme/components/toast.d.ts.map +0 -1
  121. package/dist/types/src/theme/components/toolbar.d.ts +0 -11
  122. package/dist/types/src/theme/components/toolbar.d.ts.map +0 -1
  123. package/dist/types/src/theme/components/tooltip.d.ts +0 -8
  124. package/dist/types/src/theme/components/tooltip.d.ts.map +0 -1
  125. package/dist/types/src/theme/components/treegrid.d.ts +0 -10
  126. package/dist/types/src/theme/components/treegrid.d.ts.map +0 -1
  127. package/dist/types/src/theme/index.d.ts +0 -4
  128. package/dist/types/src/theme/index.d.ts.map +0 -1
  129. package/dist/types/src/theme/primitives/column.d.ts +0 -29
  130. package/dist/types/src/theme/primitives/column.d.ts.map +0 -1
  131. package/dist/types/src/theme/primitives/index.d.ts +0 -3
  132. package/dist/types/src/theme/primitives/index.d.ts.map +0 -1
  133. package/dist/types/src/theme/primitives/panel.d.ts +0 -13
  134. package/dist/types/src/theme/primitives/panel.d.ts.map +0 -1
  135. package/dist/types/src/theme/theme.d.ts +0 -5
  136. package/dist/types/src/theme/theme.d.ts.map +0 -1
  137. package/src/css/components/selected.css +0 -30
  138. package/src/theme/components/avatar.ts +0 -95
  139. package/src/theme/components/breadcrumb.ts +0 -29
  140. package/src/theme/components/button.ts +0 -48
  141. package/src/theme/components/card.ts +0 -102
  142. package/src/theme/components/dialog.ts +0 -61
  143. package/src/theme/components/focus.ts +0 -33
  144. package/src/theme/components/icon-button.ts +0 -18
  145. package/src/theme/components/icon.ts +0 -28
  146. package/src/theme/components/index.ts +0 -30
  147. package/src/theme/components/input.ts +0 -171
  148. package/src/theme/components/link.ts +0 -25
  149. package/src/theme/components/list.ts +0 -46
  150. package/src/theme/components/main.ts +0 -34
  151. package/src/theme/components/menu.ts +0 -50
  152. package/src/theme/components/message.ts +0 -40
  153. package/src/theme/components/popover.ts +0 -41
  154. package/src/theme/components/scroll-area.ts +0 -115
  155. package/src/theme/components/select.ts +0 -52
  156. package/src/theme/components/separator.ts +0 -24
  157. package/src/theme/components/skeleton.ts +0 -23
  158. package/src/theme/components/splitter.ts +0 -20
  159. package/src/theme/components/status.ts +0 -32
  160. package/src/theme/components/tag.ts +0 -23
  161. package/src/theme/components/toast.ts +0 -53
  162. package/src/theme/components/toolbar.ts +0 -35
  163. package/src/theme/components/tooltip.ts +0 -27
  164. package/src/theme/components/treegrid.ts +0 -37
  165. package/src/theme/index.ts +0 -7
  166. package/src/theme/primitives/column.ts +0 -71
  167. package/src/theme/primitives/index.ts +0 -6
  168. package/src/theme/primitives/panel.ts +0 -43
  169. package/src/theme/theme.ts +0 -87
@@ -19,11 +19,12 @@
19
19
  oklch(from var(--color-blue-400) l c h / 0.5),
20
20
  oklch(from var(--color-blue-600) l c h / 0.5)
21
21
  );
22
- --color-cm-focused-selection: light-dark(var(--color-blue-400), var(--color-blue-600));
22
+ --color-cm-focused-selection: light-dark(var(--color-blue-400), oklch(0.445 0.057 256)); /* #3f5573 */
23
23
  --color-cm-highlight: light-dark(var(--color-neutral-950), var(--color-neutral-50));
24
24
  --color-cm-highlight-surface: light-dark(var(--color-sky-200), var(--color-cyan-800));
25
- --color-cm-comment-text: light-dark(var(--color-neutral-50), var(--color-neutral-950));
26
- --color-cm-comment-surface: light-dark(var(--color-amber-800), var(--color-amber-200));
25
+ --color-cm-comment-text: light-dark(var(--color-neutral-950), var(--color-neutral-950));
26
+ --color-cm-comment-surface: light-dark(var(--color-teal-200), var(--color-teal-200));
27
+ --color-cm-comment-current-surface: light-dark(var(--color-orange-200), var(--color-orange-200));
27
28
 
28
29
  /* Markdown syntax highlighting */
29
30
  --color-cm-code: light-dark(var(--color-stone-600), var(--color-stone-400));
@@ -8,7 +8,7 @@
8
8
  }
9
9
  .tl-container.tl-theme__light,
10
10
  .tl-container.tl-theme__dark {
11
- --color-selected: var(--color-accent-surface);
11
+ --color-selected: var(--color-accent-bg);
12
12
  --color-panel: var(--color-modal-surface);
13
13
  --color-panel-contrast: var(--color-separator);
14
14
  }
@@ -81,8 +81,14 @@
81
81
  @apply backdrop-blur-lg;
82
82
  }
83
83
  background-color: var(--color-sidebar-surface);
84
+ color: var(--color-sidebar-fg);
84
85
  --surface-bg: var(--color-sidebar-surface);
85
86
 
87
+ /* Current / selected items read one stop brighter than default body text. */
88
+ & :is([aria-current]:not([aria-current='false']), [aria-selected='true']) {
89
+ color: var(--color-sidebar-current-fg);
90
+ }
91
+
86
92
  transition-property: inset-inline-start, inset-inline-end, inline-size;
87
93
  inset-block-start: max(0.5rem, env(safe-area-inset-top));
88
94
  inset-block-end: max(0.5rem, env(safe-area-inset-bottom));
@@ -3,15 +3,28 @@
3
3
  */
4
4
 
5
5
  @layer dx-components {
6
- /**
7
- * Registers the element as a size query container.
6
+ /**
7
+ * Registers the element as a size query container.
8
8
  * Children can use @container queries to apply styles based on the container's dimensions (both width and height).
9
- * Also enables children to use cqi units (e.g., max-w-[100cqi])
9
+ * Also enables children to use cqi/cqb units (e.g., max-w-[100cqi]).
10
+ * NOTE: `container-type: size` implies layout/size containment, which breaks CodeMirror's
11
+ * coordinate measurement (causes blank viewport sections during scroll until a click forces
12
+ * a re-measure). For editor content where only inline (width-based) queries are needed,
13
+ * use `.dx-inline-size-container` instead.
10
14
  */
11
15
  .dx-size-container {
12
16
  container-type: size;
13
17
  }
14
18
 
19
+ /**
20
+ * Inline-only size query container. Provides cqi units for children without the layout
21
+ * containment side-effects of `container-type: size`. Use this in CodeMirror content
22
+ * wrappers where size containment would break viewport measurement.
23
+ */
24
+ .dx-inline-size-container {
25
+ container-type: inline-size;
26
+ }
27
+
15
28
  /**
16
29
  * Document width.
17
30
  */
@@ -227,3 +227,34 @@
227
227
  }
228
228
  --animate-blink: blink 1s step-start infinite;
229
229
  }
230
+
231
+ /**
232
+ * Shimmer (text)
233
+ * Sweeps a brighter band across text via mask alpha — preserves the consumer's color.
234
+ * Translates exactly one tile period (2× element width) per cycle so the loop seam is invisible.
235
+ */
236
+ @keyframes shimmer-text {
237
+ from {
238
+ mask-position-x: 100%;
239
+ -webkit-mask-position-x: 100%;
240
+ }
241
+ to {
242
+ mask-position-x: -100%;
243
+ -webkit-mask-position-x: -100%;
244
+ }
245
+ }
246
+
247
+ /**
248
+ * Honor user reduced-motion preference for decorative animations.
249
+ * Functional transitions (fade/slide/toast/blink) are intentionally excluded —
250
+ * suppressing them would hide UI state changes.
251
+ */
252
+ @media (prefers-reduced-motion: reduce) {
253
+ .animate-halo-pulse,
254
+ .animate-spin-slow,
255
+ .animate-trail,
256
+ .animate-trail-offset,
257
+ .animate-shimmer {
258
+ animation: none;
259
+ }
260
+ }
@@ -9,13 +9,47 @@
9
9
  */
10
10
 
11
11
  @theme {
12
+ /**
13
+ * Neutral ramp.
14
+ *
15
+ * Warm-tinted gray (not pure neutral): every level shares --dx-neutral-chroma / --dx-neutral-hue,
16
+ * so those two knobs shift the warmth across the whole ramp (and everything derived from it). The
17
+ * light end is re-spread vs Tailwind's defaults — which squeeze 50–300 into ~0.11 L while the dark
18
+ * end spans ~0.23 — so light steps (~0.025 L) roughly match dark steps (~0.030 L).
19
+ *
20
+ * Two kinds of level, listed below in ascending (darkening) order:
21
+ * - Anchors — the Tailwind hundreds (50…950), defined by explicit lightness.
22
+ * - In-between steps — `color-mix` interpolations of the surrounding anchors.
23
+ */
24
+ --dx-neutral-hue: 190;
25
+ --dx-neutral-chroma: 0.001;
26
+
27
+ --color-neutral-50: oklch(0.985 var(--dx-neutral-chroma) var(--dx-neutral-hue));
12
28
  --color-neutral-75: color-mix(in oklch, var(--color-neutral-50) 50%, var(--color-neutral-100) 50%);
29
+ --color-neutral-100: oklch(0.935 var(--dx-neutral-chroma) var(--dx-neutral-hue));
30
+ --color-neutral-125: color-mix(in oklch, var(--color-neutral-100) 75%, var(--color-neutral-200) 25%);
13
31
  --color-neutral-150: color-mix(in oklch, var(--color-neutral-100) 50%, var(--color-neutral-200) 50%);
32
+ --color-neutral-175: color-mix(in oklch, var(--color-neutral-150) 50%, var(--color-neutral-200) 50%);
33
+ --color-neutral-200: oklch(0.875 var(--dx-neutral-chroma) var(--dx-neutral-hue));
14
34
  --color-neutral-250: color-mix(in oklch, var(--color-neutral-200) 50%, var(--color-neutral-300) 50%);
35
+ --color-neutral-300: oklch(0.8 var(--dx-neutral-chroma) var(--dx-neutral-hue));
36
+ --color-neutral-400: oklch(0.708 var(--dx-neutral-chroma) var(--dx-neutral-hue));
37
+ --color-neutral-500: oklch(0.556 var(--dx-neutral-chroma) var(--dx-neutral-hue));
38
+ --color-neutral-600: oklch(0.439 var(--dx-neutral-chroma) var(--dx-neutral-hue));
39
+ --color-neutral-700: oklch(0.371 var(--dx-neutral-chroma) var(--dx-neutral-hue));
15
40
  --color-neutral-750: color-mix(in oklch, var(--color-neutral-700) 50%, var(--color-neutral-800) 50%);
41
+ --color-neutral-775: color-mix(in oklch, var(--color-neutral-750) 50%, var(--color-neutral-800) 50%);
42
+ --color-neutral-800: oklch(0.269 var(--dx-neutral-chroma) var(--dx-neutral-hue));
43
+ --color-neutral-825: color-mix(in oklch, var(--color-neutral-800) 75%, var(--color-neutral-900) 25%);
16
44
  --color-neutral-850: color-mix(in oklch, var(--color-neutral-800) 50%, var(--color-neutral-900) 50%);
45
+ --color-neutral-875: color-mix(in oklch, var(--color-neutral-800) 25%, var(--color-neutral-900) 75%);
46
+ --color-neutral-900: oklch(0.205 var(--dx-neutral-chroma) var(--dx-neutral-hue));
17
47
  --color-neutral-925: color-mix(in oklch, var(--color-neutral-900) 50%, var(--color-neutral-950) 50%);
48
+ --color-neutral-950: oklch(0.145 var(--dx-neutral-chroma) var(--dx-neutral-hue));
18
49
 
50
+ /*
51
+ * Primary
52
+ */
19
53
  --color-primary-50: var(--color-blue-50);
20
54
  --color-primary-100: var(--color-blue-100);
21
55
  --color-primary-200: var(--color-blue-200);
@@ -1,116 +1,157 @@
1
1
  /**
2
2
  * Tokens
3
+ *
4
+ * Naming convention: --color-{name}-{part}[-{state}]
5
+ * part : surface | fg | border | bg | text
6
+ * state : hover | active (optional)
7
+ *
8
+ * See DESIGN_SYSTEM.md.
3
9
  */
4
10
 
5
11
  @theme {
6
- /**
7
- * Surfaces
12
+ /*
13
+ * Elevation ladder — strictly monotonic, z-order low → high.
14
+ * Dark: darker = lower. Light: lighter = higher (inverted toward white).
8
15
  *
9
- * TODO(burdon): Align suffix with styles.css?
10
- * -xxx-surface
11
- * -xxx-surface-text
16
+ * Level Name Roles
17
+ * 0 void window gaps, scrim base
18
+ * 1 rail L0 icon rail
19
+ * 2 chrome L1/R sidebars, header
20
+ * 3 canvas base, deck
21
+ * 4 raised card, group, input
22
+ * 5 bar toolbar (sticky, drop-shadowed)
23
+ * 6 modal dialog, modal, popover
24
+ * 7 float menu, toast, tooltip
25
+ *
26
+ * These are private (--dx-*) knobs — use named surface tokens in components, not these directly.
12
27
  */
28
+ --dx-elevation-0: light-dark(var(--color-neutral-300), var(--color-neutral-950));
29
+ --dx-elevation-1: light-dark(var(--color-neutral-200), var(--color-neutral-900));
30
+ --dx-elevation-2: light-dark(var(--color-neutral-125), var(--color-neutral-875));
31
+ --dx-elevation-3: light-dark(var(--color-neutral-125), var(--color-neutral-850));
32
+ --dx-elevation-4: light-dark(var(--color-neutral-100), var(--color-neutral-825));
33
+ --dx-elevation-5: light-dark(var(--color-neutral-75), var(--color-neutral-800));
34
+ --dx-elevation-6: light-dark(var(--color-neutral-50), var(--color-neutral-775));
35
+ --dx-elevation-7: light-dark(white, var(--color-neutral-750));
36
+
37
+ /* Surfaces — each maps to exactly one elevation level */
38
+ --color-sidebar-surface: var(--dx-elevation-2);
39
+ --color-header-surface: var(--dx-elevation-2);
40
+ --color-deck-surface: var(--dx-elevation-3);
41
+ --color-base-surface: var(--dx-elevation-3);
42
+ --color-card-surface: var(--dx-elevation-3);
43
+ --color-group-surface: var(--dx-elevation-4);
44
+ /* Subtle alternate of group-surface for zebra striping (e.g. calendar months) — offset off
45
+ * elevation-4 via relative oklch so it tracks the ramp: darker in light mode, lighter in dark. */
46
+ --color-group-alt-surface: light-dark(
47
+ oklch(from var(--dx-elevation-4) calc(l - 0.03) c h),
48
+ oklch(from var(--dx-elevation-4) calc(l + 0.03) c h)
49
+ );
50
+ --color-input-surface: var(--dx-elevation-4);
51
+ --color-toolbar-surface: var(--dx-elevation-5);
52
+ --color-modal-surface: var(--dx-elevation-6);
53
+ --color-popover-surface: var(--dx-elevation-6);
13
54
 
14
- --color-base-surface: light-dark(var(--color-neutral-50), var(--color-neutral-950));
15
- --color-base-surface-text: light-dark(var(--color-neutral-950), var(--color-neutral-50));
55
+ /* Sidebar / panel layout levels */
56
+ --color-l0-surface: var(--dx-elevation-1);
57
+ --color-l1-surface: var(--dx-elevation-2);
58
+ --color-r0-surface: var(--dx-elevation-2);
59
+ --color-r1-surface: var(--dx-elevation-2);
16
60
 
17
- --color-inverse-surface: light-dark(var(--color-neutral-800), var(--color-neutral-200));
18
- --color-inverse-surface-text: light-dark(var(--color-neutral-50), var(--color-neutral-950));
19
-
20
- --color-deck-surface: light-dark(var(--color-neutral-50), var(--color-neutral-950));
21
61
  --color-scrim-surface: light-dark(
22
62
  oklch(from var(--color-neutral-50) l c h / 0.5),
23
63
  oklch(from var(--color-neutral-950) l c h / 0.25)
24
64
  );
25
65
 
26
- --color-toolbar-surface: light-dark(var(--color-neutral-75), var(--color-neutral-925));
27
- --color-card-surface: light-dark(var(--color-neutral-75), var(--color-neutral-925));
28
-
29
- --color-group-surface: light-dark(var(--color-neutral-100), var(--color-neutral-900));
30
- --color-modal-surface: light-dark(var(--color-neutral-100), var(--color-neutral-900));
31
- --color-sidebar-surface: light-dark(var(--color-neutral-100), var(--color-neutral-900));
32
- --color-header-surface: light-dark(var(--color-neutral-100), var(--color-neutral-900));
66
+ --color-inverse-surface: light-dark(var(--color-neutral-800), var(--color-neutral-200));
67
+ --color-inverse-fg: light-dark(var(--color-neutral-50), var(--color-neutral-950));
33
68
 
34
- --color-input-surface: light-dark(var(--color-neutral-200), var(--color-neutral-800));
35
- --color-input-surface-text: light-dark(var(--color-neutral-950), var(--color-neutral-50));
69
+ --color-base-fg: light-dark(var(--color-neutral-950), var(--color-neutral-150));
36
70
 
37
- /** TODO(burdon): current vs active vs selected */
38
- --color-current-surface: light-dark(var(--color-neutral-200), var(--color-neutral-800));
39
- --color-active-surface: light-dark(var(--color-neutral-200), var(--color-neutral-800));
40
- --color-active-text: light-dark(var(--color-neutral-950), var(--color-neutral-50));
71
+ /* Sidebar body text. Default sits one ramp stop below the current/selected emphasis. */
72
+ --color-sidebar-fg: light-dark(var(--color-neutral-700), var(--color-neutral-250));
73
+ --color-sidebar-current-fg: light-dark(var(--color-neutral-950), var(--color-neutral-75));
41
74
 
42
- /** TODO(burdon): Merge overlay/surface? */
43
- --color-hover-overlay: light-dark(var(--color-neutral-250), var(--color-neutral-750));
44
- --color-hover-surface: light-dark(var(--color-neutral-250), var(--color-neutral-750));
45
- --color-hover-surface-text: light-dark(var(--color-neutral-950), var(--color-neutral-50));
75
+ /* Focus */
76
+ --color-focus-surface: light-dark(var(--color-neutral-50), var(--color-neutral-850));
77
+ --color-focus-ring: light-dark(var(--color-blue-400), var(--color-blue-600));
78
+ --color-focus-ring-subtle: light-dark(var(--color-neutral-300), var(--color-neutral-600));
46
79
 
47
80
  /* Map attention to focus-surface logic so that elements acting as active attention zones highlight correctly on focus. */
48
81
  --color-attention-surface: var(--color-focus-surface);
49
- --color-attention-contains: oklch(from var(--color-accent-surface) l c h / 0.3);
50
- --color-focus-surface: light-dark(var(--color-neutral-50), var(--color-neutral-950));
51
- --color-neutral-focus-indicator: light-dark(var(--color-neutral-400), var(--color-neutral-600));
52
-
53
- /* Highlight and Selected */
82
+ --color-attention-contains: oklch(from var(--color-accent-bg) l c h / 0.3);
54
83
 
55
- --color-highlight-surface: light-dark(var(--color-neutral-100), var(--color-neutral-900));
56
- --color-highlight-surface-hover: light-dark(var(--color-neutral-250), var(--color-neutral-750));
57
- --color-highlight-surface-text: light-dark(var(--color-neutral-950), var(--color-neutral-50));
84
+ /* input */
85
+ --color-input-bg: light-dark(var(--color-neutral-250), var(--color-neutral-700));
86
+ --color-input-fg: light-dark(var(--color-neutral-950), var(--color-neutral-150));
58
87
 
59
- --color-selected-surface: light-dark(var(--color-neutral-150), var(--color-neutral-850));
60
- --color-selected-surface-hover: light-dark(var(--color-neutral-250), var(--color-neutral-750));
61
- --color-selected-surface-text: light-dark(var(--color-neutral-950), var(--color-neutral-50));
88
+ /*
89
+ * hover (:hover, data-highlighted)
90
+ * `*-base` primitives are the un-offset values;
91
+ * surface contexts (e.g. .dx-main-sidebar in state.css) re-derive the public token off the base via relative oklch.
92
+ */
93
+ --dx-hover-surface-base: light-dark(var(--color-neutral-200), var(--color-neutral-850));
94
+ --color-hover-surface: var(--dx-hover-surface-base);
95
+ --color-hover-fg: light-dark(var(--color-neutral-950), var(--color-neutral-150));
96
+
97
+ /* current (aria-current) */
98
+ --dx-current-surface-base: light-dark(var(--color-neutral-150), var(--color-neutral-800));
99
+ --dx-current-surface-hover-base: light-dark(var(--color-neutral-150), var(--color-neutral-600));
100
+ --color-current-surface: var(--dx-current-surface-base);
101
+ --color-current-surface-hover: var(--dx-current-surface-hover-base);
102
+ --color-current-fg: light-dark(var(--color-neutral-950), var(--color-neutral-50));
103
+
104
+ /* selected (aria-selected) */
105
+ --color-selected-surface: var(--color-current-surface);
106
+ --color-selected-surface-hover: var(--color-current-surface-hover);
107
+ --color-selected-fg: var(--color-current-fg);
62
108
 
63
109
  /* Accent (primary) */
64
- /* TODO(burdon): Rename primary */
65
-
66
- --color-accent-surface: light-dark(var(--color-blue-500), var(--color-blue-700));
67
- --color-accent-surface-hover: light-dark(var(--color-blue-800), var(--color-blue-800));
68
- --color-accent-surface-text: var(--color-blue-100);
110
+ --color-accent-bg: light-dark(var(--color-blue-600), var(--color-blue-700));
111
+ --color-accent-bg-hover: light-dark(var(--color-blue-700), var(--color-blue-800));
112
+ --color-accent-fg: var(--color-blue-100);
69
113
  --color-accent-text: light-dark(var(--color-blue-600), var(--color-blue-400));
70
114
  --color-accent-text-hover: light-dark(var(--color-blue-500), var(--color-blue-500));
71
- --color-accent-focus-indicator: light-dark(var(--color-blue-600), var(--color-blue-600));
72
115
 
73
116
  --color-un-accent: var(--color-neutral-400);
74
117
  --color-un-accent-hover: var(--color-neutral-500);
75
118
 
76
119
  /* Separator */
77
-
78
- --color-separator: light-dark(var(--color-neutral-200), var(--color-neutral-800));
79
- --color-subdued-separator: light-dark(var(--color-neutral-150), var(--color-neutral-850));
80
- --color-primary-separator: light-dark(var(--color-neutral-500), var(--color-neutral-700));
120
+ --color-primary-separator: light-dark(var(--color-neutral-300), var(--color-neutral-700));
121
+ --color-separator: light-dark(var(--color-neutral-200), var(--color-neutral-700));
122
+ --color-subdued-separator: light-dark(var(--color-neutral-250), var(--color-neutral-750));
81
123
  --color-active-separator: light-dark(var(--color-blue-500), var(--color-blue-500));
82
124
 
83
125
  /* Scrollbar */
84
-
85
126
  --color-scrollbar-track: light-dark(var(--color-neutral-50), var(--color-neutral-950));
86
- --color-scrollbar-thumb: light-dark(var(--color-neutral-200), var(--color-neutral-700));
127
+ --color-scrollbar-thumb: light-dark(var(--color-neutral-200), var(--color-neutral-600));
87
128
  --color-scrollbar-thumb-active: light-dark(var(--color-neutral-200), var(--color-neutral-600));
88
129
  --color-scrollbar-thumb-hover: light-dark(var(--color-neutral-200), var(--color-neutral-600));
89
130
 
90
131
  /* Sheet */
91
-
92
132
  --color-axis-selected-surface: light-dark(var(--color-neutral-100), var(--color-neutral-900));
93
133
  --color-axis-selected-text: light-dark(var(--color-neutral-100), var(--color-neutral-900));
94
134
  --color-axis-surface: light-dark(var(--color-neutral-50), var(--color-neutral-800));
95
135
  --color-axis-text: light-dark(var(--color-neutral-800), var(--color-neutral-200));
96
136
 
97
- /* Grid */
98
-
137
+ /*
138
+ * Grid
139
+ * NOTE: Update main.css when changing grid tokens (and restart dev server).
140
+ */
99
141
  --color-grid-surface: light-dark(var(--color-neutral-50), var(--color-neutral-950));
142
+ --color-grid-fg: light-dark(var(--color-neutral-950), var(--color-neutral-50));
143
+ --color-grid-line: light-dark(var(--color-neutral-200), var(--color-neutral-800));
100
144
  --color-grid-highlight: oklch(from var(--color-emerald-500) l c h / 0.5);
145
+ --color-grid-selection-surface: light-dark(var(--color-blue-500), var(--color-blue-400));
146
+ --color-grid-selection-fg: light-dark(var(--color-neutral-50), var(--color-neutral-950));
101
147
  --color-grid-comment: light-dark(var(--color-green-400), var(--color-green-600));
102
148
  --color-grid-comment-active: light-dark(
103
149
  oklch(from var(--color-green-400) l c h / 0.5),
104
150
  oklch(from var(--color-green-600) l c h / 0.5)
105
151
  );
106
- --color-grid-hover-overlay: oklch(from var(--color-neutral-500) l c h / 0.1);
107
- --color-grid-selection-overlay: var(--color-blue-500);
108
- --color-grid-line: light-dark(var(--color-neutral-200), var(--color-neutral-800));
109
- --color-grid-focus-indicator: light-dark(var(--color-primary-600), var(--color-primary-600));
110
152
 
111
153
  /* Text */
112
-
113
154
  --color-placeholder: light-dark(var(--color-neutral-400), var(--color-neutral-600));
114
- --color-subdued: light-dark(var(--color-neutral-500), var(--color-neutral-500));
155
+ --color-subdued: light-dark(var(--color-neutral-500), var(--color-neutral-600));
115
156
  --color-description: light-dark(var(--color-neutral-600), var(--color-neutral-400));
116
157
  }
@@ -34,7 +34,7 @@
34
34
  --spacing-form-section-gap: var(--spacing-trim-lg);
35
35
 
36
36
  /**
37
- * Density: fine
37
+ * Density: md (default).
38
38
  */
39
39
  --spacing-form-padding: var(--spacing-trim-sm);
40
40
  --spacing-icon-button-padding: var(--spacing-trim-xs);
@@ -43,15 +43,31 @@
43
43
 
44
44
  @layer dx-tokens {
45
45
  /**
46
- * TODO(burdon): Density: coarse
46
+ * Density: lg — large touch targets (~40px controls).
47
47
  */
48
- /*
49
- .dx-density-coarse {
48
+ .dx-density-lg {
50
49
  --spacing-form-padding: var(--spacing-trim-md);
51
50
  --spacing-icon-button-padding: var(--spacing-trim-sm);
52
51
  --spacing-scroll-padding: 8px;
53
52
  }
54
- */
53
+
54
+ /**
55
+ * Density: sm — compact (~28px controls).
56
+ */
57
+ .dx-density-sm {
58
+ --spacing-form-padding: var(--spacing-trim-xs);
59
+ --spacing-icon-button-padding: var(--spacing-trim-xs);
60
+ --spacing-scroll-padding: 2px;
61
+ }
62
+
63
+ /**
64
+ * Density: xs — ultra-compact (~24px controls).
65
+ */
66
+ .dx-density-xs {
67
+ --spacing-form-padding: var(--spacing-trim-xs);
68
+ --spacing-icon-button-padding: var(--spacing-trim-xs);
69
+ --spacing-scroll-padding: 2px;
70
+ }
55
71
  }
56
72
 
57
73
  /**
@@ -69,9 +85,9 @@
69
85
  --dx-lacuna-6: 0.75rem;
70
86
 
71
87
  --dx-gutter-xs: 0.25rem; /* Input rings */
72
- --dx-gutter-sm: 1rem;
73
- --dx-gutter-md: 2rem; /* 32px (fine card) */
74
- --dx-gutter-lg: 2.5rem; /* 40px (dialog, coarse card) */
88
+ --dx-gutter-sm: 1rem; /* 16px (sm density card) */
89
+ --dx-gutter-md: 2rem; /* 32px (md density card — default) */
90
+ --dx-gutter-lg: 2.5rem; /* 40px (dialog, lg density card) */
75
91
  }
76
92
 
77
93
  :root {
@@ -91,10 +107,11 @@
91
107
  --dx-modal-line: var(--dx-hair-line);
92
108
  --dx-grid-focus-indicator-width: var(--dx-hair-line);
93
109
 
94
- --dx-input-fine: var(--dx-lacuna-3);
95
- --dx-input-coarse: var(--dx-lacuna-4);
110
+ --dx-input-md: var(--dx-lacuna-3);
111
+ --dx-input-lg: var(--dx-lacuna-4);
112
+ --dx-input-sm: var(--dx-lacuna-3);
96
113
 
97
- --dx-default-icons-size: 1.25rem; /* size=5 */
114
+ --dx-default-icons-size: 1rem; /* size=4 */
98
115
  }
99
116
 
100
117
  [data-grid-focus-indicator-variant='stack'] {
@@ -124,7 +141,7 @@
124
141
  --dx-l0-avatar-size: 3rem;
125
142
  --dx-l1-size: calc(var(--dx-nav-sidebar-size) - var(--dx-l0-size));
126
143
  --dx-r0-size: var(--dx-rail-size);
127
- --dx-r1-size: calc(var(--dx-complementary-sidebar-size) - var(--dx-r0-size));
144
+ --dx-r1-size: calc(var(--dx-complementary-sidebar-size) - var(--dx-r0-size) - 1px);
128
145
  }
129
146
 
130
147
  :root {