@godxjp/ui 33.9.1 → 33.10.1
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/DESIGN.md +9 -7
- package/README.md +2 -2
- package/agent/DESIGN.md +9 -7
- package/agent/START-HERE.md +1 -1
- package/agent/index.json +3 -3
- package/agent/llms.txt +4 -4
- package/agent/tokens.json +35 -35
- package/dist/contracts/measurement.json +1 -1
- package/dist/styles/layers.json +1 -1
- package/dist/styles.css +1 -1
- package/dist/tokens/components/card.css +3 -3
- package/dist/tokens/components/control.css +4 -4
- package/dist/tokens/components/form.css +1 -1
- package/dist/tokens/components/table.css +1 -1
- package/dist/tokens/foundation.css +11 -11
- package/dist/tokens/semantic/layout.css +3 -3
- package/docs/TOKENS.md +62 -1
- package/package.json +2 -2
package/DESIGN.md
CHANGED
|
@@ -14,7 +14,7 @@ colors:
|
|
|
14
14
|
muted: "#f4f3f0" # --muted / --secondary (quiet fills, zebra, hover)
|
|
15
15
|
accent: "#ebe9e5" # --accent (hover/selected background, NOT a brand colour)
|
|
16
16
|
hairline: "#eeedec" # --border (dividers, card edges, table rules)
|
|
17
|
-
control-edge: "#
|
|
17
|
+
control-edge: "#8b8279" # --input (the edge of an input; 3:1 against canvas)
|
|
18
18
|
success: "#68be8d" # --success 若竹
|
|
19
19
|
warning: "#f8b500" # --warning 山吹
|
|
20
20
|
info: "#4c6cb3" # --info 群青
|
|
@@ -28,9 +28,9 @@ colors:
|
|
|
28
28
|
typography:
|
|
29
29
|
family: "system stack (--font-sans-base); Noto Sans JP via opt-in @godxjp/ui/styles/fonts"
|
|
30
30
|
base: 14px # --font-size-base; every step derives from it (ratio --font-size-ratio 1.1227)
|
|
31
|
-
page-title: { size: "
|
|
31
|
+
page-title: { size: "28px (--page-title-font-size); 21px compact", weight: 500, lineHeight: 1.25 }
|
|
32
32
|
section-title: { size: "~17.6px (--heading-h2)", weight: 500, lineHeight: 1.25 }
|
|
33
|
-
card-title: { size: "
|
|
33
|
+
card-title: { size: "~15.7px (--card-title-font-size)", weight: 500, lineHeight: 1.25 }
|
|
34
34
|
body: { size: 14px, weight: 400, lineHeight: 1.7 } # --line-height-body
|
|
35
35
|
caption: { size: "~12.5px (--font-size-xs)", weight: 400, lineHeight: 1.5 }
|
|
36
36
|
weights: [400, 500, 700] # --font-weight-semibold is 500; there is no 600
|
|
@@ -46,13 +46,13 @@ spacing:
|
|
|
46
46
|
scale: "--space-1..24 = 4px steps (4, 8, 12, 16, 20, 24, 32, 40, 48, 80, 96)"
|
|
47
47
|
stack: { xs: 4px, sm: 8px, md: 16px, lg: 24px, xl: 40px } # Flex direction="col" gap
|
|
48
48
|
inline: { xs: 4px, sm: 8px, md: 12px, lg: 16px, xl: 24px } # Flex direction="row" gap
|
|
49
|
-
page: { x:
|
|
49
|
+
page: { x: 32px, y: 32px } # --space-page-x / -y
|
|
50
50
|
section: 16px # --space-section
|
|
51
51
|
|
|
52
52
|
density:
|
|
53
53
|
axis: "AppProvider density / PageContainer density / data-density"
|
|
54
54
|
compact: "--scaling 0.92 (data-heavy tables)"
|
|
55
|
-
default: "--scaling 1 (control and row height
|
|
55
|
+
default: "--scaling 1 (control and row height 36px, --band-height-lg)"
|
|
56
56
|
comfortable: "--scaling 1.08 (login, public, touch)"
|
|
57
57
|
touch-floor: 44px # --band-height-xl
|
|
58
58
|
|
|
@@ -75,7 +75,7 @@ components:
|
|
|
75
75
|
{
|
|
76
76
|
background: "{colors.canvas}",
|
|
77
77
|
border: "1px {colors.hairline}",
|
|
78
|
-
shadow: "--shadow
|
|
78
|
+
shadow: "none (--card-shadow)",
|
|
79
79
|
radius: "{rounded.card}",
|
|
80
80
|
padding: "--card-space-inset",
|
|
81
81
|
}
|
|
@@ -117,7 +117,7 @@ Colour is scarce. Most of the screen is canvas, ink and hairline.
|
|
|
117
117
|
|
|
118
118
|
## Elevation
|
|
119
119
|
|
|
120
|
-
- Flat. A card is canvas with a 1px `--border` hairline and
|
|
120
|
+
- Flat. A card is canvas with a 1px `--border` hairline and no resting shadow; elevation is reserved for floating surfaces.
|
|
121
121
|
- `--shadow-md`/`--shadow-lg` belong to things that float: popover, dropdown, dialog, sheet, toast.
|
|
122
122
|
- No hover lift on data cards. Depth never signals importance.
|
|
123
123
|
|
|
@@ -217,3 +217,5 @@ A list whose rows are decisions. Show requester, target, reason, submitted time;
|
|
|
217
217
|
- Dark theme (`data-theme="dark"`) is supported; the exemplars are reviewed in light.
|
|
218
218
|
- From 640px up, `BlockEditor` text does not share the keyline of the `Input` above it: measured at 768/1024/1280, input text 13px inside its frame, editor text 57px inside (Δ44px), because the ⋮⋮/+ handles (two 24px targets) sit in a start gutter inside the frame. Aligning the text would put the handles outside the field border, where a content column 24px from the viewport edge has no room. Below 640px the gutter collapses (C05). `--block-editor-gutter-inline-size` sets the gutter width; it cannot close the gap, because the handles live inside it. Accepted, not a defect to fix in the app.
|
|
219
219
|
- On narrow screens the `PageContainer` title steps down (≈17.6px) while body h2 stays ≈15.7px — one step apart. A document page not built on `LegalDocumentShell` keeps only that step on phones; there is no intermediate page-title size yet.
|
|
220
|
+
|
|
221
|
+
Modern refresh: field rows use 20px; form blocks 24px. Keyboard focus uses a 2px ring and 2px offset (navigation keeps its existing inset). Overlay scrim uses 40% black. Compact page gutters remain 16px. See docs/TOKENS.md for complete restoration.
|
package/README.md
CHANGED
|
@@ -51,12 +51,12 @@ static files straight from this public repo — no hosting, no deploy step:
|
|
|
51
51
|
| --- | --- | --- |
|
|
52
52
|
| [`agent/START-HERE.md`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/START-HERE.md) | 11 KB | **read first** — self-contained: the four rules, the token override model, a page that passes review |
|
|
53
53
|
| [`agent/llms.txt`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/llms.txt) | 3 KB | the [llms.txt](https://llmstxt.org/) entry point |
|
|
54
|
-
| [`agent/DESIGN.md`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/DESIGN.md) |
|
|
54
|
+
| [`agent/DESIGN.md`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/DESIGN.md) | 18 KB | the visual spec: tokens, colour scarcity, admin screen anatomy, do/don't |
|
|
55
55
|
| [`agent/index.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/index.json) | 3 KB | manifest: version, counts, every file's URL |
|
|
56
56
|
| [`agent/components-index.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components-index.json) | 52 KB | all 169 as name + group + tagline — **fetch this first** |
|
|
57
57
|
| [`agent/components/<Name>.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components/Select.json) | 1 KB–37 KB | one file per component, each with its `importPath` — **this is the route to take** |
|
|
58
58
|
| [`agent/components.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components.json) | 1.3 MB | all 169 entries in one file — most URL fetchers truncate this silently; prefer the per-component files |
|
|
59
|
-
| [`agent/tokens.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/tokens.json) |
|
|
59
|
+
| [`agent/tokens.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/tokens.json) | 857 KB | all 2235 design tokens, their values and why they exist |
|
|
60
60
|
| [`agent/vocabulary.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/vocabulary.json) | 7 KB | the controlled prop vocabulary |
|
|
61
61
|
| [`agent/rules.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/rules.json) | 23 KB | the 44 cardinal rules |
|
|
62
62
|
<!-- prettier-ignore-end -->
|
package/agent/DESIGN.md
CHANGED
|
@@ -14,7 +14,7 @@ colors:
|
|
|
14
14
|
muted: "#f4f3f0" # --muted / --secondary (quiet fills, zebra, hover)
|
|
15
15
|
accent: "#ebe9e5" # --accent (hover/selected background, NOT a brand colour)
|
|
16
16
|
hairline: "#eeedec" # --border (dividers, card edges, table rules)
|
|
17
|
-
control-edge: "#
|
|
17
|
+
control-edge: "#8b8279" # --input (the edge of an input; 3:1 against canvas)
|
|
18
18
|
success: "#68be8d" # --success 若竹
|
|
19
19
|
warning: "#f8b500" # --warning 山吹
|
|
20
20
|
info: "#4c6cb3" # --info 群青
|
|
@@ -28,9 +28,9 @@ colors:
|
|
|
28
28
|
typography:
|
|
29
29
|
family: "system stack (--font-sans-base); Noto Sans JP via opt-in @godxjp/ui/styles/fonts"
|
|
30
30
|
base: 14px # --font-size-base; every step derives from it (ratio --font-size-ratio 1.1227)
|
|
31
|
-
page-title: { size: "
|
|
31
|
+
page-title: { size: "28px (--page-title-font-size); 21px compact", weight: 500, lineHeight: 1.25 }
|
|
32
32
|
section-title: { size: "~17.6px (--heading-h2)", weight: 500, lineHeight: 1.25 }
|
|
33
|
-
card-title: { size: "
|
|
33
|
+
card-title: { size: "~15.7px (--card-title-font-size)", weight: 500, lineHeight: 1.25 }
|
|
34
34
|
body: { size: 14px, weight: 400, lineHeight: 1.7 } # --line-height-body
|
|
35
35
|
caption: { size: "~12.5px (--font-size-xs)", weight: 400, lineHeight: 1.5 }
|
|
36
36
|
weights: [400, 500, 700] # --font-weight-semibold is 500; there is no 600
|
|
@@ -46,13 +46,13 @@ spacing:
|
|
|
46
46
|
scale: "--space-1..24 = 4px steps (4, 8, 12, 16, 20, 24, 32, 40, 48, 80, 96)"
|
|
47
47
|
stack: { xs: 4px, sm: 8px, md: 16px, lg: 24px, xl: 40px } # Flex direction="col" gap
|
|
48
48
|
inline: { xs: 4px, sm: 8px, md: 12px, lg: 16px, xl: 24px } # Flex direction="row" gap
|
|
49
|
-
page: { x:
|
|
49
|
+
page: { x: 32px, y: 32px } # --space-page-x / -y
|
|
50
50
|
section: 16px # --space-section
|
|
51
51
|
|
|
52
52
|
density:
|
|
53
53
|
axis: "AppProvider density / PageContainer density / data-density"
|
|
54
54
|
compact: "--scaling 0.92 (data-heavy tables)"
|
|
55
|
-
default: "--scaling 1 (control and row height
|
|
55
|
+
default: "--scaling 1 (control and row height 36px, --band-height-lg)"
|
|
56
56
|
comfortable: "--scaling 1.08 (login, public, touch)"
|
|
57
57
|
touch-floor: 44px # --band-height-xl
|
|
58
58
|
|
|
@@ -75,7 +75,7 @@ components:
|
|
|
75
75
|
{
|
|
76
76
|
background: "{colors.canvas}",
|
|
77
77
|
border: "1px {colors.hairline}",
|
|
78
|
-
shadow: "--shadow
|
|
78
|
+
shadow: "none (--card-shadow)",
|
|
79
79
|
radius: "{rounded.card}",
|
|
80
80
|
padding: "--card-space-inset",
|
|
81
81
|
}
|
|
@@ -117,7 +117,7 @@ Colour is scarce. Most of the screen is canvas, ink and hairline.
|
|
|
117
117
|
|
|
118
118
|
## Elevation
|
|
119
119
|
|
|
120
|
-
- Flat. A card is canvas with a 1px `--border` hairline and
|
|
120
|
+
- Flat. A card is canvas with a 1px `--border` hairline and no resting shadow; elevation is reserved for floating surfaces.
|
|
121
121
|
- `--shadow-md`/`--shadow-lg` belong to things that float: popover, dropdown, dialog, sheet, toast.
|
|
122
122
|
- No hover lift on data cards. Depth never signals importance.
|
|
123
123
|
|
|
@@ -217,3 +217,5 @@ A list whose rows are decisions. Show requester, target, reason, submitted time;
|
|
|
217
217
|
- Dark theme (`data-theme="dark"`) is supported; the exemplars are reviewed in light.
|
|
218
218
|
- From 640px up, `BlockEditor` text does not share the keyline of the `Input` above it: measured at 768/1024/1280, input text 13px inside its frame, editor text 57px inside (Δ44px), because the ⋮⋮/+ handles (two 24px targets) sit in a start gutter inside the frame. Aligning the text would put the handles outside the field border, where a content column 24px from the viewport edge has no room. Below 640px the gutter collapses (C05). `--block-editor-gutter-inline-size` sets the gutter width; it cannot close the gap, because the handles live inside it. Accepted, not a defect to fix in the app.
|
|
219
219
|
- On narrow screens the `PageContainer` title steps down (≈17.6px) while body h2 stays ≈15.7px — one step apart. A document page not built on `LegalDocumentShell` keeps only that step on phones; there is no intermediate page-title size yet.
|
|
220
|
+
|
|
221
|
+
Modern refresh: field rows use 20px; form blocks 24px. Keyboard focus uses a 2px ring and 2px offset (navigation keeps its existing inset). Overlay scrim uses 40% black. Compact page gutters remain 16px. See docs/TOKENS.md for complete restoration.
|
package/agent/START-HERE.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
You are about to write code against a design system you did not author. This file is the whole
|
|
4
4
|
contract. Read it before you write JSX.
|
|
5
5
|
|
|
6
|
-
**This catalog describes `@godxjp/ui` 33.
|
|
6
|
+
**This catalog describes `@godxjp/ui` 33.10.1.** If the project you are editing has a different
|
|
7
7
|
version in its `package.json`, read the pinned catalog for THAT version instead
|
|
8
8
|
(`…/v<their-version>/agent/…`). A catalog newer than the installed package describes props that do
|
|
9
9
|
not exist yet; older, and it hides props that do. Neither failure announces itself.
|
package/agent/index.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
{
|
|
13
13
|
"file": "DESIGN.md",
|
|
14
|
-
"note": "
|
|
14
|
+
"note": "18 KB — the visual spec: tokens, colour scarcity, admin screen anatomy (list, detail, form, settings, dashboard), do/don't. Read before composing a screen.",
|
|
15
15
|
"url": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/DESIGN.md"
|
|
16
16
|
},
|
|
17
17
|
{
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"note": "Pin to the tag that matches the @godxjp/ui version you installed. A catalog newer than your package describes props you do not have; older, and it hides props you do.",
|
|
55
55
|
"read": {
|
|
56
56
|
"live": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/index.json",
|
|
57
|
-
"pinned": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/v33.
|
|
57
|
+
"pinned": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/v33.10.1/agent/index.json"
|
|
58
58
|
},
|
|
59
59
|
"source": "mcp/src/data — the same data @godxjp/ui-mcp serves — plus the foundation and semantic token tiers, read from src/tokens/*.css",
|
|
60
60
|
"start": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/START-HERE.md",
|
|
@@ -68,5 +68,5 @@
|
|
|
68
68
|
"foundation": "the seeds a consumer is invited to set — --primary, --background, --radius",
|
|
69
69
|
"semantic": "named roles that follow the seeds — --ring, --text-link, --overlay-background"
|
|
70
70
|
},
|
|
71
|
-
"version": "33.
|
|
71
|
+
"version": "33.10.1"
|
|
72
72
|
}
|
package/agent/llms.txt
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# @godxjp/ui
|
|
2
2
|
|
|
3
3
|
> A Japanese-enterprise React design system: 169 components, 2235 design tokens,
|
|
4
|
-
> 44 cardinal rules. This file is the entry point for AI agents. Catalog version 33.
|
|
4
|
+
> 44 cardinal rules. This file is the entry point for AI agents. Catalog version 33.10.1.
|
|
5
5
|
|
|
6
6
|
If your client can run a process, do not read these files — run the MCP server instead
|
|
7
|
-
(`npx @godxjp/ui-mcp@33.
|
|
7
|
+
(`npx @godxjp/ui-mcp@33.10.1`). It is searchable and version-locked. These files exist for agents
|
|
8
8
|
that can only fetch URLs.
|
|
9
9
|
|
|
10
10
|
## Start
|
|
11
11
|
|
|
12
12
|
- [START-HERE.md](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/START-HERE.md): the whole contract — the four rules, the token override model, a page that passes review. Read this first; it is self-contained.
|
|
13
13
|
- [index.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/index.json): version, counts, and the URL of every file.
|
|
14
|
-
- [DESIGN.md](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/DESIGN.md):
|
|
14
|
+
- [DESIGN.md](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/DESIGN.md): 18 KB — the visual spec: tokens, colour scarcity, admin screen anatomy (list, detail, form, settings, dashboard), do/don't. Read it before composing a screen.
|
|
15
15
|
|
|
16
16
|
## Catalog
|
|
17
17
|
|
|
@@ -27,7 +27,7 @@ that can only fetch URLs.
|
|
|
27
27
|
## Pinning
|
|
28
28
|
|
|
29
29
|
Every URL above tracks `main`. To pin to the release a project actually installed, swap `main` for
|
|
30
|
-
the tag: `.../godx-jp/godxjp-ui/v33.
|
|
30
|
+
the tag: `.../godx-jp/godxjp-ui/v33.10.1/agent/...`. A catalog that does not match the installed
|
|
31
31
|
package describes props that are absent, or hides props that are present, and says nothing either way.
|
|
32
32
|
|
|
33
33
|
Pinned catalogs only exist for releases whose tag actually contains `agent/`. If `…/v<version>/agent/index.json` returns 404, that release predates this catalog: read `…/main/…` instead and compare `index.json` → `version` against the package you have, so you at least know which way it drifted.
|
package/agent/tokens.json
CHANGED
|
@@ -132,10 +132,10 @@
|
|
|
132
132
|
"value": "30 7% 93%"
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
|
-
"description": "CONTROL BOUNDARY role — deliberately NOT the same value as --border (gh#315). The two roles answer different questions and are held to different bars: · --border is DECORATIVE chrome — table rules, card edges, section dividers. WCAG 2.2 SC 1.4.11 does not reach it (nothing about a divider is \"required to identify a component or its state\"), and darkening it would make the JP-dense table grid roar. It stays exactly where it is. · --input is the boundary that IS the control — the 1px edge of Input, Textarea, Select, the outline Button, TagInput, the composite date field, the topbar search. `--input` also fills the Switch's unchecked track. A text field here has NO fill of its own (`background: hsl(var(--background))`) and NO shadow to speak of, so that edge is the only thing that says \"you may type here\". That is squarely SC 1.4.11's 3:1 minimum. They shipped sharing `30 7% 83%`, which measured 1.46:1 on --background/--card — the one live WCAG failure a full DXS Platform sweep turned up.
|
|
135
|
+
"description": "CONTROL BOUNDARY role — deliberately NOT the same value as --border (gh#315). The two roles answer different questions and are held to different bars: · --border is DECORATIVE chrome — table rules, card edges, section dividers. WCAG 2.2 SC 1.4.11 does not reach it (nothing about a divider is \"required to identify a component or its state\"), and darkening it would make the JP-dense table grid roar. It stays exactly where it is. · --input is the boundary that IS the control — the 1px edge of Input, Textarea, Select, the outline Button, TagInput, the composite date field, the topbar search. `--input` also fills the Switch's unchecked track. A text field here has NO fill of its own (`background: hsl(var(--background))`) and NO shadow to speak of, so that edge is the only thing that says \"you may type here\". That is squarely SC 1.4.11's 3:1 minimum. They shipped sharing `30 7% 83%`, which measured 1.46:1 on --background/--card — the one live WCAG failure a full DXS Platform sweep turned up. The modern refresh uses 51% lightness: the previous 53% passed the translucent hovered row but fell below 3:1 on the full --accent ground. The boundary test now includes that ground in both themes. Guarded by src/tokens/__tests__/input-boundary-contrast.test.ts. #8b8279 — control boundary, ≥3:1 (WCAG 2.2 SC 1.4.11)",
|
|
136
136
|
"name": "--input",
|
|
137
137
|
"tier": "foundation",
|
|
138
|
-
"value": "30 7%
|
|
138
|
+
"value": "30 7% 51%"
|
|
139
139
|
},
|
|
140
140
|
{
|
|
141
141
|
"description": "STATUS FILLS AND THE INK THAT RIDES ON THEM. The FILLS are the palette and they do not move: 若竹, 山吹, 群青, 朱 are named colours, every solid success/attention surface in every consumer is one of them, and a chip that changes hue on upgrade is a different design. What moved is the INK, and only where it failed to be readable (gh#643). Measured from these very tokens (src/tokens/__tests__/status-fill-contrast.test.ts, and confirmed in Chromium by `check:frame-axe` on /isolate/foundation-colors at 320/375/1440): role fill WAS near-white ink dark ink (48 8% 13%) success #68be8d 2.19:1 ✗ 7.08:1 ✓ attention #eb6101 3.32:1 ✗ 4.68:1 ✓ warning #f8b500 1.74:1 ✗ 8.91:1 ✓ (already dark — the precedent) primary #18181b 17.45:1 ✓ (the GoDX preset #008066: 4.86:1) destructive … 6.10:1 ✓ info #4c6cb3 5.00:1 ✓ Two of the eight light-theme fills carried an ink their own lightness cannot support, and the package already knew the answer twice over: --warning-foreground has always been this same near-black on the equally pale 山吹, and the DARK theme flips --success-foreground / --attention-foreground to 48 9% 9% for exactly this reason. The light block was the outlier. REJECTED — darkening 若竹 and 朱 so the near-white ink clears 4.5:1. A fill needs luminance ≤ 0.183 for that; 若竹 sits at 0.422, so \"keep the white text\" means a different green, not a darker one. That is the palette change this deliberately is not. 若竹 #68be8d",
|
|
@@ -525,13 +525,13 @@
|
|
|
525
525
|
"description": "Foundation tokens: color, typography, raw spacing, ratio, radius, shadow.",
|
|
526
526
|
"name": "--shadow-md",
|
|
527
527
|
"tier": "foundation",
|
|
528
|
-
"value": "0
|
|
528
|
+
"value": "0 6px 16px -4px rgb(var(--shadow-color) / 0.08), 0 1px 3px 0 rgb(var(--shadow-color) / 0.08)"
|
|
529
529
|
},
|
|
530
530
|
{
|
|
531
531
|
"description": "Foundation tokens: color, typography, raw spacing, ratio, radius, shadow.",
|
|
532
532
|
"name": "--shadow-lg",
|
|
533
533
|
"tier": "foundation",
|
|
534
|
-
"value": "0
|
|
534
|
+
"value": "0 12px 28px -6px rgb(var(--shadow-color) / 0.1), 0 2px 6px -2px rgb(var(--shadow-color) / 0.08)"
|
|
535
535
|
},
|
|
536
536
|
{
|
|
537
537
|
"description": "Foundation tokens: color, typography, raw spacing, ratio, radius, shadow.",
|
|
@@ -582,16 +582,16 @@
|
|
|
582
582
|
"value": "initial"
|
|
583
583
|
},
|
|
584
584
|
{
|
|
585
|
-
"description": "── THE SWITCH ─────────────────────────────────────────────────────────────────────────── `--focus-outline` is ONE 0/1 flag, and every painted focus length below multiplies by it: --focus-ring-width: calc(var(--focus-ring-weight) * var(--focus-outline)) — so setting it to 0 zeroes the whole indicator at once. There is deliberately no parallel mechanism: one multiplier is the only shape in which a kill switch cannot be routed around by a per-component rebind. IT SHIPS ON, as of gh#544 — it used to ship off, and that reversal is the point of this note. The old default was a real product decision: the indicator had been reported as intrusive and the owner accepted the cost, which was that this library did not satisfy WCAG 2.2 SC 2.4.7 Focus Visible (AA) and so could carry no JIS X 8341-3:2016 AA statement. What changed is not the principle but two measurements. FIRST, what the default actually produced. Counting `data-focus-outline` across the four real consumers of this package: `ql` sets it (3 files); `godx-task`, `godx-chat` and the platform app set it NOWHERE. Three of four products shipped with no keyboard-focus indicator at all — not chosen, because the switch is only discoverable by reading this file. SECOND, what the ON state now costs. It is the HAIRLINE field indicator described below, not the 3px outline the original complaint was about. The thing being turned on is no longer the thing that was turned off. The escape hatch is the same shape it always was, one attribute, now pointing the other way: <html data-focus-outline=\"off\"> (or AppProvider's equivalent) `data-focus-outline=\"on\"` still works and still means on, so every consumer that already set it is untouched. Every painted length below multiplies by `--focus-outline`, so with the switch off the outline resolves to `0px`, the halo's spread resolves to `0px`, and `--focus-field-shadow` is `none`. The `:focus-visible` selectors themselves stay exactly where they are: only the paint goes. ── THE ON WEIGHT
|
|
585
|
+
"description": "── THE SWITCH ─────────────────────────────────────────────────────────────────────────── `--focus-outline` is ONE 0/1 flag, and every painted focus length below multiplies by it: --focus-ring-width: calc(var(--focus-ring-weight) * var(--focus-outline)) — so setting it to 0 zeroes the whole indicator at once. There is deliberately no parallel mechanism: one multiplier is the only shape in which a kill switch cannot be routed around by a per-component rebind. IT SHIPS ON, as of gh#544 — it used to ship off, and that reversal is the point of this note. The old default was a real product decision: the indicator had been reported as intrusive and the owner accepted the cost, which was that this library did not satisfy WCAG 2.2 SC 2.4.7 Focus Visible (AA) and so could carry no JIS X 8341-3:2016 AA statement. What changed is not the principle but two measurements. FIRST, what the default actually produced. Counting `data-focus-outline` across the four real consumers of this package: `ql` sets it (3 files); `godx-task`, `godx-chat` and the platform app set it NOWHERE. Three of four products shipped with no keyboard-focus indicator at all — not chosen, because the switch is only discoverable by reading this file. SECOND, what the ON state now costs. It is the HAIRLINE field indicator described below, not the 3px outline the original complaint was about. The thing being turned on is no longer the thing that was turned off. The escape hatch is the same shape it always was, one attribute, now pointing the other way: <html data-focus-outline=\"off\"> (or AppProvider's equivalent) `data-focus-outline=\"on\"` still works and still means on, so every consumer that already set it is untouched. Every painted length below multiplies by `--focus-outline`, so with the switch off the outline resolves to `0px`, the halo's spread resolves to `0px`, and `--focus-field-shadow` is `none`. The `:focus-visible` selectors themselves stay exactly where they are: only the paint goes. ── THE ON WEIGHT ────────────────────────────────────────────────────── The modern default is a 2px mark with 2px offset. Hue remains --ring for at least 3:1 contrast on supported surfaces; navigation keeps its inset. Consumers can retune the two thickness knobs or use the existing opt-out. 1 = on, 0 = off",
|
|
586
586
|
"name": "--focus-outline",
|
|
587
587
|
"tier": "foundation",
|
|
588
588
|
"value": "1"
|
|
589
589
|
},
|
|
590
590
|
{
|
|
591
|
-
"description": "
|
|
591
|
+
"description": "Foundation tokens: color, typography, raw spacing, ratio, radius, shadow.",
|
|
592
592
|
"name": "--focus-outline-weight",
|
|
593
593
|
"tier": "foundation",
|
|
594
|
-
"value": "
|
|
594
|
+
"value": "var(--stroke-md)"
|
|
595
595
|
},
|
|
596
596
|
{
|
|
597
597
|
"description": "default = var(--focus-ring-color, var(--ring)), resolved at the focused element — a `:root` binding froze on the root's --ring, so a nested tenant scope never re-tinted the outline (gh#687; docs/TOKENS.md, the freeze rule)",
|
|
@@ -609,7 +609,7 @@
|
|
|
609
609
|
"description": "Foundation tokens: color, typography, raw spacing, ratio, radius, shadow.",
|
|
610
610
|
"name": "--focus-outline-offset",
|
|
611
611
|
"tier": "foundation",
|
|
612
|
-
"value": "
|
|
612
|
+
"value": "2px"
|
|
613
613
|
},
|
|
614
614
|
{
|
|
615
615
|
"description": "FOCUS RING — the two global knobs for the keyboard-focus affordance (WCAG 2.4.7 / 2.4.11). `--focus-ring-color` is the themeable hue (HSL components, defaults to --ring) and `--focus-ring-width` the standard thickness; override either ONCE — even scoped under a `[data-tenant]` — to retint or resize EVERY focus ring. `--focus-ring-color` is declared `initial` (NOT `var(--ring)`): a :root binding to a role var would freeze at the :root --ring and a scoped [data-tenant] override of --ring alone would never reach it. Every :focus-visible rule reads it with the live-role fallback `hsl(var(--focus-ring-color, var(--ring)))`, so the default re-resolves at the element that paints the ring while an explicit override still wins. default = the live --ring role",
|
|
@@ -1203,19 +1203,19 @@
|
|
|
1203
1203
|
"description": "Motion — the primitive tier for animation, so enter/transition timing reads a token instead of a literal 0.5s / cubic-bezier(...) / translateY(10px) (cardinal rule #2). the reference design keeps motion LOW: short durations, a calm decelerate curve, a small reveal shift. Consumers honour prefers-reduced-motion at the call site.",
|
|
1204
1204
|
"name": "--duration-fast",
|
|
1205
1205
|
"tier": "foundation",
|
|
1206
|
-
"value": "
|
|
1206
|
+
"value": "120ms"
|
|
1207
1207
|
},
|
|
1208
1208
|
{
|
|
1209
1209
|
"description": "Foundation tokens: color, typography, raw spacing, ratio, radius, shadow.",
|
|
1210
1210
|
"name": "--duration-base",
|
|
1211
1211
|
"tier": "foundation",
|
|
1212
|
-
"value": "
|
|
1212
|
+
"value": "180ms"
|
|
1213
1213
|
},
|
|
1214
1214
|
{
|
|
1215
1215
|
"description": "Foundation tokens: color, typography, raw spacing, ratio, radius, shadow.",
|
|
1216
1216
|
"name": "--duration-slow",
|
|
1217
1217
|
"tier": "foundation",
|
|
1218
|
-
"value": "
|
|
1218
|
+
"value": "320ms"
|
|
1219
1219
|
},
|
|
1220
1220
|
{
|
|
1221
1221
|
"description": "Foundation tokens: color, typography, raw spacing, ratio, radius, shadow.",
|
|
@@ -1440,16 +1440,16 @@
|
|
|
1440
1440
|
"value": "var(--primary)"
|
|
1441
1441
|
},
|
|
1442
1442
|
{
|
|
1443
|
-
"description": "Semantic spacing — ONE coherent 4px grid (Tailwind/Material/Ant standard). All steps reference the linear `--space-*` scale (NOT the golden φ scale — golden ratio is for modular SIZE scales like type/radius, not the spacing grid; mixing the two left an incoherent density rhythm). The φ tokens remain available as an optional golden-layout utility, just not the spacing baseline.
|
|
1443
|
+
"description": "Semantic spacing — ONE coherent 4px grid (Tailwind/Material/Ant standard). All steps reference the linear `--space-*` scale (NOT the golden φ scale — golden ratio is for modular SIZE scales like type/radius, not the spacing grid; mixing the two left an incoherent density rhythm). The φ tokens remain available as an optional golden-layout utility, just not the spacing baseline. 32px — page gutter",
|
|
1444
1444
|
"name": "--space-page-x",
|
|
1445
1445
|
"tier": "semantic",
|
|
1446
|
-
"value": "var(--space-
|
|
1446
|
+
"value": "var(--space-8)"
|
|
1447
1447
|
},
|
|
1448
1448
|
{
|
|
1449
|
-
"description": "
|
|
1449
|
+
"description": "32px",
|
|
1450
1450
|
"name": "--space-page-y",
|
|
1451
1451
|
"tier": "semantic",
|
|
1452
|
-
"value": "var(--space-
|
|
1452
|
+
"value": "var(--space-8)"
|
|
1453
1453
|
},
|
|
1454
1454
|
{
|
|
1455
1455
|
"description": "16px",
|
|
@@ -1641,7 +1641,7 @@
|
|
|
1641
1641
|
"description": "Modal scrim — the single backdrop colour shared by EVERY overlay (Dialog, AlertDialog, Sheet, Drawer, AppShell mobile nav). Themeable (rule #44) so a service tints the wash to its brand once, e.g. a navy `--overlay-background: rgb(12 26 49 / .55)`, instead of forking each overlay. HOW IT REACHES AN OVERLAY (gh#215 — it previously reached NOTHING): each surface declares its own knob `initial` and resolves a SHARE of this colour at the call site, `var(--dialog-overlay-background, color-mix(in srgb, var(--overlay-background) var(--dialog-overlay-alpha), transparent))`. That keeps the calibrated per-surface depth — a slide-in Sheet washes the page more lightly (40%) than a modal Dialog (60%) — while ONE override here retints every backdrop. Per docs/TOKENS.md the knobs must stay `initial`: a `:root` binding would freeze and a scoped `[data-tenant]`/`.dark` override of this token would never reach the overlay. Overlays are portaled, so a tenant scope must also sit on the portal container (see docs/CUSTOMER-THEMING.md).",
|
|
1642
1642
|
"name": "--overlay-background",
|
|
1643
1643
|
"tier": "semantic",
|
|
1644
|
-
"value": "rgb(0 0 0 / 0.
|
|
1644
|
+
"value": "rgb(0 0 0 / 0.4)"
|
|
1645
1645
|
},
|
|
1646
1646
|
{
|
|
1647
1647
|
"description": "RECESSED SURFACE role (gh#399) — \"the ground a card sits on\", one step BEHIND `--card`. It is a ROLE, not a derivation: the two themes order their surfaces differently, so no single expression is correct on both. Light puts `--muted` (95%) behind `--card` (99%); dark puts it (18%) in FRONT of `--card` (12%), so the shipped `hsl(var(--muted) / 0.4)` composited to rgb(35,33,30) against a rgb(33,32,28) card — the page read 1.015:1 LIGHTER than the cards on it, i.e. the elevation inverted. No alpha fixes that: the mix runs from `--background` (correct) toward `--muted` (wrong), so anything above ~0.33 crosses the card. Each theme therefore states its own ground below. Light keeps the exact shipped composite (1.036:1 behind the card); dark takes the page `--background`, which measures 1.089:1 — matching the light theme's separation instead of inverting it.",
|
|
@@ -2415,7 +2415,7 @@
|
|
|
2415
2415
|
"description": "Gap between the header and the body, and the body's own top padding — the breathing room under a title before content begins.",
|
|
2416
2416
|
"name": "--card-space-body-y",
|
|
2417
2417
|
"tier": "component",
|
|
2418
|
-
"value": "var(--space-
|
|
2418
|
+
"value": "var(--space-6)"
|
|
2419
2419
|
},
|
|
2420
2420
|
{
|
|
2421
2421
|
"description": "Symmetric block padding for a SOLO content slot, so a composed shell can tune block and inline spacing independently without targeting CardContent. Declared `initial` for the SAME reason as --card-space-shell-y above: written as `var(--card-space-inset)` here it would freeze at the :root inset, and a card carrying [data-density=\"tight\"|\"cozy\"] (which override --card-space-inset ON THE CARD) would keep the :root value. The default now resolves at the call site through the chain solo-y → shell-y → inset, so a solo body follows the general block knob when only that is set, and an explicit solo-y still wins. default = var(--card-space-shell-y, var(--card-space-inset))",
|
|
@@ -2445,7 +2445,7 @@
|
|
|
2445
2445
|
"description": "Card component tokens: card chrome derives from semantic layout tokens.",
|
|
2446
2446
|
"name": "--card-title-font-size",
|
|
2447
2447
|
"tier": "component",
|
|
2448
|
-
"value": "var(--font-size-base)"
|
|
2448
|
+
"value": "calc(var(--font-size-base) * var(--font-size-ratio))"
|
|
2449
2449
|
},
|
|
2450
2450
|
{
|
|
2451
2451
|
"description": "Card component tokens: card chrome derives from semantic layout tokens.",
|
|
@@ -2508,10 +2508,10 @@
|
|
|
2508
2508
|
"value": "initial"
|
|
2509
2509
|
},
|
|
2510
2510
|
{
|
|
2511
|
-
"description": "
|
|
2511
|
+
"description": "Flat resting cards: the hairline defines the surface; elevation is reserved for overlays. Set --card-shadow to a shadow value for opt-in elevation, or to initial to restore the live --shadow-sm fallback at the call site (including scoped shadow ramps).",
|
|
2512
2512
|
"name": "--card-shadow",
|
|
2513
2513
|
"tier": "component",
|
|
2514
|
-
"value": "
|
|
2514
|
+
"value": "none"
|
|
2515
2515
|
},
|
|
2516
2516
|
{
|
|
2517
2517
|
"description": "Brand glow layer — invisible no-op at rest (rule #44). Paired AFTER --card-shadow in the surface box-shadow so a service can wash every card with the global glow, e.g. --card-glow: var(--shadow-glow), with no markup change.",
|
|
@@ -3147,7 +3147,7 @@
|
|
|
3147
3147
|
"description": "Control primitive tokens: heights, horizontal padding, adjacent control sizes.",
|
|
3148
3148
|
"name": "--control-height-default",
|
|
3149
3149
|
"tier": "component",
|
|
3150
|
-
"value": "var(--band-height-
|
|
3150
|
+
"value": "var(--band-height-lg)"
|
|
3151
3151
|
},
|
|
3152
3152
|
{
|
|
3153
3153
|
"description": "Control primitive tokens: heights, horizontal padding, adjacent control sizes.",
|
|
@@ -3234,10 +3234,10 @@
|
|
|
3234
3234
|
"value": "var(--radius)"
|
|
3235
3235
|
},
|
|
3236
3236
|
{
|
|
3237
|
-
"description": "
|
|
3237
|
+
"description": "Match the default 6px field corner while retaining an independent Button knob. The utility consumes a concrete value, so this remains a root alias; scoped services override --button-radius directly. Pill and sharp shapes keep their own tokens.",
|
|
3238
3238
|
"name": "--button-radius",
|
|
3239
3239
|
"tier": "component",
|
|
3240
|
-
"value": "var(--radius
|
|
3240
|
+
"value": "var(--radius)"
|
|
3241
3241
|
},
|
|
3242
3242
|
{
|
|
3243
3243
|
"description": "THE BUTTON'S OWN SURFACE — one knob per painted variant (gh#880, standard §1). Every variant painted a bare role (`hsl(var(--primary))`, `hsl(var(--background))`, `hsl(var(--secondary))`, `hsl(var(--destructive))`) with no knob of its own, so the only way to retint a button was to retint the ROLE — and `--primary` is also the link ink, the focus mark and a chart series. There was no way to say \"this button is translucent\" without saying it about eight other things. WHY BUTTONS AT ALL. namethatui's source draws the line this library needed: glassmorphism is a decorative skin for ANY surface including controls, while Apple's Liquid Glass reserves glass for the floating control layer above opaque content. A glass page with a solid primary button on it is the Liquid Glass split applied backwards. FOUR FILLS, NOT SIX. `ghost` and `link` paint no resting surface, so they have nothing to knob. The HOVER fills are deliberately not knobs either: they already resolve from roles at their own call sites (`--primary-hover`, `--accent`, `--secondary`), so a theme reaches them today — the documented consequence being that a glass RESTING fill with an untouched hover gives a button that turns opaque under the pointer, and a theme that wants glass on both moves the role too. ONE BLUR FOR THE WHOLE COMPONENT, because the material is one decision per component and the variants are one component. `initial`, so unset there is no blur and no backdrop root. default = hsl(var(--primary)) at the call site",
|
|
@@ -3309,7 +3309,7 @@
|
|
|
3309
3309
|
"description": "Control primitive tokens: heights, horizontal padding, adjacent control sizes.",
|
|
3310
3310
|
"name": "--control-shadow",
|
|
3311
3311
|
"tier": "component",
|
|
3312
|
-
"value": "
|
|
3312
|
+
"value": "none"
|
|
3313
3313
|
},
|
|
3314
3314
|
{
|
|
3315
3315
|
"description": "Control primitive tokens: heights, horizontal padding, adjacent control sizes.",
|
|
@@ -3588,10 +3588,10 @@
|
|
|
3588
3588
|
"value": "1"
|
|
3589
3589
|
},
|
|
3590
3590
|
{
|
|
3591
|
-
"description": "Mark width for a BORDERED FIELD. This knob exists because a field is the one control that already owns a boundary, so it is the one place the mark could plausibly be dropped and the recoloured border left to carry the state — which is the established treatment for a bordered field: a primary border plus a translucent halo, nothing in between. It ships at the same step as `--focus-outline-weight`, the hairline stroke, so a field and a button carry the same weight. A gate asserts the two stay equal, because this token cannot literally READ the global one without freezing at :root (docs/TOKENS.md, the freeze rule). It feeds `--focus-ring-weight`, never `--focus-ring-width`. The width is `weight × --focus-outline`, so a field's mark is still switched off with everything else — a knob that bypassed the switch would be a hole in it. If a service sets this, note the unit: the halo's spread is summed with a length in `calc()`, and CSS refuses to add a unitless number to a length — a bare `0` makes the whole box-shadow invalid at computed-value time and it resolves to NONE. Write `0px`.
|
|
3591
|
+
"description": "Mark width for a BORDERED FIELD. This knob exists because a field is the one control that already owns a boundary, so it is the one place the mark could plausibly be dropped and the recoloured border left to carry the state — which is the established treatment for a bordered field: a primary border plus a translucent halo, nothing in between. It ships at the same step as `--focus-outline-weight`, the hairline stroke, so a field and a button carry the same weight. A gate asserts the two stay equal, because this token cannot literally READ the global one without freezing at :root (docs/TOKENS.md, the freeze rule). It feeds `--focus-ring-weight`, never `--focus-ring-width`. The width is `weight × --focus-outline`, so a field's mark is still switched off with everything else — a knob that bypassed the switch would be a hole in it. If a service sets this, note the unit: the halo's spread is summed with a length in `calc()`, and CSS refuses to add a unitless number to a length — a bare `0` makes the whole box-shadow invalid at computed-value time and it resolves to NONE. Write `0px`. modern 2px mark, matching global focus",
|
|
3592
3592
|
"name": "--control-focus-ring-width",
|
|
3593
3593
|
"tier": "component",
|
|
3594
|
-
"value": "
|
|
3594
|
+
"value": "var(--stroke-md)"
|
|
3595
3595
|
},
|
|
3596
3596
|
{
|
|
3597
3597
|
"description": "Outline-form gaps — marks where a radius-hugging ring would touch the glyph.",
|
|
@@ -7032,13 +7032,13 @@
|
|
|
7032
7032
|
"value": "22.5rem"
|
|
7033
7033
|
},
|
|
7034
7034
|
{
|
|
7035
|
-
"description": "Overlay scrims — `initial` so the shared semantic --overlay-background re-resolves at the CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather than a private literal, so a service retints every backdrop with one --overlay-background while the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a modal Dialog. Defaults resolve to rgb(0 0 0 / 0.
|
|
7035
|
+
"description": "Overlay scrims — `initial` so the shared semantic --overlay-background re-resolves at the CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding to it freezes at :root and a scoped override never reaches the overlay). Each surface takes a SHARE of that one scrim rather than a private literal, so a service retints every backdrop with one --overlay-background while the calibrated per-surface depth survives: a slide-in Sheet washes the page more lightly than a modal Dialog. Defaults resolve to rgb(0 0 0 / 0.16) (sheet) and rgb(0 0 0 / 0.24) (dialog).",
|
|
7036
7036
|
"name": "--sheet-overlay-background",
|
|
7037
7037
|
"tier": "component",
|
|
7038
7038
|
"value": "initial"
|
|
7039
7039
|
},
|
|
7040
7040
|
{
|
|
7041
|
-
"description": "A SHARE OF `--overlay-background`, NOT THE RESULTING ALPHA (gh#886). The base is a finished colour that already carries `/0.
|
|
7041
|
+
"description": "A SHARE OF `--overlay-background`, NOT THE RESULTING ALPHA (gh#886). The base is a finished colour that already carries `/0.4`, so `40%` composites to **0.16**, and a theme author who sets `62%` gets 0.248. That is the library-wide convention for a `--*-alpha` knob in the `color-mix(in srgb, <base> <alpha>, transparent)` share form — 100% means \"the base as authored\", 0% means gone — and it is deliberate: the calibrated depth lives ONCE in `--overlay-background` so a service retints every scrim with one line. Want an absolute opacity instead? Set `--sheet-overlay-background` directly; it wins outright. Pinned by src/styles/__tests__/overlay-alpha-share-886.test.ts. 40% of rgb(0 0 0 / 0.4) = rgb(0 0 0 / 0.16)",
|
|
7042
7042
|
"name": "--sheet-overlay-alpha",
|
|
7043
7043
|
"tier": "component",
|
|
7044
7044
|
"value": "40%"
|
|
@@ -7170,7 +7170,7 @@
|
|
|
7170
7170
|
"value": "initial"
|
|
7171
7171
|
},
|
|
7172
7172
|
{
|
|
7173
|
-
"description": "A SHARE OF `--overlay-background`, NOT THE RESULTING ALPHA (gh#886) — the miss that was reported, because this knob carried no note of its own and `60%` reads as \"0.6\". The base is a finished colour with `/0.
|
|
7173
|
+
"description": "A SHARE OF `--overlay-background`, NOT THE RESULTING ALPHA (gh#886) — the miss that was reported, because this knob carried no note of its own and `60%` reads as \"0.6\". The base is a finished colour with `/0.4` baked in, so the product is **0.24**, and `62%` gives 0.248 rather than the darker scrim that was asked for. See `--sheet-overlay-alpha` above for the convention and for the escape hatch: `--dialog-overlay-background` is an absolute colour and wins outright. Pinned by src/styles/__tests__/overlay-alpha-share-886.test.ts. 60% of rgb(0 0 0 / 0.4) = rgb(0 0 0 / 0.24)",
|
|
7174
7174
|
"name": "--dialog-overlay-alpha",
|
|
7175
7175
|
"tier": "component",
|
|
7176
7176
|
"value": "60%"
|
|
@@ -7956,10 +7956,10 @@
|
|
|
7956
7956
|
"value": "var(--control-label-font-size, var(--text-sm))"
|
|
7957
7957
|
},
|
|
7958
7958
|
{
|
|
7959
|
-
"description": "Row rhythm between a Form's own top-level blocks (gh#295) — e.g. the field group's CardContent and its CardFooter action row, or two FormFields that happen to be Form's OWN direct children (no Card framing).
|
|
7959
|
+
"description": "Row rhythm between a Form's own top-level blocks (gh#295) — e.g. the field group's CardContent and its CardFooter action row, or two FormFields that happen to be Form's OWN direct children (no Card framing). Modern block spacing is 24px. 24px",
|
|
7960
7960
|
"name": "--form-block-gap",
|
|
7961
7961
|
"tier": "component",
|
|
7962
|
-
"value": "var(--space-
|
|
7962
|
+
"value": "var(--space-6)"
|
|
7963
7963
|
},
|
|
7964
7964
|
{
|
|
7965
7965
|
"description": "THE VALIDATION FEEDBACK GLYPH. It was `controlIconClass`, which is `size-[length:var(--control-height)]` — the height of a whole CONTROL, meant for something that fills a control-sized box like the ColorPicker swatch. On a `text-xs` feedback line that rendered a ~32px icon beside ~12px text, which is what a reader actually saw and reported. A glyph that sits inline with text belongs on the ICON scale, one step above the text it accompanies so it reads as a mark rather than a letter. 14px beside 12px text",
|
|
@@ -7968,7 +7968,7 @@
|
|
|
7968
7968
|
"value": "var(--icon-size-sm)"
|
|
7969
7969
|
},
|
|
7970
7970
|
{
|
|
7971
|
-
"description": "Field-to-field row rhythm (gh#295) — mirrors --descriptions-row-gap so a read-only value mixed in via `FormField.staticText` (gh#294) and a real Descriptions block share ONE canonical rhythm. Applied via margin-based sibling spacing on FormField itself (not Form's flex `gap`, which only reaches DIRECT children — dead in the common `Form > CardContent > FormField*` composition every real Save-button form needs), so it holds at any DOM depth relative to Form. 12px",
|
|
7971
|
+
"description": "Field-to-field row rhythm (gh#295) — mirrors --descriptions-row-gap so a read-only value mixed in via `FormField.staticText` (gh#294) and a real Descriptions block share ONE canonical rhythm. Applied via margin-based sibling spacing on FormField itself (not Form's flex `gap`, which only reaches DIRECT children — dead in the common `Form > CardContent > FormField*` composition every real Save-button form needs), so it holds at any DOM depth relative to Form. 12px — shared with Descriptions",
|
|
7972
7972
|
"name": "--form-field-row-gap",
|
|
7973
7973
|
"tier": "component",
|
|
7974
7974
|
"value": "var(--space-3)"
|
|
@@ -10722,13 +10722,13 @@
|
|
|
10722
10722
|
"value": "22.5rem"
|
|
10723
10723
|
},
|
|
10724
10724
|
{
|
|
10725
|
-
"description": "Mobile-drawer scrim — `initial` so the shared --overlay-background default re-resolves at the CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding freezes at :root). Default = var(--app-shell-mobile-nav-alpha) of the global scrim, i.e. rgb(0 0 0 / 0.
|
|
10725
|
+
"description": "Mobile-drawer scrim — `initial` so the shared --overlay-background default re-resolves at the CALL SITE under a scoped [data-tenant]/.dark theme (a :root binding freezes at :root). Default = var(--app-shell-mobile-nav-alpha) of the global scrim, i.e. rgb(0 0 0 / 0.16) out of the box.",
|
|
10726
10726
|
"name": "--app-shell-mobile-nav-background",
|
|
10727
10727
|
"tier": "component",
|
|
10728
10728
|
"value": "initial"
|
|
10729
10729
|
},
|
|
10730
10730
|
{
|
|
10731
|
-
"description": "Share of the global --overlay-background this drawer's scrim uses. A slide-in drawer washes the page more lightly than a modal dialog; keeping it a RATIO means a service retints the whole system with one --overlay-background and every overlay keeps its calibrated depth. A SHARE, not the resulting alpha (gh#886): the base already carries `/0.
|
|
10731
|
+
"description": "Share of the global --overlay-background this drawer's scrim uses. A slide-in drawer washes the page more lightly than a modal dialog; keeping it a RATIO means a service retints the whole system with one --overlay-background and every overlay keeps its calibrated depth. A SHARE, not the resulting alpha (gh#886): the base already carries `/0.4`, so the product is 0.16. 40% of rgb(0 0 0 / 0.4) = rgb(0 0 0 / 0.16)",
|
|
10732
10732
|
"name": "--app-shell-mobile-nav-alpha",
|
|
10733
10733
|
"tier": "component",
|
|
10734
10734
|
"value": "40%"
|
|
@@ -12195,7 +12195,7 @@
|
|
|
12195
12195
|
"description": "Table component tokens: row height, cell padding.",
|
|
12196
12196
|
"name": "--table-row-height-default",
|
|
12197
12197
|
"tier": "component",
|
|
12198
|
-
"value": "var(--band-height-
|
|
12198
|
+
"value": "var(--band-height-lg)"
|
|
12199
12199
|
},
|
|
12200
12200
|
{
|
|
12201
12201
|
"description": "Table component tokens: row height, cell padding.",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "AUTO-GENERATED by scripts/gen-measurement-contract.mjs — do not edit. Read this instead of guessing: docs/MEASUREMENT-CONTRACT.md.",
|
|
3
|
-
"version": "33.
|
|
3
|
+
"version": "33.10.1",
|
|
4
4
|
"targetSize": {
|
|
5
5
|
"standard": "WCAG 2.2 SC 2.5.8 Target Size (Minimum), level AA — 24×24 CSS px",
|
|
6
6
|
"min": 24,
|
package/dist/styles/layers.json
CHANGED