actual-css 0.9.2 → 0.11.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.
Files changed (136) hide show
  1. package/CHANGELOG.md +169 -1
  2. package/README.md +65 -44
  3. package/components.json +35 -14
  4. package/dist/actual.full.css +877 -583
  5. package/dist/actual.full.js +1 -1
  6. package/dist/actual.full.min.css +1 -1
  7. package/docs/design-notes/app-ui.md +1 -1
  8. package/docs/design-notes/column-layout.md +103 -520
  9. package/docs/design-notes/enhancement-contract.md +16 -7
  10. package/docs/design-notes/forced-colors.md +12 -1
  11. package/docs/design-notes/naming.md +1 -1
  12. package/docs/design-notes/platform-alignment.md +8 -4
  13. package/docs/design-notes/rich-text.md +61 -0
  14. package/docs/design-notes/steps.md +2 -2
  15. package/docs/design-notes/surface-reparenting.md +8 -9
  16. package/docs/navigation.json +4 -0
  17. package/docs/pages/components/accordion.md +55 -1
  18. package/docs/pages/components/alert.md +9 -15
  19. package/docs/pages/components/aura.md +12 -13
  20. package/docs/pages/components/badge.md +16 -7
  21. package/docs/pages/components/bleed.md +42 -0
  22. package/docs/pages/components/button.md +30 -4
  23. package/docs/pages/components/card.md +21 -86
  24. package/docs/pages/components/chat.md +5 -0
  25. package/docs/pages/components/close.md +48 -0
  26. package/docs/pages/components/data-list.md +26 -1
  27. package/docs/pages/components/dialog.md +21 -18
  28. package/docs/pages/components/drawer.md +9 -9
  29. package/docs/pages/components/navbar.md +5 -5
  30. package/docs/pages/components/pagination.md +15 -15
  31. package/docs/pages/components/shimmer.md +57 -0
  32. package/docs/pages/components/skeleton.md +2 -1
  33. package/docs/pages/components/spinner.md +14 -9
  34. package/docs/pages/components/table.md +13 -0
  35. package/docs/pages/enhancements/flyout.md +2 -0
  36. package/docs/pages/enhancements/overview.md +5 -0
  37. package/docs/pages/enhancements/tabs.md +4 -0
  38. package/docs/pages/enhancements/tooltip.md +3 -1
  39. package/docs/pages/examples/overview.md +2 -1
  40. package/docs/pages/forms/choice-cards.md +116 -4
  41. package/docs/pages/forms/combobox.md +39 -12
  42. package/docs/pages/forms/joined-controls.md +2 -5
  43. package/docs/pages/forms/overview.md +10 -1
  44. package/docs/pages/forms/range.md +110 -5
  45. package/docs/pages/forms/rich-text.md +110 -0
  46. package/docs/pages/forms/validation.md +5 -1
  47. package/docs/pages/foundations/theming.md +110 -18
  48. package/docs/pages/foundations/tokens.md +41 -13
  49. package/docs/pages/guides/bootstrap.md +2 -1
  50. package/docs/pages/guides/introduction.md +15 -23
  51. package/docs/pages/guides/modular-import.md +54 -7
  52. package/docs/pages/guides/progressive-enhancement.md +19 -17
  53. package/docs/pages/guides/tailwind.md +21 -7
  54. package/docs/pages/layout/column-layout.md +92 -54
  55. package/docs/pages/layout/media.md +1 -1
  56. package/docs/pages/layout/overview.md +1 -1
  57. package/docs/pages/utilities/overview.md +1 -1
  58. package/docs/pages/utilities/sizing-wrapping.md +5 -3
  59. package/llms.txt +25 -4
  60. package/package.json +10 -6
  61. package/reserved-classes.json +6 -30
  62. package/skills/actual-css/PROJECT.md.example +65 -0
  63. package/skills/actual-css/README.md +64 -0
  64. package/skills/actual-css/SKILL.md +234 -0
  65. package/skills/actual-css/references/accessibility.md +44 -0
  66. package/skills/actual-css/references/api-and-vocabulary.md +94 -0
  67. package/skills/actual-css/references/enhancements.md +59 -0
  68. package/skills/actual-css/references/forms.md +49 -0
  69. package/skills/actual-css/references/layout-and-theming.md +82 -0
  70. package/skills/actual-css/references/review-checklist.md +51 -0
  71. package/skills/actual-css/scripts/inspect-actual-css.mjs +171 -0
  72. package/src/css/components/accordion.css +44 -7
  73. package/src/css/components/alert.css +23 -43
  74. package/src/css/components/app-nav.css +9 -0
  75. package/src/css/components/avatar.css +1 -1
  76. package/src/css/components/badge.css +11 -39
  77. package/src/css/components/bleed.css +79 -0
  78. package/src/css/components/button.css +6 -17
  79. package/src/css/components/card.css +7 -40
  80. package/src/css/components/close.css +91 -0
  81. package/src/css/components/data-list.css +18 -0
  82. package/src/css/components/drawer.css +15 -56
  83. package/src/css/components/fab.css +10 -0
  84. package/src/css/components/flyout.css +5 -1
  85. package/src/css/components/index.css +2 -0
  86. package/src/css/components/join.css +36 -20
  87. package/src/css/components/menu.css +12 -0
  88. package/src/css/components/meter.css +1 -1
  89. package/src/css/components/modal.css +10 -57
  90. package/src/css/components/navbar.css +27 -0
  91. package/src/css/components/pagination.css +3 -2
  92. package/src/css/components/rating.css +1 -1
  93. package/src/css/components/status-bar.css +2 -2
  94. package/src/css/components/steps.css +3 -3
  95. package/src/css/components/tab.css +3 -3
  96. package/src/css/components/table.css +6 -0
  97. package/src/css/components/tooltip.css +1 -1
  98. package/src/css/core/focus.css +19 -3
  99. package/src/css/core/theme.css +33 -43
  100. package/src/css/core/tokens.css +9 -5
  101. package/src/css/core/variants.css +5 -34
  102. package/src/css/effects/aura.css +51 -33
  103. package/src/css/effects/index.css +1 -0
  104. package/src/css/effects/shimmer.css +57 -0
  105. package/src/css/forms/choice-card.css +142 -24
  106. package/src/css/forms/choice.css +2 -3
  107. package/src/css/forms/control.css +17 -10
  108. package/src/css/forms/custom-select.css +4 -4
  109. package/src/css/forms/native.css +4 -4
  110. package/src/css/forms/otp.css +9 -1
  111. package/src/css/forms/range.css +72 -14
  112. package/src/css/forms/switch.css +2 -3
  113. package/src/css/layout/app-layout.css +1 -1
  114. package/src/css/layout/column-layout.css +26 -111
  115. package/src/css/utilities/extra.css +7 -6
  116. package/src/js/command.js +61 -32
  117. package/src/js/dialog.js +103 -47
  118. package/src/js/dismiss.js +1 -2
  119. package/src/js/enhance.js +91 -126
  120. package/src/js/escape.js +1 -0
  121. package/src/js/flyout.js +10 -1
  122. package/src/js/focus-group.js +2 -1
  123. package/src/js/full.js +1 -0
  124. package/src/js/keys.js +14 -0
  125. package/src/js/menu.js +2 -1
  126. package/src/js/password.js +1 -8
  127. package/src/js/range.js +151 -0
  128. package/src/js/scrollspy.js +4 -5
  129. package/src/js/status.js +21 -10
  130. package/src/js/surface.js +12 -8
  131. package/src/js/tab.js +2 -1
  132. package/src/js/tooltip.js +29 -2
  133. package/src/js/validation.js +8 -15
  134. package/dist/actual.css +0 -876
  135. package/dist/actual.js +0 -1
  136. package/dist/actual.min.css +0 -1
