@godxjp/ui 18.15.4 → 19.0.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/date-format-labels.d.ts +1 -1
- package/dist/app/time-format-labels.d.ts +1 -1
- package/dist/components/data-display/badge.d.ts +1 -1
- package/dist/components/data-display/card.d.ts +4 -13
- package/dist/components/data-display/card.js +2 -15
- package/dist/components/data-display/data-table.d.ts +3 -8
- package/dist/components/data-display/data-table.js +106 -68
- package/dist/components/data-display/descriptions.js +34 -5
- package/dist/components/data-display/empty-state.js +1 -1
- package/dist/components/data-display/permission-matrix.js +7 -7
- package/dist/components/data-display/popover.js +2 -9
- package/dist/components/data-display/qr-code.d.ts +1 -1
- package/dist/components/data-display/scroll-area.d.ts +3 -1
- package/dist/components/data-display/scroll-area.js +150 -16
- package/dist/components/data-display/table.js +12 -3
- package/dist/components/data-entry/branch-scope-picker.js +4 -4
- package/dist/components/data-entry/calendar.js +15 -24
- package/dist/components/data-entry/cascader.js +67 -71
- package/dist/components/data-entry/checkbox.js +9 -1
- package/dist/components/data-entry/command.d.ts +6 -6
- package/dist/components/data-entry/date-picker.js +28 -15
- package/dist/components/data-entry/date-range-picker.js +10 -10
- package/dist/components/data-entry/form-field.js +7 -3
- package/dist/components/data-entry/index.d.ts +2 -1
- package/dist/components/data-entry/input.js +8 -19
- package/dist/components/data-entry/label.js +4 -2
- package/dist/components/data-entry/month-picker.js +16 -15
- package/dist/components/data-entry/month-range-picker.js +17 -16
- package/dist/components/data-entry/radio.js +6 -1
- package/dist/components/data-entry/search-select.js +29 -29
- package/dist/components/data-entry/select.js +15 -18
- package/dist/components/data-entry/switch.js +7 -1
- package/dist/components/data-entry/textarea.d.ts +56 -0
- package/dist/components/data-entry/textarea.js +103 -40
- package/dist/components/data-entry/time-picker.js +52 -52
- package/dist/components/data-entry/toggle-group.d.ts +1 -0
- package/dist/components/data-entry/toggle.d.ts +1 -1
- package/dist/components/data-entry/transfer.js +14 -15
- package/dist/components/data-entry/tree-select.js +16 -22
- package/dist/components/data-entry/upload-crop-dialog.js +4 -4
- package/dist/components/data-entry/upload.d.ts +1 -1
- package/dist/components/data-entry/upload.js +46 -46
- package/dist/components/feedback/alert.js +7 -14
- package/dist/components/feedback/dialog.d.ts +23 -32
- package/dist/components/feedback/dialog.js +16 -13
- package/dist/components/feedback/sheet.d.ts +1 -1
- package/dist/components/feedback/sheet.js +14 -14
- package/dist/components/feedback/skeleton.js +13 -10
- package/dist/components/feedback/sonner.d.ts +1 -1
- package/dist/components/feedback/sonner.js +17 -8
- package/dist/components/feedback/tooltip.js +1 -1
- package/dist/components/general/activity.d.ts +44 -0
- package/dist/components/general/activity.js +65 -0
- package/dist/components/general/button.d.ts +2 -2
- package/dist/components/general/button.js +11 -24
- package/dist/components/general/index.d.ts +2 -0
- package/dist/components/general/index.js +2 -0
- package/dist/components/layout/app-shell.js +5 -3
- package/dist/components/layout/auth-divider.d.ts +9 -2
- package/dist/components/layout/auth-divider.js +7 -11
- package/dist/components/layout/index.d.ts +1 -0
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +32 -20
- package/dist/components/layout/resizable.d.ts +12 -12
- package/dist/components/layout/separator.d.ts +1 -0
- package/dist/components/layout/service-role-panel.js +47 -42
- package/dist/components/layout/sidebar.js +13 -1
- package/dist/components/layout/split-pane.d.ts +12 -1
- package/dist/components/layout/split-pane.js +13 -4
- package/dist/components/navigation/app-setting-picker.js +5 -14
- package/dist/components/navigation/dropdown-menu.js +10 -16
- package/dist/components/navigation/menubar.d.ts +3 -6
- package/dist/components/navigation/pagination-utils.d.ts +15 -2
- package/dist/components/navigation/pagination-utils.js +27 -21
- package/dist/components/navigation/pagination.d.ts +4 -4
- package/dist/components/navigation/pagination.js +2 -2
- package/dist/components/navigation/steps.js +31 -67
- package/dist/components/navigation/tabs.js +17 -5
- package/dist/components/query/infinite-query-state.js +2 -2
- package/dist/components/ui/accordion.d.ts +1 -1
- package/dist/components/ui/avatar.d.ts +1 -1
- package/dist/components/ui/avatar.js +29 -10
- package/dist/components/ui/input-otp.d.ts +8 -6
- package/dist/components/ui/rating.js +1 -1
- package/dist/components/ui/separator.d.ts +27 -2
- package/dist/components/ui/separator.js +42 -11
- package/dist/components/ui/toggle-group.d.ts +15 -5
- package/dist/components/ui/toggle-group.js +43 -18
- package/dist/components/ui/toggle.d.ts +66 -5
- package/dist/components/ui/toggle.js +64 -9
- package/dist/i18n/messages/en.json +8 -0
- package/dist/i18n/messages/ja.json +8 -0
- package/dist/i18n/messages/vi.json +8 -0
- package/dist/lib/control-styles.d.ts +14 -0
- package/dist/lib/control-styles.js +2 -0
- package/dist/props/components/data-display.prop.d.ts +85 -3
- package/dist/props/components/data-entry.prop.d.ts +17 -0
- package/dist/props/components/general.prop.d.ts +52 -1
- package/dist/props/components/layout.prop.d.ts +137 -2
- package/dist/props/registry.d.ts +116 -5
- package/dist/props/registry.js +165 -4
- package/dist/props/vocabulary/index.d.ts +2 -2
- package/dist/props/vocabulary/interaction.prop.d.ts +15 -0
- package/dist/props/vocabulary/layout.prop.d.ts +8 -0
- package/dist/styles/alert-layout.css +69 -3
- package/dist/styles/badge-layout.css +2 -2
- package/dist/styles/base.css +6 -0
- package/dist/styles/card-layout.css +25 -8
- package/dist/styles/control.css +1150 -29
- package/dist/styles/data-display-layout.css +185 -11
- package/dist/styles/data-entry-layout.css +352 -1
- package/dist/styles/density.css +2 -2
- package/dist/styles/dialog-layout.css +203 -4
- package/dist/styles/focus-ring.css +155 -0
- package/dist/styles/form-layout.css +50 -5
- package/dist/styles/index.css +1 -0
- package/dist/styles/layout.css +412 -23
- package/dist/styles/motion.css +178 -0
- package/dist/styles/navigation-layout.css +398 -22
- package/dist/styles/shell-layout.css +137 -39
- package/dist/styles/table-layout.css +153 -22
- package/dist/styles/toggle.css +59 -0
- package/dist/tokens/base.css +5 -0
- package/dist/tokens/components/activity.css +64 -0
- package/dist/tokens/components/badge.css +7 -0
- package/dist/tokens/components/card.css +14 -10
- package/dist/tokens/components/chart.css +1 -1
- package/dist/tokens/components/control.css +358 -8
- package/dist/tokens/components/data-display.css +75 -0
- package/dist/tokens/components/data-entry.css +25 -0
- package/dist/tokens/components/descriptions.css +22 -0
- package/dist/tokens/components/feedback.css +143 -4
- package/dist/tokens/components/form.css +16 -0
- package/dist/tokens/components/legal-document.css +5 -1
- package/dist/tokens/components/navigation.css +109 -0
- package/dist/tokens/components/scroll-area.css +21 -0
- package/dist/tokens/components/separator.css +52 -0
- package/dist/tokens/components/shell.css +132 -20
- package/dist/tokens/components/table.css +52 -3
- package/dist/tokens/components/toggle.css +82 -0
- package/dist/tokens/components/upload.css +107 -0
- package/dist/tokens/foundation.css +171 -10
- package/dist/tokens/semantic/layout.css +120 -1
- package/package.json +84 -68
- package/scripts/ui-audit.mjs +51 -2
|
@@ -39,6 +39,40 @@
|
|
|
39
39
|
"sidebar footer";
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/* NO TOP BAR AT ALL — `topbar`, `topbarLeft`, `topbarRight` and `logo` all undefined. AppShell
|
|
43
|
+
* renders no `<header class="app-topbar">` in that state (the mobile drawer trigger is the one
|
|
44
|
+
* exception, below) and publishes it as ONE attribute here, so the geometry is decided by the
|
|
45
|
+
* grid element itself rather than by `:has()` on whatever the consumer nested inside.
|
|
46
|
+
*
|
|
47
|
+
* The row has to go with the header. An empty --app-shell-bar-height track still costs a fixed
|
|
48
|
+
* 48px, and the header still painted a bottom border over hsl(var(--card)) — so a chat / mail /
|
|
49
|
+
* IDE shell, whose PAGE header is the top row, showed two rows of chrome (~48 + ~60px) over
|
|
50
|
+
* exactly the region that needs the height most.
|
|
51
|
+
*
|
|
52
|
+
* `auto`, not a `0` literal, is what makes one attribute enough for every branch: an absent row
|
|
53
|
+
* measures 0, a `display:none` header measures 0, and at narrow widths — where the header comes
|
|
54
|
+
* back to carry the hamburger — the row sizes itself from that header's own min-height. So the
|
|
55
|
+
* breakpoint block needs no restatement of these rows, which is the trap this file has already
|
|
56
|
+
* paid for once: the deleted 768px block re-declared grid-template-rows with a `3rem` literal
|
|
57
|
+
* and defeated --app-shell-bar-height below 768px only (see the note on the one @media block).
|
|
58
|
+
* `[data-topbar-span="full"]` re-declares grid-template-AREAS only, so it inherits this row
|
|
59
|
+
* template untouched and its named-but-empty "topbar topbar" row is 0 as well. */
|
|
60
|
+
.app-root[data-topbar="none"] {
|
|
61
|
+
grid-template-rows: auto minmax(0, 1fr) auto;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* The one thing that may still live in a bar-less shell: AppShell's OWN hamburger. Below 900px
|
|
65
|
+
* the docked sidebar is hidden, and dropping the bar there too would leave the shell with no
|
|
66
|
+
* reachable navigation at all — a worse failure than the double chrome above (gh#165). So when a
|
|
67
|
+
* drawer exists the header is still rendered, carrying the trigger and nothing else, and it is
|
|
68
|
+
* THIS rule, not the empty row, that keeps it off the wide layout: `display:none` removes its
|
|
69
|
+
* border, its background and its height together. The min-height is inert here and load-bearing
|
|
70
|
+
* at narrow widths, where it is the only thing giving the `auto` row a height. */
|
|
71
|
+
.app-root[data-topbar="none"] > .app-topbar {
|
|
72
|
+
display: none;
|
|
73
|
+
min-height: var(--app-shell-bar-height);
|
|
74
|
+
}
|
|
75
|
+
|
|
42
76
|
.app-sidebar {
|
|
43
77
|
grid-area: sidebar;
|
|
44
78
|
display: flex;
|
|
@@ -90,6 +124,15 @@
|
|
|
90
124
|
grid-area: main;
|
|
91
125
|
min-width: 0;
|
|
92
126
|
overflow: auto;
|
|
127
|
+
/* Column flow, so a page that asks to FILL can actually be bounded by the
|
|
128
|
+
* region instead of merely starting at its top. With the default `block`
|
|
129
|
+
* flow a `--fill` container could only be `min-height: 100%`, i.e. it grew
|
|
130
|
+
* past the region and pushed the scroll back out here — which is why a chat
|
|
131
|
+
* transcript slid UNDER its own sticky composer. Ordinary pages are
|
|
132
|
+
* unaffected: their container still has `min-height: 100%`, still grows,
|
|
133
|
+
* and this element still scrolls it. */
|
|
134
|
+
display: flex;
|
|
135
|
+
flex-direction: column;
|
|
93
136
|
/* Ambient brand glow hook — invisible by default (--gradient-glow: none); a service paints a
|
|
94
137
|
* radial/linear brand wash behind the whole content area by configuring the token alone. */
|
|
95
138
|
background-image: var(--gradient-glow);
|
|
@@ -427,20 +470,20 @@
|
|
|
427
470
|
--card-space-gap: var(--auth-shell-card-gap-compact);
|
|
428
471
|
}
|
|
429
472
|
|
|
473
|
+
/* AuthDivider is the auth-scoped PRESET over the labelled `Separator` (gh#308). It no longer
|
|
474
|
+
* re-implements the grid, the rule or the accessible-name contract — it only re-points
|
|
475
|
+
* Separator's knobs at the `--auth-shell-divider-*` layer, so the auth micro-scale (11px, not
|
|
476
|
+
* the stream's xs) and the auth rule/label colours stay exactly where a service already tunes
|
|
477
|
+
* them, while a day divider in a message stream is no longer coupled to a login form.
|
|
478
|
+
* `--separator-label-font-weight` is pinned to normal because the auth conjunction has always
|
|
479
|
+
* inherited the body weight, whereas the generic labelled rule defaults to medium. */
|
|
430
480
|
.ui-auth-divider {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
color:
|
|
437
|
-
font-size: var(--auth-shell-divider-label-font-size);
|
|
438
|
-
line-height: var(--auth-shell-divider-label-line-height);
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
.ui-auth-divider-rule {
|
|
442
|
-
height: 1px;
|
|
443
|
-
background: hsl(var(--auth-shell-divider-rule-color));
|
|
481
|
+
--separator-label-gap: var(--auth-shell-divider-gap);
|
|
482
|
+
--separator-label-font-size: var(--auth-shell-divider-label-font-size);
|
|
483
|
+
--separator-label-line-height: var(--auth-shell-divider-label-line-height);
|
|
484
|
+
--separator-label-font-weight: var(--font-weight-normal);
|
|
485
|
+
--separator-rule-color: var(--auth-shell-divider-rule-color);
|
|
486
|
+
--separator-label-color: var(--auth-shell-divider-label-color);
|
|
444
487
|
}
|
|
445
488
|
|
|
446
489
|
@media (max-width: 30rem) {
|
|
@@ -658,9 +701,14 @@
|
|
|
658
701
|
display: none;
|
|
659
702
|
}
|
|
660
703
|
|
|
661
|
-
/*
|
|
662
|
-
|
|
663
|
-
|
|
704
|
+
/* Bar-less shell (data-topbar="none") at narrow widths: the bar comes back for the hamburger
|
|
705
|
+
* ALONE — the only route to navigation once the docked rail is hidden. The `auto` row picks up
|
|
706
|
+
* its height from the header's min-height, so no grid-template-rows is restated here, and none
|
|
707
|
+
* may be: the one-breakpoint guard forbids a rows declaration inside this block precisely
|
|
708
|
+
* because the last one hard-coded 3rem. Docked mode never reaches this rule — it renders no
|
|
709
|
+
* drawer, so a bar-less docked shell has no header to show. */
|
|
710
|
+
.app-root[data-topbar="none"] > .app-topbar {
|
|
711
|
+
display: flex;
|
|
664
712
|
}
|
|
665
713
|
|
|
666
714
|
.app-topbar-left:has(.app-mobile-sidebar-trigger) {
|
|
@@ -699,15 +747,30 @@
|
|
|
699
747
|
display: flex;
|
|
700
748
|
}
|
|
701
749
|
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
750
|
+
/* (There is deliberately no `padding-inline` undo for docked mode any more. It existed to
|
|
751
|
+
* cancel a bar inset that stepped on the SHELL's 900px restructure; since gh#330 the inset
|
|
752
|
+
* steps on the PAGE's 720px step instead, and a docked page tightens its own gutters at that
|
|
753
|
+
* same step — so undoing the bar here would re-open the misalignment the step exists to
|
|
754
|
+
* keep closed.) */
|
|
706
755
|
.app-root[data-responsive-navigation="docked"] .app-mobile-nav-trigger {
|
|
707
756
|
display: none;
|
|
708
757
|
}
|
|
709
758
|
}
|
|
710
759
|
|
|
760
|
+
/* The compact step of the HORIZONTAL PAGE-INSET AXIS (gh#330). It is deliberately NOT the shell's
|
|
761
|
+
* 900px restructure breakpoint: the bar's inset is not a fact about whether a rail is docked, it
|
|
762
|
+
* is a fact about where the page's content edge is — and the page steps its gutters to
|
|
763
|
+
* --space-page-compact-x at exactly `(max-width: 720px)` (see styles/layout.css ·
|
|
764
|
+
* `.ui-page-container`). Stated with the identical condition so the two sides can never drift
|
|
765
|
+
* apart again; the shell's own restructure block above still owns everything that IS about the
|
|
766
|
+
* rail. This block mentions `.app-topbar` only, so the one-breakpoint `.app-root` contract
|
|
767
|
+
* (gh#213) is untouched. */
|
|
768
|
+
@media (max-width: 720px) {
|
|
769
|
+
.app-topbar {
|
|
770
|
+
padding-inline: var(--app-shell-bar-inset-compact);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
711
774
|
.sb-root {
|
|
712
775
|
display: contents;
|
|
713
776
|
}
|
|
@@ -909,8 +972,8 @@
|
|
|
909
972
|
}
|
|
910
973
|
|
|
911
974
|
.sb-product-caret svg {
|
|
912
|
-
width:
|
|
913
|
-
height:
|
|
975
|
+
width: var(--sidebar-product-caret-icon-size);
|
|
976
|
+
height: var(--sidebar-product-caret-icon-size);
|
|
914
977
|
}
|
|
915
978
|
|
|
916
979
|
.sb-nav-scroll {
|
|
@@ -929,9 +992,19 @@
|
|
|
929
992
|
margin-top: var(--sidebar-section-gap);
|
|
930
993
|
}
|
|
931
994
|
|
|
995
|
+
/* The section label is the ONE piece of sidebar text with no colour knob.
|
|
996
|
+
* Every other one has a variable with this same fallback — item, hover,
|
|
997
|
+
* active, icon — and the sidebar is paintable by design (`--sidebar-gradient`
|
|
998
|
+
* is a published knob). So a consumer that paints it can recolour every label
|
|
999
|
+
* except this heading, which stays muted-foreground and lands on whatever
|
|
1000
|
+
* they painted: measured at 1.50 against a mid-tone blue, where 11px text
|
|
1001
|
+
* needs 4.5.
|
|
1002
|
+
*
|
|
1003
|
+
* The fallback is the old value, so nothing changes for a sidebar that does
|
|
1004
|
+
* not paint itself. */
|
|
932
1005
|
.sb-section-label {
|
|
933
1006
|
padding: 0 var(--sidebar-section-label-padding-x) var(--sidebar-section-label-padding-bottom);
|
|
934
|
-
color: hsl(var(--muted-foreground));
|
|
1007
|
+
color: var(--sidebar-section-label-foreground, hsl(var(--muted-foreground)));
|
|
935
1008
|
font-size: var(--sidebar-section-label-font-size);
|
|
936
1009
|
font-weight: 700;
|
|
937
1010
|
letter-spacing: 0.08em;
|
|
@@ -968,6 +1041,23 @@
|
|
|
968
1041
|
text-align: start;
|
|
969
1042
|
}
|
|
970
1043
|
|
|
1044
|
+
/* Every nav row is a CONTROL, so it owes a visible keyboard indicator (WCAG 2.4.7) — and it
|
|
1045
|
+
* has to be the design system's, not the UA's. Measured in Chromium before this rule: the
|
|
1046
|
+
* first Tab into the shell landed on a rail item drawing Chrome's own
|
|
1047
|
+
* `outline: rgb(0,95,204) auto 1px`, a blue that belongs to no theme and matches nothing else
|
|
1048
|
+
* on the page, while every Button beside it drew the token ring. On a Slack-style shell that
|
|
1049
|
+
* is the FIRST thing a keyboard user sees.
|
|
1050
|
+
*
|
|
1051
|
+
* Same shape as `.app-main:focus-visible` above — suppress the UA outline, draw a token ring —
|
|
1052
|
+
* but NOT gated behind an opt-in width the way the region ring is. A whole-content-area frame
|
|
1053
|
+
* reads as a glitch and defaults off; a 2px ring hugging one 32px row is exactly the
|
|
1054
|
+
* affordance, so it reads the global `--focus-ring-width` and is on by default. `box-shadow`
|
|
1055
|
+
* rather than `outline` so the ring follows `--sidebar-nav-item-radius`. */
|
|
1056
|
+
.sb-nav-item:focus-visible {
|
|
1057
|
+
outline: none;
|
|
1058
|
+
box-shadow: 0 0 0 var(--focus-ring-width) hsl(var(--focus-ring-color, var(--ring)));
|
|
1059
|
+
}
|
|
1060
|
+
|
|
971
1061
|
.sb-nav-item:hover {
|
|
972
1062
|
background: hsl(var(--accent));
|
|
973
1063
|
color: var(--sidebar-nav-item-hover-foreground, hsl(var(--foreground)));
|
|
@@ -1016,20 +1106,36 @@
|
|
|
1016
1106
|
white-space: nowrap;
|
|
1017
1107
|
}
|
|
1018
1108
|
|
|
1109
|
+
/* The nav row's count pill. Its COLOUR is a knob pair, and the resting values are exactly the
|
|
1110
|
+
* literals it carried before (rule #44/#45) — `initial` at the token tier so the role defaults
|
|
1111
|
+
* re-resolve under a scoped theme, resolved here at the call site. Before the knobs the only
|
|
1112
|
+
* way to emphasise a row was to nest a `<Badge>` INSIDE `badge`, which produced two stacked
|
|
1113
|
+
* pills: a 37.11×19.14 `.sb-badge` wrapping a 25.11×19.14 `<Badge>` with its own border. */
|
|
1019
1114
|
.sb-badge {
|
|
1020
1115
|
display: inline-flex;
|
|
1021
1116
|
min-width: 1.125rem;
|
|
1022
1117
|
align-items: center;
|
|
1023
1118
|
justify-content: center;
|
|
1024
1119
|
border-radius: var(--radius-pill);
|
|
1025
|
-
background: hsl(var(--secondary));
|
|
1026
|
-
color: hsl(var(--muted-foreground));
|
|
1120
|
+
background: var(--sidebar-badge-background, hsl(var(--secondary)));
|
|
1121
|
+
color: var(--sidebar-badge-foreground, hsl(var(--muted-foreground)));
|
|
1027
1122
|
font-size: var(--sidebar-badge-font-size);
|
|
1028
1123
|
font-weight: var(--font-weight-medium);
|
|
1029
1124
|
line-height: 1.2;
|
|
1030
1125
|
padding-inline: 0.375rem;
|
|
1031
1126
|
}
|
|
1032
1127
|
|
|
1128
|
+
/* `badgeTone="destructive"` — the count is ADDRESSED TO YOU (an @mention, a direct message),
|
|
1129
|
+
* not merely unread. Present-when-on (rule #44): a neutral row emits no `data-tone` at all, so
|
|
1130
|
+
* this rule cannot reach it and the default pill is byte-identical. GEOMETRY IS UNTOUCHED — the
|
|
1131
|
+
* tone moves two colours and nothing else, which is the whole point of the axis: the row's
|
|
1132
|
+
* height, the pill's radius and its 0.375rem inline pad stay on the base rule, so a mention row
|
|
1133
|
+
* and an unread row still line up in the same column. */
|
|
1134
|
+
.sb-badge[data-tone="destructive"] {
|
|
1135
|
+
background: var(--sidebar-badge-destructive-background, hsl(var(--destructive)));
|
|
1136
|
+
color: var(--sidebar-badge-destructive-foreground, hsl(var(--destructive-foreground)));
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1033
1139
|
.sb-footer {
|
|
1034
1140
|
margin-top: auto;
|
|
1035
1141
|
border-top: 1px solid hsl(var(--border));
|
|
@@ -1174,10 +1280,6 @@
|
|
|
1174
1280
|
outline: none;
|
|
1175
1281
|
}
|
|
1176
1282
|
|
|
1177
|
-
.sb-user:focus-visible {
|
|
1178
|
-
box-shadow: 0 0 0 var(--focus-ring-width) hsl(var(--focus-ring-color, var(--ring)) / 0.45);
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
1283
|
.sb-user-avatar {
|
|
1182
1284
|
position: relative;
|
|
1183
1285
|
display: inline-flex;
|
|
@@ -1424,8 +1526,8 @@
|
|
|
1424
1526
|
|
|
1425
1527
|
.tb-chip-icon {
|
|
1426
1528
|
display: grid;
|
|
1427
|
-
width:
|
|
1428
|
-
height:
|
|
1529
|
+
width: var(--topbar-chip-icon-size);
|
|
1530
|
+
height: var(--topbar-chip-icon-size);
|
|
1429
1531
|
flex: 0 0 auto;
|
|
1430
1532
|
place-items: center;
|
|
1431
1533
|
border-radius: calc(var(--radius) - 2px);
|
|
@@ -1452,8 +1554,8 @@
|
|
|
1452
1554
|
}
|
|
1453
1555
|
|
|
1454
1556
|
.tb-chip-caret svg {
|
|
1455
|
-
width:
|
|
1456
|
-
height:
|
|
1557
|
+
width: var(--topbar-caret-icon-size);
|
|
1558
|
+
height: var(--topbar-caret-icon-size);
|
|
1457
1559
|
}
|
|
1458
1560
|
|
|
1459
1561
|
.tb-search {
|
|
@@ -1480,8 +1582,8 @@
|
|
|
1480
1582
|
|
|
1481
1583
|
.tb-search svg,
|
|
1482
1584
|
.tb-icon-btn svg {
|
|
1483
|
-
width:
|
|
1484
|
-
height:
|
|
1585
|
+
width: var(--topbar-icon-size);
|
|
1586
|
+
height: var(--topbar-icon-size);
|
|
1485
1587
|
}
|
|
1486
1588
|
|
|
1487
1589
|
.kbd {
|
|
@@ -1521,10 +1623,6 @@
|
|
|
1521
1623
|
outline: none;
|
|
1522
1624
|
}
|
|
1523
1625
|
|
|
1524
|
-
.tb-icon-btn:focus-visible {
|
|
1525
|
-
box-shadow: 0 0 0 var(--focus-ring-width) hsl(var(--focus-ring-color, var(--ring)) / 0.45);
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
1626
|
.tb-bell {
|
|
1529
1627
|
position: relative;
|
|
1530
1628
|
}
|
|
@@ -3,6 +3,27 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
@layer components {
|
|
6
|
+
/* The table's base type. It used to ride on a `text-sm` utility emitted by the component; the
|
|
7
|
+
* font-size AND its line-height companion now live here (gh#319 — see
|
|
8
|
+
* tokens/components/table.css for why both are required). */
|
|
9
|
+
[data-slot="table"] {
|
|
10
|
+
font-size: var(--table-font-size);
|
|
11
|
+
line-height: var(--table-line-height);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Horizontal rules between rows, and the "last row draws no rule" idiom. Both must be in the
|
|
15
|
+
* SAME layer: while the row's rule was a `border-b` utility, no `components` selector could
|
|
16
|
+
* zero it on the last row however specific (the gh#412 layer contract), so the tbody had to
|
|
17
|
+
* carry an arbitrary-variant utility of its own. `[data-slot="table-body"] .ui-table-row`
|
|
18
|
+
* (0,2,0) beats `.ui-table-row` (0,1,0), so the last-row reset lands cleanly. */
|
|
19
|
+
.ui-table-row {
|
|
20
|
+
border-block-end-width: var(--table-row-border-width);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
[data-slot="table-body"] .ui-table-row:last-child {
|
|
24
|
+
border-block-end-width: 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
6
27
|
[data-slot="table-head"] {
|
|
7
28
|
height: var(--table-row-height);
|
|
8
29
|
padding: var(--table-cell-padding-y) var(--table-cell-space-x);
|
|
@@ -268,10 +289,9 @@
|
|
|
268
289
|
inset-inline-end: 0;
|
|
269
290
|
}
|
|
270
291
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
292
|
+
/* The flush frame contract lives in ONE place, next to `.ui-table-bordered` below — it has to
|
|
293
|
+
* cover BOTH full-bleed surfaces (`.ui-data-table-surface` and `<Table bordered>`) or the fix
|
|
294
|
+
* for one silently regresses the other (gh#305 → gh#306). */
|
|
275
295
|
|
|
276
296
|
@media (min-width: 640px) {
|
|
277
297
|
.ui-data-table-scroll {
|
|
@@ -347,17 +367,60 @@
|
|
|
347
367
|
border-inline-end: 1px solid var(--table-border-color, hsl(var(--border)));
|
|
348
368
|
}
|
|
349
369
|
|
|
350
|
-
/*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
370
|
+
/* ── The flush full-bleed frame contract (gh#305 · gh#306) ────────────────────────────────
|
|
371
|
+
* A full-bleed surface inside `<CardContent flush>` already has the CARD's 1px frame around
|
|
372
|
+
* it, so its own outer frame doubles up as two nested rounded borders (measured on
|
|
373
|
+
* customer-inquiries detail: TABLE 1px inside the card's 1px, gh#305). Both full-bleed
|
|
374
|
+
* surfaces are covered by ONE rule: `.ui-data-table-surface` (the DataTable's own frame) and
|
|
375
|
+
* `.ui-table-bordered` (`<Table bordered>`). They used to be two rules a hundred lines apart
|
|
376
|
+
* and the gh#306 repair reached only the second — the canonical
|
|
377
|
+
* `<Card><CardContent flush><DataTable/></CardContent></Card>` kept a frameless surface, so
|
|
378
|
+
* the header still floated with no line under it (measured at HEAD: surface
|
|
379
|
+
* border-top-width 0px).
|
|
380
|
+
*
|
|
381
|
+
* ERASE, never repaint (rule #44). The earlier repair spelled this `border: 0` followed by a
|
|
382
|
+
* hard-coded `border-block-start: 1px solid …` — chrome painted unconditionally, which is the
|
|
383
|
+
* bug pattern the rule exists to forbid: it re-drew the line even where the card already had
|
|
384
|
+
* one (a banded header's own bottom border → a doubled 2px rule) and even where the card frame
|
|
385
|
+
* itself sits (a headerless card → a doubled top edge). Here only the WIDTH is zeroed, so the
|
|
386
|
+
* style and colour stay whatever the surface's own border declared, and the block-start edge is
|
|
387
|
+
* restored only where something actually needs separating.
|
|
388
|
+
*
|
|
389
|
+
* `.ui-skeleton-table` rides along in BOTH lists on purpose. It is the placeholder the real
|
|
390
|
+
* DataTable swaps for, and alert-layout.css says so in as many words ("mirrors
|
|
391
|
+
* `.ui-data-table-surface` … so the skeleton placeholder and the real DataTable it swaps for
|
|
392
|
+
* sit identically"). Give the surface a divider without giving the skeleton one and that
|
|
393
|
+
* promise breaks: a 1px line appears the instant the data lands. (alert-layout.css keeps its
|
|
394
|
+
* own copy of the erase half so Skeleton is still framed correctly for a consumer who imports
|
|
395
|
+
* it WITHOUT this layer.) */
|
|
396
|
+
[data-slot="card-content"][data-flush]
|
|
397
|
+
:is(.ui-data-table-surface, .ui-table-bordered, .ui-skeleton-table) {
|
|
398
|
+
border-width: 0;
|
|
399
|
+
border-radius: 0;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/* …restored ONLY when a plain CardHeader sits DIRECTLY above the flush body. That edge is the
|
|
403
|
+
* one place a flush surface's border does NOT coincide with something the card already draws:
|
|
404
|
+
* above it is the header's whitespace, not the card frame (gh#306, measured on a rental
|
|
405
|
+
* detail's 出荷伝票一覧 section). Adjacent-sibling, not `:has()` on the card, so the three
|
|
406
|
+
* counter-cases fall out by construction and need no extra rule: no header above → the card
|
|
407
|
+
* frame is the top edge; a BANDED header → its own `border-bottom` is the divider; a CardBar
|
|
408
|
+
* above → its own `border-block` is. Width comes from a token (rules #44/#45) whose default is
|
|
409
|
+
* the same hairline the surface itself draws, so a service quiets the divider once instead of
|
|
410
|
+
* forking this file. */
|
|
411
|
+
[data-slot="card-header"]:not([data-banded])
|
|
412
|
+
+ [data-slot="card-content"][data-flush]
|
|
413
|
+
:is(.ui-data-table-surface, .ui-table-bordered, .ui-skeleton-table) {
|
|
414
|
+
border-block-start-width: var(--table-flush-divider-width);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/* …and quieted again when a DataTable TOOLBAR sits between the header and the surface: the
|
|
418
|
+
* flush toolbar already draws that dividing line (see `.ui-data-table-toolbar` above), so the
|
|
419
|
+
* surface below it would stack a second hairline on top of it. Done by setting the token on the
|
|
420
|
+
* root rather than by another `border-*` rule, so it INHERITS down to whichever surface ends up
|
|
421
|
+
* under the toolbar and cannot get into a specificity race with the restore rule. */
|
|
422
|
+
[data-slot="card-content"][data-flush] .ui-data-table-root:has(.ui-data-table-toolbar) {
|
|
423
|
+
--table-flush-divider-width: 0px;
|
|
361
424
|
}
|
|
362
425
|
}
|
|
363
426
|
|
|
@@ -452,14 +515,82 @@
|
|
|
452
515
|
}
|
|
453
516
|
|
|
454
517
|
/* The compact tier lives in `godxjp-ui-responsive` — the LAST layer, declared after Tailwind in
|
|
455
|
-
* styles/base.css — not in `@layer components`.
|
|
456
|
-
* and `utilities` outranks `components` by LAYER ORDER, so a `font-size:` re-point
|
|
457
|
-
* a component rule
|
|
518
|
+
* styles/base.css — not in `@layer components`. The <table> USED to carry `text-sm`, a Tailwind
|
|
519
|
+
* utility, and `utilities` outranks `components` by LAYER ORDER, so a `font-size:` re-point
|
|
520
|
+
* written as a component rule could never apply however specific it was: that is exactly why
|
|
458
521
|
* `--table-action-collection-font-size-compact` was dead at every width (gh#412), leaving the
|
|
459
|
-
* narrow frame at 14px where a 5–6 character Japanese label overflows its column measure.
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
522
|
+
* narrow frame at 14px where a 5–6 character Japanese label overflows its column measure.
|
|
523
|
+
* gh#319 moved the base type off that utility and onto `[data-slot="table"]` above, but the
|
|
524
|
+
* compact tier STAYS here: a CONSUMER's own `text-*` utility on the table would otherwise
|
|
525
|
+
* half-collapse it, and this keeps the whole tier — type AND column measures — decided in ONE
|
|
526
|
+
* place. See styles/base.css · THE LAYER CONTRACT. */
|
|
527
|
+
@layer components {
|
|
528
|
+
/* DATA TABLE — the pieces around the already-tokenized cell rhythm (#319).
|
|
529
|
+
*
|
|
530
|
+
* These belong in `components`, not in the responsive layer above: an append placed them there
|
|
531
|
+
* by mistake (it targeted the file's last `}`, which closes the layer, not the layer's own end)
|
|
532
|
+
* and `table-action-collection.test.tsx` catches exactly that — the responsive layer is
|
|
533
|
+
* reserved for media-queried rules.
|
|
534
|
+
*
|
|
535
|
+
* Four of them are scoped through `.ui-data-table-root` rather than left bare, because the last
|
|
536
|
+
* layer was doing work for them: the icon rules sit on svgs inside real <Button>s where
|
|
537
|
+
* `.ui-button svg` (0,1,1) outranks a bare class, and the skeleton chip's radius competes with
|
|
538
|
+
* `.ui-skeleton-block` from the later-imported alert-layout.css. Demoting them without raising
|
|
539
|
+
* specificity would have shrunk the toolbar/pagination glyphs and re-rounded the chips. */
|
|
540
|
+
|
|
541
|
+
/* DATA TABLE — the pieces around the already-tokenized cell rhythm (#319). */
|
|
542
|
+
|
|
543
|
+
/* The select column holds only a checkbox, so it takes a fixed narrow width rather than a
|
|
544
|
+
* share of the flexible content columns. */
|
|
545
|
+
.ui-data-table-select-column {
|
|
546
|
+
inline-size: var(--table-select-column-width);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/* A sticky header floats over the scrolled rows, so it joins the one system overlay layer
|
|
550
|
+
* rather than carrying a private z-index that a portaled surface could out-rank. */
|
|
551
|
+
.ui-data-table-sticky-header {
|
|
552
|
+
position: sticky;
|
|
553
|
+
inset-block-start: 0;
|
|
554
|
+
z-index: 10;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
.ui-data-table-sort-icon {
|
|
558
|
+
inline-size: var(--table-sort-icon-size);
|
|
559
|
+
block-size: var(--table-sort-icon-size);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
.ui-data-table-root .ui-data-table-toolbar-icon {
|
|
563
|
+
inline-size: var(--table-toolbar-icon-size);
|
|
564
|
+
block-size: var(--table-toolbar-icon-size);
|
|
565
|
+
flex-shrink: 0;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
.ui-data-table-root .ui-data-table-pagination-icon {
|
|
569
|
+
inline-size: var(--table-pagination-icon-size);
|
|
570
|
+
block-size: var(--table-pagination-icon-size);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
.ui-data-table-pagination-text {
|
|
574
|
+
font-size: var(--table-pagination-font-size);
|
|
575
|
+
color: hsl(var(--muted-foreground));
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/* Skeletons mimic the real content: a checkbox square and a text line at cap height. */
|
|
579
|
+
.ui-data-table-root .ui-data-table-skeleton-check {
|
|
580
|
+
inline-size: var(--table-skeleton-check-size);
|
|
581
|
+
block-size: var(--table-skeleton-check-size);
|
|
582
|
+
border-radius: var(--table-skeleton-radius);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
.ui-data-table-root .ui-data-table-skeleton-line {
|
|
586
|
+
block-size: var(--table-skeleton-line-height);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
.ui-data-table-sort-button {
|
|
590
|
+
border-radius: var(--table-skeleton-radius);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
463
594
|
@layer godxjp-ui-responsive {
|
|
464
595
|
/* Below the step the SOURCE measures are re-pointed to their compact tier (and the type / row
|
|
465
596
|
* density with them); nothing else moves. One block per canonical step — a media/container
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/* TOGGLE · counter pill + pressed-state chrome (gh#312).
|
|
2
|
+
*
|
|
3
|
+
* The Toggle BOX itself (heights, padding, variants, the pressed fill) lives in
|
|
4
|
+
* `styles/control.css` alongside every other control — import `@godxjp/ui/styles/control` for it.
|
|
5
|
+
* This layer is only the counter pill Toggle shares with Button, plus the non-colour encodings of
|
|
6
|
+
* the pressed state; `@godxjp/ui/styles` imports it right after control.css so its pressed-state
|
|
7
|
+
* rules land later in the cascade at equal specificity.
|
|
8
|
+
*
|
|
9
|
+
* Every constant here is a token declared in `tokens/components/toggle.css`, where the share-vs-
|
|
10
|
+
* split reasoning and the measured contrast numbers live. The geometry knobs carry Button's exact
|
|
11
|
+
* counter values off the same primitive scale (asserted by the token-parity test), so the two
|
|
12
|
+
* pills are the same size; only the COLOUR knobs are deliberately Toggle's own, because Toggle's
|
|
13
|
+
* pill sits on a surface that inverts.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
@layer components {
|
|
17
|
+
.ui-toggle-count {
|
|
18
|
+
display: inline-flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
justify-content: center;
|
|
21
|
+
min-inline-size: var(--toggle-count-min-width);
|
|
22
|
+
margin-inline-start: var(--toggle-count-gap);
|
|
23
|
+
border-radius: var(--toggle-count-radius);
|
|
24
|
+
padding-inline: var(--toggle-count-space-inline);
|
|
25
|
+
background: var(--toggle-count-background, hsl(var(--muted)));
|
|
26
|
+
color: var(--toggle-count-color, hsl(var(--foreground)));
|
|
27
|
+
font-size: var(--toggle-count-font-size);
|
|
28
|
+
line-height: 1;
|
|
29
|
+
font-variant-numeric: tabular-nums;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* PRESSED — the state is never carried by hue alone (WCAG 1.4.1). Three independent encodings:
|
|
33
|
+
* the chip's own fill/label invert (control.css), the pill inverts from a quiet near-invisible
|
|
34
|
+
* chip to a solid one, and the forced-colors rule below. `aria-pressed` carries it
|
|
35
|
+
* programmatically; nothing appends "(selected)" to the accessible name. */
|
|
36
|
+
.ui-toggle[data-state="on"] {
|
|
37
|
+
border-color: var(--toggle-pressed-border-color, hsl(var(--primary)));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.ui-toggle[data-state="on"] .ui-toggle-count {
|
|
41
|
+
background: var(--toggle-pressed-count-background, hsl(var(--primary-foreground)));
|
|
42
|
+
color: var(--toggle-pressed-count-color, hsl(var(--primary)));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Forced colors flattens every background, so neither inversion distinguishes the states any
|
|
46
|
+
* more. An outline on the pressed pill restores a structural difference at zero layout cost,
|
|
47
|
+
* and the chip's border follows the system Highlight — the `default` variant's border is
|
|
48
|
+
* `transparent` when unpressed, and forced-colors preserves transparency, so the two states
|
|
49
|
+
* stay structurally different there too. */
|
|
50
|
+
@media (forced-colors: active) {
|
|
51
|
+
.ui-toggle[data-state="on"] {
|
|
52
|
+
border-color: Highlight;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.ui-toggle[data-state="on"] .ui-toggle-count {
|
|
56
|
+
outline: var(--toggle-count-forced-outline-width) solid currentColor;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
package/dist/tokens/base.css
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
@import "./semantic/layout.css";
|
|
8
8
|
@import "./axes.css";
|
|
9
9
|
@import "./components/control.css";
|
|
10
|
+
@import "./components/toggle.css";
|
|
10
11
|
@import "./components/form.css";
|
|
11
12
|
@import "./components/card.css";
|
|
12
13
|
@import "./components/chart.css";
|
|
@@ -18,11 +19,15 @@
|
|
|
18
19
|
@import "./components/badge.css";
|
|
19
20
|
@import "./components/navigation.css";
|
|
20
21
|
@import "./components/data-display.css";
|
|
22
|
+
@import "./components/scroll-area.css";
|
|
21
23
|
@import "./components/list-row.css";
|
|
22
24
|
@import "./components/logo.css";
|
|
23
25
|
@import "./components/email.css";
|
|
24
26
|
@import "./components/data-entry.css";
|
|
27
|
+
@import "./components/upload.css";
|
|
25
28
|
@import "./components/shell.css";
|
|
29
|
+
@import "./components/separator.css";
|
|
26
30
|
@import "./components/sidebar.css";
|
|
27
31
|
@import "./components/legal-document.css";
|
|
28
32
|
@import "./components/error-surface.css";
|
|
33
|
+
@import "./components/activity.css";
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ACTIVITY — the ambient/looping motion primitive (gh#313).
|
|
3
|
+
*
|
|
4
|
+
* The loop counterpart to `Reveal`: `Reveal` runs ONCE on mount, `Activity` runs FOREVER while
|
|
5
|
+
* something is happening elsewhere (someone typing, a sync in flight, a response streaming, a
|
|
6
|
+
* recording running). Every value the loop reads is a knob (cardinal rule #45) so a service theme
|
|
7
|
+
* retunes the whole ambient feel in one place instead of forking a `@keyframes`.
|
|
8
|
+
*
|
|
9
|
+
* TIMING LIVES IN THE MOTION TIER, NOT HERE. `--duration-loop`, `--activity-interval` and
|
|
10
|
+
* `--activity-stagger-step` are declared in `src/tokens/foundation.css` beside `--duration-slow`
|
|
11
|
+
* and `--reveal-stagger-step`: they are the cycle members of the motion tier, they must sit next
|
|
12
|
+
* to their one-shot siblings to stay comparable, and `check-token-tiers`' component-token name
|
|
13
|
+
* shape (`--{component}-{part}-{property}`) has no property word for a duration. Geometry, colour
|
|
14
|
+
* and alpha — everything the shape rule DOES cover — live here.
|
|
15
|
+
*
|
|
16
|
+
* Defaults are the QUIETEST ambient state (cardinal rule #44): muted ink, a small mark, low travel.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
:root {
|
|
20
|
+
/* Mark geometry. `em`-based so the whole mark tracks `--activity-font-size-*` (and therefore
|
|
21
|
+
* `--font-size-base` and the density axis) instead of pinning a px diameter per size step. */
|
|
22
|
+
--activity-mark-size: 0.25em;
|
|
23
|
+
/* Travel of one `dots` step — the loop counterpart to `--reveal-distance`, named to match.
|
|
24
|
+
* It is ALSO the height the mark row reserves, so the indicator appearing under a composer
|
|
25
|
+
* never shifts the row. */
|
|
26
|
+
--activity-mark-offset: 0.25em;
|
|
27
|
+
/* Resting opacity of a dot at the bottom of its cycle. Never 0: a dot that vanishes reads as a
|
|
28
|
+
* rendering bug at the trough, and the reduced-motion resting state must stay fully legible. */
|
|
29
|
+
--activity-mark-rest-alpha: 0.35;
|
|
30
|
+
/* The single `pulse` mark — a breathing dot (live / recording), bigger than one `dots` dot
|
|
31
|
+
* because it carries the whole affordance alone. */
|
|
32
|
+
--activity-pulse-mark-size: 0.5em;
|
|
33
|
+
|
|
34
|
+
/* Mark-to-mark and mark-to-label gap. */
|
|
35
|
+
--activity-gap: var(--space-1);
|
|
36
|
+
|
|
37
|
+
/* Root size ladder — the mark is `em`-based, so this ONE value scales the whole indicator.
|
|
38
|
+
* Steps mirror the `Text` size the label is rendered at, so mark and label stay optically
|
|
39
|
+
* paired (`--font-size-sm` IS `--font-size-base`; the ladder skips the alias). */
|
|
40
|
+
--activity-font-size-xs: var(--font-size-2xs);
|
|
41
|
+
--activity-font-size-sm: var(--font-size-xs);
|
|
42
|
+
--activity-font-size-md: var(--font-size-sm);
|
|
43
|
+
--activity-font-size-lg: var(--font-size-lg);
|
|
44
|
+
|
|
45
|
+
/* Indeterminate `bar` (syncing). Width is an inline measure, not a fill: the bar sits beside a
|
|
46
|
+
* label in a row, so `100%` would eat the label's space. */
|
|
47
|
+
--activity-bar-width: 4rem;
|
|
48
|
+
--activity-bar-radius: var(--radius-pill);
|
|
49
|
+
--activity-bar-segment-width: 40%;
|
|
50
|
+
--activity-bar-track-alpha: 0.2;
|
|
51
|
+
/* Bar THICKNESS, declared last in the group because it carries the axis exemption below.
|
|
52
|
+
* Drawn at TEXT scale, not band scale: the bar sits inline beside its label, so it tracks the
|
|
53
|
+
* type it accompanies instead of a fixed step (gh#324). */
|
|
54
|
+
/* scale-exempt: an em thickness that must track the label beside it, not a fixed band step */
|
|
55
|
+
--activity-bar-height: 0.25em;
|
|
56
|
+
|
|
57
|
+
/* Mark colour. ROLE-MIRROR KNOB ⇒ declared `initial` here with the role default at the CALL SITE
|
|
58
|
+
* (`hsl(var(--activity-color, var(--muted-foreground)))` in styles/motion.css). Written as
|
|
59
|
+
* `--activity-color: var(--muted-foreground)` it would freeze at the `:root` role value and a
|
|
60
|
+
* scoped `[data-tenant]` / `.dark` override of `--muted-foreground` would never reach it.
|
|
61
|
+
* @see docs/TOKENS.md · "Role-mirror knobs MUST be `initial`".
|
|
62
|
+
* Documented default: --activity-color = var(--muted-foreground) (tone="muted"). */
|
|
63
|
+
--activity-color: initial;
|
|
64
|
+
}
|
|
@@ -12,4 +12,11 @@
|
|
|
12
12
|
* remaps --text-xs but never that companion). Same unitless ratio here keeps the default
|
|
13
13
|
* badge pixel-identical now that badge-layout.css owns the type metrics. */
|
|
14
14
|
--badge-line-height: calc(1 / 0.75);
|
|
15
|
+
/* Leading/trailing glyph inside the pill. It was a bare `0.75rem` in badge-layout.css with no
|
|
16
|
+
* token at all, so a service could only resize it with `!important` or a forked stylesheet —
|
|
17
|
+
* the two routes the icon axis's tier 2 exists to abolish (gh#326). Same step, so nothing
|
|
18
|
+
* moves. Matches --badge-font-size's step by design: the glyph reads as a character in the
|
|
19
|
+
* label's run, so the two retune together. Deliberately NOT --scaling-multiplied — the literal
|
|
20
|
+
* it replaces did not track density. */
|
|
21
|
+
--badge-icon-size: var(--icon-size-xs);
|
|
15
22
|
}
|