@godxjp/ui 18.4.0 → 18.6.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.
Files changed (159) hide show
  1. package/README.md +16 -1
  2. package/dist/app/theme-axes.d.ts +11 -3
  3. package/dist/app/theme-axes.js +2 -1
  4. package/dist/components/charts/chart-frame.d.ts +17 -3
  5. package/dist/components/charts/chart-frame.js +7 -1
  6. package/dist/components/charts/chart-summary.d.ts +21 -0
  7. package/dist/components/charts/chart-summary.js +32 -5
  8. package/dist/components/charts/compact-bar-trend.d.ts +30 -0
  9. package/dist/components/charts/compact-bar-trend.js +74 -0
  10. package/dist/components/charts/index.d.ts +6 -0
  11. package/dist/components/charts/index.js +2 -0
  12. package/dist/components/data-display/badge.d.ts +8 -0
  13. package/dist/components/data-display/badge.js +7 -1
  14. package/dist/components/data-display/data-table.d.ts +40 -4
  15. package/dist/components/data-display/data-table.js +69 -2
  16. package/dist/components/data-display/empty-state.js +1 -1
  17. package/dist/components/data-display/index.d.ts +4 -2
  18. package/dist/components/data-display/index.js +10 -1
  19. package/dist/components/data-display/list-row.d.ts +41 -4
  20. package/dist/components/data-display/list-row.js +23 -3
  21. package/dist/components/data-display/qr-code.d.ts +1 -1
  22. package/dist/components/data-display/service-launcher-card.d.ts +40 -0
  23. package/dist/components/data-display/service-launcher-card.js +97 -0
  24. package/dist/components/data-display/table.d.ts +47 -2
  25. package/dist/components/data-display/table.js +29 -4
  26. package/dist/components/data-entry/command-palette.d.ts +37 -0
  27. package/dist/components/data-entry/command-palette.js +125 -0
  28. package/dist/components/data-entry/command.d.ts +10 -10
  29. package/dist/components/data-entry/index.d.ts +3 -0
  30. package/dist/components/data-entry/index.js +2 -0
  31. package/dist/components/data-entry/input-otp.d.ts +1 -0
  32. package/dist/components/feedback/dialog.d.ts +16 -1
  33. package/dist/components/feedback/dialog.js +46 -33
  34. package/dist/components/feedback/index.d.ts +5 -2
  35. package/dist/components/feedback/index.js +8 -2
  36. package/dist/components/feedback/sheet.d.ts +26 -4
  37. package/dist/components/feedback/sheet.js +54 -7
  38. package/dist/components/feedback/two-factor-setup.d.ts +31 -0
  39. package/dist/components/feedback/two-factor-setup.js +97 -0
  40. package/dist/components/general/index.d.ts +1 -1
  41. package/dist/components/general/logo.d.ts +49 -9
  42. package/dist/components/general/logo.js +67 -14
  43. package/dist/components/layout/app-shell.d.ts +1 -1
  44. package/dist/components/layout/app-shell.js +55 -30
  45. package/dist/components/layout/auth-account-summary.d.ts +5 -0
  46. package/dist/components/layout/auth-account-summary.js +31 -0
  47. package/dist/components/layout/auth-divider.d.ts +7 -0
  48. package/dist/components/layout/auth-divider.js +21 -0
  49. package/dist/components/layout/auth-footer.d.ts +5 -0
  50. package/dist/components/layout/auth-footer.js +24 -0
  51. package/dist/components/layout/auth-identity.d.ts +5 -0
  52. package/dist/components/layout/auth-identity.js +17 -0
  53. package/dist/components/layout/auth-shell.d.ts +9 -1
  54. package/dist/components/layout/auth-shell.js +25 -6
  55. package/dist/components/layout/auth-stack.d.ts +4 -0
  56. package/dist/components/layout/auth-stack.js +8 -0
  57. package/dist/components/layout/centered-shell.d.ts +5 -2
  58. package/dist/components/layout/centered-shell.js +29 -19
  59. package/dist/components/layout/error-surface.d.ts +35 -0
  60. package/dist/components/layout/error-surface.js +155 -0
  61. package/dist/components/layout/flex.d.ts +1 -1
  62. package/dist/components/layout/flex.js +4 -0
  63. package/dist/components/layout/index.d.ts +23 -3
  64. package/dist/components/layout/index.js +21 -2
  65. package/dist/components/layout/legal-document-shell.d.ts +34 -0
  66. package/dist/components/layout/legal-document-shell.js +186 -0
  67. package/dist/components/layout/master-detail.d.ts +24 -0
  68. package/dist/components/layout/master-detail.js +48 -0
  69. package/dist/components/layout/org-switcher.d.ts +9 -0
  70. package/dist/components/layout/org-switcher.js +218 -0
  71. package/dist/components/layout/page-container.d.ts +1 -1
  72. package/dist/components/layout/page-container.js +7 -2
  73. package/dist/components/layout/sidebar-link.d.ts +43 -0
  74. package/dist/components/layout/sidebar-link.js +13 -0
  75. package/dist/components/layout/sidebar.d.ts +42 -5
  76. package/dist/components/layout/sidebar.js +170 -85
  77. package/dist/components/navigation/app-setting-picker.js +17 -6
  78. package/dist/components/navigation/filter-bar.d.ts +12 -3
  79. package/dist/components/navigation/filter-bar.js +8 -2
  80. package/dist/components/navigation/index.d.ts +2 -2
  81. package/dist/components/navigation/index.js +3 -1
  82. package/dist/components/navigation/steps.js +38 -19
  83. package/dist/components/navigation/tabs-scroll.d.ts +70 -0
  84. package/dist/components/navigation/tabs-scroll.js +76 -0
  85. package/dist/components/navigation/tabs.js +47 -23
  86. package/dist/components/ui/avatar.d.ts +2 -1
  87. package/dist/components/ui/avatar.js +2 -1
  88. package/dist/components/ui/input-otp.d.ts +4 -1
  89. package/dist/components/ui/input-otp.js +2 -1
  90. package/dist/components/ui/toggle-group.d.ts +7 -4
  91. package/dist/components/ui/toggle-group.js +32 -21
  92. package/dist/email/brand-mark.d.ts +108 -0
  93. package/dist/email/brand-mark.js +88 -0
  94. package/dist/email/color.d.ts +53 -0
  95. package/dist/email/color.js +37 -0
  96. package/dist/email/geometry.d.ts +120 -0
  97. package/dist/email/geometry.js +90 -0
  98. package/dist/email/index.d.ts +83 -0
  99. package/dist/email/index.js +82 -0
  100. package/dist/email/inline-style.d.ts +27 -0
  101. package/dist/email/inline-style.js +26 -0
  102. package/dist/email/tokens.generated.d.ts +167 -0
  103. package/dist/email/tokens.generated.js +162 -0
  104. package/dist/email/urgency.d.ts +22 -0
  105. package/dist/email/urgency.js +14 -0
  106. package/dist/i18n/messages/en.json +36 -3
  107. package/dist/i18n/messages/ja.json +36 -3
  108. package/dist/i18n/messages/vi.json +36 -3
  109. package/dist/inertia/index.d.ts +50 -0
  110. package/dist/inertia/index.js +5 -0
  111. package/dist/props/components/app.prop.d.ts +11 -1
  112. package/dist/props/components/charts.prop.d.ts +40 -1
  113. package/dist/props/components/data-display.prop.d.ts +75 -1
  114. package/dist/props/components/data-entry.prop.d.ts +6 -0
  115. package/dist/props/components/feedback.prop.d.ts +10 -0
  116. package/dist/props/components/index.d.ts +3 -3
  117. package/dist/props/components/layout.prop.d.ts +560 -10
  118. package/dist/props/components/layout.prop.js +1 -0
  119. package/dist/props/components/navigation.prop.d.ts +24 -2
  120. package/dist/props/registry.d.ts +433 -8
  121. package/dist/props/registry.js +527 -9
  122. package/dist/props/vocabulary/data.prop.d.ts +27 -0
  123. package/dist/props/vocabulary/index.d.ts +3 -3
  124. package/dist/props/vocabulary/interaction.prop.d.ts +10 -1
  125. package/dist/props/vocabulary/layout.prop.d.ts +49 -0
  126. package/dist/styles/base.css +8 -2
  127. package/dist/styles/card-layout.css +161 -7
  128. package/dist/styles/chart-layout.css +97 -0
  129. package/dist/styles/control.css +76 -2
  130. package/dist/styles/data-display-layout.css +78 -6
  131. package/dist/styles/dialog-layout.css +105 -4
  132. package/dist/styles/fonts.css +15 -4
  133. package/dist/styles/index.css +11 -3
  134. package/dist/styles/layout.css +466 -1
  135. package/dist/styles/logo-layout.css +95 -0
  136. package/dist/styles/navigation-layout.css +152 -0
  137. package/dist/styles/shell-layout.css +790 -40
  138. package/dist/styles/table-layout.css +164 -1
  139. package/dist/theme/dxs.canonical.css +77 -0
  140. package/dist/tokens/axes.css +40 -0
  141. package/dist/tokens/base.css +6 -0
  142. package/dist/tokens/components/card.css +48 -0
  143. package/dist/tokens/components/chart.css +47 -0
  144. package/dist/tokens/components/control.css +16 -0
  145. package/dist/tokens/components/data-display.css +13 -0
  146. package/dist/tokens/components/email.css +93 -0
  147. package/dist/tokens/components/error-surface.css +36 -0
  148. package/dist/tokens/components/feedback.css +17 -0
  149. package/dist/tokens/components/legal-document.css +67 -0
  150. package/dist/tokens/components/list-row.css +43 -2
  151. package/dist/tokens/components/logo.css +74 -0
  152. package/dist/tokens/components/navigation.css +28 -0
  153. package/dist/tokens/components/sheet.css +19 -0
  154. package/dist/tokens/components/shell.css +210 -0
  155. package/dist/tokens/components/sidebar.css +33 -0
  156. package/dist/tokens/components/table.css +45 -0
  157. package/dist/tokens/foundation.css +31 -2
  158. package/dist/tokens/semantic/layout.css +69 -2
  159. package/package.json +22 -5