@@ -1,24 +1,20 @@
1
1
  # Card
2
2
 
3
- Flexible content container with optional header, body, and footer regions, plus full-bleed children.
3
+ Flexible content container with optional header, body, and footer regions.
4
4
 
5
5
  ## Class reference
6
6
 
7
- | Class | Kind | Description |
8
- | ----------- | ---------------- | ----------------------------------------------- |
9
- | `.card` | Component | Neutral raised surface for grouped content. |
10
- | `.raised` | Variant | Elevated surface with a soft shadow. |
11
- | `.subtle` | Variant | Lower contrast against the page surface. |
12
- | `.surface` | Variant | The page surface; intent in the text only. |
13
- | `.inverted` | Surface modifier | Inverse surface treatment. |
14
- | `.compact` | Density | Tighter padding and compact descendant context. |
7
+ | Class | Kind | Description |
8
+ | ---------- | --------- | ----------------------------------------------- |
9
+ | `.card` | Component | Neutral raised surface for grouped content. |
10
+ | `.raised` | Variant | Elevated surface with a soft shadow. |
11
+ | `.subtle` | Variant | Lower contrast against the page surface. |
12
+ | `.surface` | Variant | The page surface; intent in the text only. |
13
+ | `.compact` | Density | Tighter padding and compact descendant context. |
15
14
 
16
15
  `.surface` is a shared variant: it paints the page surface instead of
17
- `--surface-raised` and leaves the intent to the text.
18
-
19
- `.inverted` paints `--surface-solid` and swaps the foreground to `--surface`,
20
- so it inverts in dark themes instead of always reading as dark. Write it as
21
- `class="card inverted"`, or on any block.
16
+ `--surface-raised` and leaves the intent to the text. For a dark card on a
17
+ light page (or the reverse), put `data-theme="dark"` on the card.
22
18
 
23
19
  ## Basic usage
24
20
 
@@ -59,52 +55,8 @@ gap.
59
55
 
60
56
  ## Bleed
61
57
 
