use-wc 1.0.0-pre.73 → 1.0.0-pre.75

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.
@@ -201,7 +201,7 @@
201
201
  }
202
202
 
203
203
  @layer use-theme.selector {
204
- input:is([type="checkbox"], [type="radio"]) {
204
+ input:is([type="checkbox"], [type="radio"]):not([role="switch"]) {
205
205
  all: unset;
206
206
  appearance: none;
207
207
  box-sizing: border-box;
@@ -313,7 +313,7 @@
313
313
 
314
314
  @layer use-theme.link {
315
315
  :is(nav, header, footer, [role="navigation"], [role="menubar"], [role="tablist"], [role="toolbar"]) {
316
- --usewc-effect-link-decoration: var(--usewc-effect-link-chrome-text-decoration);
316
+ --usewc-local-link-decoration-line: var(--usewc-effect-link-chrome-text-decoration);
317
317
  }
318
318
 
319
319
  :is(a:not([class*="appearance-"]), .appearance-a) {
@@ -321,11 +321,23 @@
321
321
  all: unset;
322
322
  }
323
323
 
324
- --usewc-color-link-text: var(--usewc-color-link-text-static);
324
+ /* `--usewc-local-*` names the variables below as rule-scoped plumbing rather than themeable
325
+ tokens — set here to thread the current state (hover/active, chrome context, sidebar) into
326
+ the properties further down, as opposed to the real tokens in `semantic.css` they read
327
+ from. `--usewc-local-link-decoration-color` in particular has to be derived here rather
328
+ than hoisted into `semantic.css`: relative-color syntax reading a `var()` only resolves
329
+ once the referenced custom property is defined on the same element/rule, and
330
+ `--usewc-local-link-text` only ever exists on this one. */
331
+ --usewc-local-link-text: var(--usewc-color-link-text-static);
332
+ --usewc-local-link-decoration-opacity: var(--usewc-effect-link-decoration-opacity);
333
+ --usewc-local-link-decoration-color: oklch(
334
+ from var(--usewc-local-link-text) l c h / var(--usewc-local-link-decoration-opacity)
335
+ );
325
336
  --usewc-effect-outline-width: 0;
326
337
 
327
- color: var(--usewc-color-link-text);
328
- text-decoration: var(--usewc-effect-link-decoration, var(--usewc-effect-link-text-decoration));
338
+ color: var(--usewc-local-link-text);
339
+ text-decoration: var(--usewc-local-link-decoration-line, var(--usewc-effect-link-text-decoration));
340
+ text-decoration-color: var(--usewc-local-link-decoration-color);
329
341
  cursor: pointer;
330
342
  outline: var(--usewc-effect-outline-width) var(--usewc-effect-outline-style) var(--usewc-color-outline);
331
343
  outline-offset: var(--usewc-effect-outline-offset);
@@ -336,7 +348,7 @@
336
348
  }
337
349
 
338
350
  &:is(:hover, :focus-visible) {
339
- --usewc-color-link-text: var(--usewc-color-link-text-hover);
351
+ --usewc-local-link-text: var(--usewc-color-link-text-hover);
340
352
  }
341
353
 
342
354
  &:focus-visible {
@@ -344,12 +356,15 @@
344
356
  }
345
357
 
346
358
  &:active {
347
- --usewc-color-link-text: var(--usewc-color-link-text-active);
359
+ --usewc-local-link-text: var(--usewc-color-link-text-active);
360
+ /* Pressed reads as committed rather than merely hinted at, so the underline matches the
361
+ text exactly here instead of staying a lighter tint of it. */
362
+ --usewc-local-link-decoration-opacity: 1;
348
363
  }
349
364
 
350
365
  nav.sidebar > & {
351
366
  display: block;
352
- /* Swapping these source tokens, rather than the resolved `--usewc-color-link-text` slot
367
+ /* Swapping these source tokens, rather than the resolved `--usewc-local-link-text` slot
353
368
  itself, means the existing `:hover`/`:active` rules above keep working unmodified — they
354
369
  already read through `-hover`/`-active`, so overriding what those resolve to here is
355
370
  enough to recolor every state at once. */
@@ -1401,6 +1416,24 @@
1401
1416
  }
1402
1417
  }
1403
1418
 
1419
+ /* A link inside a cell reads as the cell's own text rather than the document's default link
1420
+ blue — the grid draws attention with its row/selection bands, not link-colored text, so a
1421
+ link that broke from the cell's color would read as an anomaly instead of an affordance.
1422
+ Hover/active still need to move, the same as the default link darkening through
1423
+ blue-600/700/800 — `currentColor` alone can't step down like that, so each state is the
1424
+ cell's own color with its lightness nudged instead. `link.css`'s own decoration-color rule
1425
+ already derives from `--usewc-local-link-text`, so the underline follows every step here for
1426
+ free, staying a lighter tint of whichever shade the text itself is in. */
1427
+ use-gridcell :is(a:not([class*="appearance-"]), .appearance-a) {
1428
+ --usewc-color-link-text-static: currentColor;
1429
+ --usewc-color-link-text-hover: oklch(
1430
+ from currentColor calc(l + var(--usewc-color-grid-cell-link-hover-lightness-shift)) c h
1431
+ );
1432
+ --usewc-color-link-text-active: oklch(
1433
+ from currentColor calc(l + var(--usewc-color-grid-cell-link-active-lightness-shift)) c h
1434
+ );
1435
+ }
1436
+
1404
1437
  use-grid:not(.chips, .list, .appearance-native) {
1405
1438
  display: block;
1406
1439
  overflow: clip;
@@ -2045,25 +2078,35 @@
2045
2078
  to reorder markup.
2046
2079
 
2047
2080
  A variant's own density sets *only* two axes on itself — `--usewc-layout-region-padding` (the
2048
- inline inset) and `--usewc-layout-region-gap` (everything block: internal spacing within a
2049
- region, and the padding a region gets on its own block edges) — plus `-avatar-size` and
2050
- `--usewc-layout-footer-justify`. Reusing `-gap` as the block padding isn't a shortcut: it's the
2051
- same "how far apart do things stack" value either way, so a region's own padding and the room
2052
- it leaves around its neighbours always agree. One generic set of region rules reads these; the
2053
- arrangement itself (flex vs. grid vs. table, where the avatar sits, which edge a footer aligns
2054
- to) stays with each variant or, where a property can't say it, a structural override. A
2055
- `use-layout.page` is a `use-layout`, so the base pin/grow rules above already cover it too.
2056
-
2057
- No variant sets a container-level stacking gap: each region already pads its own block edges by
2058
- the density's own gap, so that alone puts one gap's worth of room between two regions — a
2059
- container `gap` on top would double-count it. `.page` and `.card` carry that same gap as a
2060
- `padding-block` on the host itself, so the true top/bottom edges get it too, and the first/last
2061
- child drop their own edge-facing half so it isn't doubled with the host's.
2062
-
2063
- `.page` and `.card` also take `.divided`, which rules a header/footer off from the body — opt-in,
2064
- not a variant default. Undivided, each region's own padding does the separating. `.divided`
2065
- draws a border on whichever region isn't first instead, so the padding alone — never a gap —
2066
- is what holds the line clear of its neighbour.
2081
+ inline inset) and `--usewc-layout-region-gap` (everything block) — plus `-avatar-size` and
2082
+ `--usewc-layout-footer-justify`. For `.entry`, `.message` and `.media`, `-gap` is both a
2083
+ region's own block padding and the room it leaves around its neighbours, reused rather than
2084
+ duplicated so the two always agree. For `.page`/`.card`, `-gap` is instead the host's own
2085
+ `padding-block` and container `gap` directly — same value, same "how far apart do things
2086
+ stack" meaning, just spent at the host level since a region there carries no padding of its
2087
+ own. Each variant's own region rules read these — grouped by actual shape (`.page`/`.card`,
2088
+ `.entry`/`.message`, `.media` on its own) rather than shared across all five, since a shape
2089
+ that stacks in one column, one that's a two-column grid, and one that's a table already end up
2090
+ with different results even reading the same tokens. The arrangement itself (flex vs. grid vs.
2091
+ table, where the avatar sits, which edge a footer aligns to) stays with each variant or, where
2092
+ a property can't say it, a structural override. A `use-layout.page` is a `use-layout`, so the
2093
+ base pin/grow rules above already cover it too.
2094
+
2095
+ `.entry`, `.message` and `.media` set no container-level stacking gap: each region already pads
2096
+ its own block edges by the density's own gap, so that alone puts one gap's worth of room
2097
+ between two regions — a container `gap` on top would double-count it. `.page` and `.card` work
2098
+ the other way around instead: the host owns the entire inset itself — one `padding` for the
2099
+ true edges, one `gap` for the room between children — and a region carries no padding of its
2100
+ own at all, so there's nothing left to double-count.
2101
+
2102
+ The default, unclassed `use-layout` and `.page`/`.card` also take `.divided`, which rules every
2103
+ region off from the one before it — opt-in, not a default. Since those three already space
2104
+ their children with a real `gap`, `.divided` draws directly into it: `row-rule` (CSS Gap
2105
+ Decorations) natively decorates the gap on browsers that support it; everywhere else, each
2106
+ region gets its own padding back (the `gap` turns off) and a plain `border-block-start` does
2107
+ the dividing instead. `.entry`, `.message` and `.media` don't take `.divided` — they arrange
2108
+ their regions structurally instead of stacking them in one column, so a rule between them
2109
+ isn't a single boundary to draw.
2067
2110
 
