@dxos/ui-theme 0.9.0 → 0.9.1-main.c7dcc2e112

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.
@@ -19,12 +19,12 @@
19
19
  */
20
20
  .dx-hover {
21
21
  @apply cursor-pointer
22
- hover:bg-hover-surface! hover:text-hover-fg!
22
+ hover:bg-hover-surface-subtle! hover:text-hover-fg!
23
23
  hover:aria-selected:bg-selected-surface-hover hover:aria-selected:text-selected-fg
24
24
  hover:aria-[current=true]:bg-current-surface-hover hover:aria-[current=true]:text-current-fg;
25
25
  }
26
26
  .dx-hover-row {
27
- @apply group-hover/row:bg-hover-surface! group-hover/row:text-hover-fg!
27
+ @apply group-hover/row:bg-hover-surface-subtle! group-hover/row:text-hover-fg!
28
28
  group-hover/row:group-aria-selected/row:bg-selected-surface-hover!
29
29
  group-hover/row:group-aria-selected/row:text-selected-fg!
30
30
  group-hover/row:group-aria-[current=true]/row:bg-current-surface-hover!
@@ -74,26 +74,3 @@
74
74
  hover:data-[highlighted]:bg-current-surface-hover;
75
75
  }
76
76
  }
77
-
78
- @layer dx-tokens {
79
- /*
80
- * Sidebars sit on a different surface than the main content, so nudge the state highlights to
81
- * keep contrast: offset each token off its `*-base` (see semantic.css) — darker in light mode,
82
- * lighter in dark. Tune the magnitude via --dx-sidebar-l-shift.
83
- */
84
- .dx-main-sidebar {
85
- --dx-sidebar-l-shift: 0.04;
86
- --color-hover-surface: light-dark(
87
- oklch(from var(--dx-hover-surface-base) calc(l - var(--dx-sidebar-l-shift)) c h),
88
- oklch(from var(--dx-hover-surface-base) calc(l + var(--dx-sidebar-l-shift)) c h)
89
- );
90
- --color-current-surface: light-dark(
91
- oklch(from var(--dx-current-surface-base) calc(l - var(--dx-sidebar-l-shift)) c h),
92
- oklch(from var(--dx-current-surface-base) calc(l + var(--dx-sidebar-l-shift)) c h)
93
- );
94
- --color-current-surface-hover: light-dark(
95
- oklch(from var(--dx-current-surface-hover-base) calc(l - var(--dx-sidebar-l-shift)) c h),
96
- oklch(from var(--dx-current-surface-hover-base) calc(l + var(--dx-sidebar-l-shift)) c h)
97
- );
98
- }
99
- }
@@ -1,5 +1,13 @@
1
1
  /**
2
2
  * Surfaces
3
+ *
4
+ * A surface zone paints a background AND publishes its colour as `--surface-bg`, so descendant
5
+ * controls can derive a visible hover/current highlight from the actual surface (see the
6
+ * derivation block below) and surface-matching elements (avatars, gradients) can read it directly.
7
+ *
8
+ * Always enter a surface via one of these `dx-*-surface` classes. A bare `bg-*-surface` utility
9
+ * paints the colour but does NOT publish `--surface-bg`, so control hover collapses onto the
10
+ * base-surface fallback and can become invisible when the surface shares that elevation.
3
11
  */
4
12
 
5
13
  @layer dx-components {
@@ -8,42 +16,87 @@
8
16
  --surface-bg: var(--color-base-surface);
9
17
  }
10
18
 
19
+ .dx-deck-surface {
20
+ @apply bg-deck-surface text-base-fg;
21
+ --surface-bg: var(--color-deck-surface);
22
+ }
23
+
11
24
  .dx-sidebar-surface {
12
25
  @apply bg-sidebar-surface text-base-fg;
13
26
  --surface-bg: var(--color-sidebar-surface);
14
27
  }
15
28
 