62
- Use `.bleed` on a direct child to escape the card padding — full-width images,
63
- colored headers, or footers.
64
-
65
- ```html demo
66
- <div style="max-inline-size: 32rem">
67
- <article class="card stack">
68
- <img class="bleed" src="https://picsum.photos/seed/actual-css-card/600/300" alt="Coastal cliffs at dusk" />
69
- <header>
70
- <h3>Coastal cliffs at dusk</h3>
71
- </header>
72
- <section class="stack" aria-label="Summary">
73
- <p>A short caption that wraps across a few lines. The image bleeds to the card edges.</p>
74
- </section>
75
- <footer>
76
- <span class="badge primary soft">Photo</span>
77
- <button type="button" class="btn outline">View</button>
78
- </footer>
79
- </article>
80
- </div>
81
- ```
82
-
83
- ```html demo
84
- <article class="card stack" style="--card-max-inline-size: 24rem">
85
- <header class="bleed stack items-center text-center" style="background: var(--surface-subtle)">
86
- <hgroup>
87
- <h3>Team</h3>
88
- <p class="muted">For growing products</p>
89
- </hgroup>
90
- <p>
91
- <span style="font-size: 2rem; font-weight: var(--font-weight-semibold); line-height: 1">$24</span>
92
- <span class="muted">/ user / month</span>
93
- </p>
94
- </header>
95
-
96
- <ul class="stack items-center" style="list-style: none; padding: 0">
97
- <li>Unlimited projects</li>
98
- <li>Up to 25 seats</li>
99
- <li>Shared workspaces</li>
100
- <li>Priority support</li>
101
- </ul>
102
-
103
- <footer class="bleed" style="background: var(--surface-subtle); justify-content: center">
104
- <a class="btn primary" href="#">Upgrade</a>
105
- </footer>
106
- </article>
107
- ```
58
+ Use `.bleed` on a direct child to bring an image or band to the card edge. See
59
+ [Bleed](bleed.md) for the shared surface contract and its modular import.
108
60
 
109
61
  ## In grids
110
62
 
@@ -148,27 +100,10 @@ all footers in the row line up regardless of body length.
148
100
 
149
101
  ## Surfaces
150
102
 
151
- `.inverted` creates a contrasting surface context, not a complete theme island.
152
- On a bare block (`<header class="inverted">`, `<section class="inverted">`) it
153
- paints the surface directly; contextual content and transparent treatments such
154
- as `.btn.outline`, `.btn.ghost`, and `.btn.link` follow its foreground.
155
-
156
- Apply it directly to a component that consumes the shared `--ui-*` surface
157
- contract (`.card`, `.navbar`, `.alert`, `.badge`) to treat that component as the
158
- contrasting surface. A surface-owning component nested inside an inverted block
159
- keeps its own surface and establishes a new context for its descendants. Use a
160
- `data-theme` island when every component and form control in a subtree must use
161
- another theme.
162
-
163
- More specific component states or explicit surface variants still take
164
- precedence: `.card.inverted.subtle` keeps the `.subtle` background while the
165
- foreground stays inverted.
166
-
167
- `.inverted` and `.subtle` are competing surface treatments — do not combine
168
- them. `.subtle` paints the card's background directly while `.inverted` swaps
169
- the surface tokens, so `.card.subtle.inverted` renders a subtle background with
170
- inverted foreground. Treat them as mutually exclusive, like two competing
171
- variants.
103
+ A card is a surface-owning component: inside a painted band it keeps its own
104
+ surface and resets the context for its content. A card with
105
+ `data-theme="dark"` is a complete dark island — its fields, intents and states
106
+ all follow.
172
107
 
173
108
  `.surface` is the shared variant on a card: it drops the card to the page
174
109
  surface instead of `--surface-raised`, keeps the theme border, and lets an
@@ -198,12 +133,12 @@ treatments on either side of it.
198
133
  </hgroup>
199
134
  </article>
200
135
 
201
- <article class="card inverted stack">
136
+ <article class="card stack" data-theme="dark">
202
137
  <hgroup>
203
- <h3>Inverted</h3>
204
- <p>Inverse surface for emphasis. Text inherits the contrasting surface color.</p>
138
+ <h3>Dark island</h3>
139
+ <p class="muted">A complete dark theme on one card.</p>
205
140
  </hgroup>
206
- <button type="button" class="btn">Action</button>
141
+ <button type="button" class="btn primary outline">Action</button>
207
142
  </article>
208
143
 
209
144
  <article class="card compact">
@@ -219,5 +154,5 @@ treatments on either side of it.
219
154
 
220
155
  - `--card-radius` — corner radius.
221
156
  - `--card-max-inline-size` — maximum width.
222
- - `--card-pad` — inner padding; also drives the negative offsets that let a `.bleed` child reach the card edge. `.compact` lowers it.
157
+ - `--card-pad` — inner padding, relayed to direct children for `.bleed`. `.compact` lowers it.
223
158
  - `--card-gap` — space between direct children of a bare card. A composed layout primitive owns its own gap instead.
@@ -34,6 +34,11 @@ For a live conversation, put an appropriate live-region or `role="log"` on the
34
34
  conversation container according to the product's announcement needs. Do not
35
35
  put `role="log"` on individual messages.
36
36
 
37
+ For the message input itself, keep a native `<textarea>` inside a surface with
38
+ an actions row — see the [composer template](../../demo/templates/composer.html).
39
+ Formatting needs a hosted editor instead — see the
40
+ [rich-text template](../../demo/templates/rich-text.html).
41
+
37
42
  ## Class reference
38
43
 
39
44
  | Class | Description |
