actual-css 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/CHANGELOG.md +109 -3
  2. package/README.md +35 -30
  3. package/dist/actual.css +66 -4958
  4. package/dist/actual.full.css +7548 -0
  5. package/dist/actual.full.js +1 -0
  6. package/dist/actual.full.min.css +1 -0
  7. package/dist/actual.js +1 -1
  8. package/dist/actual.min.css +1 -1
  9. package/docs/design-notes/app-ui.md +33 -0
  10. package/docs/design-notes/cascade-layer.md +34 -13
  11. package/docs/design-notes/column-layout.md +677 -0
  12. package/docs/design-notes/enhancement-contract.md +25 -0
  13. package/docs/design-notes/forced-colors.md +3 -0
  14. package/docs/design-notes/grid.md +785 -0
  15. package/docs/design-notes/naming.md +15 -0
  16. package/docs/design-notes/references.md +1 -1
  17. package/docs/design-notes/widget-primitives.md +1 -0
  18. package/docs/navigation.json +12 -2
  19. package/docs/pages/components/alert.md +21 -14
  20. package/docs/pages/components/app-navigation.md +34 -0
  21. package/docs/pages/components/aura.md +1 -1
  22. package/docs/pages/components/avatar.md +16 -6
  23. package/docs/pages/components/badge.md +9 -7
  24. package/docs/pages/components/button.md +46 -16
  25. package/docs/pages/components/card.md +17 -9
  26. package/docs/pages/components/chat.md +8 -8
  27. package/docs/pages/components/dialog.md +7 -7
  28. package/docs/pages/components/drawer.md +3 -3
  29. package/docs/pages/components/fab.md +9 -7
  30. package/docs/pages/components/indicator.md +52 -0
  31. package/docs/pages/components/list.md +62 -0
  32. package/docs/pages/components/navbar.md +15 -8
  33. package/docs/pages/components/pagination.md +4 -3
  34. package/docs/pages/components/rating.md +68 -0
  35. package/docs/pages/components/skeleton.md +4 -4
  36. package/docs/pages/components/spinner.md +5 -5
  37. package/docs/pages/components/steps.md +57 -0
  38. package/docs/pages/components/table.md +30 -5
  39. package/docs/pages/enhancements/flyout.md +15 -15
  40. package/docs/pages/enhancements/overview.md +1 -1
  41. package/docs/pages/enhancements/scrollspy.md +6 -6
  42. package/docs/pages/enhancements/status-bar.md +5 -1
  43. package/docs/pages/enhancements/tabs.md +7 -8
  44. package/docs/pages/enhancements/tooltip.md +1 -1
  45. package/docs/pages/examples/overview.md +47 -22
  46. package/docs/pages/forms/choice-cards.md +11 -6
  47. package/docs/pages/forms/controls.md +1 -1
  48. package/docs/pages/forms/detached-actions.md +1 -1
  49. package/docs/pages/forms/floating-field.md +10 -5
  50. package/docs/pages/forms/form-actions.md +1 -1
  51. package/docs/pages/forms/input-policy.md +1 -1
  52. package/docs/pages/forms/joined-controls.md +4 -4
  53. package/docs/pages/forms/labels.md +6 -6
  54. package/docs/pages/forms/otp.md +33 -1
  55. package/docs/pages/forms/overview.md +19 -19
  56. package/docs/pages/forms/password.md +1 -1
  57. package/docs/pages/forms/range.md +1 -1
  58. package/docs/pages/forms/states-and-sizes.md +44 -48
  59. package/docs/pages/forms/sticky-actions.md +3 -3
  60. package/docs/pages/forms/switch.md +110 -2
  61. package/docs/pages/forms/validation.md +9 -9
  62. package/docs/pages/foundations/philosophy.md +1 -1
  63. package/docs/pages/foundations/theming.md +17 -2
  64. package/docs/pages/foundations/tokens.md +22 -10
  65. package/docs/pages/foundations/typography.md +50 -20
  66. package/docs/pages/guides/bootstrap.md +11 -11
  67. package/docs/pages/guides/integrating-actual-css.md +192 -0
  68. package/docs/pages/guides/introduction.md +23 -26
  69. package/docs/pages/guides/modular-import.md +173 -0
  70. package/docs/pages/guides/progressive-enhancement.md +81 -78
  71. package/docs/pages/guides/tailwind.md +6 -8
  72. package/docs/pages/layout/app-layout.md +57 -0
  73. package/docs/pages/layout/app-shell.md +28 -7
  74. package/docs/pages/layout/center.md +12 -1
  75. package/docs/pages/layout/choosing.md +54 -0
  76. package/docs/pages/layout/column-layout.md +206 -0
  77. package/docs/pages/layout/frame.md +6 -1
  78. package/docs/pages/layout/grid.md +133 -102
  79. package/docs/pages/layout/media.md +1 -1
  80. package/docs/pages/layout/overview.md +15 -2
  81. package/docs/pages/layout/scroll-snap.md +2 -2
  82. package/docs/pages/layout/scroll-target.md +45 -0
  83. package/docs/pages/layout/sidebar-layout.md +38 -18
  84. package/docs/pages/layout/stack.md +70 -1
  85. package/docs/pages/layout/switcher.md +10 -26
  86. package/docs/pages/layout/topbar.md +2 -2
  87. package/docs/pages/patterns/actions.md +1 -1
  88. package/docs/pages/patterns/code-block.md +1 -1
  89. package/docs/pages/patterns/exclusive-accordion.md +1 -1
  90. package/docs/pages/patterns/hierarchical-nav.md +1 -1
  91. package/docs/pages/patterns/icon-input.md +1 -1
  92. package/docs/pages/patterns/icon-slot.md +61 -0
  93. package/docs/pages/patterns/intent-nesting.md +1 -1
  94. package/docs/pages/patterns/navigation-list.md +1 -1
  95. package/docs/pages/patterns/overview.md +1 -1
  96. package/docs/pages/patterns/structured-lists.md +38 -40
  97. package/docs/pages/utilities/accessibility.md +3 -3
  98. package/docs/pages/utilities/flex.md +15 -15
  99. package/docs/pages/utilities/links.md +4 -4
  100. package/docs/pages/utilities/list.md +8 -8
  101. package/docs/pages/utilities/overflow.md +8 -8
  102. package/docs/pages/utilities/overview.md +1 -1
  103. package/docs/pages/utilities/shape.md +3 -3
  104. package/docs/pages/utilities/sizing-wrapping.md +23 -16
  105. package/docs/pages/utilities/spacing.md +20 -20
  106. package/docs/pages/utilities/text.md +10 -10
  107. package/llms.txt +46 -4
  108. package/package.json +43 -13
  109. package/scripts/reserved-classes.json +278 -0
  110. package/src/cli/actual-css.js +133 -0
  111. package/src/css/actual.css +1 -31
  112. package/src/css/actual.full.css +11 -2
  113. package/src/css/components/alert.css +17 -4
  114. package/src/css/components/app-nav.css +76 -0
  115. package/src/css/components/avatar.css +4 -0
  116. package/src/css/components/badge.css +19 -19
  117. package/src/css/components/breadcrumb.css +1 -1
  118. package/src/css/components/button.css +20 -32
  119. package/src/css/components/card.css +34 -9
  120. package/src/css/{optional → components}/chat.css +0 -6
  121. package/src/css/components/drawer.css +24 -5
  122. package/src/css/{optional → components}/fab.css +1 -7
  123. package/src/css/components/flyout.css +5 -0
  124. package/src/css/components/index.css +37 -27
  125. package/src/css/components/indicator.css +47 -0
  126. package/src/css/components/join.css +8 -1
  127. package/src/css/components/key.css +2 -0
  128. package/src/css/components/list.css +83 -0
  129. package/src/css/components/menu.css +11 -8
  130. package/src/css/components/meter.css +4 -1
  131. package/src/css/components/modal.css +5 -17
  132. package/src/css/components/navbar.css +6 -15
  133. package/src/css/components/pagination.css +11 -0
  134. package/src/css/components/rating.css +101 -0
  135. package/src/css/components/spinner.css +5 -0
  136. package/src/css/components/status-bar.css +5 -0
  137. package/src/css/components/steps.css +122 -0
  138. package/src/css/components/surface.css +5 -0
  139. package/src/css/components/tab.css +20 -22
  140. package/src/css/components/table.css +6 -0
  141. package/src/css/components/tooltip.css +3 -7
  142. package/src/css/{focus.css → core/focus.css} +0 -8
  143. package/src/css/core/index.css +9 -0
  144. package/src/css/core/print.css +18 -0
  145. package/src/css/{theme.css → core/theme.css} +19 -19
  146. package/src/css/{tokens.css → core/tokens.css} +16 -4
  147. package/src/css/{variants.css → core/variants.css} +3 -2
  148. package/src/css/{optional → effects}/aura.css +1 -10
  149. package/src/css/effects/index.css +2 -0
  150. package/src/css/forms/base.css +8 -0
  151. package/src/css/forms/choice-card.css +7 -15
  152. package/src/css/forms/choice.css +49 -37
  153. package/src/css/forms/control.css +4 -1
  154. package/src/css/forms/custom-select.css +2 -0
  155. package/src/css/{optional → forms}/floating-field.css +25 -7
  156. package/src/css/forms/index.css +10 -13
  157. package/src/css/forms/native.css +15 -2
  158. package/src/css/{optional → forms}/otp.css +25 -16
  159. package/src/css/forms/range.css +14 -4
  160. package/src/css/forms/switch.css +31 -29
  161. package/src/css/layout/app-layout.css +102 -0
  162. package/src/css/layout/app-shell.css +6 -0
  163. package/src/css/layout/center.css +14 -0
  164. package/src/css/layout/cluster.css +21 -0
  165. package/src/css/layout/column-layout.css +144 -0
  166. package/src/css/layout/container-query.css +15 -0
  167. package/src/css/layout/frame.css +19 -0
  168. package/src/css/layout/grid.css +155 -0
  169. package/src/css/layout/index.css +44 -0
  170. package/src/css/layout/measure.css +9 -0
  171. package/src/css/layout/media.css +10 -0
  172. package/src/css/layout/scroll-target.css +15 -0
  173. package/src/css/layout/scroller.css +41 -0
  174. package/src/css/layout/sidebar-layout.css +52 -0
  175. package/src/css/layout/stack.css +21 -0
  176. package/src/css/layout/switcher.css +23 -0
  177. package/src/css/{optional/layout-extra.css → layout/topbar.css} +0 -20
  178. package/src/css/typography/index.css +5 -0
  179. package/src/css/typography/lead.css +7 -0
  180. package/src/css/{components → typography}/overline.css +2 -2
  181. package/src/css/{prose.css → typography/prose.css} +57 -38
  182. package/src/css/{utilities.css → utilities/base.css} +2 -0
  183. package/src/css/utilities/index.css +3 -0
  184. package/src/js/escape.js +36 -0
  185. package/src/js/flyout.js +22 -12
  186. package/src/js/full.js +26 -0
  187. package/src/js/index.js +5 -21
  188. package/src/js/surface.js +1 -31
  189. package/src/js/tooltip.js +48 -19
  190. package/src/js/validation.js +1 -1
  191. package/src/tooling/css-bundle.js +308 -0
  192. package/dist/actual-themes.min.css +0 -1
  193. package/dist/optional.css +0 -1048
  194. package/dist/optional.min.css +0 -1
  195. package/docs/pages/guides/optional-components.md +0 -33
  196. package/docs/pages/layout/list.md +0 -41
  197. package/src/css/grid.css +0 -109
  198. package/src/css/layout.css +0 -123
  199. package/src/css/optional/index.css +0 -10
  200. package/src/css/optional/scroller.css +0 -63
  201. package/src/css/print.css +0 -47
  202. package/src/css/themes/corporate.css +0 -60
  203. package/src/css/themes/cyberpunk.css +0 -60
  204. package/src/css/themes/dim.css +0 -33
  205. package/src/css/themes/edge.css +0 -117
  206. package/src/css/themes/forest.css +0 -65
  207. package/src/css/themes/gradient.css +0 -97
  208. package/src/css/themes/index.css +0 -47
  209. package/src/css/themes/indigo.css +0 -33
  210. package/src/css/themes/lavender.css +0 -66
  211. package/src/css/themes/mono.css +0 -60
  212. package/src/css/themes/neon.css +0 -66
  213. package/src/css/themes/ocean.css +0 -60
  214. package/src/css/themes/petrol.css +0 -64
  215. package/src/css/themes/spruce.css +0 -64
  216. package/src/css/themes/square.css +0 -65
  217. package/src/css/themes/sunset.css +0 -66
  218. /package/src/css/{base.css → core/base.css} +0 -0
  219. /package/src/css/{intents.css → core/intents.css} +0 -0
  220. /package/src/css/{reset.css → core/reset.css} +0 -0
  221. /package/src/css/{optional → layout}/scroll-snap.css +0 -0
  222. /package/src/css/{optional/typography-fluid.css → typography/fluid.css} +0 -0
  223. /package/src/css/{optional/utilities-extra.css → utilities/extra.css} +0 -0
