@dillingerstaffing/strand-ui 0.2.1 → 0.2.3

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.
Files changed (2) hide show
  1. package/HTML_REFERENCE.md +58 -69
  2. package/package.json +2 -2
package/HTML_REFERENCE.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Strand HTML Reference
2
2
 
3
- CSS class API for using Strand UI components as raw HTML. Use this when building without the Preact/React library, for static sites, documentation pages, or server-rendered HTML.
3
+ CSS class API for Strand UI components. For design constraints, token roles, interaction patterns, and principles, read [DESIGN_LANGUAGE.md](./DESIGN_LANGUAGE.md).
4
+
5
+ > **Before writing any Strand HTML**, read [DESIGN_LANGUAGE.md Part II: Named Principles (L57-L193)](./DESIGN_LANGUAGE.md#L57). These 10 principles are hard constraints, not guidelines. Violating them produces valid HTML that looks wrong.
4
6
 
5
7
  ## Required CSS
6
8
 
@@ -9,6 +11,8 @@ CSS class API for using Strand UI components as raw HTML. Use this when building
9
11
  <link rel="stylesheet" href="path/to/@dillingerstaffing/strand-ui/dist/css/strand-ui.css">
10
12
  ```
11
13
 
14
+ > **Token roles:** Don't guess which token to use. See [DESIGN_LANGUAGE.md 3.8: Color Roles (L290-L311)](./DESIGN_LANGUAGE.md#L290) for which color in which context, and [Appendix B: Token Quick Reference (L1372-L1431)](./DESIGN_LANGUAGE.md#L1372) for the full lookup table.
15
+
12
16
  ## Presentation Mode
13
17
 
14
18
  Wrap static previews in `.strand-static` to render at full visual fidelity without interaction:
@@ -25,7 +29,7 @@ The `disabled` attribute prevents interaction. `.strand-static` overrides the di
25
29
 
26
30
  ## Recessed Viewport
27
31
 
28
- Use `.strand-viewport` for component previews and showcase containers. It creates a recessed instrument panel effect (sits below the card surface):
32
+ Use `.strand-viewport` for component previews and showcase containers:
29
33
 
30
34
  ```html
31
35
  <div class="strand-viewport strand-static">
@@ -33,40 +37,33 @@ Use `.strand-viewport` for component previews and showcase containers. It create
33
37
  </div>
34
38
  ```
35
39
 
36
- Provides: `--strand-surface-recessed` background, inset shadow, `--strand-radius-lg` corners, `--strand-space-6` padding.
40
+ > **Why recessed?** See [DESIGN_LANGUAGE.md 7.3: The Recessed Viewport (L710-L725)](./DESIGN_LANGUAGE.md#L710) and [7.2: Container Elevation Contexts (L698-L708)](./DESIGN_LANGUAGE.md#L698).
37
41
 
38
42
  ## Padding Tiers
39
43
 
44
+ > Tier values, usage guidance, and the 30% validation test: [DESIGN_LANGUAGE.md 5.2: Component Padding Tiers (L434-L444)](./DESIGN_LANGUAGE.md#L434). Spacing hierarchy rule (gap > padding): [5.3: Spacing Hierarchy (L446-L456)](./DESIGN_LANGUAGE.md#L446).
45
+
40
46
  Card padding tiers (used via `strand-card--pad-{sm|md|lg}`):
41
- - `sm`: 16px (compact widgets, dense UIs)
42
- - `md`: 24px (standard cards, default for most contexts)
43
- - `lg`: 40px (showcase, hero, documentation)
47
+ - `sm`: 16px -- `md`: 24px -- `lg`: 40px
44
48
 
45
49
  ## Focus States
46
50
 
47
- All interactive elements include `:focus-visible` styling per Part XII of the design language:
48
-
49
- ```css
50
- :focus-visible {
51
- outline: 2px solid var(--strand-blue-primary);
52
- outline-offset: 2px;
53
- }
54
- ```
55
-
56
- - Appears on keyboard navigation only (not on mouse click)
57
- - 2px solid blue outline with 2px offset from the element edge
58
- - Applied to: buttons, links, interactive cards, tab buttons, sort buttons, nav links, hamburger menu
51
+ > Full specification: [DESIGN_LANGUAGE.md 14.3: Focus Indicators (L1145-L1151)](./DESIGN_LANGUAGE.md#L1145). Always `:focus-visible`, never all `:focus`.
59
52
 
60
53
  No additional classes needed. Focus rings are built into each component's CSS.
61
54
 
62
55
  ## Boundary Integrity
63
56
 
64
- All container components (Grid, Stack, Card, Container) enforce boundary integrity. Children cannot visually breach the parent's padding zone. This is enforced at the CSS level via `overflow: hidden`, `max-width: 100%`, and `min-width: 0` on children. You do not need to add these yourself.
57
+ > Full specification: [DESIGN_LANGUAGE.md 10.4: Boundary Integrity (L865-L871)](./DESIGN_LANGUAGE.md#L865). Composability depth rule: [10.5: Composability Constraint (L873-L877)](./DESIGN_LANGUAGE.md#L873).
58
+
59
+ All container components (Grid, Stack, Card, Container) enforce boundary integrity via `overflow: hidden`, `max-width: 100%`, and `min-width: 0` on children. You do not need to add these yourself.
65
60
 
66
61
  ---
67
62
 
68
63
  ## Input Components
69
64
 
65
+ > **Interaction states for all inputs** (hover, focus, pressed, disabled, loading): [DESIGN_LANGUAGE.md Part XII: Interaction State System (L1013-L1067)](./DESIGN_LANGUAGE.md#L1013).
66
+
70
67
  ### Button
71
68
 
72
69
  ```html
@@ -81,6 +78,8 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
81
78
  **Loading:** Add class `strand-btn--loading` + `<span class="strand-btn__spinner" aria-hidden="true"></span>` before content. Set content span `style="visibility:hidden"`.
82
79
  **Disabled:** Add `disabled` attribute. Use `.strand-static` parent to show full opacity.
83
80
 
81
+ > **Blue Discipline:** Only `--primary` buttons use blue. Non-interactive blue is a violation. See [DESIGN_LANGUAGE.md Principle 4 (L102-L112)](./DESIGN_LANGUAGE.md#L102).
82
+
84
83
  ---
85
84
 
86
85
  ### Input
@@ -127,8 +126,6 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
127
126
  ```
128
127
 
129
128
  **States:** `strand-select--error` | `strand-select--disabled`
130
- **Error:** Add `strand-select--error` to wrapper and `aria-invalid="true"` to the select.
131
- **Disabled:** Add `strand-select--disabled` to wrapper and `disabled` to the select.
132
129
  **Note:** The `strand-select__arrow` span renders the dropdown caret via CSS borders. Always include it.
133
130
 
134
131
  ---
@@ -167,7 +164,6 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
167
164
  ```
168
165
 
169
166
  **States:** `strand-radio--checked` | `strand-radio--disabled`
170
- **Unchecked:** Omit `strand-radio--checked`. The dot is hidden via `transform: scale(0)` in CSS.
171
167
  **Note:** The native input is visually hidden. The dot scales up when `strand-radio--checked` is present. Group radios with the same `name` attribute.
172
168
 
173
169
  ---
@@ -185,7 +181,6 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
185
181
 
186
182
  **States:** `strand-switch--checked` | `strand-switch--disabled`
187
183
  **Off:** Omit `strand-switch--checked`. Set `aria-checked="false"`.
188
- **Disabled:** Add `strand-switch--disabled` to the label and `disabled` to the button.
189
184
  **Note:** The track is a `<button>` with `role="switch"`. The thumb translates right when checked via CSS.
190
185
 
191
186
  ---
@@ -200,7 +195,6 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
200
195
  ```
201
196
 
202
197
  **States:** `strand-slider--disabled`
203
- **Disabled:** Add `strand-slider--disabled` to wrapper and `disabled` to the input.
204
198
  **Note:** Thumb styling uses both `-webkit-slider-thumb` and `-moz-range-thumb` pseudo-elements in the CSS.
205
199
 
206
200
  ---
@@ -226,7 +220,9 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
226
220
  **States:** `strand-form-field--error`
227
221
  **Error:** Replace `strand-form-field__hint` with `<p class="strand-form-field__error" id="email-error" role="alert">Invalid email address.</p>` and add `strand-form-field--error` to the wrapper.
228
222
  **Required indicator:** Include `<span class="strand-form-field__required" aria-hidden="true">*</span>` inside the label.
229
- **Note:** The `for` attribute on the label must match the `id` on the input control.
223
+ **Note:** The `for` attribute on the label must match the `id` on the input control. FormField wraps ANY input component (Input, Select, Textarea, Checkbox, Radio, Switch, Slider).
224
+
225
+ > **Label typography:** Labels render as monospace uppercase with ultra tracking. This is the laboratory specimen label pattern. See [DESIGN_LANGUAGE.md 11.1: Form Instruments (L877-L916)](./DESIGN_LANGUAGE.md#L877).
230
226
 
231
227
  ---
232
228
 
@@ -244,6 +240,8 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
244
240
  **Padding:** `strand-card--pad-none` | `strand-card--pad-sm` | `strand-card--pad-md` | `strand-card--pad-lg`
245
241
  **Note:** `strand-card--interactive` adds hover lift and cursor pointer. Use for clickable cards.
246
242
 
243
+ > **Elevation:** Cards at rest use Level 1 shadow. On hover, Level 2. See [DESIGN_LANGUAGE.md Principle 5: Earned Elevation (L114-L125)](./DESIGN_LANGUAGE.md#L114) and [7.2: Container Elevation Contexts (L698-L708)](./DESIGN_LANGUAGE.md#L698).
244
+
247
245
  ---
248
246
 
249
247
  ### Badge
@@ -270,6 +268,8 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
270
268
  **Colors:** `strand-badge--default` | `strand-badge--teal` | `strand-badge--blue` | `strand-badge--amber` | `strand-badge--red`
271
269
  **Note:** When wrapping children, omit `strand-badge--inline`. The indicator auto-positions to top-right via `position: absolute`.
272
270
 
271
+ > **Semantic colors only in data contexts.** Badge colors encode status, not decoration. See [DESIGN_LANGUAGE.md 3.7: Usage Rules (L281-L288)](./DESIGN_LANGUAGE.md#L281).
272
+
273
273
  ---
274
274
 
275
275
  ### Avatar
@@ -318,8 +318,6 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
318
318
  </span>
319
319
  ```
320
320
 
321
- **Note:** Color classes combine with variant classes (e.g., `strand-tag--solid strand-tag--blue`). The remove icon SVG is required.
322
-
323
321
  ---
324
322
 
325
323
  ### Table
@@ -340,11 +338,6 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
340
338
  <td class="strand-table__td">Engineer</td>
341
339
  <td class="strand-table__td">Active</td>
342
340
  </tr>
343
- <tr class="strand-table__row">
344
- <td class="strand-table__td">Bob</td>
345
- <td class="strand-table__td">Designer</td>
346
- <td class="strand-table__td">Away</td>
347
- </tr>
348
341
  </tbody>
349
342
  </table>
350
343
  </div>
@@ -361,7 +354,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
361
354
  ```
362
355
 
363
356
  **Sort indicators:** `&#8593;` (ascending) | `&#8595;` (descending) | `&#8597;` (unsorted)
364
- **Note:** `strand-table-wrapper` provides horizontal scroll on overflow. Rows highlight on hover.
357
+ **Note:** `strand-table-wrapper` provides horizontal scroll on overflow. Rows highlight on hover to `--strand-blue-glow`.
365
358
 
366
359
  ---
367
360
 
@@ -387,16 +380,20 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
387
380
  </div>
388
381
  ```
389
382
 
390
- **Sizes:** `--sm` (text-xl, 25px) | default (text-3xl, 39px) | `--lg` (text-4xl, 49px). Label stays xs across all sizes. Use `--sm` in compact cards and dense data views. Use `--lg` for hero and landing page metrics.
383
+ **Sizes:** `--sm` (text-xl, 25px) | default (text-3xl, 39px) | `--lg` (text-4xl, 49px). Label stays xs across all sizes.
384
+
385
+ > **The DataReadout pattern** is uniquely Strand: monospace overline + large light-weight value + tabular numerals. See [DESIGN_LANGUAGE.md 11.2: Data Display (L918-L955)](./DESIGN_LANGUAGE.md#L918).
391
386
 
392
387
  ---
393
388
 
394
389
  ## Layout Components
395
390
 
391
+ > **Spacing rules:** 4px base unit, padding tiers, and the gap > padding hierarchy: [DESIGN_LANGUAGE.md Part V: Spacing (L410-L496)](./DESIGN_LANGUAGE.md#L410). Responsive breakpoints and container system: [Part X: Layout (L829-L877)](./DESIGN_LANGUAGE.md#L829).
392
+
396
393
  ### Stack
397
394
 
398
395
  ```html
399
- <div class="strand-stack strand-stack--vertical" style="gap: var(--strand-space-4);">
396
+ <div class="strand-stack strand-stack--vertical strand-stack--gap-4">
400
397
  <div>Item 1</div>
401
398
  <div>Item 2</div>
402
399
  <div>Item 3</div>
@@ -405,10 +402,9 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
405
402
 
406
403
  **Direction:** `strand-stack--vertical` | `strand-stack--horizontal`
407
404
  **Gap (utility classes):** `strand-stack--gap-1` | `strand-stack--gap-2` | `strand-stack--gap-3` | `strand-stack--gap-4` | `strand-stack--gap-5` | `strand-stack--gap-6` | `strand-stack--gap-8`
408
- **Alignment:** `strand-stack--align-start` | `strand-stack--align-center` | `strand-stack--align-end` (default is stretch)
405
+ **Alignment:** `strand-stack--align-start` | `strand-stack--align-center` | `strand-stack--align-end`
409
406
  **Justification:** `strand-stack--justify-start` | `strand-stack--justify-center` | `strand-stack--justify-end` | `strand-stack--justify-between` | `strand-stack--justify-around`
410
407
  **Wrap:** `strand-stack--wrap`
411
- **Note:** Use either the gap utility class (`strand-stack--gap-4`) or inline `style="gap: var(--strand-space-4)"`. The React component uses inline style; utility classes are available for pure HTML.
412
408
 
413
409
  ---
414
410
 
@@ -422,9 +418,11 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
422
418
  </div>
423
419
  ```
424
420
 
425
- **Columns (utility classes):** `strand-grid--cols-2` | `strand-grid--cols-3` | `strand-grid--cols-4`
426
- **Gap (utility classes):** `strand-grid--gap-1` | `strand-grid--gap-2` | `strand-grid--gap-3` | `strand-grid--gap-4` | `strand-grid--gap-5` | `strand-grid--gap-6` | `strand-grid--gap-8`
427
- **Note:** For column counts beyond 4, use inline style: `style="grid-template-columns: repeat(6, 1fr); gap: var(--strand-space-4);"`. The React component always uses inline style.
421
+ **Columns:** `strand-grid--cols-2` | `strand-grid--cols-3` | `strand-grid--cols-4`
422
+ **Gap:** `strand-grid--gap-1` through `strand-grid--gap-8`
423
+ **Note:** For column counts beyond 4, use inline style: `style="grid-template-columns: repeat(6, 1fr); gap: var(--strand-space-4);"`.
424
+
425
+ > **Composability:** Before nesting grids inside cards inside previews, check content width. See [DESIGN_LANGUAGE.md 10.5: Composability Constraint (L873-L877)](./DESIGN_LANGUAGE.md#L873).
428
426
 
429
427
  ---
430
428
 
@@ -436,8 +434,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
436
434
  </div>
437
435
  ```
438
436
 
439
- **Sizes:** `strand-container--narrow` | `strand-container--default` | `strand-container--wide` | `strand-container--full`
440
- **Note:** Centers content with `margin-inline: auto` and responsive horizontal padding via `clamp(1.5rem, 5vw, 4rem)`.
437
+ **Sizes:** `strand-container--narrow` (640px) | `strand-container--default` (768px) | `strand-container--wide` (1024px) | `strand-container--full` (1280px)
441
438
 
442
439
  ---
443
440
 
@@ -465,8 +462,6 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
465
462
  <div class="strand-divider strand-divider--vertical" role="separator" aria-orientation="vertical"></div>
466
463
  ```
467
464
 
468
- **Note:** Plain horizontal uses `<hr>`. Labeled horizontal uses `<div>` with two `__line` spans flanking the label. Vertical dividers use `align-self: stretch` to fill the parent height.
469
-
470
465
  ---
471
466
 
472
467
  ### Section
@@ -481,7 +476,8 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
481
476
 
482
477
  **Variants:** `strand-section--standard` | `strand-section--hero`
483
478
  **Backgrounds:** `strand-section--bg-primary` | `strand-section--bg-elevated` | `strand-section--bg-recessed`
484
- **Note:** `standard` uses responsive vertical padding `clamp(4rem, 8vw, 8rem)`. `hero` uses `clamp(6rem, 12vw, 12rem)`. Pair with `strand-container` inside for horizontal constraints.
479
+
480
+ > **Section rhythm** and responsive padding values: [DESIGN_LANGUAGE.md 5.4: Section Rhythm (L458-L466)](./DESIGN_LANGUAGE.md#L458). Background and surface choices: [Part IX: Surfaces and Backgrounds (L749-L826)](./DESIGN_LANGUAGE.md#L749).
485
481
 
486
482
  ---
487
483
 
@@ -494,7 +490,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
494
490
  ```
495
491
 
496
492
  **External:** Add `target="_blank"` and `rel="noopener noreferrer"`.
497
- **Note:** The underline animates on hover from 0% to 100% width via `background-size`. No variant or modifier classes.
493
+ **Note:** The underline animates on hover from 0% to 100% width via `background-size`.
498
494
 
499
495
  ---
500
496
 
@@ -525,7 +521,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
525
521
 
526
522
  **Active tab:** Add `strand-tabs__tab--active` + `aria-selected="true"` + `tabindex="0"`.
527
523
  **Inactive tabs:** Set `aria-selected="false"` + `tabindex="-1"`. Add `hidden` to their panels.
528
- **Note:** The tablist has a bottom border. Active tab shows a blue bottom border. Wire `aria-controls` / `aria-labelledby` IDs correctly. Arrow key navigation requires JavaScript.
524
+ **Note:** Wire `aria-controls` / `aria-labelledby` IDs correctly. Arrow key navigation requires JavaScript.
529
525
 
530
526
  ---
531
527
 
@@ -549,7 +545,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
549
545
  </nav>
550
546
  ```
551
547
 
552
- **Note:** The last item uses `strand-breadcrumb__current` with `aria-current="page"` instead of a link. Separators use `aria-hidden="true"`. The first item has no separator.
548
+ **Note:** Last item uses `strand-breadcrumb__current` with `aria-current="page"`. Separators use `aria-hidden="true"`. First item has no separator.
553
549
 
554
550
  ---
555
551
 
@@ -559,7 +555,6 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
559
555
  <nav class="strand-nav" aria-label="Main navigation">
560
556
  <div class="strand-nav__inner">
561
557
  <div class="strand-nav__logo">
562
- <!-- Logo element (image, SVG, or text) -->
563
558
  <strong>Brand</strong>
564
559
  </div>
565
560
  <div class="strand-nav__items">
@@ -568,7 +563,6 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
568
563
  <a href="/contact" class="strand-nav__link">Contact</a>
569
564
  </div>
570
565
  <div class="strand-nav__actions">
571
- <!-- Action buttons or elements -->
572
566
  <button class="strand-btn strand-btn--primary strand-btn--sm" type="button">
573
567
  <span class="strand-btn__content">Sign in</span>
574
568
  </button>
@@ -577,7 +571,6 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
577
571
  <span class="strand-nav__hamburger-icon" aria-hidden="true"></span>
578
572
  </button>
579
573
  </div>
580
- <!-- Mobile menu (hidden by default, shown via JS toggling display) -->
581
574
  <div class="strand-nav__mobile-menu" style="display:none;">
582
575
  <a href="/" class="strand-nav__mobile-link strand-nav__mobile-link--active" aria-current="page">Home</a>
583
576
  <a href="/about" class="strand-nav__mobile-link">About</a>
@@ -587,7 +580,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
587
580
  ```
588
581
 
589
582
  **Active link:** `strand-nav__link--active` (desktop) | `strand-nav__mobile-link--active` (mobile)
590
- **Note:** The nav bar is 64px tall. Desktop items and actions hide below 768px; the hamburger and mobile menu show instead. The hamburger icon is a CSS-only three-line icon (middle line + `::before`/`::after` pseudo-elements). Toggle mobile menu visibility with JavaScript.
583
+ **Note:** Nav is 64px tall. Desktop items hide below 768px; hamburger and mobile menu show instead. Toggle mobile menu visibility with JavaScript.
591
584
 
592
585
  ---
593
586
 
@@ -603,7 +596,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
603
596
  ```
604
597
 
605
598
  **Statuses:** `strand-toast--info` | `strand-toast--success` | `strand-toast--warning` | `strand-toast--error`
606
- **Toast container (for stacking multiple toasts):**
599
+ **Toast container (for stacking):**
607
600
 
608
601
  ```html
609
602
  <div class="strand-toast__container">
@@ -611,7 +604,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
611
604
  </div>
612
605
  ```
613
606
 
614
- **Note:** Container is fixed to bottom-right (`position: fixed`). Use `aria-live="assertive"` for `warning` and `error` statuses. Each status sets a colored left border accent. Dismiss button renders `&times;`.
607
+ **Note:** Container is fixed to bottom-right. Use `aria-live="assertive"` for `warning` and `error`.
615
608
 
616
609
  ---
617
610
 
@@ -624,16 +617,8 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
624
617
  ```
625
618
 
626
619
  **Statuses:** `strand-alert--info` | `strand-alert--success` | `strand-alert--warning` | `strand-alert--error`
627
- **Dismissible:** Add a dismiss button after content:
628
-
629
- ```html
630
- <div class="strand-alert strand-alert--warning" role="alert">
631
- <div class="strand-alert__content">Disk space running low.</div>
632
- <button type="button" class="strand-alert__dismiss" aria-label="Dismiss">&times;</button>
633
- </div>
634
- ```
635
-
636
- **Note:** Use `role="alert"` for `warning` and `error`, `role="status"` for `info` and `success`. Each status has a colored left border and tinted background.
620
+ **Dismissible:** Add `<button type="button" class="strand-alert__dismiss" aria-label="Dismiss">&times;</button>` after content.
621
+ **Note:** Use `role="alert"` for `warning` and `error`, `role="status"` for `info` and `success`.
637
622
 
638
623
  ---
639
624
 
@@ -653,7 +638,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
653
638
  </div>
654
639
  ```
655
640
 
656
- **Note:** The backdrop covers the viewport with a semi-transparent overlay (`position: fixed; inset: 0`). The panel is centered, max-width 560px, with elevation shadow. Focus trap and scroll lock require JavaScript. Omit the `strand-dialog__header` div if no title is needed.
641
+ **Note:** Backdrop covers the viewport. Panel is centered, max-width 560px. Focus trap and scroll lock require JavaScript.
657
642
 
658
643
  ---
659
644
 
@@ -670,7 +655,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
670
655
 
671
656
  **Positions:** `strand-tooltip--top` | `strand-tooltip--right` | `strand-tooltip--bottom` | `strand-tooltip--left`
672
657
  **Visibility:** Add `strand-tooltip--visible` to show. Without it, tooltip has `opacity: 0`.
673
- **Note:** The wrapper needs `position: relative` (provided by `strand-tooltip__wrapper`). For static display, add `strand-tooltip--visible` directly. For interactive use, toggle that class via JavaScript on hover/focus. Wire `aria-describedby` on the wrapper to the tooltip `id`.
658
+ **Note:** Wire `aria-describedby` on the wrapper to the tooltip `id`. For interactive use, toggle `strand-tooltip--visible` via JavaScript on hover/focus.
674
659
 
675
660
  ---
676
661
 
@@ -711,7 +696,9 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
711
696
 
712
697
  **Sizes (bar):** `strand-progress--sm` (4px) | `strand-progress--md` (8px) | `strand-progress--lg` (12px)
713
698
  **Sizes (ring):** `strand-progress--sm` (24px) | `strand-progress--md` (40px) | `strand-progress--lg` (56px)
714
- **Note:** For indeterminate bars, omit `aria-valuenow`; the fill animates via CSS. For rings, compute `stroke-dasharray` as `2 * PI * radius` and `stroke-dashoffset` as `dasharray * (1 - value/100)`. Ring dimensions by size: sm=24 (r=10.5), md=40 (r=18.5), lg=56 (r=26.5). Stroke width is always 3.
699
+ **Note:** For rings, compute `stroke-dasharray` as `2 * PI * radius` and `stroke-dashoffset` as `dasharray * (1 - value/100)`. Ring dimensions by size: sm=24 (r=10.5), md=40 (r=18.5), lg=56 (r=26.5). Stroke width is always 3.
700
+
701
+ > **Loading state patterns:** [DESIGN_LANGUAGE.md 6.6: Loading States (L624-L654)](./DESIGN_LANGUAGE.md#L624).
715
702
 
716
703
  ---
717
704
 
@@ -725,7 +712,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
725
712
  ```
726
713
 
727
714
  **Sizes:** `strand-spinner--sm` (16px) | `strand-spinner--md` (20px) | `strand-spinner--lg` (32px)
728
- **Note:** The ring animates a spinning border. `strand-spinner__sr-only` provides accessible text (visually hidden, read by screen readers). Always include it.
715
+ **Note:** `strand-spinner__sr-only` provides accessible text (visually hidden). Always include it.
729
716
 
730
717
  ---
731
718
 
@@ -736,7 +723,7 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
736
723
  style="width: 100%; height: 1em;"></div>
737
724
  ```
738
725
 
739
- **Variants:** `strand-skeleton--text` (4px border-radius, 1em default height) | `strand-skeleton--rectangle` (md border-radius) | `strand-skeleton--circle` (full border-radius)
726
+ **Variants:** `strand-skeleton--text` (4px radius) | `strand-skeleton--rectangle` (md radius) | `strand-skeleton--circle` (full radius)
740
727
  **Shimmer:** Always add `strand-skeleton--shimmer` for the animated gradient effect.
741
728
  **Sizing:** Set `width` and `height` via inline `style`. For circles, set equal width and height.
742
729
 
@@ -751,3 +738,5 @@ All container components (Grid, Stack, Card, Container) enforce boundary integri
751
738
  ```
752
739
 
753
740
  **Note:** Always include `aria-hidden="true"`. Skeletons are placeholder visuals, not interactive.
741
+
742
+ > **Animation:** Shimmer is 1.8s cycle. All animations respect `prefers-reduced-motion`. See [DESIGN_LANGUAGE.md 6.7: Reduced Motion (L656-L669)](./DESIGN_LANGUAGE.md#L656).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dillingerstaffing/strand-ui",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Strand UI - Preact/React component library built on the Strand Design Language",
5
5
  "author": "Dillinger Staffing <engineering@dillingerstaffing.com> (https://dillingerstaffing.com)",
6
6
  "license": "MIT",
@@ -49,7 +49,7 @@
49
49
  }
50
50
  },
51
51
  "dependencies": {
52
- "@dillingerstaffing/strand": "workspace:*"
52
+ "@dillingerstaffing/strand": "^0.2.1"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@testing-library/preact": "^3.2.0",