@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.
- 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 +30 -0
- package/dist/components/charts/compact-bar-trend.js +74 -0
- package/dist/components/charts/index.d.ts +6 -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 +40 -4
- package/dist/components/data-display/data-table.js +69 -2
- package/dist/components/data-display/empty-state.js +1 -1
- package/dist/components/data-display/index.d.ts +4 -2
- package/dist/components/data-display/index.js +10 -1
- package/dist/components/data-display/list-row.d.ts +41 -4
- package/dist/components/data-display/list-row.js +23 -3
- package/dist/components/data-display/qr-code.d.ts +1 -1
- 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-display/table.d.ts +47 -2
- package/dist/components/data-display/table.js +29 -4
- 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/command.d.ts +10 -10
- package/dist/components/data-entry/index.d.ts +3 -0
- package/dist/components/data-entry/index.js +2 -0
- package/dist/components/data-entry/input-otp.d.ts +1 -0
- package/dist/components/feedback/dialog.d.ts +16 -1
- package/dist/components/feedback/dialog.js +46 -33
- package/dist/components/feedback/index.d.ts +5 -2
- package/dist/components/feedback/index.js +8 -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 +49 -9
- package/dist/components/general/logo.js +67 -14
- package/dist/components/layout/app-shell.d.ts +1 -1
- package/dist/components/layout/app-shell.js +55 -30
- package/dist/components/layout/auth-account-summary.d.ts +5 -0
- package/dist/components/layout/auth-account-summary.js +31 -0
- 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 +9 -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 +29 -19
- package/dist/components/layout/error-surface.d.ts +35 -0
- package/dist/components/layout/error-surface.js +155 -0
- package/dist/components/layout/flex.d.ts +1 -1
- package/dist/components/layout/flex.js +4 -0
- package/dist/components/layout/index.d.ts +23 -3
- package/dist/components/layout/index.js +21 -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 +7 -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/steps.js +38 -19
- 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 +47 -23
- package/dist/components/ui/avatar.d.ts +2 -1
- package/dist/components/ui/avatar.js +2 -1
- package/dist/components/ui/input-otp.d.ts +4 -1
- package/dist/components/ui/input-otp.js +2 -1
- package/dist/components/ui/toggle-group.d.ts +7 -4
- package/dist/components/ui/toggle-group.js +32 -21
- package/dist/email/brand-mark.d.ts +108 -0
- package/dist/email/brand-mark.js +88 -0
- package/dist/email/color.d.ts +53 -0
- package/dist/email/color.js +37 -0
- package/dist/email/geometry.d.ts +120 -0
- package/dist/email/geometry.js +90 -0
- package/dist/email/index.d.ts +83 -0
- package/dist/email/index.js +82 -0
- package/dist/email/inline-style.d.ts +27 -0
- package/dist/email/inline-style.js +26 -0
- package/dist/email/tokens.generated.d.ts +167 -0
- package/dist/email/tokens.generated.js +162 -0
- package/dist/email/urgency.d.ts +22 -0
- package/dist/email/urgency.js +14 -0
- package/dist/i18n/messages/en.json +36 -3
- package/dist/i18n/messages/ja.json +36 -3
- package/dist/i18n/messages/vi.json +36 -3
- 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 +75 -1
- package/dist/props/components/data-entry.prop.d.ts +6 -0
- package/dist/props/components/feedback.prop.d.ts +10 -0
- package/dist/props/components/index.d.ts +3 -3
- package/dist/props/components/layout.prop.d.ts +560 -10
- package/dist/props/components/layout.prop.js +1 -0
- package/dist/props/components/navigation.prop.d.ts +24 -2
- package/dist/props/registry.d.ts +433 -8
- package/dist/props/registry.js +527 -9
- package/dist/props/vocabulary/data.prop.d.ts +27 -0
- package/dist/props/vocabulary/index.d.ts +3 -3
- package/dist/props/vocabulary/interaction.prop.d.ts +10 -1
- package/dist/props/vocabulary/layout.prop.d.ts +49 -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 +76 -2
- package/dist/styles/data-display-layout.css +78 -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 +466 -1
- package/dist/styles/logo-layout.css +95 -0
- package/dist/styles/navigation-layout.css +152 -0
- package/dist/styles/shell-layout.css +790 -40
- package/dist/styles/table-layout.css +164 -1
- package/dist/theme/dxs.canonical.css +77 -0
- package/dist/tokens/axes.css +40 -0
- package/dist/tokens/base.css +6 -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/data-display.css +13 -0
- package/dist/tokens/components/email.css +93 -0
- package/dist/tokens/components/error-surface.css +36 -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 +43 -2
- package/dist/tokens/components/logo.css +74 -0
- package/dist/tokens/components/navigation.css +28 -0
- package/dist/tokens/components/sheet.css +19 -0
- package/dist/tokens/components/shell.css +210 -0
- package/dist/tokens/components/sidebar.css +33 -0
- package/dist/tokens/components/table.css +45 -0
- package/dist/tokens/foundation.css +31 -2
- package/dist/tokens/semantic/layout.css +69 -2
- package/package.json +22 -5
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
/* Feedback primitive tokens: dialog, alert, empty state. */
|
|
2
2
|
|
|
3
3
|
:root {
|
|
4
|
+
--sheet-width-default: 22.5rem;
|
|
5
|
+
/* Overlay scrims — `initial` so the shared semantic --overlay-background re-resolves at the CALL
|
|
6
|
+
* SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a
|
|
7
|
+
* scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather
|
|
8
|
+
* than a private literal, so a service retints every backdrop with one --overlay-background while
|
|
9
|
+
* the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a
|
|
10
|
+
* modal Dialog. Defaults resolve to rgb(0 0 0 / 0.2) (sheet) and rgb(0 0 0 / 0.3) (dialog). */
|
|
11
|
+
--sheet-overlay-background: initial;
|
|
12
|
+
--sheet-overlay-alpha: 40%;
|
|
13
|
+
--dialog-width-default: 32rem;
|
|
14
|
+
--dialog-viewport-inset: 1.5rem;
|
|
15
|
+
--dialog-overlay-background: initial;
|
|
16
|
+
--dialog-overlay-alpha: 60%;
|
|
4
17
|
/* Dialog inset defaults to the shared global chrome tokens (override --space-chrome-* once for the
|
|
5
18
|
* whole system, or --dialog-space-x/-y for dialogs only). */
|
|
6
19
|
--dialog-space-x: var(--space-chrome-x);
|
|
@@ -22,6 +35,10 @@
|
|
|
22
35
|
--dialog-content-glow: 0 0 0 0 transparent;
|
|
23
36
|
--empty-state-space-y: var(--space-10);
|
|
24
37
|
--empty-state-space-x: var(--space-6);
|
|
38
|
+
/* Measure of the description paragraph (rule #45 — a service-tunable constant gets a knob).
|
|
39
|
+
* 28rem reads ~65 Latin characters per line; a JA/VI service that needs a shorter or longer
|
|
40
|
+
* measure for its own copy retunes this once instead of forking `.ui-empty-state-description`. */
|
|
41
|
+
--empty-state-description-max-width: 28rem;
|
|
25
42
|
--empty-state-section-space-y: var(--space-6);
|
|
26
43
|
--empty-state-section-space-x: var(--space-4);
|
|
27
44
|
--empty-state-compact-space-y: var(--space-3);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/* LegalDocumentShell component tokens — the long-form legal/policy document surface
|
|
2
|
+
* (terms of service, privacy policy, DPA, cookie policy, SLA, EULA) with a sticky
|
|
3
|
+
* table-of-contents rail.
|
|
4
|
+
*
|
|
5
|
+
* Rule #45 — every service-tunable constant is a knob: the readable measure, the rail
|
|
6
|
+
* width/offset, the section rhythm and the body leading are exactly the values a service
|
|
7
|
+
* theme wants to re-tune to match its design grid, so NONE of them are hard-coded in
|
|
8
|
+
* `src/styles/layout.css`.
|
|
9
|
+
*
|
|
10
|
+
* Rule #44 — chrome is a token, default QUIET: every divider (`*-border`) defaults to
|
|
11
|
+
* `none`. A service opts IN via theme, e.g.
|
|
12
|
+
* --legal-document-toc-border: 1px solid hsl(var(--border));
|
|
13
|
+
*
|
|
14
|
+
* Colour knobs whose default is a ROLE token are declared `initial` here with the role
|
|
15
|
+
* default at the CALL SITE (`var(--knob, var(--role))`) — see docs/TOKENS.md ·
|
|
16
|
+
* "Role-mirror knobs MUST be `initial`" — so a scoped `[data-tenant]` / `.dark`
|
|
17
|
+
* override of the role still reaches them.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
:root {
|
|
21
|
+
/* ── Geometry ─────────────────────────────────────────────────────────────── */
|
|
22
|
+
/* Readable document measure. Caps the header, the section column and the footer so
|
|
23
|
+
* a 1440px viewport still reads at ~75-90 characters per line. */
|
|
24
|
+
--legal-document-measure-max-width: 46rem;
|
|
25
|
+
/* Rail ↔ document column gutter (two-column mode only). */
|
|
26
|
+
--legal-document-column-gap: var(--space-10);
|
|
27
|
+
/* Sticky table-of-contents rail width (two-column mode only). */
|
|
28
|
+
--legal-document-toc-width: 15rem;
|
|
29
|
+
/* Distance the pinned rail keeps from the top of the scrollport. */
|
|
30
|
+
--legal-document-toc-inset-block-start: var(--space-6);
|
|
31
|
+
/* Cap for a long contents list so the rail never outgrows the viewport. */
|
|
32
|
+
--legal-document-toc-max-height: calc(100dvh - var(--space-12));
|
|
33
|
+
--legal-document-toc-gap: var(--space-1);
|
|
34
|
+
--legal-document-toc-item-padding: var(--space-1) var(--space-2);
|
|
35
|
+
--legal-document-toc-item-radius: var(--radius);
|
|
36
|
+
--legal-document-toc-title-font-size: var(--font-size-2xs);
|
|
37
|
+
--legal-document-toc-font-size: var(--font-size-xs);
|
|
38
|
+
/* Leading marker on the active contents entry — a non-colour affordance so the
|
|
39
|
+
* active state is never colour-only (WCAG 1.4.1). */
|
|
40
|
+
--legal-document-toc-marker-width: 2px;
|
|
41
|
+
/* Gap between the `documentNavigation` slot and the contents list inside the rail. */
|
|
42
|
+
--legal-document-nav-gap: var(--space-4);
|
|
43
|
+
--legal-document-header-gap: var(--space-2);
|
|
44
|
+
--legal-document-meta-gap: var(--space-2);
|
|
45
|
+
--legal-document-meta-font-size: var(--font-size-xs);
|
|
46
|
+
--legal-document-section-gap: var(--space-10);
|
|
47
|
+
--legal-document-section-title-gap: var(--space-3);
|
|
48
|
+
/* Long-form leading — legal prose reads looser than UI text. */
|
|
49
|
+
--legal-document-body-line-height: 1.8;
|
|
50
|
+
/* `scroll-margin-block-start` on every section: the offset a hash jump / anchor
|
|
51
|
+
* activation leaves above the heading so it is not hidden under sticky chrome. */
|
|
52
|
+
--legal-document-scroll-offset: var(--space-6);
|
|
53
|
+
--legal-document-footer-gap: var(--space-4);
|
|
54
|
+
|
|
55
|
+
/* ── Chrome — quiet by default (rule #44) ─────────────────────────────────── */
|
|
56
|
+
--legal-document-toc-border: none;
|
|
57
|
+
--legal-document-header-border: none;
|
|
58
|
+
--legal-document-footer-border: none;
|
|
59
|
+
|
|
60
|
+
/* ── Role-mirror knobs — `initial` here, role default at the call site ─────── */
|
|
61
|
+
--legal-document-meta-foreground: initial; /* default = hsl(var(--muted-foreground)) */
|
|
62
|
+
--legal-document-summary-foreground: initial; /* default = hsl(var(--muted-foreground)) */
|
|
63
|
+
--legal-document-toc-foreground: initial; /* default = hsl(var(--muted-foreground)) */
|
|
64
|
+
--legal-document-toc-active-foreground: initial; /* default = hsl(var(--foreground)) */
|
|
65
|
+
--legal-document-toc-active-background: initial; /* default = hsl(var(--accent)) */
|
|
66
|
+
--legal-document-toc-marker-color: initial; /* default = hsl(var(--primary)) */
|
|
67
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
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
|
|
3
|
-
* rows separate with a quiet divider (#44 — chrome defaults to the calm
|
|
2
|
+
* (sessions / API tokens / linked accounts / passkeys / notifications …). Sits in a flush
|
|
3
|
+
* CardContent; rows separate with a quiet divider (#44 — chrome defaults to the calm
|
|
4
|
+
* semantic border). */
|
|
4
5
|
:root {
|
|
5
6
|
--list-row-padding-y: var(--space-3);
|
|
6
7
|
--list-row-padding-x: var(--space-4);
|
|
@@ -8,4 +9,44 @@
|
|
|
8
9
|
/* Row divider — `initial` so the --border default re-resolves at the call site under a scoped
|
|
9
10
|
* theme (a :root binding to a role var freezes at :root). Default = 1px solid hsl(var(--border)). */
|
|
10
11
|
--list-row-border: initial;
|
|
12
|
+
/* Inline size the content column keeps before the trailing actions wrap onto their own line
|
|
13
|
+
* (#45 — a service retunes the stack threshold to its grid). Clamped with min(…, 100%) at the
|
|
14
|
+
* call site, so a container narrower than the knob can never force page-root overflow (#224). */
|
|
15
|
+
--list-row-body-min-width: 12rem;
|
|
16
|
+
/* Gap BETWEEN trailing actions — they also wrap among themselves at narrow widths (#224). */
|
|
17
|
+
--list-row-trailing-gap: var(--space-2);
|
|
18
|
+
/* ── Compact inline-actions geometry (`density="compact"`, #246) ──────────────────────────
|
|
19
|
+
* The canonical invitation / history row: a 36px leading avatar, a shrinkable title +
|
|
20
|
+
* description body and one or two small trailing Buttons, all on ONE line inside the canonical
|
|
21
|
+
* 358px card (326px content after the row's own inline inset) at a 390px viewport. These knobs
|
|
22
|
+
* only LOWER the geometry — the #224 wrap contract (row + trailing cluster wrap, body clamped
|
|
23
|
+
* with min(…, 100%)) is untouched, so a cluster that genuinely cannot fit still wraps instead of
|
|
24
|
+
* widening the page root.
|
|
25
|
+
* Declared `initial` so the spacing defaults re-resolve at the CALL SITE — --space-2 is
|
|
26
|
+
* density-scaled and re-declared inside a `.ui-density-*` subtree, so a :root binding would
|
|
27
|
+
* freeze compact rows at the :root density (docs/TOKENS.md — the :root freeze rule).
|
|
28
|
+
* Defaults = var(--space-2) block padding · var(--list-row-padding-x) inline padding ·
|
|
29
|
+
* var(--space-2) gap. */
|
|
30
|
+
--list-row-compact-padding-y: initial;
|
|
31
|
+
/* Inline inset defaults to the default row axis so compact and default rows in the same Card keep
|
|
32
|
+
* one optical axis; a service retunes it to its own grid (#45). */
|
|
33
|
+
--list-row-compact-padding-x: initial;
|
|
34
|
+
--list-row-compact-gap: initial;
|
|
35
|
+
/* Compact body threshold — small enough that avatar + body + two compact Buttons fit the
|
|
36
|
+
* canonical column (36 + 8 + 96 + 8 + 146 = 294 ≤ 326), and still a readable measure. */
|
|
37
|
+
--list-row-compact-body-min-width: 6rem;
|
|
38
|
+
/* Read (default) row surface — `initial`, documented default = transparent, i.e. the Card
|
|
39
|
+
* surface shows through untouched (#44 — chrome defaults to the quietest state). */
|
|
40
|
+
--list-row-read-background: initial;
|
|
41
|
+
/* Unread emphasis surface (`unread` rows) — `initial` so the --muted default re-resolves at the
|
|
42
|
+
* call site under a scoped theme. Documented default = hsl(var(--muted)), the same quiet
|
|
43
|
+
* emphasis role the table header uses; it keeps the xs muted description line at WCAG AA
|
|
44
|
+
* (4.63:1 light / 5.47:1 dark), which hsl(var(--accent)) would not (4.23:1 light). */
|
|
45
|
+
--list-row-unread-background: initial;
|
|
46
|
+
/* Unread indicator dot fill — `initial` so the --primary default re-resolves at the call site
|
|
47
|
+
* under a scoped theme. Documented default = hsl(var(--primary)). */
|
|
48
|
+
--list-row-indicator-color: initial;
|
|
49
|
+
/* Diameter of the read/unread indicator dot; the gutter is reserved on read rows too so the
|
|
50
|
+
* titles of a mixed list stay on one optical axis. */
|
|
51
|
+
--list-row-indicator-size: var(--space-2);
|
|
11
52
|
}
|
|
@@ -12,4 +12,78 @@
|
|
|
12
12
|
--logo-font-size-sm: var(--font-size-xs);
|
|
13
13
|
--logo-font-size-md: var(--font-size-sm);
|
|
14
14
|
--logo-font-size-lg: var(--font-size-base);
|
|
15
|
+
/* Semantic identity fill reads the --brand IDENTITY role: independent of --primary (a re-themed
|
|
16
|
+
* action colour never recolours the mark) AND of --success (the 若竹 STATUS green stays on
|
|
17
|
+
* badges/progress/"saved" text — the mark used to borrow it and rendered ΔE76 ≈ 17.5 off the
|
|
18
|
+
* canonical emerald, gh#250). Services retune the role once for every Logo.
|
|
19
|
+
* ROLE-MIRROR KNOBS — declared `initial` here with the role default at the CALL SITE
|
|
20
|
+
* (logo-layout.css), so a scoped `.dark` / `[data-tenant]` override of --brand actually
|
|
21
|
+
* reaches the mark instead of freezing at the :root value (docs/TOKENS.md ·
|
|
22
|
+
* "Role-mirror knobs MUST be `initial`"). Documented defaults:
|
|
23
|
+
* --logo-success-background = hsl(var(--brand))
|
|
24
|
+
* --logo-success-foreground = hsl(var(--logo-identity-foreground))
|
|
25
|
+
* --logo-godx-color = hsl(var(--brand)) */
|
|
26
|
+
--logo-success-background: initial;
|
|
27
|
+
--logo-success-foreground: initial;
|
|
28
|
+
--logo-godx-color: initial;
|
|
29
|
+
|
|
30
|
+
/* Identity-fill INK — the ink `mark="glyph"` sets its (caller-supplied) TEXT in when it sits on
|
|
31
|
+
* the --brand identity fill. This is deliberately NOT --brand-foreground.
|
|
32
|
+
*
|
|
33
|
+
* --brand-foreground is the identity artwork's KNOCKOUT colour, not an ink: it tracks
|
|
34
|
+
* --background in both themes (light 60 33% 99% = --background; dark 48 9% 9% = --background)
|
|
35
|
+
* because `<Logo mark="godx">` punches its inner bar as an evenodd HOLE and the email mark has to
|
|
36
|
+
* paint that hole as a solid fill to match. Negative space only has to clear WCAG 2.2 SC 1.4.11
|
|
37
|
+
* (3:1, non-text) — and at 3.67:1 on the emerald it does.
|
|
38
|
+
*
|
|
39
|
+
* The boxed glyph is a different thing: it renders real TEXT, so SC 1.4.3 applies at 4.5:1 (14px
|
|
40
|
+
* bold is NOT "large text" — that needs 18.66px bold / 24px), and the knockout white measured
|
|
41
|
+
* 3.67:1 → a genuine AA failure. This ink is 48 9% 9% (#191815), the same near-black spine the
|
|
42
|
+
* DARK theme already inked the glyph with, so it is theme-INVARIANT: dark renders byte-identically
|
|
43
|
+
* (6.89:1, unchanged) and light rises 3.67 → 4.74:1. A service that re-themes --brand to a dark
|
|
44
|
+
* fill overrides --logo-success-foreground (the public knob) to re-invert the ink.
|
|
45
|
+
*
|
|
46
|
+
* NOT a role-mirror knob: its default is a real value, not a role token, so there is no role to
|
|
47
|
+
* freeze at :root and the `initial` + call-site rule (docs/TOKENS.md) does not apply to it. */
|
|
48
|
+
--logo-identity-foreground: 48 9% 9%;
|
|
49
|
+
|
|
50
|
+
/* ── Identity-mark box (`<Logo mark="godx" />`) ──────────────────────────────────────────────
|
|
51
|
+
* The `size` prop drives the identity mark exactly like it drives the boxed glyph — a public
|
|
52
|
+
* prop that renders identically at every tier is a silent no-op, and the godx LOCKUP already
|
|
53
|
+
* scaled its wordmark per tier, so a fixed mark broke the mark↔wordmark proportion at
|
|
54
|
+
* `size="lg"` (gh#163 follow-up). The godx artwork is a horizontal capsule inside a square
|
|
55
|
+
* viewBox, so it carries less optical weight than the fully-filled glyph box: each tier sits
|
|
56
|
+
* +0.25rem above its --logo-size-* sibling. `md` is 2rem — the historical fixed value — so
|
|
57
|
+
* every existing default-size identity surface renders byte-identically.
|
|
58
|
+
*
|
|
59
|
+
* --logo-godx-size is the PIN: declared `initial` (guaranteed-invalid) here with the per-tier
|
|
60
|
+
* default at the CALL SITE (logo-layout.css), so it is inert by default and a service that
|
|
61
|
+
* sets it once freezes the mark at that box on EVERY tier — the same call-site pattern the
|
|
62
|
+
* role-mirror colour knobs use (docs/TOKENS.md). Retune a single tier via --logo-godx-size-*.
|
|
63
|
+
* Documented default: --logo-godx-size = unset (tiers apply). */
|
|
64
|
+
--logo-godx-size-xs: 1.5rem;
|
|
65
|
+
--logo-godx-size-sm: 1.75rem;
|
|
66
|
+
--logo-godx-size-md: 2rem;
|
|
67
|
+
--logo-godx-size-lg: 2.5rem;
|
|
68
|
+
--logo-godx-size: initial;
|
|
69
|
+
|
|
70
|
+
/* ── Wordmark / lockup (`<Logo wordmark="GoDX" />`) ─────────────────────────────────────────
|
|
71
|
+
* The readable product name set beside the mark. The package ships NO wordmark artwork: the
|
|
72
|
+
* wordmark is typeset in the design-system display face, so a service retunes face, weight,
|
|
73
|
+
* tracking, size and the mark↔wordmark gap here instead of writing page CSS. The colour is a
|
|
74
|
+
* role-mirror knob whose default is the IDENTITY role --brand (never --primary, never the
|
|
75
|
+
* --success status green): the GoDX/`success` lockup is canonical emerald out of the box, and
|
|
76
|
+
* every other lockup reads --foreground.
|
|
77
|
+
* Documented defaults: --logo-wordmark-font-family = var(--font-family-display);
|
|
78
|
+
* --logo-wordmark-color = hsl(var(--foreground)), or hsl(var(--brand)) on the
|
|
79
|
+
* godx / tone="success" lockup. */
|
|
80
|
+
--logo-wordmark-gap: var(--space-2);
|
|
81
|
+
--logo-wordmark-font-size-xs: var(--font-size-xs);
|
|
82
|
+
--logo-wordmark-font-size-sm: var(--font-size-sm);
|
|
83
|
+
--logo-wordmark-font-size-md: var(--font-size-base);
|
|
84
|
+
--logo-wordmark-font-size-lg: var(--font-size-lg);
|
|
85
|
+
--logo-wordmark-font-weight: 700;
|
|
86
|
+
--logo-wordmark-letter-spacing: -0.01em;
|
|
87
|
+
--logo-wordmark-font-family: initial;
|
|
88
|
+
--logo-wordmark-color: initial;
|
|
15
89
|
}
|
|
@@ -10,11 +10,35 @@
|
|
|
10
10
|
--filter-label-font-size: var(--font-size-xs);
|
|
11
11
|
--filter-picker-width-sm: 11rem;
|
|
12
12
|
--filter-picker-width-md: 14rem;
|
|
13
|
+
--steps-inline-gap: var(--space-2);
|
|
14
|
+
--steps-inline-item-gap: var(--space-1);
|
|
15
|
+
--steps-inline-font-size: var(--font-size-xs);
|
|
16
|
+
--steps-inline-separator-size: var(--control-icon-size-sm);
|
|
17
|
+
|
|
18
|
+
/* AppSettingPicker `compact` (gh#217) — the small, content-hugging labelled trigger used in an
|
|
19
|
+
* auth/legal footer, where the square icon-only default reads as a stray button and the full
|
|
20
|
+
* labelled trigger is too tall. Box height comes from the official --control-height-sm tier (never
|
|
21
|
+
* a literal / ad-hoc calc), and every other knob is themeable (rule #45). */
|
|
22
|
+
--app-setting-picker-compact-control-height: var(--control-height-sm);
|
|
23
|
+
--app-setting-picker-compact-padding-x: var(--space-2);
|
|
24
|
+
--app-setting-picker-compact-gap: var(--space-1);
|
|
25
|
+
--app-setting-picker-compact-font-size: var(--font-size-xs);
|
|
13
26
|
--breadcrumb-font-size: var(--font-size-xs);
|
|
14
27
|
--menubar-shortcut-font-size: var(--font-size-xs);
|
|
15
28
|
--tabs-list-max-inline-size: 100%;
|
|
16
29
|
--tabs-list-overflow: auto;
|
|
17
30
|
|
|
31
|
+
/* Tabs `line` active indicator (gh#248) — the ONLY selected-state decoration the line variant
|
|
32
|
+
* paints. The surrounding active ring belongs to the default/card lists, so `:focus-visible`
|
|
33
|
+
* keeps its own distinct keyboard ring here (WCAG 2.4.7). `--tabs-indicator-background` is a
|
|
34
|
+
* role-mirror knob: `initial` so hsl(var(--primary)) re-resolves at the CALL SITE under a scoped
|
|
35
|
+
* [data-tenant]/.dark theme (a :root binding to a role var would freeze at :root).
|
|
36
|
+
* Default = hsl(var(--primary)) · 2px thick · flush with the trigger edge (offset 0 = quietest,
|
|
37
|
+
* rule #44); a service raises the offset to park the bar on a thicker strip hairline. */
|
|
38
|
+
--tabs-indicator-background: initial;
|
|
39
|
+
--tabs-indicator-size: 2px;
|
|
40
|
+
--tabs-indicator-offset: 0px;
|
|
41
|
+
|
|
18
42
|
/* Menu item hover/highlight tint — `initial` so the --accent default re-resolves at the call site
|
|
19
43
|
* under a scoped theme (a :root binding to a role var freezes at :root).
|
|
20
44
|
* Defaults = hsl(var(--accent)) fill · hsl(var(--accent-foreground)) text. */
|
|
@@ -27,4 +51,8 @@
|
|
|
27
51
|
/* Fill painted only when the filter strip is pinned. Role-mirror knob (rule #45): `initial`
|
|
28
52
|
* so --background re-resolves at the call site under a scoped [data-tenant]/.dark theme. */
|
|
29
53
|
--filter-bar-sticky-background: initial;
|
|
54
|
+
/* Scrollbar gutter reserved under a `overflow="scroll"` filter strip (#216) so the inline
|
|
55
|
+
* scrollbar never overlaps the controls. Rule #45 — a service theme retunes it to its grid
|
|
56
|
+
* (0 on an overlay-scrollbar platform). */
|
|
57
|
+
--filter-bar-scroll-padding-y: var(--space-1);
|
|
30
58
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* Sheet RESPONSIVE (drawer / detail-panel) geometry.
|
|
2
|
+
*
|
|
3
|
+
* Lives in its own tier file rather than in feedback.css because these two knobs are the
|
|
4
|
+
* *responsive* contract (`SheetContent responsive="auto"`), not the static panel chrome —
|
|
5
|
+
* see feedback.css for --sheet-width-default / --sheet-pad-* / --sheet-overlay-background.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
:root {
|
|
9
|
+
/* Viewport width at and below which `SheetContent responsive="auto"` renders the mobile bottom
|
|
10
|
+
* sheet instead of the desktop side panel. Read at runtime by useSheetResponsiveMode() (a CSS
|
|
11
|
+
* @media cannot resolve a custom property), so a service moves the drawer breakpoint from ONE
|
|
12
|
+
* knob for every overlay that opts into the responsive contract — Sheet and OrgSwitcher alike.
|
|
13
|
+
* 48rem = 768px mirrors the library's canonical mobile line (useIsMobile). Accepts px/rem/em. */
|
|
14
|
+
--sheet-responsive-breakpoint-width: 48rem;
|
|
15
|
+
/* Block size cap for the responsive BOTTOM presentation only (never for a plain
|
|
16
|
+
* `side="bottom"` sheet, which stays content-sized). Keeps the sheet below the viewport so the
|
|
17
|
+
* SheetBody scrolls and the page behind it stays visible/dismissable. */
|
|
18
|
+
--sheet-bottom-max-height: 85dvh;
|
|
19
|
+
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
--sidebar-product-tenant-font-size: var(--font-size-2xs);
|
|
8
8
|
--sidebar-badge-font-size: var(--font-size-2xs);
|
|
9
9
|
--sidebar-user-role-font-size: var(--font-size-2xs);
|
|
10
|
+
--org-switcher-meta-foreground: var(--muted-foreground);
|
|
10
11
|
--sidebar-nav-sub-font-size: var(--font-size-xs);
|
|
11
12
|
--sidebar-flyout-title-font-size: var(--font-size-xs);
|
|
12
13
|
--topbar-chip-icon-font-size: var(--font-size-2xs);
|
|
@@ -23,12 +24,74 @@
|
|
|
23
24
|
/* DXS application-shell geometry. These defaults mirror the checked-in
|
|
24
25
|
* Admin/Console hi-fi source while remaining themeable by consumers. */
|
|
25
26
|
--app-shell-bar-height: 3rem;
|
|
27
|
+
/* Inline inset and slot gap of the AppShell top bar. `-compact` applies below the shell
|
|
28
|
+
* breakpoint (the docked sidebar is gone, so the bar tightens against the viewport edge). */
|
|
29
|
+
--app-shell-bar-inset: var(--space-4);
|
|
30
|
+
--app-shell-bar-inset-compact: var(--space-3);
|
|
31
|
+
--app-shell-bar-gap: var(--space-3);
|
|
32
|
+
/* Docked navigation rail widths — the SINGLE most-retuned shell constant (rule #45). A service
|
|
33
|
+
* that designs on a different grid sets `--app-shell-sidebar-width: 15.9375rem` (255px) once
|
|
34
|
+
* instead of forking `.app-root`. `-rail-` is the icon-only width used at
|
|
35
|
+
* `<AppShell sidebarCollapsed>`. */
|
|
36
|
+
--app-shell-sidebar-width: 16rem;
|
|
37
|
+
--app-shell-rail-width: 4rem;
|
|
26
38
|
--app-shell-page-max-width: 80rem;
|
|
27
39
|
--app-shell-main-background: hsl(var(--muted) / 0.4);
|
|
40
|
+
--app-shell-mobile-nav-width: 22.5rem;
|
|
41
|
+
/* Mobile-drawer scrim — `initial` so the shared --overlay-background default re-resolves at the
|
|
42
|
+
* CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding freezes at :root). Default =
|
|
43
|
+
* var(--app-shell-mobile-nav-alpha) of the global scrim, i.e. rgb(0 0 0 / 0.2) out of the box. */
|
|
44
|
+
--app-shell-mobile-nav-background: initial;
|
|
45
|
+
/* Share of the global --overlay-background this drawer's scrim uses. A slide-in drawer washes the
|
|
46
|
+
* page more lightly than a modal dialog; keeping it a RATIO means a service retints the whole
|
|
47
|
+
* system with one --overlay-background and every overlay keeps its calibrated depth. */
|
|
48
|
+
--app-shell-mobile-nav-alpha: 40%;
|
|
49
|
+
/* Inline inset of the mobile drawer's scrollable nav body. Near-zero by design: the drawer nav
|
|
50
|
+
* (the <Sidebar> node by default) owns its own inset via --sidebar-nav-scroll-padding, so the
|
|
51
|
+
* generic sheet chrome inset must NOT stack on top of it (gh#211). Set it to var(--space-6) for
|
|
52
|
+
* a custom mobileNav node that wants the full sheet chrome inset. */
|
|
53
|
+
--app-shell-mobile-nav-inset: var(--space-1);
|
|
28
54
|
--sidebar-brand-mark-size: 1.375rem;
|
|
29
55
|
--sidebar-nav-item-height: 2rem;
|
|
30
56
|
--sidebar-nav-item-font-size: 0.8125rem;
|
|
57
|
+
/* Line box of the nav LABEL, not the row (gh#254): `.sb-label` clips, so its line box is its clip
|
|
58
|
+
* box, and the row's `line-height: 1` shears descenders and Vietnamese tone marks. Keep >= 1.2. */
|
|
59
|
+
--sidebar-nav-item-line-height: 1.5;
|
|
60
|
+
/* Same gh#254 trap, two more clipping boxes. `.ui-auth-account-email` and the truncating last
|
|
61
|
+
* child of `.ui-topbar-start` both clip (`overflow: hidden`/`clip` + `text-overflow: ellipsis`),
|
|
62
|
+
* so their line box IS their clip box — inheriting a tight value shears descenders and Vietnamese
|
|
63
|
+
* tone marks exactly as the sidebar label did. Keep >= 1.2. */
|
|
64
|
+
--auth-account-summary-email-line-height: 1.5;
|
|
65
|
+
--topbar-start-truncate-line-height: 1.5;
|
|
66
|
+
--sidebar-nav-icon-size: 1rem;
|
|
67
|
+
--sidebar-nav-item-gap: 0.625rem;
|
|
68
|
+
--sidebar-nav-item-padding-x: 0.625rem;
|
|
69
|
+
--sidebar-nav-gap: 2px;
|
|
70
|
+
--sidebar-nav-scroll-padding: var(--space-3) var(--space-2);
|
|
71
|
+
--sidebar-section-gap: var(--space-4);
|
|
72
|
+
--sidebar-section-label-padding-x: var(--space-2);
|
|
73
|
+
--sidebar-section-label-padding-bottom: var(--space-1);
|
|
31
74
|
--topbar-search-max-width: 26.25rem;
|
|
75
|
+
/* Standalone <Topbar> geometry (rule #45). Topbar is a pure slot bar, so its box is intentionally
|
|
76
|
+
* QUIET by default: `auto` height and no inline inset, i.e. exactly what it did before these knobs
|
|
77
|
+
* existed — inside AppShell the `.app-topbar` grid row still owns the height. A service that
|
|
78
|
+
* places Topbar directly on a page sets `--topbar-height: 3.5rem` / `--topbar-inset: var(--space-4)`
|
|
79
|
+
* once instead of writing an app-local class. `--topbar-gap` is the gap BETWEEN the start/center/end
|
|
80
|
+
* clusters and INSIDE each of them, so one knob re-rhythms the whole bar. */
|
|
81
|
+
--topbar-height: auto;
|
|
82
|
+
--topbar-inset: 0px;
|
|
83
|
+
--topbar-gap: var(--space-2);
|
|
84
|
+
/* At compact desktop/tablet widths the docked sidebar leaves too little inline room for three
|
|
85
|
+
* intrinsically-sized clusters. The package hides the optional center slot before it can cover
|
|
86
|
+
* the breadcrumb/title or end utilities. Consumers may opt back into another display strategy
|
|
87
|
+
* (for example `flex`) once their center content has its own compact presentation. */
|
|
88
|
+
--topbar-center-compact-display: none;
|
|
89
|
+
--org-switcher-trigger-height: 2.75rem;
|
|
90
|
+
--org-switcher-trigger-padding-x: var(--space-2);
|
|
91
|
+
--org-switcher-avatar-size: 1.75rem;
|
|
92
|
+
--org-switcher-menu-width: 16rem;
|
|
93
|
+
--org-switcher-sheet-max-height: 75dvh;
|
|
94
|
+
--org-switcher-state-min-height: 8rem;
|
|
32
95
|
|
|
33
96
|
/* Sidebar active-item tint/marker — `initial` so the role defaults re-resolve at the call site
|
|
34
97
|
* under a scoped theme (a :root binding to a role var freezes at :root; a scoped role override
|
|
@@ -53,6 +116,114 @@
|
|
|
53
116
|
--auth-shell-main-padding: var(--space-6);
|
|
54
117
|
--auth-shell-footer-padding: var(--space-3) var(--space-6) var(--space-4);
|
|
55
118
|
|
|
119
|
+
/* Canonical DXS auth preset. These are public theme knobs: consumers select the preset once on
|
|
120
|
+
* AuthShell and may retune the product theme here rather than overriding individual fields. */
|
|
121
|
+
--auth-shell-canonical-control-height: 2.25rem;
|
|
122
|
+
--auth-shell-canonical-card-max-width: 22.5rem;
|
|
123
|
+
--auth-shell-canonical-heading-size: var(--font-size-base);
|
|
124
|
+
--auth-shell-canonical-main-padding: 1rem;
|
|
125
|
+
--auth-shell-canonical-main-padding-mobile: 0.9375rem;
|
|
126
|
+
/* INLINE (start/end) inset of the compact auth card — the column the title, fields and actions
|
|
127
|
+
* align to. Independent of the block axis below (gh#232). */
|
|
128
|
+
--auth-shell-compact-card-inset: var(--space-6);
|
|
129
|
+
/* BLOCK (top/bottom) padding of the compact auth card — the knob that tunes canonical Login card
|
|
130
|
+
* HEIGHT without narrowing the column. Bound to the card's --card-space-shell-y, so it really
|
|
131
|
+
* reaches CardContent's block edges (before gh#232 it was wired only to --card-space-body-y and
|
|
132
|
+
* the rendered body kept the inset on both block edges — the documented token did nothing).
|
|
133
|
+
* Declared `initial` so the default mirrors the LIVE --auth-shell-compact-card-inset resolved at
|
|
134
|
+
* the CALL SITE: the canonical card renders exactly as before (24px block = 24px inline), and a
|
|
135
|
+
* service that re-tunes the inset inside a scoped `[data-tenant]` still drags the block default
|
|
136
|
+
* with it (a :root binding would freeze at the :root inset — docs/TOKENS.md). */
|
|
137
|
+
--auth-shell-card-padding-block-compact: initial; /* default = var(--auth-shell-compact-card-inset) */
|
|
138
|
+
/* Header↔body gap inside the compact auth card (the breathing room under the title before the
|
|
139
|
+
* first field). Its own knob since gh#232 — it used to ride on
|
|
140
|
+
* --auth-shell-card-padding-block-compact, which conflated the section gap with the card's block
|
|
141
|
+
* padding and made the block knob un-tunable. Default is the pre-gh#232 12px rhythm. */
|
|
142
|
+
--auth-shell-card-body-gap-compact: var(--space-3);
|
|
143
|
+
/* IN-SLOT stack gap of the compact auth card (title ↕ description inside the header). */
|
|
144
|
+
--auth-shell-card-gap-compact: var(--space-3);
|
|
145
|
+
|
|
146
|
+
/* Named AUTH FLOW PRESETS (gh#217 / gh#220). A preset owns the whole page measure for one
|
|
147
|
+
* canonical hosted-identity flow — card max-width plus the desktop and mobile page gutters — so a
|
|
148
|
+
* consumer selects `preset` once instead of hand-overriding --auth-shell-card-max-width. Presets
|
|
149
|
+
* are orthogonal to `variant` (which owns control density / heading size) and are applied AFTER
|
|
150
|
+
* it, so `variant="canonical" preset="device-authorization"` keeps the canonical chrome and only
|
|
151
|
+
* re-measures the page. Literal lengths (not --space-*) because the canonical artboards specify
|
|
152
|
+
* exact device pixels that must not drift with --scaling. */
|
|
153
|
+
|
|
154
|
+
/* Main-axis alignment of the auth column. Default `center` = today's vertically-centred card;
|
|
155
|
+
* a flow whose intro + card + footnote stack is tall opts into `start` via this knob. */
|
|
156
|
+
--auth-shell-main-align: center;
|
|
157
|
+
/* Gap between the direct sections of the auth column (intro · card · remember row). Default 0
|
|
158
|
+
* (quiet, rule #44) so an existing single-card consumer is untouched; presets opt in. */
|
|
159
|
+
--auth-shell-card-stack-gap: 0px;
|
|
160
|
+
|
|
161
|
+
/* Login preset (gh#237) — canonical SCR-001 anchors at 1440x900, 1024x900 and 390x844.
|
|
162
|
+
* The 112px identity slot is deliberately taller than a two-line real requester. Identity
|
|
163
|
+
* content aligns to the slot end, so missing/one-line/two-line requester data changes only the
|
|
164
|
+
* empty space above it, never the card or footer position. The flow starts at y=231 desktop and
|
|
165
|
+
* y=221 mobile: 231/221 + 112 + 20 gap = card y=363/353. Literal artboard lengths belong here,
|
|
166
|
+
* not in a consumer selector, and do not drift with --scaling. */
|
|
167
|
+
--auth-shell-login-card-max-width: 22.5rem;
|
|
168
|
+
--auth-shell-login-flow-offset-block: 14.4375rem;
|
|
169
|
+
--auth-shell-login-flow-offset-block-mobile: 13.8125rem;
|
|
170
|
+
--auth-shell-login-main-padding-inline: 1rem;
|
|
171
|
+
--auth-shell-login-main-padding-inline-mobile: 0.9375rem;
|
|
172
|
+
--auth-shell-login-main-padding-block-end: 1rem;
|
|
173
|
+
--auth-shell-login-identity-slot-block-size: 7rem;
|
|
174
|
+
--auth-shell-login-card-stack-gap: 1.25rem;
|
|
175
|
+
--auth-shell-login-card-padding-block-compact: calc(
|
|
176
|
+
var(--auth-shell-compact-card-inset) + var(--control-border-width) + var(--control-border-width)
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
/* Device-authorization preset — 380px card measure, 15px block · 5px inline mobile gutter
|
|
180
|
+
* (at a 390px viewport the card is x=5px, width=380px). */
|
|
181
|
+
--auth-shell-device-card-max-width: 23.75rem;
|
|
182
|
+
--auth-shell-device-main-padding: 1rem;
|
|
183
|
+
--auth-shell-device-main-padding-mobile: 0.9375rem 0.3125rem;
|
|
184
|
+
|
|
185
|
+
/* Context-selection preset — 25rem card measure on desktop/tablet, edge-to-edge on mobile
|
|
186
|
+
* (0 inline gutter) with a 16px rhythm between the intro, the card and the remember row. */
|
|
187
|
+
--auth-shell-context-card-max-width: 25rem;
|
|
188
|
+
--auth-shell-context-main-padding: var(--space-6);
|
|
189
|
+
--auth-shell-context-main-padding-mobile: var(--space-6) 0;
|
|
190
|
+
--auth-shell-context-card-stack-gap: 1rem;
|
|
191
|
+
|
|
192
|
+
/* Account-recovery preset (gh#233) — the SCR-008 measure shared by the password-recovery panel
|
|
193
|
+
* (request · sent · new-password · expired) and the sign-in MFA challenge panel (OTP ·
|
|
194
|
+
* recovery-code · passkey-failure). Both canonical desktop panels measure w=432 at 1440, so ONE
|
|
195
|
+
* preset owns them; the 360px canonical Login measure is untouched.
|
|
196
|
+
* The mobile gutter is a DECIDED contract, not a traced artboard: the supplied 390 reference is a
|
|
197
|
+
* desktop 2x2 composite that crops horizontally and cannot be measured. 15px inline at 390 ⇒ the
|
|
198
|
+
* panel is x=15, width=360 — the same page rhythm as the canonical Login flow, so a user moving
|
|
199
|
+
* from Login to Recovery on a phone never sees the surface jump. */
|
|
200
|
+
--auth-shell-recovery-card-max-width: 27rem;
|
|
201
|
+
--auth-shell-recovery-main-padding: 1rem;
|
|
202
|
+
--auth-shell-recovery-main-padding-mobile: 0.9375rem;
|
|
203
|
+
|
|
204
|
+
/* Labelled auth divider geometry. */
|
|
205
|
+
--auth-shell-divider-gap: 0.625rem;
|
|
206
|
+
--auth-shell-divider-label-font-size: 0.6875rem;
|
|
207
|
+
--auth-shell-divider-rule-color: var(--border);
|
|
208
|
+
--auth-shell-divider-label-color: var(--muted-foreground);
|
|
209
|
+
--auth-identity-gap: 0.375rem;
|
|
210
|
+
--auth-requester-gap: 0.375rem;
|
|
211
|
+
--auth-requester-icon-size: 1rem;
|
|
212
|
+
--auth-requester-glyph-size: 0.625rem;
|
|
213
|
+
--auth-account-summary-min-height: var(--control-height-comfortable);
|
|
214
|
+
--auth-account-summary-gap: var(--space-2);
|
|
215
|
+
--auth-account-summary-padding: var(--space-1) var(--space-2);
|
|
216
|
+
--auth-account-summary-identity-min-width: 12rem;
|
|
217
|
+
--auth-account-summary-avatar-size: var(--control-height-sm);
|
|
218
|
+
--auth-account-summary-avatar-glyph-size: var(--control-icon-size-sm);
|
|
219
|
+
--auth-account-summary-email-font-size: var(--font-size-sm);
|
|
220
|
+
--auth-footer-content-gap: 0.375rem;
|
|
221
|
+
--auth-footer-text-font-size: 0.6875rem;
|
|
222
|
+
--auth-stack-gap: var(--space-3);
|
|
223
|
+
--auth-shell-field-label-gap: var(--space-1);
|
|
224
|
+
--auth-shell-field-label-font-size: var(--font-size-xs);
|
|
225
|
+
--auth-shell-field-label-line-height: 1.25;
|
|
226
|
+
|
|
56
227
|
/* CenteredShell — authenticated, no-sidebar, centred-column page shell (hosted-ID "My Page",
|
|
57
228
|
* account, standalone settings). The bar mirrors AppShell's `.app-topbar` chrome (fixed height +
|
|
58
229
|
* inline padding); the column max-width has three tiers, all wider than the 24rem auth card. A
|
|
@@ -61,7 +232,46 @@
|
|
|
61
232
|
--centered-shell-bar-padding-x: var(--space-4);
|
|
62
233
|
--centered-shell-main-padding: var(--space-6);
|
|
63
234
|
--centered-shell-footer-padding: var(--space-3) var(--space-6) var(--space-4);
|
|
235
|
+
/* Block offset of the centred column inside the 100dvh shell. `0` (default, the quietest state —
|
|
236
|
+
* rule #44) keeps the top-aligned flowing page; `auto` centres the column in the viewport, which
|
|
237
|
+
* is what CenteredShell `align="center"` sets for a SYSTEM-level standalone surface (500/503
|
|
238
|
+
* error page, maintenance notice). Auto block offsets collapse to 0 when the content is taller
|
|
239
|
+
* than the viewport, so a long localized message scrolls from the top instead of clipping. */
|
|
240
|
+
--centered-shell-column-offset-block: 0;
|
|
64
241
|
--centered-shell-width-sm: 32rem;
|
|
65
242
|
--centered-shell-width-md: 46rem;
|
|
66
243
|
--centered-shell-width-lg: 64rem;
|
|
67
244
|
}
|
|
245
|
+
|
|
246
|
+
/* CenteredShell · public-landing preset (gh#252) — the token-owned geometry of a PUBLIC marketing
|
|
247
|
+
* / product landing page: one content measure shared by header, main column and footer, the
|
|
248
|
+
* section rhythm between page sections, the flat (chrome-quiet) card presentation and the hero
|
|
249
|
+
* heading tier. Every value is a service-themeable knob (rule #45): a landing composition is a
|
|
250
|
+
* COMPOSITION of real primitives (docs/COMPOSITION-VS-COMPONENT.md — Hero/Navbar/Footer FAIL the
|
|
251
|
+
* Framework-Component Test), so the consumer must never own geometry or a media query. These
|
|
252
|
+
* knobs are read ONLY under `.ui-centered-shell[data-preset="public-landing"]`, so the default
|
|
253
|
+
* shell — which emits no `data-preset` at all — is byte-identical to before. */
|
|
254
|
+
:root {
|
|
255
|
+
--centered-shell-landing-max-width: 67.5rem; /* 1080px — header/main/footer share ONE measure */
|
|
256
|
+
--centered-shell-landing-inset-inline: var(--space-6); /* 24px page gutter ≥ 40rem */
|
|
257
|
+
--centered-shell-landing-inset-inline-compact: var(--space-4); /* 16px page gutter < 40rem */
|
|
258
|
+
--centered-shell-landing-main-padding-block: var(--space-10); /* 40px */
|
|
259
|
+
--centered-shell-landing-main-padding-block-compact: var(--space-6); /* 24px */
|
|
260
|
+
--centered-shell-landing-section-gap: var(--space-10); /* rhythm BETWEEN page sections */
|
|
261
|
+
--centered-shell-landing-section-gap-compact: var(--space-6);
|
|
262
|
+
--centered-shell-landing-footer-padding-block: var(--space-8);
|
|
263
|
+
/* Chrome is a token, default quiet (rule #44): a landing surface is FLAT — no card elevation —
|
|
264
|
+
* so a service opts back IN with `--centered-shell-landing-card-shadow: var(--card-shadow)`. */
|
|
265
|
+
--centered-shell-landing-card-shadow: none;
|
|
266
|
+
/* Hero heading tier. The preset re-points `--heading-h1` (same mechanism as
|
|
267
|
+
* `.ui-auth-shell` → `--auth-shell-heading-size`), so a hero title is a real `Heading level={1}`
|
|
268
|
+
* and never a consumer font-size. */
|
|
269
|
+
--centered-shell-landing-heading-size: var(--font-size-display);
|
|
270
|
+
--centered-shell-landing-heading-size-compact: var(--font-size-3xl);
|
|
271
|
+
/* Role-mirror knob — MUST stay `initial`, with the role default at the CALL SITE
|
|
272
|
+
* (`var(--centered-shell-landing-background, var(--background))`), so a scoped
|
|
273
|
+
* `[data-tenant]` / `.dark` override of `--background` still reaches it (docs/TOKENS.md ·
|
|
274
|
+
* "Role-mirror knobs MUST be `initial`"). Documented default = hsl(var(--background)) — a public
|
|
275
|
+
* page is the plain page canvas, not the app's `--muted` chrome. */
|
|
276
|
+
--centered-shell-landing-background: initial;
|
|
277
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* Sidebar nav-row COLOUR knobs (gh#228). The row/label and its icon are separately themeable:
|
|
2
|
+
* before this, `.sb-nav-item` painted one `--muted-foreground` that the Lucide SVG inherited, so a
|
|
3
|
+
* service could only darken its 16px nav icons by writing page-local CSS or by re-tinting every
|
|
4
|
+
* muted text globally. Geometry knobs (--sidebar-nav-icon-size, --sidebar-nav-item-height/-gap/
|
|
5
|
+
* -padding-x) live in components/shell.css and are untouched by these.
|
|
6
|
+
*
|
|
7
|
+
* ROLE-MIRROR KNOBS — declared `initial` here with the role default at the CALL SITE
|
|
8
|
+
* (`var(--knob, hsl(var(--role)))`), so a scoped `[data-tenant]` / `.dark` role override
|
|
9
|
+
* re-resolves live instead of freezing at :root (docs/TOKENS.md · "Role-mirror knobs MUST be
|
|
10
|
+
* `initial`"). Every default is byte-identical to the pre-gh#228 rendering.
|
|
11
|
+
*
|
|
12
|
+
* The ACTIVE row's own background/foreground keep their existing knobs
|
|
13
|
+
* (--sidebar-item-active-background / --sidebar-item-active-foreground, components/shell.css);
|
|
14
|
+
* only the active ICON gets a new one. */
|
|
15
|
+
|
|
16
|
+
:root {
|
|
17
|
+
/* Resting nav row + label (also the resting sub-row). Default = hsl(var(--muted-foreground)). */
|
|
18
|
+
--sidebar-nav-item-foreground: initial;
|
|
19
|
+
/* Hovered nav row + label. Default = hsl(var(--foreground)). */
|
|
20
|
+
--sidebar-nav-item-hover-foreground: initial;
|
|
21
|
+
/* `aria-disabled` nav row + label. Default = the resting row colour. */
|
|
22
|
+
--sidebar-nav-item-disabled-foreground: initial;
|
|
23
|
+
|
|
24
|
+
/* Nav ICON (`.sb-icon`, incl. the collapsed rail and group triggers). Default = currentColor,
|
|
25
|
+
* i.e. the row colour — the pre-gh#228 look. Set this alone to get canonical dark icons next to
|
|
26
|
+
* muted labels. */
|
|
27
|
+
--sidebar-nav-icon-foreground: initial;
|
|
28
|
+
/* Icon on a hovered / active / disabled row. Each falls back to --sidebar-nav-icon-foreground,
|
|
29
|
+
* then to currentColor, so setting the base icon knob alone themes every state. */
|
|
30
|
+
--sidebar-nav-icon-hover-foreground: initial;
|
|
31
|
+
--sidebar-nav-icon-active-foreground: initial;
|
|
32
|
+
--sidebar-nav-icon-disabled-foreground: initial;
|
|
33
|
+
}
|
|
@@ -7,6 +7,29 @@
|
|
|
7
7
|
--table-row-height: calc(var(--table-row-height-default) * var(--scaling));
|
|
8
8
|
--table-cell-padding-y: var(--space-2);
|
|
9
9
|
--table-cell-space-x: var(--control-padding-x);
|
|
10
|
+
/* Pagination footer inset (gh#236). The footer ships as a SELF-CONTAINED slot and is commonly
|
|
11
|
+
* placed in a flush container (`<Card><CardContent flush><DataTable/>`), where no ancestor
|
|
12
|
+
* supplies padding — so it owns its own on BOTH axes instead of declaring block-start only.
|
|
13
|
+
* Block default = the previous single `padding-top` value, now on both block edges (breathing
|
|
14
|
+
* room above the footer and before the container's closing border). Inline default = the cell
|
|
15
|
+
* inline padding, so the "rows per page" label sits on the same optical axis as the first
|
|
16
|
+
* column's text. A service retunes either axis to its own grid (#45).
|
|
17
|
+
* Both are declared `initial` so the defaults re-resolve at the CALL SITE: --space-stack-sm and
|
|
18
|
+
* --table-cell-space-x are density-scaled and re-declared inside a `.ui-density-*` subtree, and a
|
|
19
|
+
* :root binding would freeze the footer at the :root density (docs/TOKENS.md — the :root freeze
|
|
20
|
+
* rule). Defaults = var(--space-stack-sm) block · var(--table-cell-space-x) inline. */
|
|
21
|
+
--table-pagination-padding-y: initial;
|
|
22
|
+
--table-pagination-padding-x: initial;
|
|
23
|
+
/* DataTable surface — narrow-viewport legibility FLOOR (gh#253). Below the `sm` viewport step a
|
|
24
|
+
* multi-column admin grid whose columns are `white-space: nowrap` would otherwise be crushed, so
|
|
25
|
+
* the bordered surface keeps a minimum inline size and `.ui-data-table-scroll` scrolls instead.
|
|
26
|
+
* This shipped as a hard-coded `min-w-[640px]` utility on the surface element, which left a
|
|
27
|
+
* service that wants a narrower (or no) floor with no route but forking the component (#45).
|
|
28
|
+
* Default = the previous literal, in px so the floor releases at EXACTLY the same width as the
|
|
29
|
+
* px-based `sm` media query that clears it (a rem value would drift under a non-16px root and
|
|
30
|
+
* re-introduce the scroll between the two thresholds). Set `0` to opt out entirely — which is
|
|
31
|
+
* what `preset="action-collection"` does, because there the priority measures own the width. */
|
|
32
|
+
--table-surface-min-inline-size: 640px;
|
|
10
33
|
--table-head-font-size: var(--font-size-xs);
|
|
11
34
|
/* Header band — its OWN bg + fg knobs (decoupled from --secondary). Declared `initial` so the
|
|
12
35
|
* default re-resolves to the LIVE --muted / --muted-foreground roles at the call site: a :root
|
|
@@ -24,3 +47,25 @@
|
|
|
24
47
|
--table-row-hover-background: initial;
|
|
25
48
|
--table-row-selected-background: initial;
|
|
26
49
|
}
|
|
50
|
+
|
|
51
|
+
/* Table · action-collection preset (gh#253) — the canonical dense approval / action queue.
|
|
52
|
+
* Column PRIORITY measures replace the desktop intrinsic widths (a nowrap free-text column is
|
|
53
|
+
* what makes a five-column queue wider than its card and forces a horizontal scroll). Nothing
|
|
54
|
+
* here is read unless `preset="action-collection"` is set, so every existing table is untouched.
|
|
55
|
+
* Percentages so the ratio holds at any card width; the action affordance is an absolute measure
|
|
56
|
+
* because it must never be squeezed below its touch target. */
|
|
57
|
+
:root {
|
|
58
|
+
--table-action-collection-primary-width: 18%; /* requester / subject */
|
|
59
|
+
--table-action-collection-secondary-width: 22%; /* target / resource */
|
|
60
|
+
--table-action-collection-meta-width: 12%; /* timestamps, ids — lowest priority */
|
|
61
|
+
--table-action-collection-actions-width: 3.5rem; /* row-action affordance, never clipped */
|
|
62
|
+
/* Compact tier, applied below the collapse step (the 390px acceptance frame). */
|
|
63
|
+
--table-action-collection-primary-width-compact: 24%;
|
|
64
|
+
--table-action-collection-secondary-width-compact: 22%;
|
|
65
|
+
--table-action-collection-meta-width-compact: 20%;
|
|
66
|
+
--table-action-collection-actions-width-compact: 2.75rem;
|
|
67
|
+
--table-action-collection-font-size-compact: var(--font-size-xs);
|
|
68
|
+
--table-action-collection-cell-space-x-compact: var(--space-2);
|
|
69
|
+
--table-action-collection-cell-padding-y-compact: var(--space-2);
|
|
70
|
+
--table-action-collection-row-height-compact: var(--table-row-height-compact);
|
|
71
|
+
}
|