@@ -22,6 +22,75 @@ block margins are reset, so vertical rhythm always comes from `--gap`. Inline
22
22
  margins stay free — for example `margin-inline: auto` on a child centers it
23
23
  without fighting the primitive.
24
24
 
25
+ ## Don't wrap full-width regions with `.stack`
26
+
27
+ `.stack` is a column flex container, so a `.center` child — which sets its own
28
+ `inline-size` and `margin-inline: auto` — becomes a flex item that will not
29
+ stretch across the full row; it sizes to its content measure and centers inside
30
+ the flex line. For page-level full-width regions that each constrain their own
31
+ content, keep them in normal block flow instead:
32
+
33
+ ```html
34
+ <header class="center">…</header>
35
+ <main class="center">…</main>
36
+ <footer class="center">…</footer>
37
+ ```
38
+
39
+ Use `.stack` for the vertical rhythm *between* related items inside one region,
40
+ not as the wrapper that lays out independent full-width regions of a page.
41
+
42
+ ## Choosing a density
43
+
44
+ `--gap` is the primitive's channel, and the density variants set it at the point
45
+ of use. Pick the one that matches how tightly the children belong together:
46
+
47
+ | Markup | Gap | Use for |
48
+ |--------------------|------|--------------------------------------------------------|
49
+ | `.stack gap-none` | 0 | Lines that form one typographic unit — a name and a job title, a figure and its caption. |
50
+ | `.stack sm` | 8px | A homogeneous series of distinct controls — a radio list, a checkbox list, a compact vertical menu. |
51
+ | `.stack` | 12px | Normal flow between distinct elements. |
52
+ | `.stack lg` | 24px | Sections, or blocks that should read as separated. |
53
+
54
+ The distinction between the first two matters. `42` above `Open issues` is
55
+ almost a single block of text, so it takes `gap-none`. Three `.choice` labels
56
+ stay three separate controls that happen to form one group, so they take `sm` —
57
+ tighter than the default, but still spaced.
58
+
59
+ A stack that mixes kinds keeps the default: five `.field` wrappers and one lone
60
+ `.choice` is a form that contains a checkbox, not a list of options, and
61
+ tightening it would squeeze the fields.
62
+
63
+ ## Region rhythm goes on `gap`, not on `--gap`
64
+
65
+ A container that composes other primitives owns its rhythm through the `gap`
66
+ property. Setting `--gap` on it instead re-spaces everything it contains, at any
67
+ depth:
68
+
69
+ ```css
70
+ /* Leaks: --gap is inherited, so every nested stack, cluster and grid — down to
71
+ a radio list inside a field-group — is pushed to 24px too. */
72
+ .app-region {
73
+ --gap: var(--space-50);
74
+ }
75
+
76
+ /* Owns its own rhythm and nothing else. Nested primitives keep --gap. */
77
+ .app-region {
78
+ gap: var(--space-50);
79
+ }
80
+ ```
81
+
82
+ Both give the region the same spacing; only the second stops there. This is what
83
+ makes a nested `.stack sm` a real density choice — 12px down to 8px — rather
84
+ than a patch cancelling a rhythm inherited from three levels up.
85
+
86
+ Setting `--gap` is still the right move on the element that *consumes* it: a
87
+ one-off `--gap` on a card body or an actions row tunes that primitive and
88
+ nothing below it, because the setter is the consumer. The leak only appears when
89
+ a container sets the token and its children read it.
90
+
91
+ `.sm` and `.lg` are the deliberate exception: they set `--gap` precisely so a
92
+ density context reaches nested layouts.
93
+
25
94
  ## Grouping items tightly
