actual-css 0.11.0 → 0.12.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 (92) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/README.md +29 -5
  3. package/components.json +15 -17
  4. package/dist/actual.full.css +403 -227
  5. package/dist/actual.full.min.css +1 -1
  6. package/docs/brand/favicon.svg +5 -0
  7. package/docs/brand/lockup.svg +12 -0
  8. package/docs/brand/logo-dark.svg +9 -0
  9. package/docs/brand/logo-light.svg +9 -0
  10. package/docs/brand/logo.svg +11 -0
  11. package/docs/brand/mark.svg +11 -0
  12. package/docs/navigation.json +4 -2
  13. package/docs/pages/components/alert.md +2 -10
  14. package/docs/pages/components/badge.md +3 -9
  15. package/docs/pages/components/bleed.md +5 -4
  16. package/docs/pages/components/card.md +31 -2
  17. package/docs/pages/components/close.md +9 -3
  18. package/docs/pages/components/dialog.md +248 -31
  19. package/docs/pages/components/drawer.md +2 -2
  20. package/docs/pages/components/meter.md +2 -0
  21. package/docs/pages/components/navbar.md +8 -9
  22. package/docs/pages/components/table.md +3 -3
  23. package/docs/pages/enhancements/flyout.md +2 -2
  24. package/docs/pages/enhancements/scrollspy.md +1 -1
  25. package/docs/pages/enhancements/status-bar.md +2 -2
  26. package/docs/pages/examples/overview.md +3 -1
  27. package/docs/pages/forms/date-picker.md +90 -0
  28. package/docs/pages/forms/detached-actions.md +37 -30
  29. package/docs/pages/forms/form-actions.md +61 -28
  30. package/docs/pages/forms/input-policy.md +1 -1
  31. package/docs/pages/forms/overview.md +6 -5
  32. package/docs/pages/forms/sticky-actions.md +85 -83
  33. package/docs/pages/forms/validation.md +5 -5
  34. package/docs/pages/foundations/philosophy.md +5 -3
  35. package/docs/pages/foundations/theming.md +15 -4
  36. package/docs/pages/foundations/tokens.md +50 -33
  37. package/docs/pages/foundations/typography.md +4 -7
  38. package/docs/pages/guides/bootstrap.md +2 -2
  39. package/docs/pages/guides/design-tools.md +36 -0
  40. package/docs/pages/guides/integrating-actual-css.md +5 -1
  41. package/docs/pages/guides/introduction.md +3 -4
  42. package/docs/pages/guides/modular-import.md +3 -0
  43. package/docs/pages/guides/progressive-enhancement.md +2 -2
  44. package/docs/pages/guides/tailwind.md +70 -0
  45. package/docs/pages/guides/upgrading.md +74 -0
  46. package/docs/pages/layout/cluster.md +28 -2
  47. package/docs/pages/layout/overview.md +1 -1
  48. package/docs/pages/layout/stack.md +21 -16
  49. package/docs/pages/layout/topbar.md +1 -1
  50. package/docs/pages/patterns/navigation-list.md +16 -46
  51. package/docs/pages/patterns/overview.md +3 -4
  52. package/docs/pages/utilities/flex.md +30 -20
  53. package/docs/pages/utilities/sizing-wrapping.md +1 -1
  54. package/docs/pages/utilities/spacing.md +4 -3
  55. package/package.json +3 -2
  56. package/reserved-classes.json +3 -3
  57. package/skills/actual-css/references/enhancements.md +38 -0
  58. package/src/cli/actual-css.js +75 -6
  59. package/src/css/components/avatar.css +16 -9
  60. package/src/css/components/badge.css +1 -5
  61. package/src/css/components/bleed.css +5 -5
  62. package/src/css/components/button.css +17 -10
  63. package/src/css/components/card.css +18 -10
  64. package/src/css/components/chat.css +4 -5
  65. package/src/css/components/close.css +17 -6
  66. package/src/css/components/drawer.css +19 -3
  67. package/src/css/components/flyout.css +3 -0
  68. package/src/css/components/index.css +0 -1
  69. package/src/css/components/meter.css +5 -2
  70. package/src/css/components/modal.css +157 -69
  71. package/src/css/components/navbar.css +14 -25
  72. package/src/css/core/base.css +1 -1
  73. package/src/css/core/reset.css +2 -1
  74. package/src/css/core/theme.css +4 -0
  75. package/src/css/core/tokens.css +28 -10
  76. package/src/css/core/variants.css +41 -14
  77. package/src/css/forms/form-actions.css +15 -10
  78. package/src/css/forms/native.css +5 -1
  79. package/src/css/layout/cluster.css +11 -0
  80. package/src/css/layout/topbar.css +12 -6
  81. package/src/css/utilities/base.css +5 -0
  82. package/src/css/utilities/extra.css +3 -7
  83. package/src/tooling/color.js +65 -0
  84. package/src/tooling/design-components.js +286 -0
  85. package/src/tooling/design-export.js +69 -0
  86. package/src/tooling/design-tokens.js +474 -0
  87. package/src/tooling/penpot-plugin/manifest.json +7 -0
  88. package/src/tooling/penpot-plugin/plugin.js +272 -0
  89. package/src/tooling/penpot-plugin/ui.html +58 -0
  90. package/src/tooling/theme-contrast.js +209 -0
  91. package/docs/pages/patterns/actions.md +0 -52
  92. package/src/css/components/actions.css +0 -27
