@godxjp/ui 18.4.0 → 18.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -1
- package/dist/app/theme-axes.d.ts +11 -3
- package/dist/app/theme-axes.js +2 -1
- package/dist/components/charts/chart-frame.d.ts +17 -3
- package/dist/components/charts/chart-frame.js +7 -1
- package/dist/components/charts/chart-summary.d.ts +21 -0
- package/dist/components/charts/chart-summary.js +32 -5
- package/dist/components/charts/compact-bar-trend.d.ts +29 -0
- package/dist/components/charts/compact-bar-trend.js +74 -0
- package/dist/components/charts/index.d.ts +3 -0
- package/dist/components/charts/index.js +2 -0
- package/dist/components/data-display/badge.d.ts +8 -0
- package/dist/components/data-display/badge.js +7 -1
- package/dist/components/data-display/data-table.d.ts +16 -1
- package/dist/components/data-display/data-table.js +56 -0
- package/dist/components/data-display/index.d.ts +3 -1
- package/dist/components/data-display/index.js +10 -1
- package/dist/components/data-display/list-row.d.ts +22 -4
- package/dist/components/data-display/list-row.js +21 -3
- package/dist/components/data-display/service-launcher-card.d.ts +40 -0
- package/dist/components/data-display/service-launcher-card.js +97 -0
- package/dist/components/data-entry/command-palette.d.ts +37 -0
- package/dist/components/data-entry/command-palette.js +125 -0
- package/dist/components/data-entry/index.d.ts +2 -0
- package/dist/components/data-entry/index.js +2 -0
- package/dist/components/feedback/dialog.d.ts +2 -0
- package/dist/components/feedback/dialog.js +42 -33
- package/dist/components/feedback/index.d.ts +4 -1
- package/dist/components/feedback/index.js +6 -2
- package/dist/components/feedback/sheet.d.ts +26 -4
- package/dist/components/feedback/sheet.js +54 -7
- package/dist/components/feedback/two-factor-setup.d.ts +31 -0
- package/dist/components/feedback/two-factor-setup.js +97 -0
- package/dist/components/general/index.d.ts +1 -1
- package/dist/components/general/logo.d.ts +42 -8
- package/dist/components/general/logo.js +67 -14
- package/dist/components/layout/app-shell.js +21 -5
- package/dist/components/layout/auth-divider.d.ts +7 -0
- package/dist/components/layout/auth-divider.js +21 -0
- package/dist/components/layout/auth-footer.d.ts +5 -0
- package/dist/components/layout/auth-footer.js +24 -0
- package/dist/components/layout/auth-identity.d.ts +5 -0
- package/dist/components/layout/auth-identity.js +17 -0
- package/dist/components/layout/auth-shell.d.ts +8 -1
- package/dist/components/layout/auth-shell.js +25 -6
- package/dist/components/layout/auth-stack.d.ts +4 -0
- package/dist/components/layout/auth-stack.js +8 -0
- package/dist/components/layout/centered-shell.d.ts +5 -2
- package/dist/components/layout/centered-shell.js +2 -1
- package/dist/components/layout/index.d.ts +18 -3
- package/dist/components/layout/index.js +17 -2
- package/dist/components/layout/legal-document-shell.d.ts +34 -0
- package/dist/components/layout/legal-document-shell.js +186 -0
- package/dist/components/layout/master-detail.d.ts +24 -0
- package/dist/components/layout/master-detail.js +48 -0
- package/dist/components/layout/org-switcher.d.ts +9 -0
- package/dist/components/layout/org-switcher.js +218 -0
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +3 -2
- package/dist/components/layout/sidebar-link.d.ts +43 -0
- package/dist/components/layout/sidebar-link.js +13 -0
- package/dist/components/layout/sidebar.d.ts +42 -5
- package/dist/components/layout/sidebar.js +170 -85
- package/dist/components/navigation/app-setting-picker.js +17 -6
- package/dist/components/navigation/filter-bar.d.ts +12 -3
- package/dist/components/navigation/filter-bar.js +8 -2
- package/dist/components/navigation/index.d.ts +2 -2
- package/dist/components/navigation/index.js +3 -1
- package/dist/components/navigation/tabs-scroll.d.ts +70 -0
- package/dist/components/navigation/tabs-scroll.js +76 -0
- package/dist/components/navigation/tabs.js +35 -20
- package/dist/email/brand-mark.d.ts +92 -0
- package/dist/email/brand-mark.js +83 -0
- package/dist/email/color.d.ts +52 -0
- package/dist/email/color.js +37 -0
- package/dist/email/geometry.d.ts +112 -0
- package/dist/email/geometry.js +89 -0
- package/dist/email/index.d.ts +78 -0
- package/dist/email/index.js +76 -0
- package/dist/email/inline-style.d.ts +25 -0
- package/dist/email/inline-style.js +21 -0
- package/dist/email/tokens.generated.d.ts +147 -0
- package/dist/email/tokens.generated.js +142 -0
- package/dist/i18n/messages/en.json +21 -2
- package/dist/i18n/messages/ja.json +21 -2
- package/dist/i18n/messages/vi.json +21 -2
- package/dist/inertia/index.d.ts +50 -0
- package/dist/inertia/index.js +5 -0
- package/dist/props/components/app.prop.d.ts +11 -1
- package/dist/props/components/charts.prop.d.ts +40 -1
- package/dist/props/components/data-display.prop.d.ts +13 -1
- package/dist/props/components/feedback.prop.d.ts +10 -0
- package/dist/props/components/index.d.ts +2 -2
- package/dist/props/components/layout.prop.d.ts +373 -10
- package/dist/props/components/layout.prop.js +1 -0
- package/dist/props/components/navigation.prop.d.ts +19 -1
- package/dist/props/registry.d.ts +291 -7
- package/dist/props/registry.js +341 -7
- package/dist/props/vocabulary/index.d.ts +1 -1
- package/dist/props/vocabulary/interaction.prop.d.ts +1 -1
- package/dist/props/vocabulary/layout.prop.d.ts +18 -0
- package/dist/styles/base.css +8 -2
- package/dist/styles/card-layout.css +161 -7
- package/dist/styles/chart-layout.css +97 -0
- package/dist/styles/control.css +48 -2
- package/dist/styles/data-display-layout.css +52 -6
- package/dist/styles/dialog-layout.css +105 -4
- package/dist/styles/fonts.css +15 -4
- package/dist/styles/index.css +11 -3
- package/dist/styles/layout.css +367 -1
- package/dist/styles/logo-layout.css +62 -0
- package/dist/styles/navigation-layout.css +43 -0
- package/dist/styles/shell-layout.css +488 -40
- package/dist/theme/dxs.canonical.css +76 -0
- package/dist/tokens/axes.css +39 -0
- package/dist/tokens/base.css +5 -0
- package/dist/tokens/components/card.css +48 -0
- package/dist/tokens/components/chart.css +47 -0
- package/dist/tokens/components/control.css +16 -0
- package/dist/tokens/components/email.css +66 -0
- package/dist/tokens/components/feedback.css +17 -0
- package/dist/tokens/components/legal-document.css +67 -0
- package/dist/tokens/components/list-row.css +23 -2
- package/dist/tokens/components/logo.css +32 -0
- package/dist/tokens/components/navigation.css +13 -0
- package/dist/tokens/components/sheet.css +19 -0
- package/dist/tokens/components/shell.css +138 -0
- package/dist/tokens/components/sidebar.css +33 -0
- package/dist/tokens/foundation.css +5 -2
- package/dist/tokens/semantic/layout.css +44 -2
- package/package.json +16 -5
|
@@ -56,14 +56,19 @@
|
|
|
56
56
|
box-shadow: 0 0 0 1px hsl(var(--primary));
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
/* ── Density — override the shell inset/body tokens
|
|
59
|
+
/* ── Density — override the shell inset/body tokens ──────────────────────
|
|
60
|
+
* `--card-space-shell-y: initial` re-arms the block axis to follow THIS card's inset again: the
|
|
61
|
+
* `density` prop is an explicit per-instance decision and must beat an ambient shell-level block
|
|
62
|
+
* override (e.g. AuthShell compact), exactly as it did when one inset owned both axes. */
|
|
60
63
|
[data-slot="card"][data-density="tight"] {
|
|
61
64
|
--card-space-inset: var(--space-3);
|
|
65
|
+
--card-space-shell-y: initial;
|
|
62
66
|
--card-space-body-y: var(--space-3);
|
|
63
67
|
}
|
|
64
68
|
|
|
65
69
|
[data-slot="card"][data-density="cozy"] {
|
|
66
70
|
--card-space-inset: var(--space-5);
|
|
71
|
+
--card-space-shell-y: initial;
|
|
67
72
|
--card-space-body-y: var(--space-5);
|
|
68
73
|
}
|
|
69
74
|
|
|
@@ -111,7 +116,7 @@
|
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
[data-slot="card-header"]:not([data-banded]) {
|
|
114
|
-
padding-top: var(--card-space-inset);
|
|
119
|
+
padding-top: var(--card-space-shell-y, var(--card-space-inset));
|
|
115
120
|
padding-bottom: 0;
|
|
116
121
|
}
|
|
117
122
|
|
|
@@ -254,7 +259,7 @@
|
|
|
254
259
|
/* Header-only card — terminal slot owns bottom shell */
|
|
255
260
|
[data-slot="card"]:not(:has([data-slot="card-content"], [data-slot="card-footer"]))
|
|
256
261
|
[data-slot="card-header"] {
|
|
257
|
-
padding-bottom: var(--card-space-inset);
|
|
262
|
+
padding-bottom: var(--card-space-shell-y, var(--card-space-inset));
|
|
258
263
|
}
|
|
259
264
|
|
|
260
265
|
/* Cover — header below media uses section top, not shell */
|
|
@@ -271,18 +276,27 @@
|
|
|
271
276
|
padding-top: var(--card-space-body-y);
|
|
272
277
|
}
|
|
273
278
|
|
|
274
|
-
/* ── Content
|
|
279
|
+
/* ── Content ─────────────────────────────────────────────────────────────
|
|
280
|
+
* The two axes are INDEPENDENT (gh#232): the inline column reads --card-space-inset, the block
|
|
281
|
+
* shell edge reads --card-space-shell-y (default = the same inset, so the resting render is
|
|
282
|
+
* unchanged). A shell that needs a shorter card without a narrower column — AuthShell compact —
|
|
283
|
+
* now moves the block axis alone instead of hitting a wall at a uniform inset. */
|
|
275
284
|
[data-slot="card-content"] {
|
|
276
285
|
padding-inline: var(--card-space-inset);
|
|
277
|
-
padding-bottom: var(--card-space-inset);
|
|
286
|
+
padding-bottom: var(--card-space-shell-y, var(--card-space-inset));
|
|
278
287
|
}
|
|
279
288
|
|
|
280
289
|
[data-slot="card-content"]:not([data-tight]):not([data-solo]) {
|
|
281
290
|
padding-top: var(--card-space-body-y);
|
|
282
291
|
}
|
|
283
292
|
|
|
293
|
+
/* A solo body owns BOTH block edges (there is no header/footer to carry them), so this is
|
|
294
|
+
* `padding-block`, not just `padding-top` — it overrides the generic bottom edge above.
|
|
295
|
+
* The fallback chain solo-y → shell-y → inset means: a shell that tunes only the general block
|
|
296
|
+
* knob still reaches a solo body, an explicit --card-space-solo-y wins over it, and with neither
|
|
297
|
+
* set the render is the historical inset. */
|
|
284
298
|
[data-slot="card-content"][data-solo] {
|
|
285
|
-
padding-
|
|
299
|
+
padding-block: var(--card-space-solo-y, var(--card-space-shell-y, var(--card-space-inset)));
|
|
286
300
|
}
|
|
287
301
|
|
|
288
302
|
[data-slot="card-content"][data-flush] {
|
|
@@ -343,7 +357,7 @@
|
|
|
343
357
|
|
|
344
358
|
[data-slot="card-footer"]:not([data-separated]) {
|
|
345
359
|
padding-top: 0;
|
|
346
|
-
padding-bottom: var(--card-space-inset);
|
|
360
|
+
padding-bottom: var(--card-space-shell-y, var(--card-space-inset));
|
|
347
361
|
}
|
|
348
362
|
|
|
349
363
|
[data-slot="card-footer"][data-separated] {
|
|
@@ -474,4 +488,144 @@
|
|
|
474
488
|
font-size: var(--stat-card-hint-font-size);
|
|
475
489
|
line-height: var(--line-height-normal);
|
|
476
490
|
}
|
|
491
|
+
|
|
492
|
+
/* ── Service launcher — organization-scoped downstream app tile ─────── */
|
|
493
|
+
[data-slot="card"][data-service-launcher] {
|
|
494
|
+
display: flex;
|
|
495
|
+
flex-direction: column;
|
|
496
|
+
gap: var(--card-service-launcher-space-gap);
|
|
497
|
+
padding: var(--card-space-inset);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
[data-slot="service-launcher-heading"],
|
|
501
|
+
[data-slot="service-launcher-skeleton-heading"] {
|
|
502
|
+
display: flex;
|
|
503
|
+
min-width: 0;
|
|
504
|
+
align-items: center;
|
|
505
|
+
gap: var(--card-service-launcher-space-gap);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
[data-slot="service-launcher-icon"] {
|
|
509
|
+
display: inline-flex;
|
|
510
|
+
width: var(--card-service-launcher-icon-size);
|
|
511
|
+
height: var(--card-service-launcher-icon-size);
|
|
512
|
+
flex: none;
|
|
513
|
+
align-items: center;
|
|
514
|
+
justify-content: center;
|
|
515
|
+
border-radius: var(--card-service-launcher-icon-radius);
|
|
516
|
+
background: hsl(var(--card-service-launcher-icon-background, var(--accent)));
|
|
517
|
+
color: hsl(var(--card-service-launcher-icon-foreground, var(--primary)));
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/* Unavailable tile (the consumer supplied a `disabledReason`): the medallion drops its brand
|
|
521
|
+
* wash so an un-launchable service never reads as live. Role-mirror knobs default at the CALL
|
|
522
|
+
* SITE, so a scoped [data-tenant]/.dark override of --muted still reaches it (docs/TOKENS.md). */
|
|
523
|
+
[data-slot="card"][data-service-launcher][data-unavailable] [data-slot="service-launcher-icon"] {
|
|
524
|
+
background: hsl(var(--card-service-launcher-unavailable-icon-background, var(--muted)));
|
|
525
|
+
color: hsl(var(--card-service-launcher-unavailable-icon-foreground, var(--muted-foreground)));
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
[data-slot="service-launcher-icon"] > svg {
|
|
529
|
+
width: var(--card-service-launcher-icon-glyph-size);
|
|
530
|
+
height: var(--card-service-launcher-icon-glyph-size);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
[data-slot="service-launcher-title"] {
|
|
534
|
+
min-width: 0;
|
|
535
|
+
flex: 1;
|
|
536
|
+
overflow-wrap: anywhere;
|
|
537
|
+
font-size: var(--card-title-font-size);
|
|
538
|
+
font-weight: var(--card-title-font-weight);
|
|
539
|
+
line-height: var(--card-title-line-height);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
[data-slot="service-launcher-status"] {
|
|
543
|
+
flex: none;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
[data-slot="service-launcher-description"] {
|
|
547
|
+
flex: 1;
|
|
548
|
+
overflow-wrap: anywhere;
|
|
549
|
+
color: hsl(var(--muted-foreground));
|
|
550
|
+
font-size: var(--card-service-launcher-description-font-size);
|
|
551
|
+
line-height: var(--card-service-launcher-description-line-height);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/* Mono metadata ONLY (hostname · plan) — machine identifiers, never prose. */
|
|
555
|
+
[data-slot="service-launcher-metadata"] {
|
|
556
|
+
overflow-wrap: anywhere;
|
|
557
|
+
color: hsl(var(--muted-foreground));
|
|
558
|
+
font-family: var(--font-mono);
|
|
559
|
+
font-size: var(--card-service-launcher-metadata-font-size);
|
|
560
|
+
line-height: var(--card-service-launcher-metadata-line-height);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/* The disabled/unavailable reason is a localized SENTENCE — it takes the description's prose
|
|
564
|
+
* rhythm, not the mono metadata treatment (a JA/VI sentence in monospace is unreadable). */
|
|
565
|
+
[data-slot="service-launcher-disabled-reason"] {
|
|
566
|
+
overflow-wrap: anywhere;
|
|
567
|
+
color: hsl(var(--muted-foreground));
|
|
568
|
+
font-size: var(--card-service-launcher-description-font-size);
|
|
569
|
+
line-height: var(--card-service-launcher-description-line-height);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
[data-slot="service-launcher-action"] > [data-slot="button"] {
|
|
573
|
+
width: 100%;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
[data-slot="card"][data-service-catalog-cta] {
|
|
577
|
+
min-height: var(--card-service-launcher-cta-min-height);
|
|
578
|
+
display: flex;
|
|
579
|
+
flex-direction: column;
|
|
580
|
+
align-items: center;
|
|
581
|
+
justify-content: center;
|
|
582
|
+
gap: var(--card-service-launcher-space-gap);
|
|
583
|
+
border-style: dashed;
|
|
584
|
+
padding: var(--card-space-inset);
|
|
585
|
+
text-align: center;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
[data-slot="service-catalog-icon"] {
|
|
589
|
+
width: var(--card-service-launcher-icon-glyph-size);
|
|
590
|
+
height: var(--card-service-launcher-icon-glyph-size);
|
|
591
|
+
color: hsl(var(--muted-foreground));
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
[data-slot="service-catalog-title"] {
|
|
595
|
+
color: hsl(var(--muted-foreground));
|
|
596
|
+
font-size: var(--card-service-launcher-description-font-size);
|
|
597
|
+
line-height: var(--card-service-launcher-description-line-height);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
[data-slot^="service-launcher-skeleton-"] {
|
|
601
|
+
display: block;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
[data-slot="service-launcher-skeleton-icon"] {
|
|
605
|
+
width: var(--card-service-launcher-icon-size);
|
|
606
|
+
height: var(--card-service-launcher-icon-size);
|
|
607
|
+
flex: none;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
[data-slot="service-launcher-skeleton-title"] {
|
|
611
|
+
width: var(--card-service-launcher-skeleton-title-width);
|
|
612
|
+
height: var(--font-size-base);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
[data-slot="service-launcher-skeleton-status"] {
|
|
616
|
+
width: var(--card-service-launcher-skeleton-status-width);
|
|
617
|
+
height: var(--font-size-xs);
|
|
618
|
+
margin-inline-start: auto;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
[data-slot="service-launcher-skeleton-description"],
|
|
622
|
+
[data-slot="service-launcher-skeleton-metadata"],
|
|
623
|
+
[data-slot="service-launcher-skeleton-action"] {
|
|
624
|
+
width: 100%;
|
|
625
|
+
height: var(--font-size-xs);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
[data-slot="service-launcher-skeleton-action"] {
|
|
629
|
+
height: var(--control-height);
|
|
630
|
+
}
|
|
477
631
|
}
|
|
@@ -37,3 +37,100 @@
|
|
|
37
37
|
color: hsl(var(--popover-foreground));
|
|
38
38
|
font-size: var(--font-size-xs);
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
/* Content that sits BELOW the plot (the activity footer slot) — outside the
|
|
42
|
+
* `role="img"` canvas so links/buttons in it stay reachable and announced. */
|
|
43
|
+
.ui-chart-footer {
|
|
44
|
+
margin-block-start: var(--chart-trend-footer-gap);
|
|
45
|
+
font-size: var(--font-size-xs);
|
|
46
|
+
color: hsl(var(--muted-foreground));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* ─────────────────────────────────────────────────────────────────────────────
|
|
50
|
+
* CompactBarTrend — a dependency-free (no recharts) vertical bar trend.
|
|
51
|
+
* ALL geometry resolves from `--chart-trend-*` tokens; the only inline value is
|
|
52
|
+
* the DATUM itself (`--chart-trend-bar-value`, a 0..1 ratio), so a consumer never
|
|
53
|
+
* writes a height calculation or a colour of its own.
|
|
54
|
+
* ─────────────────────────────────────────────────────────────────────────── */
|
|
55
|
+
|
|
56
|
+
/* `size` → the active plot-height tier. Set on the <figure> as `data-size`. */
|
|
57
|
+
.ui-chart-trend[data-size="xs"] {
|
|
58
|
+
--chart-trend-plot-height: var(--chart-trend-plot-height-xs);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.ui-chart-trend[data-size="sm"] {
|
|
62
|
+
--chart-trend-plot-height: var(--chart-trend-plot-height-sm);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.ui-chart-trend[data-size="md"] {
|
|
66
|
+
--chart-trend-plot-height: var(--chart-trend-plot-height-md);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.ui-chart-trend[data-size="lg"] {
|
|
70
|
+
--chart-trend-plot-height: var(--chart-trend-plot-height-lg);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.ui-chart-trend-body {
|
|
74
|
+
display: flex;
|
|
75
|
+
flex-direction: column;
|
|
76
|
+
gap: var(--chart-trend-tick-gap);
|
|
77
|
+
inline-size: 100%;
|
|
78
|
+
min-inline-size: 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.ui-chart-trend-plot {
|
|
82
|
+
display: flex;
|
|
83
|
+
align-items: flex-end;
|
|
84
|
+
gap: var(--chart-trend-bar-gap);
|
|
85
|
+
block-size: var(--chart-trend-plot-height);
|
|
86
|
+
inline-size: 100%;
|
|
87
|
+
min-inline-size: 0;
|
|
88
|
+
/* Quiet by default (rule #44) — a service opts into a baseline rule with
|
|
89
|
+
* `--chart-trend-baseline-border: 1px solid hsl(var(--border));`. */
|
|
90
|
+
border-block-end: var(--chart-trend-baseline-border, none);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.ui-chart-trend-column {
|
|
94
|
+
display: flex;
|
|
95
|
+
flex: 1 1 0;
|
|
96
|
+
align-items: flex-end;
|
|
97
|
+
justify-content: center;
|
|
98
|
+
min-inline-size: 0;
|
|
99
|
+
block-size: 100%;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.ui-chart-trend-bar {
|
|
103
|
+
inline-size: 100%;
|
|
104
|
+
max-inline-size: var(--chart-trend-bar-max-width);
|
|
105
|
+
/* Data-driven: the 0..1 ratio arrives as an inline custom property. */
|
|
106
|
+
block-size: max(var(--chart-trend-bar-min-height), calc(var(--chart-trend-bar-value, 0) * 100%));
|
|
107
|
+
border-start-start-radius: var(--chart-trend-bar-radius);
|
|
108
|
+
border-start-end-radius: var(--chart-trend-bar-radius);
|
|
109
|
+
background: var(
|
|
110
|
+
--chart-trend-bar-background,
|
|
111
|
+
hsl(var(--muted-foreground) / var(--chart-trend-bar-background-alpha))
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.ui-chart-trend-bar[data-emphasized="true"] {
|
|
116
|
+
background: var(--chart-trend-bar-emphasis-background, hsl(var(--primary)));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.ui-chart-trend-ticks {
|
|
120
|
+
display: flex;
|
|
121
|
+
gap: var(--chart-trend-bar-gap);
|
|
122
|
+
inline-size: 100%;
|
|
123
|
+
min-inline-size: 0;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.ui-chart-trend-tick {
|
|
127
|
+
flex: 1 1 0;
|
|
128
|
+
min-inline-size: 0;
|
|
129
|
+
overflow: hidden;
|
|
130
|
+
font-size: var(--chart-trend-tick-font-size);
|
|
131
|
+
line-height: var(--line-height-tight);
|
|
132
|
+
color: hsl(var(--muted-foreground));
|
|
133
|
+
text-align: center;
|
|
134
|
+
text-overflow: ellipsis;
|
|
135
|
+
white-space: nowrap;
|
|
136
|
+
}
|
package/dist/styles/control.css
CHANGED
|
@@ -585,6 +585,52 @@
|
|
|
585
585
|
opacity: 0.5;
|
|
586
586
|
}
|
|
587
587
|
|
|
588
|
+
[data-slot="dialog-content"].ui-command-palette {
|
|
589
|
+
top: var(--command-palette-inset-top);
|
|
590
|
+
width: min(
|
|
591
|
+
var(--command-palette-width),
|
|
592
|
+
calc(100vw - (2 * var(--command-palette-viewport-inset)))
|
|
593
|
+
);
|
|
594
|
+
max-width: none;
|
|
595
|
+
transform: translateX(-50%);
|
|
596
|
+
gap: 0;
|
|
597
|
+
padding: 0;
|
|
598
|
+
background: hsl(var(--popover));
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
.ui-command-palette-trigger {
|
|
602
|
+
min-width: 0;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
.ui-command-palette-label {
|
|
606
|
+
min-width: 0;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
.ui-command-palette-meta {
|
|
610
|
+
margin-inline-start: auto;
|
|
611
|
+
color: hsl(var(--muted-foreground));
|
|
612
|
+
font-size: var(--font-size-xs);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
.ui-command-palette-state {
|
|
616
|
+
padding-block: var(--space-6);
|
|
617
|
+
padding-inline: var(--space-4);
|
|
618
|
+
text-align: center;
|
|
619
|
+
color: hsl(var(--muted-foreground));
|
|
620
|
+
font-size: var(--font-size-base);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
.ui-command-palette-hints {
|
|
624
|
+
display: flex;
|
|
625
|
+
flex-wrap: wrap;
|
|
626
|
+
gap: var(--command-palette-hint-gap);
|
|
627
|
+
border-top: 1px solid hsl(var(--border));
|
|
628
|
+
padding: var(--command-palette-hint-padding-y) var(--command-palette-hint-padding-x);
|
|
629
|
+
color: hsl(var(--muted-foreground));
|
|
630
|
+
font-family: var(--font-mono);
|
|
631
|
+
font-size: var(--font-size-xs);
|
|
632
|
+
}
|
|
633
|
+
|
|
588
634
|
.ui-search-input {
|
|
589
635
|
position: relative;
|
|
590
636
|
}
|
|
@@ -680,8 +726,8 @@
|
|
|
680
726
|
.ui-otp-slot {
|
|
681
727
|
position: relative;
|
|
682
728
|
display: flex;
|
|
683
|
-
width: var(--control-height);
|
|
684
|
-
height: var(--control-height);
|
|
729
|
+
width: var(--otp-slot-size, var(--control-height));
|
|
730
|
+
height: var(--otp-slot-size, var(--control-height));
|
|
685
731
|
align-items: center;
|
|
686
732
|
justify-content: center;
|
|
687
733
|
font-size: var(--font-size-base);
|
|
@@ -449,14 +449,27 @@
|
|
|
449
449
|
}
|
|
450
450
|
|
|
451
451
|
@layer components {
|
|
452
|
-
/* ListRow — single-line entity row (leading · title/description · trailing) for
|
|
453
|
-
* inside a flush CardContent. Rows separate with a quiet divider; the last row
|
|
454
|
-
* Card border to close the list. Logical properties throughout (RTL-safe).
|
|
452
|
+
/* ListRow — single-line entity row (indicator · leading · title/description · trailing) for
|
|
453
|
+
* short lists inside a flush CardContent. Rows separate with a quiet divider; the last row
|
|
454
|
+
* leaves the Card border to close the list. Logical properties throughout (RTL-safe).
|
|
455
|
+
*
|
|
456
|
+
* Overflow contract (#224): the row itself may shrink (min-inline-size: 0) and WRAPS, the
|
|
457
|
+
* content column keeps only `min(--list-row-body-min-width, 100%)` — so it can always shrink
|
|
458
|
+
* below its intrinsic width and truncate/wrap — and the trailing actions wrap onto their own
|
|
459
|
+
* line instead of pushing the row (and the page root) wider than the viewport. */
|
|
455
460
|
[data-slot="list-row"] {
|
|
456
461
|
display: flex;
|
|
462
|
+
min-inline-size: 0;
|
|
463
|
+
flex-wrap: wrap;
|
|
457
464
|
align-items: center;
|
|
458
465
|
gap: var(--list-row-gap);
|
|
459
466
|
padding: var(--list-row-padding-y) var(--list-row-padding-x);
|
|
467
|
+
background: var(--list-row-read-background, transparent);
|
|
468
|
+
}
|
|
469
|
+
/* Unread emphasis surface — paired with the indicator dot + its sr-only text, never colour
|
|
470
|
+
* alone (WCAG 1.4.1). */
|
|
471
|
+
[data-slot="list-row"][data-unread] {
|
|
472
|
+
background: var(--list-row-unread-background, hsl(var(--muted)));
|
|
460
473
|
}
|
|
461
474
|
[data-slot="list-row"][data-align="start"] {
|
|
462
475
|
align-items: flex-start;
|
|
@@ -464,6 +477,19 @@
|
|
|
464
477
|
[data-slot="list-row"]:not(:last-child) {
|
|
465
478
|
border-block-end: var(--list-row-border, 1px solid hsl(var(--border)));
|
|
466
479
|
}
|
|
480
|
+
[data-slot="list-row-indicator"] {
|
|
481
|
+
position: relative;
|
|
482
|
+
display: block;
|
|
483
|
+
flex-shrink: 0;
|
|
484
|
+
inline-size: var(--list-row-indicator-size);
|
|
485
|
+
block-size: var(--list-row-indicator-size);
|
|
486
|
+
border-radius: var(--radius-pill);
|
|
487
|
+
/* Read rows keep the gutter (titles stay on one optical axis) but paint nothing. */
|
|
488
|
+
background: transparent;
|
|
489
|
+
}
|
|
490
|
+
[data-slot="list-row"][data-unread] [data-slot="list-row-indicator"] {
|
|
491
|
+
background: hsl(var(--list-row-indicator-color, var(--primary)));
|
|
492
|
+
}
|
|
467
493
|
[data-slot="list-row-leading"] {
|
|
468
494
|
display: inline-flex;
|
|
469
495
|
flex-shrink: 0;
|
|
@@ -473,18 +499,38 @@
|
|
|
473
499
|
}
|
|
474
500
|
[data-slot="list-row-body"] {
|
|
475
501
|
display: flex;
|
|
476
|
-
min-
|
|
477
|
-
flex: 1 1
|
|
502
|
+
min-inline-size: min(var(--list-row-body-min-width, 12rem), 100%);
|
|
503
|
+
flex: 1 1 var(--list-row-body-min-width, 12rem);
|
|
478
504
|
flex-direction: column;
|
|
479
505
|
}
|
|
506
|
+
/* `overflow="wrap"` — the title/description wrap instead of truncating; `anywhere` also lowers
|
|
507
|
+
* the min-content width so an unbroken token (URL, long JA/VI compound) can't widen the row. */
|
|
508
|
+
[data-slot="list-row"][data-overflow="wrap"] [data-slot="list-row-body"] {
|
|
509
|
+
overflow-wrap: anywhere;
|
|
510
|
+
}
|
|
480
511
|
[data-slot="list-row-trailing"] {
|
|
481
512
|
display: inline-flex;
|
|
513
|
+
max-inline-size: 100%;
|
|
482
514
|
flex-shrink: 0;
|
|
515
|
+
flex-wrap: wrap;
|
|
483
516
|
align-items: center;
|
|
484
|
-
|
|
517
|
+
justify-content: flex-end;
|
|
518
|
+
gap: var(--list-row-trailing-gap, var(--space-2));
|
|
485
519
|
margin-inline-start: auto;
|
|
486
520
|
}
|
|
487
521
|
|
|
522
|
+
@media (max-width: 359px) {
|
|
523
|
+
[data-slot="list-row"] {
|
|
524
|
+
flex-wrap: wrap;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
[data-slot="list-row-trailing"] {
|
|
528
|
+
width: 100%;
|
|
529
|
+
flex-wrap: wrap;
|
|
530
|
+
justify-content: flex-end;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
488
534
|
/* CredentialReveal — one-time secret surface: caution banner, masked/revealed value row with
|
|
489
535
|
* copy/reveal/download actions, and an optional acknowledge footer. Density-aware via the
|
|
490
536
|
* --control-height tier; colours/spacing read semantic role tokens only. */
|
|
@@ -21,9 +21,22 @@
|
|
|
21
21
|
border-top: 1px solid hsl(var(--border));
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
/* Scrim = a SHARE of the ONE shared semantic scrim (--overlay-background), resolved here at the
|
|
25
|
+
* call site so a scoped [data-tenant]/.dark override of --overlay-background actually reaches the
|
|
26
|
+
* portaled overlay (docs/TOKENS.md · "Role-mirror knobs MUST be `initial`"). Setting
|
|
27
|
+
* --dialog-overlay-background / --sheet-overlay-background still wins outright. */
|
|
28
|
+
.ui-dialog-overlay {
|
|
29
|
+
background-color: var(
|
|
30
|
+
--dialog-overlay-background,
|
|
31
|
+
color-mix(in srgb, var(--overlay-background) var(--dialog-overlay-alpha), transparent)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
25
35
|
[data-slot="sheet-overlay"] {
|
|
26
|
-
background-color: var(
|
|
36
|
+
background-color: var(
|
|
37
|
+
--sheet-overlay-background,
|
|
38
|
+
color-mix(in srgb, var(--overlay-background) var(--sheet-overlay-alpha), transparent)
|
|
39
|
+
);
|
|
27
40
|
}
|
|
28
41
|
|
|
29
42
|
.ui-dialog-overlay {
|
|
@@ -38,8 +51,8 @@
|
|
|
38
51
|
top: 50%;
|
|
39
52
|
z-index: 50;
|
|
40
53
|
display: grid;
|
|
41
|
-
width: 100
|
|
42
|
-
max-width:
|
|
54
|
+
width: min(var(--dialog-width-default), calc(100% - var(--dialog-viewport-inset)));
|
|
55
|
+
max-width: none;
|
|
43
56
|
transform: translate(-50%, -50%);
|
|
44
57
|
gap: var(--dialog-space-gap);
|
|
45
58
|
border: 1px solid hsl(var(--border));
|
|
@@ -133,7 +146,95 @@
|
|
|
133
146
|
color: hsl(var(--muted-foreground));
|
|
134
147
|
}
|
|
135
148
|
|
|
149
|
+
.ui-two-factor-setup {
|
|
150
|
+
width: calc(100% - 1.5rem);
|
|
151
|
+
max-width: 27.5rem;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* No scrim override here: the two-factor dialog's backdrop is the SHARED overlay scrim
|
|
155
|
+
* (.ui-dialog-overlay above). The old literal `rgb(0 0 0 / 0.3)` re-stated the dialog default at a
|
|
156
|
+
* higher specificity and silently opted this one dialog out of --overlay-background theming. */
|
|
157
|
+
|
|
158
|
+
.ui-two-factor-setup-enrollment,
|
|
159
|
+
.ui-two-factor-setup-recovery {
|
|
160
|
+
display: flex;
|
|
161
|
+
flex-direction: column;
|
|
162
|
+
gap: var(--space-stack-md);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.ui-two-factor-setup-grid {
|
|
166
|
+
display: grid;
|
|
167
|
+
grid-template-columns: 7.5rem minmax(0, 1fr);
|
|
168
|
+
align-items: center;
|
|
169
|
+
gap: var(--space-4);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.ui-two-factor-setup-grid .ui-qr-code[data-size] {
|
|
173
|
+
inline-size: 7.5rem;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.ui-two-factor-setup-fields,
|
|
177
|
+
.ui-two-factor-setup-code {
|
|
178
|
+
display: flex;
|
|
179
|
+
min-width: 0;
|
|
180
|
+
flex-direction: column;
|
|
181
|
+
gap: var(--space-stack-xs);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.ui-two-factor-setup-notice {
|
|
185
|
+
border: 1px dashed hsl(var(--border));
|
|
186
|
+
border-radius: var(--radius-md);
|
|
187
|
+
padding: var(--space-2) var(--space-3);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.ui-two-factor-setup-recovery-codes {
|
|
191
|
+
display: grid;
|
|
192
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
193
|
+
gap: var(--space-2);
|
|
194
|
+
padding: var(--space-3);
|
|
195
|
+
border: 1px solid hsl(var(--border));
|
|
196
|
+
border-radius: var(--radius-md);
|
|
197
|
+
background: hsl(var(--muted) / 0.4);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
@media (max-width: 479px) {
|
|
201
|
+
.ui-two-factor-setup-grid {
|
|
202
|
+
grid-template-columns: 1fr;
|
|
203
|
+
justify-items: center;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.ui-two-factor-setup-fields {
|
|
207
|
+
width: 100%;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
136
211
|
[data-slot="dialog-header"]:not([data-tone="default"]) [data-slot="dialog-description"] {
|
|
137
212
|
color: hsl(var(--foreground));
|
|
138
213
|
}
|
|
139
214
|
}
|
|
215
|
+
|
|
216
|
+
/*
|
|
217
|
+
* REDUCED MOTION — every overlay enter/exit animation is gated (WCAG 2.3.3 Animation from
|
|
218
|
+
* Interactions / 2.2.2 Pause-Stop-Hide). Dialog, AlertDialog, CommandPalette (a Dialog), Sheet /
|
|
219
|
+
* mobile drawer and Popover all animate via Tailwind `data-[state]:animate-in|animate-out`
|
|
220
|
+
* utilities plus a `transition`; the content additionally zooms/slides, which is exactly the
|
|
221
|
+
* vestibular trigger the media query exists for. The overlay still fades in/out INSTANTLY, so the
|
|
222
|
+
* open/closed state is never ambiguous — only the motion is removed, never the affordance.
|
|
223
|
+
*
|
|
224
|
+
* DELIBERATELY UNLAYERED. Tailwind v4 emits `animate-in` / `slide-in-from-*` into `@layer
|
|
225
|
+
* utilities`, which beats ANY rule inside `@layer components` regardless of specificity — a gate
|
|
226
|
+
* written inside the components layer above would be dead code. Unlayered author declarations win
|
|
227
|
+
* over every layered one, so this block (and only this block) actually stops the animation.
|
|
228
|
+
*/
|
|
229
|
+
@media (prefers-reduced-motion: reduce) {
|
|
230
|
+
[data-slot="dialog-overlay"],
|
|
231
|
+
[data-slot="dialog-content"],
|
|
232
|
+
[data-slot="sheet-overlay"],
|
|
233
|
+
[data-slot="sheet-content"],
|
|
234
|
+
[data-slot="popover-content"],
|
|
235
|
+
.ui-dialog-overlay,
|
|
236
|
+
.ui-command-palette {
|
|
237
|
+
animation: none;
|
|
238
|
+
transition: none;
|
|
239
|
+
}
|
|
240
|
+
}
|
package/dist/styles/fonts.css
CHANGED
|
@@ -7,10 +7,21 @@
|
|
|
7
7
|
* Vietnamese glyph coverage used by the product locales.
|
|
8
8
|
* · Noto Sans JP — retained as the CJK fallback after M PLUS 2.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* IMPORT ORDER IS LOAD-BEARING — this file MUST be imported AFTER
|
|
11
|
+
* `@godxjp/ui/styles/base`:
|
|
12
|
+
*
|
|
13
|
+
* @import "@godxjp/ui/styles/base"; /· tokens: --font-sans-base = system stack ·/
|
|
14
|
+
* @import "@godxjp/ui/styles/fonts"; /· THEN the bundled faces overwrite it ·/
|
|
15
|
+
*
|
|
16
|
+
* The token fills below and foundation.css's font-agnostic default both target
|
|
17
|
+
* `:root` at identical specificity (0,1,0), so whichever is parsed LAST wins.
|
|
18
|
+
* Imported first, this file is silently dead — the system stack renders and the
|
|
19
|
+
* ~800 KB of @font-face is downloaded for nothing (issue #210).
|
|
20
|
+
*
|
|
21
|
+
* The all-in-one `@godxjp/ui/styles` entry pulls this in automatically, in the
|
|
22
|
+
* correct position. If you manage fonts yourself (e.g. next/font), DON'T import
|
|
23
|
+
* this — import `@godxjp/ui/styles/base` + the layout layers you use and supply
|
|
24
|
+
* your own faces via the --font-family-* tokens.
|
|
14
25
|
* ───────────────────────────────────────────────────────────────────────── */
|
|
15
26
|
@import "@fontsource/m-plus-2/400.css";
|
|
16
27
|
@import "@fontsource/m-plus-2/500.css";
|
package/dist/styles/index.css
CHANGED
|
@@ -7,13 +7,21 @@
|
|
|
7
7
|
* @import "@godxjp/ui/styles/control"; // + only the layout layers you use
|
|
8
8
|
* @import "@godxjp/ui/styles/dialog-layout";
|
|
9
9
|
* ...
|
|
10
|
-
* and add `@godxjp/ui/styles/fonts`
|
|
11
|
-
* See src/styles/base.css for the full list and rules.
|
|
10
|
+
* and add `@godxjp/ui/styles/fonts` AFTER `styles/base` if you want the bundled
|
|
11
|
+
* faces. See src/styles/base.css for the full list and rules.
|
|
12
|
+
*
|
|
13
|
+
* ORDER IS LOAD-BEARING — `fonts.css` MUST come AFTER `base.css`.
|
|
14
|
+
* `base.css` pulls in `tokens/base.css` → `tokens/foundation.css`, which declares
|
|
15
|
+
* the font-agnostic `:root { --font-sans-base: <system stack> }` default. Both
|
|
16
|
+
* declarations sit on `:root` at identical specificity (0,1,0), so the LATER one
|
|
17
|
+
* wins. With `fonts.css` first the bundled faces could never apply and every
|
|
18
|
+
* consumer downloaded ~800 KB of dead @font-face (issue #210).
|
|
12
19
|
* ───────────────────────────────────────────────────────────────────────── */
|
|
13
20
|
@import "sonner/dist/styles.css";
|
|
14
21
|
@import "react-day-picker/style.css";
|
|
15
|
-
@import "./fonts.css";
|
|
16
22
|
@import "./base.css";
|
|
23
|
+
/* AFTER the token layers — see the ORDER IS LOAD-BEARING note above. */
|
|
24
|
+
@import "./fonts.css";
|
|
17
25
|
@import "./shell-layout.css";
|
|
18
26
|
@import "./motion.css";
|
|
19
27
|
@import "./layout.css";
|