@signal9/era-ui 3.0.1 → 3.2.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/docs/css-utilities.d.ts +8 -2
- package/dist/docs/css-utilities.js +45 -12
- package/dist/era-ui.css +1 -1
- package/dist/generated-docs/llms-full.txt +267 -4
- package/dist/generated-docs/llms.txt +11 -0
- package/dist/generated-docs/manifest.json +171 -1
- package/dist/generated-docs/utilities.json +159 -0
- package/dist/generated-docs/utilities.md +256 -4
- package/dist/os/taskbar.svelte +10 -2
- package/dist/os/taskbar.svelte.d.ts +5 -0
- package/dist/styles/index.css +234 -1
- package/dist/ui/pane/pane-root.svelte.d.ts +1 -1
- package/dist/ui/pane/pane.svelte.d.ts +1 -1
- package/dist/ui/toggle/toggle.svelte.d.ts +1 -1
- package/dist/utils/index.js +21 -1
- package/package.json +1 -1
- package/skill/SKILL.md +75 -51
|
@@ -39,6 +39,17 @@ Classes, not components — they need no import beyond the stylesheet. Reach for
|
|
|
39
39
|
- `era-text-trim` — vertically center single-line control text (a label beside an icon, a button's own text) without a translateY nudge — fixed-height, non-editable elements only; see era-text-trim-caps for ALL-CAPS strings.
|
|
40
40
|
- `era-text-trim-caps` — the era-text-trim variant for ALL-CAPS single-line strings (kbd hints, acronym badges) — never use it for mixed-case text.
|
|
41
41
|
- `era-shimmer` — the in-progress text treatment — put it on a "working…" / "thinking…" label while a task streams, instead of a spinner beside the text.
|
|
42
|
+
- `h-xs · h-xxs · h-sm · h-md · h-lg` — the tier-height ladder — h-xs (icon) · h-xxs (nested pill) · h-sm (standalone pill) · h-md (control) · h-lg (bar); the named form of h-(--era-h-*).
|
|
43
|
+
- `min-h-xs · min-h-xxs · min-h-sm · min-h-md · min-h-lg` — minimum tier height for containers that may grow — a bar that is at least lg-tier but can wrap (min-h-lg).
|
|
44
|
+
- `size-xs · size-xxs · size-sm · size-md · size-lg` — a tier-sized square — size-xs is THE icon size (a Lucide glyph beside body text), size-md a square control face.
|
|
45
|
+
- `px-sm · px-md · px-lg` — tier-to-tier nesting padding (sp/2) — the horizontal padding of a bar or row that holds tiered controls; the named form of px-(--era-px-*).
|
|
46
|
+
- `gap-gutter · p-gutter · px-gutter · py-gutter` — the inter-element gap (sp/2) — flex/grid gap between sibling controls, and the matching gutter padding a scrollable list or rail owes its rows on all four sides (p-gutter on the rail = gap-gutter between its rows).
|
|
47
|
+
- `p-inset-xxs · p-inset-sm · p-inset-md · px-inset-xxs · px-inset-sm · px-inset-md · py-inset-xxs · py-inset-sm · py-inset-md` — text-symmetric content padding — (tier − text)/2, the inset that vertically centers body text in its tier; px-inset-md is a text button's side padding, p-inset-md a code block's.
|
|
48
|
+
- `px-pill-xxs · px-pill-sm` — pill side padding — the wider-than-vertical horizontal breathing room badge/chip text wants (glyph-advance derived, ~2× the vertical inset).
|
|
49
|
+
- `px-field` — text-field side padding — where typed text starts in an md-tier input; the named form of px-(--era-field-px).
|
|
50
|
+
- `p-panel · p-card · p-content` — optical padding for unbounded containers — p-panel for compact shells and menu-adjacent chrome, p-card for cards/dialogs/popovers, p-content for full content panels. Grows super-linearly with density so whitespace holds its perceived share as controls loosen.
|
|
51
|
+
- `p-menu` — menu-panel padding — the surface-owned inset (0 on flat, 2px on glass/bevel) that keeps row highlights inside a floating panel's frame; pairs with rounded-item on the rows.
|
|
52
|
+
- `duration-base` — the motion axis as an explicit transition-duration — for the rare case a utility (not the transition-* default) needs to name it; 0s at data-motion="instant", longer at "extra".
|
|
42
53
|
- `glass-blur` — the backdrop blur for a floating panel (popover, dialog, taskbar) — it applies only inside a data-surface="glass" subtree and is inert elsewhere, so it is safe to leave on a panel that renders under every surface.
|
|
43
54
|
|
|
44
55
|
Full reference (what each emits, when to use it): `/utilities.md`. Machine-readable list: `/utilities.json`.
|
|
@@ -93,18 +104,38 @@ The CSS classes era ships alongside the components — links, ink-centred text,
|
|
|
93
104
|
|
|
94
105
|
## Overview
|
|
95
106
|
|
|
96
|
-
era
|
|
97
|
-
|
|
98
|
-
|
|
107
|
+
era's styling API is pure class names — write `h-md rounded-md px-md shadow`,
|
|
108
|
+
never the `h-(--era-h-md)` var-class spelling. Everything below rides along
|
|
109
|
+
with the stylesheet and needs no import:
|
|
99
110
|
|
|
100
111
|
```ts
|
|
101
112
|
import "@sig-nine/era-ui/css";
|
|
102
113
|
```
|
|
103
114
|
|
|
104
115
|
```svelte
|
|
105
|
-
<
|
|
116
|
+
<button class="h-md rounded-md px-inset-md shadow text-body">era styled</button>
|
|
106
117
|
```
|
|
107
118
|
|
|
119
|
+
Alongside the `@utility` classes referenced below, era registers named theme
|
|
120
|
+
scales that OVERLOAD the stock Tailwind names, so ordinary-looking markup
|
|
121
|
+
renders on-design and responds to every axis (density, surface, corners,
|
|
122
|
+
motion):
|
|
123
|
+
|
|
124
|
+
| Stock-looking class | What it resolves to |
|
|
125
|
+
|---|---|
|
|
126
|
+
| `rounded-xs/xxs/sm/md/lg` | the concentric radius ladder (collapses on `data-corners="square"`) |
|
|
127
|
+
| `rounded-item` | menu-row radius, concentric inside a `rounded-md` panel |
|
|
128
|
+
| `shadow` / `shadow-lg` | resting control edge / floating panel chrome, per surface |
|
|
129
|
+
| `shadow-well` / `shadow-pressed` / `shadow-highlight` | recessed, pressed/latched, hover-material chrome |
|
|
130
|
+
| `bg-well` / `bg-elevated` / `bg-highlight` / `bg-overlay` | surface fills: resting, raised, transient feedback, modal scrim |
|
|
131
|
+
| `transition-*` (bare) | duration + easing default to the motion axis |
|
|
132
|
+
| `ease-base` / `duration-base` | the motion axis, named explicitly |
|
|
133
|
+
| `text-body` | density-derived body/control text size |
|
|
134
|
+
|
|
135
|
+
Deliberate gaps: `w-*`/`min-w-*` tier names would shadow Tailwind's container
|
|
136
|
+
scale (`min-w-md` stays 28rem), and the concentric-inset tokens are advanced
|
|
137
|
+
enough to stay var-form — `min-w-(--era-h-md)` etc. remain the escape hatch.
|
|
138
|
+
|
|
108
139
|
| Utility | Use it for |
|
|
109
140
|
|---|---|
|
|
110
141
|
| `era-interactive` | the focus/disabled recipe every era control carries — put it on a custom interactive element instead of hand-writing focus/disabled variants. |
|
|
@@ -113,6 +144,17 @@ import "@sig-nine/era-ui/css";
|
|
|
113
144
|
| `era-text-trim` | vertically center single-line control text (a label beside an icon, a button's own text) without a translateY nudge — fixed-height, non-editable elements only; see era-text-trim-caps for ALL-CAPS strings. |
|
|
114
145
|
| `era-text-trim-caps` | the era-text-trim variant for ALL-CAPS single-line strings (kbd hints, acronym badges) — never use it for mixed-case text. |
|
|
115
146
|
| `era-shimmer` | the in-progress text treatment — put it on a "working…" / "thinking…" label while a task streams, instead of a spinner beside the text. |
|
|
147
|
+
| `h-xs` `h-xxs` `h-sm` `h-md` `h-lg` | the tier-height ladder — h-xs (icon) · h-xxs (nested pill) · h-sm (standalone pill) · h-md (control) · h-lg (bar); the named form of h-(--era-h-*). |
|
|
148
|
+
| `min-h-xs` `min-h-xxs` `min-h-sm` `min-h-md` `min-h-lg` | minimum tier height for containers that may grow — a bar that is at least lg-tier but can wrap (min-h-lg). |
|
|
149
|
+
| `size-xs` `size-xxs` `size-sm` `size-md` `size-lg` | a tier-sized square — size-xs is THE icon size (a Lucide glyph beside body text), size-md a square control face. |
|
|
150
|
+
| `px-sm` `px-md` `px-lg` | tier-to-tier nesting padding (sp/2) — the horizontal padding of a bar or row that holds tiered controls; the named form of px-(--era-px-*). |
|
|
151
|
+
| `gap-gutter` `p-gutter` `px-gutter` `py-gutter` | the inter-element gap (sp/2) — flex/grid gap between sibling controls, and the matching gutter padding a scrollable list or rail owes its rows on all four sides (p-gutter on the rail = gap-gutter between its rows). |
|
|
152
|
+
| `p-inset-xxs` `p-inset-sm` `p-inset-md` `px-inset-xxs` `px-inset-sm` `px-inset-md` `py-inset-xxs` `py-inset-sm` `py-inset-md` | text-symmetric content padding — (tier − text)/2, the inset that vertically centers body text in its tier; px-inset-md is a text button's side padding, p-inset-md a code block's. |
|
|
153
|
+
| `px-pill-xxs` `px-pill-sm` | pill side padding — the wider-than-vertical horizontal breathing room badge/chip text wants (glyph-advance derived, ~2× the vertical inset). |
|
|
154
|
+
| `px-field` | text-field side padding — where typed text starts in an md-tier input; the named form of px-(--era-field-px). |
|
|
155
|
+
| `p-panel` `p-card` `p-content` | optical padding for unbounded containers — p-panel for compact shells and menu-adjacent chrome, p-card for cards/dialogs/popovers, p-content for full content panels. Grows super-linearly with density so whitespace holds its perceived share as controls loosen. |
|
|
156
|
+
| `p-menu` | menu-panel padding — the surface-owned inset (0 on flat, 2px on glass/bevel) that keeps row highlights inside a floating panel's frame; pairs with rounded-item on the rows. |
|
|
157
|
+
| `duration-base` | the motion axis as an explicit transition-duration — for the rare case a utility (not the transition-* default) needs to name it; 0s at data-motion="instant", longer at "extra". |
|
|
116
158
|
| `glass-blur` | the backdrop blur for a floating panel (popover, dialog, taskbar) — it applies only inside a data-surface="glass" subtree and is inert elsewhere, so it is safe to leave on a panel that renders under every surface. |
|
|
117
159
|
|
|
118
160
|
## era-interactive
|
|
@@ -275,6 +317,227 @@ Declared in `index.css`.
|
|
|
275
317
|
}
|
|
276
318
|
```
|
|
277
319
|
|
|
320
|
+
## h-xs · h-xxs · h-sm · h-md · h-lg
|
|
321
|
+
|
|
322
|
+
**Use it for:** the tier-height ladder — h-xs (icon) · h-xxs (nested pill) · h-sm (standalone pill) · h-md (control) · h-lg (bar); the named form of h-(--era-h-*).
|
|
323
|
+
|
|
324
|
+
Declared in `index.css`.
|
|
325
|
+
|
|
326
|
+
```css
|
|
327
|
+
@utility h-xs {
|
|
328
|
+
height: var(--era-h-xs);
|
|
329
|
+
}
|
|
330
|
+
@utility h-xxs {
|
|
331
|
+
height: var(--era-h-xxs);
|
|
332
|
+
}
|
|
333
|
+
@utility h-sm {
|
|
334
|
+
height: var(--era-h-sm);
|
|
335
|
+
}
|
|
336
|
+
@utility h-md {
|
|
337
|
+
height: var(--era-h-md);
|
|
338
|
+
}
|
|
339
|
+
@utility h-lg {
|
|
340
|
+
height: var(--era-h-lg);
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## min-h-xs · min-h-xxs · min-h-sm · min-h-md · min-h-lg
|
|
345
|
+
|
|
346
|
+
**Use it for:** minimum tier height for containers that may grow — a bar that is at least lg-tier but can wrap (min-h-lg).
|
|
347
|
+
|
|
348
|
+
Declared in `index.css`.
|
|
349
|
+
|
|
350
|
+
```css
|
|
351
|
+
@utility min-h-xs {
|
|
352
|
+
min-height: var(--era-h-xs);
|
|
353
|
+
}
|
|
354
|
+
@utility min-h-xxs {
|
|
355
|
+
min-height: var(--era-h-xxs);
|
|
356
|
+
}
|
|
357
|
+
@utility min-h-sm {
|
|
358
|
+
min-height: var(--era-h-sm);
|
|
359
|
+
}
|
|
360
|
+
@utility min-h-md {
|
|
361
|
+
min-height: var(--era-h-md);
|
|
362
|
+
}
|
|
363
|
+
@utility min-h-lg {
|
|
364
|
+
min-height: var(--era-h-lg);
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
## size-xs · size-xxs · size-sm · size-md · size-lg
|
|
369
|
+
|
|
370
|
+
**Use it for:** a tier-sized square — size-xs is THE icon size (a Lucide glyph beside body text), size-md a square control face.
|
|
371
|
+
|
|
372
|
+
Declared in `index.css`.
|
|
373
|
+
|
|
374
|
+
```css
|
|
375
|
+
@utility size-xs {
|
|
376
|
+
width: var(--era-h-xs);
|
|
377
|
+
height: var(--era-h-xs);
|
|
378
|
+
}
|
|
379
|
+
@utility size-xxs {
|
|
380
|
+
width: var(--era-h-xxs);
|
|
381
|
+
height: var(--era-h-xxs);
|
|
382
|
+
}
|
|
383
|
+
@utility size-sm {
|
|
384
|
+
width: var(--era-h-sm);
|
|
385
|
+
height: var(--era-h-sm);
|
|
386
|
+
}
|
|
387
|
+
@utility size-md {
|
|
388
|
+
width: var(--era-h-md);
|
|
389
|
+
height: var(--era-h-md);
|
|
390
|
+
}
|
|
391
|
+
@utility size-lg {
|
|
392
|
+
width: var(--era-h-lg);
|
|
393
|
+
height: var(--era-h-lg);
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
## px-sm · px-md · px-lg
|
|
398
|
+
|
|
399
|
+
**Use it for:** tier-to-tier nesting padding (sp/2) — the horizontal padding of a bar or row that holds tiered controls; the named form of px-(--era-px-*).
|
|
400
|
+
|
|
401
|
+
Declared in `index.css`.
|
|
402
|
+
|
|
403
|
+
```css
|
|
404
|
+
@utility px-sm {
|
|
405
|
+
padding-inline: var(--era-px-sm);
|
|
406
|
+
}
|
|
407
|
+
@utility px-md {
|
|
408
|
+
padding-inline: var(--era-px-md);
|
|
409
|
+
}
|
|
410
|
+
@utility px-lg {
|
|
411
|
+
padding-inline: var(--era-px-lg);
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## gap-gutter · p-gutter · px-gutter · py-gutter
|
|
416
|
+
|
|
417
|
+
**Use it for:** the inter-element gap (sp/2) — flex/grid gap between sibling controls, and the matching gutter padding a scrollable list or rail owes its rows on all four sides (p-gutter on the rail = gap-gutter between its rows).
|
|
418
|
+
|
|
419
|
+
Declared in `index.css`.
|
|
420
|
+
|
|
421
|
+
```css
|
|
422
|
+
@utility gap-gutter {
|
|
423
|
+
gap: var(--era-gap);
|
|
424
|
+
}
|
|
425
|
+
@utility p-gutter {
|
|
426
|
+
padding: var(--era-gap);
|
|
427
|
+
}
|
|
428
|
+
@utility px-gutter {
|
|
429
|
+
padding-inline: var(--era-gap);
|
|
430
|
+
}
|
|
431
|
+
@utility py-gutter {
|
|
432
|
+
padding-block: var(--era-gap);
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
## p-inset-xxs · p-inset-sm · p-inset-md · px-inset-xxs · px-inset-sm · px-inset-md · py-inset-xxs · py-inset-sm · py-inset-md
|
|
437
|
+
|
|
438
|
+
**Use it for:** text-symmetric content padding — (tier − text)/2, the inset that vertically centers body text in its tier; px-inset-md is a text button's side padding, p-inset-md a code block's.
|
|
439
|
+
|
|
440
|
+
Declared in `index.css`.
|
|
441
|
+
|
|
442
|
+
```css
|
|
443
|
+
@utility p-inset-xxs {
|
|
444
|
+
padding: var(--era-inset-xxs);
|
|
445
|
+
}
|
|
446
|
+
@utility p-inset-sm {
|
|
447
|
+
padding: var(--era-inset-sm);
|
|
448
|
+
}
|
|
449
|
+
@utility p-inset-md {
|
|
450
|
+
padding: var(--era-inset-md);
|
|
451
|
+
}
|
|
452
|
+
@utility px-inset-xxs {
|
|
453
|
+
padding-inline: var(--era-inset-xxs);
|
|
454
|
+
}
|
|
455
|
+
@utility px-inset-sm {
|
|
456
|
+
padding-inline: var(--era-inset-sm);
|
|
457
|
+
}
|
|
458
|
+
@utility px-inset-md {
|
|
459
|
+
padding-inline: var(--era-inset-md);
|
|
460
|
+
}
|
|
461
|
+
@utility py-inset-xxs {
|
|
462
|
+
padding-block: var(--era-inset-xxs);
|
|
463
|
+
}
|
|
464
|
+
@utility py-inset-sm {
|
|
465
|
+
padding-block: var(--era-inset-sm);
|
|
466
|
+
}
|
|
467
|
+
@utility py-inset-md {
|
|
468
|
+
padding-block: var(--era-inset-md);
|
|
469
|
+
}
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
## px-pill-xxs · px-pill-sm
|
|
473
|
+
|
|
474
|
+
**Use it for:** pill side padding — the wider-than-vertical horizontal breathing room badge/chip text wants (glyph-advance derived, ~2× the vertical inset).
|
|
475
|
+
|
|
476
|
+
Declared in `index.css`.
|
|
477
|
+
|
|
478
|
+
```css
|
|
479
|
+
@utility px-pill-xxs {
|
|
480
|
+
padding-inline: var(--era-pill-xxs);
|
|
481
|
+
}
|
|
482
|
+
@utility px-pill-sm {
|
|
483
|
+
padding-inline: var(--era-pill-sm);
|
|
484
|
+
}
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
## px-field
|
|
488
|
+
|
|
489
|
+
**Use it for:** text-field side padding — where typed text starts in an md-tier input; the named form of px-(--era-field-px).
|
|
490
|
+
|
|
491
|
+
Declared in `index.css`.
|
|
492
|
+
|
|
493
|
+
```css
|
|
494
|
+
@utility px-field {
|
|
495
|
+
padding-inline: var(--era-field-px);
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
## p-panel · p-card · p-content
|
|
500
|
+
|
|
501
|
+
**Use it for:** optical padding for unbounded containers — p-panel for compact shells and menu-adjacent chrome, p-card for cards/dialogs/popovers, p-content for full content panels. Grows super-linearly with density so whitespace holds its perceived share as controls loosen.
|
|
502
|
+
|
|
503
|
+
Declared in `index.css`.
|
|
504
|
+
|
|
505
|
+
```css
|
|
506
|
+
@utility p-panel {
|
|
507
|
+
padding: var(--era-pad-sm);
|
|
508
|
+
}
|
|
509
|
+
@utility p-card {
|
|
510
|
+
padding: var(--era-pad-md);
|
|
511
|
+
}
|
|
512
|
+
@utility p-content {
|
|
513
|
+
padding: var(--era-content-p);
|
|
514
|
+
}
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
## p-menu
|
|
518
|
+
|
|
519
|
+
**Use it for:** menu-panel padding — the surface-owned inset (0 on flat, 2px on glass/bevel) that keeps row highlights inside a floating panel's frame; pairs with rounded-item on the rows.
|
|
520
|
+
|
|
521
|
+
Declared in `index.css`.
|
|
522
|
+
|
|
523
|
+
```css
|
|
524
|
+
@utility p-menu {
|
|
525
|
+
padding: var(--era-panel-inset);
|
|
526
|
+
}
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
## duration-base
|
|
530
|
+
|
|
531
|
+
**Use it for:** the motion axis as an explicit transition-duration — for the rare case a utility (not the transition-* default) needs to name it; 0s at data-motion="instant", longer at "extra".
|
|
532
|
+
|
|
533
|
+
Declared in `index.css`.
|
|
534
|
+
|
|
535
|
+
```css
|
|
536
|
+
@utility duration-base {
|
|
537
|
+
transition-duration: var(--era-duration);
|
|
538
|
+
}
|
|
539
|
+
```
|
|
540
|
+
|
|
278
541
|
## glass-blur
|
|
279
542
|
|
|
280
543
|
**Use it for:** the backdrop blur for a floating panel (popover, dialog, taskbar) — it applies only inside a data-surface="glass" subtree and is inert elsewhere, so it is safe to leave on a panel that renders under every surface.
|
|
@@ -43,6 +43,17 @@ Classes, not components — they need no import beyond the stylesheet. Reach for
|
|
|
43
43
|
- `era-text-trim` — vertically center single-line control text (a label beside an icon, a button's own text) without a translateY nudge — fixed-height, non-editable elements only; see era-text-trim-caps for ALL-CAPS strings.
|
|
44
44
|
- `era-text-trim-caps` — the era-text-trim variant for ALL-CAPS single-line strings (kbd hints, acronym badges) — never use it for mixed-case text.
|
|
45
45
|
- `era-shimmer` — the in-progress text treatment — put it on a "working…" / "thinking…" label while a task streams, instead of a spinner beside the text.
|
|
46
|
+
- `h-xs · h-xxs · h-sm · h-md · h-lg` — the tier-height ladder — h-xs (icon) · h-xxs (nested pill) · h-sm (standalone pill) · h-md (control) · h-lg (bar); the named form of h-(--era-h-*).
|
|
47
|
+
- `min-h-xs · min-h-xxs · min-h-sm · min-h-md · min-h-lg` — minimum tier height for containers that may grow — a bar that is at least lg-tier but can wrap (min-h-lg).
|
|
48
|
+
- `size-xs · size-xxs · size-sm · size-md · size-lg` — a tier-sized square — size-xs is THE icon size (a Lucide glyph beside body text), size-md a square control face.
|
|
49
|
+
- `px-sm · px-md · px-lg` — tier-to-tier nesting padding (sp/2) — the horizontal padding of a bar or row that holds tiered controls; the named form of px-(--era-px-*).
|
|
50
|
+
- `gap-gutter · p-gutter · px-gutter · py-gutter` — the inter-element gap (sp/2) — flex/grid gap between sibling controls, and the matching gutter padding a scrollable list or rail owes its rows on all four sides (p-gutter on the rail = gap-gutter between its rows).
|
|
51
|
+
- `p-inset-xxs · p-inset-sm · p-inset-md · px-inset-xxs · px-inset-sm · px-inset-md · py-inset-xxs · py-inset-sm · py-inset-md` — text-symmetric content padding — (tier − text)/2, the inset that vertically centers body text in its tier; px-inset-md is a text button's side padding, p-inset-md a code block's.
|
|
52
|
+
- `px-pill-xxs · px-pill-sm` — pill side padding — the wider-than-vertical horizontal breathing room badge/chip text wants (glyph-advance derived, ~2× the vertical inset).
|
|
53
|
+
- `px-field` — text-field side padding — where typed text starts in an md-tier input; the named form of px-(--era-field-px).
|
|
54
|
+
- `p-panel · p-card · p-content` — optical padding for unbounded containers — p-panel for compact shells and menu-adjacent chrome, p-card for cards/dialogs/popovers, p-content for full content panels. Grows super-linearly with density so whitespace holds its perceived share as controls loosen.
|
|
55
|
+
- `p-menu` — menu-panel padding — the surface-owned inset (0 on flat, 2px on glass/bevel) that keeps row highlights inside a floating panel's frame; pairs with rounded-item on the rows.
|
|
56
|
+
- `duration-base` — the motion axis as an explicit transition-duration — for the rare case a utility (not the transition-* default) needs to name it; 0s at data-motion="instant", longer at "extra".
|
|
46
57
|
- `glass-blur` — the backdrop blur for a floating panel (popover, dialog, taskbar) — it applies only inside a data-surface="glass" subtree and is inert elsewhere, so it is safe to leave on a panel that renders under every surface.
|
|
47
58
|
|
|
48
59
|
Full reference (what each emits, when to use it): `{{ORIGIN}}/utilities.md`. Machine-readable list: `{{ORIGIN}}/utilities.json`.
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"slug": "utilities",
|
|
45
45
|
"title": "Utilities",
|
|
46
46
|
"summary": "The CSS classes era ships alongside the components — links, ink-centred text, shimmer, hidden scrollbars.",
|
|
47
|
-
"tokenEstimate":
|
|
47
|
+
"tokenEstimate": 4259,
|
|
48
48
|
"sections": [
|
|
49
49
|
"Overview",
|
|
50
50
|
"era-interactive",
|
|
@@ -53,6 +53,17 @@
|
|
|
53
53
|
"era-text-trim",
|
|
54
54
|
"era-text-trim-caps",
|
|
55
55
|
"era-shimmer",
|
|
56
|
+
"h-xs · h-xxs · h-sm · h-md · h-lg",
|
|
57
|
+
"min-h-xs · min-h-xxs · min-h-sm · min-h-md · min-h-lg",
|
|
58
|
+
"size-xs · size-xxs · size-sm · size-md · size-lg",
|
|
59
|
+
"px-sm · px-md · px-lg",
|
|
60
|
+
"gap-gutter · p-gutter · px-gutter · py-gutter",
|
|
61
|
+
"p-inset-xxs · p-inset-sm · p-inset-md · px-inset-xxs · px-inset-sm · px-inset-md · py-inset-xxs · py-inset-sm · py-inset-md",
|
|
62
|
+
"px-pill-xxs · px-pill-sm",
|
|
63
|
+
"px-field",
|
|
64
|
+
"p-panel · p-card · p-content",
|
|
65
|
+
"p-menu",
|
|
66
|
+
"duration-base",
|
|
56
67
|
"glass-blur"
|
|
57
68
|
],
|
|
58
69
|
"file": "utilities.md"
|
|
@@ -922,6 +933,9 @@
|
|
|
922
933
|
"utilities": [
|
|
923
934
|
{
|
|
924
935
|
"name": "era-interactive",
|
|
936
|
+
"names": [
|
|
937
|
+
"era-interactive"
|
|
938
|
+
],
|
|
925
939
|
"file": "index.css",
|
|
926
940
|
"useCase": "the focus/disabled recipe every era control carries — put it on a custom interactive element instead of hand-writing focus/disabled variants.",
|
|
927
941
|
"description": "Shared interactive-state recipe: quiet focus, disabled affordance.\nEquivalent to `focus:outline-none disabled:cursor-not-allowed disabled:opacity-50`.",
|
|
@@ -929,6 +943,9 @@
|
|
|
929
943
|
},
|
|
930
944
|
{
|
|
931
945
|
"name": "era-link",
|
|
946
|
+
"names": [
|
|
947
|
+
"era-link"
|
|
948
|
+
],
|
|
932
949
|
"file": "index.css",
|
|
933
950
|
"useCase": "understated, motion-aware inline text link — the canonical style for a link in body copy or prose; prefer it over a hand-rolled underline or `Button variant=\"link\"` (which is a control, not running text).",
|
|
934
951
|
"description": "Inline text link. An understated, permanent underline that darkens from\nmuted to the text colour on hover — no layout shift, no appearing/vanishing\nunderline. The colour fade rides the MOTION axis (--era-duration/-ease), so\nit snaps at data-motion=\"instant\", eases at \"normal\", and sweeps longer at\n\"extra\" — matching every other era transition. Font-agnostic: it styles\ndecoration + colour only, so it reads correctly in mono, sans, or serif, and\nthe 0.2em offset scales with the type size. Keyboard focus mirrors hover so\nthe affordance is reachable without a pointer.",
|
|
@@ -936,6 +953,9 @@
|
|
|
936
953
|
},
|
|
937
954
|
{
|
|
938
955
|
"name": "scrollbar-none",
|
|
956
|
+
"names": [
|
|
957
|
+
"scrollbar-none"
|
|
958
|
+
],
|
|
939
959
|
"file": "index.css",
|
|
940
960
|
"useCase": "hide the scrollbar on an overflowing strip or rail while keeping it scrollable — for a scroll region that should show its bar, use ScrollArea.",
|
|
941
961
|
"description": "Scrollable but chromeless — hides the scrollbar while keeping wheel / touch /\ndrag scrolling (e.g. an overflowing tab strip in a small pane handle).",
|
|
@@ -943,6 +963,9 @@
|
|
|
943
963
|
},
|
|
944
964
|
{
|
|
945
965
|
"name": "era-text-trim",
|
|
966
|
+
"names": [
|
|
967
|
+
"era-text-trim"
|
|
968
|
+
],
|
|
946
969
|
"file": "index.css",
|
|
947
970
|
"useCase": "vertically center single-line control text (a label beside an icon, a button's own text) without a translateY nudge — fixed-height, non-editable elements only; see era-text-trim-caps for ALL-CAPS strings.",
|
|
948
971
|
"description": "Font-agnostic vertical ink-centering for single-line control text.\nMeasured verdict (4 fonts x 2 dpr, ink from device-pixel screenshots):\nthe offset has TWO causes — a fractional line box (14px x 1.5lh = 21px in\na 24px row places ink on a half pixel, ~1px error) and font ascent/descent\nasymmetry (+-1px, sign flips per font). line-height: 1 fixes the first and\nis the Firefox fallback; text-box ex/alphabetic fixes the second by\ncentering the x-height band — the visual mass of MIXED-CASE text (caps and\ndescenders cancel above/below). cap alphabetic is the spec-example recipe\nbut is descender-blind (reads high; CSSWG #9148) — measured 4x worse here.\nWhere text-box is supported it fully determines the box, so the two\ndeclarations never fight. Worst-case residual: 0.44px.\n\nThe hard rules concern overflow clipping, and there are TWO of them.\n\n1. NEVER on a NATIVE EDITABLE — <input>, <textarea>, <select>. These clip to\n a UA-owned inner editor box that IS the trimmed line box, so a fixed\n height does NOT hold it open: whatever you type gets its ascenders and\n descenders sliced off (a \"d\" renders as an \"o\"). This rule used to read\n the other way round — it claimed a fixed-height <input> was the trim's\n intended home — and the Input component shipped chopped text as a result.\n A tier-height input centres its own text; it needs no trim.\n\n2. NEVER on an AUTO-height element that clips — a `truncate` child, an\n auto-height box with overflow-hidden. With no height to hold it open the\n box collapses to the x-height band (~7.5px at 14px) and the clip chops the\n glyphs into a middle stripe. Put the trim on the fixed-height ROW instead\n and let the child centre via the row's items-center.\n\nA fixed-height NON-editable element is the safe home: the ink overflows the\ntrimmed LINE box but stays inside the padding box, which is what actually\nclips. Both rules are enforced at runtime by typography/collapsed-text-trim.",
|
|
@@ -950,6 +973,9 @@
|
|
|
950
973
|
},
|
|
951
974
|
{
|
|
952
975
|
"name": "era-text-trim-caps",
|
|
976
|
+
"names": [
|
|
977
|
+
"era-text-trim-caps"
|
|
978
|
+
],
|
|
953
979
|
"file": "index.css",
|
|
954
980
|
"useCase": "the era-text-trim variant for ALL-CAPS single-line strings (kbd hints, acronym badges) — never use it for mixed-case text.",
|
|
955
981
|
"description": "ALL-CAPS single-line text (kbd hints, acronym badges): the x-height band\nmisjudges caps-only strings — cap/alphabetic edges are the right box.",
|
|
@@ -957,13 +983,157 @@
|
|
|
957
983
|
},
|
|
958
984
|
{
|
|
959
985
|
"name": "era-shimmer",
|
|
986
|
+
"names": [
|
|
987
|
+
"era-shimmer"
|
|
988
|
+
],
|
|
960
989
|
"file": "index.css",
|
|
961
990
|
"useCase": "the in-progress text treatment — put it on a \"working…\" / \"thinking…\" label while a task streams, instead of a spinner beside the text.",
|
|
962
991
|
"description": "In-progress text shimmer — a bright sweep through muted text (the standard\n\"working…\" label treatment in streaming UIs). Timing derives from the motion\naxis (10× --era-duration ≈ 1.5s at normal, 2.6s at extra); at instant the\nduration is 0s and the sweep freezes on its base frame — plain muted text —\nso reduced-motion and data-motion=\"instant\" both kill it for free.",
|
|
963
992
|
"css": "@utility era-shimmer {\n\tbackground: linear-gradient(\n\t\t110deg,\n\t\tvar(--color-muted) 0% 43%,\n\t\tvar(--color-bright) 50%,\n\t\tvar(--color-muted) 57% 100%\n\t);\n\tbackground-size: 200% 100%;\n\tbackground-clip: text;\n\t-webkit-text-fill-color: transparent;\n\tanimation: era-shimmer calc(var(--era-duration) * 10) cubic-bezier(0.7, 0, 1, 0.4) infinite;\n}"
|
|
964
993
|
},
|
|
994
|
+
{
|
|
995
|
+
"name": "h-xs",
|
|
996
|
+
"names": [
|
|
997
|
+
"h-xs",
|
|
998
|
+
"h-xxs",
|
|
999
|
+
"h-sm",
|
|
1000
|
+
"h-md",
|
|
1001
|
+
"h-lg"
|
|
1002
|
+
],
|
|
1003
|
+
"file": "index.css",
|
|
1004
|
+
"useCase": "the tier-height ladder — h-xs (icon) · h-xxs (nested pill) · h-sm (standalone pill) · h-md (control) · h-lg (bar); the named form of h-(--era-h-*).",
|
|
1005
|
+
"description": "",
|
|
1006
|
+
"css": "@utility h-xs {\n\theight: var(--era-h-xs);\n}\n@utility h-xxs {\n\theight: var(--era-h-xxs);\n}\n@utility h-sm {\n\theight: var(--era-h-sm);\n}\n@utility h-md {\n\theight: var(--era-h-md);\n}\n@utility h-lg {\n\theight: var(--era-h-lg);\n}"
|
|
1007
|
+
},
|
|
1008
|
+
{
|
|
1009
|
+
"name": "min-h-xs",
|
|
1010
|
+
"names": [
|
|
1011
|
+
"min-h-xs",
|
|
1012
|
+
"min-h-xxs",
|
|
1013
|
+
"min-h-sm",
|
|
1014
|
+
"min-h-md",
|
|
1015
|
+
"min-h-lg"
|
|
1016
|
+
],
|
|
1017
|
+
"file": "index.css",
|
|
1018
|
+
"useCase": "minimum tier height for containers that may grow — a bar that is at least lg-tier but can wrap (min-h-lg).",
|
|
1019
|
+
"description": "",
|
|
1020
|
+
"css": "@utility min-h-xs {\n\tmin-height: var(--era-h-xs);\n}\n@utility min-h-xxs {\n\tmin-height: var(--era-h-xxs);\n}\n@utility min-h-sm {\n\tmin-height: var(--era-h-sm);\n}\n@utility min-h-md {\n\tmin-height: var(--era-h-md);\n}\n@utility min-h-lg {\n\tmin-height: var(--era-h-lg);\n}"
|
|
1021
|
+
},
|
|
1022
|
+
{
|
|
1023
|
+
"name": "size-xs",
|
|
1024
|
+
"names": [
|
|
1025
|
+
"size-xs",
|
|
1026
|
+
"size-xxs",
|
|
1027
|
+
"size-sm",
|
|
1028
|
+
"size-md",
|
|
1029
|
+
"size-lg"
|
|
1030
|
+
],
|
|
1031
|
+
"file": "index.css",
|
|
1032
|
+
"useCase": "a tier-sized square — size-xs is THE icon size (a Lucide glyph beside body text), size-md a square control face.",
|
|
1033
|
+
"description": "",
|
|
1034
|
+
"css": "@utility size-xs {\n\twidth: var(--era-h-xs);\n\theight: var(--era-h-xs);\n}\n@utility size-xxs {\n\twidth: var(--era-h-xxs);\n\theight: var(--era-h-xxs);\n}\n@utility size-sm {\n\twidth: var(--era-h-sm);\n\theight: var(--era-h-sm);\n}\n@utility size-md {\n\twidth: var(--era-h-md);\n\theight: var(--era-h-md);\n}\n@utility size-lg {\n\twidth: var(--era-h-lg);\n\theight: var(--era-h-lg);\n}"
|
|
1035
|
+
},
|
|
1036
|
+
{
|
|
1037
|
+
"name": "px-sm",
|
|
1038
|
+
"names": [
|
|
1039
|
+
"px-sm",
|
|
1040
|
+
"px-md",
|
|
1041
|
+
"px-lg"
|
|
1042
|
+
],
|
|
1043
|
+
"file": "index.css",
|
|
1044
|
+
"useCase": "tier-to-tier nesting padding (sp/2) — the horizontal padding of a bar or row that holds tiered controls; the named form of px-(--era-px-*).",
|
|
1045
|
+
"description": "",
|
|
1046
|
+
"css": "@utility px-sm {\n\tpadding-inline: var(--era-px-sm);\n}\n@utility px-md {\n\tpadding-inline: var(--era-px-md);\n}\n@utility px-lg {\n\tpadding-inline: var(--era-px-lg);\n}"
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
"name": "gap-gutter",
|
|
1050
|
+
"names": [
|
|
1051
|
+
"gap-gutter",
|
|
1052
|
+
"p-gutter",
|
|
1053
|
+
"px-gutter",
|
|
1054
|
+
"py-gutter"
|
|
1055
|
+
],
|
|
1056
|
+
"file": "index.css",
|
|
1057
|
+
"useCase": "the inter-element gap (sp/2) — flex/grid gap between sibling controls, and the matching gutter padding a scrollable list or rail owes its rows on all four sides (p-gutter on the rail = gap-gutter between its rows).",
|
|
1058
|
+
"description": "",
|
|
1059
|
+
"css": "@utility gap-gutter {\n\tgap: var(--era-gap);\n}\n@utility p-gutter {\n\tpadding: var(--era-gap);\n}\n@utility px-gutter {\n\tpadding-inline: var(--era-gap);\n}\n@utility py-gutter {\n\tpadding-block: var(--era-gap);\n}"
|
|
1060
|
+
},
|
|
1061
|
+
{
|
|
1062
|
+
"name": "p-inset-xxs",
|
|
1063
|
+
"names": [
|
|
1064
|
+
"p-inset-xxs",
|
|
1065
|
+
"p-inset-sm",
|
|
1066
|
+
"p-inset-md",
|
|
1067
|
+
"px-inset-xxs",
|
|
1068
|
+
"px-inset-sm",
|
|
1069
|
+
"px-inset-md",
|
|
1070
|
+
"py-inset-xxs",
|
|
1071
|
+
"py-inset-sm",
|
|
1072
|
+
"py-inset-md"
|
|
1073
|
+
],
|
|
1074
|
+
"file": "index.css",
|
|
1075
|
+
"useCase": "text-symmetric content padding — (tier − text)/2, the inset that vertically centers body text in its tier; px-inset-md is a text button's side padding, p-inset-md a code block's.",
|
|
1076
|
+
"description": "",
|
|
1077
|
+
"css": "@utility p-inset-xxs {\n\tpadding: var(--era-inset-xxs);\n}\n@utility p-inset-sm {\n\tpadding: var(--era-inset-sm);\n}\n@utility p-inset-md {\n\tpadding: var(--era-inset-md);\n}\n@utility px-inset-xxs {\n\tpadding-inline: var(--era-inset-xxs);\n}\n@utility px-inset-sm {\n\tpadding-inline: var(--era-inset-sm);\n}\n@utility px-inset-md {\n\tpadding-inline: var(--era-inset-md);\n}\n@utility py-inset-xxs {\n\tpadding-block: var(--era-inset-xxs);\n}\n@utility py-inset-sm {\n\tpadding-block: var(--era-inset-sm);\n}\n@utility py-inset-md {\n\tpadding-block: var(--era-inset-md);\n}"
|
|
1078
|
+
},
|
|
1079
|
+
{
|
|
1080
|
+
"name": "px-pill-xxs",
|
|
1081
|
+
"names": [
|
|
1082
|
+
"px-pill-xxs",
|
|
1083
|
+
"px-pill-sm"
|
|
1084
|
+
],
|
|
1085
|
+
"file": "index.css",
|
|
1086
|
+
"useCase": "pill side padding — the wider-than-vertical horizontal breathing room badge/chip text wants (glyph-advance derived, ~2× the vertical inset).",
|
|
1087
|
+
"description": "",
|
|
1088
|
+
"css": "@utility px-pill-xxs {\n\tpadding-inline: var(--era-pill-xxs);\n}\n@utility px-pill-sm {\n\tpadding-inline: var(--era-pill-sm);\n}"
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
"name": "px-field",
|
|
1092
|
+
"names": [
|
|
1093
|
+
"px-field"
|
|
1094
|
+
],
|
|
1095
|
+
"file": "index.css",
|
|
1096
|
+
"useCase": "text-field side padding — where typed text starts in an md-tier input; the named form of px-(--era-field-px).",
|
|
1097
|
+
"description": "",
|
|
1098
|
+
"css": "@utility px-field {\n\tpadding-inline: var(--era-field-px);\n}"
|
|
1099
|
+
},
|
|
1100
|
+
{
|
|
1101
|
+
"name": "p-panel",
|
|
1102
|
+
"names": [
|
|
1103
|
+
"p-panel",
|
|
1104
|
+
"p-card",
|
|
1105
|
+
"p-content"
|
|
1106
|
+
],
|
|
1107
|
+
"file": "index.css",
|
|
1108
|
+
"useCase": "optical padding for unbounded containers — p-panel for compact shells and menu-adjacent chrome, p-card for cards/dialogs/popovers, p-content for full content panels. Grows super-linearly with density so whitespace holds its perceived share as controls loosen.",
|
|
1109
|
+
"description": "",
|
|
1110
|
+
"css": "@utility p-panel {\n\tpadding: var(--era-pad-sm);\n}\n@utility p-card {\n\tpadding: var(--era-pad-md);\n}\n@utility p-content {\n\tpadding: var(--era-content-p);\n}"
|
|
1111
|
+
},
|
|
1112
|
+
{
|
|
1113
|
+
"name": "p-menu",
|
|
1114
|
+
"names": [
|
|
1115
|
+
"p-menu"
|
|
1116
|
+
],
|
|
1117
|
+
"file": "index.css",
|
|
1118
|
+
"useCase": "menu-panel padding — the surface-owned inset (0 on flat, 2px on glass/bevel) that keeps row highlights inside a floating panel's frame; pairs with rounded-item on the rows.",
|
|
1119
|
+
"description": "",
|
|
1120
|
+
"css": "@utility p-menu {\n\tpadding: var(--era-panel-inset);\n}"
|
|
1121
|
+
},
|
|
1122
|
+
{
|
|
1123
|
+
"name": "duration-base",
|
|
1124
|
+
"names": [
|
|
1125
|
+
"duration-base"
|
|
1126
|
+
],
|
|
1127
|
+
"file": "index.css",
|
|
1128
|
+
"useCase": "the motion axis as an explicit transition-duration — for the rare case a utility (not the transition-* default) needs to name it; 0s at data-motion=\"instant\", longer at \"extra\".",
|
|
1129
|
+
"description": "",
|
|
1130
|
+
"css": "@utility duration-base {\n\ttransition-duration: var(--era-duration);\n}"
|
|
1131
|
+
},
|
|
965
1132
|
{
|
|
966
1133
|
"name": "glass-blur",
|
|
1134
|
+
"names": [
|
|
1135
|
+
"glass-blur"
|
|
1136
|
+
],
|
|
967
1137
|
"file": "surfaces/glass.css",
|
|
968
1138
|
"useCase": "the backdrop blur for a floating panel (popover, dialog, taskbar) — it applies only inside a data-surface=\"glass\" subtree and is inert elsewhere, so it is safe to leave on a panel that renders under every surface.",
|
|
969
1139
|
"description": "Tailwind v4 cannot resolve var() inside backdrop-blur-[], so the filter\nis a registered utility, gated to glass subtrees.",
|