package/CHANGELOG.md CHANGED
@@ -2,6 +2,79 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.12.0] - 2026-10-02
6
+ ### Breaking changes
7
+
8
+ - `.actions` is removed; compose a `<menu>` (or `<ul>`) with `cluster` for a row, or `stack list-reset` for a vertical list.
9
+ - `.navbar-nav` is removed; the horizontal link list is a `.cluster` with the framework `--gap`.
10
+ - `.dialog-confirmation` is removed; compose `.media` with `.dialog-icon`, then `<footer class="bleed background-subtle cluster justify-content-space-between">` (recipe in `docs/pages/components/dialog.md`).
11
+ - The `dialog.modal` body `<footer>` has no layout of its own; compose its row as `<footer class="cluster justify-content-end">`, as in the drawer.
12
+ - `--modal-header-bg` is removed; put a `.background-*` utility on the `dialog.modal > header` band.
13
+ - `.form-actions` no longer lays out its row; write `class="cluster form-actions"` (`--form-actions-justify` and `--form-actions-align` still apply).
14
+ - `.form-actions` drops its top margin and `--form-actions-margin-block-start`; space it from the fields with `.stack` on the form.
15
+ - `.justify-content-*` no longer sets `--cluster-justify`, so it aligns only its own element, never a nested `.cluster`.
16
+ - `.card` header and footer rows drop to zero specificity: `.media`, `.cluster`, `.form-actions` and `.justify-content-*` on a slot now take over its layout.
17
+ - `--font-width-dense` is removed; set `font-stretch` on an element that should render condensed.
18
+ - A theme sets `--control-pad-x-sm` / `-md` / `-lg` instead of `--control-pad-x`, which `.sm`/`.lg` and `.compact`/`.spacious` now select from.
19
+ - A theme that sets its own control steps re-selects them in its block to work as a nested island (recipe in `docs/pages/foundations/tokens.md`).
20
+
21
+ ### Added
22
+
23
+ - `actual-css contrast [--theme FILE]` (Bun) measures a theme's soft, focus, invalid-focus and inverse pairs in each declared scheme, and exits 1 on a miss.
24
+ - `.tight` and `.loose` set the inherited `--gap` to `--space-20` / `--space-50` alone, without the padding or control size of `.compact` / `.spacious`.
25
+ - `docs/pages/guides/upgrading.md` lists the edits a 0.11 project needs for 0.12.
26
+ - `.items-baseline` aligns children on their first text baseline and sets `--items-align`, completing the `.items-*` series.
27
+
28
+ ### Changed
29
+
30
+ - An action row composed from `.cluster` inherits the framework `--gap` (0.75rem); the removed `.actions` set 0.5rem. Use `.tight` for the tighter rhythm.
31
+ - `.cluster` removes the native list chrome (`margin`, `padding`, `list-style`) from a `ul`, `ol` or `menu` it is applied to; the element stays a list in the DOM.
32
+ - A heading that is the first child beside a leading `.dialog-icon` in a `.media` row centers on the icon anywhere, not only in a dialog.
33
+ - A `dialog.modal` or `.drawer` header gives back its corner-close room when the dialog contains no `.close`; without `:has()` the room stays.
34
+ - `.compact` and `.spacious` no longer set `font-stretch`: density changes rhythm and geometry, never typography.
35
+ - `.compact` and `.spacious` select `--control-pad-x-sm` / `-lg`, so density controls get narrower or wider, not only shorter or taller.
36
+ - `.sm` controls use the shared `--control-pad-x-sm` step: 13px of inline padding instead of 14px.
37
+ - `.card.compact` lowers `--card-gap` to `--space-20` along with `--card-pad`.
38
+ - `.nav-list` rows sit `--space-10` apart instead of `--space-20`, so a vertical nav reads as one list.
39
+ - `.topbar` lays out its default row at zero specificity, so `topbar cluster` hands the row to `.cluster`.
40
+ - The WCAG and OKLCH color math moves from `scripts/utils/color.js` to `src/tooling/color.js`.
41
+ - `report:theme-contrast` labels a dark-only preset (`dim`, `glass`, `indigo`, `neon`) as dark instead of light.
42
+
43
+ ### Fixed
44
+
45
+ - `actual-css contrast` counts a resting soft pair under 4.5:1 as a miss; it only gated the hovered pair.
46
+ - The `design` and `contrast` examples run `bunx --bun actual-css`: plain `bunx` honors the CLI's Node shebang and stops on "needs Bun".
47
+ - `dialog.modal.scrollable` lays the body wrapper out as a flex column: a structural header or footer keeps its size and every other region scrolls, so a modal with an external `dialog > header` no longer collapses its footer to zero.
48
+ - `--dialog-icon-size` and `--dialog-icon-glyph-size` are read, not declared, on `.dialog-icon`, so an override on the icon's media row or the dialog moves the circle and the heading beside it together.
49
+ - An `.avatar-stack` avatar layers its fill over `--surface-opaque`, so a translucent fill no longer shows the neighbour it overlaps.
50
+ - `prefers-reduced-motion` also resets `::backdrop`, so a modal or drawer scrim no longer fades when the user reduces motion.
51
+
52
+ ## [0.11.1] - 2026-09-30
53
+
54
+ ### Added
55
+
56
+ - `dialog.modal > header` provides aligned icon/title/action chrome through `--modal-header-bg`; modal body wrappers expose `--modal-pad` and support `.bleed` bands.
57
+ - `actual-css design` (Bun) exports a theme to Figma and Penpot tokens; see `docs/pages/guides/design-tools.md`.
58
+ - `actual-css design` writes a Penpot plugin that builds Button, Input, Badge, Alert and Card bound to those tokens.
59
+ - Soft fills and borders export as recipe tokens named `<variant>-<intent>-<role>` (`soft-danger-bg`).
60
+ - `scripts/serve.js --cors` serves the repository to another origin, such as penpot.app loading a local plugin.
61
+ - `--meter-track` sets the `.meter` track, matching `--progress-track`.
62
+ - `--close-bg` sets the dialog corner `.close` background, so a dialog over a painted band can drop the default chip.
63
+ - `--close-color` and `--close-hover-color` set the X ink at rest and on hover, so a bare X can take a painted band's foreground.
64
+ - `--close-hover-overlay` routes the `.close` hover/active wash (matching `--btn-hover-overlay`); the modal/drawer corner sets it transparent so only the ink changes.
65
+
66
+ ### Changed
67
+
68
+ - `dialog.modal` is borderless: the raised surface and shadow define the panel, so a full-bleed header, footer, or hero band no longer meets a hard edge; a forced-colors border keeps the outline.
69
+
70
+ ### Fixed
71
+
72
+ - A corner `.close` that is a direct child of `dialog.modal > header` reserves inline room for itself; previously only the wrapper `<header>` did, so a long chrome title could run under it.
73
+ - `dialog.modal` derives one `--dialog-inner-radius` for the body wrapper, the header band, and the `.dialog-confirmation` footer, so an edge band keeps the panel corner instead of taking its own radius.
74
+ - The `.dialog-confirmation` action band spreads a two-action decision to its edges, keeping a cancel action apart from the committing one.
75
+ - `.dialog-confirmation` centers its leading icon on the title while keeping supporting copy in the same text column.
76
+ - `.btn` and the `.file` selector button take their borders out of the block padding, so they match `.input` height at every size instead of standing 2px taller outside a `.join`.
77
+ - `tests/browser/control-geometry.test.js` measures controls outside a `.join`, whose stretch had hidden the mismatch.
5
78
 
