@signal9/era-ui 20.0.0 → 22.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/CHANGELOG.md +41 -0
- package/dist/dev/audit/audits/index.d.ts +2 -1
- package/dist/dev/audit/audits/index.js +3 -1
- package/dist/dev/audit/audits/off-tier-height.js +16 -2
- package/dist/dev/audit/audits/wall-is-isotropic.d.ts +2 -0
- package/dist/dev/audit/audits/wall-is-isotropic.js +152 -0
- package/dist/era-ui.css +1 -1
- package/dist/os/taskbar.svelte +7 -1
- package/dist/styles/density.css +68 -67
- package/dist/styles/typography.css +48 -9
- package/dist/ui/bar/bar.svelte +57 -14
- package/dist/ui/bar/bar.svelte.d.ts +78 -18
- package/dist/ui/card/card.svelte +3 -0
- package/dist/ui/date-field/date-field-input.svelte +9 -0
- package/dist/ui/date-range-field/date-range-field-input.svelte +9 -0
- package/dist/ui/meter/meter.svelte +50 -2
- package/dist/ui/meter/meter.svelte.d.ts +38 -1
- package/dist/ui/time-field/time-field-input.svelte +9 -0
- package/dist/ui/time-range-field/time-range-field-input.svelte +9 -0
- package/package.json +7 -4
- package/skill/SKILL.md +12 -9
package/dist/styles/density.css
CHANGED
|
@@ -6,45 +6,43 @@
|
|
|
6
6
|
* TIER LADDER
|
|
7
7
|
* ===========
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* md = 3·sp (buttons, inputs, selects, triggers)
|
|
13
|
-
* lg = 4·sp (bars, containers)
|
|
9
|
+
* The rungs — icon, pill, chip, control, bar — are listed with their roles and
|
|
10
|
+
* per-mode values where they are declared, below. What belongs up here is why
|
|
11
|
+
* each formula has the shape it does:
|
|
14
12
|
*
|
|
15
|
-
*
|
|
16
|
-
* 4px above
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
13
|
+
* icon (sp + 6) a +6 floor so a glyph stays legible (≥14px) at every sp.
|
|
14
|
+
* pill (sp + 10) 4px above icon: enough box around body text to read as
|
|
15
|
+
* a pill, while still fitting inside a control with a
|
|
16
|
+
* visible concentric gap (≥3px at dense).
|
|
17
|
+
* chip (2·sp + 6) the generous rung — gives switch thumbs their sp/2 slot
|
|
18
|
+
* and KV rows their padded feel.
|
|
19
|
+
* control (3·sp) pure sp multiples, so button and bar heights don't
|
|
20
|
+
* bar (4·sp) inflate as the modes loosen.
|
|
21
21
|
*
|
|
22
22
|
* Concentric nesting gaps:
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
23
|
+
* chip ⊃ icon = sp/2 (4/5/6 at dense/balanced/spacious)
|
|
24
|
+
* bar ⊃ control = sp/2 (4/5/6)
|
|
25
|
+
* control ⊃ chip = (sp−6)/2 (1/2/3 — tight but present)
|
|
26
|
+
* control ⊃ pill = (2sp−10)/2 (3/5/7 — the "pill inside a button" gap)
|
|
27
|
+
* pill ⊃ icon = 2 (flat; pill is sized around text, not as a
|
|
28
|
+
* container for icon content)
|
|
29
29
|
*
|
|
30
|
-
* Invariant
|
|
31
|
-
* sp ∈ [8, 16] so this is mode-bounded.
|
|
30
|
+
* Invariant icon < pill < chip < control < bar holds for sp ≥ 7. Canonical
|
|
31
|
+
* range is sp ∈ [8, 16] so this is mode-bounded.
|
|
32
32
|
*
|
|
33
|
-
*
|
|
34
|
-
* and
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* Dense values: 14, 18, 22, 24, 32.
|
|
38
|
-
* Touch values: 22, 26, 38, 48, 64 (md ≥ 44px tap-target floor).
|
|
33
|
+
* icon IS the icon tier — there is no separate token for "a box holding one
|
|
34
|
+
* glyph", because that box and the glyph are the same size; any padding lives
|
|
35
|
+
* on the parent rung.
|
|
39
36
|
*
|
|
40
37
|
* INSETS
|
|
41
38
|
* ======
|
|
42
39
|
*
|
|
43
|
-
* --era-
|
|
44
|
-
*
|
|
45
|
-
* --era-inset-{
|
|
46
|
-
*
|
|
47
|
-
* --era-icon-inset-chip
|
|
40
|
+
* --era-gap sp/2 — inter-element gap, and the
|
|
41
|
+
* tier-to-tier nesting padding
|
|
42
|
+
* --era-inset-{pill,chip,control} (T − text)/2 — text-symmetric content padding
|
|
43
|
+
* (text is 12px at dense, 14 above)
|
|
44
|
+
* --era-icon-inset-chip (chip − icon)/2 — centring an icon-tier element
|
|
45
|
+
* = sp/2 inside a chip
|
|
48
46
|
*
|
|
49
47
|
* OPTICAL PADDING (unbounded content containers)
|
|
50
48
|
* ==============================================
|
|
@@ -56,7 +54,7 @@
|
|
|
56
54
|
* grow linearly while text barely moves (12px at dense, 14 above), so
|
|
57
55
|
* whitespace must grow SUPER-linearly
|
|
58
56
|
* to hold the same perceived balance. (The tokens that already feel right
|
|
59
|
-
* across modes — inset-
|
|
57
|
+
* across modes — inset-control 6→17, pad-content 16→48 — are exactly the convex
|
|
60
58
|
* ones; the cramped ones — card's old sp/2 = 4→8 — are the linear ones.)
|
|
61
59
|
*
|
|
62
60
|
* The optical unit is the mean of the linear and quadratic scales:
|
|
@@ -73,17 +71,17 @@
|
|
|
73
71
|
* --era-pad-card so 8 / 11.25 / 15 / 24 — cards, card sections, dialogs, popovers
|
|
74
72
|
* --era-pad-content 2·so 16 / 22.5 / 30 / 48 — full content panels (docs sections)
|
|
75
73
|
*
|
|
76
|
-
* Whitespace share rises with mode: pad-
|
|
74
|
+
* Whitespace share rises with mode: pad-card / h-control = 0.33 dense → 0.50 touch.
|
|
77
75
|
*
|
|
78
76
|
* IDENTITY USED AT NESTING SITES
|
|
79
77
|
* ==============================
|
|
80
78
|
*
|
|
81
|
-
* A flush pill at
|
|
79
|
+
* A flush pill at a control-container edge needs −(inset-pill) margin so
|
|
82
80
|
* the horizontal gap equals the vertical concentric gap. Proof:
|
|
83
|
-
* inset-
|
|
84
|
-
* = (
|
|
85
|
-
* = (
|
|
86
|
-
* = inset-
|
|
81
|
+
* inset-control − pill-inset-control
|
|
82
|
+
* = (control − text)/2 − (control − pill)/2
|
|
83
|
+
* = (pill − text)/2
|
|
84
|
+
* = inset-pill.
|
|
87
85
|
*
|
|
88
86
|
* RADII (concentric progression, sp-derived)
|
|
89
87
|
* ==========================================
|
|
@@ -146,12 +144,13 @@
|
|
|
146
144
|
--era-glyph-stroke-width: 1.75; /* Lucide SVG stroke, tuned to sit beside 14px body text */
|
|
147
145
|
|
|
148
146
|
/* Icon-button glyph sub-tiers. The glyph normally IS the icon tier (h-icon, the
|
|
149
|
-
sp+6 legibility floor) — that's what every text button's icon and every
|
|
150
|
-
icon button uses. But when the BOX collapses toward the icon tier
|
|
151
|
-
|
|
152
|
-
glyph steps below the floor by 2px per tier, preserving
|
|
153
|
-
sp+4 in
|
|
154
|
-
2·3·4·5 across icon·pill·chip·control — a unit step off the
|
|
147
|
+
sp+6 legibility floor) — that's what every text button's icon and every
|
|
148
|
+
control/chip icon button uses. But when the BOX collapses toward the icon tier
|
|
149
|
+
— a pill box, and an icon box where box == h-icon — an h-icon glyph would fill
|
|
150
|
+
it edge to edge. So the glyph steps below the floor by 2px per tier, preserving
|
|
151
|
+
a concentric gap: sp+4 in a pill box (pad 3), sp+2 in an icon box (pad 2). The
|
|
152
|
+
dense pads then run 2·3·4·5 across icon·pill·chip·control — a unit step off the
|
|
153
|
+
floor, per Button. */
|
|
155
154
|
--era-glyph-pill: calc(
|
|
156
155
|
var(--era-sp) + 0.25rem
|
|
157
156
|
); /* 12/14/16 = sp + 4 (glyph in a pill-tier button) */
|
|
@@ -211,33 +210,33 @@
|
|
|
211
210
|
--era-pill-px: max(0px, calc((var(--era-h-pill) - 0.6 * var(--era-text)) / 2)); /* 5.4/5.8/6.8 */
|
|
212
211
|
--era-chip-px: max(0px, calc((var(--era-h-chip) - 0.6 * var(--era-text)) / 2)); /* 7.4/8.8/10.8 */
|
|
213
212
|
|
|
214
|
-
/* Text-field side padding — the horizontal room where typed text starts in
|
|
215
|
-
|
|
216
|
-
Purpose-named, NOT "pill": an input is not a pill, and it lives on the
|
|
217
|
-
tier while the pill tokens are
|
|
213
|
+
/* Text-field side padding — the horizontal room where typed text starts in a
|
|
214
|
+
control-tier input (Input, Textarea, combobox/command inputs, date/time fields).
|
|
215
|
+
Purpose-named, NOT "pill": an input is not a pill, and it lives on the control
|
|
216
|
+
tier while the pill tokens are chip/pill.
|
|
218
217
|
|
|
219
|
-
It borrows
|
|
220
|
-
of text vs a single
|
|
221
|
-
algebraically sp − 1.2px, so it grows slower than the
|
|
222
|
-
proportionally TIGHTEST at dense — 6.8px in a 24px box read cramped. The
|
|
223
|
-
floor only bites at dense (
|
|
218
|
+
It borrows --era-chip-px's glyph-advance derivation (the right shape for a
|
|
219
|
+
STRING of text vs a single centred glyph) but floors it at 0.5rem. chip-px is
|
|
220
|
+
algebraically sp − 1.2px, so it grows slower than the control height (3·sp) and
|
|
221
|
+
is proportionally TIGHTEST at dense — 6.8px in a 24px box read cramped. The
|
|
222
|
+
floor only bites at dense (chip-px ≥ 8.8 at every looser mode), lifting dense
|
|
224
223
|
to 8px and leaving balanced/spacious/touch exactly as they were. */
|
|
225
224
|
--era-field-px: max(var(--era-chip-px), 0.5rem); /* 8/8.8/10.8/14.8 — floor lifts dense only */
|
|
226
225
|
|
|
227
226
|
/* Concentric insets — center a smaller tier element inside a larger one. */
|
|
228
|
-
/* --era-icon-inset-chip stays at sp/2 by construction (
|
|
229
|
-
what switch thumbs and KV icons rely on. --era-pill-inset-control is the
|
|
230
|
-
inside a button" concentric gap used both vertically (trigger padding)
|
|
227
|
+
/* --era-icon-inset-chip stays at sp/2 by construction (chip − icon = sp), which
|
|
228
|
+
is what switch thumbs and KV icons rely on. --era-pill-inset-control is the
|
|
229
|
+
"pill inside a button" concentric gap used both vertically (trigger padding)
|
|
231
230
|
and horizontally (inter-chip gap inside multi-select Value). */
|
|
232
231
|
--era-icon-inset-chip: calc((var(--era-h-chip) - var(--era-h-icon)) / 2); /* 4/5/6 = sp/2 */
|
|
233
232
|
--era-icon-inset-pill: calc(
|
|
234
233
|
(var(--era-h-pill) - var(--era-h-icon)) / 2
|
|
235
|
-
); /* 2 (flat) —
|
|
234
|
+
); /* 2 (flat) — centre an icon-tier element (dismiss button) inside a pill */
|
|
236
235
|
--era-pill-inset-control: calc(
|
|
237
236
|
(var(--era-h-control) - var(--era-h-pill)) / 2
|
|
238
237
|
); /* 3/5/7 = sp − 5 */
|
|
239
|
-
/* Centre
|
|
240
|
-
|
|
238
|
+
/* Centre a pill inside a chip — a dismiss chip in a standalone chip, a
|
|
239
|
+
pill-tier control in a chip-tier bar.
|
|
241
240
|
It reads like a duplicate of --era-inset-pill (3/3/4/6) and used to BE one:
|
|
242
241
|
while text was 14px everywhere, (h-chip − h-pill)/2 and (h-pill − text)/2 were
|
|
243
242
|
the same number, and callers borrowed the text inset rather than declaring
|
|
@@ -246,16 +245,18 @@
|
|
|
246
245
|
--era-pill-inset-chip: calc((var(--era-h-chip) - var(--era-h-pill)) / 2); /* 2/3/4/6 */
|
|
247
246
|
--era-icon-inset-control: calc(
|
|
248
247
|
(var(--era-h-control) - var(--era-h-icon)) / 2
|
|
249
|
-
); /* 5/7/9 = sp − 3 —
|
|
248
|
+
); /* 5/7/9 = sp − 3 — centre an icon control inside a control (= rd-control − rd-icon) */
|
|
250
249
|
--era-icon-inset-bar: calc(
|
|
251
250
|
(var(--era-h-bar) - var(--era-h-icon)) / 2
|
|
252
|
-
); /* 9/12/15 —
|
|
251
|
+
); /* 9/12/15 — centre an icon control inside a bar (= rd-bar − rd-icon) */
|
|
253
252
|
--era-chip-inset-control: calc(
|
|
254
253
|
(var(--era-h-control) - var(--era-h-chip)) / 2
|
|
255
|
-
); /* 1/2/3 —
|
|
254
|
+
); /* 1/2/3 — centre a chip control inside a control field (= rd-control − rd-chip),
|
|
255
|
+
e.g. the date picker's trailing trigger */
|
|
256
256
|
--era-chip-inset-bar: calc(
|
|
257
257
|
(var(--era-h-bar) - var(--era-h-chip)) / 2
|
|
258
|
-
); /* 5/7/9 = sp − 3 — inset
|
|
258
|
+
); /* 5/7/9 = sp − 3 — inset a chip panel (drag bar) concentrically in a bar-tier
|
|
259
|
+
pane (= rd-bar − rd-chip) */
|
|
259
260
|
|
|
260
261
|
/* Roundness ladder — golden base + concentric progression, both gated by scale. */
|
|
261
262
|
/* rd-T = scale · (R + (h-T − h-icon) / 2). R = sp / φ². max(0px, …) clamps tier
|
|
@@ -269,11 +270,11 @@
|
|
|
269
270
|
a center of curvature with zero arithmetic.
|
|
270
271
|
|
|
271
272
|
The one trap: a CONTAINER's radius follows its corner REGION's tier, never
|
|
272
|
-
its overall bulk. A pane capped by
|
|
273
|
-
|
|
273
|
+
its overall bulk. A pane capped by a chip-tier handle bar (icon controls at
|
|
274
|
+
icon-inset-chip) is a chip corner region → rd-chip, however large the pane.
|
|
274
275
|
Choosing rd by visual importance is how concentricity breaks. Precedents:
|
|
275
|
-
Chip (
|
|
276
|
-
panels (rd-
|
|
276
|
+
Chip (chip shell + icon dismiss), Bar (h-T ↔ rd-T), Pane.Root (rd-chip), menu
|
|
277
|
+
panels (rd-control, items at era-item-rd = rd-control − panel-inset). */
|
|
277
278
|
--era-roundness: calc(var(--era-roundness-scale) * var(--era-sp) / 2.618);
|
|
278
279
|
--era-rd-icon: max(0px, var(--era-roundness));
|
|
279
280
|
--era-rd-pill: max(
|
|
@@ -384,7 +385,7 @@
|
|
|
384
385
|
}
|
|
385
386
|
|
|
386
387
|
[data-mode='touch'] {
|
|
387
|
-
--era-sp: 1rem; /* 16px —
|
|
388
|
+
--era-sp: 1rem; /* 16px — the control tier becomes 48px, clearing the 44px tap-target floor */
|
|
388
389
|
--era-density: 2;
|
|
389
390
|
}
|
|
390
391
|
|
|
@@ -37,19 +37,58 @@
|
|
|
37
37
|
--era-font-serif: ui-serif, Georgia, 'Times New Roman', serif;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
/*
|
|
41
|
+
* THE AXIS RESOLVES BY DEPTH, WHICH IT DID NOT USED TO.
|
|
42
|
+
*
|
|
43
|
+
* These were three flat rules of the form
|
|
44
|
+
*
|
|
45
|
+
* [data-font='mono'], [data-font='mono'] * { font-family: …!important }
|
|
46
|
+
*
|
|
47
|
+
* and every one of them matched at the same specificity. So for nested axes —
|
|
48
|
+
* mono inside sans — BOTH rules matched the inner element with equal weight and
|
|
49
|
+
* the cascade fell through to SOURCE ORDER: serif beat sans beat mono, whatever
|
|
50
|
+
* the DOM said. `data-font` was not a subtree axis at all, it was a document-wide
|
|
51
|
+
* one that happened to look right whenever only one value was in play. Every
|
|
52
|
+
* other era axis (mode, surface, corners, motion) nests correctly; this one
|
|
53
|
+
* silently did not, and a consumer scoping a serif panel inside a mono app got
|
|
54
|
+
* serif everywhere or nothing, depending on nothing they could see.
|
|
55
|
+
*
|
|
56
|
+
* The split below is what fixes it, and each half is doing a different job:
|
|
57
|
+
*
|
|
58
|
+
* 1. The [data-font='…'] rules set an INHERITED pointer. Inheritance resolves
|
|
59
|
+
* by depth by definition — the nearest ancestor that declares it wins — so
|
|
60
|
+
* nesting is correct for free and no specificity fight exists.
|
|
61
|
+
*
|
|
62
|
+
* 2. The application rule stays on `*` with `!important`, because era's own
|
|
63
|
+
* token components carry Tailwind's `font-mono` utility (design rule 9:
|
|
64
|
+
* Badge, Chip, KV, CodeBlock). A utility sets font-family ON the element,
|
|
65
|
+
* which beats anything inherited, so applying the axis only to the
|
|
66
|
+
* [data-font] host would let those components ignore it. Keeping the
|
|
67
|
+
* application per-element also keeps the axis winning over a consumer's
|
|
68
|
+
* own font utilities, which is what an app-level font switch has to do.
|
|
69
|
+
*
|
|
70
|
+
* THE CONTRACT THIS IMPLIES, stated because it is not guessable: --era-font-*
|
|
71
|
+
* is read where --era-font-stack is declared, which is the [data-font] element.
|
|
72
|
+
* Re-point a stack AT or ABOVE the element that carries the axis. Setting
|
|
73
|
+
* --era-font-mono on a descendant of it does nothing — the pointer was already
|
|
74
|
+
* resolved higher up. (That is why /audit re-asserts the shipped stacks on
|
|
75
|
+
* :root rather than on its own <main>.)
|
|
76
|
+
*/
|
|
77
|
+
[data-font='mono'] {
|
|
78
|
+
--era-font-stack: var(--era-font-mono);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
[data-font='sans'] {
|
|
82
|
+
--era-font-stack: var(--era-font-sans);
|
|
43
83
|
}
|
|
44
84
|
|
|
45
|
-
[data-font='
|
|
46
|
-
|
|
47
|
-
font-family: var(--era-font-sans) !important;
|
|
85
|
+
[data-font='serif'] {
|
|
86
|
+
--era-font-stack: var(--era-font-serif);
|
|
48
87
|
}
|
|
49
88
|
|
|
50
|
-
[data-font
|
|
51
|
-
[data-font
|
|
52
|
-
font-family: var(--era-font-
|
|
89
|
+
[data-font],
|
|
90
|
+
[data-font] * {
|
|
91
|
+
font-family: var(--era-font-stack) !important;
|
|
53
92
|
}
|
|
54
93
|
|
|
55
94
|
/*
|
package/dist/ui/bar/bar.svelte
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
2
|
import { cn, tv } from '../../utils/index.js';
|
|
3
3
|
|
|
4
|
-
// A Bar is a flex container sized to a tier height, holding
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// Radius stays concentric to the height
|
|
11
|
-
// the
|
|
4
|
+
// A Bar is a flex container sized to a tier height, holding smaller controls
|
|
5
|
+
// at the even concentric gap. The height scales with density; pick the tier
|
|
6
|
+
// that fits the content:
|
|
7
|
+
// bar (default) — full toolbar / page header of controls (32/40/48/64)
|
|
8
|
+
// control — compact toolbar (24/30/36/48)
|
|
9
|
+
// chip — title / handle bar of icon buttons (22/26/30/38)
|
|
10
|
+
// Radius stays concentric to the height. The gap and the wall are NOT one
|
|
11
|
+
// number across the sizes — see the content variant below for why, and what
|
|
12
|
+
// each pairing actually resolves to.
|
|
12
13
|
export const barVariants = tv({
|
|
13
14
|
base: 'flex items-center leading-none',
|
|
14
15
|
variants: {
|
|
@@ -25,14 +26,34 @@
|
|
|
25
26
|
* had each restated the two-tier value by hand, and the geometry spec had
|
|
26
27
|
* been rewritten twice chasing which token they were restating.
|
|
27
28
|
*
|
|
28
|
-
* - `tier` (default) — one tier smaller, the pairing above.
|
|
29
|
-
*
|
|
30
|
-
* - `pill` — the compact pairing: pills and fields (a filter beside
|
|
31
|
-
*
|
|
32
|
-
* per size and comes from the compounds
|
|
29
|
+
* - `tier` (default) — one tier smaller, the pairing above. Each size gets
|
|
30
|
+
* its OWN token, from the compounds below.
|
|
31
|
+
* - `pill` — the compact pairing: pills and fields (a filter beside a
|
|
32
|
+
* pill-tier icon button, a title bar). Two tiers down, so the inset
|
|
33
|
+
* differs per size and also comes from the compounds.
|
|
34
|
+
*
|
|
35
|
+
* THIS USED TO BE ONE CLASS FOR ALL THREE SIZES — `px-icon-inset-chip`,
|
|
36
|
+
* on the stated reasoning that "chip⊃icon, control⊃chip and bar⊃control
|
|
37
|
+
* all equal sp/2". Two of those three do. control⊃chip does not:
|
|
38
|
+
*
|
|
39
|
+
* chip ⊃ icon = ((2sp+6) − (sp+6))/2 = sp/2 4/5/6
|
|
40
|
+
* bar ⊃ control = (4sp − 3sp)/2 = sp/2 4/5/6
|
|
41
|
+
* control ⊃ chip = (3sp − (2sp+6))/2 = (sp−6)/2 1/2/3 ← not sp/2
|
|
42
|
+
*
|
|
43
|
+
* chip is the one rung that is not a clean sp multiple (it carries the
|
|
44
|
+
* same +6 legibility floor as icon), so the difference cancels for the
|
|
45
|
+
* pair that spans it and survives for the pair that does not. A control
|
|
46
|
+
* bar therefore padded 4px horizontally while items-center centred its
|
|
47
|
+
* children to 1px — the wall was four times the gap it was meant to
|
|
48
|
+
* match, which is what a reader sees as "more space on the left".
|
|
49
|
+
*
|
|
50
|
+
* No audit caught it: layout/wall-matches-gap compares the horizontal
|
|
51
|
+
* wall to the horizontal gap (4 and 4 — even), and
|
|
52
|
+
* layout/even-container-padding compares top to bottom (equal). Nothing
|
|
53
|
+
* compared ACROSS the axes. layout/wall-is-isotropic now does.
|
|
33
54
|
*/
|
|
34
55
|
content: {
|
|
35
|
-
tier: '
|
|
56
|
+
tier: '',
|
|
36
57
|
pill: ''
|
|
37
58
|
},
|
|
38
59
|
/**
|
|
@@ -59,6 +80,28 @@
|
|
|
59
80
|
}
|
|
60
81
|
},
|
|
61
82
|
compoundVariants: [
|
|
83
|
+
// content="tier" — one tier down, each pairing named for itself.
|
|
84
|
+
// chip ⊃ icon = sp/2.
|
|
85
|
+
{
|
|
86
|
+
size: 'chip',
|
|
87
|
+
content: 'tier',
|
|
88
|
+
class: 'gap-icon-inset-chip px-icon-inset-chip'
|
|
89
|
+
},
|
|
90
|
+
// control ⊃ chip = (sp−6)/2 — the tight-but-present rung, 1/2/3.
|
|
91
|
+
{
|
|
92
|
+
size: 'control',
|
|
93
|
+
content: 'tier',
|
|
94
|
+
class: 'gap-chip-inset-control px-chip-inset-control'
|
|
95
|
+
},
|
|
96
|
+
// bar ⊃ control = sp/2, which is exactly --era-gap. era already calls
|
|
97
|
+
// this pairing "the gutter" (see the rounded-row derivation in
|
|
98
|
+
// styles/index.css), so it takes that name rather than borrowing
|
|
99
|
+
// icon-inset-chip's — same number, but a reader can tell why.
|
|
100
|
+
{
|
|
101
|
+
size: 'bar',
|
|
102
|
+
content: 'tier',
|
|
103
|
+
class: 'gap-gutter px-gutter'
|
|
104
|
+
},
|
|
62
105
|
// control ⊃ pill = (3sp − sp − 10)/2 — the named token.
|
|
63
106
|
{
|
|
64
107
|
size: 'control',
|
|
@@ -12,14 +12,34 @@ export declare const barVariants: import("tailwind-variants").TVReturnType<{
|
|
|
12
12
|
* had each restated the two-tier value by hand, and the geometry spec had
|
|
13
13
|
* been rewritten twice chasing which token they were restating.
|
|
14
14
|
*
|
|
15
|
-
* - `tier` (default) — one tier smaller, the pairing above.
|
|
16
|
-
*
|
|
17
|
-
* - `pill` — the compact pairing: pills and fields (a filter beside
|
|
18
|
-
*
|
|
19
|
-
* per size and comes from the compounds
|
|
15
|
+
* - `tier` (default) — one tier smaller, the pairing above. Each size gets
|
|
16
|
+
* its OWN token, from the compounds below.
|
|
17
|
+
* - `pill` — the compact pairing: pills and fields (a filter beside a
|
|
18
|
+
* pill-tier icon button, a title bar). Two tiers down, so the inset
|
|
19
|
+
* differs per size and also comes from the compounds.
|
|
20
|
+
*
|
|
21
|
+
* THIS USED TO BE ONE CLASS FOR ALL THREE SIZES — `px-icon-inset-chip`,
|
|
22
|
+
* on the stated reasoning that "chip⊃icon, control⊃chip and bar⊃control
|
|
23
|
+
* all equal sp/2". Two of those three do. control⊃chip does not:
|
|
24
|
+
*
|
|
25
|
+
* chip ⊃ icon = ((2sp+6) − (sp+6))/2 = sp/2 4/5/6
|
|
26
|
+
* bar ⊃ control = (4sp − 3sp)/2 = sp/2 4/5/6
|
|
27
|
+
* control ⊃ chip = (3sp − (2sp+6))/2 = (sp−6)/2 1/2/3 ← not sp/2
|
|
28
|
+
*
|
|
29
|
+
* chip is the one rung that is not a clean sp multiple (it carries the
|
|
30
|
+
* same +6 legibility floor as icon), so the difference cancels for the
|
|
31
|
+
* pair that spans it and survives for the pair that does not. A control
|
|
32
|
+
* bar therefore padded 4px horizontally while items-center centred its
|
|
33
|
+
* children to 1px — the wall was four times the gap it was meant to
|
|
34
|
+
* match, which is what a reader sees as "more space on the left".
|
|
35
|
+
*
|
|
36
|
+
* No audit caught it: layout/wall-matches-gap compares the horizontal
|
|
37
|
+
* wall to the horizontal gap (4 and 4 — even), and
|
|
38
|
+
* layout/even-container-padding compares top to bottom (equal). Nothing
|
|
39
|
+
* compared ACROSS the axes. layout/wall-is-isotropic now does.
|
|
20
40
|
*/
|
|
21
41
|
content: {
|
|
22
|
-
tier: "
|
|
42
|
+
tier: "";
|
|
23
43
|
pill: "";
|
|
24
44
|
};
|
|
25
45
|
/**
|
|
@@ -58,14 +78,34 @@ export declare const barVariants: import("tailwind-variants").TVReturnType<{
|
|
|
58
78
|
* had each restated the two-tier value by hand, and the geometry spec had
|
|
59
79
|
* been rewritten twice chasing which token they were restating.
|
|
60
80
|
*
|
|
61
|
-
* - `tier` (default) — one tier smaller, the pairing above.
|
|
62
|
-
*
|
|
63
|
-
* - `pill` — the compact pairing: pills and fields (a filter beside
|
|
64
|
-
*
|
|
65
|
-
* per size and comes from the compounds
|
|
81
|
+
* - `tier` (default) — one tier smaller, the pairing above. Each size gets
|
|
82
|
+
* its OWN token, from the compounds below.
|
|
83
|
+
* - `pill` — the compact pairing: pills and fields (a filter beside a
|
|
84
|
+
* pill-tier icon button, a title bar). Two tiers down, so the inset
|
|
85
|
+
* differs per size and also comes from the compounds.
|
|
86
|
+
*
|
|
87
|
+
* THIS USED TO BE ONE CLASS FOR ALL THREE SIZES — `px-icon-inset-chip`,
|
|
88
|
+
* on the stated reasoning that "chip⊃icon, control⊃chip and bar⊃control
|
|
89
|
+
* all equal sp/2". Two of those three do. control⊃chip does not:
|
|
90
|
+
*
|
|
91
|
+
* chip ⊃ icon = ((2sp+6) − (sp+6))/2 = sp/2 4/5/6
|
|
92
|
+
* bar ⊃ control = (4sp − 3sp)/2 = sp/2 4/5/6
|
|
93
|
+
* control ⊃ chip = (3sp − (2sp+6))/2 = (sp−6)/2 1/2/3 ← not sp/2
|
|
94
|
+
*
|
|
95
|
+
* chip is the one rung that is not a clean sp multiple (it carries the
|
|
96
|
+
* same +6 legibility floor as icon), so the difference cancels for the
|
|
97
|
+
* pair that spans it and survives for the pair that does not. A control
|
|
98
|
+
* bar therefore padded 4px horizontally while items-center centred its
|
|
99
|
+
* children to 1px — the wall was four times the gap it was meant to
|
|
100
|
+
* match, which is what a reader sees as "more space on the left".
|
|
101
|
+
*
|
|
102
|
+
* No audit caught it: layout/wall-matches-gap compares the horizontal
|
|
103
|
+
* wall to the horizontal gap (4 and 4 — even), and
|
|
104
|
+
* layout/even-container-padding compares top to bottom (equal). Nothing
|
|
105
|
+
* compared ACROSS the axes. layout/wall-is-isotropic now does.
|
|
66
106
|
*/
|
|
67
107
|
content: {
|
|
68
|
-
tier: "
|
|
108
|
+
tier: "";
|
|
69
109
|
pill: "";
|
|
70
110
|
};
|
|
71
111
|
/**
|
|
@@ -104,14 +144,34 @@ export declare const barVariants: import("tailwind-variants").TVReturnType<{
|
|
|
104
144
|
* had each restated the two-tier value by hand, and the geometry spec had
|
|
105
145
|
* been rewritten twice chasing which token they were restating.
|
|
106
146
|
*
|
|
107
|
-
* - `tier` (default) — one tier smaller, the pairing above.
|
|
108
|
-
*
|
|
109
|
-
* - `pill` — the compact pairing: pills and fields (a filter beside
|
|
110
|
-
*
|
|
111
|
-
* per size and comes from the compounds
|
|
147
|
+
* - `tier` (default) — one tier smaller, the pairing above. Each size gets
|
|
148
|
+
* its OWN token, from the compounds below.
|
|
149
|
+
* - `pill` — the compact pairing: pills and fields (a filter beside a
|
|
150
|
+
* pill-tier icon button, a title bar). Two tiers down, so the inset
|
|
151
|
+
* differs per size and also comes from the compounds.
|
|
152
|
+
*
|
|
153
|
+
* THIS USED TO BE ONE CLASS FOR ALL THREE SIZES — `px-icon-inset-chip`,
|
|
154
|
+
* on the stated reasoning that "chip⊃icon, control⊃chip and bar⊃control
|
|
155
|
+
* all equal sp/2". Two of those three do. control⊃chip does not:
|
|
156
|
+
*
|
|
157
|
+
* chip ⊃ icon = ((2sp+6) − (sp+6))/2 = sp/2 4/5/6
|
|
158
|
+
* bar ⊃ control = (4sp − 3sp)/2 = sp/2 4/5/6
|
|
159
|
+
* control ⊃ chip = (3sp − (2sp+6))/2 = (sp−6)/2 1/2/3 ← not sp/2
|
|
160
|
+
*
|
|
161
|
+
* chip is the one rung that is not a clean sp multiple (it carries the
|
|
162
|
+
* same +6 legibility floor as icon), so the difference cancels for the
|
|
163
|
+
* pair that spans it and survives for the pair that does not. A control
|
|
164
|
+
* bar therefore padded 4px horizontally while items-center centred its
|
|
165
|
+
* children to 1px — the wall was four times the gap it was meant to
|
|
166
|
+
* match, which is what a reader sees as "more space on the left".
|
|
167
|
+
*
|
|
168
|
+
* No audit caught it: layout/wall-matches-gap compares the horizontal
|
|
169
|
+
* wall to the horizontal gap (4 and 4 — even), and
|
|
170
|
+
* layout/even-container-padding compares top to bottom (equal). Nothing
|
|
171
|
+
* compared ACROSS the axes. layout/wall-is-isotropic now does.
|
|
112
172
|
*/
|
|
113
173
|
content: {
|
|
114
|
-
tier: "
|
|
174
|
+
tier: "";
|
|
115
175
|
pill: "";
|
|
116
176
|
};
|
|
117
177
|
/**
|
package/dist/ui/card/card.svelte
CHANGED
|
@@ -144,6 +144,7 @@
|
|
|
144
144
|
aria-disabled={disabled || undefined}
|
|
145
145
|
tabindex={disabled ? -1 : undefined}
|
|
146
146
|
onclick={disabled ? (e) => e.preventDefault() : onclick}
|
|
147
|
+
data-era-unbounded
|
|
147
148
|
class={cn(cardVariants({ tone, sectioned, interactive: true }), className)}
|
|
148
149
|
{...restProps}
|
|
149
150
|
>
|
|
@@ -163,6 +164,7 @@
|
|
|
163
164
|
{name}
|
|
164
165
|
{value}
|
|
165
166
|
{onclick}
|
|
167
|
+
data-era-unbounded
|
|
166
168
|
class={cn(cardVariants({ tone, sectioned, interactive: true }), className)}
|
|
167
169
|
{...restProps}
|
|
168
170
|
>
|
|
@@ -171,6 +173,7 @@
|
|
|
171
173
|
{:else}
|
|
172
174
|
<div
|
|
173
175
|
bind:this={ref as HTMLDivElement}
|
|
176
|
+
data-era-unbounded
|
|
174
177
|
class={cn(cardVariants({ tone, sectioned }), className)}
|
|
175
178
|
{...restProps}
|
|
176
179
|
>
|
|
@@ -6,8 +6,17 @@
|
|
|
6
6
|
let { ref = $bindable(null), class: className, ...restProps }: DateField.InputProps = $props();
|
|
7
7
|
</script>
|
|
8
8
|
|
|
9
|
+
<!-- A TEXT FIELD'S SIDE PADDING IS DELIBERATELY NOT ITS CONCENTRIC INSET.
|
|
10
|
+
--era-field-px is the room where typed text STARTS — purpose-named in
|
|
11
|
+
density.css and floored at 0.5rem because the derived 6.8px read cramped at
|
|
12
|
+
dense — while the segment boxes inside are chip-tier and centre 1px from the
|
|
13
|
+
top. So this row is 8px at the sides against 1px above and below, on
|
|
14
|
+
purpose, and it says so rather than being quietly skipped by
|
|
15
|
+
layout/wall-is-isotropic's heuristics: a claim a reviewer can check beats a
|
|
16
|
+
silence. -->
|
|
9
17
|
<DateField.Input
|
|
10
18
|
bind:ref
|
|
19
|
+
data-era-anisotropic
|
|
11
20
|
data-input-field
|
|
12
21
|
class={cn(
|
|
13
22
|
inputVariants(),
|
|
@@ -10,8 +10,17 @@
|
|
|
10
10
|
}: DateRangeField.InputProps = $props();
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
|
+
<!-- A TEXT FIELD'S SIDE PADDING IS DELIBERATELY NOT ITS CONCENTRIC INSET.
|
|
14
|
+
--era-field-px is the room where typed text STARTS — purpose-named in
|
|
15
|
+
density.css and floored at 0.5rem because the derived 6.8px read cramped at
|
|
16
|
+
dense — while the segment boxes inside are chip-tier and centre 1px from the
|
|
17
|
+
top. So this row is 8px at the sides against 1px above and below, on
|
|
18
|
+
purpose, and it says so rather than being quietly skipped by
|
|
19
|
+
layout/wall-is-isotropic's heuristics: a claim a reviewer can check beats a
|
|
20
|
+
silence. -->
|
|
13
21
|
<DateRangeField.Input
|
|
14
22
|
bind:ref
|
|
23
|
+
data-era-anisotropic
|
|
15
24
|
data-input-field
|
|
16
25
|
class={cn(
|
|
17
26
|
inputVariants(),
|