actual-css 0.4.1 → 0.5.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 (74) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +2 -2
  3. package/dist/actual.css +53 -14
  4. package/dist/actual.full.css +300 -91
  5. package/dist/actual.full.js +1 -1
  6. package/dist/actual.full.min.css +1 -1
  7. package/dist/actual.min.css +1 -1
  8. package/docs/design-notes/spacing-units.md +286 -0
  9. package/docs/navigation.json +1 -0
  10. package/docs/pages/components/alert.md +1 -1
  11. package/docs/pages/components/app-navigation.md +2 -0
  12. package/docs/pages/components/badge.md +17 -3
  13. package/docs/pages/components/button.md +9 -2
  14. package/docs/pages/components/card.md +13 -0
  15. package/docs/pages/components/data-list.md +72 -0
  16. package/docs/pages/components/dialog.md +2 -0
  17. package/docs/pages/components/drawer.md +2 -0
  18. package/docs/pages/components/fab.md +2 -0
  19. package/docs/pages/components/meter.md +56 -1
  20. package/docs/pages/components/progress.md +10 -0
  21. package/docs/pages/components/skeleton.md +2 -0
  22. package/docs/pages/components/steps.md +10 -2
  23. package/docs/pages/components/table.md +1 -0
  24. package/docs/pages/enhancements/flyout.md +2 -0
  25. package/docs/pages/enhancements/status-bar.md +10 -1
  26. package/docs/pages/examples/overview.md +2 -1
  27. package/docs/pages/forms/joined-controls.md +2 -0
  28. package/docs/pages/forms/overview.md +1 -1
  29. package/docs/pages/forms/range.md +2 -0
  30. package/docs/pages/forms/states-and-sizes.md +1 -1
  31. package/docs/pages/forms/validation.md +2 -0
  32. package/docs/pages/foundations/philosophy.md +11 -1
  33. package/docs/pages/foundations/tokens.md +7 -3
  34. package/docs/pages/foundations/typography.md +10 -2
  35. package/docs/pages/guides/introduction.md +1 -1
  36. package/docs/pages/layout/scroll-snap.md +2 -0
  37. package/docs/pages/layout/sidebar-layout.md +2 -0
  38. package/docs/pages/layout/topbar.md +2 -0
  39. package/docs/pages/utilities/accessibility.md +18 -0
  40. package/package.json +1 -1
  41. package/scripts/reserved-classes.json +4 -0
  42. package/src/css/components/actions.css +1 -0
  43. package/src/css/components/breadcrumb.css +1 -0
  44. package/src/css/components/data-list.css +27 -0
  45. package/src/css/components/drawer.css +30 -11
  46. package/src/css/components/flyout.css +17 -12
  47. package/src/css/components/index.css +1 -0
  48. package/src/css/components/meter.css +28 -1
  49. package/src/css/components/modal.css +28 -11
  50. package/src/css/components/navbar.css +2 -0
  51. package/src/css/components/pagination.css +1 -0
  52. package/src/css/components/progress.css +5 -0
  53. package/src/css/components/status-bar.css +31 -15
  54. package/src/css/components/steps.css +36 -9
  55. package/src/css/components/surface.css +5 -3
  56. package/src/css/components/tab.css +1 -0
  57. package/src/css/components/tooltip.css +5 -8
  58. package/src/css/core/base.css +7 -1
  59. package/src/css/core/intents.css +6 -0
  60. package/src/css/core/tokens.css +23 -9
  61. package/src/css/core/variants.css +17 -4
  62. package/src/css/forms/form-actions.css +1 -0
  63. package/src/css/forms/form.css +4 -4
  64. package/src/css/layout/cluster.css +1 -0
  65. package/src/css/layout/scroll-snap.css +1 -0
  66. package/src/css/layout/sidebar-layout.css +1 -0
  67. package/src/css/layout/switcher.css +1 -0
  68. package/src/css/layout/topbar.css +1 -0
  69. package/src/css/typography/prose.css +2 -3
  70. package/src/css/utilities/base.css +16 -0
  71. package/src/js/selectors.js +1 -0
  72. package/src/js/status.js +88 -7
  73. package/src/js/surface.js +2 -11
  74. package/src/js/transition.js +20 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,60 @@