29
+ .dx-header-surface {
30
+ @apply bg-header-surface text-base-fg;
31
+ --surface-bg: var(--color-header-surface);
32
+ }
33
+
34
+ .dx-card-surface {
35
+ @apply bg-card-surface text-base-fg;
36
+ --surface-bg: var(--color-card-surface);
37
+ }
38
+
39
+ .dx-group-surface {
40
+ @apply bg-group-surface text-base-fg;
41
+ --surface-bg: var(--color-group-surface);
42
+ }
43
+
44
+ .dx-input-surface {
45
+ @apply bg-input-surface text-base-fg;
46
+ --surface-bg: var(--color-input-surface);
47
+ }
48
+
49
+ .dx-toolbar-surface {
50
+ @apply bg-toolbar-surface text-base-fg;
51
+ --surface-bg: var(--color-toolbar-surface);
52
+ }
53
+
16
54
  .dx-modal-surface {
17
55
  @apply bg-modal-surface text-base-fg backdrop-blur-md;
18
56
  --surface-bg: var(--color-modal-surface);
19
57
  }
20
58
 
21
- .dx-attention-surface {
22
- @apply bg-attention-surface text-base-fg;
23
- --surface-bg: var(--color-attention-surface);
24
- }
25
-
26
59
  .dx-popover-surface {
27
60
  @apply bg-popover-surface text-base-fg backdrop-blur-md;
28
61
  --surface-bg: var(--color-popover-surface);
29
62
  }
63
+
64
+ .dx-attention-surface {
65
+ @apply bg-attention-surface text-base-fg;
66
+ --surface-bg: var(--color-attention-surface);
67
+ }
30
68
  }
31
69
 