@@ -0,0 +1,48 @@
1
+ # Close
2
+
3
+ > Icon-only X button that closes a dialog, dismisses an alert, or removes a tag.
4
+
5
+ **Related terms:** close button, dismiss button, remove button, clear, X.
6
+
7
+ - Use an empty `<button class="close" aria-label="…">`: it paints its own X from `--icon-close`, so it needs no icon font and no text glyph.
8
+ - `.close` is always the X. A button with another pictogram is a `.btn.icon-only`.
9
+ - The class names the look, not the mechanism. Close with the container's own action: `command="request-close"` or `method="dialog"` in a dialog, `command="--dismiss"` on an alert, application logic on a tag.
10
+ - The container sets the size and place: the top inline-end corner of a `.modal` or a `.drawer`, the last column of an `.alert`, the end of a `.badge`.
11
+ - A modular build imports `actual-css/css/components/close` next to the component that hosts it.
12
+
13
+ ## Basic usage
14
+
15
+ ```html demo
16
+ <div class="cluster">
17
+ <button class="close" type="button" aria-label="Close"></button>
18
+
19
+ <span class="badge primary soft">
20
+ Design
21
+ <button class="close" type="button" aria-label="Remove Design"></button>
22
+ </span>
23
+ </div>
24
+ ```
25
+
26
+ ## In a dialog
27
+
28
+ In a `.modal` or a `.drawer`, the close sits out of the content flow at the
29
+ panel's top inline-end corner. Place it as a direct child of the dialog, of its
30
+ top-level `form` or `header`, or of a `form` inside that header; a `.close`
31
+ deeper in the content keeps its own place. See [Dialog](dialog.md) and
32
+ [Drawer](drawer.md).
33
+
34
+ ```html
35
+ <dialog class="modal" id="details">
36
+ <button class="close" type="button" commandfor="details" command="request-close"
37
+ aria-label="Close dialog"></button>
38
+ …
39
+ </dialog>
40
+ ```
41
+
42
+ ## CSS hooks
43
+
44
+ - `--close-size` — inline and block size of the button; `--control-size` unless the container sets it.
45
+ - `--close-icon-size` — size of the X.
46
+
47
+ Alerts and badges declare both hooks on themselves, so set them on the container
48
+ or on the button.
@@ -61,6 +61,24 @@ metadata.
61
61
  </article>