@@ -18,6 +18,18 @@
18
18
  font-weight: var(--font-weight-medium);
19
19
  }
20
20
 
21
+ /* Entity-header mark — `<Avatar shape="square">` (gh#249). Opt-in ONLY: without the attribute the
22
+ * avatar above is untouched. Geometry and colour are token-owned (rule #45); the brand fill is
23
+ * handed down through --avatar-background so the fallback slot picks it up with no extra rule,
24
+ * and a service that only wants a neutral square overrides --avatar-square-background. */
25
+ .ui-avatar[data-shape="square"] {
26
+ inline-size: var(--avatar-square-size);
27
+ block-size: var(--avatar-square-size);
28
+ border-radius: var(--avatar-square-radius);
29
+ --avatar-background: var(--avatar-square-background, hsl(var(--primary)));
30
+ color: var(--avatar-square-foreground, hsl(var(--primary-foreground)));
31
+ }
32
+
21
33
  .ui-avatar-image {
22
34
  width: 100%;
23
35
  height: 100%;
@@ -449,14 +461,27 @@
449
461
  }
450
462
 
451
463
  @layer components {
452
- /* ListRow — single-line entity row (leading · title/description · trailing) for short lists
453
- * inside a flush CardContent. Rows separate with a quiet divider; the last row leaves the
454
- * Card border to close the list. Logical properties throughout (RTL-safe). */
464
+ /* ListRow — single-line entity row (indicator · leading · title/description · trailing) for
465
+ * short lists inside a flush CardContent. Rows separate with a quiet divider; the last row
466
+ * leaves the Card border to close the list. Logical properties throughout (RTL-safe).
467
+ *
468
+ * Overflow contract (#224): the row itself may shrink (min-inline-size: 0) and WRAPS, the
469
+ * content column keeps only `min(--list-row-body-min-width, 100%)` — so it can always shrink
470
+ * below its intrinsic width and truncate/wrap — and the trailing actions wrap onto their own
471
+ * line instead of pushing the row (and the page root) wider than the viewport. */
455
472
  [data-slot="list-row"] {
456
473
  display: flex;
474
+ min-inline-size: 0;
475
+ flex-wrap: wrap;
457
476
  align-items: center;
458
477
  gap: var(--list-row-gap);
459
478
  padding: var(--list-row-padding-y) var(--list-row-padding-x);
479
+ background: var(--list-row-read-background, transparent);
480
+ }
481
+ /* Unread emphasis surface — paired with the indicator dot + its sr-only text, never colour
482
+ * alone (WCAG 1.4.1). */
483
+ [data-slot="list-row"][data-unread] {
484
+ background: var(--list-row-unread-background, hsl(var(--muted)));
460
485
  }
461
486
  [data-slot="list-row"][data-align="start"] {
462
487
  align-items: flex-start;
@@ -464,6 +489,19 @@
464
489
  [data-slot="list-row"]:not(:last-child) {
465
490
  border-block-end: var(--list-row-border, 1px solid hsl(var(--border)));
466
491
  }
492
+ [data-slot="list-row-indicator"] {
493
+ position: relative;
494
+ display: block;
495
+ flex-shrink: 0;
496
+ inline-size: var(--list-row-indicator-size);
497
+ block-size: var(--list-row-indicator-size);
498
+ border-radius: var(--radius-pill);
499
+ /* Read rows keep the gutter (titles stay on one optical axis) but paint nothing. */
500
+ background: transparent;
501
+ }
502
+ [data-slot="list-row"][data-unread] [data-slot="list-row-indicator"] {
503
+ background: hsl(var(--list-row-indicator-color, var(--primary)));
504
+ }
467
505
  [data-slot="list-row-leading"] {
468
506
  display: inline-flex;
469
507
  flex-shrink: 0;
@@ -473,18 +511,52 @@
473
511
  }
474
512
  [data-slot="list-row-body"] {
475
513
  display: flex;
476
- min-width: 0;
477
- flex: 1 1 auto;
514
+ min-inline-size: min(var(--list-row-body-min-width, 12rem), 100%);
515
+ flex: 1 1 var(--list-row-body-min-width, 12rem);
478
516
  flex-direction: column;
479
517
  }
518
+ /* `overflow="wrap"` — the title/description wrap instead of truncating; `anywhere` also lowers
519
+ * the min-content width so an unbroken token (URL, long JA/VI compound) can't widen the row. */
520
+ [data-slot="list-row"][data-overflow="wrap"] [data-slot="list-row-body"] {
521
+ overflow-wrap: anywhere;
522
+ }
523
+ /* `density="compact"` (#246) — the compact inline-actions geometry: tighter block padding and
524
+ * column gap plus a LOWER body threshold, so a 36px avatar, the title/description and one or two
525
+ * small trailing Buttons stay inline inside the canonical 326px content column at 390px. It only
526
+ * LOWERS thresholds; the #224 overflow contract above is untouched (the row still wraps, the body
527
+ * is still clamped with min(…, 100%)), so a compact row can never widen the page root. */
528
+ [data-slot="list-row"][data-density="compact"] {
529
+ gap: var(--list-row-compact-gap, var(--space-2));
530
+ padding: var(--list-row-compact-padding-y, var(--space-2))
531
+ var(--list-row-compact-padding-x, var(--list-row-padding-x));
532
+ }
533
+ [data-slot="list-row"][data-density="compact"] [data-slot="list-row-body"] {
534
+ min-inline-size: min(var(--list-row-compact-body-min-width, 6rem), 100%);
535
+ flex-basis: var(--list-row-compact-body-min-width, 6rem);
536
+ }
480
537
  [data-slot="list-row-trailing"] {
481
538
  display: inline-flex;
539
+ max-inline-size: 100%;
482
540
  flex-shrink: 0;
541
+ flex-wrap: wrap;
483
542
  align-items: center;
484
- gap: var(--space-2);
543
+ justify-content: flex-end;
544
+ gap: var(--list-row-trailing-gap, var(--space-2));
485
545
  margin-inline-start: auto;
486
546
  }
487
547
 
548
+ @media (max-width: 359px) {
549
+ [data-slot="list-row"] {
550
+ flex-wrap: wrap;
551
+ }
552
+
553
+ [data-slot="list-row-trailing"] {
554
+ width: 100%;
555
+ flex-wrap: wrap;
556
+ justify-content: flex-end;
557
+ }
558
+ }
559
+
488
560
  /* CredentialReveal — one-time secret surface: caution banner, masked/revealed value row with
489
561
  * copy/reveal/download actions, and an optional acknowledge footer. Density-aware via the
490
562
  * --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
- .ui-dialog-overlay,
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(--overlay-background);
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: 32rem;
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
+ }
@@ -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
- * The all-in-one `@godxjp/ui/styles` entry pulls this in automatically. If you
11
- * manage fonts yourself (e.g. next/font), DON'T import this — import
12
- * `@godxjp/ui/styles/base` + the layout layers you use and supply your own
13
- * faces via the --font-family-* tokens.
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";
@@ -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` only if you want the bundled faces.
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";