@godxjp/ui 18.9.0 → 18.10.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/LICENSE +202 -0
- package/dist/components/data-display/badge.d.ts +7 -0
- package/dist/components/data-display/badge.js +1 -1
- package/dist/components/data-display/card.d.ts +3 -27
- package/dist/components/data-display/card.js +1 -4
- package/dist/components/data-display/data-table.js +5 -4
- package/dist/components/data-display/index.d.ts +2 -0
- package/dist/components/data-display/index.js +2 -0
- package/dist/components/data-display/permission-matrix.d.ts +26 -0
- package/dist/components/data-display/permission-matrix.js +219 -0
- package/dist/components/data-display/table.d.ts +12 -0
- package/dist/components/data-entry/branch-scope-picker.d.ts +43 -0
- package/dist/components/data-entry/branch-scope-picker.js +200 -0
- package/dist/components/data-entry/command-palette.d.ts +1 -42
- package/dist/components/data-entry/command-palette.js +2 -31
- package/dist/components/data-entry/index.d.ts +2 -0
- package/dist/components/data-entry/index.js +2 -0
- package/dist/components/data-entry/input-otp.d.ts +1 -1
- package/dist/components/feedback/alert.d.ts +2 -20
- package/dist/components/feedback/alert.js +1 -11
- package/dist/components/feedback/banner.d.ts +21 -0
- package/dist/components/feedback/banner.js +15 -0
- package/dist/components/feedback/index.d.ts +4 -2
- package/dist/components/feedback/index.js +2 -2
- package/dist/components/general/typography.d.ts +1 -0
- package/dist/components/general/typography.js +32 -13
- package/dist/components/layout/auth-shell.d.ts +2 -2
- package/dist/components/layout/index.d.ts +2 -2
- package/dist/components/layout/index.js +2 -2
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +45 -19
- package/dist/components/layout/service-role-panel.d.ts +25 -0
- package/dist/components/layout/service-role-panel.js +206 -0
- package/dist/components/navigation/filter-bar.d.ts +2 -2
- package/dist/components/navigation/filter-bar.js +113 -34
- package/dist/components/navigation/index.d.ts +1 -1
- package/dist/components/navigation/steps.d.ts +2 -2
- package/dist/components/navigation/steps.js +2 -4
- package/dist/components/ui/avatar.d.ts +1 -1
- package/dist/components/ui/avatar.js +1 -2
- package/dist/components/ui/input-otp.d.ts +3 -15
- package/dist/components/ui/input-otp.js +1 -2
- package/dist/email/tokens.generated.d.ts +2 -2
- package/dist/email/tokens.generated.js +2 -2
- package/dist/i18n/messages/en.json +56 -4
- package/dist/i18n/messages/ja.json +51 -5
- package/dist/i18n/messages/vi.json +50 -4
- package/dist/props/components/data-display.prop.d.ts +66 -16
- package/dist/props/components/data-entry.prop.d.ts +54 -7
- package/dist/props/components/feedback.prop.d.ts +3 -3
- package/dist/props/components/general.prop.d.ts +8 -1
- package/dist/props/components/layout.prop.d.ts +75 -54
- package/dist/props/components/navigation.prop.d.ts +77 -59
- package/dist/props/registry.d.ts +274 -73
- package/dist/props/registry.js +362 -93
- package/dist/props/vocabulary/content.prop.d.ts +5 -0
- package/dist/props/vocabulary/index.d.ts +1 -1
- package/dist/props/vocabulary/interaction.prop.d.ts +4 -7
- package/dist/props/vocabulary/layout.prop.d.ts +2 -2
- package/dist/styles/alert-layout.css +15 -32
- package/dist/styles/badge-layout.css +5 -0
- package/dist/styles/base.css +0 -28
- package/dist/styles/card-layout.css +13 -49
- package/dist/styles/control.css +2 -12
- package/dist/styles/data-display-layout.css +0 -16
- package/dist/styles/layout.css +102 -108
- package/dist/styles/navigation-layout.css +3 -8
- package/dist/styles/shell-layout.css +17 -17
- package/dist/styles/table-layout.css +77 -29
- package/dist/styles/text-layout.css +13 -0
- package/dist/tokens/base.css +1 -0
- package/dist/tokens/components/badge.css +5 -0
- package/dist/tokens/components/banner.css +16 -0
- package/dist/tokens/components/card.css +0 -12
- package/dist/tokens/components/control.css +0 -16
- package/dist/tokens/components/data-display.css +0 -12
- package/dist/tokens/components/email.css +2 -8
- package/dist/tokens/components/feedback.css +0 -20
- package/dist/tokens/components/navigation.css +10 -34
- package/dist/tokens/components/shell.css +24 -36
- package/dist/tokens/components/table.css +41 -22
- package/dist/tokens/semantic/layout.css +5 -12
- package/package.json +15 -2
- package/dist/components/layout/page-header.d.ts +0 -22
- package/dist/components/layout/page-header.js +0 -89
package/dist/styles/base.css
CHANGED
|
@@ -28,34 +28,6 @@
|
|
|
28
28
|
* ───────────────────────────────────────────────────────────────────────── */
|
|
29
29
|
@import "tailwindcss";
|
|
30
30
|
|
|
31
|
-
/* ── THE LAYER CONTRACT (gh#412) ───────────────────────────────────────────
|
|
32
|
-
* `@import "tailwindcss"` establishes `theme, base, components, utilities`. Everything this
|
|
33
|
-
* package styles lives in `@layer components`, which is EARLIER than `utilities` — so a Tailwind
|
|
34
|
-
* utility a component itself emits silently outranks the package rule that is supposed to own the
|
|
35
|
-
* same property, no matter how specific that rule is. That is not a specificity bug you can fix
|
|
36
|
-
* with another selector; layer order beats specificity outright.
|
|
37
|
-
*
|
|
38
|
-
* It shipped as a real defect: `<table class="… text-sm">` (utilities) vs the collection preset's
|
|
39
|
-
* `font-size: var(--table-action-collection-font-size-compact)` (components) — the compact type
|
|
40
|
-
* tier never applied at ANY width, so the documented token was dead and a 5–6 character Japanese
|
|
41
|
-
* label could not fit the narrow-frame column measure (WCAG 2.2 SC 1.4.10, and only ever visible
|
|
42
|
-
* in Japanese). Two independent consumers reported it.
|
|
43
|
-
*
|
|
44
|
-
* `godxjp-ui-responsive` is declared HERE, after Tailwind, so it is the LAST layer and outranks
|
|
45
|
-
* `utilities`. It is reserved for one thing: RESPONSIVE RE-POINTS — the container/media blocks
|
|
46
|
-
* that must win over a component's own static utility for the layout contract to hold. Nothing
|
|
47
|
-
* static belongs in it; a rule that does not sit inside a `@container`/`@media` query goes in
|
|
48
|
-
* `@layer components` like everything else.
|
|
49
|
-
*
|
|
50
|
-
* What this layer canNOT do — and the rule consumers must follow: an UNLAYERED consumer rule
|
|
51
|
-
* outranks EVERY layer, including this one. So app CSS must theme this package through TOKENS on
|
|
52
|
-
* a wrapper, never by writing its own selectors against `[data-slot]` / `[data-priority]`
|
|
53
|
-
* elements. A consumer that does write such a rule must put it in a layer
|
|
54
|
-
* (`@layer components { … }`), or it will silently kill the responsive re-points the package
|
|
55
|
-
* makes — a column measured to 0px and wrapped one character per line is what that looks like.
|
|
56
|
-
* See docs/TOKENS.md · "The layer contract". */
|
|
57
|
-
@layer godxjp-ui-responsive;
|
|
58
|
-
|
|
59
31
|
/* Per-language font wiring — token-only, NO hardcoded faces. Each locale reads
|
|
60
32
|
* an OPTIONAL per-lang slot token (empty by default) and falls back to the
|
|
61
33
|
* base sans. Consumers switch a locale's face by setting its slot, e.g.
|
|
@@ -51,16 +51,9 @@
|
|
|
51
51
|
background: transparent;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
/* `featured` = the brand-toned perimeter. Its colour is a role-mirror knob (rule #45): declared
|
|
55
|
-
* `initial` in the token layer so the --primary default resolves HERE, at the call site, and a
|
|
56
|
-
* scoped [data-tenant]/.dark override of --primary still reaches it. A service that wants the
|
|
57
|
-
* featured ring in a non-brand tone overrides --card-featured-border-color; a card that wants a
|
|
58
|
-
* SEMANTIC perimeter (attention / destructive / success …) uses
|
|
59
|
-
* `accent="…" accentPlacement="perimeter"` instead — same geometry, tone-owned. */
|
|
60
54
|
[data-slot="card"][data-variant="featured"] {
|
|
61
|
-
border-color:
|
|
62
|
-
box-shadow: 0 0 0 var(--
|
|
63
|
-
var(--card-featured-border-color, hsl(var(--primary)));
|
|
55
|
+
border-color: hsl(var(--primary));
|
|
56
|
+
box-shadow: 0 0 0 1px hsl(var(--primary));
|
|
64
57
|
}
|
|
65
58
|
|
|
66
59
|
/* ── Density — override the shell inset/body tokens ──────────────────────
|
|
@@ -79,39 +72,33 @@
|
|
|
79
72
|
--card-space-body-y: var(--space-5);
|
|
80
73
|
}
|
|
81
74
|
|
|
82
|
-
/* ── Accent
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
75
|
+
/* ── Accent edge — semantic left stripe (token width), content on shell ─ */
|
|
76
|
+
[data-slot="card"][data-accent] {
|
|
77
|
+
border-inline-start-width: var(--card-accent-rail-width);
|
|
78
|
+
}
|
|
79
|
+
|
|
87
80
|
[data-slot="card"][data-accent="primary"] {
|
|
88
|
-
|
|
81
|
+
border-inline-start-color: hsl(var(--primary));
|
|
89
82
|
}
|
|
90
83
|
|
|
91
84
|
[data-slot="card"][data-accent="success"] {
|
|
92
|
-
|
|
85
|
+
border-inline-start-color: hsl(var(--success));
|
|
93
86
|
}
|
|
94
87
|
|
|
95
88
|
[data-slot="card"][data-accent="warning"] {
|
|
96
|
-
|
|
89
|
+
border-inline-start-color: hsl(var(--warning));
|
|
97
90
|
}
|
|
98
91
|
|
|
99
92
|
[data-slot="card"][data-accent="info"] {
|
|
100
|
-
|
|
93
|
+
border-inline-start-color: hsl(var(--info));
|
|
101
94
|
}
|
|
102
95
|
|
|
103
96
|
[data-slot="card"][data-accent="attention"] {
|
|
104
|
-
|
|
97
|
+
border-inline-start-color: hsl(var(--attention));
|
|
105
98
|
}
|
|
106
99
|
|
|
107
100
|
[data-slot="card"][data-accent="destructive"] {
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/* ── Accent placement `edge` (DEFAULT) — semantic left stripe (token width), content on shell ─ */
|
|
112
|
-
[data-slot="card"][data-accent] {
|
|
113
|
-
border-inline-start-width: var(--card-accent-rail-width);
|
|
114
|
-
border-inline-start-color: var(--card-accent-color);
|
|
101
|
+
border-inline-start-color: hsl(var(--destructive));
|
|
115
102
|
}
|
|
116
103
|
|
|
117
104
|
[data-slot="card"][data-accent] > [data-slot="card-header"],
|
|
@@ -120,29 +107,6 @@
|
|
|
120
107
|
padding-inline-start: calc(var(--card-space-inset) - var(--card-accent-rail-width));
|
|
121
108
|
}
|
|
122
109
|
|
|
123
|
-
/* ── Accent placement `perimeter` — the full attention border (gh#12) ───
|
|
124
|
-
* The whole edge carries the semantic tone instead of one rail, so a card can read as
|
|
125
|
-
* "action required" / "failed" at a glance without borrowing `--primary` the way
|
|
126
|
-
* `variant="featured"` does. Same optical weight as `featured` (border + 1px ring), tone-owned.
|
|
127
|
-
* Because the rail is gone, the slot padding compensation above is undone — content returns to
|
|
128
|
-
* the normal shell column, so switching placement never shifts the text. */
|
|
129
|
-
[data-slot="card"][data-accent][data-accent-placement="perimeter"] {
|
|
130
|
-
border-width: var(--card-accent-perimeter-width);
|
|
131
|
-
border-color: var(--card-accent-color);
|
|
132
|
-
box-shadow:
|
|
133
|
-
0 0 0 var(--card-accent-perimeter-ring-width) var(--card-accent-color),
|
|
134
|
-
var(--card-shadow),
|
|
135
|
-
var(--card-glow);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
[data-slot="card"][data-accent][data-accent-placement="perimeter"] > [data-slot="card-header"],
|
|
139
|
-
[data-slot="card"][data-accent][data-accent-placement="perimeter"]
|
|
140
|
-
> [data-slot="card-content"]:not([data-flush]),
|
|
141
|
-
[data-slot="card"][data-accent][data-accent-placement="perimeter"]
|
|
142
|
-
> [data-slot="card-footer"]:not([data-flush]) {
|
|
143
|
-
padding-inline-start: var(--card-space-inset);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
110
|
/* ── Header ──────────────────────────────────────────────────────────── */
|
|
147
111
|
[data-slot="card-header"] {
|
|
148
112
|
display: flex;
|
package/dist/styles/control.css
CHANGED
|
@@ -714,18 +714,8 @@
|
|
|
714
714
|
.ui-otp-container {
|
|
715
715
|
display: flex;
|
|
716
716
|
align-items: center;
|
|
717
|
-
justify-content: var(--otp-container-align, flex-start);
|
|
718
717
|
gap: var(--space-2);
|
|
719
718
|
}
|
|
720
|
-
/* `align` on InputOTP lands on the hidden <input> (input-otp owns the container element), so the
|
|
721
|
-
* container reads it through :has() — the same mechanism this file already uses for the invalid
|
|
722
|
-
* and disabled states. Specificity puts the per-instance prop above the theme token. */
|
|
723
|
-
.ui-otp-container:has(.ui-otp-input[data-align="center"]) {
|
|
724
|
-
justify-content: center;
|
|
725
|
-
}
|
|
726
|
-
.ui-otp-container:has(.ui-otp-input[data-align="end"]) {
|
|
727
|
-
justify-content: flex-end;
|
|
728
|
-
}
|
|
729
719
|
.ui-otp-input:disabled {
|
|
730
720
|
cursor: not-allowed;
|
|
731
721
|
}
|
|
@@ -736,8 +726,8 @@
|
|
|
736
726
|
.ui-otp-slot {
|
|
737
727
|
position: relative;
|
|
738
728
|
display: flex;
|
|
739
|
-
width: var(--otp-slot-
|
|
740
|
-
height: var(--otp-slot-
|
|
729
|
+
width: var(--otp-slot-size, var(--control-height));
|
|
730
|
+
height: var(--otp-slot-size, var(--control-height));
|
|
741
731
|
align-items: center;
|
|
742
732
|
justify-content: center;
|
|
743
733
|
font-size: var(--font-size-base);
|
|
@@ -30,22 +30,6 @@
|
|
|
30
30
|
color: var(--avatar-square-foreground, hsl(var(--primary-foreground)));
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/* CAPABILITY MEDALLION — `<Avatar appearance="tinted">` (gh#12). The tinted companion of the
|
|
34
|
-
* solid entity mark: same box, same radius, a soft role wash instead of a solid fill and the
|
|
35
|
-
* glyph in the role itself. Declared AFTER the square rule (equal specificity) so it retints
|
|
36
|
-
* either shape. The glyph rule is scoped to this appearance ON PURPOSE — a global
|
|
37
|
-
* `.ui-avatar svg` would outrank the per-call-site icon classes existing avatars already use. */
|
|
38
|
-
.ui-avatar[data-appearance="tinted"] {
|
|
39
|
-
--avatar-background: var(--avatar-tinted-background, hsl(var(--primary) / 0.1));
|
|
40
|
-
color: var(--avatar-tinted-foreground, hsl(var(--primary)));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.ui-avatar[data-appearance="tinted"] svg {
|
|
44
|
-
inline-size: var(--avatar-tinted-glyph-size);
|
|
45
|
-
block-size: var(--avatar-tinted-glyph-size);
|
|
46
|
-
flex: none;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
33
|
.ui-avatar-image {
|
|
50
34
|
width: 100%;
|
|
51
35
|
height: 100%;
|
package/dist/styles/layout.css
CHANGED
|
@@ -521,47 +521,35 @@
|
|
|
521
521
|
width: 100%;
|
|
522
522
|
}
|
|
523
523
|
|
|
524
|
-
.
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
line-height: var(--line-height-tight);
|
|
529
|
-
overflow-wrap: anywhere;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
/* Title + `meta` share one baseline-aligned band (gh#255). The band only exists when `meta` is
|
|
533
|
-
* passed, so a header without it keeps its historical bare-`<h1>` DOM. `wrap` is what keeps a
|
|
534
|
-
* long JA/VI title and a status Badge legible at 390px instead of squeezing the title column. */
|
|
535
|
-
.ui-page-title-band {
|
|
524
|
+
/* Title line + status/meta band (PageContainer `status`, godxjp-ui#255). The band sits on
|
|
525
|
+
* the title's baseline row at the token-owned gap and WRAPS under the title when the
|
|
526
|
+
* viewport (390px) or a long JA/VI title leaves no room — never clips, never overlaps. */
|
|
527
|
+
.ui-page-header-title-row {
|
|
536
528
|
display: flex;
|
|
537
529
|
flex-wrap: wrap;
|
|
538
|
-
align-items:
|
|
539
|
-
gap: var(--page-header-
|
|
530
|
+
align-items: center;
|
|
531
|
+
gap: var(--page-header-status-gap);
|
|
532
|
+
min-inline-size: 0;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
.ui-page-header-title-row > .ui-page-title {
|
|
540
536
|
min-inline-size: 0;
|
|
541
537
|
}
|
|
542
538
|
|
|
543
|
-
.ui-page-header-
|
|
539
|
+
.ui-page-header-status {
|
|
544
540
|
display: flex;
|
|
545
541
|
flex-wrap: wrap;
|
|
546
542
|
align-items: center;
|
|
547
|
-
gap: var(--page-header-
|
|
543
|
+
gap: var(--page-header-status-gap);
|
|
548
544
|
min-inline-size: 0;
|
|
549
545
|
}
|
|
550
546
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
max-inline-size: 100%;
|
|
558
|
-
min-block-size: var(--page-title-placeholder-block-size);
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
.ui-page-subtitle-placeholder {
|
|
562
|
-
inline-size: var(--page-subtitle-placeholder-measure);
|
|
563
|
-
max-inline-size: 100%;
|
|
564
|
-
min-block-size: var(--page-subtitle-placeholder-block-size);
|
|
547
|
+
.ui-page-title {
|
|
548
|
+
font-size: var(--page-title-font-size);
|
|
549
|
+
font-weight: var(--font-weight-medium);
|
|
550
|
+
letter-spacing: var(--letter-spacing-tight);
|
|
551
|
+
line-height: var(--line-height-tight);
|
|
552
|
+
overflow-wrap: anywhere;
|
|
565
553
|
}
|
|
566
554
|
|
|
567
555
|
/* Compact viewports use a responsive type step, not compact density: body/control text and
|
|
@@ -953,84 +941,6 @@
|
|
|
953
941
|
font-size: var(--filter-label-font-size);
|
|
954
942
|
}
|
|
955
943
|
|
|
956
|
-
/* ── FilterBar typed model (#258) ──────────────────────────────────────────────────────────
|
|
957
|
-
* Every rule below is scoped to a region the bar only emits when its prop is passed, so a bar
|
|
958
|
-
* built the old way (children + onClear) matches none of them and is geometrically untouched.
|
|
959
|
-
*
|
|
960
|
-
* SEARCH — full-width while the strip is stacked (a bounded search box on a 390px screen wastes
|
|
961
|
-
* the row), then one shared token-owned measure from the 640px step up. This single measure is
|
|
962
|
-
* what the issue was filed against: as a plain child, every page picked its own width. */
|
|
963
|
-
.ui-filter-bar-search {
|
|
964
|
-
width: 100%;
|
|
965
|
-
min-width: 0;
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
@media (min-width: 640px) {
|
|
969
|
-
.ui-filter-bar-search {
|
|
970
|
-
width: var(--filter-bar-search-width);
|
|
971
|
-
max-width: 100%;
|
|
972
|
-
flex: 0 0 auto;
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
/* CHIPS — always their own full-width line. Applied filters are a record of state, not another
|
|
977
|
-
* control in the row; wrapping them in beside the pickers makes both harder to scan. */
|
|
978
|
-
.ui-filter-bar-chips {
|
|
979
|
-
display: flex;
|
|
980
|
-
width: 100%;
|
|
981
|
-
flex-basis: 100%;
|
|
982
|
-
flex-wrap: wrap;
|
|
983
|
-
align-items: center;
|
|
984
|
-
gap: var(--filter-bar-chip-row-gap);
|
|
985
|
-
min-width: 0;
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
.ui-filter-bar-chip {
|
|
989
|
-
display: inline-flex;
|
|
990
|
-
max-width: 100%;
|
|
991
|
-
align-items: center;
|
|
992
|
-
gap: var(--filter-bar-chip-gap);
|
|
993
|
-
padding: var(--filter-bar-chip-padding-block) var(--filter-bar-chip-padding-inline);
|
|
994
|
-
border-radius: var(--filter-bar-chip-radius);
|
|
995
|
-
background: hsl(var(--filter-bar-chip-background, var(--muted)));
|
|
996
|
-
color: hsl(var(--filter-bar-chip-foreground, var(--muted-foreground)));
|
|
997
|
-
font-size: var(--filter-bar-chip-font-size);
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
/* A long JA/VI chip value wraps inside the chip rather than pushing the row into a horizontal
|
|
1001
|
-
* scroll — the remove control must stay reachable at 390px. */
|
|
1002
|
-
.ui-filter-bar-chip-label {
|
|
1003
|
-
min-width: 0;
|
|
1004
|
-
overflow-wrap: anywhere;
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
.ui-filter-bar-chip-remove {
|
|
1008
|
-
flex: none;
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
.ui-filter-bar-count {
|
|
1012
|
-
color: hsl(var(--filter-bar-count-foreground, var(--muted-foreground)));
|
|
1013
|
-
font-size: var(--filter-bar-count-font-size);
|
|
1014
|
-
/* The count is a number that changes in place — tabular figures stop the row from twitching
|
|
1015
|
-
* as it goes 9 → 10 → 100. */
|
|
1016
|
-
font-variant-numeric: tabular-nums;
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
.ui-filter-bar-actions {
|
|
1020
|
-
display: flex;
|
|
1021
|
-
width: 100%;
|
|
1022
|
-
flex-wrap: wrap;
|
|
1023
|
-
align-items: center;
|
|
1024
|
-
gap: var(--space-inline-sm);
|
|
1025
|
-
}
|
|
1026
|
-
|
|
1027
|
-
@media (min-width: 640px) {
|
|
1028
|
-
.ui-filter-bar-actions {
|
|
1029
|
-
width: auto;
|
|
1030
|
-
flex: 0 0 auto;
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
944
|
/* Toolbar/FilterBar `overflow="scroll"` (#216) — one bounded row that scrolls INLINE instead of
|
|
1035
945
|
* wrapping onto extra rows. Below 640px the strip still stacks (the `wrap` base rules above own
|
|
1036
946
|
* that): a 390px viewport must never hide a filter behind a horizontal scroll it cannot see.
|
|
@@ -1063,6 +973,90 @@
|
|
|
1063
973
|
z-index: 1;
|
|
1064
974
|
background: hsl(var(--filter-bar-sticky-background, var(--background)));
|
|
1065
975
|
}
|
|
976
|
+
|
|
977
|
+
/* Typed-model reset+actions cluster gets the same viewport-pinned treatment (gh#258). */
|
|
978
|
+
.ui-toolbar[data-overflow="scroll"] > .ui-filter-bar-end {
|
|
979
|
+
position: sticky;
|
|
980
|
+
inset-inline-end: 0;
|
|
981
|
+
margin-inline-start: auto;
|
|
982
|
+
flex: 0 0 auto;
|
|
983
|
+
z-index: 1;
|
|
984
|
+
background: hsl(var(--filter-bar-sticky-background, var(--background)));
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
/* ── FilterBar typed model (gh#258) ─────────────────────────────────────────────
|
|
989
|
+
* Canonical model layout: strip (search → filters → children → reset → actions) →
|
|
990
|
+
* applied-chips row → result-count/error line. Geometry is entirely token-owned
|
|
991
|
+
* (`--filter-bar-*`); stacking below 640px reuses the `.ui-toolbar` base rules, so
|
|
992
|
+
* 1440/1024/390 behave identically to the composition form. */
|
|
993
|
+
.ui-filter-bar {
|
|
994
|
+
display: flex;
|
|
995
|
+
flex-direction: column;
|
|
996
|
+
gap: var(--filter-bar-section-gap);
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
.ui-filter-bar .ui-filter-bar-search {
|
|
1000
|
+
inline-size: 100%;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
.ui-filter-bar-end {
|
|
1004
|
+
display: flex;
|
|
1005
|
+
flex-wrap: wrap;
|
|
1006
|
+
align-items: center;
|
|
1007
|
+
gap: var(--space-2);
|
|
1008
|
+
width: 100%;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
/* Inside the end cluster the clear button gives up its own auto margin — the CLUSTER is what
|
|
1012
|
+
* parks at the inline end, so reset and actions stay adjacent in the keyboard/DOM order. */
|
|
1013
|
+
.ui-filter-bar-end .ui-toolbar-clear {
|
|
1014
|
+
margin-inline-start: 0;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
.ui-filter-bar-actions {
|
|
1018
|
+
display: flex;
|
|
1019
|
+
flex-wrap: wrap;
|
|
1020
|
+
align-items: center;
|
|
1021
|
+
gap: var(--space-2);
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
@media (min-width: 640px) {
|
|
1025
|
+
.ui-filter-bar .ui-filter-bar-search {
|
|
1026
|
+
inline-size: min(100%, var(--filter-bar-search-width));
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
.ui-filter-bar .ui-filter-bar-filter {
|
|
1030
|
+
min-inline-size: min(100%, var(--filter-bar-filter-width));
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
.ui-filter-bar-end {
|
|
1034
|
+
width: auto;
|
|
1035
|
+
margin-inline-start: auto;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
.ui-filter-bar-chips {
|
|
1040
|
+
display: flex;
|
|
1041
|
+
flex-wrap: wrap;
|
|
1042
|
+
align-items: center;
|
|
1043
|
+
gap: var(--filter-bar-chip-gap);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
.ui-filter-bar-chip {
|
|
1047
|
+
display: inline-flex;
|
|
1048
|
+
align-items: center;
|
|
1049
|
+
gap: var(--space-1);
|
|
1050
|
+
min-width: 0;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
.ui-filter-bar-meta {
|
|
1054
|
+
font-size: var(--filter-label-font-size);
|
|
1055
|
+
color: hsl(var(--muted-foreground));
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
.ui-filter-bar-error {
|
|
1059
|
+
color: hsl(var(--destructive));
|
|
1066
1060
|
}
|
|
1067
1061
|
|
|
1068
1062
|
/* ── LegalDocumentShell (#222) ─────────────────────────────────────────────────
|
|
@@ -394,15 +394,10 @@
|
|
|
394
394
|
box-shadow: 0 0 0 var(--focus-ring-width) hsl(var(--focus-ring-color, var(--ring)));
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
-
/* The step NUMBER carries the emphasis. Both knobs exist because the canonical hosted-identity
|
|
398
|
-
* row marks the step with an accent TINT at normal weight, while the original marked it with
|
|
399
|
-
* bold at the inherited colour — a service picks its own emphasis instead of forking this rule
|
|
400
|
-
* (rule #45). Defaults are the original bold + inherited colour, so nothing moves. */
|
|
401
397
|
.ui-steps-inline-index {
|
|
402
398
|
flex: none;
|
|
403
399
|
font-variant-numeric: tabular-nums;
|
|
404
|
-
font-weight: var(--
|
|
405
|
-
color: var(--steps-inline-index-color, currentColor);
|
|
400
|
+
font-weight: var(--font-weight-bold);
|
|
406
401
|
}
|
|
407
402
|
|
|
408
403
|
.ui-steps-inline-title {
|
|
@@ -423,7 +418,8 @@
|
|
|
423
418
|
color: hsl(var(--destructive));
|
|
424
419
|
}
|
|
425
420
|
|
|
426
|
-
.ui-steps-inline-item[data-status="wait"] .ui-steps-inline-control
|
|
421
|
+
.ui-steps-inline-item[data-status="wait"] .ui-steps-inline-control,
|
|
422
|
+
.ui-steps-inline-separator {
|
|
427
423
|
color: hsl(var(--muted-foreground));
|
|
428
424
|
}
|
|
429
425
|
|
|
@@ -431,6 +427,5 @@
|
|
|
431
427
|
width: var(--steps-inline-separator-size);
|
|
432
428
|
height: var(--steps-inline-separator-size);
|
|
433
429
|
flex: none;
|
|
434
|
-
color: var(--steps-inline-separator-color, hsl(var(--muted-foreground)));
|
|
435
430
|
}
|
|
436
431
|
}
|
|
@@ -192,14 +192,9 @@
|
|
|
192
192
|
text-align: center;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
/* Device-authorization also owns its CODE FIELD (gh#12): the preset's subject is the code, so
|
|
196
|
-
* the slot box comes from the preset instead of the generic square control tier. Scoped on the
|
|
197
|
-
* shell so every OTP inside the device flow inherits it; a per-instance override still wins. */
|
|
198
195
|
.ui-auth-shell[data-preset="device-authorization"] {
|
|
199
196
|
--auth-shell-card-max-width: var(--auth-shell-device-card-max-width);
|
|
200
197
|
--auth-shell-main-padding: var(--auth-shell-device-main-padding);
|
|
201
|
-
--otp-slot-inline-size: var(--auth-shell-device-otp-slot-inline-size);
|
|
202
|
-
--otp-slot-block-size: var(--auth-shell-device-otp-slot-block-size);
|
|
203
198
|
}
|
|
204
199
|
|
|
205
200
|
.ui-auth-shell[data-preset="context-selection"] {
|
|
@@ -343,12 +338,21 @@
|
|
|
343
338
|
.ui-auth-shell[data-variant="canonical"] .ui-form-field {
|
|
344
339
|
--field-label-gap: var(--auth-shell-field-label-gap);
|
|
345
340
|
}
|
|
341
|
+
}
|
|
346
342
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
343
|
+
/* INTENTIONALLY UNLAYERED (like density.css) — the Label primitive carries `text-sm leading-none`
|
|
344
|
+
* Tailwind utility classes, and the utilities layer is declared after `components`, so a
|
|
345
|
+
* components-layer declaration of the same properties can NEVER win regardless of specificity.
|
|
346
|
+
* That left `--auth-shell-field-label-font-size` / `--auth-shell-field-label-line-height` dead and
|
|
347
|
+
* the canonical field label rendering as a 14px/1.0 line box instead of the canonical 12px/1.5 =
|
|
348
|
+
* 18px, sitting the email input 4px high (gh#263). Unlayered author CSS out-cascades every layer;
|
|
349
|
+
* the two tokens remain the public tuning knobs. */
|
|
350
|
+
.ui-auth-shell[data-variant="canonical"] [data-slot="form-field-label"] [data-slot="label"] {
|
|
351
|
+
font-size: var(--auth-shell-field-label-font-size);
|
|
352
|
+
line-height: var(--auth-shell-field-label-line-height);
|
|
353
|
+
}
|
|
351
354
|
|
|
355
|
+
@layer components {
|
|
352
356
|
/*
|
|
353
357
|
* Compact auth card density — the two card axes are wired to SEPARATE knobs (gh#232), so a
|
|
354
358
|
* service can shorten the canonical Login card without narrowing its column (or vice versa):
|
|
@@ -384,7 +388,7 @@
|
|
|
384
388
|
gap: var(--auth-shell-divider-gap);
|
|
385
389
|
color: hsl(var(--auth-shell-divider-label-color));
|
|
386
390
|
font-size: var(--auth-shell-divider-label-font-size);
|
|
387
|
-
line-height:
|
|
391
|
+
line-height: var(--auth-shell-divider-label-line-height);
|
|
388
392
|
}
|
|
389
393
|
|
|
390
394
|
.ui-auth-divider-rule {
|
|
@@ -423,8 +427,8 @@
|
|
|
423
427
|
|
|
424
428
|
/* registration = 15px inline at 390 (card x=15, width=360 — the same page rhythm as Login, so
|
|
425
429
|
* sign-in → sign-up never jumps on a phone). The block insets tighten but the footer clearance
|
|
426
|
-
* stays deliberately larger than
|
|
427
|
-
*
|
|
430
|
+
* stays deliberately larger than a bare gutter: at 390 the form is at its tallest and the
|
|
431
|
+
* consent/legal footer must not sit flush against the submit button. */
|
|
428
432
|
.ui-auth-shell[data-preset="registration"] {
|
|
429
433
|
--auth-shell-main-padding: var(--auth-shell-registration-main-padding-block-start-mobile)
|
|
430
434
|
var(--auth-shell-registration-main-padding-inline-mobile)
|
|
@@ -524,11 +528,7 @@
|
|
|
524
528
|
}
|
|
525
529
|
|
|
526
530
|
/* AppShell-owned mobile drawer trigger — hidden on desktop, shown once the docked sidebar
|
|
527
|
-
* collapses out
|
|
528
|
-
* (1024px): this comment said "below lg" for six minors while the shipped rule below and the
|
|
529
|
-
* hamburger's own `max-[900px]:inline-flex` both fired at 900 — see the block comment on the
|
|
530
|
-
* `@media (width <= 56.25rem)` rule for why 900 is the canonical value. The drawer nav itself is
|
|
531
|
-
* a focus-trapped Sheet. */
|
|
531
|
+
* collapses out below `lg` (gh#165). The drawer nav itself is a focus-trapped Sheet. */
|
|
532
532
|
.app-mobile-nav-trigger {
|
|
533
533
|
display: none;
|
|
534
534
|
flex: 0 0 auto;
|