26
95
 
27
96
  Stack spacing is a `--gap` between every direct child; the primitive cannot
@@ -52,4 +121,4 @@ additive, so a negative block margin on the child cancels the following gap:
52
121
  ```
53
122
 
54
123
  The stack resets child block margins to zero, so this re-adds a margin on that
55
- one child only; the rest of the stack keeps its rhythm.
124
+ one child only; the rest of the stack keeps its rhythm.
@@ -1,36 +1,20 @@
1
1
  # Switcher
2
2
 
3
- Row that becomes a column when space gets tight, useful for small sets of panels.
4
-
5
- > **Optional** — import `actual-css/css/optional/layout-extra` or `actual-css/css/optional/index`.
6
-
7
- Use `.switcher` for rows that should become columns when space gets tight.
3
+ Use `.switcher` for a small set of peer regions that should switch together
4
+ between one row and a vertical stack. Unlike `.grid`, it never produces a
5
+ partial row such as two items followed by one orphan.
8
6
 
9
7
  ```html demo
10
8
  <section class="switcher">
11
- <article class="card">
12
- <h3>Profile</h3>
13
- <p>Personal details and preferences.</p>
14
- </article>
15
- <article class="card">
16
- <h3>Security</h3>
17
- <p>Password and login settings.</p>
18
- </article>
19
- <article class="card">
20
- <h3>Billing</h3>
21
- <p>Invoices and payment methods.</p>
22
- </article>
9
+ <article class="card"><h3>Profile</h3><p>Personal details.</p></article>
10
+ <article class="card"><h3>Security</h3><p>Login settings.</p></article>
11
+ <article class="card"><h3>Billing</h3><p>Payment details.</p></article>
23
12
  </section>
