@dxos/ui-theme 0.8.4-main.8360d9e660 → 0.8.4-main.8baae0fced

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 (157) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/browser/index.mjs +414 -479
  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 +414 -479
  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/{theme.css → main.css} +189 -122
  10. package/dist/plugin/node-cjs/main.css.map +7 -0
  11. package/dist/plugin/node-cjs/meta.json +1 -1
  12. package/dist/plugin/node-cjs/plugins/ThemePlugin.cjs +8 -15
  13. package/dist/plugin/node-cjs/plugins/ThemePlugin.cjs.map +3 -3
  14. package/dist/plugin/node-esm/{theme.css → main.css} +189 -122
  15. package/dist/plugin/node-esm/main.css.map +7 -0
  16. package/dist/plugin/node-esm/meta.json +1 -1
  17. package/dist/plugin/node-esm/plugins/ThemePlugin.mjs +8 -15
  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 +1 -4
  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/fragments/index.d.ts +0 -4
  27. package/dist/types/src/fragments/index.d.ts.map +1 -1
  28. package/dist/types/src/fragments/text.d.ts +0 -1
  29. package/dist/types/src/fragments/text.d.ts.map +1 -1
  30. package/dist/types/src/index.d.ts +1 -1
  31. package/dist/types/src/index.d.ts.map +1 -1
  32. package/dist/types/src/plugins/ThemePlugin.d.ts +1 -1
  33. package/dist/types/src/plugins/ThemePlugin.d.ts.map +1 -1
  34. package/dist/types/src/theme/components/avatar.d.ts.map +1 -1
  35. package/dist/types/src/theme/components/button.d.ts +2 -2
  36. package/dist/types/src/theme/components/button.d.ts.map +1 -1
  37. package/dist/types/src/theme/components/card.d.ts +1 -0
  38. package/dist/types/src/theme/components/card.d.ts.map +1 -1
  39. package/dist/types/src/theme/components/dialog.d.ts.map +1 -1
  40. package/dist/types/src/theme/components/focus.d.ts +6 -0
  41. package/dist/types/src/theme/components/focus.d.ts.map +1 -0
  42. package/dist/types/src/theme/components/icon-button.d.ts +1 -0
  43. package/dist/types/src/theme/components/icon-button.d.ts.map +1 -1
  44. package/dist/types/src/theme/components/icon.d.ts.map +1 -1
  45. package/dist/types/src/theme/components/index.d.ts +1 -0
  46. package/dist/types/src/theme/components/index.d.ts.map +1 -1
  47. package/dist/types/src/theme/components/input.d.ts +8 -8
  48. package/dist/types/src/theme/components/input.d.ts.map +1 -1
  49. package/dist/types/src/theme/components/link.d.ts.map +1 -1
  50. package/dist/types/src/theme/components/list.d.ts.map +1 -1
  51. package/dist/types/src/theme/components/main.d.ts.map +1 -1
  52. package/dist/types/src/theme/components/message.d.ts.map +1 -1
  53. package/dist/types/src/theme/components/popover.d.ts.map +1 -1
  54. package/dist/types/src/theme/components/scroll-area.d.ts +12 -2
  55. package/dist/types/src/theme/components/scroll-area.d.ts.map +1 -1
  56. package/dist/types/src/theme/components/select.d.ts.map +1 -1
  57. package/dist/types/src/theme/components/status.d.ts +1 -1
  58. package/dist/types/src/theme/components/status.d.ts.map +1 -1
  59. package/dist/types/src/theme/components/toast.d.ts.map +1 -1
  60. package/dist/types/src/theme/components/tooltip.d.ts.map +1 -1
  61. package/dist/types/src/theme/components/treegrid.d.ts.map +1 -1
  62. package/dist/types/src/theme/index.d.ts +1 -0
  63. package/dist/types/src/theme/index.d.ts.map +1 -1
  64. package/dist/types/src/theme/primitives/column.d.ts +25 -3
  65. package/dist/types/src/theme/primitives/column.d.ts.map +1 -1
  66. package/dist/types/src/theme/primitives/panel.d.ts +9 -5
  67. package/dist/types/src/theme/primitives/panel.d.ts.map +1 -1
  68. package/dist/types/src/theme/theme.d.ts.map +1 -1
  69. package/dist/types/src/util/elevation.d.ts.map +1 -0
  70. package/dist/types/src/util/hash-styles.d.ts +1 -1
  71. package/dist/types/src/util/hash-styles.d.ts.map +1 -1
  72. package/dist/types/src/util/index.d.ts +3 -0
  73. package/dist/types/src/util/index.d.ts.map +1 -1
  74. package/dist/types/src/util/mx.d.ts +49 -284
  75. package/dist/types/src/util/mx.d.ts.map +1 -1
  76. package/dist/types/src/util/size.d.ts +27 -0
  77. package/dist/types/src/util/size.d.ts.map +1 -0
  78. package/dist/types/src/util/valence.d.ts +4 -0
  79. package/dist/types/src/util/valence.d.ts.map +1 -0
  80. package/dist/types/tsconfig.tsbuildinfo +1 -1
  81. package/package.json +14 -18
  82. package/src/Theme.stories.tsx +5 -5
  83. package/src/css/DESIGN_SYSTEM.md +159 -0
  84. package/src/css/base/base.css +2 -2
  85. package/src/css/components/button.css +4 -3
  86. package/src/css/components/checkbox.css +1 -1
  87. package/src/css/components/{focus-ring.css → focus.css} +27 -13
  88. package/src/css/components/icon.css +9 -0
  89. package/src/css/components/link.css +3 -0
  90. package/src/css/components/panel.css +45 -45
  91. package/src/css/components/selected.css +63 -10
  92. package/src/css/components/selected.md +101 -0
  93. package/src/css/components/surface.css +4 -4
  94. package/src/css/components/tag.css +25 -23
  95. package/src/css/integrations/codemirror.css +5 -3
  96. package/src/css/integrations/tldraw.css +1 -0
  97. package/src/css/layout/main.css +0 -7
  98. package/src/css/layout/size.css +16 -26
  99. package/src/css/theme/animation.css +31 -0
  100. package/src/css/theme/palette.css +6 -0
  101. package/src/css/theme/semantic.css +47 -46
  102. package/src/css/theme/spacing.css +31 -17
  103. package/src/css/theme/styles.css +22 -22
  104. package/src/css/utilities.css +114 -3
  105. package/src/defs.ts +1 -1
  106. package/src/fragments/AUDIT.md +55 -0
  107. package/src/fragments/density.ts +8 -5
  108. package/src/fragments/hover.ts +0 -2
  109. package/src/fragments/index.ts +1 -5
  110. package/src/fragments/text.ts +1 -1
  111. package/src/index.ts +1 -1
  112. package/src/{theme.css → main.css} +47 -10
  113. package/src/plugins/ThemePlugin.ts +12 -24
  114. package/src/plugins/main.css +45 -0
  115. package/src/theme/components/avatar.ts +3 -4
  116. package/src/theme/components/button.ts +2 -2
  117. package/src/theme/components/card.ts +15 -6
  118. package/src/theme/components/dialog.ts +4 -3
  119. package/src/theme/components/focus.ts +33 -0
  120. package/src/theme/components/icon-button.ts +6 -5
  121. package/src/theme/components/icon.ts +7 -5
  122. package/src/theme/components/index.ts +1 -0
  123. package/src/theme/components/input.ts +18 -33
  124. package/src/theme/components/link.ts +1 -2
  125. package/src/theme/components/list.ts +4 -4
  126. package/src/theme/components/menu.ts +4 -4
  127. package/src/theme/components/message.ts +6 -7
  128. package/src/theme/components/popover.ts +4 -5
  129. package/src/theme/components/scroll-area.ts +58 -46
  130. package/src/theme/components/select.ts +2 -3
  131. package/src/theme/components/status.ts +5 -5
  132. package/src/theme/components/toast.ts +2 -3
  133. package/src/theme/components/tooltip.ts +2 -3
  134. package/src/theme/components/treegrid.ts +1 -1
  135. package/src/theme/index.ts +1 -0
  136. package/src/theme/primitives/column.ts +49 -8
  137. package/src/theme/primitives/panel.ts +18 -25
  138. package/src/theme/theme.ts +2 -0
  139. package/src/typings.d.ts +3 -0
  140. package/src/util/hash-styles.ts +19 -19
  141. package/src/util/index.ts +3 -0
  142. package/src/util/mx.ts +112 -7
  143. package/src/util/size.ts +103 -0
  144. package/dist/plugin/node-cjs/theme.css.map +0 -7
  145. package/dist/plugin/node-esm/theme.css.map +0 -7
  146. package/dist/types/src/fragments/elevation.d.ts.map +0 -1
  147. package/dist/types/src/fragments/focus.d.ts +0 -4
  148. package/dist/types/src/fragments/focus.d.ts.map +0 -1
  149. package/dist/types/src/fragments/size.d.ts +0 -9
  150. package/dist/types/src/fragments/size.d.ts.map +0 -1
  151. package/dist/types/src/fragments/valence.d.ts +0 -4
  152. package/dist/types/src/fragments/valence.d.ts.map +0 -1
  153. package/src/fragments/focus.ts +0 -11
  154. package/src/fragments/size.ts +0 -123
  155. /package/dist/types/src/{fragments → util}/elevation.d.ts +0 -0
  156. /package/src/{fragments → util}/elevation.ts +0 -0
  157. /package/src/{fragments → util}/valence.ts +0 -0