3
3
  ## [Unreleased]
4
4
 
5
5
 
6
+ ## [0.5.0] - 2026-09-01
7
+
8
+ ### Added
9
+
10
+ * `surface` shared variant: the page surface with the theme border, intent in the text only.
11
+ Fills the gap between `soft` (always intent-tinted) and `outline` (no fill at all).
12
+ * `--link` is now read by the base `a` rule, so a theme that sets it colors bare links and
13
+ prose links at once. Unset, nothing changes.
14
+ * `touch-target` for small buttons.
15
+ * `data-list` for compact term–value pairs describing the properties of a single object.
16
+ * Segmented `meter`.
17
+ * `intent-color` to apply color based on intent.
18
+ * `demo/templates/motion.html` — a motion catalogue that replays each overlay's
19
+ entry/exit side by side, stretches durations to read the presence curves, and
20
+ simulates reduced motion.
21
+
22
+ ### Changed
23
+
24
+ * `--bar-height` is a public hook. It was classified Internal by mistake while both
25
+ `progress` and `meter` used it as their only thickness mechanism. Size variants stay
26
+ unsupported on those two: a bar keeps its inline size and only changes thickness, which
27
+ the hook expresses better than a three-step scale.
28
+ * Removed the `.field-group + .field-group` sibling margin (breaking, pre-1.0). A component
29
+ cannot know whether its siblings are stacked or gridded; space consecutive groups with
30
+ `.stack` on the form.
31
+ * `steps` now separates the two accented states: `.complete` is a filled marker with an
32
+ accented connector, `[aria-current="step"]` an outlined one with a thicker ring. They were
33
+ visually identical, so a numbered stepper could not show position without a check glyph.
34
+ A step carrying both renders entirely as current, connector and completion glyph included.
35
+ * `status-bar` visibility is driven by the `.is-open` state class instead of `:empty`,
36
+ and `status.clear()` now empties the text and intent only after the exit transition,
37
+ so the bar animates out at the size and color it was shown at. A message dispatched
38
+ during that exit cancels the pending cleanup. An empty message now clears instead of
39
+ opening a blank pill. The runtime also lifts the bar above the mobile software keyboard
40
+ via `visualViewport`. Deferred component cleanup now shares one CSS-transition helper,
41
+ so unrelated or infinite author animations cannot strand a status bar or surface.
42
+ * Removed the generic `--ease` motion token (breaking, pre-1.0). Generic interaction and
43
+ state transitions now use the CSS default `ease` directly; the dialog shake and the
44
+ `actual-dialog` View Transition keep that default deliberately, so no behavior changes.
45
+ * Introduced `--ease-enter` / `--ease-exit` presence curves for one-shot open/close, applied
46
+ to `status-bar`, `modal`, and `drawer`. The drawer exit shortens to `--duration` (entry
47
+ stays `--duration-slow`) and its `::backdrop` follows the panel duration. Flyout, tooltip,
48
+ and all backdrops keep the neutral `ease`; they share a single fast transition list or are
49
+ pure-opacity scrims where the presence pair does not resolve.
50
+
51
+
52
+ ## [0.4.2] - 2026-08-25
53
+
54
+ ### Fixed
55
+
56
+ * `card` + `cluster` regression.
57
+ * Some markup in demos.
58
+
59
+
6
60
  ## [0.4.1] - 2026-08-25
7
61
 
8
62
  ### Added
package/README.md CHANGED
@@ -65,7 +65,7 @@ Add classes to your HTML. Components define the structure, variants change the s
65
65
 
66
66
  Intents such as `.primary`, `.secondary`, `.success`, `.warning`, and `.danger` work across components.
67
67
 
68
- Variants such as `.solid`, `.soft`, and `.outline` are shared by components like buttons, badges, alerts, and cards. `.inverted` is a shared surface modifier: it paints any block with the inverse surface. `.ghost` and `.link` are button-only variants.
68
+ Variants such as `.solid`, `.soft`, `.outline`, and `.surface` are shared by components like buttons, badges, alerts, and cards. `.inverted` is a shared surface modifier: it paints any block with the inverse surface. `.ghost` and `.link` are button-only variants.
69
69
 
