actual-css 0.9.2 → 0.10.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.
- package/CHANGELOG.md +96 -0
- package/README.md +65 -44
- package/components.json +33 -13
- package/dist/actual.full.css +585 -499
- package/dist/actual.full.js +1 -1
- package/dist/actual.full.min.css +1 -1
- package/docs/design-notes/app-ui.md +1 -1
- package/docs/design-notes/column-layout.md +103 -520
- package/docs/design-notes/forced-colors.md +12 -1
- package/docs/design-notes/naming.md +1 -1
- package/docs/design-notes/surface-reparenting.md +8 -9
- package/docs/navigation.json +2 -0
- package/docs/pages/components/accordion.md +55 -1
- package/docs/pages/components/alert.md +9 -15
- package/docs/pages/components/badge.md +6 -7
- package/docs/pages/components/bleed.md +42 -0
- package/docs/pages/components/button.md +30 -4
- package/docs/pages/components/card.md +21 -86
- package/docs/pages/components/close.md +48 -0
- package/docs/pages/components/data-list.md +26 -1
- package/docs/pages/components/dialog.md +16 -16
- package/docs/pages/components/drawer.md +9 -9
- package/docs/pages/components/navbar.md +5 -5
- package/docs/pages/components/spinner.md +3 -3
- package/docs/pages/enhancements/overview.md +5 -0
- package/docs/pages/enhancements/tooltip.md +3 -1
- package/docs/pages/examples/overview.md +2 -1
- package/docs/pages/forms/choice-cards.md +39 -0
- package/docs/pages/forms/combobox.md +23 -11
- package/docs/pages/forms/joined-controls.md +2 -5
- package/docs/pages/forms/overview.md +6 -0
- package/docs/pages/foundations/theming.md +64 -18
- package/docs/pages/foundations/tokens.md +28 -10
- package/docs/pages/guides/introduction.md +15 -23
- package/docs/pages/guides/modular-import.md +53 -6
- package/docs/pages/guides/progressive-enhancement.md +6 -3
- package/docs/pages/guides/tailwind.md +17 -5
- package/docs/pages/layout/column-layout.md +92 -54
- package/docs/pages/layout/media.md +1 -1
- package/docs/pages/layout/overview.md +1 -1
- package/docs/pages/utilities/overview.md +1 -1
- package/docs/pages/utilities/sizing-wrapping.md +5 -3
- package/llms.txt +24 -4
- package/package.json +6 -6
- package/reserved-classes.json +5 -30
- package/skills/actual-css/PROJECT.md.example +65 -0
- package/skills/actual-css/README.md +64 -0
- package/skills/actual-css/SKILL.md +234 -0
- package/skills/actual-css/references/accessibility.md +44 -0
- package/skills/actual-css/references/api-and-vocabulary.md +94 -0
- package/skills/actual-css/references/enhancements.md +59 -0
- package/skills/actual-css/references/forms.md +49 -0
- package/skills/actual-css/references/layout-and-theming.md +82 -0
- package/skills/actual-css/references/review-checklist.md +51 -0
- package/skills/actual-css/scripts/inspect-actual-css.mjs +171 -0
- package/src/css/components/accordion.css +44 -7
- package/src/css/components/alert.css +23 -43
- package/src/css/components/app-nav.css +9 -0
- package/src/css/components/badge.css +11 -39
- package/src/css/components/bleed.css +79 -0
- package/src/css/components/button.css +6 -17
- package/src/css/components/card.css +7 -40
- package/src/css/components/close.css +91 -0
- package/src/css/components/data-list.css +18 -0
- package/src/css/components/drawer.css +15 -56
- package/src/css/components/fab.css +10 -0
- package/src/css/components/flyout.css +1 -0
- package/src/css/components/index.css +2 -0
- package/src/css/components/join.css +36 -20
- package/src/css/components/menu.css +12 -0
- package/src/css/components/modal.css +10 -57
- package/src/css/components/navbar.css +27 -0
- package/src/css/core/focus.css +9 -3
- package/src/css/core/theme.css +25 -43
- package/src/css/core/tokens.css +1 -1
- package/src/css/core/variants.css +3 -33
- package/src/css/forms/choice-card.css +74 -4
- package/src/css/forms/choice.css +2 -3
- package/src/css/forms/control.css +15 -8
- package/src/css/forms/custom-select.css +4 -4
- package/src/css/forms/native.css +4 -4
- package/src/css/forms/range.css +23 -8
- package/src/css/forms/switch.css +2 -3
- package/src/css/layout/app-layout.css +1 -1
- package/src/css/layout/column-layout.css +26 -111
- package/src/css/utilities/extra.css +7 -6
- package/src/js/dialog.js +95 -24
- package/src/js/enhance.js +7 -3
- package/src/js/escape.js +1 -0
- package/src/js/flyout.js +10 -1
- package/src/js/focus-group.js +2 -1
- package/src/js/keys.js +14 -0
- package/src/js/menu.js +2 -1
- package/src/js/status.js +19 -0
- package/src/js/surface.js +12 -8
- package/src/js/tab.js +2 -1
- package/src/js/tooltip.js +18 -1
- package/src/js/validation.js +5 -6
- package/dist/actual.css +0 -876
- package/dist/actual.js +0 -1
- package/dist/actual.min.css +0 -1
|
@@ -30,6 +30,12 @@ an essential shape, state, or affordance.
|
|
|
30
30
|
|
|
31
31
|
## Pattern: custom property + single override
|
|
32
32
|
|
|
33
|
+
The hook-only form below is fine until an application overrides the hook: the
|
|
34
|
+
override sits at the same specificity, loads after the framework, and wins the
|
|
35
|
+
variable — leaving a non-system fill the browser then remaps to `Canvas`. For
|
|
36
|
+
a masked marker, write the forced value on the property itself so no hook
|
|
37
|
+
override can take it away (accordion) — same for range track/thumb fills.
|
|
38
|
+
|
|
33
39
|
```css
|
|
34
40
|
.component {
|
|
35
41
|
--cmp-marker-color: var(--text-muted);
|
|
@@ -48,6 +54,11 @@ an essential shape, state, or affordance.
|
|
|
48
54
|
.component {
|
|
49
55
|
--cmp-marker-color: CanvasText;
|
|
50
56
|
}
|
|
57
|
+
|
|
58
|
+
/* Masked markers: pin the property, not just the hook. */
|
|
59
|
+
.component::marker {
|
|
60
|
+
background-color: CanvasText;
|
|
61
|
+
}
|
|
51
62
|
}
|
|
52
63
|
```
|
|
53
64
|
|
|
@@ -104,7 +115,7 @@ remapping is perfect:
|
|
|
104
115
|
|
|
105
116
|
- `.card` — `background: Canvas`, `color: CanvasText` are already the defaults
|
|
106
117
|
- `.flyout` / `.menu` — `Canvas`/`CanvasText` for content, `ButtonText` for borders
|
|
107
|
-
- `.
|
|
118
|
+
- `.breadcrumb` — pure remapping gets everything right
|
|
108
119
|
- `.status-bar` — `CanvasText` on `Canvas` background
|
|
109
120
|
|
|
110
121
|
The only forced-colors rules that should remain after a full audit are the ones
|
|
@@ -47,7 +47,7 @@ never about opting in.
|
|
|
47
47
|
- **Base** (`utilities/base.css`) is a curated set of common ergonomic
|
|
48
48
|
shortcuts (`.overflow-auto`, `.gap-none`, `.text-nowrap`, `.px`, `.py`).
|
|
49
49
|
- **Extra** (`utilities/extra.css`) uses explicit property/value names
|
|
50
|
-
(`.overflow-hidden`, `.padding-context`, `.
|
|
50
|
+
(`.overflow-hidden`, `.padding-context`, `.flex-nowrap`).
|
|
51
51
|
|
|
52
52
|
Call them base and extra, after the files. "Optional" is the wrong word for
|
|
53
53
|
either: it reads as a layer an author has to opt into, which is true of every
|
|
@@ -20,8 +20,8 @@ every scope that reached it *by inheritance*. The panel was styled by one set of
|
|
|
20
20
|
ancestors while closed, and by a different set from the moment it became
|
|
21
21
|
visible.
|
|
22
22
|
|
|
23
|
-
Actual leans on inheritance deliberately: theme islands, density,
|
|
24
|
-
|
|
23
|
+
Actual leans on inheritance deliberately: theme islands, density, and the
|
|
24
|
+
custom properties an application scopes to its own containers all
|
|
25
25
|
travel that way. So this was not one bug about themes. It was the same bug in as
|
|
26
26
|
many forms as there are inherited contexts.
|
|
27
27
|
|
|
@@ -30,13 +30,12 @@ many forms as there are inherited contexts.
|
|
|
30
30
|
Chrome, one `.flyout` per scope, values read off the panel before and after the
|
|
31
31
|
click that opens it:
|
|
32
32
|
|
|
33
|
-
| Scope | Closed
|
|
34
|
-
| ------------------------- |
|
|
35
|
-
| `[data-theme="dark"]` | `background: rgb(30, 26, 35)`
|
|
36
|
-
| `.sm` | `--control-size: 2rem`
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
| `.sm` inside a `<dialog>` | `--control-size: 2rem` | `2.375rem` |
|
|
33
|
+
| Scope | Closed | Open |
|
|
34
|
+
| ------------------------- | ----------------------------- | -------------------- |
|
|
35
|
+
| `[data-theme="dark"]` | `background: rgb(30, 26, 35)` | `rgb(255, 255, 255)` |
|
|
36
|
+
| `.sm` | `--control-size: 2rem` | `2.375rem` |
|
|
37
|
+
| app-scoped `--app-accent` | `rgb(1, 2, 3)` | *(unset)* |
|
|
38
|
+
| `.sm` inside a `<dialog>` | `--control-size: 2rem` | `2.375rem` |
|
|
40
39
|
|
|
41
40
|
Every context broke. Three consequences were worth stating plainly:
|
|
42
41
|
|
package/docs/navigation.json
CHANGED
|
@@ -116,4 +116,58 @@ The end marker is a shared token-based chevron; swapping it for a local icon is
|
|
|
116
116
|
## CSS hooks
|
|
117
117
|
|
|
118
118
|
- `--accordion-radius` — outer corner radius.
|
|
119
|
-
- `--accordion-
|
|
119
|
+
- `--accordion-pad` — inset of the summary row and the panel. The panel relays it as `--surface-pad`, so a direct `.bleed` child of the panel reaches the item's sides and bottom corners (never the summary); `.flush` drops the inline half and the relay with it.
|
|
120
|
+
- `--accordion-marker-color` — color of the end marker; it reinforces to the summary text color on hover. In forced-colors mode the marker is pinned to `CanvasText` on the property itself, so an application override of the hook cannot leave a `Canvas`-remapped fill.
|
|
121
|
+
- `--accordion-marker-size` — edge length of the end marker.
|
|
122
|
+
|
|
123
|
+
### Replacing the marker
|
|
124
|
+
|
|
125
|
+
The marker is a masked box: `--accordion-marker-color` fills it and the chevron
|
|
126
|
+
mask clips it to the glyph. A background, ring, or shadow set on it is clipped
|
|
127
|
+
to the same silhouette, so a decorated marker — a chevron inside a pill — has
|
|
128
|
+
to be a real element: hide the built-in one and put a
|
|
129
|
+
`<span class="marker" aria-hidden="true"></span>` at the end of the summary. The
|
|
130
|
+
pill is the span; the chevron is its pseudo-element, which reads the same color
|
|
131
|
+
hook, so the hover reinforcement carries over. The forced-colors pin does not
|
|
132
|
+
carry over through the hook — an application hook override at the same
|
|
133
|
+
specificity loads after the framework and would win the variable — so the
|
|
134
|
+
recipe repeats it on its own property:
|
|
135
|
+
|
|
136
|
+
```css
|
|
137
|
+
.accordion.custom-marker summary::after {
|
|
138
|
+
display: none;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.accordion.custom-marker .marker {
|
|
142
|
+
display: grid;
|
|
143
|
+
place-items: center;
|
|
144
|
+
margin-inline-start: auto;
|
|
145
|
+
padding: var(--space-10);
|
|
146
|
+
border-radius: 50%;
|
|
147
|
+
background: var(--surface-subtle);
|
|
148
|
+
transition: transform var(--duration);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.accordion.custom-marker .marker::before {
|
|
152
|
+
content: "";
|
|
153
|
+
inline-size: var(--accordion-marker-size);
|
|
154
|
+
block-size: var(--accordion-marker-size);
|
|
155
|
+
background-color: var(--accordion-marker-color);
|
|
156
|
+
-webkit-mask: var(--icon-chevron) center / contain no-repeat;
|
|
157
|
+
mask: var(--icon-chevron) center / contain no-repeat;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.accordion.custom-marker summary:hover .marker {
|
|
161
|
+
--accordion-marker-color: currentColor;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.accordion.custom-marker details[open] .marker {
|
|
165
|
+
transform: rotate(180deg);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
@media (forced-colors: active) {
|
|
169
|
+
.accordion.custom-marker .marker::before {
|
|
170
|
+
background-color: CanvasText;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
```
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
- Supports intent colors.
|
|
6
6
|
- Supports longer text and lists.
|
|
7
7
|
- Links inherit alert color by default.
|
|
8
|
-
- Alerts are soft by default. Use `.surface` for neutral chrome with the intent only in the ink, `.solid` or `.outline` when the message needs stronger or quieter emphasis
|
|
8
|
+
- Alerts are soft by default. Use `.surface` for neutral chrome with the intent only in the ink, `.solid` or `.outline` when the message needs stronger or quieter emphasis.
|
|
9
9
|
- Use `<menu class="actions cluster">` for alert action lists.
|
|
10
10
|
- Use `role="alert"` only when the alert is injected dynamically and should be announced.
|
|
11
11
|
- Not a toast.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
- A title and a description are plain siblings: the alert owns the small space between its direct content blocks, so neither needs a wrapper. Nested content keeps its own rhythm — wrap several paragraphs in `.prose`, or a differently spaced group in `.stack`, when the message needs a rhythm of its own.
|
|
14
14
|
- Alerts may include a decorative leading icon. Use `.alert-icon` on the icon element; the rest of the content flows into the remaining text column.
|
|
15
15
|
- Use `.compact` or `.spacious` for density changes. The inline padding stays stable.
|
|
16
|
-
- Use `.
|
|
16
|
+
- Use a [`.close`](close.md) button to make the alert dismissible. It is a direct trailing child in standard alerts and lives inside `.alert-title` in admonitions; the alert makes it compact.
|
|
17
17
|
|
|
18
18
|
Because alerts are soft by default, adding `.soft` to an intent (`.alert.soft.primary`,
|
|
19
19
|
`.alert.soft.danger`, …) is a no-op: it already resolves to a soft version of that
|
|
@@ -26,14 +26,13 @@ itself needs to change, not `.soft`.
|
|
|
26
26
|
| ---------------- | ----------- | ----------------------------------------------- |
|
|
27
27
|
| `.alert` | Component | Inline status surface; soft by default. |
|
|
28
28
|
| `.alert-icon` | Composition | Decorative leading icon, in the first column. |
|
|
29
|
-
| `.
|
|
29
|
+
| `.close` | Composition | Dismiss button, in the last column. |
|
|
30
30
|
| `.alert-title` | Composition | Admonition title bar; hosts the dismiss button. |
|
|
31
31
|
| `.alert-body` | Composition | Admonition body on the page surface. |
|
|
32
32
|
| `.callout` | Variant | Leading-edge flag; owns the border geometry. |
|
|
33
33
|
| `.admonition` | Variant | Tinted title bar, body on the page surface. |
|
|
34
34
|
| Shared intents | Intent | `.primary`, `.secondary`, `.success`, … |
|
|
35
35
|
| Shared variants | Variant | `.solid`, `.outline`, `.surface`. |
|
|
36
|
-
| `.inverted` | Surface | Inverse surface, any intent. |
|
|
37
36
|
| Density contexts | Density | Descendant rhythm; inline padding stays stable. |
|
|
38
37
|
|
|
39
38
|
## Basic usage
|
|
@@ -101,7 +100,7 @@ intent treatment when the color itself carries the meaning.
|
|
|
101
100
|
|
|
102
101
|
## Trailing action
|
|
103
102
|
|
|
104
|
-
The grid pins `.alert-icon` and `.
|
|
103
|
+
The grid pins `.alert-icon` and `.close` to the outer columns. A
|
|
105
104
|
trailing link or button is content, not anatomy, so it lives in the text column:
|
|
106
105
|
wrap the row in a `.cluster` and push the two ends apart. Same recipe as any
|
|
107
106
|
split / spread row — there is no `.alert-action` class.
|
|
@@ -129,10 +128,6 @@ center.
|
|
|
129
128
|
I'm a surface alert — theme chrome, intent in the ink
|
|
130
129
|
</div>
|
|
131
130
|
|
|
132
|
-
<div class="alert inverted" role="alert">
|
|
133
|
-
I'm an inverted alert <a href="#">with a link</a>
|
|
134
|
-
</div>
|
|
135
|
-
|
|
136
131
|
<div class="alert danger compact" role="alert">
|
|
137
132
|
I'm an error in a compact context
|
|
138
133
|
</div>
|
|
@@ -153,7 +148,7 @@ center.
|
|
|
153
148
|
|
|
154
149
|
## Dismiss
|
|
155
150
|
|
|
156
|
-
|
|
151
|
+
Add a `.close` button to let a user remove an inline alert. Inside an alert it is compact and at reduced opacity, and it follows the alert's ink with any intent. The runtime `--dismiss` command removes the alert — no custom script.
|
|
157
152
|
|
|
158
153
|
```html demo
|
|
159
154
|
<div class="alert warning" id="warning-alert">
|
|
@@ -162,7 +157,7 @@ Use `.alert-dismiss` to let a user remove an inline alert. The button is transpa
|
|
|
162
157
|
<p>Something needs your attention.</p>
|
|
163
158
|
|
|
164
159
|
<button
|
|
165
|
-
class="
|
|
160
|
+
class="close"
|
|
166
161
|
type="button"
|
|
167
162
|
commandfor="warning-alert"
|
|
168
163
|
command="--dismiss"
|
|
@@ -171,14 +166,14 @@ Use `.alert-dismiss` to let a user remove an inline alert. The button is transpa
|
|
|
171
166
|
</div>
|
|
172
167
|
```
|
|
173
168
|
|
|
174
|
-
In an admonition, place `.
|
|
169
|
+
In an admonition, place `.close` inside `.alert-title`; it rides the inline end of the title bar:
|
|
175
170
|
|
|
176
171
|
```html
|
|
177
172
|
<div class="alert admonition warning" id="notice">
|
|
178
173
|
<div class="alert-title">
|
|
179
174
|
<span>Warning</span>
|
|
180
175
|
<button
|
|
181
|
-
class="
|
|
176
|
+
class="close"
|
|
182
177
|
type="button"
|
|
183
178
|
commandfor="notice"
|
|
184
179
|
command="--dismiss"
|
|
@@ -261,8 +256,7 @@ An admonition is a structured box with a tinted title bar, an optional icon, and
|
|
|
261
256
|
- `--alert-pad-block` — block padding.
|
|
262
257
|
- `--alert-font-size` — base font size.
|
|
263
258
|
- `--alert-icon-size` — size of a leading `.alert-icon`.
|
|
264
|
-
- `--
|
|
265
|
-
- `--alert-dismiss-icon-size` — size of the dismiss glyph.
|
|
259
|
+
- `--close-size` / `--close-icon-size` — the alert declares compact values for its `.close`; set them on the alert to change them.
|
|
266
260
|
- `--alert-radius` — corner radius, when the default `--radius-lg` does not fit.
|
|
267
261
|
- `--alert-border-inline-start-color` / `--alert-border-inline-start-width` — extension points for a callout-style colored flag on the leading edge instead of a uniform border.
|
|
268
262
|
|
|
@@ -177,21 +177,20 @@ Override the existing hooks when the three-step scale does not fit the content.
|
|
|
177
177
|
|
|
178
178
|
## Removable tag pattern
|
|
179
179
|
|
|
180
|
-
Use `.badge soft` for tag visuals. Add a direct
|
|
180
|
+
Use `.badge soft` for tag visuals. Add a direct [`.close`](close.md) button only when the tag can actually be removed. There is no separate chip component.
|
|
181
181
|
For a compact action or filter, use `.btn.sm` instead; badges describe content
|
|
182
182
|
and must not be turned into toggle controls merely to obtain a compact shape.
|
|
183
183
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
used instead.
|
|
184
|
+
Inside a badge the close follows the pill's size, keeps a 24px pointer target,
|
|
185
|
+
and tucks into the padding.
|
|
187
186
|
|
|
188
187
|
```html demo
|
|
189
188
|
<span class="badge primary soft">
|
|
190
189
|
Design
|
|
191
|
-
<button type="button" aria-label="Remove Design"></button>
|
|
190
|
+
<button class="close" type="button" aria-label="Remove Design"></button>
|
|
192
191
|
</span>
|
|
193
192
|
<span class="badge primary soft">
|
|
194
|
-
<button type="button" aria-label="Remove Design"></button>
|
|
193
|
+
<button class="close" type="button" aria-label="Remove Design"></button>
|
|
195
194
|
Design
|
|
196
195
|
</span>
|
|
197
196
|
```
|
|
@@ -204,4 +203,4 @@ used instead.
|
|
|
204
203
|
- `--badge-font-size` — label font size.
|
|
205
204
|
- `--badge-icon-size` — decorative child size; `1em` follows the label by default.
|
|
206
205
|
- `--badge-pad-x` — inline padding. Derived from `--badge-size`, so it stays proportional to the pill; set it to opt out.
|
|
207
|
-
- `--
|
|
206
|
+
- `--close-size` / `--close-icon-size` — the badge declares them for its `.close`; set them on the badge to change them.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Bleed
|
|
2
|
+
|
|
3
|
+
`.bleed` lets a direct child of a padded surface reach its edges. Use it for a
|
|
4
|
+
full-width image, a colored header or footer, or a notice band.
|
|
5
|
+
|
|
6
|
+
It works inside `.card`, `.drawer`, and an accordion panel. The accordion panel
|
|
7
|
+
owns the padding, so place `.bleed` directly inside the panel, after the summary.
|
|
8
|
+
A deeper descendant stays within its wrapper. A modular build imports
|
|
9
|
+
`actual-css/css/components/bleed` alongside the surface component.
|
|
10
|
+
|
|
11
|
+
```html demo
|
|
12
|
+
<article class="card stack" style="--card-max-inline-size: 24rem">
|
|
13
|
+
<img class="bleed" src="https://picsum.photos/seed/actual-css-card/600/300" alt="" />
|
|
14
|
+
<header><h3>Full-width image</h3></header>
|
|
15
|
+
<p>The image reaches the card edges.</p>
|
|
16
|
+
<footer class="bleed" style="background: var(--surface-subtle)">
|
|
17
|
+
<button type="button" class="btn outline">View</button>
|
|
18
|
+
</footer>
|
|
19
|
+
</article>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
An `<img>`, `<picture>`, `<video>`, `<canvas>`, or `<svg>` with `.bleed` expands
|
|
23
|
+
to the surface width. For a responsive image, put `.bleed` on `<picture>`; its
|
|
24
|
+
image fills the picture and is clipped by it.
|
|
25
|
+
|
|
26
|
+
Structural `header`, `footer`, and `figure` bands keep the surface's inner
|
|
27
|
+
padding while their background reaches the edge. Other bands can read the
|
|
28
|
+
relayed inset with `--bleed-pad`:
|
|
29
|
+
|
|
30
|
+
```css
|
|
31
|
+
.status-row {
|
|
32
|
+
padding: var(--bleed-pad);
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The participating surface relays its inset to direct children only. Read
|
|
37
|
+
`--bleed-pad` on one of those children when a custom band needs matching
|
|
38
|
+
padding. An author-defined surface needs its own direct-child relay to join
|
|
39
|
+
this contract.
|
|
40
|
+
|
|
41
|
+
See [Card](card.md), [Drawer](drawer.md), and [Accordion](accordion.md) for
|
|
42
|
+
surface examples.
|
|
@@ -61,10 +61,37 @@ Reach for `.surface` when a secondary action must sit on an opaque, neutral
|
|
|
61
61
|
chip: `.outline` lets whatever is behind it show through, and `.soft` is the
|
|
62
62
|
intent-tinted treatment (its baseline fallback uses `--surface-subtle`).
|
|
63
63
|
|
|
64
|
+
None of the three gives an opaque fill *under* an intent-colored border —
|
|
65
|
+
`.surface` keeps the neutral `--border`, and `.outline` has no fill. Set
|
|
66
|
+
`--ui-bg` on the element for that combination; it is the variant relay every
|
|
67
|
+
component with shared variants reads, so the same declaration works on a badge:
|
|
68
|
+
|
|
69
|
+
```css
|
|
70
|
+
.chip-on-tint {
|
|
71
|
+
--ui-bg: var(--surface);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The rule ties with the variant's own `--ui-bg` on specificity, so load it after
|
|
76
|
+
Actual CSS or import `actual.layer.css`.
|
|
77
|
+
|
|
64
78
|
Transparent treatments (`.outline`, `.ghost`, `.link`) follow the surrounding
|
|
65
|
-
foreground by default, including on a
|
|
66
|
-
intent class still wins: `.danger.outline` uses the danger color in
|
|
67
|
-
context
|
|
79
|
+
foreground by default, including on a band your application paints. A local
|
|
80
|
+
intent class still wins: `.danger.outline` uses the danger color in any
|
|
81
|
+
context, and nothing tunes that color for a surface you paint yourself. For
|
|
82
|
+
intent ink on a dark band, use a `data-theme` island, whose palette is tuned
|
|
83
|
+
for its surface. Filled buttons own their surface and keep their normal intent
|
|
84
|
+
recipe.
|
|
85
|
+
|
|
86
|
+
A dark button (inverse, contrast) is a custom intent on the button itself, so
|
|
87
|
+
every variant keeps working — `.outline` and `.ghost` take the solid ink:
|
|
88
|
+
|
|
89
|
+
```css
|
|
90
|
+
.btn.app-dark {
|
|
91
|
+
--intent: var(--surface-solid);
|
|
92
|
+
--intent-fg: var(--surface);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
68
95
|
|
|
69
96
|
`.btn.link` is a link-style action: it keeps button behavior and states, but
|
|
70
97
|
remains intrinsically sized like text instead of stretching with its layout
|
|
@@ -251,5 +278,4 @@ For exclusive groups, manage a single pressed button:
|
|
|
251
278
|
## CSS hooks
|
|
252
279
|
|
|
253
280
|
- `--btn-radius` — corner radius.
|
|
254
|
-
- `--btn-focus-color` — focus ring base color; the ring itself is derived from it.
|
|
255
281
|
- `--btn-gap` — space between an icon and the label text (default `0.375em`).
|
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
# Card
|
|
2
2
|
|
|
3
|
-
Flexible content container with optional header, body, and footer regions
|
|
3
|
+
Flexible content container with optional header, body, and footer regions.
|
|
4
4
|
|
|
5
5
|
## Class reference
|
|
6
6
|
|
|
7
|
-
| Class
|
|
8
|
-
|
|
|
9
|
-
| `.card`
|
|
10
|
-
| `.raised`
|
|
11
|
-
| `.subtle`
|
|
12
|
-
| `.surface`
|
|
13
|
-
| `.
|
|
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
|
|
63
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
|
136
|
+
<article class="card stack" data-theme="dark">
|
|
202
137
|
<hgroup>
|
|
203
|
-
<h3>
|
|
204
|
-
<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
|
|
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.
|
|
@@ -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.
|