@@ -1,23 +1,76 @@
1
1
  /**
2
- * Selected / Highlighted state utilities
2
+ * Selected / Current / Highlighted state utilities.
3
+ *
4
+ * See `./selected.md` for the ARIA pairing grammar — every class below
5
+ * fires off a specific attribute and silently does nothing without it.
3
6
  */
4
7
 
5
8
  @layer dx-components {
9
+ /*
10
+ * Pure visual affordance, no ARIA pair. Combine with dx-selected or dx-current.
11
+ *
12
+ * Picks the hover variant matching the element's underlying state:
13
+ * - neither aria-selected nor aria-current → hover-surface
14
+ * - aria-selected="true" → selected-surface-hover
15
+ * - aria-current="true" → current-surface-hover (wins if both)
16
+ *
17
+ * Higher-specificity rules (attribute selectors) override the plain :hover rule,
18
+ * and `aria-current` is listed last so it beats `aria-selected` at equal specificity.
19
+ */
6
20
  .dx-hover {
7
- @apply hover:bg-highlight-surface! hover:text-highlight-surface-text!;
21
+ @apply cursor-pointer
22
+ hover:bg-hover-surface! hover:text-hover-foreground!
23
+ hover:aria-selected:bg-selected-surface-hover! hover:aria-selected:text-selected-foreground!
24
+ hover:aria-[current=true]:bg-current-surface-hover! hover:aria-[current=true]:text-current-foreground!;
8
25
  }
9
-
10
- .dx-highlighted {
11
- @apply data-[highlighted]:bg-highlight-surface
12
- data-[highlighted]:text-highlight-surface-text
13
- hover:data-[highlighted]:bg-highlight-surface-hover;
26
+ .dx-hover-row {
27
+ @apply group-hover/row:bg-hover-surface! group-hover/row:text-hover-foreground!
28
+ group-hover/row:group-aria-selected/row:bg-selected-surface-hover!
29
+ group-hover/row:group-aria-selected/row:text-selected-foreground!
30
+ group-hover/row:group-aria-[current=true]/row:bg-current-surface-hover!
31
+ group-hover/row:group-aria-[current=true]/row:text-current-foreground!;
14
32
  }
15
33
 
34
+ /*
35
+ * Pairs with `aria-selected`. Use for listbox/option selection (master/detail).
36
+ * `!` is required: these utilities live in the `dx-components` layer, but
37
+ * background utilities like `bg-card-surface` live in Tailwind's
38
+ * `utilities` layer (declared later in the cascade), so without
39
+ * `!important` the card background would override the state colour.
40
+ *
41
+ * NOTE: Declared before `.dx-current` so that when an element has both
42
+ * `aria-selected="true"` and `aria-current="true"`, `dx-current` wins at
43
+ * equal specificity (consistent with how `dx-hover` resolves the same
44
+ * conflict).
45
+ */
16
46
  .dx-selected {
17
- @apply aria-selected:bg-selected-surface
18
- aria-selected:text-selected-surface-text
19
- hover:aria-selected:text-selected-surface-text
47
+ @apply aria-selected:bg-selected-surface! aria-selected:text-selected-foreground!
20
48
  aria-selected:font-semibold aria-selected:tracking-normal
21
49
  transition-[color,font-variation-settings,letter-spacing];
22
50
  }
51
+
52
+ /*
53
+ * Pairs with `aria-current="true|page|…"`. Use for "you are here" navigation.
54
+ *
55
+ * The ring uses the subdued focus indicator (neutral) rather than the
56
+ * accent blue — `dx-current` marks position, not focus, so a saturated
57
+ * ring would compete with the actual keyboard focus ring.
58
+ */
59
+ .dx-current {
60
+ @apply dx-ring-pseudo
61
+ aria-[current=true]:bg-current-surface! aria-[current=true]:text-current-foreground!
62
+ aria-[current=true]:after:ring-focus-ring-subtle!;
63
+ }
64
+ .dx-current-row {
65
+ @apply group-aria-[current=true]/row:bg-current-surface! group-aria-[current=true]/row:text-current-foreground!;
66
+ }
67
+
68
+ /*
69
+ * Pairs with Radix-managed `data-highlighted`. Don't set the attribute manually.
70
+ */
71
+ .dx-highlighted {
72
+ @apply data-[highlighted]:bg-current-surface
73
+ data-[highlighted]:text-current-foreground
74
+ hover:data-[highlighted]:bg-current-surface-hover;
75
+ }
23
76
  }
@@ -0,0 +1,101 @@
1
+ # `dx-*` selection / navigation grammar
2
+
3
+ Companion to `selected.css`. The four selection-state utilities below are
4
+ each bound to a specific ARIA attribute (or `data-*`) selector. **The
5
+ class only fires when the matching ARIA attribute is set on the same
6
+ element.** Mismatches (e.g. `dx-current` paired with `aria-selected`)
7
+ silently render as a plain row.
8
+
9
+ | Class | Bound selector | Pair with | Use when |
10
+ | ---------------- | ---------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11
+ | `dx-hover` | `hover:` | (no ARIA — pure visual affordance) | Always, on any clickable row. Adds the cursor + hover bg/text. |
12
+ | `dx-selected` | `aria-selected:` | `aria-selected={boolean}` | A row is "the chosen one" driving a master/detail panel. Listbox / option pattern. Multi-select OK. |
13
+ | `dx-current` | `aria-[current=true]:` | `aria-current='true'` | A row is "where you are" in a navigation set (current page, current step). At most one current per group. The CSS variant fires only on `aria-current='true'`, so use that literal even on `<a>`/nav links. |
14
+ | `dx-highlighted` | `data-[highlighted]:` | Radix `data-highlighted` (managed) | A Radix-managed transient highlight (menu / combobox active option). Don't set the attribute manually. |
15
+
16
+ ## Rules
17
+
18
+ 1. **Never combine `dx-selected` and `dx-current` on the same element**
19
+ unless you also set both `aria-selected` and `aria-current`. They
20
+ express different things (chosen vs you-are-here) and the visual
21
+ weight is similar enough that combining them defeats both.
22
+ 2. **`aria-pressed`, `aria-checked`, `aria-expanded`, `aria-disabled`
23
+ are not selection-row attributes.** None of the `dx-*` selection
24
+ utilities pair with them. Toggle buttons (mute/unmute) want
25
+ `aria-pressed`; a selection row wants `aria-selected`.
26
+ 3. **`aria-selected` is only valid on roles that admit it** — `option`,
27
+ `tab`, `gridcell`, `row`, `treeitem`, `columnheader`, `rowheader`.
28
+ On a plain `<button>` inside a `<ul role='listbox'>`, give the button
29
+ `role='option'` so assistive tech sees the attribute.
30
+ 4. **`dx-active` does not exist.** If you see it in code it's a no-op
31
+ string. Use `dx-selected` (selection) or `dx-current` (navigation)
32
+ instead.
33
+ 5. **Set ARIA before adding the class.** The class is inert without
34
+ the attribute; it's not a fallback styler. Reviewers should reject
35
+ PRs that add `dx-selected` without `aria-selected`.
36
+
37
+ ## Canonical patterns
38
+
39
+ ### Selectable row in a list (master/detail)
40
+
41
+ ```tsx
42
+ <ul role='listbox' aria-label='…'>
43
+ {items.map((item) => (
44
+ <li key={item.id} role='presentation'>
45
+ <button
46
+ type='button'
47
+ role='option'
48
+ aria-selected={item.id === selectedId}
49
+ className='dx-hover dx-selected'
50
+ onClick={() => onSelect(item.id)}
51
+ >
52
+ {item.label}
53
+ </button>
54
+ </li>
55
+ ))}
56
+ </ul>
57
+ ```
58
+
59
+ ### "You are here" in a navigation list
60
+
61
+ ```tsx
62
+ <nav>
63
+ <ul>
64
+ {pages.map((page) => (
65
+ <li key={page.href}>
66
+ <a
67
+ href={page.href}
68
+ aria-current={page.href === currentHref ? 'true' : undefined}
69
+ className='dx-hover dx-current'
70
+ >
71
+ {page.label}
72
+ </a>
73
+ </li>
74
+ ))}
75
+ </ul>
76
+ </nav>
77
+ ```
78
+
79
+ ### Toggle button (NOT a row)
80
+
81
+ Don't reach for `dx-selected` here. Toggle buttons want their own
82
+ visual treatment via `aria-pressed:` variants — out of scope for this
83
+ file.
84
+
85
+ ```tsx
86
+ <button type='button' aria-pressed={muted} onClick={toggleMute}>
87
+ {muted ? 'Unmute' : 'Mute'}
88
+ </button>
89
+ ```
90
+
91
+ ## Enforcing the grammar
92
+
93
+ A future ESLint rule could flag:
94
+
95
+ - `dx-selected` without `aria-selected` on the same element.
96
+ - `dx-current` without `aria-current` on the same element.
97
+ - `dx-active` literal anywhere.
98
+
99
+ Until that exists, reviewers and the `react-ui-list` `RowList` /
100
+ `CardList` containers (which set both attribute and class together)
101
+ are the enforcement.
@@ -4,22 +4,22 @@
4
4
 
5
5
  @layer dx-components {
6
6
  .dx-base-surface {
7
- @apply bg-base-surface text-base-surface-text;
7
+ @apply bg-base-surface text-base-foreground;
8
8
  --surface-bg: var(--color-base-surface);
9
9
  }
10
10
 
11
11
  .dx-sidebar-surface {
12
- @apply bg-sidebar-surface text-base-surface-text;
12
+ @apply bg-sidebar-surface text-base-foreground;
13
13
  --surface-bg: var(--color-sidebar-surface);
14
14
  }
15
15
 
16
16
  .dx-modal-surface {
17
- @apply bg-modal-surface text-base-surface-text backdrop-blur-md;
17
+ @apply bg-modal-surface text-base-foreground backdrop-blur-md;
18
18
  --surface-bg: var(--color-modal-surface);
19
19
  }
20
20
 
21
21
  .dx-attention-surface {
22
- @apply bg-attention-surface text-base-surface-text;
22
+ @apply bg-attention-surface text-base-foreground;
23
23
  --surface-bg: var(--color-attention-surface);
24
24
  }
25
25
  }
@@ -11,7 +11,9 @@
11
11
 
12
12
  .dx-tag--anchor {
13
13
  /* NOTE: Margin offsets padding so that border is flush with text. This should only apply to anchor tags inside of Codemirror. */
14
- @apply inline cursor-pointer -mx-[4px] px-[3px] py-0.5 border border-separator rounded-xs bg-group-surface transition-colors;
14
+ @apply inline cursor-pointer -mx-[3px] px-[2px] py-0.5 border rounded-xs transition-colors;
15
+ /** TODO(burdon): Configure secondary color. */
16
+ @apply bg-group-surface text-sky-foreground border-sky-border;
15
17
 
16
18
  &:hover {
17
19
  @apply bg-hover-surface;
@@ -20,111 +22,111 @@
20
22
 
21
23
  .dx-tag[data-hue='neutral'],
22
24
  .dx-tag--neutral {
23
- @apply bg-neutral-surface text-neutral-surface-text;
25
+ @apply bg-neutral-surface text-neutral-foreground;
24
26
  }
25
27
 
26
28
  .dx-tag[data-hue='red'],
27
29
  .dx-tag--red {
28
- @apply bg-red-surface text-red-surface-text;
30
+ @apply bg-red-surface text-red-foreground;
29
31
  }
30
32
 
31
33
  .dx-tag[data-hue='orange'],
32
34
  .dx-tag--orange {
33
- @apply bg-orange-surface text-orange-surface-text;
35
+ @apply bg-orange-surface text-orange-foreground;
34
36
  }
35
37
 
36
38
  .dx-tag[data-hue='amber'],
37
39
  .dx-tag--amber {
38
- @apply bg-amber-surface text-amber-surface-text;
40
+ @apply bg-amber-surface text-amber-foreground;
39
41
  }
40
42
 
41
43
  .dx-tag[data-hue='yellow'],
42
44
  .dx-tag--yellow {
43
- @apply bg-yellow-surface text-yellow-surface-text;
45
+ @apply bg-yellow-surface text-yellow-foreground;
44
46
  }
45
47
 
46
48
  .dx-tag[data-hue='lime'],
47
49
  .dx-tag--lime {
48
- @apply bg-lime-surface text-lime-surface-text;
50
+ @apply bg-lime-surface text-lime-foreground;
49
51
  }
50
52
 
51
53
  .dx-tag[data-hue='green'],
52
54
  .dx-tag--green {
53
- @apply bg-green-surface text-green-surface-text;
55
+ @apply bg-green-surface text-green-foreground;
54
56
  }
55
57
 
56
58
  .dx-tag[data-hue='emerald'],
57
59
  .dx-tag--emerald {
58
- @apply bg-emerald-surface text-emerald-surface-text;
60
+ @apply bg-emerald-surface text-emerald-foreground;
59
61
  }
60
62
 
61
63
  .dx-tag[data-hue='teal'],
62
64
  .dx-tag--teal {
63
- @apply bg-teal-surface text-teal-surface-text;
65
+ @apply bg-teal-surface text-teal-foreground;
64
66
  }
65
67
 
66
68
  .dx-tag[data-hue='cyan'],
67
69
  .dx-tag--cyan {
68
- @apply bg-cyan-surface text-cyan-surface-text;
70
+ @apply bg-cyan-surface text-cyan-foreground;
69
71
  }
70
72
 
71
73
  .dx-tag[data-hue='sky'],
72
74
  .dx-tag--sky {
73
- @apply bg-sky-surface text-sky-surface-text;
75
+ @apply bg-sky-surface text-sky-foreground;
74
76
  }
75
77
 
76
78
  .dx-tag[data-hue='blue'],
77
79
  .dx-tag--blue {
78
- @apply bg-blue-surface text-blue-surface-text;
80
+ @apply bg-blue-surface text-blue-foreground;
79
81
  }
80
82
 
81
83
  .dx-tag[data-hue='indigo'],
82
84
  .dx-tag--indigo {
83
- @apply bg-indigo-surface text-indigo-surface-text;
85
+ @apply bg-indigo-surface text-indigo-foreground;
84
86
  }
85
87
 
86
88
  .dx-tag[data-hue='violet'],
87
89
  .dx-tag--violet {
88
- @apply bg-violet-surface text-violet-surface-text;
90
+ @apply bg-violet-surface text-violet-foreground;
89
91
  }
90
92
 
91
93
  .dx-tag[data-hue='purple'],
92
94
  .dx-tag--purple {
93
- @apply bg-purple-surface text-purple-surface-text;
95
+ @apply bg-purple-surface text-purple-foreground;
94
96
  }
95
97
 
96
98
  .dx-tag[data-hue='fuchsia'],
97
99
  .dx-tag--fuchsia {
98
- @apply bg-fuchsia-surface text-fuchsia-surface-text;
100
+ @apply bg-fuchsia-surface text-fuchsia-foreground;
99
101
  }
100
102
 
101
103
  .dx-tag[data-hue='pink'],
102
104
  .dx-tag--pink {
103
- @apply bg-pink-surface text-pink-surface-text;
105
+ @apply bg-pink-surface text-pink-foreground;
104
106
  }
105
107
 
106
108
  .dx-tag[data-hue='rose'],
107
109
  .dx-tag--rose {
108
- @apply bg-rose-surface text-rose-surface-text;
110
+ @apply bg-rose-surface text-rose-foreground;
109
111
  }
110
112
 
111
113
  .dx-tag[data-hue='info'],
112
114
  .dx-tag--info {
113
- @apply bg-cyan-surface text-cyan-surface-text;
115
+ @apply bg-cyan-surface text-cyan-foreground;
114
116
  }
115
117
 
116
118
  .dx-tag[data-hue='success'],
117
119
  .dx-tag--success {
118
- @apply bg-emerald-surface text-emerald-surface-text;
120
+ @apply bg-emerald-surface text-emerald-foreground;
119
121
  }
120
122
 
121
123
  .dx-tag[data-hue='warning'],
122
124
  .dx-tag--warning {
123
- @apply bg-amber-surface text-amber-surface-text;
125
+ @apply bg-amber-surface text-amber-foreground;
124
126
  }
125
127
 
126
128
  .dx-tag[data-hue='error'],
127
129
  .dx-tag--error {
128
- @apply bg-rose-surface text-rose-surface-text;
130
+ @apply bg-rose-surface text-rose-foreground;
129
131
  }
130
132
  }
@@ -6,6 +6,7 @@
6
6
  * TODO(burdon): This could move into the ui-editor package (similar to graph.css).
7
7
  */
8
8
 
9
+ /** TODO(burdon): Move to ui-editor */
9
10
  @theme {
10
11
  --color-cm-codeblock: oklch(from var(--color-neutral-500) l c h / 0.1);
11
12
  --color-cm-active-line: light-dark(
@@ -25,8 +26,9 @@
25
26
  --color-cm-comment-surface: light-dark(var(--color-amber-800), var(--color-amber-200));
26
27
 
27
28
  /* Markdown syntax highlighting */
28
- --color-cm-code: light-dark(var(--color-neutral-700), var(--color-neutral-300));
29
+ --color-cm-code: light-dark(var(--color-stone-600), var(--color-stone-400));
30
+ --color-cm-code-inline: light-dark(var(--color-green-500), var(--color-green-500));
29
31
  --color-cm-code-mark: var(--color-blue-500);
30
- --color-cm-mark-opacity: 0.5;
31
- --color-cm-heading: light-dark(var(--color-neutral-900), var(--color-neutral-400));
32
+ --color-cm-heading: light-dark(var(--color-blue-700), var(--color-blue-300));
33
+ --color-cm-heading-number: light-dark(var(--color-blue-600), var(--color-blue-400));
32
34
  }
@@ -2,6 +2,7 @@
2
2
  * Tldraw
3
3
  */
4
4
 
5
+ /** TODO(burdon): Move to tldraw */
5
6
  .tl-background {
6
7
  --color-background: var(--color-base-surface);
7
8
  }
@@ -18,13 +18,6 @@
18
18
  z-index: 0;
19
19
  }
20
20
 
21
- /**
22
- * Main Mobile app.
23
- */
24
- .dx-main-mobile-layout {
25
- @apply absolute inset-0 overflow-hidden flex flex-col;
26
- }
27
-
28
21
  /** TODO(burdon): Reconcile with dx-main-bounce-layout */
29
22
  .dx-main-content-padding-transitions {
30
23
  transition-duration: 200ms;
@@ -3,40 +3,26 @@
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/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.
9
14
  */
10
15
  .dx-size-container {
11
16
  container-type: size;
12
17
  }
13
18
 
14
19
  /**
15
- * Layout rules for flex-based scroll containment:
16
- * `flex flex-col`
17
- * On a container: makes it a flex column so children stack and can use `flex-1`.
18
- * `flex-1`
19
- * On a child: grows to fill the flex parent. Requires the parent to be `flex`.
20
- * `min-h-0` (alongside `flex-1`):
21
- * Overrides default flex children: `min-height:auto` (sized to content), which prevents shrinking.
22
- * Allows element to shrink and trigger overflow/scrolling.
23
- * Always pair with `flex-1` when scroll is needed.
24
- * `h-full`:
25
- * Fills 100% of the parent's *computed* height.
26
- * Use when the parent has a definite height but is not a flex container (e.g. `overflow:hidden` wrapper).
27
- * Unlike `flex-1`, does not require the parent to be flex.
28
- *
29
- * Pattern for a scrollable region inside a flex ancestor:
30
- * ancestor → `flex flex-col` (or `flex flex-row`)
31
- * scroll root → `flex-1 min-h-0` (fills ancestor, can shrink)
32
- * scroll viewport → `h-full overflow-y-scroll` (fills root, scrolls)
33
- */
34
-
35
- /**
36
- * Container that fills the available space.
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.
37
23
  */
38
- .dx-container {
39
- @apply flex-1 min-h-0 min-w-0 h-full w-full;
24
+ .dx-inline-size-container {
25
+ container-type: inline-size;
40
26
  }
41
27
 
42
28
  /**
@@ -50,6 +36,10 @@
50
36
  * Card
51
37
  */
52
38
 
39
+ .dx-card {
40
+ @apply flex flex-col w-full;
41
+ }
42
+
53
43
  .dx-card-square {
54
44
  inline-size: min(
55
45
  min(var(--radix-popper-available-width), var(--spacing-card-max-width)),
@@ -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
+ }
@@ -27,4 +27,10 @@
27
27
  --color-primary-800: var(--color-blue-800);
28
28
  --color-primary-900: var(--color-blue-900);
29
29
  --color-primary-950: var(--color-blue-950);
30
+
31
+ /* Composer logo colors */
32
+ --color-composer-100: rgb(5 40 61);
33
+ --color-composer-200: rgb(10 75 105);
34
+ --color-composer-300: rgb(1 122 183);
35
+ --color-composer-400: rgb(6 197 253);
30
36
  }