32
70
  @layer dx-tokens {
33
71
  /*
34
- * Elevated surfaces (modal, popover) sit higher than the hover/current base tokens, so the
35
- * un-offset state colours collide with the surface itself (e.g. in dark mode the popover surface
36
- * and hover surface are both neutral-750 the highlight is invisible). Re-derive the state
37
- * colours off the actual surface (--surface-bg) via relative oklch darker in light mode,
38
- * lighter in dark so highlights stay visible regardless of how the surface tokens are tuned.
39
- * Mirrors the .dx-main-sidebar offset in state.css.
72
+ * Re-derive the state colours (hover, current, selected) off the host surface for every context
73
+ * that publishes its own --surface-bg. Custom-property substitution runs once per scope, so the
74
+ * formula must be repeated here (it cannot simply inherit from semantic.css, which resolved it
75
+ * against the root surface). Listing all surface zones in one block keeps the offsets identical
76
+ * across surfacesthere is no per-surface divergence to tune.
77
+ *
78
+ * Magnitudes mirror semantic.css; selected-* track current-* via the aliases declared there.
40
79
  */
80
+ .dx-base-surface,
81
+ .dx-deck-surface,
82
+ .dx-sidebar-surface,
83
+ .dx-header-surface,
84
+ .dx-card-surface,
85
+ .dx-group-surface,
86
+ .dx-input-surface,
87
+ .dx-toolbar-surface,
41
88
  .dx-modal-surface,
42
- .dx-popover-surface {
89
+ .dx-popover-surface,
90
+ .dx-attention-surface,
91
+ .dx-main-sidebar {
43
92
  --color-hover-surface: light-dark(
44
93
  oklch(from var(--surface-bg) calc(l - 0.08) c h),
45
94
  oklch(from var(--surface-bg) calc(l + 0.08) c h)
46
95
  );
96
+ --color-hover-surface-subtle: light-dark(
97
+ oklch(from var(--surface-bg) calc(l - 0.02) c h),
98
+ oklch(from var(--surface-bg) calc(l + 0.02) c h)
99
+ );
47
100
  --color-current-surface: light-dark(
48
101
  oklch(from var(--surface-bg) calc(l - 0.1) c h),
49
102
  oklch(from var(--surface-bg) calc(l + 0.1) c h)
@@ -64,7 +64,7 @@
64
64
  }
65
65
 
66
66
  .dx-card-popover {
67
- @apply inline-card-max-width bg-card-surface;
67
+ @apply inline-card-max-width bg-popover-surface;
68
68
  max-width: min(var(--radix-popper-available-width), var(--spacing-card-max-width));
69
69
  max-height: min(var(--radix-popper-available-height), var(--spacing-card-max-height));
70
70
  }
@@ -13,15 +13,15 @@
13
13
  * Elevation ladder — strictly monotonic, z-order low → high.
14
14
  * Dark: darker = lower. Light: lighter = higher (inverted toward white).
15
15
  *
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
16
+ * Level Name Roles
17
+ * 0 void deck, scrim base
18
+ * 1 base base content, L0 icon rail
19
+ * 2 chrome L1/R sidebars, header
20
+ * 3 card card
21
+ * 4 raised group, input, focus/attention
22
+ * 5 bar dialog/modal, toolbar (sticky, drop-shadowed)
23
+ * 6 modal popover, menu, toast, tooltip
24
+ * 7 float
25
25
  *
26
26
  * These are private (--dx-*) knobs — use named surface tokens in components, not these directly.
27
27
  */
@@ -34,12 +34,61 @@
34
34
  --dx-elevation-6: light-dark(var(--color-neutral-50), var(--color-neutral-775));
35
35
  --dx-elevation-7: light-dark(white, var(--color-neutral-750));
36
36
 
37
- /* Surfaces — each maps to exactly one elevation level */
38
- --color-sidebar-surface: var(--dx-elevation-2);
37
+ /**
38
+ * Elevation 0
39
+ */
40
+
41
+ --color-deck-surface: var(--dx-elevation-0);
42
+
43
+ /* Translucent dimming layer; tracks the lowest elevation (void) rather than a raw neutral. */
44
+ --color-scrim-surface: light-dark(
45
+ oklch(from var(--dx-elevation-0) l c h / 0.5),
46
+ oklch(from var(--dx-elevation-0) l c h / 0.25)
47
+ );
48
+
49
+ /**
50
+ * Elevation 1
51
+ */
52
+
53
+ --color-base-surface: var(--dx-elevation-1);
54
+ --color-base-fg: light-dark(var(--color-neutral-950), var(--color-neutral-150));
55
+
56
+ /**
57
+ * Elevation 2
58
+ */
59
+
39
60
  --color-header-surface: var(--dx-elevation-2);
40
- --color-deck-surface: var(--dx-elevation-3);
41
- --color-base-surface: var(--dx-elevation-3);
61
+
62
+ --color-sidebar-surface: var(--dx-elevation-2);
63
+ /* Sidebar body text. Default sits one ramp stop below the current/selected emphasis. */
64
+ --color-sidebar-fg: light-dark(var(--color-neutral-700), var(--color-neutral-250));
65
+ --color-sidebar-current-fg: light-dark(var(--color-neutral-950), var(--color-neutral-75));
66
+
67
+ /* Sidebar / panel layout levels */
68
+ --color-l0-surface: var(--dx-elevation-1);
69
+ --color-l1-surface: var(--dx-elevation-2);
70
+ --color-r0-surface: var(--dx-elevation-2);
71
+ --color-r1-surface: var(--dx-elevation-2);
72
+
73
+ /**
74
+ * Elevation 3
75
+ */
76
+
42
77
  --color-card-surface: var(--dx-elevation-3);
78
+
79
+ /* Map attention to focus-surface logic so that elements acting as active attention zones highlight correctly on focus. */
80
+ --color-attention-surface: var(--dx-elevation-3);
81
+ --color-attention-contains: oklch(from var(--color-accent-bg) l c h / 0.3);
82
+
83
+ /**
84
+ * Elevation 4
85
+ */
86
+
87
+ /* Focus — a raised content surface (one level above card) so an attended pane reads as lifted. */
88
+ --color-focus-surface: var(--dx-elevation-4);
89
+ --color-focus-ring: light-dark(var(--color-blue-400), var(--color-blue-600));
90
+ --color-focus-ring-subtle: light-dark(var(--color-neutral-300), var(--color-neutral-600));
91
+
43
92
  --color-group-surface: var(--dx-elevation-4);
44
93
  /* Subtle alternate of group-surface for zebra striping (e.g. calendar months) — offset off
45
94
  * elevation-4 via relative oklch so it tracks the ramp: darker in light mode, lighter in dark. */
@@ -47,61 +96,92 @@
47
96
  oklch(from var(--dx-elevation-4) calc(l - 0.03) c h),
48
97
  oklch(from var(--dx-elevation-4) calc(l + 0.03) c h)
49
98
  );
99
+
50
100
  --color-input-surface: var(--dx-elevation-4);
101
+
102
+ /**
103
+ * Elevation 5
104
+ */
105
+
51
106
  --color-toolbar-surface: var(--dx-elevation-5);
52
- --color-modal-surface: var(--dx-elevation-6);
53
- --color-popover-surface: var(--dx-elevation-6);
54
107
 
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);
108
+ --color-modal-surface: var(--dx-elevation-5);
60
109
 
61
- --color-scrim-surface: light-dark(
62
- oklch(from var(--color-neutral-50) l c h / 0.5),
63
- oklch(from var(--color-neutral-950) l c h / 0.25)
64
- );
110
+ /**
111
+ * Elevation 6
112
+ */
65
113
 
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));
114
+ --color-popover-surface: var(--dx-elevation-6);
68
115
 