6
79
  ## [0.11.0] - 2026-09-30
7
80
 
package/README.md CHANGED
@@ -1,7 +1,14 @@
1
+ <picture>
2
+ <source media="(prefers-color-scheme: dark)" srcset="docs/brand/logo-dark.svg">
3
+ <img src="docs/brand/logo-light.svg" alt="Actual CSS" width="380">
4
+ </picture>
5
+
1
6
  # Actual CSS
2
7
 
3
8
  Plain CSS component framework for new projects. Semantic classes, shared variants, small tokens, theme hooks, and progressive enhancement.
4
9
 
10
+ Documentation: <https://lekoala.github.io/actual-css/>
11
+
5
12
  Actual CSS claims a documented set of global class names; the package publishes
6
13
  it as [`actual-css/reserved-classes.json`](reserved-classes.json).
7
14
 
@@ -42,6 +49,10 @@ Flatten the composition for production with
42
49
  resolves package subpaths and relative files, then inlines them without
43
50
  transpiling modern CSS.
44
51
 
52
+ Hand your theme to designers with `bunx --bun actual-css design --theme theme.css --out design/`:
53
+ Figma and Penpot tokens, plus a Penpot plugin that builds the core components.
54
+ See [Design tools](docs/pages/guides/design-tools.md).
55
+
45
56
  ### Full bundle (zero-config)