62
62
  ```
63
63
 
64
+ ## Stacked
65
+
66
+ `.stacked` puts each value under its term instead of beside it, for a narrow
67
+ column or for values too long to share a row.
68
+
69
+ ```html demo
70
+ <dl class="data-list stacked" style="max-inline-size: 16rem">
71
+ <dt>Billing contact</dt>
72
+ <dd>alice@example.com</dd>
73
+
74
+ <dt>Registered address</dt>
75
+ <dd>42 Rue des Fleurs, 1000 Brussels, Belgium</dd>
76
+
77
+ <dt>Renewal</dt>
78
+ <dd><time datetime="2026-09-14">14 Sep 2026</time></dd>
79
+ </dl>
80
+ ```
81
+
64
82
  ## Contract
65
83
 
66
84
  `.data-list` styles one `<dt>` followed by one `<dd>` per property. A valid
@@ -69,4 +87,11 @@ markup does not belong in `.data-list` — use a plain description list instead,
69
87
  where `.prose` already covers the editorial cases.
70
88
 
71
89
  Use `.data-list` for the properties of a single object. Use a `<table>` when
72
- comparing the same properties across multiple objects.
90
+ comparing the same properties across multiple objects.
91
+
92
+ A per-property icon goes inside the `<dt>`, next to the term. There is no
93
+ gutter slot spanning a term and its value: a `<dl>` admits only `<dt>` and
94
+ `<dd>` per pair — directly or inside a `<div>` wrapper — so no third element
95
+ can hold it. When the icon is the point and the term/value relation is not,
96
+ the content is not a description list: reach for `.media` with an `.overline`
97
+ label instead.
@@ -6,22 +6,24 @@
6
6
 
7
7
  ## Class reference
8
8
 
9
- | Class | Kind | Description |
10
- | ---------------------- | --------- | ---------------------------------------------- |
11
- | `.modal` | Component | Centered surface on the native `<dialog>`. |
12
- | `.scrollable` | Variant | Header and footer stay while the body scrolls. |
13
- | `.dialog-confirmation` | Variant | Message above a full-width action band. |
14
- | `.dialog-icon` | Component | Circular intent-aware icon well. |
15
- | `.dialog-close` | Component | Icon-only close button, at the top end. |
16
-
17
- `.dialog-close` sits outside the content flow, so it does not take part in the
18
- dialog's own layout.
9
+ | Class | Kind | Description |
10
+ | ---------------------- | ----------- | ---------------------------------------------- |
11
+ | `.modal` | Component | Centered surface on the native `<dialog>`. |
12
+ | `.scrollable` | Variant | Header and footer stay while the body scrolls. |
13
+ | `.dialog-confirmation` | Variant | Message above a full-width action band. |
14
+ | `.dialog-icon` | Component | Circular intent-aware icon well. |
15
+ | `.close` | Composition | Icon-only close button, at the top end. |
16
+
17
+ A [`.close`](close.md) placed as a direct child of the dialog or of its form
18
+ sits outside the content flow, so it does not take part in the dialog's own
19
+ layout.
19
20
 
20
21
  ## Usage
21
22
 
22
23
  Modals use the platform-native `<dialog class="modal">` element with `commandfor` and `command` buttons.
23
24
 
24
- Use `command="show-modal"` to open a modal dialog.
25
+ Use `command="show-modal"` to open a modal dialog, or `command="--show"` to open
26
+ it non-modally.
25
27
 
26
28
  Add `aria-haspopup="dialog"` and `aria-controls="<id>"` to opening buttons so
27
29
  their semantics are present before either native or framework JavaScript runs.
@@ -138,7 +140,7 @@ has no action button; the header close button dismisses the dialog.
138
140
  id="details-dialog"
139
141
  closedby="any"
140
142
  data-dialog-dismissible>
141
- <button class="dialog-close"
143
+ <button class="close"
142
144
  type="button"
143
145
  commandfor="details-dialog"
144
146
  command="request-close"
@@ -243,7 +245,7 @@ promoted above it and still unclickable.
243
245
  id="overlay-dialog"
244
246
  closedby="any"
245
247
  data-dialog-dismissible>
246
- <button class="dialog-close"
248
+ <button class="close"
247
249
  type="button"
248
250
  commandfor="overlay-dialog"
249
251
  command="request-close"
@@ -296,7 +298,9 @@ Available options:
296
298
  light dismiss and closes the dialog (or rewrites `closedby="any"` to
297
299
  `closedby="closerequest"` so the native dialog does not double-handle).
298
300
  It never affects Escape or explicit close requests.
299
- * `data-dialog-modal="false"` opens with `show()` instead of `showModal()`.
301
+ * `data-dialog-modal="false"` makes direct `openDialog()` calls use `show()`
302
+ instead of `showModal()`. The `show-modal` and `--show` commands override
303
+ this default.
300
304
  * `data-dialog-view-transition` enables a view transition that morphs the dialog to/from its trigger. Only active when the browser supports `document.startViewTransition` and the user allows motion.
301
305
  * `closedby` keeps its native meaning: `"any"` closes on backdrop click and
302
306
  Escape, `"closerequest"` closes on Escape only, `"none"` disables both. The
@@ -381,7 +385,6 @@ Keep the button a direct child of `dialog.modal` so the scrolling content
381
385
  - `--dialog-viewport-gap` — distance kept between the dialog and the viewport edges.
382
386
  - `--dialog-icon-size` — diameter of the `.dialog-icon` circle.
383
387
  - `--dialog-icon-glyph-size` — size of the glyph centered inside `.dialog-icon`.
384
- - `--control-size` — inline and block size of the `.dialog-close` button. The
385
- header reserves `calc(var(--control-size) + var(--space-30))` on its inline
386
- end so the title never runs under the close.
387
- - `--dialog-close-icon-size` — size of the close glyph.
388
+ - `--close-size` / `--close-icon-size` — size of the corner `.close` and of its
389
+ X. The header reserves the close size plus `--space-30` on its inline end so
390
+ the title never runs under it.
@@ -6,10 +6,10 @@
6
6
 
7
7
  ## Class reference
8
8
 
9
- | Class | Kind | Description |
10
- | --------------- | --------- | ---------------------------------------------------------- |
11
- | `.drawer` | Component | Modal side-sheet built on the native `<dialog>` element. |
12
- | `.drawer-close` | Component | Icon-only close button that sits inside the drawer header. |
9
+ | Class | Kind | Description |
10
+ | --------- | ----------- | -------------------------------------------------------- |
11
+ | `.drawer` | Component | Modal side-sheet built on the native `<dialog>` element. |
12
+ | `.close` | Composition | Icon-only close button, at the top end. |
13
13
 
14
14
  ## Usage
15
15
 
@@ -56,7 +56,7 @@ your intended target `autofocus`; otherwise the body claims initial focus.
56
56
  <strong>Menu</strong>
57
57
 
58
58
  <form method="dialog">
59
- <button class="drawer-close" type="submit" aria-label="Close navigation"></button>
59
+ <button class="close" type="submit" aria-label="Close navigation"></button>
60
60
  </form>
61
61
  </header>
62
62
 
@@ -96,7 +96,7 @@ actions and the close button can close the drawer.
96
96
  <form method="dialog">
97
97
  <header>
98
98
  <strong>Settings</strong>
99
- <button class="drawer-close" type="submit" aria-label="Close settings"></button>
99
+ <button class="close" type="submit" aria-label="Close settings"></button>
100
100
  </header>
101
101
 
102
102
  <div class="stack">
@@ -123,6 +123,6 @@ useful for drawers that should not be dismissed accidentally.
123
123
 
124
124
  - `--drawer-size` — panel width.
125
125
  - `--drawer-pad` — panel padding.
126
- - `--control-size` — size of the `.drawer-close` button. The drawer header
127
- reserves `calc(var(--control-size) + var(--space-30))` on its inline end so
128
- the title never runs under the close.
126
+ - `--close-size` / `--close-icon-size` — size of the corner [`.close`](close.md)
127
+ and of its X. The header reserves the close size plus `--space-30` on its
128
+ inline end so the title never runs under it.
@@ -51,7 +51,7 @@ icons. See [App Navigation](app-navigation.md).
51
51
 
52
52
  For a vertical sidebar nav, use `.nav-list` inside the drawer or sidebar.
53
53
  Links inside `.nav-list` stretch to the available inline size, providing a
54
- full-row hit target for vertical navigation. The [Workspaces example](../examples/overview.md)
54
+ full-row hit target for vertical navigation. The [Workspaces example](../examples/overview.md#page-shapes)
55
55
  shows the sectioned-sidebar composition: grouped `.nav-list` blocks with
56
56
  section titles, a pinned account footer, and the native current state.
57
57
 
@@ -94,15 +94,15 @@ accessible name.
94
94
  <header>
95
95
  <strong>Menu</strong>
96
96
  <form method="dialog">
97
- <button class="drawer-close" type="submit" aria-label="Close navigation"></button>
97
+ <button class="close" type="submit" aria-label="Close navigation"></button>
98
98
  </form>
99
99
  </header>
100
100
 
101
101
  <nav>
102
102
  <ul class="nav-list stack">
103
- <li><a href="#" aria-current="page">Home</a></li>
104
- <li><a href="#">Docs</a></li>
105
- <li><a href="#">Components</a></li>
103
+ <li><a class="nav-link" href="#" aria-current="page">Home</a></li>
104
+ <li><a class="nav-link" href="#">Docs</a></li>
105
+ <li><a class="nav-link" href="#">Components</a></li>
106
106
  </ul>
107
107
  </nav>
108
108
  </dialog>
@@ -7,8 +7,8 @@
7
7
  - Use `aria-current="page"` for the current page.
8
8
  - Put `.sm` or `.lg` on `.pagination` to scale its controls.
9
9
  - Numeric links may use `aria-label="Page N"` for clearer screen reader output.
10
- - Prefer text labels for Previous and Next. Icon-only controls need an accessible name.
11
- - Page links can compose with `.btn` for button-like hit targets.
10
+ - Prefer text labels for Previous and Next; a chevron icon may accompany them. Icon-only controls need an accessible name.
11
+ - Compose page links with `.btn.ghost`; `aria-current="page"` fills the current one, so it is the only boxed item.
12
12
  - Arrows, page numbers, and truncation ellipses share one geometric system: every item gets the same minimum footprint, and wider content (100, 1000, text labels) grows past it naturally.
13
13
  - Truncated ranges are plain text with `.muted` and `aria-hidden="true"`, not `.btn` — they are decorative, not actionable.
14
14
 
@@ -24,12 +24,12 @@
24
24
  ```html demo