24
13
  ```
25
14
 
26
- This is useful for small sets of panels, not large card collections. Use `.grid` for repeatable collections.
27
-
28
- ## CSS hooks
15
+ Use `.grid` instead for repeatable collections whose items can reflow
16
+ independently.
29
17
 
30
- - `--switcher-threshold` — container width at which the row becomes a column.
18
+ ### Hooks
31
19
 
32
- ```css
33
- .settings-panels {
34
- --switcher-threshold: 55rem;
35
- }
36
- ```
20
+ - `--switcher-threshold` controls the space needed before all peers share a row.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Sticky, frosted top bar shell for app/dashboard layouts with a persistent sidebar.
4
4
 
5
- > **Optional** — import `actual-css/css/optional/layout-extra` or `actual-css/css/optional/index`.
5
+ > **Module** — import `actual-css/css/layout/topbar` or `actual-css/css/layout`.
6
6
 
7
7
  Use `.topbar` for the structural shell of an app-shell header: sticky positioning, stacking, and a frosted background. Row content — search, breadcrumb, actions — stays local to the page.
8
8
 
@@ -20,4 +20,4 @@ Use `.topbar` for the structural shell of an app-shell header: sticky positionin
20
20
  </header>
21
21
  ```
22
22
 
23
- This is for the app-shell topbar specifically — a structural need that recurs unchanged across app UIs regardless of brand. It is not for marketing or editorial site headers, which are one-off visual identity per page.
23
+ This is for the app-shell topbar specifically — a structural need that recurs unchanged across app UIs regardless of brand. It is not for marketing or editorial site headers, which are one-off visual identity per page.
@@ -49,4 +49,4 @@ Prefer composition over making each component reimplement action-list layout.
49
49
  padding: 0;
50
50
  list-style: none;
51
51
  }
52
- ```
52
+ ```
@@ -33,4 +33,4 @@ enhance({
33
33
  });
34
34
  ```
35
35
 
36
- No core JS, no syntax highlighter — the recipe is the documentation.
36
+ No core JS, no syntax highlighter — the recipe is the documentation.
@@ -13,4 +13,4 @@ Browsers that support the `name` attribute on `<details>` get native exclusive a
13
13
  </details>
14
14
  ```
15
15
 
16
- Not shipping an accordion JS engine is a design decision, not a gap.
16
+ Not shipping an accordion JS engine is a design decision, not a gap.
@@ -23,4 +23,4 @@ App shell with a collapsible nav tree. Uses existing primitives only — no tree
23
23
  - Native `<details>`: exclusive accordion with `<details name>` (no JS engine)
24
24
  - `data-enhance="scrollspy"`: scroll-driven `aria-current`
25
25
  - `.scroller`: thin, theme-aware scrollbar
26
- - No `.nav-heading` / `.nav-sublist` classes — the existing primitives are enough
26
+ - No `.nav-heading` / `.nav-sublist` classes — the existing primitives are enough
@@ -22,4 +22,4 @@ The icon keeps a fixed `--input-icon-size` (1.25rem); density contexts shrink th
22
22
  </div>