70
70
  Size variants `.sm` and `.lg` scale controls consistently.
71
71
 
@@ -77,7 +77,7 @@ Actual CSS uses a small unprefixed class grammar:
77
77
  .component [intent] [variant] [size] [modifier]
78
78
  ```
79
79
 
80
- Components, layout helpers, form helpers, and utilities claim their documented class names. Intents are `.primary`, `.secondary`, `.success`, `.warning`, and `.danger`; shared variants are `.solid`, `.soft`, and `.outline`; `.inverted` is a shared surface modifier; button-only variants are `.ghost` and `.link`; shared sizes are `.sm` and `.lg`.
80
+ Components, layout helpers, form helpers, and utilities claim their documented class names. Intents are `.primary`, `.secondary`, `.success`, `.warning`, and `.danger`; shared variants are `.solid`, `.soft`, `.outline`, and `.surface`; `.inverted` is a shared surface modifier; button-only variants are `.ghost` and `.link`; shared sizes are `.sm` and `.lg`.
81
81
 
82
82
  Undocumented `is-*` classes are runtime internals.
83
83
 
package/dist/actual.css CHANGED
@@ -56,8 +56,8 @@ select {
56
56
  *
57
57
  * Derived: "Theme-derived aliases" and "State tokens" reference intent and
58
58
  * surface tokens and follow the theme; do not hard-code values into them.
59
- * Internal: indicator offsets, --bar-height, --disabled-opacity and the
60
- * like are consumed by components, not authored.
59
+ * Internal: indicator offsets, --disabled-opacity and the like are
60
+ * consumed by components, not authored.
61
61
  *
62
62
  * Component-local hooks and internal state relays live with their
63
63
  * components. See docs/pages/foundations/tokens.md for the public/internal
@@ -81,9 +81,10 @@ select {
81
81
  --font-size-md: 1rem;
82
82
  --font-size-lg: 1.125rem;
83
83
 
84
- /* Spacing — official steps are named in tens so the scale stays open for
85
- application themes to intercalate intermediate values (--space-15,
86
- --space-45…) without colliding with future framework steps. */
84
+ /* Spacing — official steps are named in tens so the scale stays open.
85
+ Actual CSS will never define a --space-* that is not a multiple of 10:
86
+ the intermediate names (--space-15, --space-45…) are reserved for
87
+ applications, and no future framework step can collide with them. */
87
88
  --gap: 0.75rem;
88
89
  --density-space: var(--space-40);
89
90
  --density-compact-size: 1.5rem;
@@ -101,14 +102,25 @@ select {
101
102
  --shadow-popout: 0 0.25rem 0.75rem rgb(0 0 0 / 0.15);
102
103
 
103
104
  /* Motion — see reset.css for the prefers-reduced-motion hard reset.
104
- --duration drives component transitions (hover/focus); the dedicated
105
- animation rates below tune one-shot open/close and decorative loops. */
105
+ --duration scales component transitions (hover/focus); the dedicated
106
+ animation rates below tune one-shot open/close and decorative loops.
107
+ Generic state/interaction motion uses the CSS default `ease` directly
108
+ (registered nowhere). --ease-enter/--ease-exit express the character of
109
+ one-shot presence changes, owned by the open/closed state rules that
110
+ separate them (status-bar, drawer, modal). The pair follows the standard
111
+ M3 rhythm; the more aggressive emphasized-decelerate entrance is
112
+ deliberately not offered because it only pays off on 250–400ms motions,
113
+ beyond this vocabulary. Toggles that share one transition list at
114
+ --duration-fast (flyout, tooltip) and pure-opacity backdrops stay on
115
+ `ease`: at 100ms the curve has almost no resolving time, and a scrim is
116
+ not traveling anywhere. */
106
117
  --duration: 150ms;
107
118
  --duration-fast: 100ms;
108
119
  --duration-slow: 200ms;
109
120
  --duration-spin: 0.75s;
110
121
  --duration-shimmer: 1.2s;
111
- --ease: ease;
122
+ --ease-enter: cubic-bezier(0.2, 0, 0, 1);
123
+ --ease-exit: cubic-bezier(0.4, 0, 1, 1);
112
124
 
113
125
  /* Focus ring — shared by every interactive component's :focus-visible */
114
126
  --focus-outline-color: currentColor;
@@ -126,7 +138,9 @@ select {
126
138
  --backdrop-opacity: 0.45;
127
139
  --backdrop-fill: rgb(0 0 0 / var(--backdrop-opacity));
128
140
 
129
- /* Progress / meter track height */
141
+ /* Bar thickness shared by .progress and .meter — two conceptual variants of
142
+ the same geometry. Public: set it on the element or on an application
143
+ class rather than reaching for a size variant. */
130
144
  --bar-height: 0.65rem;
131
145
 
132
146
  /* Controls — inputs and buttons share --control-size so heights always match.
@@ -449,6 +463,9 @@ select {
449
463
  *
450
464
  * Sits between reset (browser defaults) and prose (rich content scope).
451
465
  * These styles apply everywhere — cards, dialogs, heroes — not only in prose.
466
+ *
467
+ * Public hooks:
468
+ * --link
452
469
  */
453
470
 
454
471
  body {
@@ -458,8 +475,11 @@ body {
458
475
  line-height: var(--line-height);
459
476
  }
460
477
 
478
+ /* Bare links inherit their ink by default, so nothing changes unless a theme
479
+ opts in by setting --link. Because this is an element selector, any component
480
+ rule that colors its own anchors still wins. */
461
481
  a {
462
- color: inherit;
482
+ color: var(--link, inherit);
463
483
  text-underline-offset: 0.18em;
464
484
  }
465
485
 
@@ -543,11 +563,17 @@ small {
543
563
  --intent-fg: var(--neutral-fg);
544
564
  }
545
565
 
566
+ /* Paint an inherited or local intent on a simple foreground element without
567
+ turning the intent classes into general-purpose color utilities. */
568
+ .intent-color {
569
+ color: var(--intent);
570
+ }
571
+
546
572
  /*
547
573
  * Cross-cutting variant token mapping.
548
574
  *
549
- * Variant scope: .solid/.soft/.outline set --ui-* for components that opt into
550
- * shared variants. .inverted is a surface modifier, not a variant: it paints
575
+ * Variant scope: .solid/.soft/.outline/.surface set --ui-* for components that
576
+ * opt into shared variants. .inverted is a surface modifier, not a variant: it paints
551
577
  * the element directly (background/color/border-color) so it works on any bare
552
578
  * block, and remaps the shared --ui-* tokens so participating components
553
579
  * (.card, .navbar, .alert, .badge) invert through their own rules. Loaded
@@ -566,8 +592,10 @@ small {
566
592
  * components may consume --density-* when the density context should affect
567
593
  * their local rhythm. Compact components may consume --density-compact-size.
568
594
  * Components with bespoke sizing (spinner, avatar) define local .sm/.lg;
569
- * applying .sm/.lg to card, dialog, accordion, navbar, table is
570
- * a no-op.
595
+ * applying .sm/.lg to card, dialog, accordion, navbar, table, progress, meter
596
+ * is a no-op. Progress and meter are deliberate: a bar keeps its inline size
597
+ * and only changes thickness, which --bar-height expresses better than a
598
+ * three-step scale.
571
599
  *
572
600
  * Intent list source of truth: intents.css. Components consume --intent* tokens
573
601
  * instead of re-listing intent classes.
@@ -590,6 +618,17 @@ small {
590
618
  --ui-border: var(--intent, currentColor);
591
619
  }
592
620
 
621
+ /* Neutral chrome, intent only in the ink: the page surface with the theme
622
+ border. .soft is the intent-tinted treatment (its baseline fallback uses
623
+ --surface-subtle) and .outline has no fill at all, so neither can express
624
+ it. Deliberately literal — no color-mix enhancement — so this stays the one
625
+ variant that reads exactly as the theme's own surface. */
626
+ .surface {
627
+ --ui-bg: var(--surface);
628
+ --ui-fg: var(--intent, var(--text));
629
+ --ui-border: var(--border);
630
+ }
631
+
593
632
  /* Inverse surface treatment. Paints the element directly (so it works on any
594
633
  bare block) and remaps the shared --ui-* tokens so opt-in components
595
634
  (.card, .navbar) invert through their own rules. Because this loads before