@godxjp/ui 16.3.0 → 16.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/dist/app/app-provider.js +1 -0
- package/dist/components/data-display/card.d.ts +5 -1
- package/dist/components/data-display/card.js +4 -2
- package/dist/components/feedback/sheet.js +3 -1
- package/dist/components/navigation/steps.js +2 -2
- package/dist/lib/control-styles.d.ts +7 -5
- package/dist/lib/control-styles.js +4 -4
- package/dist/props/registry.d.ts +1 -1
- package/dist/props/registry.js +1 -1
- package/dist/styles/alert-layout.css +7 -5
- package/dist/styles/card-layout.css +33 -1
- package/dist/styles/control.css +24 -14
- package/dist/styles/data-display-layout.css +15 -12
- package/dist/styles/data-entry-layout.css +2 -2
- package/dist/styles/dialog-layout.css +6 -2
- package/dist/styles/index.css +52 -7
- package/dist/styles/layout.css +3 -0
- package/dist/styles/navigation-layout.css +10 -10
- package/dist/styles/shell-layout.css +17 -6
- package/dist/styles/table-layout.css +5 -5
- package/dist/tokens/foundation.css +70 -8
- package/package.json +10 -8
- package/dist/tokens/components/badge.css +0 -10
- package/dist/tokens/components/card.css +0 -51
- package/dist/tokens/components/control.css +0 -82
- package/dist/tokens/components/data-display.css +0 -8
- package/dist/tokens/components/data-entry.css +0 -6
- package/dist/tokens/components/descriptions.css +0 -9
- package/dist/tokens/components/feedback.css +0 -25
- package/dist/tokens/components/form.css +0 -11
- package/dist/tokens/components/list-row.css +0 -9
- package/dist/tokens/components/navigation.css +0 -15
- package/dist/tokens/components/shell.css +0 -17
- package/dist/tokens/components/table.css +0 -13
- package/dist/tokens/semantic/layout.css +0 -49
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
background: hsl(var(--popover));
|
|
9
9
|
color: hsl(var(--popover-foreground));
|
|
10
10
|
padding: var(--space-1);
|
|
11
|
-
box-shadow: var(--shadow-md);
|
|
11
|
+
box-shadow: var(--shadow-md), var(--shadow-glow);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
.ui-context-menu-item,
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
.ui-menubar-sub-trigger:hover,
|
|
56
56
|
.ui-navigation-menu-link:hover,
|
|
57
57
|
.ui-navigation-menu-item:hover {
|
|
58
|
-
background:
|
|
59
|
-
color:
|
|
58
|
+
background: var(--menubar-item-hover-background);
|
|
59
|
+
color: var(--menubar-item-hover-foreground);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
.ui-context-menu-item[data-state="open"],
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
.ui-menubar-sub-trigger[data-state="open"],
|
|
69
69
|
.ui-navigation-menu-link[data-highlighted],
|
|
70
70
|
.ui-navigation-menu-item[data-focus-visible] {
|
|
71
|
-
background:
|
|
72
|
-
color:
|
|
71
|
+
background: var(--menubar-item-hover-background);
|
|
72
|
+
color: var(--menubar-item-hover-foreground);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
.ui-context-menu-item[data-variant="destructive"],
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
background: hsl(var(--popover));
|
|
147
147
|
color: hsl(var(--popover-foreground));
|
|
148
148
|
padding: var(--space-1);
|
|
149
|
-
box-shadow: var(--shadow-md);
|
|
149
|
+
box-shadow: var(--shadow-md), var(--shadow-glow);
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
.ui-context-menu-sub-trigger-icon,
|
|
@@ -179,13 +179,13 @@
|
|
|
179
179
|
background: hsl(var(--popover));
|
|
180
180
|
color: hsl(var(--popover-foreground));
|
|
181
181
|
padding: var(--space-1);
|
|
182
|
-
box-shadow: var(--shadow-md);
|
|
182
|
+
box-shadow: var(--shadow-md), var(--shadow-glow);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
.ui-menubar-trigger[data-state="open"],
|
|
186
186
|
.ui-menubar-sub-trigger[data-state="open"] {
|
|
187
|
-
background:
|
|
188
|
-
color:
|
|
187
|
+
background: var(--menubar-item-hover-background);
|
|
188
|
+
color: var(--menubar-item-hover-foreground);
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
.ui-navigation-menu {
|
|
@@ -233,7 +233,7 @@
|
|
|
233
233
|
background: hsl(var(--popover));
|
|
234
234
|
color: hsl(var(--popover-foreground));
|
|
235
235
|
padding: var(--space-1);
|
|
236
|
-
box-shadow: var(--shadow-md);
|
|
236
|
+
box-shadow: var(--shadow-md), var(--shadow-glow);
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
.ui-navigation-menu-link {
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
overflow: hidden;
|
|
31
31
|
border-inline-end: 1px solid hsl(var(--border));
|
|
32
32
|
background: hsl(var(--card));
|
|
33
|
+
/* Opt-in brand-chrome wash — invisible by default (--sidebar-gradient: none). */
|
|
34
|
+
background-image: var(--sidebar-gradient);
|
|
33
35
|
color: hsl(var(--foreground));
|
|
34
36
|
}
|
|
35
37
|
|
|
@@ -45,6 +47,8 @@
|
|
|
45
47
|
padding-inline: var(--space-4);
|
|
46
48
|
border-bottom: 1px solid hsl(var(--border));
|
|
47
49
|
background: hsl(var(--background) / 0.92);
|
|
50
|
+
/* Opt-in brand-chrome wash — invisible by default (--topbar-gradient: none). */
|
|
51
|
+
background-image: var(--topbar-gradient);
|
|
48
52
|
backdrop-filter: blur(12px);
|
|
49
53
|
}
|
|
50
54
|
|
|
@@ -52,6 +56,9 @@
|
|
|
52
56
|
grid-area: main;
|
|
53
57
|
min-width: 0;
|
|
54
58
|
overflow: auto;
|
|
59
|
+
/* Ambient brand glow hook — invisible by default (--gradient-glow: none); a service paints a
|
|
60
|
+
* radial/linear brand wash behind the whole content area by configuring the token alone. */
|
|
61
|
+
background-image: var(--gradient-glow);
|
|
55
62
|
/* Sole scroll/clip boundary for the page area. `overflow:auto` alone does NOT reliably
|
|
56
63
|
* establish a paint-containment boundary in Chrome: tall nested scrollers (a two-pane
|
|
57
64
|
* `grid` of long lists, a nested `overflow-y:auto` region) — or any absolutely-positioned
|
|
@@ -254,13 +261,17 @@
|
|
|
254
261
|
text-align: start;
|
|
255
262
|
}
|
|
256
263
|
|
|
257
|
-
.sb-nav-item:hover
|
|
258
|
-
.sb-nav-item[data-active="true"] {
|
|
264
|
+
.sb-nav-item:hover {
|
|
259
265
|
background: hsl(var(--accent));
|
|
260
266
|
color: hsl(var(--foreground));
|
|
261
267
|
}
|
|
262
268
|
|
|
269
|
+
/* Active item reads its own bg/fg tokens (defaults = the hover look) so a service can give the
|
|
270
|
+
* selected nav row a brand treatment — e.g. a gold tint + gold text on a navy sidebar — without
|
|
271
|
+
* forking CSS. Defaults are byte-identical to the hover state. */
|
|
263
272
|
.sb-nav-item[data-active="true"] {
|
|
273
|
+
background: var(--sidebar-item-active-background);
|
|
274
|
+
color: var(--sidebar-item-active-foreground);
|
|
264
275
|
font-weight: var(--font-weight-medium);
|
|
265
276
|
}
|
|
266
277
|
|
|
@@ -351,12 +362,12 @@
|
|
|
351
362
|
|
|
352
363
|
.sb-nav-item--sub[data-active="true"] {
|
|
353
364
|
background: transparent;
|
|
354
|
-
color:
|
|
365
|
+
color: var(--sidebar-item-active-color);
|
|
355
366
|
font-weight: 500;
|
|
356
367
|
}
|
|
357
368
|
|
|
358
369
|
.sb-nav-item--sub[data-active="true"]::before {
|
|
359
|
-
background:
|
|
370
|
+
background: var(--sidebar-item-active-tint);
|
|
360
371
|
opacity: 1;
|
|
361
372
|
}
|
|
362
373
|
|
|
@@ -406,7 +417,7 @@
|
|
|
406
417
|
}
|
|
407
418
|
|
|
408
419
|
.sb-user:focus-visible {
|
|
409
|
-
box-shadow: 0 0 0 var(--
|
|
420
|
+
box-shadow: 0 0 0 var(--focus-ring-width) hsl(var(--focus-ring-color) / 0.45);
|
|
410
421
|
}
|
|
411
422
|
|
|
412
423
|
.sb-user-avatar {
|
|
@@ -649,7 +660,7 @@
|
|
|
649
660
|
}
|
|
650
661
|
|
|
651
662
|
.tb-icon-btn:focus-visible {
|
|
652
|
-
box-shadow: 0 0 0 var(--
|
|
663
|
+
box-shadow: 0 0 0 var(--focus-ring-width) hsl(var(--focus-ring-color) / 0.45);
|
|
653
664
|
}
|
|
654
665
|
|
|
655
666
|
.tb-bell {
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
padding: var(--table-cell-padding-y) var(--table-cell-space-x);
|
|
9
9
|
text-align: start;
|
|
10
10
|
vertical-align: middle;
|
|
11
|
-
background:
|
|
11
|
+
background: var(--table-header-background);
|
|
12
12
|
font-size: var(--table-head-font-size);
|
|
13
13
|
font-weight: var(--font-weight-medium);
|
|
14
|
-
color:
|
|
14
|
+
color: var(--table-header-foreground);
|
|
15
15
|
white-space: nowrap;
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
/* Zebra striping (opt-in via the `striped` prop). Selected rows keep their
|
|
98
98
|
* own emphasis, so they are excluded from the stripe. */
|
|
99
99
|
.ui-data-table-surface[data-striped] tbody tr:nth-child(even):not([data-state="selected"]) {
|
|
100
|
-
background-color:
|
|
100
|
+
background-color: var(--table-row-striped-background);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
/* Empty-state cell hosts the built-in EmptyState (which brings its own padding). */
|
|
@@ -195,10 +195,10 @@
|
|
|
195
195
|
/* Mirror the row's hover / selected tint — a translucent muted wash layered
|
|
196
196
|
* over the opaque base, so the pinned cell matches the rest of its row. */
|
|
197
197
|
.ui-data-table-surface tbody tr:hover > .ui-data-table-pin-end {
|
|
198
|
-
background-image: linear-gradient(
|
|
198
|
+
background-image: linear-gradient(var(--table-row-hover-background), var(--table-row-hover-background));
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
.ui-data-table-surface tbody tr[data-state="selected"] > .ui-data-table-pin-end {
|
|
202
|
-
background-image: linear-gradient(
|
|
202
|
+
background-image: linear-gradient(var(--table-row-selected-background), var(--table-row-selected-background));
|
|
203
203
|
}
|
|
204
204
|
}
|
|
@@ -37,6 +37,13 @@
|
|
|
37
37
|
--text-disabled: 40 6% 68%; /* disabled control text */
|
|
38
38
|
--text-link: 204 100% 39%; /* inline link — defaults to brand blue */
|
|
39
39
|
--text-brand: 204 100% 39%; /* brand-colored text / numerals */
|
|
40
|
+
/* Status TEXT colours — darker than the fill roles so small coloured text (a StatCard delta, an
|
|
41
|
+
* outline status badge label) clears WCAG AA 4.5:1 on white. The fill roles (--success/--warning/
|
|
42
|
+
* --info) stay the brighter wa-iro for badges/bars; only TEXT reads these via text-*-strong. */
|
|
43
|
+
--text-success: 152 84% 22%; /* deep 若竹 — AA green text on white */
|
|
44
|
+
--text-warning: 36 100% 28%; /* dark 山吹 amber — yellow can never pass as text */
|
|
45
|
+
--text-info: 221 70% 38%; /* deep 群青 — AA blue text on white */
|
|
46
|
+
--text-error: 357 75% 38%; /* deep 茜 — AA red text on white */
|
|
40
47
|
|
|
41
48
|
/* Interaction ramp — hover / active steps (services override to their own brand ramp). */
|
|
42
49
|
--primary-hover: 204 100% 33%;
|
|
@@ -93,18 +100,51 @@
|
|
|
93
100
|
0 20px 25px -5px rgb(var(--shadow-color) / 0.1), 0 8px 10px -6px rgb(var(--shadow-color) / 0.1);
|
|
94
101
|
--shadow-2xl: 0 25px 50px -12px rgb(var(--shadow-color) / 0.25);
|
|
95
102
|
|
|
103
|
+
/* Brand GLOW — an opt-in coloured halo for the primary CTA (and any surface that opts in).
|
|
104
|
+
* Quiet by default (cardinal rule #44): a zero-size transparent shadow, which is invalid as a
|
|
105
|
+
* bare `none` inside a comma shadow list but valid as `0 0 0 0 transparent`. A service turns it
|
|
106
|
+
* on by overriding the whole value once, e.g. `--shadow-glow: 0 8px 20px hsl(var(--primary) / .32)`
|
|
107
|
+
* — the CTA then carries a brand glow with no component change. */
|
|
108
|
+
--shadow-glow: 0 0 0 0 transparent;
|
|
109
|
+
|
|
110
|
+
/* FOCUS RING — the two global knobs for the keyboard-focus affordance (WCAG 2.4.7 / 2.4.11).
|
|
111
|
+
* `--focus-ring-color` is the themeable hue (HSL components, defaults to --ring) and
|
|
112
|
+
* `--focus-ring-width` the standard thickness; override either ONCE — even scoped under a
|
|
113
|
+
* `[data-tenant]` — to retint or resize EVERY focus ring. Both are leaf tokens (a colour and a
|
|
114
|
+
* length, no nested var) so they re-resolve at the element that paints the ring; every
|
|
115
|
+
* :focus-visible rule reads them DIRECTLY as `0 0 0 var(--focus-ring-width)
|
|
116
|
+
* hsl(var(--focus-ring-color))`, never via an intermediate composite (a `:root`-declared
|
|
117
|
+
* composite that wraps these would freeze at :root and ignore a scoped override). */
|
|
118
|
+
--focus-ring-color: var(--ring);
|
|
119
|
+
--focus-ring-width: 2px;
|
|
120
|
+
|
|
121
|
+
/* GRADIENTS — opt-in decorative fills exposed at the token layer so a service can paint a hero
|
|
122
|
+
* banner, a brand wash, or a radial brand glow purely by configuring tokens (cardinal rule #45).
|
|
123
|
+
* All default to a transparent no-op so nothing renders until a theme opts in; a surface that
|
|
124
|
+
* supports a gradient reads one of these as its background-image. Examples a service might set:
|
|
125
|
+
* --gradient-brand: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
|
|
126
|
+
* --gradient-hero: linear-gradient(180deg, hsl(var(--secondary)), hsl(var(--background)));
|
|
127
|
+
* --gradient-glow: radial-gradient(60% 80% at 50% 0%, hsl(var(--primary) / .25), transparent); */
|
|
128
|
+
--gradient-brand: none;
|
|
129
|
+
--gradient-hero: none;
|
|
130
|
+
--gradient-glow: none;
|
|
131
|
+
|
|
96
132
|
/* Sans stack — script-aware per the international convention for mixed
|
|
97
133
|
* Latin/CJK UI: native Latin system fonts FIRST (clean, familiar English &
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* tuned to harmonise with kana, not for standalone English — made English read
|
|
103
|
-
* oddly; Latin-first fixes that without losing the bundled JP face. */
|
|
134
|
+
* DEFAULT face is the bundled "Noto Sans JP" (Japanese + clean Latin), with system sans as
|
|
135
|
+
* the network/loading fallback. The Vietnamese locale swaps this token to Montserrat via
|
|
136
|
+
* `:root:lang(vi)` in styles/index.css (set by AppProvider's <html lang>). Browsers resolve
|
|
137
|
+
* fonts per-glyph, so 日本語 and Latin both render in Noto Sans JP when it's loaded. */
|
|
104
138
|
--font-family-sans:
|
|
105
|
-
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
|
|
106
|
-
system-ui, "
|
|
139
|
+
"Noto Sans JP", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
|
|
140
|
+
system-ui, "Hiragino Sans", sans-serif;
|
|
107
141
|
--font-family-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
142
|
+
/* Dual-font split (opt-in) — many brand designs pair a DISPLAY face for headings with a separate
|
|
143
|
+
* BODY face (e.g. Source Sans 3 display + Inter body). Both default to --font-family-sans, so a
|
|
144
|
+
* single-font system is unchanged; a service overrides one or both. Headings read
|
|
145
|
+
* --font-family-display, body reads --font-family-body (wired in styles/index.css @layer base). */
|
|
146
|
+
--font-family-display: var(--font-family-sans);
|
|
147
|
+
--font-family-body: var(--font-family-sans);
|
|
108
148
|
/* ── Type scale — GOLDEN-RATIO modular scale (Ant/Tailwind model). ONE base + ONE ratio; every
|
|
109
149
|
* step is base × ratioⁿ, so the whole scale stays in golden proportion. `--font-size-ratio` is
|
|
110
150
|
* φ^¼ (the golden ratio's quarter-step ≈ 1.1227) — a TRUE golden ratio yet dense enough that
|
|
@@ -124,6 +164,19 @@
|
|
|
124
164
|
--font-size-xl: calc(var(--font-size-lg) * var(--font-size-ratio)); /* ratio³ ≈ 19.8px */
|
|
125
165
|
--font-size-2xl: calc(var(--font-size-xl) * var(--font-size-ratio)); /* ratio⁴ ≈ 22.3px */
|
|
126
166
|
|
|
167
|
+
/* DISPLAY type — OPT-IN large sizes for MARKETING / hero surfaces (landing pages, CTA banners).
|
|
168
|
+
* The enterprise heading scale stays small by design (h1 = 20px, 渋み restraint); these are a
|
|
169
|
+
* SEPARATE bolder ramp a marketing surface opts into via the text-3xl/-4xl/-5xl utilities (wired
|
|
170
|
+
* in styles/index.css @theme). A service rescales the whole display ramp from --font-size-display
|
|
171
|
+
* (its own base). Nothing in the admin system uses them, so defaults are unchanged. */
|
|
172
|
+
--font-size-display: 3.375rem; /* 54px — hero display (the single display knob) */
|
|
173
|
+
--font-size-display-ratio: 1.28; /* bolder step than the body φ^¼ — marketing wants more contrast */
|
|
174
|
+
--font-size-3xl: calc(
|
|
175
|
+
var(--font-size-display) / var(--font-size-display-ratio) / var(--font-size-display-ratio)
|
|
176
|
+
); /* ≈ 33 → 28px feature heading */
|
|
177
|
+
--font-size-4xl: calc(var(--font-size-display) / var(--font-size-display-ratio)); /* ≈ 36px section */
|
|
178
|
+
--font-size-5xl: var(--font-size-display); /* 54px hero */
|
|
179
|
+
|
|
127
180
|
/* Headings — also golden-derived. h1=ratio³, h2=ratio²; h3/h4 reuse body sizes (single source). */
|
|
128
181
|
--heading-h1: calc(
|
|
129
182
|
var(--font-size-base) * var(--font-size-ratio) * var(--font-size-ratio) * var(--font-size-ratio)
|
|
@@ -141,6 +194,10 @@
|
|
|
141
194
|
* so any remaining reference renders at 500. `bold` is the 700 emphasis weight. */
|
|
142
195
|
--font-weight-semibold: 500;
|
|
143
196
|
--font-weight-bold: 700;
|
|
197
|
+
/* Display/black weight — OPT-IN for marketing display type (hero/CTA). The enterprise system caps
|
|
198
|
+
* at 700 (簡素 restraint); this is only reached via the .font-display-weight utility / a service
|
|
199
|
+
* setting it on a display surface, so admin text is unchanged. */
|
|
200
|
+
--font-weight-black: 800;
|
|
144
201
|
--line-height-tight: 1.25;
|
|
145
202
|
--line-height-normal: 1.5;
|
|
146
203
|
--line-height-body: 1.7;
|
|
@@ -287,6 +344,11 @@
|
|
|
287
344
|
--text-disabled: 45 6% 40%;
|
|
288
345
|
--text-link: 204 90% 66%;
|
|
289
346
|
--text-brand: 204 90% 66%;
|
|
347
|
+
/* Status text on the dark spine reads LIGHT (AA on dark surfaces). */
|
|
348
|
+
--text-success: 146 55% 64%;
|
|
349
|
+
--text-warning: 44 95% 62%;
|
|
350
|
+
--text-info: 221 70% 72%;
|
|
351
|
+
--text-error: 357 75% 68%;
|
|
290
352
|
--primary-hover: 204 90% 66%;
|
|
291
353
|
--primary-active: 204 90% 72%;
|
|
292
354
|
--secondary-hover: 45 6% 22%;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@godxjp/ui",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"packageManager": "pnpm@10.29.1",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -275,7 +275,7 @@
|
|
|
275
275
|
"test:coverage": "vitest run --coverage",
|
|
276
276
|
"check:example-imports": "node scripts/check-example-imports.mjs",
|
|
277
277
|
"verify": "pnpm typecheck && pnpm lint && pnpm format && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm check:audit-sync && pnpm test",
|
|
278
|
-
"verify:release": "pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm check:audit-sync && pnpm check:mcp-prop-sync && pnpm test",
|
|
278
|
+
"verify:release": "pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm check:audit-sync && pnpm check:mcp-prop-sync && pnpm check:contrast && pnpm test",
|
|
279
279
|
"check:mcp-sync": "node scripts/check-mcp-sync.mjs",
|
|
280
280
|
"check:mcp-orphans": "node scripts/check-mcp-orphans.mjs",
|
|
281
281
|
"check:mcp-prop-sync": "node scripts/check-mcp-prop-sync.mjs",
|
|
@@ -297,23 +297,24 @@
|
|
|
297
297
|
"dev": "node scripts/dev.mjs",
|
|
298
298
|
"prepublishOnly": "pnpm run build",
|
|
299
299
|
"check:audit-sync": "node scripts/check-audit-sync.mjs",
|
|
300
|
+
"check:contrast": "node scripts/check-contrast.mjs",
|
|
300
301
|
"visual-audit": "node scripts/visual-audit.mjs",
|
|
301
302
|
"postinstall": "node scripts/postinstall.mjs",
|
|
302
303
|
"init-agent": "node scripts/init-agent-kit.mjs"
|
|
303
304
|
},
|
|
304
305
|
"peerDependencies": {
|
|
306
|
+
"@axe-core/playwright": "*",
|
|
305
307
|
"@hookform/resolvers": "^5.2.0",
|
|
306
308
|
"@tanstack/react-query": ">=5.0.0",
|
|
309
|
+
"axe-core": "*",
|
|
310
|
+
"playwright": "*",
|
|
307
311
|
"react": ">=19.0.0",
|
|
308
312
|
"react-dom": ">=19.0.0",
|
|
309
313
|
"react-hook-form": "^7.76.0",
|
|
310
314
|
"react-router-dom": ">=7.0.0",
|
|
311
315
|
"recharts": "^2.13.0 || ^3.0.0",
|
|
312
316
|
"tailwindcss": ">=4.0.0",
|
|
313
|
-
"zod": "^4.4.0"
|
|
314
|
-
"playwright": "*",
|
|
315
|
-
"@axe-core/playwright": "*",
|
|
316
|
-
"axe-core": "*"
|
|
317
|
+
"zod": "^4.4.0"
|
|
317
318
|
},
|
|
318
319
|
"peerDependenciesMeta": {
|
|
319
320
|
"recharts": {
|
|
@@ -331,8 +332,8 @@
|
|
|
331
332
|
},
|
|
332
333
|
"dependencies": {
|
|
333
334
|
"@date-fns/tz": "^1.5.0",
|
|
334
|
-
"@
|
|
335
|
-
"@fontsource/
|
|
335
|
+
"@fontsource/montserrat": "^5.2.8",
|
|
336
|
+
"@fontsource/noto-sans-jp": "^5.2.9",
|
|
336
337
|
"@radix-ui/react-accordion": "^1.2.12",
|
|
337
338
|
"@radix-ui/react-alert-dialog": "^1.1.15",
|
|
338
339
|
"@radix-ui/react-aspect-ratio": "^1.1.8",
|
|
@@ -359,6 +360,7 @@
|
|
|
359
360
|
"@radix-ui/react-toggle": "^1.1.10",
|
|
360
361
|
"@radix-ui/react-toggle-group": "^1.1.11",
|
|
361
362
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
363
|
+
"@tanstack/react-table": "^8.21.3",
|
|
362
364
|
"class-variance-authority": "^0.7.1",
|
|
363
365
|
"clsx": "^2.1.1",
|
|
364
366
|
"cmdk": "^1.1.1",
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/* Badge component tokens. */
|
|
2
|
-
|
|
3
|
-
:root {
|
|
4
|
-
--badge-space-gap: var(--space-inline-xs);
|
|
5
|
-
--badge-space-x: var(--space-2);
|
|
6
|
-
--badge-space-y: var(--space-1);
|
|
7
|
-
/* Small-by-design (badge/pill/counter). A knob (rule #45) so a service can
|
|
8
|
-
* re-tune badge text without touching the global --font-size-xs step. */
|
|
9
|
-
--badge-font-size: var(--font-size-xs);
|
|
10
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/* Card component tokens: card chrome derives from semantic layout tokens. */
|
|
2
|
-
|
|
3
|
-
:root {
|
|
4
|
-
/* Horizontal inset of every slot (header / content / footer) + the resting top/bottom
|
|
5
|
-
* shell padding. This is the column the title, body and footer all align to. */
|
|
6
|
-
--card-space-inset: var(--space-section-active);
|
|
7
|
-
/* Vertical padding of a BANDED header band (top = bottom). Drives --card-space-divided-y. */
|
|
8
|
-
--card-space-header-y: var(--space-stack-sm);
|
|
9
|
-
/* Gap between the header and the body, and the body's own top padding — the breathing
|
|
10
|
-
* room under a title before content begins. */
|
|
11
|
-
--card-space-body-y: var(--space-section-active);
|
|
12
|
-
/* Vertical padding of a SEPARATED footer band (top = bottom). Drives --card-space-divided-y. */
|
|
13
|
-
--card-space-footer-y: var(--space-stack-sm);
|
|
14
|
-
/* DIVIDED-section vertical padding (rule #44/#45). A header/footer that carries a divider
|
|
15
|
-
* border (banded header, separated footer) reads as its own band, so it pads SYMMETRICALLY
|
|
16
|
-
* top+bottom — distinct from a plain header that flows into the body (top inset, no bottom).
|
|
17
|
-
* One themeable knob keeps the header- and footer-band rhythm in sync; a service theme tunes
|
|
18
|
-
* the band density here instead of forking per-slot CSS. */
|
|
19
|
-
--card-space-divided-y: var(--card-space-header-y);
|
|
20
|
-
/* Vertical gap between stacked items WITHIN a slot (e.g. title ↕ description in the header). */
|
|
21
|
-
--card-space-gap: var(--space-stack-xs);
|
|
22
|
-
--card-title-font-size: var(--font-size-base);
|
|
23
|
-
--card-title-line-height: var(--line-height-tight);
|
|
24
|
-
--card-title-font-weight: var(--font-weight-semibold);
|
|
25
|
-
--card-description-font-size: var(--font-size-sm);
|
|
26
|
-
--card-description-line-height: var(--line-height-normal);
|
|
27
|
-
--card-background: var(--card);
|
|
28
|
-
--card-border: var(--border);
|
|
29
|
-
--card-header-background: var(--muted);
|
|
30
|
-
--card-header-background-alpha: 0.55;
|
|
31
|
-
/* Banded-header divider — tokenised (rule #44) so a service theme can make it
|
|
32
|
-
* dashed / heavier / none without forking CSS. Pair with
|
|
33
|
-
* --card-header-background-alpha: 0 for a quiet borderless-band header. */
|
|
34
|
-
--card-header-border-bottom: 1px solid hsl(var(--card-border));
|
|
35
|
-
--card-radius: var(--radius);
|
|
36
|
-
/* Accent edge — width of the semantic leading-edge stripe (data-accent).
|
|
37
|
-
* Tokenised (rule #44) so a service theme can re-tune it without forking CSS.
|
|
38
|
-
* The slot padding compensation in card-layout.css subtracts the same token,
|
|
39
|
-
* so content stays aligned on the shell whatever the rail width. */
|
|
40
|
-
--card-accent-rail-width: 6px;
|
|
41
|
-
--stat-card-label-font-size: var(--font-size-xs);
|
|
42
|
-
--stat-card-label-font-weight: var(--font-weight-medium);
|
|
43
|
-
--stat-card-label-letter-spacing: 0.04em;
|
|
44
|
-
--stat-card-value-font-size: var(--font-size-2xl);
|
|
45
|
-
--stat-card-value-line-height: 1.1;
|
|
46
|
-
--stat-card-value-font-weight: var(--font-weight-semibold);
|
|
47
|
-
--stat-card-hint-font-size: var(--font-size-xs);
|
|
48
|
-
--stat-card-gap: var(--space-stack-xs);
|
|
49
|
-
--stat-card-icon-size: 2.25rem;
|
|
50
|
-
--stat-card-delta-font-size: var(--font-size-xs);
|
|
51
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/* Control primitive tokens: heights, horizontal padding, adjacent control sizes. */
|
|
2
|
-
|
|
3
|
-
:root {
|
|
4
|
-
--control-height-compact: 1.75rem;
|
|
5
|
-
--control-height-default: 2rem;
|
|
6
|
-
--control-height-comfortable: 2.75rem;
|
|
7
|
-
--control-padding-x-compact: var(--space-2);
|
|
8
|
-
--control-padding-x-default: var(--space-3);
|
|
9
|
-
--control-padding-x-comfortable: var(--space-4);
|
|
10
|
-
|
|
11
|
-
--control-height: calc(var(--control-height-default) * var(--scaling));
|
|
12
|
-
/* Adjacent control sizes, derived from the active --control-height. The ±step
|
|
13
|
-
* is scaled too so the whole control ladder stays proportional under --scaling. */
|
|
14
|
-
--control-height-sm: calc(var(--control-height) - calc(0.25rem * var(--scaling)));
|
|
15
|
-
--control-height-lg: calc(var(--control-height) + calc(0.25rem * var(--scaling)));
|
|
16
|
-
--control-height-xs: calc(var(--control-height) - calc(0.5rem * var(--scaling)));
|
|
17
|
-
--control-padding-x: var(--control-padding-x-default);
|
|
18
|
-
--control-gap: var(--space-inline-sm);
|
|
19
|
-
--control-gap-sm: var(--space-inline-xs);
|
|
20
|
-
--control-radius: var(--radius);
|
|
21
|
-
--control-icon-size: calc(1rem * var(--scaling));
|
|
22
|
-
--control-icon-size-sm: calc(0.875rem * var(--scaling));
|
|
23
|
-
--control-focus-ring-width: 2px;
|
|
24
|
-
|
|
25
|
-
--checkbox-size: calc(1rem * var(--scaling));
|
|
26
|
-
--checkbox-size-compact: 0.875rem;
|
|
27
|
-
--checkbox-size-comfortable: 1.125rem;
|
|
28
|
-
--choice-gap: var(--space-inline-sm);
|
|
29
|
-
--choice-group-gap-x: var(--space-6);
|
|
30
|
-
--choice-group-gap-y: var(--space-3);
|
|
31
|
-
--choice-description-gap: 0.125rem;
|
|
32
|
-
--choice-control-offset: 0.125rem;
|
|
33
|
-
|
|
34
|
-
--switch-width: calc(2.25rem * var(--scaling));
|
|
35
|
-
--switch-width-compact: 2rem;
|
|
36
|
-
--switch-width-comfortable: 2.5rem;
|
|
37
|
-
--switch-height: calc(1.25rem * var(--scaling));
|
|
38
|
-
--switch-height-compact: 1.125rem;
|
|
39
|
-
--switch-height-comfortable: 1.375rem;
|
|
40
|
-
--switch-thumb-size: calc(1rem * var(--scaling));
|
|
41
|
-
--switch-thumb-size-compact: 0.875rem;
|
|
42
|
-
--switch-thumb-size-comfortable: 1.125rem;
|
|
43
|
-
--switch-thumb-translate: calc(1rem * var(--scaling));
|
|
44
|
-
--switch-thumb-translate-compact: 0.875rem;
|
|
45
|
-
--switch-thumb-translate-comfortable: 1.125rem;
|
|
46
|
-
|
|
47
|
-
--slider-track-height: 0.375rem;
|
|
48
|
-
--slider-thumb-size: 1rem;
|
|
49
|
-
|
|
50
|
-
--color-picker-input-width: 6.5rem;
|
|
51
|
-
|
|
52
|
-
--command-list-max-height: min(300px, 50vh);
|
|
53
|
-
--command-input-padding-x: var(--space-3);
|
|
54
|
-
--command-group-padding: var(--space-1);
|
|
55
|
-
--command-item-padding-y: var(--space-2);
|
|
56
|
-
--command-item-padding-x: var(--space-2);
|
|
57
|
-
--search-input-edge-inset: var(--space-3);
|
|
58
|
-
--search-input-start-padding: calc(
|
|
59
|
-
var(--search-input-edge-inset) + var(--control-icon-size) + var(--control-gap)
|
|
60
|
-
);
|
|
61
|
-
--search-input-end-padding: calc(
|
|
62
|
-
var(--search-input-edge-inset) + var(--control-icon-size) + var(--control-gap)
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
--choice-description-font-size: var(--font-size-xs);
|
|
66
|
-
--color-picker-hex-font-size: var(--font-size-xs);
|
|
67
|
-
--command-group-heading-font-size: var(--font-size-xs);
|
|
68
|
-
--search-input-label-font-size: var(--font-size-xs);
|
|
69
|
-
--tag-input-chip-font-size: var(--font-size-xs);
|
|
70
|
-
--toggle-sm-font-size: var(--font-size-xs);
|
|
71
|
-
--button-sm-font-size: var(--font-size-xs);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/* Rule #24 — on touch devices (coarse pointer) interactive controls keep a ≥44px tap target
|
|
75
|
-
* regardless of density; desktop (fine pointer) keeps the compact heights above. --control-height
|
|
76
|
-
* resolves through these via var(), so inputs/buttons/selects/table rows all bump together. */
|
|
77
|
-
@media (pointer: coarse) {
|
|
78
|
-
:root {
|
|
79
|
-
--control-height-compact: 2.75rem;
|
|
80
|
-
--control-height-default: 2.75rem;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/* Data-display component tokens — small-by-design text knobs (rule #45/#46). */
|
|
2
|
-
|
|
3
|
-
:root {
|
|
4
|
-
--progress-label-font-size: var(--font-size-xs);
|
|
5
|
-
--tree-item-title-font-size: var(--font-size-xs);
|
|
6
|
-
--tree-item-description-font-size: var(--font-size-xs);
|
|
7
|
-
--timeline-note-font-size: var(--font-size-xs);
|
|
8
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/* Descriptions component tokens. */
|
|
2
|
-
|
|
3
|
-
:root {
|
|
4
|
-
/* Width of the label column when <Descriptions layout="horizontal">. Labels align to this
|
|
5
|
-
* shared column so the values line up (the horizontal-detail look, mirroring <Form layout>).
|
|
6
|
-
* A rem value gives a fixed aligned column; set `max-content` to size each label to its text.
|
|
7
|
-
* (rule #44/#45 — a service theme tunes it here instead of forking CSS.) */
|
|
8
|
-
--descriptions-label-width: 8rem;
|
|
9
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/* Feedback primitive tokens: dialog, alert, empty state. */
|
|
2
|
-
|
|
3
|
-
:root {
|
|
4
|
-
/* Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the
|
|
5
|
-
* whole system, or --dialog-space-x/-y for dialogs only). */
|
|
6
|
-
--dialog-space-x: var(--space-chrome-x);
|
|
7
|
-
--dialog-space-y: var(--space-chrome-y);
|
|
8
|
-
--dialog-space-inset: var(--dialog-space-y) var(--dialog-space-x);
|
|
9
|
-
--dialog-space-gap: var(--space-stack-md);
|
|
10
|
-
--dialog-close-space-offset: var(--space-4);
|
|
11
|
-
--alert-space-inset: var(--space-section-active);
|
|
12
|
-
--alert-space-gap: var(--space-inline-md);
|
|
13
|
-
--alert-inner-space-gap: var(--space-stack-sm);
|
|
14
|
-
--alert-dismiss-space-offset: var(--space-3);
|
|
15
|
-
/* Soft (subtle) semantic tint ratios — themeable so a service can hit its exact spec
|
|
16
|
-
* (a brand's success-bg/-border are often more present than the faint 5%/30% default). */
|
|
17
|
-
--alert-bg-alpha: 0.05;
|
|
18
|
-
--alert-border-alpha: 0.3;
|
|
19
|
-
--empty-state-space-y: var(--space-10);
|
|
20
|
-
--empty-state-space-x: var(--space-6);
|
|
21
|
-
--skeleton-row-gap: var(--space-stack-sm);
|
|
22
|
-
--skeleton-cell-gap: var(--space-inline-lg);
|
|
23
|
-
--skeleton-card-inset: var(--space-section-active);
|
|
24
|
-
--skeleton-radius: var(--radius);
|
|
25
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/* Form layout tokens: horizontal-layout label column geometry. */
|
|
2
|
-
|
|
3
|
-
:root {
|
|
4
|
-
/* Width of the label column in horizontal/inline layout. A service theme sets
|
|
5
|
-
* this once (e.g. 110px) to align every form to its design grid; the Form/
|
|
6
|
-
* FormField `labelWidth` prop overrides per form/field. */
|
|
7
|
-
--form-label-width: max-content;
|
|
8
|
-
|
|
9
|
-
/* Column gap between the label and its control in horizontal/inline layout. */
|
|
10
|
-
--form-label-gap: var(--space-4); /* 16px */
|
|
11
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/* ListRow component tokens — a single-line entity row for short lists inside a Card
|
|
2
|
-
* (sessions / API tokens / linked accounts / passkeys …). Sits in a flush CardContent;
|
|
3
|
-
* rows separate with a quiet divider (#44 — chrome defaults to the calm semantic border). */
|
|
4
|
-
:root {
|
|
5
|
-
--list-row-padding-y: var(--space-3);
|
|
6
|
-
--list-row-padding-x: var(--space-4);
|
|
7
|
-
--list-row-gap: var(--space-3);
|
|
8
|
-
--list-row-border: 1px solid hsl(var(--border));
|
|
9
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/* Navigation primitive tokens: pagination, filters, compact pickers. */
|
|
2
|
-
|
|
3
|
-
:root {
|
|
4
|
-
--pagination-gap: var(--space-inline-sm);
|
|
5
|
-
--pagination-item-gap: var(--space-inline-xs);
|
|
6
|
-
--pagination-size-width: 5.5rem;
|
|
7
|
-
--pagination-total-font-size: var(--font-size-sm);
|
|
8
|
-
--filter-bar-gap: var(--space-3);
|
|
9
|
-
--filter-bar-padding-y: var(--space-2);
|
|
10
|
-
--filter-label-font-size: var(--font-size-xs);
|
|
11
|
-
--filter-picker-width-sm: 11rem;
|
|
12
|
-
--filter-picker-width-md: 14rem;
|
|
13
|
-
--breadcrumb-font-size: var(--font-size-xs);
|
|
14
|
-
--menubar-shortcut-font-size: var(--font-size-xs);
|
|
15
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/* Shell (sidebar / topbar / kbd) component tokens — small-by-design text
|
|
2
|
-
* knobs (rule #45/#46). A service re-tunes chrome text without moving the
|
|
3
|
-
* global scale. */
|
|
4
|
-
|
|
5
|
-
:root {
|
|
6
|
-
--sidebar-section-label-font-size: var(--font-size-2xs);
|
|
7
|
-
--sidebar-product-tenant-font-size: var(--font-size-2xs);
|
|
8
|
-
--sidebar-badge-font-size: var(--font-size-2xs);
|
|
9
|
-
--sidebar-user-role-font-size: var(--font-size-2xs);
|
|
10
|
-
--sidebar-nav-sub-font-size: var(--font-size-xs);
|
|
11
|
-
--sidebar-flyout-title-font-size: var(--font-size-xs);
|
|
12
|
-
--topbar-chip-icon-font-size: var(--font-size-2xs);
|
|
13
|
-
--kbd-font-size: var(--font-size-2xs);
|
|
14
|
-
--sidebar-logo-mark-font-size: var(--font-size-xs);
|
|
15
|
-
--sidebar-avatar-font-size: var(--font-size-2xs);
|
|
16
|
-
--sidebar-user-name-font-size: var(--font-size-xs);
|
|
17
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/* Table component tokens: row height, cell padding. */
|
|
2
|
-
|
|
3
|
-
:root {
|
|
4
|
-
--table-row-height-compact: 1.75rem;
|
|
5
|
-
--table-row-height-default: 2rem;
|
|
6
|
-
--table-row-height-comfortable: 2.75rem;
|
|
7
|
-
--table-row-height: calc(var(--table-row-height-default) * var(--scaling));
|
|
8
|
-
--table-cell-padding-y: var(--space-2);
|
|
9
|
-
--table-cell-space-x: var(--control-padding-x);
|
|
10
|
-
--table-head-font-size: var(--font-size-xs);
|
|
11
|
-
/* Inline-end shadow that lifts a pinned (sticky) action column off the body it scrolls over. */
|
|
12
|
-
--table-pin-shadow: -6px 0 6px -5px hsl(var(--foreground) / 0.12);
|
|
13
|
-
}
|