23
23
  ```
24
24
 
25
- Trailing icons are supported too: an icon that follows the input is positioned at the end and the input grows its end padding. It stays decorative — `pointer-events: none` means an interactive trailing control such as a clear button is not covered by this class.
25
+ Trailing icons are supported too: an icon that follows the input is positioned at the end and the input grows its end padding. It stays decorative — `pointer-events: none` means an interactive trailing control such as a clear button is not covered by this class.
@@ -0,0 +1,61 @@
1
+ # Icon slot
2
+
3
+ > Contained icon zones — a leading icon, an icon disc, a status marker — appear
4
+ > across product UI: notifications, activity feeds, list actions, cards. There
5
+ > is no dedicated primitive; the same small contract is composed from existing
6
+ > pieces.
7
+
8
+ A contained icon zone must be a **stable box** that never shrinks, always
9
+ centers its glyph, and clips overflow:
10
+
11
+ - fixed `inline-size` / `block-size` (or `aspect-ratio: 1` for a disc);
12
+ - `display: grid; place-items: center;` for reliable centering;
13
+ - `flex: 0 0 auto` so a flex row never compresses it;
14
+ - `overflow: hidden`;
15
+ - a child `svg` constrained to the box.
16
+
17
+ ## The contract
18
+
19
+ ```css
20
+ .product-icon {
21
+ flex: 0 0 auto;
22
+ inline-size: 1.5rem;
23
+ block-size: 1.5rem;
24
+ display: grid;
25
+ place-items: center;
26
+ overflow: hidden;
27
+ }
28
+
29
+ .product-icon svg {
30
+ inline-size: 100%;
31
+ block-size: 100%;
32
+ }
33
+ ```
34
+
35
+ For a round disc, add the `.circle` utility — it supplies the `border-radius`:
36
+
37
+ ```css
38
+ .product-icon.circle {
39
+ background: var(--surface-subtle);
40
+ }
41
+ ```
42
+
43
+ ## Reuse the existing icon slots
44
+
45
+ Several components already embody this slot — reach for them before composing
46
+ your own:
47
+
48
+ - `.alert-icon` — the leading icon in an alert.
49
+ - `.avatar` — initials or image in a fixed circular box.
50
+ - `.btn.icon-only` — a square icon button sized to the control height.
51
+ - `.input-icon` — a leading icon in a search/filter input.
52
+
53
+ ```html demo
54
+ <div class="media">
55
+ <span class="avatar primary"><abbr>AM</abbr></span>
56
+ <div class="stack">
57
+ <strong>Ada Meridian</strong>
58
+ <span class="muted">Senior designer.</span>
59
+ </div>
60
+ </div>
61
+ ```
@@ -1,3 +1,3 @@
1
1
  # Intent Nesting
2
2
 
3
- Intent on an ancestor must not tint nested components, and a local intent inside an intent-carrying ancestor must win. Both directions are verified in `tests/css-audit.test.js` and the kitchen-sink demo template. Intent classes only expose `--intent` and `--intent-fg`; each consuming component opens a local intent boundary in a `:where()` block that resets exactly the tokens it consumes to initial. Parent intents do not leak into nested components, and a local intent class still wins because it has higher specificity than `:where()`.
3
+ Intent on an ancestor must not tint nested components, and a local intent inside an intent-carrying ancestor must win. Both directions are verified in `tests/css-audit.test.js` and the kitchen-sink demo template. Intent classes only expose `--intent` and `--intent-fg`; each consuming component opens a local intent boundary in a `:where()` block that resets exactly the tokens it consumes to initial. Parent intents do not leak into nested components, and a local intent class still wins because it has higher specificity than `:where()`.
@@ -232,4 +232,4 @@ A project may add `.side-nav` only when it needs specific visual behavior such a
232
232
  }
233
233
  ```
234
234
 
235
- Keep this separate from layout primitives. `.cluster` and `.stack` should not style links.
235
+ Keep this separate from layout primitives. `.cluster` and `.stack` should not style links.
@@ -55,4 +55,4 @@ If list chrome should be removed, use an explicit pattern.
55
55
  <li><a href="/docs">Docs</a></li>
56
56
  <li><a href="/components">Components</a></li>
57
57
  </ul>
58
- ```
58
+ ```
@@ -1,47 +1,45 @@
1
1
  # Structured Lists
2
2
 
3
- Use native lists plus layout primitives for rich content rows. Reset list chrome only when markers are not part of the content.
3
+ Choose list markup from the content semantics, then add only the layout or
4
+ component contract the collection needs.
4
5
 
5
- ```html demo
6
- <figure class="stack">
7
- <figcaption><strong>Most played songs this week</strong></figcaption>
6
+ | Need | Use |
7
+ | --- | --- |
8
+ | Bullets or order carry meaning | Native `<ul>` or `<ol>` |
9
+ | One leading element and one flexible content region | [`.media`](../layout/media.md) |
10
+ | Repeated application rows with leading, content, and trailing regions | [`.list`](../components/list.md) |
11
+ | A list of navigation links | [`.nav-list`](./navigation-list.md) |
12
+ | A richer collection with its own item structure | Native list plus layout primitives and components |
8
13
 
9
- <ul class="list-reset stack gap-none">
10
- <li class="media items-center py" style="border-block-end: var(--border-width) solid var(--border)">
11
- <div class="avatar">
12
- <img src="https://i.pravatar.cc/48?img=5" alt="Dio Lupa" />
13
- </div>
14
- <div class="cluster">
15
- <div class="stack grow" style="--gap: var(--space-10)">
16
- <strong>Dio Lupa</strong>
17
- <span class="muted">Remaining Reason</span>
18
- </div>
19
- <span class="muted">3:45</span>
20
- <button class="btn ghost" type="button" aria-label="Play">
21
- <i class="ti ti-player-play" aria-hidden="true"></i>
22
- </button>
23
- </div>
24
- </li>
14
+ `.media` and `.list` are not interchangeable. `.media` is geometry for one
15
+ two-part composition and requires exactly two direct children. `.list` owns the
16
+ repeated-row treatment: three regions, row padding, minimum touch height,
17
+ dividers, navigable-row hover, and supporting text.
25
18
 
26
- <li class="media items-center py" style="border-block-end: var(--border-width) solid var(--border)">
27
- <div class="avatar">
28
- <img src="https://i.pravatar.cc/48?img=10" alt="Astral Planes" />
29
- </div>
30
- <div class="cluster">
31
- <div class="stack grow" style="--gap: var(--space-10)">
32
- <strong>Astral Planes</strong>
33
- <span class="muted">Neon Drift</span>
34
- </div>
35
- <span class="muted">4:12</span>
36
- <button class="btn ghost" type="button" aria-label="Play">
37
- <i class="ti ti-player-play" aria-hidden="true"></i>
38
- </button>
39
- </div>
40
- </li>
41
- </ul>
42
- </figure>
43
- ```
19
+ Keep native markers when they communicate sequence, rank, or grouping. Remove
20
+ them with `.list-reset` only when they are not part of the content. A reset
21
+ changes list chrome; it does not create a row component.
44
22
 
