@godxjp/ui 2.2.0 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/BRAND.md +39 -29
  2. package/CHANGELOG.md +566 -10
  3. package/README.md +143 -168
  4. package/config/eslint.js +54 -0
  5. package/config/prettier.cjs +20 -0
  6. package/config/tsconfig.base.json +22 -0
  7. package/config/vitest.base.ts +26 -0
  8. package/dist/MiniMonth-YAmPGEpC.d.ts +143 -0
  9. package/dist/Table.types-BbsxoIYE.d.ts +352 -0
  10. package/dist/color-DO0qqUAb.d.ts +38 -0
  11. package/dist/components/composites.d.ts +963 -0
  12. package/dist/components/composites.js +7340 -0
  13. package/dist/components/composites.js.map +1 -0
  14. package/dist/components/primitives.d.ts +2633 -163
  15. package/dist/components/primitives.js +7266 -165
  16. package/dist/components/primitives.js.map +1 -1
  17. package/dist/components/shell.d.ts +82 -12
  18. package/dist/components/shell.js +168 -162
  19. package/dist/components/shell.js.map +1 -1
  20. package/dist/hooks.d.ts +83 -8
  21. package/dist/hooks.js +497 -83
  22. package/dist/hooks.js.map +1 -1
  23. package/dist/i18n.d.ts +55 -3
  24. package/dist/i18n.js +456 -5
  25. package/dist/i18n.js.map +1 -1
  26. package/dist/index.d.ts +24 -5
  27. package/dist/index.js +12524 -267
  28. package/dist/index.js.map +1 -1
  29. package/dist/padding-DY0JV5Ja.d.ts +16 -0
  30. package/dist/preferences.d.ts +132 -0
  31. package/dist/preferences.js +262 -0
  32. package/dist/preferences.js.map +1 -0
  33. package/dist/props.d.ts +86 -0
  34. package/dist/props.js +16 -0
  35. package/dist/props.js.map +1 -0
  36. package/dist/size-CQwNvOWd.d.ts +19 -0
  37. package/dist/{data.d.ts → types-LTj-2bl-.d.ts} +7 -12
  38. package/dist/useTableViews-D5NIAJ7h.d.ts +154 -0
  39. package/package.json +92 -35
  40. package/src/tokens/tailwind.css +158 -0
  41. package/dist/components/screens.d.ts +0 -51
  42. package/dist/components/screens.js +0 -806
  43. package/dist/components/screens.js.map +0 -1
  44. package/dist/data.js +0 -93
  45. package/dist/data.js.map +0 -1
  46. package/src/tokens/tokens-ext.css +0 -401
  47. package/src/tokens/tokens.css +0 -765
@@ -1,765 +0,0 @@
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; }