46
57
 
47
58
  The bare `actual-css` entrypoint and `actual-css/full` both resolve to the
@@ -53,7 +64,7 @@ size is not worth optimizing:
53
64
  ```
54
65
 
55
66
  ```html
56
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/actual-css@0.11/dist/actual.full.min.css">
67
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/actual-css@0.12/dist/actual.full.min.css">
57
68
  ```
58
69
 
59
70
  ## Usage
@@ -73,8 +84,7 @@ Variants such as `.solid`, `.soft`, `.outline`, and `.surface` are shared by com
73
84
 
74
85
  Size variants `.sm` and `.lg` scale typography and participating component
75
86
  geometry consistently. Density contexts `.compact` and `.spacious` change
76
- spacing and geometry without changing font size or icons; `.compact` may
77
- slightly narrow typefaces that support a width axis.
87
+ spacing and geometry without changing font size, font width or icons.
78
88
 
79
89
  ## Public Class Grammar
80
90
 
@@ -94,7 +104,7 @@ Undocumented `is-*` classes are runtime internals.
94
104
 
95
105
  **UI components** — dialog, drawer, flyout, tooltip, tabs, scrollspy, context menus, and other components that rely on JavaScript or modern platform behavior.
96
106
 
97
- **Patterns** — actions, navbar, and overline. These are regular source files and can be imported only when needed.
107
+ **Patterns** — navbar and overline. These are regular source files and can be imported only when needed.
98
108
 
99
109
  **Layout primitives** — `.stack`, `.cluster`, `.grid`, `.switcher`, `.center`, `.media`, `.frame`, `.app-shell`, `.sidebar-layout`, and `.container-query`.
100
110
 
@@ -127,7 +137,7 @@ registries:
127
137
  * **Full runtime, zero-config** — every built-in enhancer, compiled:
128
138
 
129
139
  ```html