25
25
  <nav aria-label="Pagination">
26
26
  <ol class="pagination sm">
27
- <li><a href="?page=2" class="btn outline" rel="prev">Previous</a></li>
28
- <li><a href="?page=1" class="btn outline" aria-label="Page 1">1</a></li>
29
- <li><a href="?page=2" class="btn outline" aria-label="Page 2">2</a></li>
30
- <li><a href="?page=3" class="btn" aria-current="page" aria-label="Page 3">3</a></li>
31
- <li><a href="?page=4" class="btn outline" aria-label="Page 4">4</a></li>
32
- <li><a href="?page=5" class="btn outline" rel="next">Next</a></li>
27
+ <li><a href="?page=2" class="btn ghost" rel="prev"><i class="ti ti-chevron-left" aria-hidden="true"></i> Previous</a></li>
28
+ <li><a href="?page=1" class="btn ghost" aria-label="Page 1">1</a></li>
29
+ <li><a href="?page=2" class="btn ghost" aria-label="Page 2">2</a></li>
30
+ <li><a href="?page=3" class="btn ghost" aria-current="page" aria-label="Page 3">3</a></li>
31
+ <li><a href="?page=4" class="btn ghost" aria-label="Page 4">4</a></li>
32
+ <li><a href="?page=5" class="btn ghost" rel="next">Next <i class="ti ti-chevron-right" aria-hidden="true"></i></a></li>
33
33
  </ol>
34
34
  </nav>
35
35
  ```
@@ -42,15 +42,15 @@ buttons — they are decorative, not actionable.
42
42
  ```html demo
43
43
  <nav aria-label="Pagination">
44
44
  <ol class="pagination sm">
45
- <li><a href="?page=1" class="btn outline" rel="prev">Previous</a></li>
46
- <li><a href="?page=1" class="btn outline" aria-label="Page 1">1</a></li>
45
+ <li><a href="?page=7" class="btn ghost" rel="prev"><i class="ti ti-chevron-left" aria-hidden="true"></i> Previous</a></li>
46
+ <li><a href="?page=1" class="btn ghost" aria-label="Page 1">1</a></li>
47
47
  <li><span class="muted" aria-hidden="true">…</span></li>