45
- Use `.actions` for action controls and `.nav-list` for navigation links. For structured content items, compose `.list-reset`, `.stack`, `.cluster`, `.media`, and components directly.
23
+ For a collection whose items are complete compositions rather than application
24
+ rows, keep the native list and compose each item independently:
46
25
 
47
- `.media` is a two-slot object: it lays out exactly two children — the leading element and one content column. Trailing metadata and actions belong inside the content column (nest a `.cluster` and put `.grow` on the flexible part), never as extra row children: additional children silently wrap onto a second grid row.
26
+ ```html demo
27
+ <ul class="list-reset grid" style="--grid-min: 16rem">
28
+ <li>
29
+ <article class="card stack">
30
+ <span class="badge">Guide</span>
31
+ <h2>Choose a layout</h2>
32
+ <p>Match intrinsic behavior to the structure of the content.</p>
33
+ <a href="#layout-guide">Read the guide</a>
34
+ </article>
35
+ </li>
36
+ <li>
37
+ <article class="card stack">
38
+ <span class="badge">Reference</span>
39
+ <h2>Compose spacing</h2>
40
+ <p>Use shared rhythm without coupling content to a component.</p>
41
+ <a href="#spacing-reference">View the reference</a>
42
+ </article>
43
+ </li>
44
+ </ul>
45
+ ```
@@ -4,8 +4,8 @@ Text hidden visually but still available to assistive technology.
4
4
 
5
5
  ## Class reference
6
6
 
7
- | Class | Kind | Description |
8
- |---|---|---|
7
+ | Class | Kind | Description |
8
+ |------------|---------|-----------------------------------------------------------------|
9
9
  | `.sr-only` | Utility | Visually hides text while keeping it in the accessibility tree. |
10
10
 
11
11
  ## Screen reader only
@@ -31,4 +31,4 @@ Use `.sr-only` for text that should be available to assistive technology but vis
31
31
  white-space: nowrap;
32
32
  border: 0;
33
33
  }
34
- ```
34
+ ```
@@ -4,19 +4,19 @@ Small flex helpers for grow behavior and other one-line needs.
4
4
 
5
5
  ## Class reference
6
6
 
7
- | Class | Kind | Description |
8
- |---|---|---|
9
- | `.grow` | Utility | Makes an item take available flex space without overflowing. |
10
- | `.items-start` | Utility | Aligns children to the block-start edge; sets `--items-align`. |
11
- | `.items-center` | Utility | Centers children on the cross axis; sets `--items-align`. |
12
- | `.items-end` | Utility | Aligns children to the block-end edge; sets `--items-align`. |
13
- | `.dot` | Utility | Inline separator dot for metadata rows. |
14
- | `.justify-content-start` | Utility | `justify-content: flex-start` and `--cluster-justify`. Optional layer. |
15
- | `.justify-content-center` | Utility | `justify-content: center` and `--cluster-justify`. Optional layer. |
16
- | `.justify-content-end` | Utility | `justify-content: flex-end` and `--cluster-justify`. Optional layer. |
7
+ | Class | Kind | Description |
8
+ |----------------------------------|---------|---------------------------------------------------------------------------|
9
+ | `.grow` | Utility | Makes an item take available flex space without overflowing. |
10
+ | `.items-start` | Utility | Aligns children to the block-start edge; sets `--items-align`. |
11
+ | `.items-center` | Utility | Centers children on the cross axis; sets `--items-align`. |
12
+ | `.items-end` | Utility | Aligns children to the block-end edge; sets `--items-align`. |
13
+ | `.dot` | Utility | Inline separator dot for metadata rows. |
14
+ | `.justify-content-start` | Utility | `justify-content: flex-start` and `--cluster-justify`. Optional layer. |
15
+ | `.justify-content-center` | Utility | `justify-content: center` and `--cluster-justify`. Optional layer. |
16
+ | `.justify-content-end` | Utility | `justify-content: flex-end` and `--cluster-justify`. Optional layer. |
17
17
  | `.justify-content-space-between` | Utility | `justify-content: space-between` and `--cluster-justify`. Optional layer. |
18
- | `.flex-wrap` | Utility | `flex-wrap: wrap` on any flex container. Optional layer. |
19
- | `.flex-nowrap` | Utility | `flex-wrap: nowrap` on any flex container. Optional layer. |
18
+ | `.flex-wrap` | Utility | `flex-wrap: wrap` on any flex container. Optional layer. |
19
+ | `.flex-nowrap` | Utility | `flex-wrap: nowrap` on any flex container. Optional layer. |
20
20
 
21
21
  ## Grow
22
22
 
@@ -65,8 +65,8 @@ flex containers:
65
65
 
66
66
  - `.items-start` / `.items-center` / `.items-end` set `--items-align`, read by `.alert` and `.card`.
67
67
  - `.text-start` / `.text-center` / `.text-end` set `--text-align`, read by `.table` cells.
68
- - `.justify-content-*` (optional layer) set `--cluster-justify`, read by `.cluster`.
69
- - `.flex-wrap` / `.flex-nowrap` (optional layer) set `flex-wrap` directly on any flex container.
68
+ - `.justify-content-*` (utilities/extra) set `--cluster-justify`, read by `.cluster`.
69
+ - `.flex-wrap` / `.flex-nowrap` (utilities/extra) set `flex-wrap` directly on any flex container.
70
70
 
71
71
  Set the property directly when you need a value the helpers do not ship.
72
72
 
@@ -102,4 +102,4 @@ Always mark it `aria-hidden="true"` — it is a visual separator, not content.
102
102
 
103
103
  - `--items-align` — cross-axis alignment, set by `.items-start` / `.items-center` / `.items-end`.
104
104
  - `--text-align` — text alignment, set by `.text-start` / `.text-center` / `.text-end`.