2068
2111
  `.entry` also takes `.compact`, which steps its own density down for a tighter repetition of
2069
2112
  the same shape — a nav item rather than a list row. Each variant that supports it declares its
@@ -2094,6 +2137,7 @@
2094
2137
  use-layout {
2095
2138
  display: flex;
2096
2139
  flex-direction: column;
2140
+ gap: var(--usewc-layout-region-gap, normal);
2097
2141
  }
2098
2142
 
2099
2143
  use-layout[inline] {
@@ -2144,30 +2188,6 @@
2144
2188
  justify-content: space-around;
2145
2189
  }
2146
2190
 
2147
- use-layout[gap="xsmall"] {
2148
- gap: var(--usewc-layout-flex-gap-xsmall);
2149
- }
2150
-
2151
- use-layout[gap="small"] {
2152
- gap: var(--usewc-layout-flex-gap-small);
2153
- }
2154
-
2155
- use-layout[gap="medium"] {
2156
- gap: var(--usewc-layout-flex-gap-medium);
2157
- }
2158
-
2159
- use-layout[gap="large"] {
2160
- gap: var(--usewc-layout-flex-gap-large);
2161
- }
2162
-
2163
- use-layout[gap="xlarge"] {
2164
- gap: var(--usewc-layout-flex-gap-xlarge);
2165
- }
2166
-
2167
- use-layout[gap="super"] {
2168
- gap: var(--usewc-layout-flex-gap-super);
2169
- }
2170
-
2171
2191
  /* `padding`/`padding-block`/`padding-inline` step through their own named scale
2172
2192
  (`--usewc-layout-flex-padding-*`), aliased in semantic.css to the same values as `gap`'s — the
2173
2193
  same "how far apart do things sit" size either way, just read through a padding-named token
@@ -2274,6 +2294,17 @@
2274
2294
  min-inline-size: 0;
2275
2295
  }
2276
2296
 
2297
+ /* `--usewc-layout-region-gap`/`-padding` are custom properties, which inherit by default — left
2298
+ alone, a nested `use-layout` would pick up its ancestor's density instead of its own default
2299
+ of "no gap/padding of its own." Resetting them here, at `:where()`'s zero specificity, stops
2300
+ that inheritance at every `use-layout` boundary without affecting a variant class or a
2301
+ `gap`/`padding` attribute below, both of which carry real specificity and still win on the
2302
+ element they target. */
2303
+ :where(use-layout) {
2304
+ --usewc-layout-region-gap: initial;
2305
+ --usewc-layout-region-padding: initial;
2306
+ }
2307
+
2277
2308
  /* ── Variant density ────────────────────────────────────────────────────────────────────────
2278
2309
  A variant class sets its own scale and nothing else; the generic region rules below read
2279
2310
  these properties. Keeping the arrangement in one ruleset rather than four means a future
@@ -2290,6 +2321,14 @@
2290
2321
  --usewc-layout-footer-justify: space-between;
2291
2322
  }
2292
2323
 
2324
+ /* A page's own `h1` — its title, wherever it sits in the topbar — reads at the page's title
2325
+ size and weight rather than the browser's default heading style. Matched at any depth, since
2326
+ a topbar routinely nests it a `<section>` or an `<hgroup>` down. */
2327
+ use-layout.page h1 {
2328
+ font-size: var(--usewc-font-page-title-size);
2329
+ font-weight: var(--usewc-font-page-title-weight);
2330
+ }
2331
+
2293
2332
  use-layout.entry {
2294
2333
  --usewc-layout-region-padding: var(--usewc-layout-entry-padding);
2295
2334
  --usewc-layout-region-gap: var(--usewc-layout-entry-gap);
@@ -2332,82 +2371,119 @@
2332
2371
  --usewc-layout-footer-justify: flex-start;
2333
2372
  }