130
- <script src="https://cdn.jsdelivr.net/npm/actual-css@0.11/dist/actual.full.js" type="module"></script>
140
+ <script src="https://cdn.jsdelivr.net/npm/actual-css@0.12/dist/actual.full.js" type="module"></script>
131
141
  ```
132
142
 
133
143
  * **Your own build** — copy the package's `src/js/full.js` as your entry,
@@ -160,6 +170,20 @@ Actual CSS does not currently ship a separate compatibility build. It is designe
160
170
 
161
171
  For more conservative fallbacks, import and compose the source entrypoints directly.
162
172
 
173
+ ## Versioning
174
+
175
+ Actual CSS is before 1.0:
176
+
177
+ * A minor release (`0.11` → `0.12`) may remove or rename classes and hooks. Each
178
+ one ships an upgrade guide; the current one is
179
+ [Upgrading to 0.12](docs/pages/guides/upgrading.md).
180
+ * A patch release (`0.11.0` → `0.11.1`) keeps every class and hook. It fixes
181
+ bugs and may add hooks, so a fix can still move a rendering by a few pixels.
182
+
183
+ The floating `@0.11` CDN path takes patches automatically. Pin the exact
184
+ version (`actual-css@0.12.1`) when the rendering must not change without a
185
+ review.
186
+
163
187
  ## Browser support
164
188
 
165
189
  Actual CSS is built around progressive enhancement.
package/components.json CHANGED
@@ -18,17 +18,6 @@
18
18
  "open"
19
19
  ]
20
20
  },
21
- {
22
- "name": "actions",
23
- "source": "src/css/components/actions.css",
24
- "cssImport": "actual-css/css/components/actions",
25
- "classes": [
26
- "actions"
27
- ],
28
- "internalHooks": [
29
- "--gap"
30
- ]
31
- },
32
21
  {
33
22
  "name": "alert",
34
23
  "source": "src/css/components/alert.css",
@@ -135,7 +124,8 @@
135
124
  "source": "src/css/components/bleed.css",
136
125
  "cssImport": "actual-css/css/components/bleed",
137
126
  "classes": [
138
- "bleed"
127
+ "bleed",
128
+ "stack"
139
129
  ],
140
130
  "publicHooks": [
141
131
  "--bleed-pad"
@@ -195,9 +185,9 @@
195
185
  "--btn-bg",
196
186
  "--btn-fg",
197
187
  "--btn-border",
198
- "--btn-default-hover-bg",
199
188
  "--btn-border-block-end-color",
200
189
  "--btn-border-block-end-width",
190
+ "--btn-border-block",
201
191
  "--spinner-width"
202
192
  ],
203
193
  "states": [
@@ -262,7 +252,11 @@
262
252
  ],
263
253
  "publicHooks": [
264
254
  "--close-size",
265
- "--close-icon-size"
255
+ "--close-icon-size",
256
+ "--close-bg",
257
+ "--close-color",
258
+ "--close-hover-color",
259
+ "--close-hover-overlay"
266
260
  ]
267
261
  },
268
262
  {
@@ -289,6 +283,7 @@
289
283
  "internalHooks": [
290
284
  "--drawer-closed-translate",
291
285
  "--drawer-focus-bleed",
286
+ "--drawer-close-reserve",
292
287
  "--drawer-motion-duration"
293
288
  ],
294
289
  "states": [
@@ -444,6 +439,7 @@
444
439
  "meter"
445
440
  ],
446
441
  "publicHooks": [
442
+ "--meter-track",
447
443
  "--meter-value",
448
444
  "--bar-height"
449
445
  ]
@@ -453,21 +449,24 @@
453
449
  "source": "src/css/components/modal.css",
454
450
  "cssImport": "actual-css/css/components/modal",
455
451
  "classes": [
456
- "dialog-confirmation",
457
452
  "dialog-icon",
458
453
  "had-scrollbar",
459
454
  "has-modal-open",
460
455
  "is-static",
456
+ "media",
461
457
  "modal",
462
458
  "scrollable"
463
459
  ],
464
460
  "publicHooks": [
465
461
  "--modal-size",
462
+ "--modal-pad",
466
463
  "--dialog-viewport-gap",
467
464
  "--dialog-icon-size",
468
465
  "--dialog-icon-glyph-size"
469
466
  ],
470
467
  "internalHooks": [
468
+ "--dialog-inner-radius",
469
+ "--dialog-close-reserve",
471
470
  "--dialog-focus-bleed",
472
471
  "--dialog-viewport-block",
473
472
  "--dialog-viewport-gap-default",
@@ -485,8 +484,7 @@
485
484
  "nav-link",
486
485
  "nav-list",
487
486
  "navbar",
488
- "navbar-brand",
489
- "navbar-nav"
487
+ "navbar-brand"
490
488
  ],
491
489
  "internalHooks": [
492
490
  "--gap"