105
- - `--cluster-justify` — main-axis distribution, set by the optional `.justify-content-*` helpers and read by `.cluster`.
105
+ - `--cluster-justify` — main-axis distribution, set by the optional `.justify-content-*` helpers and read by `.cluster`.
@@ -4,10 +4,10 @@ Link styling for chrome that is conceptually a link but should not look like pro
4
4
 
5
5
  ## Class reference
6
6
 
7
- | Class | Kind | Description |
8
- |---|---|---|
7
+ | Class | Kind | Description |
8
+ |---------------|---------|-----------------------------------------------------------|
9
9
  | `.link-plain` | Utility | Removes the underline and inherits the surrounding color. |
10
- | `.link-muted` | Utility | Muted link that shifts to the full text color on hover. |
10
+ | `.link-muted` | Utility | Muted link that shifts to the full text color on hover. |
11
11
 
12
12
  ## Plain
13
13
 
@@ -15,4 +15,4 @@ Link styling for chrome that is conceptually a link but should not look like pro
15
15
 
16
16
  ## Muted
17
17
 
18
- `.link-muted` is a `.link-plain` that starts in the muted text color and shifts to the full text color on hover. Use for navigation lists, table of contents, and other secondary navigation surfaces.
18
+ `.link-muted` is a `.link-plain` that starts in the muted text color and shifts to the full text color on hover. Use for navigation lists, table of contents, and other secondary navigation surfaces.
@@ -4,11 +4,11 @@ Utilities for list chrome reset, readable measure, and editorial kicker labels.
4
4
 
5
5
  ## Class reference
6
6
 
7
- | Class | Kind | Description |
8
- |---|---|---|
9
- | `.list-reset` | Utility | Removes native list margin, padding, and markers. |
10
- | `.measure` | Utility | Caps a block at a readable width via `--prose-measure`. |
11
- | `.overline` | Component | Small editorial kicker label: muted, uppercase, letterspaced. |
7
+ | Class | Kind | Description |
8
+ |---------------|-----------|---------------------------------------------------------------|
9
+ | `.list-reset` | Utility | Removes native list margin, padding, and markers. |
10
+ | `.measure` | Utility | Caps a block at a readable width via `--measure`. |
11
+ | `.overline` | Component | Small editorial kicker label: muted, uppercase, letterspaced. |
12
12
 
13
13
  ## List reset
14
14
 
@@ -16,7 +16,7 @@ Utilities for list chrome reset, readable measure, and editorial kicker labels.
16
16
 
17
17
  ## Measure
18
18
 
19
- `.measure` caps a block at a readable width using `--prose-measure`. It does not center — combine with `.center` for the common centered reading column, or with `margin-inline: auto` for a one-off centered block.
19
+ `.measure` caps a block at a readable width using `--measure`. It does not center — combine with `.center` for the common centered reading column, or with `margin-inline: auto` for a one-off centered block.
20
20
 
21
21
  Use it for any content that needs a comfortable measure: prose articles, TOC lists, form fields, callouts. Avoid using it for full-bleed surfaces.
22
22
 
@@ -28,5 +28,5 @@ The overline exists because categories, kicker labels, and section markers recur
28
28
 
29
29
  ## CSS hooks
30
30
 
31
- - `--prose-measure` — the readable measure `.measure` caps at; defaults to `70ch`.
32
- - `--overline-radius` — the pill chip's corner radius; defaults to `--radius-full`.
31
+ - `--measure` — the readable measure `.measure` caps at; defaults to `70ch`.
32
+ - `--overline-radius` — the pill chip's corner radius; defaults to `--radius-full`.
@@ -4,13 +4,13 @@ Explicit overflow handling for content that may exceed its container.
4
4
 
5
5
  ## Class reference
6
6
 
7
- | Class | Kind | Description |
8
- |---|---|---|
9
- | `.overflow-auto` | Utility | Enables scrolling when content exceeds the container. |
10
- | `.overflow-hidden` | Utility | Clips overflowing content. Optional layer. |
11
- | `.overflow-clip` | Utility | Clips overflowing content without a scroll container. Optional layer. |
12
- | `.overflow-x-auto` | Utility | Horizontal scrolling only. Optional layer. |
13
- | `.overflow-y-auto` | Utility | Vertical scrolling only. Optional layer. |
7
+ | Class | Kind | Description |
8
+ |--------------------|---------|-----------------------------------------------------------------------|
9
+ | `.overflow-auto` | Utility | Enables scrolling when content exceeds the container. |
10
+ | `.overflow-hidden` | Utility | Clips overflowing content. Optional layer. |
11
+ | `.overflow-clip` | Utility | Clips overflowing content without a scroll container. Optional layer. |
12
+ | `.overflow-x-auto` | Utility | Horizontal scrolling only. Optional layer. |
13
+ | `.overflow-y-auto` | Utility | Vertical scrolling only. Optional layer. |
14
14
 
15
15
  Use `.overflow-auto` when content may overflow its container, especially tables and code-like regions.
16
16
 
@@ -40,4 +40,4 @@ Use `.overflow-auto` when content may overflow its container, especially tables
40
40
  }