69
- --color-base-fg: light-dark(var(--color-neutral-950), var(--color-neutral-150));
116
+ /**
117
+ * Elevation 7
118
+ */
70
119
 
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));
120
+ /**
121
+ * Misc
122
+ */
74
123
 
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));
124
+ --color-inverse-surface: light-dark(var(--color-neutral-800), var(--color-neutral-200));
125
+ --color-inverse-fg: light-dark(var(--color-neutral-50), var(--color-neutral-950));
79
126
 
80
- /* Map attention to focus-surface logic so that elements acting as active attention zones highlight correctly on focus. */
81
- --color-attention-surface: var(--color-focus-surface);
82
- --color-attention-contains: oklch(from var(--color-accent-bg) l c h / 0.3);
127
+ /*
128
+ * Text emphasis — foregrounds at decreasing emphasis, anchored on --color-base-fg (strongest):
129
+ * base-fg description subdued placeholder (weakest).
130
+ * Tuned for legibility against the surfaces rather than mapped to the elevation ladder (which
131
+ * governs backgrounds, not text contrast), so these stay explicit neutrals.
132
+ */
133
+ --color-description: light-dark(var(--color-neutral-600), var(--color-neutral-400));
134
+ --color-subdued: light-dark(var(--color-neutral-500), var(--color-neutral-600));
135
+ --color-placeholder: light-dark(var(--color-neutral-400), var(--color-neutral-600));
83
136
 
84
- /* input */
137
+ /*
138
+ * Controls — the input/control fill is a deliberate off-ladder token (cf. the grid "paper"
139
+ * surfaces). It backs text inputs and the default/ghost button (bg-input-bg) and must contrast
140
+ * whatever surface it sits on: a subtle inset well in light mode, a raised fill in dark mode that
141
+ * reads lighter than the topmost surface. Do not map it to an elevation level.
142
+ */
85
143
  --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));
144
+ --color-input-fg: var(--color-base-fg);
87
145
 
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.
146
+ /*
147
+ * State surfaces (hover, current, selected) are derived from the host surface (--surface-bg) via
148
+ * relative oklch darker in light mode, lighter in dark — so a highlight stays visible at any
149
+ * elevation. The values here resolve against the root --surface-bg (= base-surface, set in
150
+ * base.css), giving the correct default for content outside any surface zone. Surface zones
151
+ * publish their own --surface-bg and re-derive these tokens in surface.css, which is where the
152
+ * substitution re-runs for that subtree.
153
+ *
154
+ * Offset magnitudes (lightness): hover ∓0.08, subtle ∓0.02, current ∓0.10, current-hover ∓0.12.
155
+ * Keep these in sync with the per-zone re-derivation in components/surface.css.
92
156
  */
93
- --dx-hover-surface-base: light-dark(var(--color-neutral-200), var(--color-neutral-850));
94
- --color-hover-surface: var(--dx-hover-surface-base);
157
+ --color-hover-surface: light-dark(
158
+ oklch(from var(--surface-bg, var(--color-base-surface)) calc(l - 0.08) c h),
159
+ oklch(from var(--surface-bg, var(--color-base-surface)) calc(l + 0.08) c h)
160
+ );
95
161
  --color-hover-fg: light-dark(var(--color-neutral-950), var(--color-neutral-150));
96
162
 
163
+ /*
164
+ * Subtle region hover for large highlight targets (list rows, tiles) where the full
165
+ * control-strength hover reads as too heavy. Consumed by `.dx-hover` / `.dx-hover-row`;
166
+ * controls (buttons) keep --color-hover-surface.
167
+ */
168
+ --color-hover-surface-subtle: light-dark(
169
+ oklch(from var(--surface-bg, var(--color-base-surface)) calc(l - 0.02) c h),
170
+ oklch(from var(--surface-bg, var(--color-base-surface)) calc(l + 0.02) c h)
171
+ );
172
+
97
173
  /* 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);
174
+ --color-current-surface: light-dark(
175
+ oklch(from var(--surface-bg, var(--color-base-surface)) calc(l - 0.1) c h),
176
+ oklch(from var(--surface-bg, var(--color-base-surface)) calc(l + 0.1) c h)
177
+ );
178
+ --color-current-surface-hover: light-dark(
179
+ oklch(from var(--surface-bg, var(--color-base-surface)) calc(l - 0.12) c h),
180
+ oklch(from var(--surface-bg, var(--color-base-surface)) calc(l + 0.12) c h)
181
+ );
102
182
  --color-current-fg: light-dark(var(--color-neutral-950), var(--color-neutral-50));
103
183
 
104
- /* selected (aria-selected) */
184
+ /* selected (aria-selected) tracks current */
105
185
  --color-selected-surface: var(--color-current-surface);