48
- <li><a href="?page=7" class="btn outline" aria-label="Page 7">7</a></li>
49
- <li><a href="?page=8" class="btn" aria-current="page" aria-label="Page 8">8</a></li>
50
- <li><a href="?page=9" class="btn outline" aria-label="Page 9">9</a></li>
48
+ <li><a href="?page=7" class="btn ghost" aria-label="Page 7">7</a></li>
49
+ <li><a href="?page=8" class="btn ghost" aria-current="page" aria-label="Page 8">8</a></li>
50
+ <li><a href="?page=9" class="btn ghost" aria-label="Page 9">9</a></li>
51
51
  <li><span class="muted" aria-hidden="true">…</span></li>
52
- <li><a href="?page=20" class="btn outline" aria-label="Page 20">20</a></li>
53
- <li><a href="?page=9" class="btn outline" rel="next">Next</a></li>
52
+ <li><a href="?page=20" class="btn ghost" aria-label="Page 20">20</a></li>
53
+ <li><a href="?page=9" class="btn ghost" rel="next">Next <i class="ti ti-chevron-right" aria-hidden="true"></i></a></li>
54
54
  </ol>
55
55
  </nav>
56
56
  ```
@@ -0,0 +1,57 @@
1
+ # Shimmer
2
+
3
+ > **Module** — import `actual-css/css/effects/shimmer` or `actual-css/css/effects`.
4
+
5
+ Shimmer sweeps a highlight across a text label to show an activity in
6
+ progress: an agent working, a chatbot composing, a job processing.
7
+
8
+ ```html demo
9
+ <div class="stack">
10
+ <span class="shimmer" role="status">Working…</span>
11
+ <p class="cluster">
12
+ <span class="spinner" aria-hidden="true"></span>
13
+ <span class="shimmer" role="status">Generating the report…</span>
14
+ </p>
15
+ </div>
16
+ ```
17
+
18
+ **Related terms:** shimmering text, loading text, thinking indicator, pending
19
+ label, typing indicator.
20
+
21
+ Shimmer is presentation only and selects no ARIA attribute. Put
22
+ `role="status"` on a message that should be announced, and `aria-busy="true"`
23
+ on the region whose content is being updated — not on the message because it
24
+ looks busy. Assistive technology may hold back changes inside a busy region
25
+ until it is released.
26
+
27
+ The label rests on `--shimmer-color` and the band passes in
28
+ `--shimmer-highlight`; one pass takes `--duration-shimmer`, the pace shared
29
+ with `.skeleton` and indeterminate `.progress`. With reduced motion, or in a
30
+ browser without `background-clip: text`, the label is plain
31
+ `--shimmer-color` text. Recolor a label through these hooks: its own `color`
32
+ shows only where the sweep does not run.
33
+
34
+ ## Choosing a waiting signal
35
+
36
+ | Primitive | Signals |
37
+ | -------------------------- | -------------------------------------------- |
38
+ | [`.spinner`](spinner.md) | An operation takes time |
39
+ | [`.skeleton`](skeleton.md) | Content is not available yet |
40
+ | `.shimmer` | This label describes an activity in progress |
41
+ | [`.aura`](aura.md) | This object is emphasized |
42
+
43
+ They compose rather than imply one another: `aria-busy` never adds an aura or
44
+ a shimmer. A card being processed can carry several, each for its own reason:
45
+
46
+ ```html demo
47
+ <span class="aura primary">
48
+ <article class="card stack" style="inline-size: 18rem">
49
+ <p><strong>Quarterly import</strong></p>
50
+ <p class="shimmer" role="status">Processing 1,204 rows…</p>
51
+ <div class="stack" aria-busy="true">
52
+ <div class="skeleton" data-shape="text" aria-hidden="true"></div>
53
+ <div class="skeleton" data-shape="text" aria-hidden="true"></div>
54
+ </div>
55
+ </article>
56
+ </span>
57
+ ```
@@ -8,7 +8,8 @@
8
8
  - Use layout utilities for placeholder arrangement.
9
9
  - Only relevant for simple placeholders - use more structural solutions like phantom-ui for complex cases.
10
10
 
11
- **Related terms:** skeleton screen, shimmer, loading placeholder.
11
+ **Related terms:** skeleton screen, shimmer, loading placeholder. For a text
12
+ label showing an activity in progress, see [Shimmer](shimmer.md).
12
13
 
13
14
  ## Class reference
14
15
 
@@ -12,11 +12,15 @@
12
12
 
13
13
  ## Class reference
14
14
 
15
- | Class | Kind | Description |
16
- | -------------- | --------- | ------------------------------------------------------------------ |
17
- | `.spinner` | Component | Circular loading indicator using `currentColor`. |
18
- | `.sm` / `.lg` | Size | Smaller (`0.75em`) or larger (`2rem`) spinner. |
19
- | Shared intents | Intent | `.primary`, `.secondary`, `.success`, `.warning`, `.danger` color. |
15
+ | Class | Kind | Description |
16
+ | -------------------- | --------- | ------------------------------------------------ |
17
+ | `.spinner` | Component | Circular loading indicator using `currentColor`. |
18
+ | `[aria-busy="true"]` | State | Loading region; see Busy state below. |
19
+ | `.sm` / `.lg` | Size | Smaller (`0.75em`) or larger (`2rem`) spinner. |
20
+ | Shared intents | Intent | `.primary`, `.secondary`, `.success`, … |
21
+
22
+ The shared intents are `.primary`, `.secondary`, `.success`, `.warning` and
23
+ `.danger`.
20
24
 
21
25
  ## Basic usage
22
26
 
@@ -68,13 +72,14 @@ Size follows the font (`1em`); use `.sm` / `.lg` rather than sizing it directly.
68
72
 
69
73
  ## Busy state
70
74
 
71
- A container-wide loading state that keeps the underlying content in place. It is
75
+ The spinner is the indicator; `aria-busy` is the state. A container-wide
76
+ loading state keeps the underlying content in place. It is
72
77
  driven by `aria-busy="true"` plus a direct last-child `.spinner` — there is no
73
78
  separate `.busy` class. The spinner is shown as a centered overlay over a faded
74
79
  surface; buttons keep their spinners inline instead (see Button).
75
80
 
76
81
  - Set `aria-busy="true"` on the container and add `<span class="spinner" aria-hidden="true"></span>` as its last direct child.
77
- - The overlay uses `--busy-overlay-bg`; an inverted surface (`.inverted`) already composes with it.
82
+ - The overlay uses `--busy-overlay-bg`; a card derives it from its own surface.
78
83
  - Decorative spinners stay `aria-hidden="true"`; announce progress on the region with `role="status"` and a label when needed.
79
84
 
80
85
  ```html demo