41
41
  ```
42
42
 
43
- The optional layer extends the same concern with axis-specific and clipping variants. For quiet, custom scrollbar chrome instead of the native OS scrollbar, pair `.overflow-auto` with `.scroller` on the Sizing And Wrapping page.
43
+ The extra utilities extend the same concern with axis-specific and clipping variants. To give the native scrollbar the theme's density and colour, pair `.overflow-auto` with `.scroller` on the Sizing And Wrapping page.
@@ -15,4 +15,4 @@ Utilities are a small escape hatch for common single-purpose needs. They should
15
15
  - No color scales such as `.text-primary` or `.bg-success` — intent colors belong to components and state.
16
16
  - No breakpoint utility variants — use container queries or layout primitives.
17
17
  - No utility variants for hover, focus, dark mode, or arbitrary selectors — use component states.
18
- - No full spacing scale with every step and direction — the 17 spacing helpers across the core and optional layers cover the most common escape hatches.
18
+ - No full spacing scale with every step and direction — the 17 spacing helpers across the core and extra utilities cover the most common escape hatches.
@@ -4,8 +4,8 @@ Rare shape utilities for cases that must be perfectly round or square.
4
4
 
5
5
  ## Class reference
6
6
 
7
- | Class | Kind | Description |
8
- |---|---|---|
7
+ | Class | Kind | Description |
8
+ |-----------|---------|-----------------------------------------------------|
9
9
  | `.circle` | Utility | Forces a perfectly round shape via `--radius-full`. |
10
10
 
11
11
  Shape utilities should be rare because shape is mostly theme-level.
@@ -22,4 +22,4 @@ Use `.circle` only when an element must be perfectly round.
22
22
  }
23
23
  ```
24
24
 
25
- Do not add `.rounded-sm`, `.rounded-lg`, `.square`, or `.pill` unless repeated real use proves they are needed.
25
+ Do not add `.rounded-sm`, `.rounded-lg`, `.square`, or `.pill` unless repeated real use proves they are needed.
@@ -4,12 +4,12 @@ Small layout corrections for controls, labels, and compact rails.
4
4
 
5
5
  ## Class reference
6
6
 
7
- | Class | Kind | Description |
8
- |---|---|---|
9
- | `.fit` | Utility | Shrinks a control or element to its content width. |
10
- | `.text-nowrap` | Utility | Keeps text on one line. |
11
- | `.truncate` | Utility | Ellipsizes overflowing single-line text. |
12
- | `.scroller` | Utility | Quiet custom scrollbar chrome for scroll containers. Optional layer. |
7
+ | Class | Kind | Description |
8
+ |---------------------------|---------|---------------------------------------------------------------------------|
9
+ | `.fit` | Utility | Shrinks a control or element to its content width. |
10
+ | `.text-nowrap` | Utility | Keeps text on one line. |
11
+ | `.truncate` | Utility | Ellipsizes overflowing single-line text. |
12
+ | `.scroller` | Utility | Theme-aware scrollbar density and colour for scroll containers. Optional layer. |
13
13
  | `.scroller.stable-gutter` | Variant | Reserves scrollbar gutter space so layout does not shift. Optional layer. |
14
14
 
15
15
  Use `.fit` when a control or element should shrink to its content instead of filling the available inline space.
@@ -66,10 +66,22 @@ Use `.truncate` on the flexible item that should ellipsize inside a constrained
66
66
 
67
67
  Use `.scroller` to apply optional framework scrollbar treatment to a scroll container. It styles the scrollbar only; pair it with `.overflow-auto` or a component that already creates overflow.
68
68
 
69
+ The utility is two standard declarations and nothing else — the engine keeps
70
+ drawing the scrollbar, `.scroller` only hands it a density and a colour that
71
+ follow the theme. There is no `::-webkit-scrollbar` chrome: rebuilding a thumb
72
+ by hand means re-implementing the hover, the corner and the light/dark
73
+ adaptation that `color-scheme` already provides, and the hand-built version
74
+ never quite matches the native one anyway.
75
+
76
+ `scrollbar-color` and `scrollbar-width` land in Chromium 121 and Safari 18.2,
77
+ above the capability floor. An engine that knows neither ignores both
78
+ declarations and draws its native scrollbar — the intended fallback, not a
79
+ broken state.
80
+
69
81
  `scroller` is not imported by `actual.css`. Import it explicitly when a project wants Actual CSS scrollbar chrome instead of the native OS default:
70
82
 
71
83
  ```css
72
- @import "actual-css/css/optional/scroller";
84
+ @import "actual-css/css/layout/scroller";
73
85
  ```
74
86
 
75
87
  ```html demo
@@ -84,11 +96,8 @@ Use `.scroller` to apply optional framework scrollbar treatment to a scroll cont
84
96
 
85
97
  ```css
86
98
  .scroller {
87
- --scroller-size: 0.625rem;
88
- --scroller-padding: 0.125rem;
89
99
  --scroller-track: transparent;
90
100
  --scroller-thumb: var(--border);
91
- --scroller-thumb-hover: var(--text-muted);
92
101
 
93
102
  scrollbar-color: var(--scroller-thumb) var(--scroller-track);
94
103
  scrollbar-width: thin;
@@ -98,18 +107,16 @@ Use `.scroller` to apply optional framework scrollbar treatment to a scroll cont
98
107
  Customize locally when a scroll surface needs more contrast:
99
108
 
100
109
  ```html
101
- <div class="overflow-auto scroller"
102
- style="--scroller-thumb: var(--text-muted); --scroller-thumb-hover: var(--text)">
110
+ <div class="overflow-auto scroller" style="--scroller-thumb: var(--text-muted)">
103
111
  ...
104
112
  </div>
105
113
  ```
106
114
 
107
- For rounded scroll containers, keep the thumb visually away from the edge by tuning `--scroller-padding` rather than adding extra wrappers or masking pseudo-elements.
115
+ Thickness is not a hook: `scrollbar-width` takes `thin` or `auto`, not a length.
116
+ Hover is left to the engine — it varies by platform, and matching it by hand was
117
+ the part of a custom scrollbar that never held up.
108
118
 
109
119
  ## CSS hooks
110
120
 
111
- - `--scroller-size` — scrollbar thickness.
112
- - `--scroller-padding` — inset between the thumb and the track edge.
113
121
  - `--scroller-track` — scrollbar track color.
114
122
  - `--scroller-thumb` — scrollbar thumb color.
115
- - `--scroller-thumb-hover` — scrollbar thumb color on hover.