106
186
  --color-selected-surface-hover: var(--color-current-surface-hover);
107
187
  --color-selected-fg: var(--color-current-fg);
@@ -113,6 +193,7 @@
113
193
  --color-accent-text: light-dark(var(--color-blue-600), var(--color-blue-400));
114
194
  --color-accent-text-hover: light-dark(var(--color-blue-500), var(--color-blue-500));
115
195
 
196
+ /* Unaccented */
116
197
  --color-un-accent: var(--color-neutral-400);
117
198
  --color-un-accent-hover: var(--color-neutral-500);
118
199
 
@@ -128,16 +209,21 @@
128
209
  --color-scrollbar-thumb-active: light-dark(var(--color-neutral-200), var(--color-neutral-600));
129
210
  --color-scrollbar-thumb-hover: light-dark(var(--color-neutral-200), var(--color-neutral-600));
130
211
 
131
- /* Sheet */
132
- --color-axis-selected-surface: light-dark(var(--color-neutral-100), var(--color-neutral-900));
133
- --color-axis-selected-text: light-dark(var(--color-neutral-100), var(--color-neutral-900));
134
- --color-axis-surface: light-dark(var(--color-neutral-50), var(--color-neutral-800));
135
- --color-axis-text: light-dark(var(--color-neutral-800), var(--color-neutral-200));
136
-
137
212
  /*
138
- * Grid
213
+ * Sheet / Grid — intentionally OFF the elevation ladder.
139
214
  * NOTE: Update main.css when changing grid tokens (and restart dev server).
215
+ *
216
+ * These are "paper" surfaces for the data grid: maximum-contrast canvases (near-white in light,
217
+ * near-black in dark) plus saturated selection/comment accents. The elevation ladder is
218
+ * monotonic (light: lighter = higher), so it cannot express a surface that is simultaneously the
219
+ * lightest in light mode and the darkest in dark mode. Keep these as explicit neutrals/accents;
220
+ * do not fold them into --dx-elevation-*.
140
221
  */
222
+ --color-axis-surface: light-dark(var(--color-neutral-100), var(--color-neutral-900));
223
+ --color-axis-text: light-dark(var(--color-neutral-700), var(--color-neutral-300));
224
+ --color-axis-selected-surface: light-dark(var(--color-neutral-100), var(--color-neutral-900));
225
+ --color-axis-selected-text: light-dark(var(--color-neutral-100), var(--color-neutral-900));
226
+
141
227
  --color-grid-surface: light-dark(var(--color-neutral-50), var(--color-neutral-950));
142
228
  --color-grid-fg: light-dark(var(--color-neutral-950), var(--color-neutral-50));
143
229
  --color-grid-line: light-dark(var(--color-neutral-200), var(--color-neutral-800));
@@ -149,9 +235,4 @@
149
235
  oklch(from var(--color-green-400) l c h / 0.5),
150
236
  oklch(from var(--color-green-600) l c h / 0.5)
151
237
  );
152
-
153
- /* Text */
154
- --color-placeholder: light-dark(var(--color-neutral-400), var(--color-neutral-600));
155
- --color-subdued: light-dark(var(--color-neutral-500), var(--color-neutral-600));
156
- --color-description: light-dark(var(--color-neutral-600), var(--color-neutral-400));
157
238
  }
@@ -31,7 +31,7 @@
31
31
  /** Minimal trim to allow for ring/outline. */
32
32
  --spacing-form-chrome: var(--spacing-trim-xs);
33
33
  --spacing-form-gap: var(--spacing-trim-sm);
34
- --spacing-form-section-gap: var(--spacing-trim-lg);
34
+ --spacing-form-section-gap: var(--spacing-trim-md);
35
35
 
36
36
  /**
37
37
  * Density: md (default).