@godxjp/ui 0.2.0 → 2.1.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.
@@ -0,0 +1,765 @@
1
+ /* ============================================================================
2
+ * dxs-kintai — Design tokens
3
+ *
4
+ * Extracted from admin-web/src/app/globals.css (the inlined Omnify UI theme).
5
+ * Source-of-truth for design tools and HTML mockups in this project.
6
+ *
7
+ * Design philosophy
8
+ * 渋み (shibumi) — restrained elegance. Primary chroma ≤ 0.18 in OKLCH.
9
+ * 間 (ma) — vertical breathing room. Body line-height 1.7.
10
+ * 簡素 (kanso) — three weights only (400 / 500 / 700).
11
+ * ========================================================================= */
12
+
13
+ @import url("https://fonts.googleapis.com/css2?family=M+PLUS+2:wght@300;400;500;600;700&display=swap");
14
+
15
+ :root {
16
+ /* ── Type ──────────────────────────────────────────────────────────── */
17
+
18
+ --font-sans-jp:
19
+ "M PLUS 2", "Hiragino Sans", "ヒラギノ角ゴシック", "Hiragino Kaku Gothic ProN",
20
+ "Yu Gothic Medium", "游ゴシック Medium", YuGothic, "Noto Sans JP", Meiryo, メイリオ,
21
+ -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
22
+
23
+ --font-weight-normal: 400; /* body */
24
+ --font-weight-medium: 500; /* heading default — freee vibes */
25
+ --font-weight-semibold: 600; /* legacy alias, prefer 700 */
26
+ --font-weight-bold: 700; /* emphasis only */
27
+
28
+ --text-2xs: 0.6875rem; /* 11px — fine print */
29
+ --text-xs: 0.75rem; /* 12px — caption / label */
30
+ --text-sm: 0.8125rem; /* 13px — dense table */
31
+ --text-base:0.875rem; /* 14px — DEFAULT body (JP density override) */
32
+ --text-md: 1rem; /* 16px — content-heavy body */
33
+ --text-lg: 1.125rem; /* 18px — subheading */
34
+ --text-xl: 1.25rem; /* 20px — h3 / page title */
35
+ --text-2xl: 1.5rem; /* 24px — h2 */
36
+ --text-3xl: 1.875rem; /* 30px */
37
+ --text-4xl: 2rem; /* 32px — h1 cap */
38
+
39
+ --leading-none: 1;
40
+ --leading-tight: 1.25; /* headings */
41
+ --leading-normal: 1.5; /* dense / single-line UI */
42
+ --leading-body: 1.7; /* JP body default — 間 (ma) principle */
43
+ --leading-relaxed: 1.625;
44
+ --leading-loose: 2;
45
+
46
+ /* Semantic heading sizes (intentionally small — info-dense JP enterprise) */
47
+ --heading-h1: var(--text-xl); /* 20px */
48
+ --heading-h2: var(--text-lg); /* 18px */
49
+ --heading-h3: var(--text-base); /* 14px */
50
+ --heading-h4: var(--text-sm); /* 13px */
51
+
52
+ /* ── Color — Phase B (OKLCH, 渋み) ────────────────────────────────── */
53
+
54
+ --background: oklch(99% 0.002 60); /* warm off-white */
55
+ --foreground: oklch(20% 0.006 60); /* warm off-black — SmartHR TEXT_BLACK #23221e */
56
+ --card: oklch(99% 0.002 60);
57
+ --card-foreground: oklch(20% 0.006 60);
58
+ --popover: oklch(99% 0.002 60);
59
+ --popover-foreground:oklch(20% 0.006 60);
60
+
61
+ --primary: oklch(56% 0.15 240); /* SmartHR MAIN #0077c7 */
62
+ --primary-foreground:oklch(99% 0.002 60);
63
+
64
+ --secondary: oklch(96% 0.004 60);
65
+ --secondary-foreground: oklch(20% 0.006 60);
66
+ --muted: oklch(96% 0.004 60);
67
+ --muted-foreground: oklch(48% 0.008 60); /* SmartHR TEXT_GREY #706d65 */
68
+ --accent: oklch(93% 0.005 60);
69
+ --accent-foreground: oklch(20% 0.006 60);
70
+
71
+ --destructive: oklch(52% 0.18 25); /* 茜 #b7282e (chroma capped) */
72
+ --destructive-foreground: oklch(99% 0.002 60);
73
+
74
+ --border: oklch(86% 0.006 60); /* SmartHR BORDER #d6d3d0 */
75
+ --input: oklch(86% 0.006 60);
76
+ --input-background: oklch(99% 0.002 60);
77
+ --ring: oklch(56% 0.15 240);
78
+
79
+ /* Semantic — 和色 (traditional Japanese) hue centers */
80
+ --success: oklch(72% 0.13 155); /* 若竹 #68be8d */
81
+ --success-foreground:oklch(99% 0.002 60);
82
+ --warning: oklch(80% 0.17 85); /* 山吹 #f8b500 */
83
+ --warning-foreground:oklch(20% 0.006 60);
84
+ --info: oklch(55% 0.12 265); /* 群青 #4c6cb3 */
85
+ --info-foreground: oklch(99% 0.002 60);
86
+ --error: oklch(52% 0.18 25); /* 茜 #b7282e */
87
+ --error-foreground: oklch(99% 0.002 60);
88
+ --attention: oklch(66% 0.19 45); /* 朱 #eb6101 — softer than red */
89
+ --attention-foreground: oklch(99% 0.002 60);
90
+
91
+ /* 和色 (wa-iro) decorative palette — accents, charts, tags. NEVER role-mapped. */
92
+ --wa-ai: #165e83; /* 藍 indigo (info dark) */
93
+ --wa-gunjo: #4c6cb3; /* 群青 ultramarine (info) */
94
+ --wa-ruri: #1e50a2; /* 瑠璃 lapis (primary saturated) */
95
+ --wa-kon: #223a70; /* 紺 navy (text emphasis) */
96
+ --wa-wakatake: #68be8d; /* 若竹 young bamboo (success) */
97
+ --wa-moegi: #006e54; /* 萌葱 spring green (success dark) */
98
+ --wa-yamabuki: #f8b500; /* 山吹 mountain yellow (warning) */
99
+ --wa-shu: #eb6101; /* 朱 vermilion (attention) */
100
+ --wa-akane: #b7282e; /* 茜 madder (danger) */
101
+ --wa-enji: #b94047; /* 臙脂 cochineal */
102
+ --wa-sakura: #fef4f4; /* 桜 cherry (soft info bg) */
103
+ --wa-sumi: #595857; /* 墨 ink (warm text) */
104
+ --wa-nezu: #949495; /* 鼠 mouse-grey (muted text) */
105
+
106
+ --gray-50: #f9fafb; --gray-100:#f3f4f6; --gray-200:#e5e7eb;
107
+ --gray-300:#d1d5db; --gray-400:#9ca3af; --gray-500:#6b7280;
108
+ --gray-600:#4b5563; --gray-700:#374151; --gray-800:#1f2937;
109
+ --gray-900:#111827;
110
+
111
+ --blue-50:#eff6ff; --blue-100:#dbeafe; --blue-500:#3b82f6;
112
+ --blue-600:#2563eb; --blue-700:#1d4ed8;
113
+
114
+ /* ── Spacing (4px grid) ──────────────────────────────────────────── */
115
+ --spacing-0: 0; --spacing-1: 0.25rem; --spacing-2: 0.5rem;
116
+ --spacing-3: 0.75rem; --spacing-4: 1rem; --spacing-5: 1.25rem;
117
+ --spacing-6: 1.5rem; --spacing-8: 2rem; --spacing-10:2.5rem;
118
+ --spacing-12:3rem; --spacing-16:4rem; --spacing-20:5rem;
119
+ --spacing-24:6rem;
120
+
121
+ /* ── Density (default mode) ──────────────────────────────────────── */
122
+ --density-element-xs: 1.5rem; /* 24px */
123
+ --density-element-sm: 1.75rem; /* 28px */
124
+ --density-element: 2rem; /* 32px — default */
125
+ --density-element-lg: 2.25rem; /* 36px */
126
+ --density-element-xl: 2.75rem; /* 44px — login forms / WCAG floor */
127
+ --density-card: 1rem;
128
+ --density-dialog: 1.25rem;
129
+ --density-page: 1rem;
130
+ --density-section: 1rem;
131
+ --density-page-title: 1.25rem;
132
+ --density-table-head: 2rem;
133
+ --touch-target-min: 44px; /* Digital Agency hard rule */
134
+
135
+ /* ── Layout ──────────────────────────────────────────────────────── */
136
+ --header-height: 3rem; /* 48px */
137
+ --sidebar-width: 16rem; /* 256px */
138
+ --sidebar-collapsed-width: 4rem; /* 64px */
139
+ --sidebar-transition: 300ms;
140
+ --content-sidebar-width: 20rem;
141
+ --container-max-width: 1280px;
142
+
143
+ /* ── Radius / border ─────────────────────────────────────────────── */
144
+ --radius: 0.375rem; /* 6px — base */
145
+ --radius-sm: calc(var(--radius) - 4px);
146
+ --radius-md: calc(var(--radius) - 2px);
147
+ --radius-lg: var(--radius);
148
+ --radius-xl: calc(var(--radius) + 4px);
149
+ --radius-full: 9999px;
150
+ --border-width: 1px;
151
+
152
+ /* ── Shadow ──────────────────────────────────────────────────────── */
153
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / .05);
154
+ --shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);
155
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);
156
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);
157
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);
158
+ --shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / .25);
159
+ --shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / .05);
160
+
161
+ /* ── Motion ──────────────────────────────────────────────────────── */
162
+ --transition-fast: 150ms;
163
+ --transition-base: 200ms;
164
+ --transition-slow: 300ms;
165
+ --transition-slower: 500ms;
166
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
167
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
168
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
169
+
170
+ /* ── Aspect ratios (decorative — never for type scale) ──────────── */
171
+ --aspect-silver: 1.4142; /* 白銀比 (hakuginhi) — A4, manga */
172
+ --aspect-golden: 1.618; /* 黄金比 — Western */
173
+ }
174
+
175
+ /* Tenant override — Betoya (Vietnamese restaurant) */
176
+ [data-tenant="betoya"] {
177
+ --primary: oklch(58% 0.159 150); /* Vietnam green #009444 */
178
+ --primary-foreground: oklch(99% 0.002 60);
179
+ --ring: oklch(58% 0.159 150);
180
+ --foreground: oklch(20% 0.004 85);
181
+ --brand-betoya-primary: #009444;
182
+ --brand-betoya-secondary:#ffc20e;
183
+ --brand-betoya-accent: #00b856;
184
+ --brand-betoya-attention:#f95c39;
185
+ --brand-betoya-text: #171614;
186
+ }
187
+
188
+ /* Density override — compact (kintone-style data tables) */
189
+ [data-density="compact"] {
190
+ --density-element-xs: 1.25rem;
191
+ --density-element-sm: 1.5rem;
192
+ --density-element: 1.75rem; /* 28px */
193
+ --density-element-lg: 2rem;
194
+ --density-element-xl: 2.25rem;
195
+ --density-card: 0.75rem;
196
+ --density-dialog: 1rem;
197
+ --density-page: 0.75rem;
198
+ --density-section: 0.75rem;
199
+ --header-height: 2.5rem;
200
+ --density-table-head: 1.75rem;
201
+ }
202
+
203
+ /* Density override — comfortable (public surfaces, 44px touch floor) */
204
+ [data-density="comfortable"] {
205
+ --density-element-xs: 2rem;
206
+ --density-element-sm: 2.25rem;
207
+ --density-element: 2.75rem; /* 44px */
208
+ --density-element-lg: 3rem;
209
+ --density-element-xl: 3.5rem;
210
+ --density-card: 1.5rem;
211
+ --density-dialog: 2rem;
212
+ --density-page: 1.5rem;
213
+ --density-section: 1.5rem;
214
+ --header-height: 3.5rem;
215
+ --density-table-head: 2.5rem;
216
+ }
217
+
218
+ /* ── Base element styles (mirrors @layer base in globals.css) ─────── */
219
+ html { font-size: 16px; }
220
+ body {
221
+ font-family: var(--font-sans-jp);
222
+ font-size: var(--text-base);
223
+ line-height: var(--leading-body);
224
+ color: var(--foreground);
225
+ background: var(--background);
226
+ -webkit-font-smoothing: antialiased;
227
+ text-rendering: optimizeLegibility;
228
+ }
229
+ h1 { font-size: var(--heading-h1); font-weight: var(--font-weight-medium); line-height: var(--leading-tight); }
230
+ h2 { font-size: var(--heading-h2); font-weight: var(--font-weight-medium); line-height: var(--leading-tight); }
231
+ h3 { font-size: var(--heading-h3); font-weight: var(--font-weight-medium); line-height: var(--leading-tight); }
232
+ h4 { font-size: var(--heading-h4); font-weight: var(--font-weight-medium); line-height: var(--leading-tight); }
233
+ label { font-size: var(--text-base); font-weight: var(--font-weight-medium); line-height: var(--leading-normal); }
234
+ button { font-size: var(--text-base); font-weight: var(--font-weight-medium); line-height: var(--leading-normal); }
235
+ input { font-size: var(--text-base); font-weight: var(--font-weight-normal); line-height: var(--leading-normal); }
236
+ /* ============================================================================
237
+ * Famgia / godx — Unified Design System extensions
238
+ * Builds on tokens.css (dxs-kintai) + adds:
239
+ * - Dark mode
240
+ * - 4 tenant presets (godx, betoya, kintai, tempo)
241
+ * - Sidebar variables, status dots, focus rings
242
+ * - Utility classes used across the prototype
243
+ * ========================================================================= */
244
+
245
+ :root {
246
+ /* Layout extensions */
247
+ --sidebar-bg: oklch(98% 0.003 60);
248
+ --sidebar-border: var(--border);
249
+ --sidebar-fg: var(--foreground);
250
+ --sidebar-muted: var(--muted-foreground);
251
+ --sidebar-active-bg: oklch(95% 0.02 240);
252
+ --sidebar-active-fg: var(--primary);
253
+ --topbar-bg: var(--background);
254
+ --topbar-border: var(--border);
255
+
256
+ --surface-1: oklch(99% 0.002 60); /* card, popover */
257
+ --surface-2: oklch(97% 0.003 60); /* page bg subtle */
258
+ --surface-3: oklch(95% 0.004 60); /* hover, accent */
259
+ --surface-inset: oklch(96% 0.004 60);
260
+
261
+ --kbd-bg: oklch(94% 0.005 60);
262
+
263
+ /* Status dot tokens — use as bg-color */
264
+ --dot-success: var(--success);
265
+ --dot-warning: var(--warning);
266
+ --dot-error: var(--error);
267
+ --dot-info: var(--info);
268
+ --dot-attention: var(--attention);
269
+ --dot-muted: var(--muted-foreground);
270
+ }
271
+
272
+ [data-tenant="godx"] {
273
+ /* Default: Famgia emerald accent (--brand) + SmartHR blue primary */
274
+ --primary: oklch(56% 0.15 240);
275
+ --primary-foreground: oklch(99% 0.002 60);
276
+ --ring: oklch(56% 0.15 240);
277
+ --brand: oklch(60% 0.137 163);
278
+ }
279
+
280
+ [data-tenant="kintai"] {
281
+ --primary: oklch(56% 0.15 240); /* SmartHR blue */
282
+ --primary-foreground: oklch(99% 0.002 60);
283
+ --ring: oklch(56% 0.15 240);
284
+ --brand: oklch(56% 0.15 240);
285
+ }
286
+
287
+ [data-tenant="tempo"] {
288
+ --primary: oklch(48% 0.16 285); /* deeper indigo for Tempo */
289
+ --primary-foreground: oklch(99% 0.002 60);
290
+ --ring: oklch(48% 0.16 285);
291
+ --brand: oklch(48% 0.16 285);
292
+ }
293
+
294
+ [data-tenant="betoya"] {
295
+ --primary: oklch(58% 0.159 150);
296
+ --primary-foreground: oklch(99% 0.002 60);
297
+ --ring: oklch(58% 0.159 150);
298
+ --brand: oklch(58% 0.159 150);
299
+ }
300
+
301
+ /* Dark mode */
302
+ [data-theme="dark"] {
303
+ --background: oklch(18% 0.005 60);
304
+ --foreground: oklch(95% 0.005 60);
305
+ --card: oklch(22% 0.005 60);
306
+ --card-foreground: oklch(95% 0.005 60);
307
+ --popover: oklch(24% 0.005 60);
308
+ --popover-foreground: oklch(95% 0.005 60);
309
+ --secondary: oklch(26% 0.006 60);
310
+ --secondary-foreground: oklch(95% 0.005 60);
311
+ --muted: oklch(26% 0.006 60);
312
+ --muted-foreground: oklch(68% 0.008 60);
313
+ --accent: oklch(30% 0.008 60);
314
+ --accent-foreground: oklch(95% 0.005 60);
315
+ --border: oklch(32% 0.008 60);
316
+ --input: oklch(32% 0.008 60);
317
+ --input-background: oklch(24% 0.005 60);
318
+
319
+ --sidebar-bg: oklch(20% 0.005 60);
320
+ --sidebar-border: oklch(28% 0.006 60);
321
+ --sidebar-fg: oklch(92% 0.005 60);
322
+ --sidebar-muted: oklch(64% 0.008 60);
323
+ --sidebar-active-bg: oklch(28% 0.04 240);
324
+ --sidebar-active-fg: oklch(78% 0.13 240);
325
+ --topbar-bg: oklch(20% 0.005 60);
326
+ --topbar-border: oklch(28% 0.006 60);
327
+
328
+ --surface-1: oklch(22% 0.005 60);
329
+ --surface-2: oklch(20% 0.005 60);
330
+ --surface-3: oklch(28% 0.008 60);
331
+ --surface-inset: oklch(24% 0.006 60);
332
+
333
+ --kbd-bg: oklch(28% 0.008 60);
334
+
335
+ --primary: oklch(70% 0.13 240);
336
+ --primary-foreground: oklch(18% 0.005 60);
337
+ --ring: oklch(70% 0.13 240);
338
+ }
339
+
340
+ [data-theme="dark"][data-tenant="kintai"] { --primary: oklch(70% 0.13 240); --ring: oklch(70% 0.13 240); --brand: oklch(70% 0.13 240); }
341
+ [data-theme="dark"][data-tenant="tempo"] { --primary: oklch(70% 0.14 285); --ring: oklch(70% 0.14 285); --brand: oklch(70% 0.14 285); }
342
+ [data-theme="dark"][data-tenant="betoya"] { --primary: oklch(72% 0.14 150); --ring: oklch(72% 0.14 150); --brand: oklch(72% 0.14 150); }
343
+ [data-theme="dark"][data-tenant="godx"] { --primary: oklch(70% 0.13 240); --ring: oklch(70% 0.13 240); --brand: oklch(72% 0.13 163); }
344
+
345
+ /* ── Globals ──────────────────────────────────────────────────────── */
346
+ * { box-sizing: border-box; }
347
+ html, body { margin: 0; padding: 0; }
348
+ body {
349
+ font-family: var(--font-sans-jp);
350
+ font-size: var(--text-base);
351
+ line-height: var(--leading-body);
352
+ color: var(--foreground);
353
+ background: var(--background);
354
+ -webkit-font-smoothing: antialiased;
355
+ text-rendering: optimizeLegibility;
356
+ font-feature-settings: "palt";
357
+ }
358
+
359
+ button { font-family: inherit; cursor: pointer; }
360
+ input, textarea, select { font-family: inherit; color: inherit; }
361
+ ::selection { background: color-mix(in oklch, var(--primary) 30%, transparent); }
362
+
363
+ /* Scrollbar */
364
+ ::-webkit-scrollbar { width: 10px; height: 10px; }
365
+ ::-webkit-scrollbar-thumb { background: color-mix(in oklch, var(--muted-foreground) 30%, transparent); border-radius: 99px; border: 2px solid transparent; background-clip: padding-box; }
366
+ ::-webkit-scrollbar-thumb:hover { background: color-mix(in oklch, var(--muted-foreground) 50%, transparent); border: 2px solid transparent; background-clip: padding-box; }
367
+ ::-webkit-scrollbar-track { background: transparent; }
368
+
369
+ /* ── App shell ────────────────────────────────────────────────────── */
370
+ .app-root {
371
+ display: grid;
372
+ grid-template-columns: var(--sidebar-width) 1fr;
373
+ grid-template-rows: var(--header-height) 1fr;
374
+ grid-template-areas: "sidebar topbar" "sidebar main";
375
+ height: 100vh;
376
+ background: var(--surface-2);
377
+ transition: grid-template-columns var(--sidebar-transition) var(--ease-in-out);
378
+ }
379
+ .app-root[data-collapsed="true"] { grid-template-columns: var(--sidebar-collapsed-width) 1fr; }
380
+
381
+ .app-sidebar { grid-area: sidebar; background: var(--sidebar-bg); border-right: 1px solid var(--sidebar-border); display: flex; flex-direction: column; overflow: hidden; }
382
+ .app-topbar { grid-area: topbar; background: var(--topbar-bg); border-bottom: 1px solid var(--topbar-border); display: flex; align-items: center; padding: 0 var(--spacing-4); gap: var(--spacing-3); }
383
+ .app-main { grid-area: main; overflow: auto; }
384
+
385
+ /* Sidebar */
386
+ .sb-product { display: flex; align-items: center; gap: var(--spacing-2); height: var(--header-height); padding: 0 var(--spacing-4); border-bottom: 1px solid var(--sidebar-border); flex-shrink: 0; cursor: pointer; user-select: none; }
387
+ .sb-product:hover { background: var(--surface-3); }
388
+ .sb-logo-mark { width: 24px; height: 24px; border-radius: 6px; background: var(--brand); color: var(--primary-foreground); display: grid; place-items: center; font-weight: 700; font-size: 12px; flex-shrink: 0; }
389
+ .sb-product-name { font-weight: 500; font-size: var(--text-sm); white-space: nowrap; overflow: hidden; }
390
+ .sb-product-tenant { font-size: var(--text-2xs); color: var(--sidebar-muted); white-space: nowrap; }
391
+
392
+ .sb-section { padding: var(--spacing-3) var(--spacing-2); }
393
+ .sb-section + .sb-section { border-top: 1px solid var(--sidebar-border); }
394
+ .sb-section-label { font-size: var(--text-2xs); color: var(--sidebar-muted); text-transform: uppercase; letter-spacing: 0.06em; padding: 0 var(--spacing-2) var(--spacing-1); white-space: nowrap; overflow: hidden; }
395
+ .sb-nav { display: flex; flex-direction: column; gap: 1px; }
396
+ .sb-nav-item { display: flex; align-items: center; gap: var(--spacing-2); height: var(--density-element-sm); padding: 0 var(--spacing-2); border-radius: var(--radius-md); color: var(--sidebar-fg); font-size: var(--text-sm); cursor: pointer; user-select: none; white-space: nowrap; overflow: hidden; }
397
+ .sb-nav-item:hover { background: var(--surface-3); }
398
+ .sb-nav-item[data-active="true"] { background: var(--sidebar-active-bg); color: var(--sidebar-active-fg); font-weight: 500; }
399
+ .sb-nav-item .sb-icon { flex-shrink: 0; width: 16px; height: 16px; display: grid; place-items: center; }
400
+ .sb-nav-item .sb-label { flex: 1; overflow: hidden; text-overflow: ellipsis; }
401
+ .sb-nav-item .sb-badge { background: var(--surface-3); color: var(--muted-foreground); font-size: var(--text-2xs); padding: 1px 6px; border-radius: var(--radius-full); }
402
+ .sb-nav-item[data-active="true"] .sb-badge { background: color-mix(in oklch, var(--primary) 18%, transparent); color: var(--primary); }
403
+
404
+ .app-root[data-collapsed="true"] .sb-product-name,
405
+ .app-root[data-collapsed="true"] .sb-product-tenant,
406
+ .app-root[data-collapsed="true"] .sb-section-label,
407
+ .app-root[data-collapsed="true"] .sb-label,
408
+ .app-root[data-collapsed="true"] .sb-badge { display: none; }
409
+ .app-root[data-collapsed="true"] .sb-nav-item { justify-content: center; padding: 0; width: var(--density-element-sm); margin: 0 auto; }
410
+ .app-root[data-collapsed="true"] .sb-product { padding: 0; justify-content: center; }
411
+
412
+ .sb-footer { margin-top: auto; border-top: 1px solid var(--sidebar-border); padding: var(--spacing-3) var(--spacing-2); }
413
+
414
+ /* Topbar */
415
+ .tb-breadcrumb { display: flex; align-items: center; gap: var(--spacing-1); font-size: var(--text-sm); color: var(--muted-foreground); flex: 1; min-width: 0; }
416
+ .tb-breadcrumb .crumb { padding: 2px 6px; border-radius: var(--radius-md); white-space: nowrap; }
417
+
418
+ /* Switcher chips in topbar — Linear-style quick switch */
419
+ .tb-switcher { display: flex; align-items: center; gap: 2px; flex: 1; min-width: 0; }
420
+ .tb-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 8px 4px 6px; border-radius: var(--radius-md); border: 1px solid transparent; background: transparent; font-size: var(--text-sm); color: var(--foreground); cursor: pointer; max-width: 240px; min-width: 0; transition: background .12s, border-color .12s; }
421
+ .tb-chip:hover { background: var(--surface-3); }
422
+ .tb-chip[data-open="true"] { background: var(--surface-3); border-color: var(--border); }
423
+ .tb-chip-icon { width: 18px; height: 18px; border-radius: 4px; display: grid; place-items: center; color: var(--primary-foreground); font-weight: 700; font-size: 10px; flex-shrink: 0; }
424
+ .tb-chip-label { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
425
+ .tb-chip-caret { color: var(--muted-foreground); flex-shrink: 0; }
426
+ .tb-chip.empty { color: var(--muted-foreground); border: 1px dashed var(--border); }
427
+ .tb-chip-sep { color: var(--muted-foreground); user-select: none; padding: 0 1px; }
428
+ .tb-chip-route { color: var(--muted-foreground); padding: 4px 6px; font-size: var(--text-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
429
+
430
+ /* Switcher dropdown */
431
+ .sw-pop {
432
+ position: absolute; top: calc(100% + 4px); z-index: 100;
433
+ width: 360px; max-height: 460px;
434
+ background: var(--popover); color: var(--popover-foreground);
435
+ border: 1px solid var(--border); border-radius: var(--radius-lg);
436
+ box-shadow: var(--shadow-2xl);
437
+ display: flex; flex-direction: column; overflow: hidden;
438
+ animation: sw-pop-in .14s var(--ease-out);
439
+ }
440
+ @keyframes sw-pop-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
441
+ .sw-pop-search { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
442
+ .sw-pop-search input { flex: 1; border: 0; outline: 0; background: transparent; font-size: var(--text-sm); color: var(--foreground); padding: 0; }
443
+ .sw-pop-list { flex: 1; overflow-y: auto; padding: 4px; }
444
+ .sw-pop-section { padding: 8px 10px 4px; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted-foreground); display: flex; align-items: center; justify-content: space-between; }
445
+ .sw-pop-item { display: flex; align-items: center; gap: 10px; padding: 6px 8px; border-radius: var(--radius-md); cursor: pointer; font-size: var(--text-sm); }
446
+ .sw-pop-item:hover, .sw-pop-item[data-focused="true"] { background: var(--surface-3); }
447
+ .sw-pop-item[data-active="true"] { background: color-mix(in oklch, var(--primary) 10%, transparent); }
448
+ .sw-pop-item-meta { color: var(--muted-foreground); font-size: var(--text-2xs); margin-left: auto; flex-shrink: 0; }
449
+ .sw-pop-empty { padding: 24px 12px; text-align: center; color: var(--muted-foreground); font-size: var(--text-sm); }
450
+ .sw-pop-foot { padding: 6px 10px; border-top: 1px solid var(--border); display: flex; align-items: center; gap: 12px; font-size: 10px; color: var(--muted-foreground); flex-shrink: 0; }
451
+ .sw-pop-foot .kbd { font-size: 9px; }
452
+ .sw-kind-chip { padding: 1px 5px; border-radius: 3px; font-size: 9px; font-weight: 500; letter-spacing: 0.04em; text-transform: uppercase; background: var(--surface-3); color: var(--muted-foreground); border: 1px solid var(--border); }
453
+ .tb-breadcrumb .crumb.current { color: var(--foreground); font-weight: 500; }
454
+ .tb-breadcrumb .sep { opacity: 0.4; }
455
+ .tb-search { display: flex; align-items: center; gap: var(--spacing-2); width: 320px; height: var(--density-element-sm); padding: 0 var(--spacing-2); border: 1px solid var(--input); border-radius: var(--radius-md); background: var(--input-background); color: var(--muted-foreground); font-size: var(--text-sm); cursor: pointer; }
456
+ .tb-search:hover { border-color: var(--muted-foreground); }
457
+ .tb-search .kbd { margin-left: auto; }
458
+
459
+ .kbd { display: inline-flex; align-items: center; padding: 1px 5px; border: 1px solid var(--border); border-bottom-width: 2px; border-radius: 4px; background: var(--kbd-bg); font-size: var(--text-2xs); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--muted-foreground); line-height: 1.2; }
460
+
461
+ .tb-icon-btn { width: var(--density-element-sm); height: var(--density-element-sm); display: grid; place-items: center; border-radius: var(--radius-md); border: 0; background: transparent; color: var(--muted-foreground); }
462
+ .tb-icon-btn:hover { background: var(--surface-3); color: var(--foreground); }
463
+ .tb-icon-btn[data-active="true"] { color: var(--primary); }
464
+
465
+ .avatar { width: 28px; height: 28px; border-radius: 99px; background: var(--surface-3); display: grid; place-items: center; font-size: var(--text-xs); font-weight: 600; color: var(--foreground); flex-shrink: 0; }
466
+ .avatar.brand { background: var(--brand); color: var(--primary-foreground); }
467
+
468
+ /* ── Page primitives ──────────────────────────────────────────────── */
469
+ .page { padding: var(--spacing-6); max-width: var(--container-max-width); margin: 0 auto; }
470
+ .page-header { display: flex; align-items: flex-start; gap: var(--spacing-4); margin-bottom: var(--spacing-6); }
471
+ .page-title { font-size: var(--density-page-title); font-weight: 500; line-height: 1.25; margin: 0 0 var(--spacing-1); letter-spacing: -0.01em; }
472
+ .page-subtitle { font-size: var(--text-sm); color: var(--muted-foreground); margin: 0; }
473
+ .page-actions { margin-left: auto; display: flex; gap: var(--spacing-2); align-items: center; }
474
+
475
+ .card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--density-card); }
476
+ .card-header { display: flex; align-items: center; gap: var(--spacing-2); margin-bottom: var(--spacing-3); padding-bottom: var(--spacing-3); border-bottom: 1px solid var(--border); }
477
+ .card-title { font-size: var(--text-base); font-weight: 500; margin: 0; }
478
+ .card-subtitle { font-size: var(--text-xs); color: var(--muted-foreground); margin: 0; }
479
+
480
+ .btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--spacing-2); height: var(--density-element); padding: 0 var(--spacing-3); border-radius: var(--radius-md); border: 1px solid transparent; font-size: var(--text-sm); font-weight: 500; line-height: 1; transition: background var(--transition-fast), border-color var(--transition-fast); white-space: nowrap; }
481
+ .btn:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
482
+ .btn-primary { background: var(--primary); color: var(--primary-foreground); }
483
+ .btn-primary:hover { background: color-mix(in oklch, var(--primary) 88%, black); }
484
+ .btn-secondary { background: var(--surface-1); color: var(--foreground); border-color: var(--border); }
485
+ .btn-secondary:hover { background: var(--surface-3); }
486
+ .btn-ghost { background: transparent; color: var(--foreground); }
487
+ .btn-ghost:hover { background: var(--surface-3); }
488
+ .btn-danger { background: var(--destructive); color: var(--destructive-foreground); }
489
+ .btn-danger:hover { background: color-mix(in oklch, var(--destructive) 90%, black); }
490
+ .btn-sm { height: var(--density-element-sm); padding: 0 var(--spacing-2); font-size: var(--text-xs); }
491
+ .btn-lg { height: var(--density-element-lg); padding: 0 var(--spacing-4); }
492
+
493
+ .input { display: flex; align-items: center; height: var(--density-element); padding: 0 var(--spacing-3); border: 1px solid var(--input); border-radius: var(--radius-md); background: var(--input-background); color: var(--foreground); font-size: var(--text-sm); width: 100%; }
494
+ .input:focus { outline: 2px solid var(--ring); outline-offset: -1px; border-color: transparent; }
495
+ textarea.input { padding: var(--spacing-2) var(--spacing-3); height: auto; line-height: var(--leading-normal); resize: vertical; }
496
+
497
+ .label { display: block; font-size: var(--text-xs); font-weight: 500; color: var(--foreground); margin-bottom: var(--spacing-1); }
498
+ .help { font-size: var(--text-xs); color: var(--muted-foreground); margin-top: var(--spacing-1); }
499
+
500
+ /* Badges */
501
+ .badge { display: inline-flex; align-items: center; gap: 4px; padding: 1px 8px; border-radius: var(--radius-full); font-size: var(--text-2xs); font-weight: 500; line-height: 1.5; border: 1px solid transparent; }
502
+ .badge .dot { width: 6px; height: 6px; border-radius: 99px; flex-shrink: 0; }
503
+ .badge-success { background: color-mix(in oklch, var(--success) 14%, transparent); color: color-mix(in oklch, var(--success) 80%, var(--foreground)); }
504
+ .badge-success .dot { background: var(--success); }
505
+ .badge-warning { background: color-mix(in oklch, var(--warning) 18%, transparent); color: color-mix(in oklch, var(--warning) 50%, var(--foreground)); }
506
+ .badge-warning .dot { background: var(--warning); }
507
+ .badge-info { background: color-mix(in oklch, var(--info) 14%, transparent); color: color-mix(in oklch, var(--info) 80%, var(--foreground)); }
508
+ .badge-info .dot { background: var(--info); }
509
+ .badge-error { background: color-mix(in oklch, var(--error) 14%, transparent); color: color-mix(in oklch, var(--error) 80%, var(--foreground)); }
510
+ .badge-error .dot { background: var(--error); }
511
+ .badge-attention { background: color-mix(in oklch, var(--attention) 14%, transparent); color: color-mix(in oklch, var(--attention) 80%, var(--foreground)); }
512
+ .badge-attention .dot { background: var(--attention); }
513
+ .badge-neutral { background: var(--surface-3); color: var(--muted-foreground); }
514
+ .badge-neutral .dot { background: var(--muted-foreground); }
515
+ .badge-outline { background: transparent; border-color: var(--border); color: var(--muted-foreground); }
516
+
517
+ /* Tags / chips */
518
+ .chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; background: var(--surface-3); color: var(--foreground); border-radius: var(--radius-md); font-size: var(--text-xs); }
519
+
520
+ /* Table */
521
+ .table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
522
+ .table thead th { background: var(--surface-2); text-align: left; padding: 0 var(--spacing-3); height: var(--density-table-head); font-size: var(--text-xs); font-weight: 500; color: var(--muted-foreground); border-bottom: 1px solid var(--border); white-space: nowrap; }
523
+ .table tbody td { padding: var(--spacing-2) var(--spacing-3); border-bottom: 1px solid var(--border); vertical-align: middle; }
524
+ .table tbody tr:hover td { background: var(--surface-2); }
525
+ .table tbody tr:last-child td { border-bottom: 0; }
526
+ .table .num { font-variant-numeric: tabular-nums; text-align: right; }
527
+ .table .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--text-xs); }
528
+
529
+ /* Tabs */
530
+ .tabs { display: flex; gap: 0; border-bottom: 1px solid var(--border); }
531
+ .tab { padding: var(--spacing-2) var(--spacing-3); font-size: var(--text-sm); color: var(--muted-foreground); border-bottom: 2px solid transparent; margin-bottom: -1px; cursor: pointer; user-select: none; }
532
+ .tab:hover { color: var(--foreground); }
533
+ .tab[data-active="true"] { color: var(--foreground); font-weight: 500; border-bottom-color: var(--primary); }
534
+
535
+ /* KPI cards */
536
+ .kpi { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--density-card); display: flex; flex-direction: column; gap: var(--spacing-1); }
537
+ .kpi-label { font-size: var(--text-xs); color: var(--muted-foreground); display: flex; align-items: center; gap: var(--spacing-1); }
538
+ .kpi-value { font-size: var(--text-2xl); font-weight: 500; line-height: 1.2; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
539
+ .kpi-delta { font-size: var(--text-xs); color: var(--success); display: flex; align-items: center; gap: 4px; font-variant-numeric: tabular-nums; }
540
+ .kpi-delta.down { color: var(--error); }
541
+
542
+ /* Activity / log lines */
543
+ .log-line { display: grid; grid-template-columns: 80px 80px 1fr; gap: var(--spacing-3); padding: var(--spacing-1) var(--spacing-2); border-radius: var(--radius-md); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--text-xs); line-height: var(--leading-normal); align-items: baseline; }
544
+ .log-line:hover { background: var(--surface-2); }
545
+ .log-line .time { color: var(--muted-foreground); }
546
+ .log-line .src { color: var(--info); }
547
+ .log-line .src.warn { color: var(--attention); }
548
+ .log-line .src.err { color: var(--error); }
549
+ .log-line .src.ok { color: var(--success); }
550
+
551
+ /* Diff hunks (for code browser) */
552
+ .diff { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--text-xs); line-height: 1.5; border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; }
553
+ .diff-row { display: grid; grid-template-columns: 40px 40px 1fr; }
554
+ .diff-row .ln { background: var(--surface-2); color: var(--muted-foreground); text-align: right; padding: 0 var(--spacing-2); user-select: none; border-right: 1px solid var(--border); }
555
+ .diff-row .body { padding: 0 var(--spacing-3); white-space: pre; }
556
+ .diff-row.add { background: color-mix(in oklch, var(--success) 8%, transparent); }
557
+ .diff-row.add .body::before { content: "+ "; color: var(--success); }
558
+ .diff-row.del { background: color-mix(in oklch, var(--error) 8%, transparent); }
559
+ .diff-row.del .body::before { content: "− "; color: var(--error); }
560
+ .diff-row.ctx .body::before { content: " "; }
561
+
562
+ /* Kanban */
563
+ .kanban { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--spacing-3); }
564
+ .kanban-col { background: var(--surface-2); border-radius: var(--radius-lg); padding: var(--spacing-3); display: flex; flex-direction: column; gap: var(--spacing-2); min-height: 320px; }
565
+ .kanban-col-head { display: flex; align-items: center; gap: var(--spacing-2); font-size: var(--text-xs); color: var(--muted-foreground); text-transform: uppercase; letter-spacing: 0.05em; }
566
+ .kanban-col-count { background: var(--surface-3); padding: 0 6px; border-radius: 99px; font-size: var(--text-2xs); color: var(--foreground); font-weight: 500; }
567
+ .issue-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--spacing-3); display: flex; flex-direction: column; gap: var(--spacing-2); cursor: grab; }
568
+ .issue-card:hover { border-color: var(--primary); }
569
+ .issue-id { font-size: var(--text-2xs); color: var(--muted-foreground); font-family: ui-monospace, monospace; }
570
+ .issue-title { font-size: var(--text-sm); font-weight: 500; }
571
+
572
+ /* Wiki TOC */
573
+ .wiki-layout { display: grid; grid-template-columns: 220px 1fr 220px; gap: var(--spacing-6); }
574
+ .wiki-toc { font-size: var(--text-xs); color: var(--muted-foreground); position: sticky; top: var(--spacing-4); align-self: start; }
575
+ .wiki-toc a { display: block; padding: 4px 8px; border-radius: 4px; color: inherit; text-decoration: none; }
576
+ .wiki-toc a:hover { background: var(--surface-3); color: var(--foreground); }
577
+ .wiki-toc a.active { color: var(--primary); border-left: 2px solid var(--primary); padding-left: 6px; }
578
+
579
+ .prose { max-width: 70ch; }
580
+ .prose h1 { font-size: var(--text-2xl); font-weight: 500; margin: 0 0 var(--spacing-3); }
581
+ .prose h2 { font-size: var(--text-xl); font-weight: 500; margin: var(--spacing-6) 0 var(--spacing-3); padding-bottom: var(--spacing-1); border-bottom: 1px solid var(--border); }
582
+ .prose h3 { font-size: var(--text-lg); font-weight: 500; margin: var(--spacing-5) 0 var(--spacing-2); }
583
+ .prose p { margin: 0 0 var(--spacing-3); line-height: var(--leading-body); }
584
+ .prose code { font-family: ui-monospace, monospace; font-size: 0.9em; background: var(--surface-3); padding: 1px 5px; border-radius: 4px; }
585
+ .prose pre { background: var(--surface-3); padding: var(--spacing-3); border-radius: var(--radius-md); overflow-x: auto; margin: var(--spacing-3) 0; }
586
+ .prose pre code { background: transparent; padding: 0; }
587
+ .prose ul { padding-left: 1.5rem; margin: 0 0 var(--spacing-3); }
588
+ .prose blockquote { border-left: 3px solid var(--border); padding-left: var(--spacing-3); margin: var(--spacing-3) 0; color: var(--muted-foreground); }
589
+
590
+ /* Misc helpers */
591
+ .row { display: flex; align-items: center; }
592
+ .col { display: flex; flex-direction: column; }
593
+ .gap-1 { gap: var(--spacing-1); } .gap-2 { gap: var(--spacing-2); } .gap-3 { gap: var(--spacing-3); } .gap-4 { gap: var(--spacing-4); } .gap-6 { gap: var(--spacing-6); }
594
+ .muted { color: var(--muted-foreground); }
595
+ .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--text-xs); }
596
+ .tnum { font-variant-numeric: tabular-nums; }
597
+ .divider { height: 1px; background: var(--border); border: 0; margin: var(--spacing-3) 0; }
598
+ .dot { display: inline-block; width: 6px; height: 6px; border-radius: 99px; }
599
+ .grow { flex: 1; min-width: 0; }
600
+ .ml-auto { margin-left: auto; }
601
+
602
+ /* Sparkline */
603
+ .spark { height: 32px; width: 100%; display: block; }
604
+ .spark path.line { stroke: var(--primary); stroke-width: 1.5; fill: none; }
605
+ .spark path.area { fill: var(--primary); fill-opacity: 0.08; }
606
+
607
+ /* Donut */
608
+ .donut { width: 80px; height: 80px; }
609
+
610
+ /* Login screen */
611
+ .auth-shell { min-height: 100vh; display: grid; grid-template-columns: 1fr 1fr; }
612
+ .auth-card { display: flex; align-items: center; justify-content: center; padding: var(--spacing-12); }
613
+ .auth-art { background: linear-gradient(135deg, var(--brand) 0%, color-mix(in oklch, var(--brand) 60%, var(--foreground)) 100%); display: flex; flex-direction: column; justify-content: space-between; padding: var(--spacing-12); color: var(--primary-foreground); position: relative; overflow: hidden; }
614
+ .auth-art::after { content: ""; position: absolute; inset: 0; background: radial-gradient(circle at 20% 80%, color-mix(in oklch, white 10%, transparent), transparent 50%); pointer-events: none; }
615
+
616
+ @media (max-width: 768px) {
617
+ .auth-shell { grid-template-columns: 1fr; }
618
+ .auth-art { display: none; }
619
+ }
620
+
621
+ /* Animations */
622
+ @keyframes pulse-dot {
623
+ 0%, 100% { opacity: 1; }
624
+ 50% { opacity: 0.55; }
625
+ }
626
+ .pulse { animation: pulse-dot 2s var(--ease-in-out) infinite; }
627
+ .pulse-dot { animation: pulse-dot 2s var(--ease-in-out) infinite; }
628
+ @media (prefers-reduced-motion: reduce) {
629
+ .pulse, .pulse-dot { animation: none; }
630
+ }
631
+
632
+ @keyframes fade-in {
633
+ from { opacity: 0; transform: translateY(4px); }
634
+ to { opacity: 1; transform: none; }
635
+ }
636
+ .fade-in { animation: fade-in var(--transition-base) var(--ease-out) both; }
637
+
638
+ /* ── Floating panels (Popover, DropdownMenu) ──────────────────────── */
639
+ /* Shared shell for any Radix-portaled floating content. Sits on top
640
+ of the canonical `--popover` surface, with the hairline border +
641
+ subtle shadow the brand uses for elevated layers. */
642
+ .floating-panel {
643
+ background: var(--popover);
644
+ color: var(--popover-foreground);
645
+ border: 1px solid var(--border);
646
+ border-radius: var(--radius-md);
647
+ box-shadow: 0 4px 12px -2px color-mix(in oklch, var(--foreground) 14%, transparent),
648
+ 0 0 0 1px color-mix(in oklch, var(--foreground) 4%, transparent);
649
+ padding: var(--spacing-1);
650
+ font-size: var(--text-sm);
651
+ min-width: 8rem;
652
+ z-index: 50;
653
+ animation: fade-in var(--transition-fast) var(--ease-out) both;
654
+ }
655
+
656
+ .popover-content { /* alias for semantic clarity at call sites */
657
+ composes: floating-panel;
658
+ padding: var(--spacing-3);
659
+ }
660
+ .popover-content,
661
+ .dropdown-menu-content {
662
+ background: var(--popover);
663
+ color: var(--popover-foreground);
664
+ border: 1px solid var(--border);
665
+ border-radius: var(--radius-md);
666
+ box-shadow: 0 4px 12px -2px color-mix(in oklch, var(--foreground) 14%, transparent),
667
+ 0 0 0 1px color-mix(in oklch, var(--foreground) 4%, transparent);
668
+ font-size: var(--text-sm);
669
+ z-index: 50;
670
+ animation: fade-in var(--transition-fast) var(--ease-out) both;
671
+ }
672
+ .popover-content { padding: var(--spacing-3); }
673
+ .dropdown-menu-content { padding: var(--spacing-1); min-width: 8rem; }
674
+
675
+ .dropdown-menu-item {
676
+ display: flex;
677
+ align-items: center;
678
+ gap: var(--spacing-2);
679
+ padding: var(--spacing-1) var(--spacing-2);
680
+ border-radius: var(--radius-sm, 4px);
681
+ font-size: var(--text-sm);
682
+ color: var(--foreground);
683
+ cursor: pointer;
684
+ user-select: none;
685
+ outline: none;
686
+ }
687
+ .dropdown-menu-item[data-highlighted] { background: var(--surface-3); }
688
+ .dropdown-menu-item[data-disabled] { color: var(--muted-foreground); pointer-events: none; opacity: 0.6; }
689
+ .dropdown-menu-item[data-variant="destructive"] { color: var(--destructive); }
690
+ .dropdown-menu-item[data-variant="destructive"][data-highlighted] {
691
+ background: color-mix(in oklch, var(--destructive) 12%, transparent);
692
+ }
693
+ .dropdown-menu-item[data-inset="true"] { padding-left: var(--spacing-6); }
694
+
695
+ .dropdown-menu-separator {
696
+ height: 1px;
697
+ margin: var(--spacing-1) calc(-1 * var(--spacing-1));
698
+ background: var(--border);
699
+ }
700
+
701
+ .dropdown-menu-label {
702
+ padding: var(--spacing-1) var(--spacing-2);
703
+ font-size: var(--text-2xs);
704
+ text-transform: uppercase;
705
+ letter-spacing: 0.06em;
706
+ color: var(--muted-foreground);
707
+ }
708
+
709
+ .dropdown-menu-shortcut {
710
+ margin-left: auto;
711
+ font-size: var(--text-2xs);
712
+ color: var(--muted-foreground);
713
+ letter-spacing: 0.04em;
714
+ }
715
+
716
+ /* ── Calendar (react-day-picker) ──────────────────────────────────── */
717
+ /* Tokenised so the calendar inherits brand colors automatically. The
718
+ `.calendar` class is applied to <DayPicker className=…>; the
719
+ day-picker library's BEM-ish class names (rdp-…) are themed via
720
+ nested rules. */
721
+ .calendar {
722
+ --rdp-cell-size: 32px;
723
+ --rdp-accent-color: var(--primary);
724
+ --rdp-background-color: var(--surface-3);
725
+ --rdp-accent-color-dark: var(--primary);
726
+ --rdp-background-color-dark: var(--surface-3);
727
+ --rdp-outline: 2px solid var(--ring);
728
+ --rdp-outline-selected: 2px solid var(--ring);
729
+ font-size: var(--text-sm);
730
+ color: var(--foreground);
731
+ padding: var(--spacing-2);
732
+ }
733
+ .calendar .rdp-caption_label { font-weight: 500; font-size: var(--text-sm); }
734
+ .calendar .rdp-head_cell { font-weight: 500; color: var(--muted-foreground); font-size: var(--text-2xs); }
735
+ .calendar .rdp-button { border-radius: var(--radius-md); }
736
+ .calendar .rdp-day_today:not(.rdp-day_selected) {
737
+ background: var(--surface-3);
738
+ color: var(--foreground);
739
+ font-weight: 500;
740
+ }
741
+ .calendar .rdp-day_selected {
742
+ background: var(--primary);
743
+ color: var(--primary-foreground);
744
+ }
745
+ .calendar .rdp-day_outside { color: var(--muted-foreground); opacity: 0.6; }
746
+
747
+ /* ── Time input (HH:mm) ───────────────────────────────────────────── */
748
+ /* Visually identical to `.input` but typically narrower. Caller can
749
+ constrain width via inline style or wrapper. */
750
+ .time-input {
751
+ display: inline-flex;
752
+ align-items: center;
753
+ height: var(--density-element);
754
+ padding: 0 var(--spacing-3);
755
+ border: 1px solid var(--input);
756
+ border-radius: var(--radius-md);
757
+ background: var(--input-background);
758
+ color: var(--foreground);
759
+ font-size: var(--text-sm);
760
+ font-variant-numeric: tabular-nums;
761
+ width: 5.5rem;
762
+ }
763
+ .time-input:focus { outline: 2px solid var(--ring); outline-offset: -1px; border-color: transparent; }
764
+ .time-input[aria-invalid="true"] { border-color: var(--destructive); }
765
+ .time-input:disabled { opacity: 0.5; cursor: not-allowed; }