@tensor_1/tokens 2.0.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/build/css/components.css +1388 -0
- package/build/css/styles.css +1637 -0
- package/build/css/tokens.css +187 -0
- package/build/tailwind/preset.cjs +80 -0
- package/build/tailwind/theme.css +72 -0
- package/build/ts/tokens.d.ts +6 -0
- package/build/ts/tokens.js +355 -0
- package/package.json +48 -0
- package/themes/mission-control.css +4 -0
- package/themes/posx.css +4 -0
- package/themes/shopx.css +4 -0
- package/themes/tensor.css +4 -0
- package/tokens/base/color.json +68 -0
- package/tokens/base/effect.json +26 -0
- package/tokens/base/size.json +20 -0
- package/tokens/base/space.json +15 -0
- package/tokens/base/typography.json +23 -0
- package/tokens/dark/color.json +59 -0
- package/tokens/dark/effect.json +3 -0
|
@@ -0,0 +1,1637 @@
|
|
|
1
|
+
|
|
2
|
+
@layer uix.tokens, uix.base, uix.util, uix.motion, uix.components;
|
|
3
|
+
/* uix-styleguide — aggregate stylesheet. Declares the cascade-layer order, then imports each layer.
|
|
4
|
+
Component @imports are appended here as phases land (each component file declares @layer uix.components). */
|
|
5
|
+
/* uix tokens — REDIRECT (no longer hand-authored).
|
|
6
|
+
The --uix-* contract is now GENERATED from the DTCG source by Style Dictionary:
|
|
7
|
+
source of truth : tokens/*.json
|
|
8
|
+
build : npm run build:tokens
|
|
9
|
+
output : build/css/tokens.css (this file just re-exports it)
|
|
10
|
+
Edit tokens/ and rebuild — never edit the generated CSS. Kept as a stable import path so
|
|
11
|
+
styles/main.css and any copy-paste consumers keep working. */
|
|
12
|
+
/* GENERATED — do not edit. Source: tokens/ • Build: npm run build:tokens (Style Dictionary).
|
|
13
|
+
The --uix-* contract: light on :root, dark on the dark selector. Names match UIx v1;
|
|
14
|
+
projects override VALUES via the write-only --uix-brand / --uix-brand-fg slots, never names. */
|
|
15
|
+
@layer uix.tokens {
|
|
16
|
+
:root {
|
|
17
|
+
--uix-bg-app: #FAFAFA;
|
|
18
|
+
--uix-bg-subtle: #F5F5F5;
|
|
19
|
+
--uix-bg-hover: #EFEFEF;
|
|
20
|
+
--uix-bg-active: #E5E5E5;
|
|
21
|
+
--uix-surface: #FFFFFF;
|
|
22
|
+
--uix-surface-2: #FFFFFF;
|
|
23
|
+
--uix-surface-3: #FAFAFA;
|
|
24
|
+
--uix-border: #E5E5E5;
|
|
25
|
+
--uix-border-strong: #D4D4D4;
|
|
26
|
+
--uix-text: #0A0A0A;
|
|
27
|
+
--uix-text-hushed: rgba(10,10,10,.62);
|
|
28
|
+
--uix-text-muted: #6B6B6B;
|
|
29
|
+
--uix-text-reverse: #FFFFFF;
|
|
30
|
+
--uix-text-hushed-reverse: rgba(255,255,255,.62);
|
|
31
|
+
--uix-accent: var(--uix-brand,#1447E6);
|
|
32
|
+
--uix-accent-dark: #0E3AC0;
|
|
33
|
+
--uix-accent-light: #4D77F0;
|
|
34
|
+
--uix-accent-hover: color-mix(in srgb, var(--uix-accent) 88%, #000000);
|
|
35
|
+
--uix-accent-fg: var(--uix-brand-fg,#FFFFFF);
|
|
36
|
+
--uix-link: var(--uix-brand,#1447E6);
|
|
37
|
+
--uix-ring: var(--uix-brand,#1447E6);
|
|
38
|
+
--uix-brand-muted: color-mix(in srgb, var(--uix-accent) 12%, transparent);
|
|
39
|
+
--uix-success: #047857;
|
|
40
|
+
--uix-success-fg: #FFFFFF;
|
|
41
|
+
--uix-success-bg: #D0FAE5;
|
|
42
|
+
--uix-warning: #F99C00;
|
|
43
|
+
--uix-warning-fg: #1A1A1A;
|
|
44
|
+
--uix-warning-bg: #FEF3D6;
|
|
45
|
+
--uix-warning-text: #92400E;
|
|
46
|
+
--uix-info: #1447E6;
|
|
47
|
+
--uix-info-fg: #FFFFFF;
|
|
48
|
+
--uix-info-bg: #E3EBFF;
|
|
49
|
+
--uix-info-text: #1447E6;
|
|
50
|
+
--uix-danger: #E40014;
|
|
51
|
+
--uix-danger-fg: #FFFFFF;
|
|
52
|
+
--uix-danger-bg: #FFE4E6;
|
|
53
|
+
--uix-danger-text: #C20012;
|
|
54
|
+
--uix-success-solid: #10B981;
|
|
55
|
+
--uix-warning-solid: #F59E0B;
|
|
56
|
+
--uix-info-solid: #2563EB;
|
|
57
|
+
--uix-danger-solid: #EF4444;
|
|
58
|
+
--uix-chart-1: #2563EB;
|
|
59
|
+
--uix-chart-2: #0891B2;
|
|
60
|
+
--uix-chart-3: #16A34A;
|
|
61
|
+
--uix-chart-4: #F59E0B;
|
|
62
|
+
--uix-chart-5: #EA580C;
|
|
63
|
+
--uix-chart-6: #E11D48;
|
|
64
|
+
--uix-chart-7: #7C3AED;
|
|
65
|
+
--uix-chart-8: #DB2777;
|
|
66
|
+
--uix-chart-neutral: #64748B;
|
|
67
|
+
--uix-row: #FFFFFF;
|
|
68
|
+
--uix-row-alt: #FAFAFA;
|
|
69
|
+
--uix-row-pinned-bg: #F4F7FF;
|
|
70
|
+
--uix-scrollbar-thumb: rgba(10,10,10,.20);
|
|
71
|
+
--uix-scrollbar-thumb-hover: rgba(10,10,10,.34);
|
|
72
|
+
--uix-scrollbar-track: transparent;
|
|
73
|
+
--uix-scrim: rgba(0,0,0,.5);
|
|
74
|
+
--uix-scrim-strong: rgba(0,0,0,.7);
|
|
75
|
+
--uix-shadow-sm: 0 1px 2px rgba(0,0,0,.06);
|
|
76
|
+
--uix-shadow-popover: 0 8px 24px rgba(0,0,0,.10),0 1px 2px rgba(0,0,0,.05);
|
|
77
|
+
--uix-shadow-overlay: 0 16px 48px rgba(0,0,0,.18);
|
|
78
|
+
--uix-highlight-top: inset 0 1px 0 rgba(255,255,255,0);
|
|
79
|
+
--uix-ease-out: cubic-bezier(.23,1,.32,1);
|
|
80
|
+
--uix-ease-out-strong: cubic-bezier(.2,0,0,1);
|
|
81
|
+
--uix-ease-in: cubic-bezier(.4,0,1,1);
|
|
82
|
+
--uix-ease-in-out: cubic-bezier(.77,0,.175,1);
|
|
83
|
+
--uix-ease-spring: cubic-bezier(.34,1.56,.64,1);
|
|
84
|
+
--uix-dur-fast: 120ms;
|
|
85
|
+
--uix-dur: 160ms;
|
|
86
|
+
--uix-dur-slow: 240ms;
|
|
87
|
+
--uix-dur-slower: 320ms;
|
|
88
|
+
--uix-lift: 4px;
|
|
89
|
+
--uix-z-raised: 1;
|
|
90
|
+
--uix-z-sticky: 3;
|
|
91
|
+
--uix-z-dropdown: 10;
|
|
92
|
+
--uix-z-overlay: 20;
|
|
93
|
+
--uix-z-tooltip: 30;
|
|
94
|
+
--uix-z-toast: 100;
|
|
95
|
+
--uix-radius-xs: 4px;
|
|
96
|
+
--uix-radius-sm: 8px;
|
|
97
|
+
--uix-radius-md: 12px;
|
|
98
|
+
--uix-radius-lg: 16px;
|
|
99
|
+
--uix-radius-pill: 999px;
|
|
100
|
+
--uix-row-h: 56px;
|
|
101
|
+
--uix-row-h-compact: 44px;
|
|
102
|
+
--uix-row-h-comfortable: 68px;
|
|
103
|
+
--uix-control-h: 36px;
|
|
104
|
+
--uix-sidebar-w: 248px;
|
|
105
|
+
--uix-topbar-h: 56px;
|
|
106
|
+
--uix-scrollbar-size: 10px;
|
|
107
|
+
--uix-icon-sm: 16px;
|
|
108
|
+
--uix-icon-md: 20px;
|
|
109
|
+
--uix-icon-lg: 24px;
|
|
110
|
+
--uix-peek-w: 420px;
|
|
111
|
+
--uix-space-0: 0;
|
|
112
|
+
--uix-space-1: 4px;
|
|
113
|
+
--uix-space-2: 8px;
|
|
114
|
+
--uix-space-3: 12px;
|
|
115
|
+
--uix-space-4: 16px;
|
|
116
|
+
--uix-space-5: 20px;
|
|
117
|
+
--uix-space-6: 24px;
|
|
118
|
+
--uix-space-7: 32px;
|
|
119
|
+
--uix-space-8: 40px;
|
|
120
|
+
--uix-space-9: 48px;
|
|
121
|
+
--uix-space-10: 64px;
|
|
122
|
+
--uix-space-11: 80px;
|
|
123
|
+
--uix-space-12: 96px;
|
|
124
|
+
--uix-font-sans: "Inter",system-ui,sans-serif;
|
|
125
|
+
--uix-font-heading: "IBM Plex Sans","Inter",system-ui,sans-serif;
|
|
126
|
+
--uix-font-mono: "IBM Plex Mono",ui-monospace,monospace;
|
|
127
|
+
--uix-text-display: 40px;
|
|
128
|
+
--uix-leading-display: 1.05;
|
|
129
|
+
--uix-text-data-hero: 34px;
|
|
130
|
+
--uix-leading-data-hero: 1.1;
|
|
131
|
+
--uix-text-h2: 24px;
|
|
132
|
+
--uix-leading-h2: 1.15;
|
|
133
|
+
--uix-text-h3: 15px;
|
|
134
|
+
--uix-leading-h3: 1.3;
|
|
135
|
+
--uix-text-body: 14px;
|
|
136
|
+
--uix-leading-body: 1.5;
|
|
137
|
+
--uix-text-meta: 12.5px;
|
|
138
|
+
--uix-leading-meta: 1.4;
|
|
139
|
+
--uix-text-eyebrow: 11px;
|
|
140
|
+
--uix-leading-eyebrow: 1.2;
|
|
141
|
+
--uix-tracking-tight: -0.02em;
|
|
142
|
+
--uix-tracking-eyebrow: 0.06em;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
:root:where(.dark,[data-theme="dark"]) {
|
|
146
|
+
--uix-bg-app: #0A0A0A;
|
|
147
|
+
--uix-bg-subtle: #171717;
|
|
148
|
+
--uix-bg-hover: #1F1F1F;
|
|
149
|
+
--uix-bg-active: #262626;
|
|
150
|
+
--uix-surface: #111111;
|
|
151
|
+
--uix-surface-2: #171717;
|
|
152
|
+
--uix-surface-3: #262626;
|
|
153
|
+
--uix-border: rgba(255,255,255,.08);
|
|
154
|
+
--uix-border-strong: rgba(255,255,255,.14);
|
|
155
|
+
--uix-text: #FAFAFA;
|
|
156
|
+
--uix-text-hushed: rgba(250,250,250,.64);
|
|
157
|
+
--uix-text-muted: #A1A1A1;
|
|
158
|
+
--uix-accent: var(--uix-brand,#2563EB);
|
|
159
|
+
--uix-accent-hover: color-mix(in srgb, var(--uix-accent) 82%, #FFFFFF);
|
|
160
|
+
--uix-link: color-mix(in srgb, var(--uix-brand,#5B8DEF) 70%, #FFFFFF);
|
|
161
|
+
--uix-ring: var(--uix-brand,#3080FF);
|
|
162
|
+
--uix-brand-muted: color-mix(in srgb, var(--uix-accent) 16%, transparent);
|
|
163
|
+
--uix-success: #00D294;
|
|
164
|
+
--uix-success-fg: #002C22;
|
|
165
|
+
--uix-success-bg: rgba(0,210,148,.15);
|
|
166
|
+
--uix-warning: #FCBB00;
|
|
167
|
+
--uix-warning-fg: #1A1A1A;
|
|
168
|
+
--uix-warning-bg: rgba(249,156,0,.16);
|
|
169
|
+
--uix-warning-text: var(--uix-warning,#FCBB00);
|
|
170
|
+
--uix-info: #2563EB;
|
|
171
|
+
--uix-info-fg: #FFFFFF;
|
|
172
|
+
--uix-info-bg: rgba(48,128,255,.16);
|
|
173
|
+
--uix-info-text: #60A5FA;
|
|
174
|
+
--uix-danger: #DC2626;
|
|
175
|
+
--uix-danger-fg: #FFFFFF;
|
|
176
|
+
--uix-danger-bg: rgba(220,38,38,.20);
|
|
177
|
+
--uix-danger-text: #F87171;
|
|
178
|
+
--uix-success-solid: #34D399;
|
|
179
|
+
--uix-warning-solid: #FBBF24;
|
|
180
|
+
--uix-info-solid: #3B82F6;
|
|
181
|
+
--uix-danger-solid: #F87171;
|
|
182
|
+
--uix-chart-1: #3080FF;
|
|
183
|
+
--uix-chart-2: #00C2B0;
|
|
184
|
+
--uix-chart-3: #00D294;
|
|
185
|
+
--uix-chart-4: #FCBB00;
|
|
186
|
+
--uix-chart-5: #FF8B1A;
|
|
187
|
+
--uix-chart-6: #FF6568;
|
|
188
|
+
--uix-chart-7: #A685FF;
|
|
189
|
+
--uix-chart-8: #FF667F;
|
|
190
|
+
--uix-chart-neutral: #A1A1A1;
|
|
191
|
+
--uix-row: #111111;
|
|
192
|
+
--uix-row-alt: #161616;
|
|
193
|
+
--uix-row-pinned-bg: rgba(48,128,255,.08);
|
|
194
|
+
--uix-scrollbar-thumb: rgba(255,255,255,.18);
|
|
195
|
+
--uix-scrollbar-thumb-hover: rgba(255,255,255,.30);
|
|
196
|
+
--uix-highlight-top: inset 0 1px 0 rgba(255,255,255,.04);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/* uix base — reset, fonts, element defaults, focus, selection, themed scrollbars.
|
|
200
|
+
Layer order: tokens < base < util < motion < components. */
|
|
201
|
+
/* Fonts load via the Google Fonts <link> in index.html (Inter + IBM Plex Sans + IBM Plex Mono). */
|
|
202
|
+
@layer uix.base {
|
|
203
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
204
|
+
* { margin: 0; }
|
|
205
|
+
|
|
206
|
+
html { -webkit-text-size-adjust: 100%; }
|
|
207
|
+
/* default theme follows the OS until JS sets data-theme */
|
|
208
|
+
@media (prefers-color-scheme: dark) { :root:not([data-theme]):not(.dark) { color-scheme: dark; } }
|
|
209
|
+
:root[data-theme="dark"], :root.dark { color-scheme: dark; }
|
|
210
|
+
:root[data-theme="light"] { color-scheme: light; }
|
|
211
|
+
|
|
212
|
+
body {
|
|
213
|
+
font-family: var(--uix-font-sans);
|
|
214
|
+
font-size: var(--uix-text-body);
|
|
215
|
+
line-height: var(--uix-leading-body);
|
|
216
|
+
color: var(--uix-text);
|
|
217
|
+
background: var(--uix-bg-app);
|
|
218
|
+
-webkit-font-smoothing: antialiased;
|
|
219
|
+
text-rendering: optimizeLegibility;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
h1, h2, h3 { font-family: var(--uix-font-heading); letter-spacing: var(--uix-tracking-tight); font-weight: 600; }
|
|
223
|
+
h1 { font-size: var(--uix-text-display); line-height: var(--uix-leading-display); }
|
|
224
|
+
h2 { font-size: var(--uix-text-h2); line-height: var(--uix-leading-h2); }
|
|
225
|
+
h3 { font-size: var(--uix-text-h3); line-height: var(--uix-leading-h3); }
|
|
226
|
+
|
|
227
|
+
img, svg, video, canvas { display: block; max-width: 100%; }
|
|
228
|
+
input, button, textarea, select { font: inherit; color: inherit; }
|
|
229
|
+
code, kbd, pre, samp { font-family: var(--uix-font-mono); }
|
|
230
|
+
|
|
231
|
+
a { color: var(--uix-link); text-decoration: none; }
|
|
232
|
+
a:hover { text-decoration: underline; }
|
|
233
|
+
/* Content links carry a persistent underline so they aren't distinguished from body text by
|
|
234
|
+
colour alone (WCAG 1.4.1 / link-in-text-block). Chrome links — nav, buttons, tabs, breadcrumbs,
|
|
235
|
+
pills — are all class-bearing, so :not([class]) scopes this to in-text content links only. */
|
|
236
|
+
a[href]:not([class]) { text-decoration: underline; }
|
|
237
|
+
|
|
238
|
+
:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
|
|
239
|
+
:focus:not(:focus-visible) { outline: none; }
|
|
240
|
+
::selection { background: var(--uix-brand-muted); }
|
|
241
|
+
|
|
242
|
+
/* themed scrollbars — Firefox */
|
|
243
|
+
* { scrollbar-width: thin; scrollbar-color: var(--uix-scrollbar-thumb) var(--uix-scrollbar-track); }
|
|
244
|
+
/* themed scrollbars — WebKit/Blink */
|
|
245
|
+
::-webkit-scrollbar { width: var(--uix-scrollbar-size); height: var(--uix-scrollbar-size); }
|
|
246
|
+
::-webkit-scrollbar-track { background: var(--uix-scrollbar-track); }
|
|
247
|
+
::-webkit-scrollbar-thumb {
|
|
248
|
+
background: var(--uix-scrollbar-thumb);
|
|
249
|
+
border-radius: var(--uix-radius-pill);
|
|
250
|
+
border: 2px solid transparent;
|
|
251
|
+
background-clip: content-box;
|
|
252
|
+
}
|
|
253
|
+
::-webkit-scrollbar-thumb:hover {
|
|
254
|
+
background: var(--uix-scrollbar-thumb-hover);
|
|
255
|
+
background-clip: content-box;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/* uix utilities — a few layout/a11y helpers. Keep this small; tokens + components do the heavy lifting. */
|
|
259
|
+
@layer uix.util {
|
|
260
|
+
/* visually hidden but available to screen readers */
|
|
261
|
+
.uix-visually-hidden {
|
|
262
|
+
position: absolute !important;
|
|
263
|
+
width: 1px; height: 1px;
|
|
264
|
+
padding: 0; margin: -1px;
|
|
265
|
+
overflow: hidden; clip: rect(0, 0, 0, 0);
|
|
266
|
+
white-space: nowrap; border: 0;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/* vertical rhythm — set gap via --gap (defaults to --uix-space-4 / 16px) */
|
|
270
|
+
.uix-stack { display: flex; flex-direction: column; gap: var(--gap, var(--uix-space-4)); }
|
|
271
|
+
/* horizontal grouping that wraps */
|
|
272
|
+
.uix-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap, var(--uix-space-2)); }
|
|
273
|
+
|
|
274
|
+
.uix-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
275
|
+
}
|
|
276
|
+
/* uix motion — shared keyframes, enter/exit helpers, and the reduced-motion guard.
|
|
277
|
+
Components reference these tokens/keyframes; overlays pair the helpers with @starting-style. */
|
|
278
|
+
/* Reduced-motion guard — UNLAYERED so its !important beats every component transition. */
|
|
279
|
+
@media (prefers-reduced-motion: reduce) {
|
|
280
|
+
*, *::before, *::after {
|
|
281
|
+
animation-duration: .001ms !important;
|
|
282
|
+
animation-iteration-count: 1 !important;
|
|
283
|
+
transition-duration: .001ms !important;
|
|
284
|
+
scroll-behavior: auto !important;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/* Keyframes (cascade-neutral). */
|
|
288
|
+
@keyframes uix-fade-in { from { opacity: 0; } to { opacity: 1; } }
|
|
289
|
+
@keyframes uix-pop-in {
|
|
290
|
+
from { opacity: 0; transform: scale(.96) translateY(var(--uix-lift)); }
|
|
291
|
+
to { opacity: 1; transform: none; }
|
|
292
|
+
}
|
|
293
|
+
@keyframes uix-slide-in-right { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }
|
|
294
|
+
@keyframes uix-slide-in-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
|
|
295
|
+
@keyframes uix-spin { to { transform: rotate(1turn); } }
|
|
296
|
+
@keyframes uix-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
|
|
297
|
+
@layer uix.motion {
|
|
298
|
+
.uix-anim-fade { animation: uix-fade-in var(--uix-dur) var(--uix-ease-out); }
|
|
299
|
+
.uix-anim-pop { animation: uix-pop-in var(--uix-dur-fast) var(--uix-ease-out); }
|
|
300
|
+
.uix-anim-up { animation: uix-slide-in-up var(--uix-dur) var(--uix-ease-out); }
|
|
301
|
+
|
|
302
|
+
/* Hover-lift affordance for interactive cards/tiles. Gated so touch devices don't get a stuck hover. */
|
|
303
|
+
.uix-lift-hover { transition: transform var(--uix-dur-fast) var(--uix-ease-out), box-shadow var(--uix-dur-fast) var(--uix-ease-out); }
|
|
304
|
+
@media (hover: hover) and (pointer: fine) {
|
|
305
|
+
.uix-lift-hover:hover { transform: translateY(calc(-1 * var(--uix-lift))); box-shadow: var(--uix-shadow-popover); }
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/* components */
|
|
309
|
+
/* uix button — depends only on --uix-* tokens. */
|
|
310
|
+
@layer uix.components {
|
|
311
|
+
.uix-btn {
|
|
312
|
+
display: inline-flex; align-items: center; justify-content: center; gap: .5em;
|
|
313
|
+
height: var(--uix-control-h); padding: 0 var(--uix-space-4); border: 1px solid transparent;
|
|
314
|
+
border-radius: var(--uix-radius-md); font: inherit; font-size: var(--uix-text-body); font-weight: 500;
|
|
315
|
+
line-height: 1; cursor: pointer; user-select: none; white-space: nowrap;
|
|
316
|
+
transition: background-color var(--uix-dur-fast) var(--uix-ease-out),
|
|
317
|
+
border-color var(--uix-dur-fast) var(--uix-ease-out),
|
|
318
|
+
color var(--uix-dur-fast) var(--uix-ease-out),
|
|
319
|
+
transform var(--uix-dur-fast) var(--uix-ease-out);
|
|
320
|
+
}
|
|
321
|
+
.uix-btn:active { transform: scale(.97); }
|
|
322
|
+
.uix-btn:disabled, .uix-btn[aria-disabled="true"] { opacity: .5; pointer-events: none; }
|
|
323
|
+
.uix-btn:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
|
|
324
|
+
.uix-btn svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
|
|
325
|
+
|
|
326
|
+
.uix-btn--primary { background: var(--uix-accent); color: var(--uix-accent-fg); }
|
|
327
|
+
.uix-btn--primary:hover { background: var(--uix-accent-hover); }
|
|
328
|
+
.uix-btn--secondary { background: var(--uix-bg-subtle); color: var(--uix-text); border-color: var(--uix-border); }
|
|
329
|
+
.uix-btn--secondary:hover { background: var(--uix-bg-hover); }
|
|
330
|
+
.uix-btn--outline { background: transparent; color: var(--uix-text); border-color: var(--uix-border-strong); }
|
|
331
|
+
.uix-btn--outline:hover { background: var(--uix-bg-hover); }
|
|
332
|
+
.uix-btn--ghost { background: transparent; color: var(--uix-text); }
|
|
333
|
+
.uix-btn--ghost:hover { background: var(--uix-bg-hover); }
|
|
334
|
+
.uix-btn--danger { background: var(--uix-danger); color: var(--uix-danger-fg); }
|
|
335
|
+
.uix-btn--danger:hover { background: color-mix(in srgb, var(--uix-danger) 88%, black); }
|
|
336
|
+
.uix-btn--link { background: transparent; color: var(--uix-link); height: auto; padding: 0; }
|
|
337
|
+
.uix-btn--link:hover { text-decoration: underline; }
|
|
338
|
+
|
|
339
|
+
.uix-btn--sm { height: 28px; padding: 0 var(--uix-space-3); font-size: var(--uix-text-meta); }
|
|
340
|
+
.uix-btn--lg { height: 44px; padding: 0 var(--uix-space-5); }
|
|
341
|
+
.uix-btn--icon { width: var(--uix-control-h); padding: 0; }
|
|
342
|
+
.uix-btn--icon.uix-btn--sm { width: 28px; }
|
|
343
|
+
.uix-btn--icon.uix-btn--lg { width: 44px; }
|
|
344
|
+
|
|
345
|
+
.uix-btn[data-loading] { color: transparent !important; position: relative; pointer-events: none; }
|
|
346
|
+
.uix-btn[data-loading]::after {
|
|
347
|
+
content: ""; position: absolute; width: 1em; height: 1em;
|
|
348
|
+
border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
|
|
349
|
+
color: var(--uix-accent-fg); animation: uix-spin .6s linear infinite;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/* attached group */
|
|
353
|
+
.uix-btn-group { display: inline-flex; }
|
|
354
|
+
.uix-btn-group .uix-btn { border-radius: 0; border-right-width: 0; }
|
|
355
|
+
.uix-btn-group .uix-btn:first-child { border-top-left-radius: var(--uix-radius-md); border-bottom-left-radius: var(--uix-radius-md); }
|
|
356
|
+
.uix-btn-group .uix-btn:last-child { border-radius: 0 var(--uix-radius-md) var(--uix-radius-md) 0; border-right-width: 1px; }
|
|
357
|
+
}
|
|
358
|
+
/* uix input + field wrapper — depends only on --uix-* tokens. */
|
|
359
|
+
@layer uix.components {
|
|
360
|
+
.uix-field { display: flex; flex-direction: column; gap: var(--uix-space-2); }
|
|
361
|
+
.uix-field__label { font-size: var(--uix-text-meta); font-weight: 500; color: var(--uix-text); }
|
|
362
|
+
.uix-field__label[data-required]::after { content: " *"; color: var(--uix-danger-text); }
|
|
363
|
+
.uix-field__hint { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
364
|
+
.uix-field__error { font-size: var(--uix-text-meta); color: var(--uix-danger-text); display: inline-flex; align-items: center; gap: var(--uix-space-2); }
|
|
365
|
+
.uix-field__error svg, .uix-field__success svg { width: 14px; height: 14px; flex: none; }
|
|
366
|
+
.uix-field__success { font-size: var(--uix-text-meta); color: var(--uix-success); display: inline-flex; align-items: center; gap: var(--uix-space-2); }
|
|
367
|
+
|
|
368
|
+
.uix-input {
|
|
369
|
+
height: var(--uix-control-h); width: 100%;
|
|
370
|
+
padding: 0 var(--uix-space-3); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md);
|
|
371
|
+
background: var(--uix-surface); color: var(--uix-text); font: inherit; font-size: var(--uix-text-body);
|
|
372
|
+
transition: border-color var(--uix-dur-fast) var(--uix-ease-out), box-shadow var(--uix-dur-fast) var(--uix-ease-out);
|
|
373
|
+
}
|
|
374
|
+
.uix-input::placeholder { color: var(--uix-text-muted); }
|
|
375
|
+
.uix-input:hover { border-color: var(--uix-border-strong); }
|
|
376
|
+
.uix-input:focus { outline: none; border-color: var(--uix-ring); box-shadow: 0 0 0 3px var(--uix-brand-muted); }
|
|
377
|
+
.uix-input:disabled { opacity: .55; cursor: not-allowed; background: var(--uix-bg-subtle); }
|
|
378
|
+
.uix-input[readonly] { background: var(--uix-bg-subtle); }
|
|
379
|
+
.uix-input[aria-invalid="true"] { border-color: var(--uix-danger); }
|
|
380
|
+
.uix-input[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px var(--uix-danger-bg); }
|
|
381
|
+
.uix-input--sm { height: 28px; font-size: var(--uix-text-meta); }
|
|
382
|
+
|
|
383
|
+
/* leading/trailing adornments */
|
|
384
|
+
.uix-input-group { position: relative; display: flex; align-items: center; }
|
|
385
|
+
.uix-input-group__icon { position: absolute; left: 10px; color: var(--uix-text-muted); display: inline-flex; pointer-events: none; }
|
|
386
|
+
.uix-input-group__icon svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
|
|
387
|
+
.uix-input-group--has-leading .uix-input { padding-left: 38px; }
|
|
388
|
+
/* validation microinteractions */
|
|
389
|
+
.uix-input[data-valid] { border-color: var(--uix-success); }
|
|
390
|
+
.uix-input[data-valid]:focus { box-shadow: 0 0 0 3px var(--uix-success-bg); }
|
|
391
|
+
.uix-input-group--has-trailing .uix-input { padding-right: 38px; }
|
|
392
|
+
.uix-input-group__icon--trailing { left: auto; right: 10px; }
|
|
393
|
+
}
|
|
394
|
+
/* uix textarea — depends only on --uix-* tokens. */
|
|
395
|
+
@layer uix.components {
|
|
396
|
+
.uix-textarea {
|
|
397
|
+
width: 100%; min-height: 84px; padding: var(--uix-space-3) var(--uix-space-3); resize: vertical;
|
|
398
|
+
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md);
|
|
399
|
+
background: var(--uix-surface); color: var(--uix-text); font: inherit; font-size: var(--uix-text-body);
|
|
400
|
+
line-height: var(--uix-leading-body);
|
|
401
|
+
transition: border-color var(--uix-dur-fast) var(--uix-ease-out), box-shadow var(--uix-dur-fast) var(--uix-ease-out);
|
|
402
|
+
}
|
|
403
|
+
.uix-textarea::placeholder { color: var(--uix-text-muted); }
|
|
404
|
+
.uix-textarea:hover { border-color: var(--uix-border-strong); }
|
|
405
|
+
.uix-textarea:focus { outline: none; border-color: var(--uix-ring); box-shadow: 0 0 0 3px var(--uix-brand-muted); }
|
|
406
|
+
.uix-textarea:disabled { opacity: .55; background: var(--uix-bg-subtle); }
|
|
407
|
+
.uix-textarea[aria-invalid="true"] { border-color: var(--uix-danger); }
|
|
408
|
+
}
|
|
409
|
+
/* uix select (native, styled) — depends only on --uix-* tokens. */
|
|
410
|
+
@layer uix.components {
|
|
411
|
+
.uix-select {
|
|
412
|
+
height: var(--uix-control-h); width: 100%; padding: 0 var(--uix-space-8) 0 var(--uix-space-3); appearance: none;
|
|
413
|
+
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md);
|
|
414
|
+
background-color: var(--uix-surface); color: var(--uix-text); font: inherit; font-size: var(--uix-text-body); cursor: pointer;
|
|
415
|
+
background-repeat: no-repeat; background-position: right 12px center;
|
|
416
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23737373' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
|
417
|
+
transition: border-color var(--uix-dur-fast) var(--uix-ease-out), box-shadow var(--uix-dur-fast) var(--uix-ease-out);
|
|
418
|
+
}
|
|
419
|
+
.uix-select:hover { border-color: var(--uix-border-strong); }
|
|
420
|
+
.uix-select:focus { outline: none; border-color: var(--uix-ring); box-shadow: 0 0 0 3px var(--uix-brand-muted); }
|
|
421
|
+
.uix-select:disabled { opacity: .55; cursor: not-allowed; background-color: var(--uix-bg-subtle); }
|
|
422
|
+
.uix-select--sm { height: 28px; font-size: var(--uix-text-meta); }
|
|
423
|
+
|
|
424
|
+
/* command-palette-style rich select: a trigger that opens a .uix-cmdk popover (search + options) */
|
|
425
|
+
.uix-select-trigger { display: inline-flex; align-items: center; gap: var(--uix-space-2); height: var(--uix-control-h); padding: 0 var(--uix-space-3); min-width: 220px;
|
|
426
|
+
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); background: var(--uix-surface); color: var(--uix-text);
|
|
427
|
+
font: inherit; font-size: var(--uix-text-body); cursor: pointer; transition: border-color var(--uix-dur-fast) var(--uix-ease-out); }
|
|
428
|
+
.uix-select-trigger:hover { border-color: var(--uix-border-strong); }
|
|
429
|
+
.uix-select-trigger:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
|
|
430
|
+
.uix-select-trigger__chevron { margin-left: auto; color: var(--uix-text-muted); width: var(--uix-icon-sm); height: var(--uix-icon-sm); }
|
|
431
|
+
}
|
|
432
|
+
/* uix checkbox — depends only on --uix-* tokens. Markup:
|
|
433
|
+
<label class="uix-checkbox"><input type="checkbox"><span class="uix-checkbox__box">{check svg}</span> Label</label> */
|
|
434
|
+
@layer uix.components {
|
|
435
|
+
.uix-checkbox { display: inline-flex; align-items: center; gap: var(--uix-space-2); cursor: pointer; font-size: var(--uix-text-body); color: var(--uix-text); }
|
|
436
|
+
.uix-checkbox > input { position: absolute; opacity: 0; width: 1px; height: 1px; }
|
|
437
|
+
.uix-checkbox__box {
|
|
438
|
+
width: 18px; height: 18px; flex: none; display: grid; place-items: center;
|
|
439
|
+
border: 1px solid var(--uix-border-strong); border-radius: var(--uix-radius-xs); background: var(--uix-surface);
|
|
440
|
+
transition: background-color var(--uix-dur-fast) var(--uix-ease-out), border-color var(--uix-dur-fast) var(--uix-ease-out);
|
|
441
|
+
}
|
|
442
|
+
.uix-checkbox__box svg {
|
|
443
|
+
width: 13px; height: 13px; color: var(--uix-accent-fg); opacity: 0; transform: scale(.5);
|
|
444
|
+
transition: opacity var(--uix-dur-fast) var(--uix-ease-out), transform var(--uix-dur-fast) var(--uix-ease-spring);
|
|
445
|
+
}
|
|
446
|
+
.uix-checkbox > input:checked + .uix-checkbox__box,
|
|
447
|
+
.uix-checkbox > input:indeterminate + .uix-checkbox__box { background: var(--uix-accent); border-color: var(--uix-accent); }
|
|
448
|
+
.uix-checkbox > input:checked + .uix-checkbox__box svg { opacity: 1; transform: none; }
|
|
449
|
+
.uix-checkbox > input:focus-visible + .uix-checkbox__box { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
|
|
450
|
+
.uix-checkbox > input:disabled ~ * { opacity: .5; }
|
|
451
|
+
}
|
|
452
|
+
/* uix radio + radio-group — depends only on --uix-* tokens. */
|
|
453
|
+
@layer uix.components {
|
|
454
|
+
.uix-radio-group { display: flex; flex-direction: column; gap: var(--uix-space-2); }
|
|
455
|
+
.uix-radio { display: inline-flex; align-items: center; gap: var(--uix-space-2); cursor: pointer; font-size: var(--uix-text-body); color: var(--uix-text); }
|
|
456
|
+
.uix-radio > input { position: absolute; opacity: 0; width: 1px; height: 1px; }
|
|
457
|
+
.uix-radio__dot {
|
|
458
|
+
width: 18px; height: 18px; flex: none; border-radius: 50%;
|
|
459
|
+
border: 1px solid var(--uix-border-strong); background: var(--uix-surface);
|
|
460
|
+
display: grid; place-items: center;
|
|
461
|
+
transition: border-color var(--uix-dur-fast) var(--uix-ease-out);
|
|
462
|
+
}
|
|
463
|
+
.uix-radio__dot::after {
|
|
464
|
+
content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--uix-accent);
|
|
465
|
+
opacity: 0; transform: scale(.4); transition: opacity var(--uix-dur-fast) var(--uix-ease-out), transform var(--uix-dur-fast) var(--uix-ease-spring);
|
|
466
|
+
}
|
|
467
|
+
.uix-radio > input:checked + .uix-radio__dot { border-color: var(--uix-accent); }
|
|
468
|
+
.uix-radio > input:checked + .uix-radio__dot::after { opacity: 1; transform: none; }
|
|
469
|
+
.uix-radio > input:focus-visible + .uix-radio__dot { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
|
|
470
|
+
.uix-radio > input:disabled ~ * { opacity: .5; }
|
|
471
|
+
}
|
|
472
|
+
/* uix switch — depends only on --uix-* tokens. */
|
|
473
|
+
@layer uix.components {
|
|
474
|
+
.uix-switch { display: inline-flex; align-items: center; gap: var(--uix-space-2); cursor: pointer; color: var(--uix-text); font-size: var(--uix-text-body); }
|
|
475
|
+
.uix-switch > input { position: absolute; opacity: 0; width: 1px; height: 1px; }
|
|
476
|
+
.uix-switch__track {
|
|
477
|
+
width: 36px; height: 20px; flex: none; border-radius: var(--uix-radius-pill);
|
|
478
|
+
background: var(--uix-bg-active); position: relative;
|
|
479
|
+
transition: background-color var(--uix-dur) var(--uix-ease-out);
|
|
480
|
+
}
|
|
481
|
+
.uix-switch__track::after {
|
|
482
|
+
content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%;
|
|
483
|
+
background: var(--uix-text-reverse); box-shadow: var(--uix-shadow-sm);
|
|
484
|
+
transition: transform var(--uix-dur) var(--uix-ease-out);
|
|
485
|
+
}
|
|
486
|
+
.uix-switch > input:checked + .uix-switch__track { background: var(--uix-accent); }
|
|
487
|
+
.uix-switch > input:checked + .uix-switch__track::after { transform: translateX(16px); }
|
|
488
|
+
.uix-switch > input:focus-visible + .uix-switch__track { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
|
|
489
|
+
.uix-switch > input:disabled + .uix-switch__track { opacity: .5; }
|
|
490
|
+
}
|
|
491
|
+
/* uix segmented control — depends only on --uix-* tokens. */
|
|
492
|
+
@layer uix.components {
|
|
493
|
+
.uix-segmented { display: inline-flex; padding: var(--uix-space-1); gap: var(--uix-space-1); background: var(--uix-bg-subtle); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); }
|
|
494
|
+
.uix-segmented__option {
|
|
495
|
+
border: 0; background: transparent; color: var(--uix-text-hushed); font: inherit; font-size: var(--uix-text-meta); font-weight: 500;
|
|
496
|
+
padding: var(--uix-space-2) var(--uix-space-3); border-radius: calc(var(--uix-radius-md) - 3px); cursor: pointer;
|
|
497
|
+
transition: background-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
|
|
498
|
+
}
|
|
499
|
+
.uix-segmented__option:hover { color: var(--uix-text); }
|
|
500
|
+
.uix-segmented__option[aria-selected="true"], .uix-segmented__option[aria-pressed="true"] { background: var(--uix-surface); color: var(--uix-text); box-shadow: var(--uix-shadow-sm); }
|
|
501
|
+
.uix-segmented__option:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: 1px; }
|
|
502
|
+
}
|
|
503
|
+
/* uix slider (native range, styled) — depends only on --uix-* tokens. */
|
|
504
|
+
@layer uix.components {
|
|
505
|
+
.uix-slider { -webkit-appearance: none; appearance: none; width: 220px; height: 20px; background: transparent; cursor: pointer; }
|
|
506
|
+
.uix-slider::-webkit-slider-runnable-track { height: 6px; border-radius: var(--uix-radius-pill); background: var(--uix-bg-active); }
|
|
507
|
+
.uix-slider::-moz-range-track { height: 6px; border-radius: var(--uix-radius-pill); background: var(--uix-bg-active); }
|
|
508
|
+
.uix-slider::-moz-range-progress { height: 6px; border-radius: var(--uix-radius-pill); background: var(--uix-accent); }
|
|
509
|
+
.uix-slider::-webkit-slider-thumb {
|
|
510
|
+
-webkit-appearance: none; appearance: none; margin-top: -6px; width: 18px; height: 18px; border-radius: 50%;
|
|
511
|
+
background: var(--uix-surface); border: 2px solid var(--uix-accent); box-shadow: var(--uix-shadow-sm);
|
|
512
|
+
transition: transform var(--uix-dur-fast) var(--uix-ease-out);
|
|
513
|
+
}
|
|
514
|
+
.uix-slider::-moz-range-thumb { width: 18px; height: 18px; border: 2px solid var(--uix-accent); border-radius: 50%; background: var(--uix-surface); box-shadow: var(--uix-shadow-sm); }
|
|
515
|
+
.uix-slider:active::-webkit-slider-thumb { transform: scale(1.12); }
|
|
516
|
+
.uix-slider:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--uix-ring); outline-offset: 2px; }
|
|
517
|
+
.uix-slider:disabled { opacity: .5; cursor: not-allowed; }
|
|
518
|
+
}
|
|
519
|
+
/* uix number stepper — depends only on --uix-* tokens. */
|
|
520
|
+
@layer uix.components {
|
|
521
|
+
.uix-stepper { display: inline-flex; align-items: center; height: var(--uix-control-h); overflow: hidden;
|
|
522
|
+
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); background: var(--uix-surface); }
|
|
523
|
+
.uix-stepper__btn { width: 32px; align-self: stretch; border: 0; background: transparent; color: var(--uix-text); cursor: pointer;
|
|
524
|
+
display: grid; place-items: center; transition: background-color var(--uix-dur-fast) var(--uix-ease-out); }
|
|
525
|
+
.uix-stepper__btn:hover { background: var(--uix-bg-hover); }
|
|
526
|
+
.uix-stepper__btn svg { width: var(--uix-icon-sm); height: var(--uix-icon-sm); }
|
|
527
|
+
.uix-stepper__input { width: 52px; text-align: center; border: 0; height: 100%; background: transparent; color: var(--uix-text);
|
|
528
|
+
font: inherit; border-inline: 1px solid var(--uix-border); -moz-appearance: textfield; }
|
|
529
|
+
.uix-stepper__input::-webkit-outer-spin-button, .uix-stepper__input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
|
|
530
|
+
.uix-stepper:focus-within { border-color: var(--uix-ring); box-shadow: 0 0 0 3px var(--uix-brand-muted); }
|
|
531
|
+
}
|
|
532
|
+
/* uix file upload / dropzone — depends only on --uix-* tokens. */
|
|
533
|
+
@layer uix.components {
|
|
534
|
+
.uix-dropzone {
|
|
535
|
+
display: flex; flex-direction: column; align-items: center; gap: var(--uix-space-2); padding: var(--uix-space-7); text-align: center;
|
|
536
|
+
border: 1.5px dashed var(--uix-border-strong); border-radius: var(--uix-radius-lg);
|
|
537
|
+
background: var(--uix-bg-subtle); color: var(--uix-text-muted); cursor: pointer;
|
|
538
|
+
transition: border-color var(--uix-dur-fast) var(--uix-ease-out), background-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
|
|
539
|
+
}
|
|
540
|
+
.uix-dropzone:hover, .uix-dropzone[data-dragover] { border-color: var(--uix-accent); background: var(--uix-brand-muted); color: var(--uix-text); }
|
|
541
|
+
.uix-dropzone svg { width: var(--uix-icon-lg); height: var(--uix-icon-lg); }
|
|
542
|
+
.uix-filelist { display: flex; flex-direction: column; gap: var(--uix-space-2); margin-top: var(--uix-space-3); }
|
|
543
|
+
.uix-filelist__item { display: flex; align-items: center; gap: var(--uix-space-3); padding: var(--uix-space-2) var(--uix-space-3); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); background: var(--uix-surface); font-size: var(--uix-text-meta); color: var(--uix-text); }
|
|
544
|
+
.uix-filelist__size { margin-left: auto; color: var(--uix-text-muted); }
|
|
545
|
+
}
|
|
546
|
+
/* uix combobox / listbox surface — depends only on --uix-* tokens. */
|
|
547
|
+
@layer uix.components {
|
|
548
|
+
.uix-combobox { position: relative; }
|
|
549
|
+
.uix-listbox {
|
|
550
|
+
list-style: none; margin: 0; padding: var(--uix-space-1); min-width: 200px;
|
|
551
|
+
background: var(--uix-surface-2); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md);
|
|
552
|
+
box-shadow: var(--uix-shadow-popover);
|
|
553
|
+
}
|
|
554
|
+
.uix-listbox__option {
|
|
555
|
+
padding: var(--uix-space-2) var(--uix-space-3); border-radius: var(--uix-radius-sm); font-size: var(--uix-text-body); color: var(--uix-text);
|
|
556
|
+
cursor: pointer; display: flex; align-items: center; gap: var(--uix-space-2);
|
|
557
|
+
}
|
|
558
|
+
.uix-listbox__option:hover, .uix-listbox__option[aria-selected="true"], .uix-listbox__option[data-active] { background: var(--uix-bg-hover); }
|
|
559
|
+
.uix-listbox__option[aria-selected="true"] { color: var(--uix-link); }
|
|
560
|
+
.uix-listbox__empty { padding: var(--uix-space-3); text-align: center; color: var(--uix-text-muted); font-size: var(--uix-text-meta); }
|
|
561
|
+
}
|
|
562
|
+
/* uix tag input / multi-select chips — depends only on --uix-* tokens. */
|
|
563
|
+
@layer uix.components {
|
|
564
|
+
.uix-taginput {
|
|
565
|
+
display: flex; flex-wrap: wrap; align-items: center; gap: var(--uix-space-2); min-height: var(--uix-control-h); padding: var(--uix-space-1) var(--uix-space-2);
|
|
566
|
+
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); background: var(--uix-surface);
|
|
567
|
+
}
|
|
568
|
+
.uix-taginput:focus-within { border-color: var(--uix-ring); box-shadow: 0 0 0 3px var(--uix-brand-muted); }
|
|
569
|
+
.uix-taginput__field { flex: 1; min-width: 80px; border: 0; outline: none; background: transparent; color: var(--uix-text); font: inherit; }
|
|
570
|
+
.uix-tag {
|
|
571
|
+
display: inline-flex; align-items: center; gap: var(--uix-space-1); padding: var(--uix-space-1) var(--uix-space-1) var(--uix-space-1) var(--uix-space-2); border-radius: var(--uix-radius-sm);
|
|
572
|
+
background: var(--uix-bg-active); color: var(--uix-text); font-size: var(--uix-text-meta);
|
|
573
|
+
}
|
|
574
|
+
.uix-tag__remove { display: grid; place-items: center; width: 16px; height: 16px; border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; border-radius: var(--uix-radius-xs); }
|
|
575
|
+
.uix-tag__remove:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
|
|
576
|
+
.uix-tag__remove svg { width: 12px; height: 12px; }
|
|
577
|
+
}
|
|
578
|
+
/* uix form layout — depends only on --uix-* tokens. */
|
|
579
|
+
@layer uix.components {
|
|
580
|
+
.uix-form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--uix-space-5); }
|
|
581
|
+
.uix-fieldset { border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); padding: var(--uix-space-6); }
|
|
582
|
+
.uix-fieldset > legend { padding: 0 var(--uix-space-2); font-size: var(--uix-text-meta); font-weight: 600; color: var(--uix-text); }
|
|
583
|
+
.uix-form-inline { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--uix-space-4); }
|
|
584
|
+
.uix-validation-summary {
|
|
585
|
+
border: 1px solid var(--uix-danger); background: var(--uix-danger-bg); color: var(--uix-text);
|
|
586
|
+
border-radius: var(--uix-radius-md); padding: var(--uix-space-3) var(--uix-space-4); font-size: var(--uix-text-meta);
|
|
587
|
+
}
|
|
588
|
+
.uix-validation-summary strong { color: var(--uix-danger-text); }
|
|
589
|
+
.uix-validation-summary ul { margin: var(--uix-space-2) 0 0; padding-left: var(--uix-space-5); }
|
|
590
|
+
.uix-validation-summary a { color: var(--uix-danger-text); text-decoration: underline; }
|
|
591
|
+
}
|
|
592
|
+
/* uix app shell — sidebar + topbar + content grid. Depends only on --uix-* tokens. */
|
|
593
|
+
@layer uix.components {
|
|
594
|
+
.uix-shell {
|
|
595
|
+
display: grid;
|
|
596
|
+
grid-template-columns: var(--uix-sidebar-w) 1fr;
|
|
597
|
+
grid-template-rows: var(--uix-topbar-h) 1fr;
|
|
598
|
+
height: 100%; min-height: 360px;
|
|
599
|
+
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); overflow: hidden;
|
|
600
|
+
transition: grid-template-columns var(--uix-dur) var(--uix-ease-out);
|
|
601
|
+
}
|
|
602
|
+
.uix-shell__sidebar { grid-row: 1 / 3; background: var(--uix-bg-subtle); border-right: 1px solid var(--uix-border); overflow-y: auto; }
|
|
603
|
+
.uix-shell__topbar { grid-column: 2; display: flex; align-items: center; gap: var(--uix-space-3); padding: 0 var(--uix-space-6); background: var(--uix-bg-app); border-bottom: 1px solid var(--uix-border); }
|
|
604
|
+
.uix-shell__main { grid-column: 2; overflow: auto; padding: var(--uix-space-7); background: var(--uix-bg-app); }
|
|
605
|
+
.uix-shell[data-collapsed] { grid-template-columns: 56px 1fr; }
|
|
606
|
+
}
|
|
607
|
+
/* uix sidebar nav — items, favorites, collapsible sub-items, collapsed rail. Depends only on --uix-* tokens. */
|
|
608
|
+
@layer uix.components {
|
|
609
|
+
.uix-sidebar { width: var(--uix-sidebar-w); background: var(--uix-bg-subtle); display: flex; flex-direction: column; gap: var(--uix-space-1); padding: var(--uix-space-2); overflow-x: hidden; overflow-y: auto; }
|
|
610
|
+
.uix-sidebar__eyebrow {
|
|
611
|
+
font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow); text-transform: uppercase;
|
|
612
|
+
color: var(--uix-text-muted); padding: var(--uix-space-3) var(--uix-space-3) var(--uix-space-1);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/* brand header */
|
|
616
|
+
.uix-sidebar__head { display: flex; align-items: center; justify-content: space-between; gap: var(--uix-space-2); padding: var(--uix-space-1) var(--uix-space-2) var(--uix-space-2); }
|
|
617
|
+
.uix-sidebar__brand { min-width: 0; font-size: var(--uix-text-h3); font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
618
|
+
.uix-sidebar__toggle {
|
|
619
|
+
display: grid; place-items: center; width: 28px; height: 28px; flex: none;
|
|
620
|
+
border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; border-radius: var(--uix-radius-sm);
|
|
621
|
+
transition: background-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
|
|
622
|
+
}
|
|
623
|
+
.uix-sidebar__toggle:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
|
|
624
|
+
.uix-sidebar__toggle svg { width: 18px; height: 18px; }
|
|
625
|
+
|
|
626
|
+
.uix-navitem {
|
|
627
|
+
display: flex; align-items: center; gap: var(--uix-space-3); height: 36px; padding: 0 var(--uix-space-3);
|
|
628
|
+
border-radius: var(--uix-radius-sm); color: var(--uix-text-hushed); cursor: pointer; text-decoration: none;
|
|
629
|
+
border: 0; background: transparent; font: inherit; font-size: var(--uix-text-body); width: 100%; text-align: left;
|
|
630
|
+
transition: background-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
|
|
631
|
+
}
|
|
632
|
+
.uix-navitem:hover { background: var(--uix-bg-hover); color: var(--uix-text); text-decoration: none; }
|
|
633
|
+
/* active uses --uix-link (the brightened-on-dark accent) not raw --uix-accent: the deep accent
|
|
634
|
+
fails AA as text on the brand-muted tint in dark; link reads legibly in both themes. */
|
|
635
|
+
.uix-navitem[aria-current="page"] { background: var(--uix-brand-muted); color: var(--uix-link); font-weight: 500; }
|
|
636
|
+
.uix-navitem__icon { width: var(--uix-icon-md); height: var(--uix-icon-md); flex: none; }
|
|
637
|
+
.uix-navitem__label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
638
|
+
.uix-navitem__badge { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
639
|
+
/* on the active tint, muted badge dips below AA — hushed composites darker on the tint */
|
|
640
|
+
.uix-navitem[aria-current="page"] .uix-navitem__badge { color: var(--uix-text-hushed); }
|
|
641
|
+
.uix-navitem__star { display: grid; place-items: center; width: 22px; height: 22px; border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; border-radius: var(--uix-radius-xs); opacity: 0; transition: opacity var(--uix-dur-fast) var(--uix-ease-out); }
|
|
642
|
+
.uix-navitem__star svg { width: 15px; height: 15px; }
|
|
643
|
+
.uix-navitem:hover .uix-navitem__star { opacity: 1; }
|
|
644
|
+
.uix-navitem__star[data-on] { opacity: 1; color: var(--uix-warning); }
|
|
645
|
+
.uix-navitem__star[data-on] svg { fill: currentColor; }
|
|
646
|
+
|
|
647
|
+
/* collapsible group */
|
|
648
|
+
.uix-navgroup { }
|
|
649
|
+
.uix-navgroup__trigger .uix-navgroup__chevron { margin-left: auto; transition: transform var(--uix-dur) var(--uix-ease-out); }
|
|
650
|
+
.uix-navgroup__trigger[aria-expanded="false"] .uix-navgroup__chevron { transform: rotate(-90deg); }
|
|
651
|
+
.uix-navgroup__chevron { width: var(--uix-icon-sm); height: var(--uix-icon-sm); }
|
|
652
|
+
.uix-navgroup__panel { display: grid; grid-template-rows: 1fr; transition: grid-template-rows var(--uix-dur) var(--uix-ease-out); }
|
|
653
|
+
.uix-navgroup__trigger[aria-expanded="false"] + .uix-navgroup__panel { grid-template-rows: 0fr; }
|
|
654
|
+
.uix-navgroup__panel > div { overflow: hidden; }
|
|
655
|
+
.uix-subitem { padding-left: var(--uix-space-5); }
|
|
656
|
+
.uix-subitem .uix-navitem__label::before { content: ""; display: inline-block; width: 4px; height: 4px; border-radius: 50%; background: var(--uix-text-muted); margin-right: var(--uix-space-3); vertical-align: middle; }
|
|
657
|
+
|
|
658
|
+
/* collapsed rail */
|
|
659
|
+
.uix-sidebar[data-collapsed] { width: 56px; }
|
|
660
|
+
.uix-sidebar[data-collapsed] .uix-navitem__label,
|
|
661
|
+
.uix-sidebar[data-collapsed] .uix-navitem__badge,
|
|
662
|
+
.uix-sidebar[data-collapsed] .uix-navitem__star,
|
|
663
|
+
.uix-sidebar[data-collapsed] .uix-sidebar__eyebrow,
|
|
664
|
+
.uix-sidebar[data-collapsed] .uix-sidebar__brand,
|
|
665
|
+
.uix-sidebar[data-collapsed] .uix-navgroup__chevron,
|
|
666
|
+
.uix-sidebar[data-collapsed] .uix-navgroup__panel { display: none; }
|
|
667
|
+
/* center the icon-only rail; head keeps just the toggle, centered */
|
|
668
|
+
.uix-sidebar[data-collapsed] .uix-navitem { justify-content: center; padding: 0; gap: 0; }
|
|
669
|
+
.uix-sidebar[data-collapsed] .uix-sidebar__head { justify-content: center; padding-inline: 0; }
|
|
670
|
+
}
|
|
671
|
+
/* uix breadcrumbs — depends only on --uix-* tokens. */
|
|
672
|
+
@layer uix.components {
|
|
673
|
+
.uix-breadcrumbs { display: flex; align-items: center; gap: var(--uix-space-2); flex-wrap: wrap; font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
674
|
+
.uix-breadcrumbs a { color: var(--uix-text-muted); text-decoration: none; }
|
|
675
|
+
.uix-breadcrumbs a:hover { color: var(--uix-text); text-decoration: underline; }
|
|
676
|
+
.uix-breadcrumbs__sep { opacity: .55; }
|
|
677
|
+
.uix-breadcrumbs [aria-current="page"] { color: var(--uix-text); font-weight: 500; }
|
|
678
|
+
}
|
|
679
|
+
/* uix tabs — line / enclosed / pill. Depends only on --uix-* tokens. */
|
|
680
|
+
@layer uix.components {
|
|
681
|
+
.uix-tabs { display: flex; gap: var(--uix-space-1); }
|
|
682
|
+
.uix-tab {
|
|
683
|
+
border: 0; background: transparent; font: inherit; font-size: var(--uix-text-body); font-weight: 500;
|
|
684
|
+
color: var(--uix-text-hushed); padding: var(--uix-space-3) var(--uix-space-3); cursor: pointer; position: relative;
|
|
685
|
+
transition: color var(--uix-dur-fast) var(--uix-ease-out), background-color var(--uix-dur-fast) var(--uix-ease-out);
|
|
686
|
+
}
|
|
687
|
+
.uix-tab:hover { color: var(--uix-text); }
|
|
688
|
+
.uix-tab[aria-selected="true"] { color: var(--uix-text); }
|
|
689
|
+
.uix-tab:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: -2px; border-radius: var(--uix-radius-sm); }
|
|
690
|
+
|
|
691
|
+
/* line */
|
|
692
|
+
.uix-tabs--line { border-bottom: 1px solid var(--uix-border); }
|
|
693
|
+
.uix-tabs--line .uix-tab::after {
|
|
694
|
+
content: ""; position: absolute; left: 8px; right: 8px; bottom: -1px; height: 2px;
|
|
695
|
+
background: var(--uix-accent); border-radius: var(--uix-radius-pill);
|
|
696
|
+
transform: scaleX(0); transition: transform var(--uix-dur) var(--uix-ease-out);
|
|
697
|
+
}
|
|
698
|
+
.uix-tabs--line .uix-tab[aria-selected="true"]::after { transform: scaleX(1); }
|
|
699
|
+
|
|
700
|
+
/* enclosed */
|
|
701
|
+
.uix-tabs--enclosed { gap: 0; border-bottom: 1px solid var(--uix-border); }
|
|
702
|
+
.uix-tabs--enclosed .uix-tab { border: 1px solid transparent; border-top-left-radius: var(--uix-radius-md); border-top-right-radius: var(--uix-radius-md); margin-bottom: -1px; }
|
|
703
|
+
.uix-tabs--enclosed .uix-tab[aria-selected="true"] { border-color: var(--uix-border); border-bottom-color: var(--uix-bg-app); background: var(--uix-bg-app); }
|
|
704
|
+
|
|
705
|
+
/* pill */
|
|
706
|
+
.uix-tabs--pill { display: inline-flex; background: var(--uix-bg-subtle); padding: var(--uix-space-1); border-radius: var(--uix-radius-md); }
|
|
707
|
+
.uix-tabs--pill .uix-tab { padding: var(--uix-space-2) var(--uix-space-4); border-radius: calc(var(--uix-radius-md) - 3px); }
|
|
708
|
+
.uix-tabs--pill .uix-tab[aria-selected="true"] { background: var(--uix-surface); box-shadow: var(--uix-shadow-sm); }
|
|
709
|
+
}
|
|
710
|
+
/* uix pagination — depends only on --uix-* tokens. */
|
|
711
|
+
@layer uix.components {
|
|
712
|
+
.uix-pagination { display: inline-flex; align-items: center; gap: var(--uix-space-1); }
|
|
713
|
+
.uix-pagination__btn {
|
|
714
|
+
min-width: 32px; height: 32px; padding: 0 var(--uix-space-2); display: inline-flex; align-items: center; justify-content: center;
|
|
715
|
+
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-sm); background: var(--uix-surface);
|
|
716
|
+
color: var(--uix-text); font: inherit; font-size: var(--uix-text-meta); line-height: 1; cursor: pointer;
|
|
717
|
+
transition: background-color var(--uix-dur-fast) var(--uix-ease-out), border-color var(--uix-dur-fast) var(--uix-ease-out);
|
|
718
|
+
}
|
|
719
|
+
.uix-pagination__btn:hover { background: var(--uix-bg-hover); }
|
|
720
|
+
.uix-pagination__btn[aria-current="page"] { background: var(--uix-accent); border-color: var(--uix-accent); color: var(--uix-accent-fg); }
|
|
721
|
+
.uix-pagination__btn:disabled { opacity: .45; pointer-events: none; }
|
|
722
|
+
.uix-pagination__ellipsis { padding: 0 var(--uix-space-1); color: var(--uix-text-muted); }
|
|
723
|
+
}
|
|
724
|
+
/* uix steps / wizard — depends only on --uix-* tokens. */
|
|
725
|
+
@layer uix.components {
|
|
726
|
+
.uix-steps { display: flex; align-items: center; gap: 0; }
|
|
727
|
+
.uix-step { display: flex; align-items: center; gap: var(--uix-space-3); color: var(--uix-text-muted); }
|
|
728
|
+
.uix-step__marker {
|
|
729
|
+
width: 26px; height: 26px; flex: none; border-radius: 50%; display: grid; place-items: center;
|
|
730
|
+
border: 1px solid var(--uix-border-strong); background: var(--uix-surface); font-size: var(--uix-text-meta); font-weight: 600;
|
|
731
|
+
line-height: 1; /* hug the glyph so place-items:center truly centers single digits/symbols */
|
|
732
|
+
}
|
|
733
|
+
.uix-step__label { font-size: var(--uix-text-meta); font-weight: 500; }
|
|
734
|
+
.uix-step__connector { flex: 1; height: 1px; min-width: 28px; background: var(--uix-border); margin: 0 var(--uix-space-3); }
|
|
735
|
+
.uix-step[data-state="active"] { color: var(--uix-text); }
|
|
736
|
+
.uix-step[data-state="active"] .uix-step__marker { border-color: var(--uix-accent); color: var(--uix-accent); box-shadow: 0 0 0 3px var(--uix-brand-muted); }
|
|
737
|
+
.uix-step[data-state="done"] { color: var(--uix-text); }
|
|
738
|
+
.uix-step[data-state="done"] .uix-step__marker { background: var(--uix-accent); border-color: var(--uix-accent); color: var(--uix-accent-fg); }
|
|
739
|
+
.uix-step[data-state="done"] + .uix-step__connector,
|
|
740
|
+
.uix-step__connector[data-done] { background: var(--uix-accent); }
|
|
741
|
+
}
|
|
742
|
+
/* uix command palette (⌘K) — inner surface; mounts in a dialog/popover (overlay mechanics in motion + overlays). */
|
|
743
|
+
@layer uix.components {
|
|
744
|
+
.uix-cmdk { width: min(560px, 92vw); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); background: var(--uix-surface-2); box-shadow: var(--uix-shadow-overlay); overflow: hidden; }
|
|
745
|
+
.uix-cmdk__input { width: 100%; height: 48px; border: 0; border-bottom: 1px solid var(--uix-border); background: transparent; color: var(--uix-text); font: inherit; font-size: var(--uix-text-h3); padding: 0 var(--uix-space-4); }
|
|
746
|
+
.uix-cmdk__input:focus { outline: none; }
|
|
747
|
+
.uix-cmdk__list { max-height: 320px; overflow-y: auto; padding: var(--uix-space-2); }
|
|
748
|
+
.uix-cmdk__group { font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow); text-transform: uppercase; color: var(--uix-text-muted); padding: var(--uix-space-2) var(--uix-space-3) var(--uix-space-1); }
|
|
749
|
+
.uix-cmdk__item { display: flex; align-items: center; gap: var(--uix-space-3); padding: var(--uix-space-3) var(--uix-space-3); border-radius: var(--uix-radius-sm); color: var(--uix-text); cursor: pointer; font-size: var(--uix-text-body); }
|
|
750
|
+
.uix-cmdk__item svg { width: var(--uix-icon-md); height: var(--uix-icon-md); color: var(--uix-text-muted); }
|
|
751
|
+
.uix-cmdk__item:hover, .uix-cmdk__item[data-active] { background: var(--uix-bg-hover); }
|
|
752
|
+
.uix-cmdk__item .uix-kbd { margin-left: auto; }
|
|
753
|
+
/* ⌘K is keyboard-triggered and high-frequency → open instantly, no animation (Emil's rule) */
|
|
754
|
+
dialog[data-uix-cmdk-dialog], dialog[data-uix-cmdk-dialog]::backdrop { transition: none; }
|
|
755
|
+
}
|
|
756
|
+
/* uix menu / dropdown / context menu — popover-anchored surface. Depends only on --uix-* tokens. */
|
|
757
|
+
@layer uix.components {
|
|
758
|
+
.uix-menu { min-width: 200px; margin: 0; padding: var(--uix-space-1); list-style: none; background: var(--uix-surface-2); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); box-shadow: var(--uix-shadow-popover); }
|
|
759
|
+
.uix-menu__item {
|
|
760
|
+
display: flex; align-items: center; gap: var(--uix-space-3); width: 100%; text-align: left; padding: var(--uix-space-2) var(--uix-space-3);
|
|
761
|
+
border: 0; background: transparent; border-radius: var(--uix-radius-sm); color: var(--uix-text); font: inherit; font-size: var(--uix-text-body); cursor: pointer;
|
|
762
|
+
}
|
|
763
|
+
.uix-menu__item svg { width: var(--uix-icon-md); height: var(--uix-icon-md); color: var(--uix-text-muted); }
|
|
764
|
+
.uix-menu__item:hover, .uix-menu__item[data-active] { background: var(--uix-bg-hover); }
|
|
765
|
+
.uix-menu__item--danger { color: var(--uix-danger-text); }
|
|
766
|
+
.uix-menu__item--danger svg { color: var(--uix-danger-text); }
|
|
767
|
+
.uix-menu__item .uix-kbd { margin-left: auto; }
|
|
768
|
+
.uix-menu__sep { height: 1px; background: var(--uix-border); margin: var(--uix-space-1) 0; }
|
|
769
|
+
.uix-menu__label { font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow); text-transform: uppercase; color: var(--uix-text-muted); padding: var(--uix-space-2) var(--uix-space-3) var(--uix-space-1); }
|
|
770
|
+
}
|
|
771
|
+
/* uix page header — title/subtitle/actions row. Depends only on --uix-* tokens. */
|
|
772
|
+
@layer uix.components {
|
|
773
|
+
.uix-page-header { display: flex; align-items: flex-start; gap: var(--uix-space-5); flex-wrap: wrap; padding-bottom: var(--uix-space-6); margin-bottom: var(--uix-space-7); border-bottom: 1px solid var(--uix-border); }
|
|
774
|
+
.uix-page-header__titles { flex: 1; min-width: 220px; }
|
|
775
|
+
.uix-page-header__eyebrow { font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow); text-transform: uppercase; font-weight: 600; color: var(--uix-text-muted); margin-bottom: var(--uix-space-2); }
|
|
776
|
+
.uix-page-header__title { font-size: var(--uix-text-h2); font-weight: 600; letter-spacing: var(--uix-tracking-tight); }
|
|
777
|
+
.uix-page-header__subtitle { color: var(--uix-text-muted); font-size: var(--uix-text-meta); margin-top: var(--uix-space-2); max-width: 70ch; }
|
|
778
|
+
.uix-page-header__actions { display: flex; gap: var(--uix-space-2); align-items: center; flex-wrap: wrap; }
|
|
779
|
+
}
|
|
780
|
+
/* uix keyboard-shortcut chip — depends only on --uix-* tokens. */
|
|
781
|
+
@layer uix.components {
|
|
782
|
+
.uix-kbd {
|
|
783
|
+
display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 var(--uix-space-2);
|
|
784
|
+
font-family: var(--uix-font-mono); font-size: var(--uix-text-eyebrow); color: var(--uix-text-muted);
|
|
785
|
+
background: var(--uix-bg-subtle); border: 1px solid var(--uix-border); border-bottom-width: 2px; border-radius: var(--uix-radius-xs);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
/* uix card — depends only on --uix-* tokens. */
|
|
789
|
+
@layer uix.components {
|
|
790
|
+
.uix-card { background: var(--uix-surface); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); box-shadow: var(--uix-shadow-sm); }
|
|
791
|
+
.uix-card__header { padding: var(--uix-space-5) var(--uix-space-6); border-bottom: 1px solid var(--uix-border); display: flex; align-items: center; gap: var(--uix-space-3); }
|
|
792
|
+
.uix-card__title { font-size: var(--uix-text-h3); font-weight: 600; }
|
|
793
|
+
.uix-card__subtitle { font-size: var(--uix-text-meta); color: var(--uix-text-muted); margin-top: var(--uix-space-1); }
|
|
794
|
+
.uix-card__body { padding: var(--uix-space-6); }
|
|
795
|
+
.uix-card__footer { padding: var(--uix-space-4) var(--uix-space-6); border-top: 1px solid var(--uix-border); display: flex; gap: var(--uix-space-2); justify-content: flex-end; }
|
|
796
|
+
}
|
|
797
|
+
/* uix KPI / stat tile — depends only on --uix-* tokens. */
|
|
798
|
+
@layer uix.components {
|
|
799
|
+
.uix-stat { background: var(--uix-surface); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); padding: var(--uix-space-6); }
|
|
800
|
+
.uix-stat__label { font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow); text-transform: uppercase; color: var(--uix-text-muted); display: flex; align-items: center; justify-content: space-between; gap: var(--uix-space-2); }
|
|
801
|
+
.uix-stat__label svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
|
|
802
|
+
.uix-stat__value { font-size: var(--uix-text-data-hero); font-weight: 600; line-height: var(--uix-leading-data-hero); margin-top: var(--uix-space-3); }
|
|
803
|
+
.uix-stat__meta { font-size: var(--uix-text-meta); color: var(--uix-text-muted); margin-top: var(--uix-space-2); display: flex; align-items: center; gap: var(--uix-space-2); }
|
|
804
|
+
.uix-stat__trend { display: inline-flex; align-items: center; gap: var(--uix-space-1); font-size: var(--uix-text-meta); font-weight: 600; padding: var(--uix-space-1) var(--uix-space-2); border-radius: var(--uix-radius-pill); }
|
|
805
|
+
.uix-stat__trend--up { color: var(--uix-success); background: var(--uix-success-bg); }
|
|
806
|
+
.uix-stat__trend--down { color: var(--uix-danger-text); background: var(--uix-danger-bg); }
|
|
807
|
+
}
|
|
808
|
+
/* uix status pill — tone API (status / priority / SLA). Depends only on --uix-* tokens. */
|
|
809
|
+
@layer uix.components {
|
|
810
|
+
.uix-pill {
|
|
811
|
+
display: inline-flex; align-items: center; gap: var(--uix-space-2); padding: var(--uix-space-1) var(--uix-space-3); border-radius: var(--uix-radius-pill);
|
|
812
|
+
font-size: var(--uix-text-meta); font-weight: 500; line-height: 1.4;
|
|
813
|
+
background: var(--tone-bg, var(--uix-bg-active)); color: var(--tone-fg, var(--uix-text-hushed));
|
|
814
|
+
}
|
|
815
|
+
.uix-pill__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--tone-dot, currentColor); flex: none; }
|
|
816
|
+
.uix-pill--neutral { --tone-bg: var(--uix-bg-active); --tone-fg: var(--uix-text-hushed); --tone-dot: var(--uix-text-muted); }
|
|
817
|
+
.uix-pill--success { --tone-bg: var(--uix-success-bg); --tone-fg: var(--uix-success); --tone-dot: var(--uix-success); }
|
|
818
|
+
.uix-pill--info { --tone-bg: var(--uix-info-bg); --tone-fg: var(--uix-info-text); --tone-dot: var(--uix-info); }
|
|
819
|
+
.uix-pill--warning { --tone-bg: var(--uix-warning-bg); --tone-fg: var(--uix-warning-text); --tone-dot: var(--uix-warning); }
|
|
820
|
+
.uix-pill--danger { --tone-bg: var(--uix-danger-bg); --tone-fg: var(--uix-danger-text); --tone-dot: var(--uix-danger); }
|
|
821
|
+
/* critical = the one SOLID fill (most urgent); muted = a quiet, chrome-less label */
|
|
822
|
+
.uix-pill--critical { --tone-bg: var(--uix-danger); --tone-fg: var(--uix-danger-fg); --tone-dot: var(--uix-danger-fg); }
|
|
823
|
+
.uix-pill--muted { --tone-bg: transparent; --tone-fg: var(--uix-text-muted); --tone-dot: var(--uix-text-muted); }
|
|
824
|
+
|
|
825
|
+
/* outline treatment — transparent fill, tone-tinted border, tone-colored text. The border tints
|
|
826
|
+
the tone hue (--tone-fg) at 40%; neutral/muted use the structural borders, critical reads strongest. */
|
|
827
|
+
.uix-pill--outline { background: transparent; border: 1px solid var(--tone-line, color-mix(in srgb, var(--tone-fg) 40%, transparent)); }
|
|
828
|
+
.uix-pill--outline.uix-pill--neutral { --tone-line: var(--uix-border-strong); }
|
|
829
|
+
.uix-pill--outline.uix-pill--muted { --tone-line: var(--uix-border); }
|
|
830
|
+
.uix-pill--outline.uix-pill--critical { color: var(--uix-danger-text); --tone-dot: var(--uix-danger); --tone-line: color-mix(in srgb, var(--uix-danger) 60%, transparent); }
|
|
831
|
+
}
|
|
832
|
+
/* uix data table — zebra, sticky header, sort, selection, density, pinned rows. Depends only on --uix-* tokens. */
|
|
833
|
+
@layer uix.components {
|
|
834
|
+
.uix-table-wrap { overflow: auto; max-height: 460px; border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); background: var(--uix-surface); }
|
|
835
|
+
.uix-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--uix-text-body); }
|
|
836
|
+
|
|
837
|
+
.uix-table thead th {
|
|
838
|
+
position: sticky; top: 0; z-index: var(--uix-z-raised); background: var(--uix-surface); text-align: left;
|
|
839
|
+
font-size: var(--uix-text-meta); font-weight: 600; color: var(--uix-text-hushed);
|
|
840
|
+
padding: 0 var(--uix-space-4); height: 44px; border-bottom: 1px solid var(--uix-border); white-space: nowrap;
|
|
841
|
+
}
|
|
842
|
+
.uix-table th[data-sort] { cursor: pointer; user-select: none; }
|
|
843
|
+
.uix-table th[data-sort]:hover { color: var(--uix-text); }
|
|
844
|
+
.uix-table th[data-sort]::after { content: " ↕"; opacity: .35; }
|
|
845
|
+
.uix-table th[aria-sort="ascending"]::after { content: " ↑"; opacity: 1; color: var(--uix-accent); }
|
|
846
|
+
.uix-table th[aria-sort="descending"]::after { content: " ↓"; opacity: 1; color: var(--uix-accent); }
|
|
847
|
+
|
|
848
|
+
.uix-table td { padding: 0 var(--uix-space-4); height: var(--uix-row-h); border-bottom: 1px solid var(--uix-border); color: var(--uix-text); vertical-align: middle; }
|
|
849
|
+
.uix-table tbody tr { background: var(--uix-row); }
|
|
850
|
+
.uix-table tbody tr:nth-child(even) { background: var(--uix-row-alt); }
|
|
851
|
+
.uix-table--no-zebra tbody tr, .uix-table--no-zebra tbody tr:nth-child(even) { background: var(--uix-row); }
|
|
852
|
+
.uix-table tbody tr[data-pinned] { background: var(--uix-row-pinned-bg); }
|
|
853
|
+
.uix-table tbody tr[aria-selected="true"] { background: var(--uix-brand-muted); }
|
|
854
|
+
.uix-table tbody tr:hover { background: var(--uix-bg-hover); }
|
|
855
|
+
/* density tiers — standard is the default td height above; data-density overrides it.
|
|
856
|
+
.uix-table--compact kept as a back-compat alias. */
|
|
857
|
+
.uix-table[data-density="compact"] td, .uix-table--compact td { height: var(--uix-row-h-compact); }
|
|
858
|
+
.uix-table[data-density="comfortable"] td { height: var(--uix-row-h-comfortable); }
|
|
859
|
+
|
|
860
|
+
.uix-table__pin { border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; padding: var(--uix-space-1); border-radius: var(--uix-radius-xs); opacity: 0; transition: opacity var(--uix-dur-fast) var(--uix-ease-out); }
|
|
861
|
+
.uix-table tbody tr:hover .uix-table__pin, .uix-table__pin[data-on] { opacity: 1; }
|
|
862
|
+
.uix-table__pin:hover { background: var(--uix-bg-active); color: var(--uix-text); }
|
|
863
|
+
.uix-table__pin[data-on] { color: var(--uix-accent); }
|
|
864
|
+
.uix-table__pin svg { width: 15px; height: 15px; }
|
|
865
|
+
.uix-table__pin[data-on] svg { fill: currentColor; }
|
|
866
|
+
|
|
867
|
+
/* frozen first column (opt-in via .uix-table--pinned-col) — keeps the identifier visible on horizontal scroll, preserving zebra/state bg */
|
|
868
|
+
.uix-table--pinned-col th:first-child, .uix-table--pinned-col td:first-child { position: sticky; left: 0; z-index: var(--uix-z-raised); box-shadow: 1px 0 0 var(--uix-border); }
|
|
869
|
+
.uix-table--pinned-col thead th:first-child { z-index: var(--uix-z-sticky); background: var(--uix-surface); }
|
|
870
|
+
.uix-table--pinned-col tbody tr td:first-child { background: var(--uix-row); }
|
|
871
|
+
.uix-table--pinned-col tbody tr:nth-child(even) td:first-child { background: var(--uix-row-alt); }
|
|
872
|
+
.uix-table--pinned-col.uix-table--no-zebra tbody tr td:first-child,
|
|
873
|
+
.uix-table--pinned-col.uix-table--no-zebra tbody tr:nth-child(even) td:first-child { background: var(--uix-row); }
|
|
874
|
+
.uix-table--pinned-col tbody tr[data-pinned] td:first-child { background: var(--uix-row-pinned-bg); }
|
|
875
|
+
.uix-table--pinned-col tbody tr:hover td:first-child { background: var(--uix-bg-hover); }
|
|
876
|
+
}
|
|
877
|
+
/* uix table toolbar + two-row filter bar (status / type). Depends only on --uix-* tokens. */
|
|
878
|
+
@layer uix.components {
|
|
879
|
+
.uix-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--uix-space-2); margin-bottom: var(--uix-space-3); }
|
|
880
|
+
.uix-toolbar__spacer { flex: 1; }
|
|
881
|
+
|
|
882
|
+
/* responsive: the status + type groups sit on ONE line when they fit, wrap to two only when cramped */
|
|
883
|
+
.uix-filterbar { display: flex; flex-wrap: wrap; gap: var(--uix-space-2) var(--uix-space-5); margin-bottom: var(--uix-space-3); }
|
|
884
|
+
.uix-filterrow { display: flex; flex-wrap: wrap; align-items: center; gap: var(--uix-space-2); }
|
|
885
|
+
.uix-filterrow__label { font-size: var(--uix-text-meta); color: var(--uix-text-muted); width: 54px; flex: none; }
|
|
886
|
+
|
|
887
|
+
.uix-chip {
|
|
888
|
+
display: inline-flex; align-items: center; gap: var(--uix-space-2); padding: var(--uix-space-1) var(--uix-space-3); border-radius: var(--uix-radius-pill);
|
|
889
|
+
border: 1px solid var(--uix-border); background: var(--uix-surface); color: var(--uix-text-hushed);
|
|
890
|
+
font: inherit; font-size: var(--uix-text-meta); cursor: pointer;
|
|
891
|
+
transition: background-color var(--uix-dur-fast) var(--uix-ease-out), border-color var(--uix-dur-fast) var(--uix-ease-out), color var(--uix-dur-fast) var(--uix-ease-out);
|
|
892
|
+
}
|
|
893
|
+
.uix-chip:hover { border-color: var(--uix-border-strong); color: var(--uix-text); }
|
|
894
|
+
.uix-chip[data-on] { background: var(--uix-brand-muted); border-color: var(--uix-accent); color: var(--uix-accent); }
|
|
895
|
+
.uix-chip__count { font-variant-numeric: tabular-nums; opacity: .7; }
|
|
896
|
+
}
|
|
897
|
+
/* uix table View menu — consolidates density / zebra / freeze / columns into one popover.
|
|
898
|
+
Reuses .uix-popover (surface + animation), .uix-segmented, .uix-switch. Depends only on --uix-* tokens. */
|
|
899
|
+
@layer uix.components {
|
|
900
|
+
.uix-view-menu { min-width: 248px; padding: var(--uix-space-2); }
|
|
901
|
+
.uix-view-menu__group { padding: var(--uix-space-2) var(--uix-space-2); }
|
|
902
|
+
.uix-view-menu__group + .uix-view-menu__group { border-top: 1px solid var(--uix-border); }
|
|
903
|
+
.uix-view-menu__label { font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow); text-transform: uppercase; color: var(--uix-text-muted); margin-bottom: var(--uix-space-2); }
|
|
904
|
+
.uix-view-menu__row { display: flex; align-items: center; justify-content: space-between; gap: var(--uix-space-3); font-size: var(--uix-text-body); color: var(--uix-text); cursor: pointer; }
|
|
905
|
+
.uix-view-menu__row + .uix-view-menu__row { margin-top: var(--uix-space-3); }
|
|
906
|
+
.uix-view-menu .uix-segmented { display: flex; width: 100%; }
|
|
907
|
+
.uix-view-menu .uix-segmented__option { flex: 1; text-align: center; }
|
|
908
|
+
.uix-view-menu__cols { display: flex; flex-direction: column; gap: var(--uix-space-1); max-height: 180px; overflow: auto; }
|
|
909
|
+
.uix-view-menu__cols .uix-menu__item { font-size: var(--uix-text-meta); }
|
|
910
|
+
}
|
|
911
|
+
/* uix list + list-item — depends only on --uix-* tokens. */
|
|
912
|
+
@layer uix.components {
|
|
913
|
+
.uix-list { display: flex; flex-direction: column; border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); overflow: hidden; background: var(--uix-surface); }
|
|
914
|
+
.uix-list__item { display: flex; align-items: center; gap: var(--uix-space-3); padding: var(--uix-space-4) var(--uix-space-5); border-bottom: 1px solid var(--uix-border); }
|
|
915
|
+
.uix-list__item:last-child { border-bottom: 0; }
|
|
916
|
+
.uix-list__item:hover { background: var(--uix-bg-hover); }
|
|
917
|
+
.uix-list__title { font-weight: 500; }
|
|
918
|
+
.uix-list__meta { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
919
|
+
.uix-list__trail { margin-left: auto; display: flex; align-items: center; gap: var(--uix-space-2); }
|
|
920
|
+
}
|
|
921
|
+
/* uix description / key-value list — depends only on --uix-* tokens. */
|
|
922
|
+
@layer uix.components {
|
|
923
|
+
.uix-dl { display: grid; grid-template-columns: max-content 1fr; gap: var(--uix-space-3) var(--uix-space-6); }
|
|
924
|
+
.uix-dl dt { color: var(--uix-text-muted); font-size: var(--uix-text-meta); }
|
|
925
|
+
.uix-dl dd { color: var(--uix-text); font-size: var(--uix-text-body); margin: 0; }
|
|
926
|
+
}
|
|
927
|
+
/* uix avatar / avatar-group / user-chip — depends only on --uix-* tokens. */
|
|
928
|
+
@layer uix.components {
|
|
929
|
+
.uix-avatar {
|
|
930
|
+
width: 32px; height: 32px; flex: none; border-radius: 50%; background: var(--uix-bg-active); color: var(--uix-text);
|
|
931
|
+
display: inline-flex; align-items: center; justify-content: center; font-size: var(--uix-text-meta); font-weight: 600;
|
|
932
|
+
line-height: 1; overflow: hidden; position: relative;
|
|
933
|
+
}
|
|
934
|
+
.uix-avatar img { width: 100%; height: 100%; object-fit: cover; }
|
|
935
|
+
.uix-avatar--sm { width: 24px; height: 24px; font-size: var(--uix-text-eyebrow); }
|
|
936
|
+
.uix-avatar--lg { width: 44px; height: 44px; }
|
|
937
|
+
.uix-avatar__status { position: absolute; right: -1px; bottom: -1px; width: 10px; height: 10px; border-radius: 50%; border: 2px solid var(--uix-surface); background: var(--uix-success); }
|
|
938
|
+
.uix-avatar-group { display: inline-flex; }
|
|
939
|
+
.uix-avatar-group .uix-avatar { box-shadow: 0 0 0 2px var(--uix-surface); margin-left: calc(-1 * var(--uix-space-2)); }
|
|
940
|
+
.uix-avatar-group .uix-avatar:first-child { margin-left: 0; }
|
|
941
|
+
.uix-user-chip { display: inline-flex; align-items: center; gap: var(--uix-space-2); }
|
|
942
|
+
.uix-user-chip__name { font-size: var(--uix-text-body); font-weight: 500; }
|
|
943
|
+
.uix-user-chip__sub { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
944
|
+
|
|
945
|
+
/* editable avatar — hover/focus overlay for "change photo"; empty = upload placeholder */
|
|
946
|
+
.uix-avatar--editable { cursor: pointer; }
|
|
947
|
+
.uix-avatar__edit { position: absolute; inset: 0; display: grid; place-items: center; background: var(--uix-scrim); color: var(--uix-text-reverse); opacity: 0; transition: opacity var(--uix-dur-fast) var(--uix-ease-out); }
|
|
948
|
+
.uix-avatar__edit svg { width: 45%; height: 45%; }
|
|
949
|
+
.uix-avatar--editable:hover .uix-avatar__edit, .uix-avatar--editable:focus-visible .uix-avatar__edit { opacity: 1; }
|
|
950
|
+
.uix-avatar--empty { background: var(--uix-bg-subtle); border: 1.5px dashed var(--uix-border-strong); color: var(--uix-text-muted); }
|
|
951
|
+
}
|
|
952
|
+
/* uix tooltip — CSS hover/focus tooltip via [data-uix-tip]. Depends only on --uix-* tokens. */
|
|
953
|
+
@layer uix.components {
|
|
954
|
+
[data-uix-tip] { position: relative; }
|
|
955
|
+
[data-uix-tip]::after {
|
|
956
|
+
content: attr(data-uix-tip); position: absolute; bottom: calc(100% + 6px); left: 50%;
|
|
957
|
+
transform: translateX(-50%) translateY(var(--uix-lift));
|
|
958
|
+
background: var(--uix-text); color: var(--uix-bg-app); font-size: var(--uix-text-meta); font-weight: 500;
|
|
959
|
+
padding: var(--uix-space-2) var(--uix-space-3); border-radius: var(--uix-radius-sm); white-space: nowrap; box-shadow: var(--uix-shadow-popover);
|
|
960
|
+
opacity: 0; pointer-events: none; z-index: var(--uix-z-tooltip);
|
|
961
|
+
transition: opacity var(--uix-dur-fast) var(--uix-ease-out), transform var(--uix-dur-fast) var(--uix-ease-out);
|
|
962
|
+
}
|
|
963
|
+
[data-uix-tip]:hover::after, [data-uix-tip]:focus-visible::after { opacity: 1; transform: translateX(-50%) translateY(0); }
|
|
964
|
+
}
|
|
965
|
+
/* uix progress bar + ring — depends only on --uix-* tokens. */
|
|
966
|
+
@layer uix.components {
|
|
967
|
+
.uix-progress { height: 8px; background: var(--uix-bg-active); border-radius: var(--uix-radius-pill); overflow: hidden; }
|
|
968
|
+
.uix-progress__bar { height: 100%; background: var(--uix-accent); border-radius: inherit; transition: width var(--uix-dur) var(--uix-ease-out); }
|
|
969
|
+
.uix-progress--indeterminate { position: relative; }
|
|
970
|
+
.uix-progress--indeterminate .uix-progress__bar { width: 40%; animation: uix-progress-slide 1.2s var(--uix-ease-in-out) infinite; }
|
|
971
|
+
@keyframes uix-progress-slide { 0% { transform: translateX(-110%); } 100% { transform: translateX(280%); } }
|
|
972
|
+
|
|
973
|
+
.uix-ring { width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
|
|
974
|
+
background: conic-gradient(var(--uix-accent) calc(var(--val, .66) * 360deg), var(--uix-bg-active) 0); }
|
|
975
|
+
.uix-ring__inner { width: 32px; height: 32px; border-radius: 50%; background: var(--uix-surface); display: grid; place-items: center; font-size: var(--uix-text-meta); font-weight: 600; }
|
|
976
|
+
}
|
|
977
|
+
/* uix meter / utilization bar (threshold tones) — depends only on --uix-* tokens. */
|
|
978
|
+
@layer uix.components {
|
|
979
|
+
.uix-meter { height: 8px; background: var(--uix-bg-active); border-radius: var(--uix-radius-pill); overflow: hidden; }
|
|
980
|
+
.uix-meter__fill { height: 100%; border-radius: inherit; background: var(--uix-success); transition: width var(--uix-dur) var(--uix-ease-out); }
|
|
981
|
+
.uix-meter__fill[data-tone="warning"] { background: var(--uix-warning); }
|
|
982
|
+
.uix-meter__fill[data-tone="danger"] { background: var(--uix-danger); }
|
|
983
|
+
}
|
|
984
|
+
/* uix timeline / activity feed — depends only on --uix-* tokens. */
|
|
985
|
+
@layer uix.components {
|
|
986
|
+
.uix-timeline { display: flex; flex-direction: column; }
|
|
987
|
+
.uix-timeline__item { display: grid; grid-template-columns: 24px 1fr; gap: var(--uix-space-3); }
|
|
988
|
+
.uix-timeline__rail { display: flex; flex-direction: column; align-items: center; }
|
|
989
|
+
.uix-timeline__node { width: 12px; height: 12px; border-radius: 50%; background: var(--uix-accent); margin-top: var(--uix-space-1); flex: none; box-shadow: 0 0 0 3px var(--uix-brand-muted); }
|
|
990
|
+
.uix-timeline__line { width: 1px; flex: 1; background: var(--uix-border); margin: var(--uix-space-1) 0; }
|
|
991
|
+
.uix-timeline__item:last-child .uix-timeline__line { display: none; }
|
|
992
|
+
.uix-timeline__body { padding-bottom: var(--uix-space-5); }
|
|
993
|
+
.uix-timeline__meta { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
994
|
+
}
|
|
995
|
+
/* uix tree view — depends only on --uix-* tokens. */
|
|
996
|
+
@layer uix.components {
|
|
997
|
+
.uix-tree, .uix-tree ul { list-style: none; margin: 0; padding: 0; }
|
|
998
|
+
.uix-tree ul { padding-left: var(--uix-space-5); }
|
|
999
|
+
.uix-tree__row { display: flex; align-items: center; gap: var(--uix-space-2); padding: var(--uix-space-2) var(--uix-space-2); border-radius: var(--uix-radius-sm); cursor: pointer; color: var(--uix-text); font-size: var(--uix-text-body); border: 0; background: transparent; width: 100%; text-align: left; font-family: inherit; }
|
|
1000
|
+
.uix-tree__row:hover { background: var(--uix-bg-hover); }
|
|
1001
|
+
.uix-tree__toggle { width: 16px; height: 16px; flex: none; display: grid; place-items: center; color: var(--uix-text-muted); transition: transform var(--uix-dur) var(--uix-ease-out); }
|
|
1002
|
+
.uix-tree__toggle svg { width: 14px; height: 14px; }
|
|
1003
|
+
.uix-tree__row[aria-expanded="false"] .uix-tree__toggle { transform: rotate(-90deg); }
|
|
1004
|
+
.uix-tree__row[aria-expanded="false"] + ul { display: none; }
|
|
1005
|
+
}
|
|
1006
|
+
/* uix calendar (shared by date pickers) — depends only on --uix-* tokens. */
|
|
1007
|
+
@layer uix.components {
|
|
1008
|
+
.uix-calendar { width: 280px; border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); background: var(--uix-surface); padding: var(--uix-space-3); }
|
|
1009
|
+
.uix-calendar__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--uix-space-2); font-weight: 600; font-size: var(--uix-text-body); }
|
|
1010
|
+
.uix-calendar__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--uix-space-1); }
|
|
1011
|
+
.uix-calendar__dow { text-align: center; font-size: var(--uix-text-eyebrow); color: var(--uix-text-muted); padding: var(--uix-space-1) 0; }
|
|
1012
|
+
.uix-calendar__day { aspect-ratio: 1; display: grid; place-items: center; border-radius: var(--uix-radius-sm); font-size: var(--uix-text-meta); color: var(--uix-text); cursor: pointer; border: 0; background: transparent; }
|
|
1013
|
+
.uix-calendar__day:hover { background: var(--uix-bg-hover); }
|
|
1014
|
+
.uix-calendar__day[data-muted] { color: var(--uix-text-muted); opacity: .45; }
|
|
1015
|
+
.uix-calendar__day[data-today] { box-shadow: inset 0 0 0 1px var(--uix-border-strong); }
|
|
1016
|
+
.uix-calendar__day[data-range] { background: var(--uix-brand-muted); border-radius: 0; }
|
|
1017
|
+
.uix-calendar__day[aria-selected="true"] { background: var(--uix-accent); color: var(--uix-accent-fg); }
|
|
1018
|
+
}
|
|
1019
|
+
/* uix states — empty + skeleton loaders. Depends only on --uix-* tokens. */
|
|
1020
|
+
@layer uix.components {
|
|
1021
|
+
.uix-empty { display: flex; flex-direction: column; align-items: center; gap: var(--uix-space-3); text-align: center; padding: var(--uix-space-8); color: var(--uix-text-muted); }
|
|
1022
|
+
.uix-empty__icon { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 50%; background: var(--uix-bg-subtle); color: var(--uix-text-muted); }
|
|
1023
|
+
.uix-empty__icon svg { width: 22px; height: 22px; }
|
|
1024
|
+
.uix-empty__title { font-size: var(--uix-text-h3); font-weight: 600; color: var(--uix-text); }
|
|
1025
|
+
/* error tone — ErrorState reuses .uix-empty with a danger-toned icon */
|
|
1026
|
+
.uix-empty__icon--danger { background: var(--uix-danger-bg); color: var(--uix-danger); }
|
|
1027
|
+
|
|
1028
|
+
.uix-skeleton { background: linear-gradient(90deg, var(--uix-bg-subtle) 25%, var(--uix-bg-hover) 50%, var(--uix-bg-subtle) 75%); background-size: 200% 100%; animation: uix-shimmer 1.4s linear infinite; border-radius: var(--uix-radius-sm); }
|
|
1029
|
+
.uix-skeleton--text { height: 12px; border-radius: var(--uix-radius-pill); }
|
|
1030
|
+
.uix-skeleton--circle { border-radius: 50%; }
|
|
1031
|
+
}
|
|
1032
|
+
/* uix chart container + legend — palette + framing only; pair sample SVGs / a chart lib using --uix-chart-*. */
|
|
1033
|
+
@layer uix.components {
|
|
1034
|
+
.uix-chart { background: var(--uix-surface); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); padding: var(--uix-space-5); }
|
|
1035
|
+
.uix-chart__title { font-size: var(--uix-text-h3); font-weight: 600; }
|
|
1036
|
+
.uix-chart__subtitle { font-size: var(--uix-text-meta); color: var(--uix-text-muted); margin-bottom: var(--uix-space-4); }
|
|
1037
|
+
.uix-legend { display: flex; flex-wrap: wrap; gap: var(--uix-space-3); margin-top: var(--uix-space-3); }
|
|
1038
|
+
.uix-legend__item { display: inline-flex; align-items: center; gap: var(--uix-space-2); font-size: var(--uix-text-meta); color: var(--uix-text-hushed); }
|
|
1039
|
+
.uix-legend__swatch { width: 10px; height: 10px; border-radius: var(--uix-radius-xs); flex: none; }
|
|
1040
|
+
}
|
|
1041
|
+
/* uix alert / inline banner — tone API. Depends only on --uix-* tokens. */
|
|
1042
|
+
@layer uix.components {
|
|
1043
|
+
.uix-alert {
|
|
1044
|
+
display: flex; gap: var(--uix-space-3); padding: var(--uix-space-3) var(--uix-space-4); border-radius: var(--uix-radius-md);
|
|
1045
|
+
border: 1px solid var(--tone-border, var(--uix-border)); background: var(--tone-bg, var(--uix-bg-subtle));
|
|
1046
|
+
color: var(--uix-text); font-size: var(--uix-text-body);
|
|
1047
|
+
}
|
|
1048
|
+
.uix-alert__icon { color: var(--tone-fg, var(--uix-text)); flex: none; }
|
|
1049
|
+
.uix-alert__icon svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
|
|
1050
|
+
.uix-alert__title { font-weight: 600; margin-bottom: var(--uix-space-1); }
|
|
1051
|
+
.uix-alert__body { font-size: var(--uix-text-meta); color: var(--uix-text-hushed); }
|
|
1052
|
+
.uix-alert--info { --tone-bg: var(--uix-info-bg); --tone-border: color-mix(in srgb, var(--uix-info) 30%, transparent); --tone-fg: var(--uix-info-text); }
|
|
1053
|
+
.uix-alert--success { --tone-bg: var(--uix-success-bg); --tone-border: color-mix(in srgb, var(--uix-success) 30%, transparent); --tone-fg: var(--uix-success); }
|
|
1054
|
+
.uix-alert--warning { --tone-bg: var(--uix-warning-bg); --tone-border: color-mix(in srgb, var(--uix-warning) 40%, transparent); --tone-fg: var(--uix-warning); }
|
|
1055
|
+
.uix-alert--danger { --tone-bg: var(--uix-danger-bg); --tone-border: color-mix(in srgb, var(--uix-danger) 30%, transparent); --tone-fg: var(--uix-danger-text); }
|
|
1056
|
+
}
|
|
1057
|
+
/* uix toast / notification — depends only on --uix-* tokens. JS appends to .uix-toaster. */
|
|
1058
|
+
@layer uix.components {
|
|
1059
|
+
.uix-toaster { position: fixed; bottom: 16px; right: 16px; z-index: var(--uix-z-toast); display: flex; flex-direction: column; gap: var(--uix-space-2); width: 340px; max-width: calc(100vw - 32px); }
|
|
1060
|
+
.uix-toast {
|
|
1061
|
+
display: flex; gap: var(--uix-space-3); align-items: flex-start; padding: var(--uix-space-3) var(--uix-space-4); border-radius: var(--uix-radius-md);
|
|
1062
|
+
background: var(--uix-surface-2); border: 1px solid var(--uix-border); box-shadow: var(--uix-shadow-popover);
|
|
1063
|
+
animation: uix-slide-in-right var(--uix-dur-slow) var(--uix-ease-out);
|
|
1064
|
+
}
|
|
1065
|
+
.uix-toast[data-leaving] { animation: uix-toast-out var(--uix-dur) var(--uix-ease-in) forwards; }
|
|
1066
|
+
@keyframes uix-toast-out { to { opacity: 0; transform: translateX(16px); } }
|
|
1067
|
+
.uix-toast__icon { flex: none; margin-top: 1px; }
|
|
1068
|
+
.uix-toast__icon svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
|
|
1069
|
+
.uix-toast__body { flex: 1; }
|
|
1070
|
+
.uix-toast__title { font-weight: 600; font-size: var(--uix-text-body); }
|
|
1071
|
+
.uix-toast__msg { font-size: var(--uix-text-meta); color: var(--uix-text-muted); margin-top: var(--uix-space-1); }
|
|
1072
|
+
.uix-toast__close { border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; padding: var(--uix-space-1) var(--uix-space-2); border-radius: var(--uix-radius-xs); }
|
|
1073
|
+
.uix-toast__close:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
|
|
1074
|
+
.uix-toast--success .uix-toast__icon { color: var(--uix-success); }
|
|
1075
|
+
.uix-toast--danger .uix-toast__icon { color: var(--uix-danger); }
|
|
1076
|
+
.uix-toast--info .uix-toast__icon { color: var(--uix-info); }
|
|
1077
|
+
}
|
|
1078
|
+
/* uix modal / dialog — native <dialog>, animated enter/exit via @starting-style + allow-discrete. */
|
|
1079
|
+
@layer uix.components {
|
|
1080
|
+
.uix-dialog {
|
|
1081
|
+
margin: auto; width: 100%; max-width: min(520px, 92vw); padding: 0; color: var(--uix-text);
|
|
1082
|
+
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg);
|
|
1083
|
+
background: var(--uix-surface-2); box-shadow: var(--uix-shadow-overlay);
|
|
1084
|
+
opacity: 0; transform: translateY(8px) scale(.98);
|
|
1085
|
+
transition: opacity var(--uix-dur-slow) var(--uix-ease-out), transform var(--uix-dur-slow) var(--uix-ease-out),
|
|
1086
|
+
overlay var(--uix-dur-slow) allow-discrete, display var(--uix-dur-slow) allow-discrete;
|
|
1087
|
+
/* Author display values for both states required for the fade-in to animate: the allow-discrete
|
|
1088
|
+
`display` transition only engages with author values, which also lets @starting-style fire.
|
|
1089
|
+
With only the UA dialog display, the modal stays at opacity:0. Closed = none; open = block. */
|
|
1090
|
+
display: none;
|
|
1091
|
+
}
|
|
1092
|
+
.uix-dialog[open] { opacity: 1; transform: none; display: block; }
|
|
1093
|
+
@starting-style { .uix-dialog[open] { opacity: 0; transform: translateY(8px) scale(.98); } }
|
|
1094
|
+
.uix-dialog::backdrop {
|
|
1095
|
+
background: var(--uix-scrim); opacity: 0;
|
|
1096
|
+
transition: opacity var(--uix-dur-slow) var(--uix-ease-out), overlay var(--uix-dur-slow) allow-discrete, display var(--uix-dur-slow) allow-discrete;
|
|
1097
|
+
}
|
|
1098
|
+
.uix-dialog[open]::backdrop { opacity: 1; }
|
|
1099
|
+
@starting-style { .uix-dialog[open]::backdrop { opacity: 0; } }
|
|
1100
|
+
|
|
1101
|
+
.uix-dialog__header { display: flex; align-items: center; gap: var(--uix-space-3); padding: var(--uix-space-4) var(--uix-space-5); border-bottom: 1px solid var(--uix-border); }
|
|
1102
|
+
.uix-dialog__title { font-size: var(--uix-text-h3); font-weight: 600; }
|
|
1103
|
+
.uix-dialog__close { margin-left: auto; border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; width: 30px; height: 30px; display: grid; place-items: center; border-radius: var(--uix-radius-sm); }
|
|
1104
|
+
.uix-dialog__close:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
|
|
1105
|
+
.uix-dialog__close svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
|
|
1106
|
+
.uix-dialog__body { padding: var(--uix-space-5); color: var(--uix-text-hushed); }
|
|
1107
|
+
.uix-dialog__footer { display: flex; gap: var(--uix-space-2); justify-content: flex-end; padding: var(--uix-space-4) var(--uix-space-5); border-top: 1px solid var(--uix-border); }
|
|
1108
|
+
}
|
|
1109
|
+
/* uix drawer / side sheet — native <dialog> sliding from the right edge. */
|
|
1110
|
+
@layer uix.components {
|
|
1111
|
+
.uix-drawer {
|
|
1112
|
+
margin: 0 0 0 auto; height: 100dvh; max-height: 100dvh; width: min(420px, 100vw); padding: 0; color: var(--uix-text);
|
|
1113
|
+
border: 0; border-left: 1px solid var(--uix-border); border-radius: 0;
|
|
1114
|
+
background: var(--uix-surface); box-shadow: var(--uix-shadow-overlay);
|
|
1115
|
+
transform: translateX(100%);
|
|
1116
|
+
transition: transform var(--uix-dur-slow) var(--uix-ease-out),
|
|
1117
|
+
overlay var(--uix-dur-slow) allow-discrete, display var(--uix-dur-slow) allow-discrete;
|
|
1118
|
+
/* Author display values for both states required for the slide-in (see peek.css). Closed = none. */
|
|
1119
|
+
display: none;
|
|
1120
|
+
}
|
|
1121
|
+
.uix-drawer[open] { transform: none; display: flex; flex-direction: column; }
|
|
1122
|
+
@starting-style { .uix-drawer[open] { transform: translateX(100%); } }
|
|
1123
|
+
.uix-drawer::backdrop {
|
|
1124
|
+
background: var(--uix-scrim); opacity: 0;
|
|
1125
|
+
transition: opacity var(--uix-dur-slow) var(--uix-ease-out), overlay var(--uix-dur-slow) allow-discrete, display var(--uix-dur-slow) allow-discrete;
|
|
1126
|
+
}
|
|
1127
|
+
.uix-drawer[open]::backdrop { opacity: 1; }
|
|
1128
|
+
@starting-style { .uix-drawer[open]::backdrop { opacity: 0; } }
|
|
1129
|
+
.uix-drawer__header { display: flex; align-items: center; gap: var(--uix-space-3); padding: var(--uix-space-4) var(--uix-space-5); border-bottom: 1px solid var(--uix-border); }
|
|
1130
|
+
.uix-drawer__body { padding: var(--uix-space-5); overflow-y: auto; flex: 1; }
|
|
1131
|
+
.uix-drawer__footer { display: flex; gap: var(--uix-space-2); padding: var(--uix-space-4) var(--uix-space-5); border-top: 1px solid var(--uix-border); }
|
|
1132
|
+
}
|
|
1133
|
+
/* uix side-peek drawer (the §5.8 peek pattern, reused by table rows + sidebar items).
|
|
1134
|
+
Native <dialog>, slides from the right; keyboard ↑/↓ navigates records (app.js). */
|
|
1135
|
+
@layer uix.components {
|
|
1136
|
+
.uix-peek {
|
|
1137
|
+
margin: 0 0 0 auto; height: 100dvh; max-height: 100dvh; width: var(--uix-peek-w); padding: 0; color: var(--uix-text);
|
|
1138
|
+
border: 0; border-left: 1px solid var(--uix-border); border-radius: 0;
|
|
1139
|
+
background: var(--uix-surface); box-shadow: var(--uix-shadow-overlay);
|
|
1140
|
+
transform: translateX(100%);
|
|
1141
|
+
transition: transform var(--uix-dur-slow) var(--uix-ease-out),
|
|
1142
|
+
overlay var(--uix-dur-slow) allow-discrete, display var(--uix-dur-slow) allow-discrete;
|
|
1143
|
+
/* Author display values for BOTH states are required for the slide-in to animate: the
|
|
1144
|
+
allow-discrete `display` transition only engages with author values, and that gating also
|
|
1145
|
+
lets the @starting-style entrance fire. With only the UA dialog display, the panel stays
|
|
1146
|
+
parked at translateX(100%). Closed = none; open = flex. */
|
|
1147
|
+
display: none;
|
|
1148
|
+
}
|
|
1149
|
+
.uix-peek[open] { transform: none; display: flex; flex-direction: column; }
|
|
1150
|
+
@starting-style { .uix-peek[open] { transform: translateX(100%); } }
|
|
1151
|
+
.uix-peek::backdrop {
|
|
1152
|
+
background: var(--uix-scrim); opacity: 0;
|
|
1153
|
+
transition: opacity var(--uix-dur-slow) var(--uix-ease-out), overlay var(--uix-dur-slow) allow-discrete, display var(--uix-dur-slow) allow-discrete;
|
|
1154
|
+
}
|
|
1155
|
+
.uix-peek[open]::backdrop { opacity: 1; }
|
|
1156
|
+
@starting-style { .uix-peek[open]::backdrop { opacity: 0; } }
|
|
1157
|
+
|
|
1158
|
+
.uix-peek__header { display: flex; align-items: center; gap: var(--uix-space-3); padding: var(--uix-space-4) var(--uix-space-4); border-bottom: 1px solid var(--uix-border); }
|
|
1159
|
+
.uix-peek__nav { display: inline-flex; gap: var(--uix-space-1); }
|
|
1160
|
+
.uix-peek__navbtn { width: 28px; height: 28px; display: grid; place-items: center; border: 1px solid var(--uix-border); background: var(--uix-surface); color: var(--uix-text); border-radius: var(--uix-radius-sm); cursor: pointer; }
|
|
1161
|
+
.uix-peek__navbtn:hover { background: var(--uix-bg-hover); }
|
|
1162
|
+
.uix-peek__title { font-size: var(--uix-text-h3); font-weight: 600; }
|
|
1163
|
+
.uix-peek__title a { color: var(--uix-link); }
|
|
1164
|
+
.uix-peek__close { margin-left: auto; border: 0; background: transparent; color: var(--uix-text-muted); cursor: pointer; width: 30px; height: 30px; display: grid; place-items: center; border-radius: var(--uix-radius-sm); }
|
|
1165
|
+
.uix-peek__close:hover { background: var(--uix-bg-hover); color: var(--uix-text); }
|
|
1166
|
+
.uix-peek__body { padding: var(--uix-space-5); overflow-y: auto; flex: 1; }
|
|
1167
|
+
.uix-peek__hint { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
1168
|
+
.uix-peek__footer { display: flex; gap: var(--uix-space-2); padding: var(--uix-space-4) var(--uix-space-4); border-top: 1px solid var(--uix-border); }
|
|
1169
|
+
|
|
1170
|
+
/* a table wired to open the peek (app.js sets data-uix-rowpeek): its rows read as clickable,
|
|
1171
|
+
since clicking a ticket row is the queue's primary way to open the side-peek. */
|
|
1172
|
+
[data-uix-rowpeek] tbody tr { cursor: pointer; }
|
|
1173
|
+
[data-uix-rowpeek] tbody tr:hover td { background: var(--uix-bg-hover); }
|
|
1174
|
+
|
|
1175
|
+
/* Pattern B table layout: columns keep natural width, no squeezing or wrapping.
|
|
1176
|
+
Subject is the only column that may truncate (it can be long). */
|
|
1177
|
+
[data-uix-table-v2] .uix-table td { white-space: nowrap; }
|
|
1178
|
+
[data-uix-table-v2] .uix-table td:nth-child(2) { max-width: 280px; overflow: hidden; text-overflow: ellipsis; }
|
|
1179
|
+
|
|
1180
|
+
/* ID cell in pattern B table: ID text + ↗ arrow, single button, quiet/on-brand at rest.
|
|
1181
|
+
Monospace so IDs align vertically. Arrow fades in on row hover. */
|
|
1182
|
+
.uix-id-cell__btn {
|
|
1183
|
+
border: 0; background: transparent; cursor: pointer; padding: 0;
|
|
1184
|
+
color: var(--uix-text); font: inherit;
|
|
1185
|
+
display: inline-flex; align-items: center; gap: var(--uix-space-1); white-space: nowrap;
|
|
1186
|
+
}
|
|
1187
|
+
.uix-id-cell__btn:hover { color: var(--uix-accent); }
|
|
1188
|
+
.uix-id-cell__btn:focus-visible { outline: 2px solid var(--uix-ring); outline-offset: 2px; border-radius: var(--uix-radius-xs); }
|
|
1189
|
+
.uix-id-cell__arrow {
|
|
1190
|
+
width: var(--uix-icon-sm); height: var(--uix-icon-sm); flex-shrink: 0; color: var(--uix-text-muted);
|
|
1191
|
+
opacity: 0;
|
|
1192
|
+
transition: opacity var(--uix-dur-fast) var(--uix-ease-out);
|
|
1193
|
+
}
|
|
1194
|
+
[data-uix-rowpeek] tbody tr:hover .uix-id-cell__arrow { opacity: 1; }
|
|
1195
|
+
@media (prefers-reduced-motion: reduce) { .uix-id-cell__arrow { transition: none; } }
|
|
1196
|
+
}
|
|
1197
|
+
/* uix popover — generic anchored surface via the native Popover API; animated with @starting-style. */
|
|
1198
|
+
@layer uix.components {
|
|
1199
|
+
.uix-popover { margin: 0; padding: var(--uix-space-2); background: var(--uix-surface-2); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); box-shadow: var(--uix-shadow-popover); color: var(--uix-text); }
|
|
1200
|
+
[popover].uix-popover {
|
|
1201
|
+
opacity: 0; transform: translateY(calc(-1 * var(--uix-lift)));
|
|
1202
|
+
transition: opacity var(--uix-dur-fast) var(--uix-ease-out), transform var(--uix-dur-fast) var(--uix-ease-out),
|
|
1203
|
+
overlay var(--uix-dur-fast) allow-discrete, display var(--uix-dur-fast) allow-discrete;
|
|
1204
|
+
}
|
|
1205
|
+
[popover].uix-popover:popover-open { opacity: 1; transform: none; }
|
|
1206
|
+
@starting-style { [popover].uix-popover:popover-open { opacity: 0; transform: translateY(calc(-1 * var(--uix-lift))); } }
|
|
1207
|
+
}
|
|
1208
|
+
/* uix spinner + progress overlay — depends only on --uix-* tokens. */
|
|
1209
|
+
@layer uix.components {
|
|
1210
|
+
.uix-spinner { width: 20px; height: 20px; border: 2px solid var(--uix-border-strong); border-right-color: transparent; border-radius: 50%; display: inline-block; animation: uix-spin .6s linear infinite; }
|
|
1211
|
+
.uix-spinner--accent { border-color: var(--uix-accent); border-right-color: transparent; }
|
|
1212
|
+
.uix-spinner--lg { width: 32px; height: 32px; border-width: 3px; }
|
|
1213
|
+
.uix-overlay-progress {
|
|
1214
|
+
position: absolute; inset: 0; display: grid; place-items: center; border-radius: inherit;
|
|
1215
|
+
background: color-mix(in srgb, var(--uix-bg-app) 60%, transparent); backdrop-filter: blur(2px);
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
/* uix detail layout — two-column record (main + side meta). Depends only on --uix-* tokens. */
|
|
1219
|
+
@layer uix.components {
|
|
1220
|
+
.uix-detail { display: grid; grid-template-columns: 1fr 280px; gap: var(--uix-space-5); align-items: start; }
|
|
1221
|
+
.uix-detail__main { min-width: 0; display: flex; flex-direction: column; gap: var(--uix-space-4); }
|
|
1222
|
+
.uix-detail__side { display: flex; flex-direction: column; gap: var(--uix-space-4); }
|
|
1223
|
+
@media (max-width: 820px) { .uix-detail { grid-template-columns: 1fr; } }
|
|
1224
|
+
}
|
|
1225
|
+
/* uix comments thread + composer (@mention) — depends only on --uix-* tokens. */
|
|
1226
|
+
@layer uix.components {
|
|
1227
|
+
.uix-comments { display: flex; flex-direction: column; gap: var(--uix-space-4); }
|
|
1228
|
+
.uix-comment { display: grid; grid-template-columns: 32px 1fr; gap: var(--uix-space-3); }
|
|
1229
|
+
.uix-comment__body { background: var(--uix-bg-subtle); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); padding: var(--uix-space-3) var(--uix-space-3); }
|
|
1230
|
+
.uix-comment__meta { font-size: var(--uix-text-meta); color: var(--uix-text-muted); margin-bottom: var(--uix-space-1); }
|
|
1231
|
+
.uix-comment__author { font-weight: 600; color: var(--uix-text); }
|
|
1232
|
+
.uix-mention { color: var(--uix-link); background: var(--uix-brand-muted); padding: 0 var(--uix-space-1); border-radius: var(--uix-radius-xs); font-weight: 500; }
|
|
1233
|
+
.uix-composer { border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); background: var(--uix-surface); }
|
|
1234
|
+
.uix-composer:focus-within { border-color: var(--uix-ring); box-shadow: 0 0 0 3px var(--uix-brand-muted); }
|
|
1235
|
+
.uix-composer textarea { width: 100%; border: 0; background: transparent; resize: vertical; padding: var(--uix-space-3) var(--uix-space-3); color: var(--uix-text); font: inherit; min-height: 60px; }
|
|
1236
|
+
.uix-composer textarea:focus { outline: none; }
|
|
1237
|
+
.uix-composer__bar { display: flex; justify-content: flex-end; gap: var(--uix-space-2); padding: var(--uix-space-2); border-top: 1px solid var(--uix-border); }
|
|
1238
|
+
/* Block so the thumbnail drops onto its own line below the comment text (not inline with it). */
|
|
1239
|
+
.uix-comment__image { display: block; margin-top: var(--uix-space-2); padding: 0; border-radius: var(--uix-radius-sm); overflow: hidden; border: 1px solid var(--uix-border); background: none; cursor: zoom-in; max-width: 200px; }
|
|
1240
|
+
.uix-comment__image img { display: block; width: 100%; height: auto; }
|
|
1241
|
+
}
|
|
1242
|
+
/* uix emoji reactions — pills with counts + an add-reaction picker popover. Depends only on --uix-* tokens. */
|
|
1243
|
+
@layer uix.components {
|
|
1244
|
+
.uix-reactions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--uix-space-2); margin-top: var(--uix-space-2); }
|
|
1245
|
+
.uix-reaction {
|
|
1246
|
+
display: inline-flex; align-items: center; gap: var(--uix-space-2); padding: 1px var(--uix-space-2); line-height: 1.7;
|
|
1247
|
+
border-radius: var(--uix-radius-pill); border: 1px solid var(--uix-border); background: var(--uix-surface);
|
|
1248
|
+
color: var(--uix-text-hushed); font: inherit; font-size: var(--uix-text-meta); cursor: pointer;
|
|
1249
|
+
}
|
|
1250
|
+
.uix-reaction:hover { border-color: var(--uix-border-strong); }
|
|
1251
|
+
.uix-reaction[data-mine] { background: var(--uix-brand-muted); border-color: var(--uix-accent); color: var(--uix-accent); }
|
|
1252
|
+
.uix-reaction__count { font-variant-numeric: tabular-nums; }
|
|
1253
|
+
.uix-reaction-add {
|
|
1254
|
+
display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 24px;
|
|
1255
|
+
border-radius: var(--uix-radius-pill); border: 1px dashed var(--uix-border-strong); background: transparent;
|
|
1256
|
+
color: var(--uix-text-muted); cursor: pointer;
|
|
1257
|
+
}
|
|
1258
|
+
.uix-reaction-add:hover { color: var(--uix-text); border-color: var(--uix-text-muted); }
|
|
1259
|
+
.uix-reaction-add svg { width: var(--uix-icon-sm); height: var(--uix-icon-sm); }
|
|
1260
|
+
.uix-emoji-picker { display: flex; flex-wrap: wrap; gap: var(--uix-space-1); width: 196px; }
|
|
1261
|
+
.uix-emoji-picker__btn { font-size: 18px; line-height: 1; padding: var(--uix-space-2); border: 0; background: transparent; border-radius: var(--uix-radius-sm); cursor: pointer; }
|
|
1262
|
+
.uix-emoji-picker__btn:hover { background: var(--uix-bg-hover); }
|
|
1263
|
+
}
|
|
1264
|
+
/* uix media / device-asset card — image (or icon placeholder) + name + meta. Depends only on --uix-* tokens. */
|
|
1265
|
+
@layer uix.components {
|
|
1266
|
+
.uix-media { display: flex; gap: var(--uix-space-3); align-items: center; }
|
|
1267
|
+
.uix-media__thumb { width: 64px; height: 64px; flex: none; border-radius: var(--uix-radius-md); overflow: hidden; background: var(--uix-bg-subtle); border: 1px solid var(--uix-border); display: grid; place-items: center; }
|
|
1268
|
+
.uix-media__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
1269
|
+
.uix-media__thumb svg { width: 28px; height: 28px; color: var(--uix-text-muted); }
|
|
1270
|
+
.uix-media__name { font-weight: 600; }
|
|
1271
|
+
.uix-media__meta { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
1272
|
+
}
|
|
1273
|
+
/* uix image lightbox — native <dialog>, click a thumbnail to enlarge. Depends only on --uix-* tokens. */
|
|
1274
|
+
@layer uix.components {
|
|
1275
|
+
/* margin:auto centers the modal <dialog> in the viewport — required because base.css
|
|
1276
|
+
resets `* { margin: 0 }`, which zeroes the UA dialog's own margin:auto (it would otherwise
|
|
1277
|
+
pin to the top-left). Matches .uix-dialog. */
|
|
1278
|
+
.uix-lightbox { margin: auto; border: 0; background: transparent; padding: 0; max-width: 92vw; max-height: 92vh; box-shadow: var(--uix-shadow-overlay); overflow: visible; }
|
|
1279
|
+
/* A definite width is required: an SVG with a viewBox but no intrinsic width/height collapses to
|
|
1280
|
+
0×0 under width:auto, which then shrink-wraps the fit-content <dialog> to nothing (nothing shows
|
|
1281
|
+
on open). min() keeps it within the viewport; height:auto preserves the aspect ratio. */
|
|
1282
|
+
.uix-lightbox img { display: block; width: min(720px, 92vw); height: auto; max-height: 92vh; border-radius: var(--uix-radius-md); }
|
|
1283
|
+
.uix-lightbox::backdrop { background: var(--uix-scrim-strong); }
|
|
1284
|
+
}
|
|
1285
|
+
/* uix prose content card + note callouts — for KB articles, descriptions, release notes. Depends only on --uix-* tokens. */
|
|
1286
|
+
@layer uix.components {
|
|
1287
|
+
.uix-prose { max-width: 66ch; color: var(--uix-text); }
|
|
1288
|
+
.uix-prose > * + * { margin-top: var(--uix-space-3); }
|
|
1289
|
+
.uix-prose h3 { font-size: var(--uix-text-h2); font-weight: 600; }
|
|
1290
|
+
.uix-prose h4 { font-size: var(--uix-text-h3); font-weight: 600; margin-top: var(--uix-space-5); }
|
|
1291
|
+
.uix-prose p { line-height: var(--uix-leading-body); color: var(--uix-text-hushed); }
|
|
1292
|
+
.uix-prose a { color: var(--uix-link); }
|
|
1293
|
+
.uix-prose ul, .uix-prose ol { padding-left: var(--uix-space-5); }
|
|
1294
|
+
.uix-prose li + li { margin-top: var(--uix-space-1); }
|
|
1295
|
+
.uix-prose code { font-family: var(--uix-font-mono); font-size: .9em; background: var(--uix-bg-subtle); padding: 1px var(--uix-space-2); border-radius: var(--uix-radius-xs); }
|
|
1296
|
+
.uix-prose blockquote { border-left: 3px solid var(--uix-border-strong); padding-left: var(--uix-space-3); color: var(--uix-text-muted); }
|
|
1297
|
+
|
|
1298
|
+
.uix-note { display: flex; gap: var(--uix-space-3); padding: var(--uix-space-3) var(--uix-space-4); border-radius: var(--uix-radius-md); border: 1px solid var(--uix-border); background: var(--uix-surface); }
|
|
1299
|
+
.uix-note__icon { flex: none; }
|
|
1300
|
+
.uix-note__icon svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
|
|
1301
|
+
.uix-note__body { font-size: var(--uix-text-body); color: var(--uix-text); }
|
|
1302
|
+
.uix-note__body > * + * { margin-top: var(--uix-space-2); }
|
|
1303
|
+
.uix-note--info { background: var(--uix-info-bg); border-color: color-mix(in srgb, var(--uix-info) 30%, transparent); }
|
|
1304
|
+
.uix-note--info .uix-note__icon { color: var(--uix-info); }
|
|
1305
|
+
.uix-note--success { background: var(--uix-success-bg); border-color: color-mix(in srgb, var(--uix-success) 30%, transparent); }
|
|
1306
|
+
.uix-note--success .uix-note__icon { color: var(--uix-success); }
|
|
1307
|
+
.uix-note--warning { background: var(--uix-warning-bg); border-color: color-mix(in srgb, var(--uix-warning) 30%, transparent); }
|
|
1308
|
+
.uix-note--warning .uix-note__icon { color: var(--uix-warning); }
|
|
1309
|
+
.uix-note--danger { background: var(--uix-danger-bg); border-color: color-mix(in srgb, var(--uix-danger) 30%, transparent); }
|
|
1310
|
+
.uix-note--danger .uix-note__icon { color: var(--uix-danger); }
|
|
1311
|
+
}
|
|
1312
|
+
/* uix kanban board / column — depends only on --uix-* tokens. */
|
|
1313
|
+
@layer uix.components {
|
|
1314
|
+
.uix-kanban { display: flex; gap: var(--uix-space-4); overflow-x: auto; padding-bottom: var(--uix-space-2); }
|
|
1315
|
+
.uix-kanban__col { flex: 0 0 260px; background: var(--uix-bg-subtle); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); display: flex; flex-direction: column; max-height: 460px; }
|
|
1316
|
+
.uix-kanban__head { display: flex; align-items: center; gap: var(--uix-space-2); padding: var(--uix-space-3) var(--uix-space-4); font-weight: 600; font-size: var(--uix-text-meta); }
|
|
1317
|
+
.uix-kanban__count { margin-left: auto; color: var(--uix-text-muted); font-weight: 500; }
|
|
1318
|
+
.uix-kanban__body { padding: 0 var(--uix-space-3) var(--uix-space-3); display: flex; flex-direction: column; gap: var(--uix-space-2); overflow-y: auto; }
|
|
1319
|
+
.uix-kanban__card { background: var(--uix-surface); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); padding: var(--uix-space-3); box-shadow: var(--uix-shadow-sm); cursor: grab; transition: box-shadow var(--uix-dur-fast) var(--uix-ease-out), transform var(--uix-dur-fast) var(--uix-ease-out); }
|
|
1320
|
+
.uix-kanban__card:hover { box-shadow: var(--uix-shadow-popover); }
|
|
1321
|
+
@media (hover: hover) and (pointer: fine) { .uix-kanban__card:hover { transform: translateY(calc(-1 * var(--uix-lift))); } }
|
|
1322
|
+
.uix-kanban__card:active { cursor: grabbing; }
|
|
1323
|
+
.uix-kanban__card-title { font-weight: 500; font-size: var(--uix-text-body); margin-bottom: var(--uix-space-2); }
|
|
1324
|
+
.uix-kanban__card-meta { display: flex; align-items: center; gap: var(--uix-space-2); }
|
|
1325
|
+
}
|
|
1326
|
+
/* uix inbox master-detail — depends only on --uix-* tokens. */
|
|
1327
|
+
@layer uix.components {
|
|
1328
|
+
.uix-inbox { display: grid; grid-template-columns: 300px 1fr; border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); overflow: hidden; height: 420px; }
|
|
1329
|
+
.uix-inbox__list { border-right: 1px solid var(--uix-border); overflow-y: auto; background: var(--uix-surface); }
|
|
1330
|
+
.uix-inbox__item { position: relative; display: flex; flex-direction: column; gap: var(--uix-space-1); padding: var(--uix-space-3) var(--uix-space-4); border-bottom: 1px solid var(--uix-border); cursor: pointer; }
|
|
1331
|
+
.uix-inbox__item:hover { background: var(--uix-bg-hover); }
|
|
1332
|
+
.uix-inbox__item[aria-selected="true"] { background: linear-gradient(to right, var(--uix-accent) 3px, var(--uix-brand-muted) 3px); }
|
|
1333
|
+
.uix-inbox__item[data-unread] .uix-inbox__subject { font-weight: 600; }
|
|
1334
|
+
.uix-inbox__subject { font-size: var(--uix-text-body); }
|
|
1335
|
+
.uix-inbox__preview { font-size: var(--uix-text-meta); color: var(--uix-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1336
|
+
.uix-inbox__detail { overflow-y: auto; padding: var(--uix-space-5); background: var(--uix-bg-app); }
|
|
1337
|
+
@media (max-width: 700px) { .uix-inbox { grid-template-columns: 1fr; } .uix-inbox__detail { display: none; } }
|
|
1338
|
+
}
|
|
1339
|
+
/* uix notification center — depends only on --uix-* tokens. */
|
|
1340
|
+
@layer uix.components {
|
|
1341
|
+
.uix-notifs { background: var(--uix-surface-2); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg); overflow: hidden; }
|
|
1342
|
+
.uix-notifs__head { display: flex; align-items: center; padding: var(--uix-space-3) var(--uix-space-4); border-bottom: 1px solid var(--uix-border); font-weight: 600; }
|
|
1343
|
+
.uix-notif { display: grid; grid-template-columns: auto 1fr; gap: var(--uix-space-3); padding: var(--uix-space-3) var(--uix-space-4); border-bottom: 1px solid var(--uix-border); }
|
|
1344
|
+
.uix-notif:last-child { border-bottom: 0; }
|
|
1345
|
+
.uix-notif[data-unread] { background: var(--uix-brand-muted); }
|
|
1346
|
+
.uix-notif__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--uix-accent); margin-top: var(--uix-space-2); }
|
|
1347
|
+
.uix-notif[data-unread] .uix-notif__dot { background: var(--uix-accent); }
|
|
1348
|
+
.uix-notif:not([data-unread]) .uix-notif__dot { background: transparent; }
|
|
1349
|
+
.uix-notif__meta { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
1350
|
+
/* on the unread brand-muted tint, muted meta dips below AA — hushed composites darker on the tint */
|
|
1351
|
+
.uix-notif[data-unread] .uix-notif__meta { color: var(--uix-text-hushed); }
|
|
1352
|
+
}
|
|
1353
|
+
/* uix label / tag taxonomy — colored via --label-color (set to a --uix-chart-* token). */
|
|
1354
|
+
@layer uix.components {
|
|
1355
|
+
.uix-label {
|
|
1356
|
+
display: inline-flex; align-items: center; gap: var(--uix-space-2); padding: 1px var(--uix-space-2); border-radius: var(--uix-radius-sm);
|
|
1357
|
+
font-size: var(--uix-text-meta); font-weight: 500;
|
|
1358
|
+
background: color-mix(in srgb, var(--label-color, var(--uix-accent)) 16%, transparent);
|
|
1359
|
+
/* Pull the hue toward the theme foreground so the text clears WCAG AA on its own 16% tint.
|
|
1360
|
+
Raw chart hues (esp. amber #F59E0B at 1.9:1) are tuned for fills, not text-on-tint; the dot
|
|
1361
|
+
keeps the full hue. --uix-text flips per theme, so this darkens on light and lightens on dark. */
|
|
1362
|
+
color: color-mix(in srgb, var(--label-color, var(--uix-accent)) 55%, var(--uix-text));
|
|
1363
|
+
}
|
|
1364
|
+
.uix-label__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--label-color, var(--uix-accent)); }
|
|
1365
|
+
}
|
|
1366
|
+
/* uix attachment list — depends only on --uix-* tokens. */
|
|
1367
|
+
@layer uix.components {
|
|
1368
|
+
.uix-attachments { display: flex; flex-direction: column; gap: var(--uix-space-2); }
|
|
1369
|
+
.uix-attachment { display: flex; align-items: center; gap: var(--uix-space-3); padding: var(--uix-space-2) var(--uix-space-3); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); background: var(--uix-surface); }
|
|
1370
|
+
.uix-attachment__icon { width: 32px; height: 32px; flex: none; border-radius: var(--uix-radius-sm); background: var(--uix-bg-subtle); display: grid; place-items: center; color: var(--uix-text-muted); }
|
|
1371
|
+
.uix-attachment__icon svg { width: var(--uix-icon-md); height: var(--uix-icon-md); }
|
|
1372
|
+
.uix-attachment__name { font-size: var(--uix-text-body); }
|
|
1373
|
+
.uix-attachment__size { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
1374
|
+
.uix-attachment__actions { margin-left: auto; }
|
|
1375
|
+
}
|
|
1376
|
+
/* uix deal / pipeline stage bar — depends only on --uix-* tokens. */
|
|
1377
|
+
@layer uix.components {
|
|
1378
|
+
.uix-pipeline { display: flex; gap: var(--uix-space-1); }
|
|
1379
|
+
.uix-pipeline__stage { flex: 1; text-align: center; padding: var(--uix-space-2) var(--uix-space-2); font-size: var(--uix-text-meta); color: var(--uix-text-muted); background: var(--uix-bg-subtle); }
|
|
1380
|
+
.uix-pipeline__stage:first-child { border-radius: var(--uix-radius-pill) 0 0 var(--uix-radius-pill); }
|
|
1381
|
+
.uix-pipeline__stage:last-child { border-radius: 0 var(--uix-radius-pill) var(--uix-radius-pill) 0; }
|
|
1382
|
+
.uix-pipeline__stage[data-state="done"] { background: var(--uix-accent); color: var(--uix-accent-fg); }
|
|
1383
|
+
.uix-pipeline__stage[data-state="active"] { background: var(--uix-brand-muted); color: var(--uix-link); font-weight: 600; }
|
|
1384
|
+
}
|
|
1385
|
+
/* uix flow — workflow & pipeline diagrams: boxed nodes + connectors.
|
|
1386
|
+
Depends only on --uix-* tokens. Edges are decorative inline SVG (aria-hidden);
|
|
1387
|
+
straight runs use pure-CSS connectors. Node state follows the tone-API pattern
|
|
1388
|
+
(see status-pill.css): state --modifiers set only --tone-* vars, the base reads them. */
|
|
1389
|
+
@layer uix.components {
|
|
1390
|
+
|
|
1391
|
+
/* ============================================================ node */
|
|
1392
|
+
.uix-node {
|
|
1393
|
+
position: relative;
|
|
1394
|
+
display: inline-grid; grid-template-columns: auto 1fr; align-items: center;
|
|
1395
|
+
gap: var(--uix-space-3); min-width: 132px; width: max-content; max-width: 220px; padding: var(--uix-space-3) var(--uix-space-3);
|
|
1396
|
+
background: var(--uix-surface);
|
|
1397
|
+
border: 1px solid var(--tone-border, var(--uix-border-strong));
|
|
1398
|
+
border-radius: var(--uix-radius-md);
|
|
1399
|
+
box-shadow: var(--uix-shadow-sm);
|
|
1400
|
+
color: var(--uix-text); font-size: var(--uix-text-body); text-align: left;
|
|
1401
|
+
}
|
|
1402
|
+
.uix-node__icon {
|
|
1403
|
+
display: grid; place-items: center; width: 30px; height: 30px; flex: none;
|
|
1404
|
+
border-radius: var(--uix-radius-sm);
|
|
1405
|
+
background: var(--tone-bg, var(--uix-bg-subtle));
|
|
1406
|
+
color: var(--tone-fg, var(--uix-text-muted));
|
|
1407
|
+
}
|
|
1408
|
+
.uix-node__icon svg { width: var(--uix-icon-sm); height: var(--uix-icon-sm); }
|
|
1409
|
+
.uix-node__body { min-width: 0; }
|
|
1410
|
+
.uix-node__title { font-weight: 500; line-height: 1.25; }
|
|
1411
|
+
.uix-node__meta { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
1412
|
+
.uix-node__status {
|
|
1413
|
+
display: inline-flex; align-items: center; gap: var(--uix-space-2); margin-top: var(--uix-space-1);
|
|
1414
|
+
font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow);
|
|
1415
|
+
text-transform: uppercase; color: var(--tone-fg, var(--uix-text-muted));
|
|
1416
|
+
}
|
|
1417
|
+
.uix-node__status::before {
|
|
1418
|
+
content: ""; width: 7px; height: 7px; flex: none; border-radius: 50%;
|
|
1419
|
+
background: var(--tone-dot, var(--uix-text-muted));
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
/* connection handles — decorative connection-point affordance */
|
|
1423
|
+
.uix-node__handle {
|
|
1424
|
+
position: absolute; top: 50%; width: 9px; height: 9px; border-radius: 50%;
|
|
1425
|
+
background: var(--uix-surface); border: 1.5px solid var(--uix-border-strong);
|
|
1426
|
+
transform: translateY(-50%);
|
|
1427
|
+
}
|
|
1428
|
+
.uix-node__handle--in { left: -5px; }
|
|
1429
|
+
.uix-node__handle--out { right: -5px; }
|
|
1430
|
+
|
|
1431
|
+
/* ---- state modifiers: set tone vars only ---- */
|
|
1432
|
+
.uix-node--pending { --tone-bg: var(--uix-bg-subtle); --tone-fg: var(--uix-text-muted); --tone-dot: var(--uix-text-muted); --tone-border: var(--uix-border); }
|
|
1433
|
+
.uix-node--active { --tone-bg: var(--uix-brand-muted); --tone-fg: var(--uix-link); --tone-dot: var(--uix-accent); --tone-border: var(--uix-accent); }
|
|
1434
|
+
.uix-node--running { --tone-bg: var(--uix-info-bg); --tone-fg: var(--uix-info-text); --tone-dot: var(--uix-info); --tone-border: var(--uix-info); }
|
|
1435
|
+
.uix-node--done { --tone-bg: var(--uix-success-bg); --tone-fg: var(--uix-success); --tone-dot: var(--uix-success); --tone-border: var(--uix-success); }
|
|
1436
|
+
.uix-node--error { --tone-bg: var(--uix-danger-bg); --tone-fg: var(--uix-danger-text); --tone-dot: var(--uix-danger); --tone-border: var(--uix-danger); }
|
|
1437
|
+
/* active/running read as "current" via a soft halo in their own tone */
|
|
1438
|
+
.uix-node--active, .uix-node--running { box-shadow: var(--uix-shadow-sm), 0 0 0 3px var(--tone-bg); }
|
|
1439
|
+
|
|
1440
|
+
/* running node spins its icon */
|
|
1441
|
+
.uix-node--running .uix-node__icon svg { animation: uix-flow-spin 1s linear infinite; }
|
|
1442
|
+
|
|
1443
|
+
/* ---- decision / diamond ---- */
|
|
1444
|
+
.uix-node--decision {
|
|
1445
|
+
min-width: 0; width: 112px; height: 112px; padding: 0; overflow: visible;
|
|
1446
|
+
/* reset the base node's `auto 1fr` columns to one full-width track, else the lone title is
|
|
1447
|
+
trapped in the left `auto` column and place-items:center can't center it over the diamond. */
|
|
1448
|
+
display: grid; grid-template-columns: 1fr; place-items: center; background: transparent; border: 0; box-shadow: none;
|
|
1449
|
+
}
|
|
1450
|
+
.uix-node--decision::before {
|
|
1451
|
+
content: ""; position: absolute; left: 50%; top: 50%; width: 78px; height: 78px;
|
|
1452
|
+
transform: translate(-50%, -50%) rotate(45deg);
|
|
1453
|
+
background: var(--tone-bg, var(--uix-surface));
|
|
1454
|
+
border: 1px solid var(--tone-border, var(--uix-border-strong));
|
|
1455
|
+
border-radius: var(--uix-radius-sm); box-shadow: var(--uix-shadow-sm);
|
|
1456
|
+
}
|
|
1457
|
+
.uix-node--decision .uix-node__title {
|
|
1458
|
+
position: relative; z-index: var(--uix-z-raised); max-width: 88px; text-align: center;
|
|
1459
|
+
font-size: var(--uix-text-meta); color: var(--tone-fg, var(--uix-text));
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
/* ---- start / end terminals (pills) ---- */
|
|
1463
|
+
.uix-node--start, .uix-node--end {
|
|
1464
|
+
grid-template-columns: 1fr; min-width: 0; justify-items: center;
|
|
1465
|
+
padding: var(--uix-space-2) var(--uix-space-5); border-radius: var(--uix-radius-pill);
|
|
1466
|
+
background: var(--uix-bg-active); color: var(--uix-text-hushed); font-weight: 500;
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
/* ============================================================ flow + edges */
|
|
1470
|
+
.uix-flow {
|
|
1471
|
+
position: relative; width: 100%;
|
|
1472
|
+
color: var(--uix-border-strong); /* edges inherit via currentColor */
|
|
1473
|
+
}
|
|
1474
|
+
.uix-flow__edges {
|
|
1475
|
+
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
1476
|
+
overflow: visible; pointer-events: none; /* never block node hover/focus */
|
|
1477
|
+
}
|
|
1478
|
+
.uix-flow__edge { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
|
|
1479
|
+
.uix-flow__edge--branch-yes { stroke: var(--uix-success); }
|
|
1480
|
+
.uix-flow__edge--branch-no { stroke: var(--uix-danger); }
|
|
1481
|
+
.uix-flow__edge--loop { stroke: var(--uix-accent); stroke-dasharray: 5 4; }
|
|
1482
|
+
.uix-flow__arrow { fill: currentColor; }
|
|
1483
|
+
.uix-flow__edge-label { fill: var(--uix-text-muted); font-family: var(--uix-font-sans); font-size: var(--uix-text-eyebrow); }
|
|
1484
|
+
.uix-flow__edge-label--loop { fill: var(--uix-accent); }
|
|
1485
|
+
|
|
1486
|
+
/* hovering/focusing a diagram sets its edges "flowing" (marching dashes) to read direction */
|
|
1487
|
+
@media (hover: hover) and (pointer: fine) {
|
|
1488
|
+
.uix-flow:hover .uix-flow__edge,
|
|
1489
|
+
.uix-flow:focus-within .uix-flow__edge {
|
|
1490
|
+
stroke-dasharray: 5 4; animation: uix-flow-march var(--uix-dur-slow) linear infinite;
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
/* ---- linear: flex row of nodes + pure-CSS connectors (no SVG) ---- */
|
|
1495
|
+
.uix-flow--linear .uix-flow__row { display: flex; align-items: center; flex-wrap: wrap; gap: var(--uix-space-1); }
|
|
1496
|
+
.uix-flow__connector {
|
|
1497
|
+
position: relative; flex: 1 1 30px; min-width: 30px; height: 0;
|
|
1498
|
+
border-top: 1.5px solid var(--uix-border-strong); margin: 0 var(--uix-space-1);
|
|
1499
|
+
}
|
|
1500
|
+
.uix-flow__connector::after {
|
|
1501
|
+
content: ""; position: absolute; right: -1px; top: 50%; width: 6px; height: 6px;
|
|
1502
|
+
border-top: 1.5px solid var(--uix-border-strong); border-right: 1.5px solid var(--uix-border-strong);
|
|
1503
|
+
transform: translate(0, -50%) rotate(45deg);
|
|
1504
|
+
}
|
|
1505
|
+
.uix-flow__connector[data-done] { border-color: var(--uix-success); }
|
|
1506
|
+
.uix-flow__connector[data-done]::after { border-color: var(--uix-success); }
|
|
1507
|
+
|
|
1508
|
+
/* ---- branch / loop / mindmap: absolutely-positioned nodes over an SVG edge layer.
|
|
1509
|
+
Container aspect-ratio matches each SVG viewBox so % node positions and path
|
|
1510
|
+
coordinates scale together (uniform), keeping edges glued to nodes at any width. */
|
|
1511
|
+
.uix-flow--branch, .uix-flow--loop { aspect-ratio: 5 / 2; }
|
|
1512
|
+
.uix-flow--mindmap { aspect-ratio: 2 / 1; }
|
|
1513
|
+
.uix-flow--branch .uix-node,
|
|
1514
|
+
.uix-flow--loop .uix-node,
|
|
1515
|
+
.uix-flow--mindmap .uix-node,
|
|
1516
|
+
.uix-flow--canvas .uix-node { position: absolute; transform: translate(-50%, -50%); }
|
|
1517
|
+
|
|
1518
|
+
/* mindmap leaves sit tighter than default nodes */
|
|
1519
|
+
.uix-flow--mindmap .uix-node { min-width: 0; }
|
|
1520
|
+
.uix-flow--mindmap .uix-node--hub { min-width: 120px; }
|
|
1521
|
+
|
|
1522
|
+
/* ============================================================ builder canvas */
|
|
1523
|
+
.uix-flow--canvas {
|
|
1524
|
+
display: grid; grid-template-columns: 188px 1fr;
|
|
1525
|
+
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-lg);
|
|
1526
|
+
overflow: hidden; background: var(--uix-surface); width: 100%;
|
|
1527
|
+
}
|
|
1528
|
+
.uix-flow__palette {
|
|
1529
|
+
display: flex; flex-direction: column; gap: var(--uix-space-2); padding: var(--uix-space-4);
|
|
1530
|
+
border-right: 1px solid var(--uix-border); background: var(--uix-surface);
|
|
1531
|
+
}
|
|
1532
|
+
.uix-flow__palette-title {
|
|
1533
|
+
font-size: var(--uix-text-eyebrow); letter-spacing: var(--uix-tracking-eyebrow);
|
|
1534
|
+
text-transform: uppercase; color: var(--uix-text-muted); margin-bottom: var(--uix-space-1);
|
|
1535
|
+
}
|
|
1536
|
+
.uix-flow__chip {
|
|
1537
|
+
display: flex; align-items: center; gap: var(--uix-space-2); padding: var(--uix-space-2) var(--uix-space-3);
|
|
1538
|
+
border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md);
|
|
1539
|
+
background: var(--uix-surface); color: var(--uix-text);
|
|
1540
|
+
font-size: var(--uix-text-meta); cursor: grab; box-shadow: var(--uix-shadow-sm);
|
|
1541
|
+
transition: box-shadow var(--uix-dur-fast) var(--uix-ease-out),
|
|
1542
|
+
transform var(--uix-dur-fast) var(--uix-ease-out);
|
|
1543
|
+
}
|
|
1544
|
+
.uix-flow__chip svg { width: var(--uix-icon-sm); height: var(--uix-icon-sm); color: var(--uix-text-muted); flex: none; }
|
|
1545
|
+
.uix-flow__chip:active { cursor: grabbing; }
|
|
1546
|
+
@media (hover: hover) and (pointer: fine) {
|
|
1547
|
+
.uix-flow__chip:hover { box-shadow: var(--uix-shadow-popover); transform: translateY(calc(-1 * var(--uix-lift))); }
|
|
1548
|
+
}
|
|
1549
|
+
/* the canvas: a dotted grid, free-placed nodes, one SVG edge layer */
|
|
1550
|
+
.uix-flow__canvas {
|
|
1551
|
+
position: relative; aspect-ratio: 16 / 9; min-height: 280px;
|
|
1552
|
+
background-color: var(--uix-bg-subtle);
|
|
1553
|
+
background-image: radial-gradient(var(--uix-border-strong) 1px, transparent 1px);
|
|
1554
|
+
background-size: 22px 22px; background-position: -1px -1px;
|
|
1555
|
+
}
|
|
1556
|
+
.uix-flow--canvas .uix-node { cursor: grab; }
|
|
1557
|
+
.uix-flow--canvas .uix-node:active { cursor: grabbing; }
|
|
1558
|
+
|
|
1559
|
+
/* selected node ring — mirrors the focus-ring construction (double box-shadow on --uix-ring) */
|
|
1560
|
+
.uix-flow .uix-node[data-selected] {
|
|
1561
|
+
border-color: var(--uix-ring);
|
|
1562
|
+
box-shadow: 0 0 0 2px var(--uix-surface), 0 0 0 4px var(--uix-ring);
|
|
1563
|
+
}
|
|
1564
|
+
/* keyboard/click selection on focusable canvas pieces — no JS needed */
|
|
1565
|
+
.uix-flow__chip:focus-visible,
|
|
1566
|
+
.uix-flow--canvas .uix-node:focus-visible {
|
|
1567
|
+
outline: none; border-color: var(--uix-ring);
|
|
1568
|
+
box-shadow: 0 0 0 2px var(--uix-surface), 0 0 0 4px var(--uix-ring);
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
/* ============================================================ motion */
|
|
1572
|
+
@keyframes uix-flow-spin { to { transform: rotate(360deg); } }
|
|
1573
|
+
@keyframes uix-flow-march { to { stroke-dashoffset: -18; } }
|
|
1574
|
+
|
|
1575
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1576
|
+
.uix-node--running .uix-node__icon svg,
|
|
1577
|
+
.uix-flow:hover .uix-flow__edge,
|
|
1578
|
+
.uix-flow:focus-within .uix-flow__edge { animation: none; }
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
/* uix audit-log entry — depends only on --uix-* tokens. */
|
|
1582
|
+
@layer uix.components {
|
|
1583
|
+
.uix-audit { display: flex; flex-direction: column; }
|
|
1584
|
+
.uix-audit__row { display: grid; grid-template-columns: auto 1fr auto; gap: var(--uix-space-3); align-items: center; padding: var(--uix-space-3) 0; border-bottom: 1px solid var(--uix-border); font-size: var(--uix-text-meta); }
|
|
1585
|
+
.uix-audit__row:last-child { border-bottom: 0; }
|
|
1586
|
+
.uix-audit__actor { font-weight: 500; color: var(--uix-text); }
|
|
1587
|
+
.uix-audit__detail { color: var(--uix-text-hushed); }
|
|
1588
|
+
.uix-audit__detail ins { background: var(--uix-success-bg); color: var(--uix-success); text-decoration: none; padding: 0 var(--uix-space-1); border-radius: var(--uix-radius-xs); }
|
|
1589
|
+
.uix-audit__detail del { background: var(--uix-danger-bg); color: var(--uix-danger-text); text-decoration: line-through; padding: 0 var(--uix-space-1); border-radius: var(--uix-radius-xs); }
|
|
1590
|
+
.uix-audit__time { color: var(--uix-text-muted); white-space: nowrap; }
|
|
1591
|
+
}
|
|
1592
|
+
/* uix contact / customer card (CRM) — depends only on --uix-* tokens. */
|
|
1593
|
+
@layer uix.components {
|
|
1594
|
+
.uix-contact { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--uix-space-1); padding: var(--uix-space-5); }
|
|
1595
|
+
.uix-contact__name { font-size: var(--uix-text-h3); font-weight: 600; margin-top: var(--uix-space-2); }
|
|
1596
|
+
.uix-contact__role { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
1597
|
+
.uix-contact__actions { display: flex; gap: var(--uix-space-2); margin-top: var(--uix-space-3); align-self: stretch; }
|
|
1598
|
+
.uix-contact__actions > .uix-btn { flex: 1; }
|
|
1599
|
+
.uix-contact__stats { display: flex; gap: var(--uix-space-5); margin-top: var(--uix-space-4); }
|
|
1600
|
+
.uix-contact__stat { text-align: center; }
|
|
1601
|
+
.uix-contact__stat b { display: block; font-size: var(--uix-text-h3); }
|
|
1602
|
+
.uix-contact__stat span { font-size: var(--uix-text-meta); color: var(--uix-text-muted); }
|
|
1603
|
+
}
|
|
1604
|
+
/* uix SLA indicator / timer (breach states) — depends only on --uix-* tokens. */
|
|
1605
|
+
@layer uix.components {
|
|
1606
|
+
.uix-sla { display: inline-flex; align-items: center; gap: var(--uix-space-2); font-size: var(--uix-text-meta); font-weight: 500; color: var(--uix-text-hushed); }
|
|
1607
|
+
.uix-sla svg { width: 14px; height: 14px; }
|
|
1608
|
+
.uix-sla[data-state="ok"] { color: var(--uix-success); }
|
|
1609
|
+
.uix-sla[data-state="at-risk"] { color: var(--uix-warning-text); }
|
|
1610
|
+
.uix-sla[data-state="breach"] { color: var(--uix-danger-text); }
|
|
1611
|
+
}
|
|
1612
|
+
/* uix utility/typography bits — code, pre, blockquote, divider, status dots. Depends only on --uix-* tokens. */
|
|
1613
|
+
@layer uix.components {
|
|
1614
|
+
.uix-code { font-family: var(--uix-font-mono); font-size: .9em; background: var(--uix-bg-subtle); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-xs); padding: .1em .4em; color: var(--uix-text); }
|
|
1615
|
+
.uix-pre { font-family: var(--uix-font-mono); font-size: var(--uix-text-meta); line-height: 1.5; background: var(--uix-bg-subtle); border: 1px solid var(--uix-border); border-radius: var(--uix-radius-md); padding: var(--uix-space-4) var(--uix-space-4); overflow-x: auto; color: var(--uix-text); }
|
|
1616
|
+
.uix-blockquote { border-left: 3px solid var(--uix-accent); padding: var(--uix-space-1) 0 var(--uix-space-1) var(--uix-space-4); color: var(--uix-text-hushed); font-style: italic; }
|
|
1617
|
+
.uix-divider { height: 1px; background: var(--uix-border); border: 0; margin: var(--uix-space-4) 0; }
|
|
1618
|
+
.uix-divider--label { display: flex; align-items: center; gap: var(--uix-space-3); color: var(--uix-text-muted); font-size: var(--uix-text-meta); background: transparent; height: auto; }
|
|
1619
|
+
.uix-divider--label::before, .uix-divider--label::after { content: ""; flex: 1; height: 1px; background: var(--uix-border); }
|
|
1620
|
+
.uix-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--uix-text-muted); }
|
|
1621
|
+
.uix-dot--success { background: var(--uix-success); }
|
|
1622
|
+
.uix-dot--warning { background: var(--uix-warning); }
|
|
1623
|
+
.uix-dot--danger { background: var(--uix-danger); }
|
|
1624
|
+
.uix-dot--info { background: var(--uix-info); }
|
|
1625
|
+
}
|
|
1626
|
+
/* uix heartbeat / live status indicator — a pulsing ping. Respects reduced-motion (guard stops the ping). */
|
|
1627
|
+
@layer uix.components {
|
|
1628
|
+
.uix-heartbeat { position: relative; display: inline-grid; place-items: center; width: 8px; height: 8px; flex: none; }
|
|
1629
|
+
.uix-heartbeat__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--uix-success); z-index: var(--uix-z-raised); }
|
|
1630
|
+
.uix-heartbeat__ping { position: absolute; inset: 0; border-radius: 50%; background: var(--uix-success); animation: uix-ping 1.6s var(--uix-ease-out) infinite; }
|
|
1631
|
+
@keyframes uix-ping { 0% { transform: scale(1); opacity: .55; } 100% { transform: scale(2.8); opacity: 0; } }
|
|
1632
|
+
.uix-heartbeat--warning .uix-heartbeat__dot, .uix-heartbeat--warning .uix-heartbeat__ping { background: var(--uix-warning); }
|
|
1633
|
+
.uix-heartbeat--danger .uix-heartbeat__dot, .uix-heartbeat--danger .uix-heartbeat__ping { background: var(--uix-danger); }
|
|
1634
|
+
.uix-heartbeat--idle .uix-heartbeat__dot { background: var(--uix-text-muted); }
|
|
1635
|
+
.uix-heartbeat--idle .uix-heartbeat__ping { display: none; }
|
|
1636
|
+
.uix-live { display: inline-flex; align-items: center; gap: var(--uix-space-2); font-size: var(--uix-text-meta); font-weight: 500; color: var(--uix-text-hushed); }
|
|
1637
|
+
}
|