@@ -89,5 +94,5 @@ surface; buttons keep their spinners inline instead (see Button).
89
94
 
90
95
  - `--spinner-track` — the ring color.
91
96
  - `--spinner-value` — the moving gap; swap the two for an inverted spinner.
92
- - `--busy-overlay-bg` — background of the busy overlay. An inverted surface
93
- (`.inverted`) overrides it to blend with its own surface.
97
+ - `--busy-overlay-bg` — background of the busy overlay. Set it on a surface you
98
+ paint yourself so the overlay blends with that surface.
@@ -124,6 +124,19 @@ same vocabulary as `.card.compact`.
124
124
  </div>
125
125
  ```
126
126
 
127
+ ## When a table stops reading as a table
128
+
129
+ Responsive strategy is horizontal overflow: the wrap scrolls, the table keeps
130
+ its columns and its column scanability. No `data-label` restructuring, no
131
+ second representation of the data.
132
+
133
+ For datasets that no longer read well as a table on narrow screens, compose a
134
+ different view instead of restructuring the table: a `.list` / `.media` row
135
+ with badges and actions for a CRUD collection, [`.data-list`](data-list.md)
136
+ for one object's properties, or a dedicated data grid for interactive tables
137
+ (sorting, filtering, selection). Two views for two contexts is a feature, not
138
+ a duplication.
139
+
127
140
  ## CSS hooks
128
141
 
129
142
  - `--table-cell-pad` — cell padding; `.compact` re-declares it tighter.
@@ -522,6 +522,8 @@ delay; a number sets the delay in milliseconds.
522
522
 
523
523
  The repetition is the point: the two hooks are different contracts, and only
524
524
  the cap may enter the runtime's `min()`.
525
+ - `--flyout-pad` — panel padding. Defaults to `var(--space-10)`, tight for
526
+ action menus; rich panels opt into dialog air per instance.
525
527
  - `--menu-item-size` — minimum row height of `.menu-item`.
526
528
  - `--menu-item-icon-size` — shared leading-column width for icons and checked-state indicators.
527
529
 
@@ -53,6 +53,11 @@ Enhancer modules self-register when imported. They do not require init calls and
53
53
  are safe to import during server-side rendering: outside a browser, registration
54
54
  is a no-op until the module is loaded again with a DOM.
55
55
 
56
+ Load the full bundle **or** the source modules, never both: each evaluation
57
+ owns its registry and document handlers, so a dist bundle mixed with
58
+ `actual-css/js/*` source subpaths (or two dist bundles) registers every
59
+ behavior twice and a flyout opens then immediately closes.
60
+
56
61
  ## Component pages
57
62
 
58
63
  Each interactive component has its own page documenting the exact markup its
@@ -22,6 +22,10 @@
22
22
  - JavaScript owns roving `tabindex`, `aria-selected`, `hidden`, and keyboard behavior.
23
23
  - Left/Right select tabs and wrap at the ends. Home/End jump to first/last. Down moves focus into the selected panel.
24
24
  - A tab list needs both `.tabs` and `role="tablist"`; `.tab` styles each trigger.
25
+ - Naming follows the container/item convention (like `menu` / `menu-item`):
26
+ `.tabs` is the strip, `.tab` is one trigger. The JS module
27
+ (`actual-css/js/tab`) is named for the file; the behavior token
28
+ (`data-enhance="tabs"`) is named for what it wires.
25
29
  - A `.tab` with an icon uses `--tab-gap` (default `0.375em`) for the space between icon and label.
26
30
  - A tab that is `hidden`, `disabled`, `aria-disabled`, or has no panel is skipped
27
31
  by the arrow keys. An application filtering a tab strip only has to set