2334
2373
 
2335
- /* `.divided` rules a region off from the one before it by position, not by tag — the border
2336
- lands on "whichever child isn't first", so a `<figure>`, an author's own `<section>`, or any
2337
- other stand-in divides exactly like `header`/`main`/`footer` do, with nothing to name per
2338
- tag. It only makes sense for `.page` and `.card`, the two plain-column variants where "the
2339
- next region" is unambiguous; `.entry`, `.message` and `.media` arrange their regions
2340
- structurally instead, so a rule between them isn't a single boundary to draw.
2341
-
2342
- Every child already gets its own `padding-block` (below), figure included here, which is the
2343
- one thing that changes: undivided, a `<figure>` bleeds edge to edge; divided, it takes the
2344
- same padding as its neighbours so the rule between it and the next region doesn't run flush
2345
- against the image. */
2346
- use-layout:is(.page, .card).divided {
2347
- & > * {
2348
- padding-block: var(--usewc-layout-region-gap);
2349
- }
2374
+ /* `gap`'s named scale lands in the same `--usewc-layout-region-gap` a variant's own density
2375
+ sets above, rather than a separate variable — one property, one source of truth, so an
2376
+ author's explicit `gap` on a variant reliably overrides its default instead of silently
2377
+ losing a specificity tie. Coming after "Variant density" in source is what makes that
2378
+ override direction work: same specificity as a variant class, later wins. The base
2379
+ `use-layout` rule reads whichever one landed here into the real `gap` property. */
2380
+ use-layout[gap="xsmall"] {
2381
+ --usewc-layout-region-gap: var(--usewc-layout-flex-gap-xsmall);
2382
+ }
2350
2383
 
2351
- & > :not(:first-child) {
2352
- border-block-start: var(--usewc-layout-region-rule);
2353
- }
2384
+ use-layout[gap="small"] {
2385
+ --usewc-layout-region-gap: var(--usewc-layout-flex-gap-small);
2354
2386
  }
2355
2387
 
2356
- /* `.page` and `.card` stack with no container-level gap between regions (see the removal of
2357
- `--usewc-layout-region-row-gap` from their density above): each region already pads its own
2358
- block edges by the density's own gap, so two adjacent regions naturally end up one gap's
2359
- worth of breathing room apart without a container gap doubling it. That padding is no longer
2360
- tag-gated — anything dropped directly into `.page`/`.card`, not only `header`/`main`/`footer`,
2361
- gets the same inset, which is what lets any content live there. `figure` is excluded, since it
2362
- bleeds to the container's own edge instead (see below).
2388
+ use-layout[gap="medium"] {
2389
+ --usewc-layout-region-gap: var(--usewc-layout-flex-gap-medium);
2390
+ }
2363
2391
 
2364
- The host itself carries the matching `padding-block`, so the true top/bottom edges get one
2365
- gap's worth of space; the first and last child then drop their own edge-facing half so it
2366
- isn't doubled with the host's. Both rules skip `:where()` so they reliably out-rank the
2367
- per-tag padding on `header`/`footer`/`use-layout[fill]` above regardless of source order — the
2368
- same trick `.flush` already relies on below. */
2369
- :where(use-layout:is(.page, .card)) > :not(figure) {
2370
- padding-inline: var(--usewc-layout-region-padding);
2371
- padding-block: var(--usewc-layout-region-gap);
2392
+ use-layout[gap="large"] {
2393
+ --usewc-layout-region-gap: var(--usewc-layout-flex-gap-large);
2372
2394
  }
2373
2395
 
2374
- /* Same reasoning as `main`'s own first/last-child margin reset further below, generalized to
2375
- match the padding rule just above: any non-`figure` child of `.page`/`.card` is a region now,
2376
- not only `main`/`use-layout[fill]`, so a plain `<div>` or `<ul>` dropped in directly gets the
2377
- same treatment — its own first/last child sheds the block margin that would otherwise stack
2378
- on top of the region's padding. */
2379
- :where(use-layout:is(.page, .card)) > :not(figure) > :first-child {
2380
- margin-block-start: 0;
2396
+ use-layout[gap="xlarge"] {
2397
+ --usewc-layout-region-gap: var(--usewc-layout-flex-gap-xlarge);
2381
2398
  }
2382
2399
 
2383
- :where(use-layout:is(.page, .card)) > :not(figure) > :last-child {
2384
- margin-block-end: 0;
2400
+ use-layout[gap="super"] {
2401
+ --usewc-layout-region-gap: var(--usewc-layout-flex-gap-super);
2385
2402
  }
2386
2403
 
2404
+ /* `.page` and `.card` own their entire inset on the host itself — one `padding` for the true
2405
+ edges, the base rule's own `gap` (above) for the room between children — rather than each
2406
+ child padding its own block edges and the first/last shedding the half that would double up
2407
+ with the host's. A region carries no padding of its own any more (below), so nothing here is
2408
+ tag-gated: whatever lands directly in `.page`/`.card`, not only `header`/`main`/`footer`,
2409
+ gets the same inset for free by virtue of sitting inside the host's own box. */
2387
2410
  use-layout:is(.page, .card) {
2388
- padding-block: var(--usewc-layout-region-gap);
2411
+ padding: var(--usewc-layout-region-gap) var(--usewc-layout-region-padding);
2389
2412
  }
2390
2413
 
2391
- use-layout:is(.page, .card) > :first-child {
2392
- padding-block-start: 0;
2414
+ /* Zeroes what the generic region rules above put on `header`/`main`/`footer`/`use-layout[fill]`,
2415
+ and reaches a plain, unnamed child the same way — the host's own padding and gap already do
2416
+ that job now. `figure` is excluded: it never had padding to zero, since it bleeds past the
2417
+ host's inset instead (below) rather than sitting inside it. */
2418
+ use-layout:is(.page, .card) > :not(figure) {
2419
+ padding: 0;
2393
2420
  }
2394
2421
 
2395
- use-layout:is(.page, .card) > :last-child {
2396
- padding-block-end: 0;
2422
+ /* A `<figure>` bleeds past the host's own inset on every edge it touches — the full inline
2423
+ width always, since nothing else pads it back in from the sides now that the host carries
2424
+ inline padding too; the block edges only when it's first or last, the same way it always has.
2425
+ `.divided` (below) is excluded: a divided figure sits inset like any other region instead of
2426
+ bleeding past the rule that would otherwise land on it. `.flush` already zeroes the host's
2427
+ own padding, so there is nothing left to pull out of either way.
2428
+
2429
+ Skips `:where()`, unlike the rules around it: the generic region block further down sets a
2430
+ flat `margin: 0` on every variant's `figure` at the same specificity a `:where()`-wrapped
2431
+ selector would carry, and being later in source it would otherwise win. Out-specifying it on
2432
+ purpose is the same trick `.flush` already relies on above. */
2433
+ use-layout:is(.page, .card):not(.divided):not(.flush) > figure {
2434
+ margin-inline: calc(var(--usewc-layout-region-padding) * -1);
2397
2435
  }
2398
2436
 
2399
- /* A `<figure>` sitting at the very top or bottom edge bleeds through the host's own edge padding
2400
- with a matching negative margin, the same way it always has. `.divided` opts every region,
2401
- figure included, into the same padding as its neighbours instead (above), so it's excluded
2402
- here; `.flush` already zeroes the host's own padding, so there is nothing left to pull out of. */
2403
- :where(use-layout:is(.page, .card):not(.divided):not(.flush)) > figure:first-child {
2437
+ use-layout:is(.page, .card):not(.divided):not(.flush) > figure:first-child {
2404
2438
  margin-block-start: calc(var(--usewc-layout-region-gap) * -1);
2405
2439
  }
2406
2440
 
2407
- :where(use-layout:is(.page, .card):not(.divided):not(.flush)) > figure:last-child {
2441
+ use-layout:is(.page, .card):not(.divided):not(.flush) > figure:last-child {
2408
2442
  margin-block-end: calc(var(--usewc-layout-region-gap) * -1);
2409
2443
  }
2410
2444
 
2445
+ /* `.divided` rules a region off from the one before it by position, not by tag — so a
2446
+ `<figure>`, an author's own `<section>`, or any other stand-in divides exactly like
2447
+ `header`/`main`/`footer` do, with nothing to name per tag. It only makes sense on the plain
2448
+ stacking shapes — the default, unclassed `use-layout` and `.page`/`.card` — where "the next
2449
+ region" is unambiguous; `.entry`, `.message` and `.media` arrange their regions structurally
2450
+ instead, so a rule between them isn't a single boundary to draw.
2451
+
2452
+ The rule is drawn *in* the gap on browsers that support `row-rule` (CSS Gap Decorations), so
2453
+ `.divided` needs no model of its own there: it's the same host `padding`/`gap` as undivided
2454
+ (the base rule's own `gap` reads `--usewc-layout-region-gap` regardless of whether it came
2455
+ from the `gap` attribute or a variant's own density), just with `row-rule` decorating it.
2456
+
2457
+ Everywhere else, a generated pseudo-element standing in for the gap doesn't hold up: a
2458
+ `use-layout[fill]` region (the scrolling body of a page, say) has its own `overflow: auto`,
2459
+ which scrolls and clips any pseudo generated *on* it right along with the rest of its
2460
+ content — there's no positioning trick that both lives inside that region and stays put
2461
+ against its own scrolling. So the fallback reaches for the one thing that's neither a
2462
+ scrollable descendant nor a flex item of the region it's drawn on: a real
2463
+ `border-block-start`, on the region's own box rather than a pseudo tucked inside it. That
2464
+ needs a region to have padding again to keep the rule off its content, which means turning
2465
+ the container `gap` back off — the same shape `.divided` had before this file started
2466
+ spending it at the host level. */
2467
+ @supports (row-rule-style: solid) {
2468
+ use-layout.divided:not(.entry):not(.message):not(.media) {
2469
+ row-rule: var(--usewc-layout-region-rule);
2470
+ }
2471
+ }
2472
+
2473
+ @supports not (row-rule-style: solid) {
2474
+ use-layout.divided:not(.entry):not(.message):not(.media) {
2475
+ gap: 0;
2476
+
2477
+ & > * {
2478
+ padding-block: var(--usewc-layout-region-gap, 0px);
2479
+ }
2480
+
2481
+ & > :not(:first-child) {
2482
+ border-block-start: var(--usewc-layout-region-rule);
2483
+ }
2484
+ }
2485
+ }
2486
+
2411
2487
  /* `.flush` zeroes a use-layout's own outer inset. Inline padding is one token consumed
2412
2488
  everywhere it's set (every region, and the container itself for `.entry`/`.message`/`.media`),
2413
2489
  so overriding it here reaches all of them at once regardless of variant. Block padding comes
@@ -2432,39 +2508,13 @@
2432
2508
  padding-block-end: 0;
2433
2509
  }
2434
2510
 
2435
- /* ── Generic regions ────────────────────────────────────────────────────────────────────────
2436
- One ruleset for every variant, reading the properties above. Nested under the shared variant
2437
- list rather than repeating it on every selector, so it stays in one place as variants are
2438
- added. A rule colour left unset falls back to `transparent`, so a variant opts into a
2439
- hairline by naming one rather than by having a rule of its own. */
2440
- :where(use-layout:is(.page, .entry, .message, .card, .media)) {
2511
+ /* ── Regions: .page / .card ─────────────────────────────────────────────────────────────────
2512
+ Header/footer content is a flex row of its own — an avatar or icon-like figure squared to
2513
+ the variant's avatar size, an `hgroup` growing to fill the rest, a trailing action or two —
2514
+ independent of the outer inset, which the host itself owns (above). Neither gets its own
2515
+ padding here: that's the whole point of the host owning it instead. */
2516
+ :where(use-layout:is(.page, .card)) {
2441
2517
  min-block-size: 0;
2442
- gap: var(--usewc-layout-region-row-gap);
2443
-
2444
- & > use-layout[fill] {
2445
- padding-inline: var(--usewc-layout-region-padding);
2446
- padding-block: var(--usewc-layout-region-gap);
2447
- }
2448
-
2449
- & > main {
2450
- padding-inline: var(--usewc-layout-region-padding);
2451
- padding-block: var(--usewc-layout-region-gap);
2452
- }
2453
-
2454
- /* The region owns its outer spacing, so the first and last things in it shed the block
2455
- margins they'd otherwise stack on top of the padding — a leading `<p>`, `<ul>`, `<ol>` or
2456
- heading would otherwise push itself away from an edge that's already spaced. Matched by
2457
- position rather than by tag so it holds for whatever flow content lands there. Tag-gated to
2458
- `main`/`use-layout[fill]` here since `.entry`/`.message`/`.media` don't accept arbitrary
2459
- content as a region the way `.page`/`.card` do — those two get the same treatment
2460
- generalized to any non-`figure` child, above, alongside the padding it's paired with. */
2461
- & > :is(main, use-layout[fill]) > :first-child {
2462
- margin-block-start: 0;
2463
- }
2464
-
2465
- & > :is(main, use-layout[fill]) > :last-child {
2466
- margin-block-end: 0;
2467
- }
2468
2518
 
2469
2519
  & > figure {
2470
2520
  margin: 0;
@@ -2482,8 +2532,6 @@
2482
2532
  align-items: center;
2483
2533
  justify-content: flex-start;
2484
2534
  gap: var(--usewc-layout-region-gap);
2485
- padding-inline: var(--usewc-layout-region-padding);
2486
- padding-block: var(--usewc-layout-region-gap);
2487
2535
  }
2488
2536
 
2489
2537
  & > footer {
@@ -2491,15 +2539,12 @@
2491
2539
  align-items: center;
2492
2540
  justify-content: var(--usewc-layout-footer-justify, flex-end);
2493
2541
  gap: var(--usewc-layout-region-gap);
2494
- padding-inline: var(--usewc-layout-region-padding);
2495
- padding-block: var(--usewc-layout-region-gap);
2496
2542
  }
2497
2543
 
2498
2544
  /* A header's leading likeness is a `use-avatar` or a `<figure>` — no `img.avatar`
2499
2545
  convention, since a bare `<img>` in a header is as likely to be a logo as a face, and a
2500
2546
  class would have to be remembered where the element already says it. Both are squared to
2501
- the variant's avatar size; a `<figure>` centres whatever it holds, the same way the
2502
- message rail does. */
2547
+ the variant's avatar size; a `<figure>` centres whatever it holds. */
2503
2548
  & > header > :is(use-avatar, figure) {
2504
2549
  flex: none;
2505
2550
  inline-size: var(--usewc-layout-region-avatar-size);
@@ -2578,6 +2623,212 @@
2578
2623
  }
2579
2624
  }
2580
2625
 
2626
+ /* ── Regions: .entry / .message ─────────────────────────────────────────────────────────────
2627
+ Same header/footer/hgroup treatment as `.page`/`.card`, minus the two things their own
2628
+ shape already covers elsewhere: `header`/`main`/`footer` take no padding of their own here
2629
+ either (the structural rules below own the inset), and `main`/`use-layout[fill]`'s own
2630
+ first/last child still sheds the block margin that would otherwise stack on top of it. */
2631
+ :where(use-layout:is(.entry, .message)) {
2632
+ min-block-size: 0;
2633
+ gap: var(--usewc-layout-region-row-gap);
2634
+
2635
+ & > :is(main, use-layout[fill]) > :first-child {
2636
+ margin-block-start: 0;
2637
+ }
2638
+
2639
+ & > :is(main, use-layout[fill]) > :last-child {
2640
+ margin-block-end: 0;
2641
+ }
2642
+
2643
+ & > figure {
2644
+ margin: 0;
2645
+ }
2646
+
2647
+ & > figure > img {
2648
+ display: block;
2649
+ inline-size: 100%;
2650
+ block-size: auto;
2651
+ object-fit: cover;
2652
+ }
2653
+
2654
+ & > header {
2655
+ display: flex;
2656
+ align-items: center;
2657
+ justify-content: flex-start;
2658
+ gap: var(--usewc-layout-region-gap);
2659
+ }
2660
+
2661
+ & > footer {
2662
+ display: flex;
2663
+ align-items: center;
2664
+ justify-content: var(--usewc-layout-footer-justify, flex-end);
2665
+ gap: var(--usewc-layout-region-gap);
2666
+ }
2667
+
2668
+ & > header > :is(use-avatar, figure) {
2669
+ flex: none;
2670
+ inline-size: var(--usewc-layout-region-avatar-size);
2671
+ block-size: var(--usewc-layout-region-avatar-size);
2672
+ border-radius: var(--usewc-effect-surface-avatar-border-radius);
2673
+ overflow: hidden;
2674
+ }
2675
+
2676
+ & > header > figure {
2677
+ display: flex;
2678
+ align-items: center;
2679
+ justify-content: center;
2680
+ margin-inline: 0;
2681
+ font-size: calc(var(--usewc-layout-region-avatar-size) * 0.4);
2682
+ line-height: 1;
2683
+ }
2684
+
2685
+ & > header > figure > img {
2686
+ inline-size: 100%;
2687
+ block-size: 100%;
2688
+ object-fit: cover;
2689
+ }
2690
+
2691
+ & > :is(header, footer) hgroup {
2692
+ display: flex;
2693
+ flex-direction: column;
2694
+ gap: var(--usewc-layout-region-title-gap);
2695
+ min-inline-size: 0;
2696
+ }
2697
+
2698
+ & > header > hgroup {
2699
+ flex: 1;
2700
+ }
2701
+
2702
+ & > :is(header, footer) hgroup > * {
2703
+ line-height: max(var(--usewc-layout-region-title-line-height), 1.25em);
2704
+ }
2705
+
2706
+ & > :is(header, footer) hgroup > * + * {
2707
+ font-size: var(--usewc-font-region-subtitle-size);
2708
+ line-height: var(--usewc-layout-region-subtitle-line-height);
2709
+ color: var(--usewc-color-document-text-muted);
2710
+ }
2711
+
2712
+ & > :is(header, footer) > *,
2713
+ & > :is(header, footer) hgroup > *,
2714
+ & > :is(header, footer) :is(h1, h2, h3, h4, h5, h6) {
2715
+ margin-block: 0;
2716
+ }
2717
+
2718
+ & > :is(header, footer) > section {
2719
+ display: flex;
2720
+ align-items: center;
2721
+ gap: var(--usewc-layout-region-gap);
2722
+ }
2723
+
2724
+ & > :is(header, footer):has(> section ~ section) {
2725
+ justify-content: space-between;
2726
+ }
2727
+ }
2728
+
2729
+ /* ── Regions: .media ────────────────────────────────────────────────────────────────────────
2730
+ Same header/footer/hgroup treatment again, adapted to the one thing `.media` does
2731
+ differently: any non-rail child is a region, not just `header`/`main`/`footer` (its own
2732
+ structural rule below reads by position, not by tag), so nothing here needs its own padding
2733
+ either — that's already zeroed generically there. */
2734
+ :where(use-layout.media) {
2735
+ min-block-size: 0;
2736
+ gap: var(--usewc-layout-region-row-gap);
2737
+
2738
+ & > :is(main, use-layout[fill]) > :first-child {
2739
+ margin-block-start: 0;
2740
+ }
2741
+
2742
+ & > :is(main, use-layout[fill]) > :last-child {
2743
+ margin-block-end: 0;
2744
+ }
2745
+
2746
+ & > figure {
2747
+ margin: 0;
2748
+ }
2749
+
2750
+ & > figure > img {
2751
+ display: block;
2752
+ inline-size: 100%;
2753
+ block-size: auto;
2754
+ object-fit: cover;
2755
+ }
2756
+
2757
+ & > header {
2758
+ display: flex;
2759
+ align-items: center;
2760
+ justify-content: flex-start;
2761
+ gap: var(--usewc-layout-region-gap);
2762
+ }
2763
+
2764
+ & > footer {
2765
+ display: flex;
2766
+ align-items: center;
2767
+ justify-content: var(--usewc-layout-footer-justify, flex-end);
2768
+ gap: var(--usewc-layout-region-gap);
2769
+ }
2770
+
2771
+ & > header > :is(use-avatar, figure) {
2772
+ flex: none;
2773
+ inline-size: var(--usewc-layout-region-avatar-size);
2774
+ block-size: var(--usewc-layout-region-avatar-size);
2775
+ border-radius: var(--usewc-effect-surface-avatar-border-radius);
2776
+ overflow: hidden;
2777
+ }
2778
+
2779
+ & > header > figure {
2780
+ display: flex;
2781
+ align-items: center;
2782
+ justify-content: center;
2783
+ margin-inline: 0;
2784
+ font-size: calc(var(--usewc-layout-region-avatar-size) * 0.4);
2785
+ line-height: 1;
2786
+ }
2787
+
2788
+ & > header > figure > img {
2789
+ inline-size: 100%;
2790
+ block-size: 100%;
2791
+ object-fit: cover;
2792
+ }
2793
+
2794
+ & > :is(header, footer) hgroup {
2795
+ display: flex;
2796
+ flex-direction: column;
2797
+ gap: var(--usewc-layout-region-title-gap);
2798
+ min-inline-size: 0;
2799
+ }
2800
+
2801
+ & > header > hgroup {
2802
+ flex: 1;
2803
+ }
2804
+
2805
+ & > :is(header, footer) hgroup > * {
2806
+ line-height: max(var(--usewc-layout-region-title-line-height), 1.25em);
2807
+ }
2808
+
2809
+ & > :is(header, footer) hgroup > * + * {
2810
+ font-size: var(--usewc-font-region-subtitle-size);
2811
+ line-height: var(--usewc-layout-region-subtitle-line-height);
2812
+ color: var(--usewc-color-document-text-muted);
2813
+ }
2814
+
2815
+ & > :is(header, footer) > *,
2816
+ & > :is(header, footer) hgroup > *,
2817
+ & > :is(header, footer) :is(h1, h2, h3, h4, h5, h6) {
2818
+ margin-block: 0;
2819
+ }
2820
+
2821
+ & > :is(header, footer) > section {
2822
+ display: flex;
2823
+ align-items: center;
2824
+ gap: var(--usewc-layout-region-gap);
2825
+ }
2826
+
2827
+ & > :is(header, footer):has(> section ~ section) {
2828
+ justify-content: space-between;
2829
+ }
2830
+ }
2831
+
2581
2832
  /* ── Structural overrides ───────────────────────────────────────────────────────────────────
2582
2833
  The arrangements a density property can't express. Same `:where()` weight as the generic
2583
2834
  rules, winning on source order. */
@@ -2608,7 +2859,6 @@
2608
2859
 
2609
2860
  :where(use-layout:is(.entry, .message)) > :is(header, main, footer) {
2610
2861
  grid-column: 2;
2611
- padding: 0;
2612
2862
  }
2613
2863
 
2614
2864
  :where(use-layout.message) > footer {