diff --git a/configurator/src/data/api-index.generated.json b/configurator/src/data/api-index.generated.json index e9363e02..7531cfd4 100644 --- a/configurator/src/data/api-index.generated.json +++ b/configurator/src/data/api-index.generated.json @@ -2,7 +2,7 @@ "_sync": { "generatedBy": "configurator/scripts/sync-api.mjs", "source": "docs/api-index.json", - "tokensHash": "e5e711cd49af", + "tokensHash": "68fb960217b8", "bundles": [ "essential", "full", @@ -565,7 +565,7 @@ "group": "Bento grid", "description": "Configuration tokens for the bento-grid layout primitive.", "note": "Default column count for the bento grid.", - "value": "3", + "value": "4", "aliasOf": null, "registered": false, "syntax": null, @@ -12461,7 +12461,7 @@ "namespace": "lumlocker", "category": "Core tokens", "group": "LumLocker", - "description": "OKLCH L value used by the :root[data-lumlocker] override in core/themes.css. Locks all 5 brand colors (primary, secondary, tertiary, action, neutral) to one shared lightness while keeping their individual hue and chroma. Base is excluded — it must remain near-white in light…", + "description": "OKLCH L value used by the :root[data-lumlocker] override in core/themes.css. Locks the 4 brand colors (primary, secondary, tertiary, action) to one shared lightness while keeping their individual hue and chroma. Neutral and base are excluded — neutral is a desaturated grey…", "note": "", "value": "0.65", "aliasOf": null, diff --git a/core/layout.css b/core/layout.css index 9731b7a3..30d192e3 100644 --- a/core/layout.css +++ b/core/layout.css @@ -444,6 +444,18 @@ min-height: 100dvh; } + /* -- Single-column grid -------------------------------------- + Plain single-column grid. No container context — it never + needs CQ breakpoints (there's only one column). Use when you + want consistent gap spacing without affecting container queries + on child elements. + ---------------------------------------------------------- */ + + .sf-grid-cols-1 { + display: grid; + gap: var(--sf-grid-gap); + } + /* -- Fixed column grids (container-query responsive) --------- Responsive fixed-column grids with no media queries. @@ -454,7 +466,7 @@ Wrap in .sf-container (or any element with container-type: inline-size). ---------------------------------------------------------- */ - .sf-grid-cols-1, .sf-grid-cols-2, .sf-grid-cols-3, .sf-grid-cols-4, .sf-grid-cols-6 { + .sf-grid-cols-2, .sf-grid-cols-3, .sf-grid-cols-4, .sf-grid-cols-6 { display: grid; gap: var(--sf-grid-gap); container: sf-grid / inline-size; @@ -535,7 +547,23 @@ /* -- Bento grid ---------------------------------------------- Free-form grid with auto-flow dense, responsive via CQ. - Override: style="--sf-bento-cols: 4; --sf-bento-row: 12rem" + Default: 4 columns (4 divides evenly for 1+3, 2+2, 3+1, 2×2). + Override: style="--sf-bento-cols: 6; --sf-bento-row: 12rem" + + Column modifiers (on container): + .sf-bento--2 → 2 columns + .sf-bento--3 → 3 columns + .sf-bento--6 → 6 columns + + Row height modifiers (on container): + .sf-bento--compact → shorter rows + .sf-bento--tall → taller rows + + Span modifiers (on children): + .sf-bento-wide → span 2 columns + .sf-bento-full → span all columns + .sf-bento-tall → span 2 rows + .sf-bento-featured → span 2 columns × 2 rows ---------------------------------------------------------- */ .sf-bento { @@ -552,16 +580,27 @@ .sf-bento { grid-template-columns: 1fr; } } - /* CQ breakpoints S/L — 30em / 48em. Cannot use var() inside @container per CSS spec. */ + /* CQ breakpoint S — 30em–47.99em. 2 columns regardless of modifier. */ @container (min-width: 30em) and (max-width: 47.99em) { .sf-bento { grid-template-columns: repeat(2, 1fr); } } + /* Container column modifiers */ .sf-bento--2 { --sf-bento-cols: 2; } - .sf-bento--4 { --sf-bento-cols: 4; } + .sf-bento--3 { --sf-bento-cols: 3; } + .sf-bento--6 { --sf-bento-cols: 6; } + + /* Container row height modifiers */ .sf-bento--compact { --sf-bento-row: var(--sf-bento-row-compact); } .sf-bento--tall { --sf-bento-row: var(--sf-bento-row-tall); } + /* Child span modifiers — place on individual bento items. + grid-auto-flow: dense on the parent fills gaps automatically. */ + .sf-bento-wide { grid-column: span 2; } + .sf-bento-full { grid-column: 1 / -1; } + .sf-bento-tall { grid-row: span 2; } + .sf-bento-featured { grid-column: span 2; grid-row: span 2; } + /* -- Subgrid ------------------------------------------------- A grid child that inherits its parent's tracks. ---------------------------------------------------------- */ diff --git a/core/themes.css b/core/themes.css index 04e91a57..0379f2cf 100644 --- a/core/themes.css +++ b/core/themes.css @@ -63,15 +63,17 @@ } /* LumLocker — opt-in via [data-lumlocker] on :root. - Locks the 5 brand colors (primary, secondary, tertiary, action, - neutral) to one shared OKLCH L value (--sf-lumlocker, - default 0.65 in core/tokens.css), keeping each color's own hue - and chroma. Useful when a brand picker produces colors with - wildly different L values that look mismatched in weight. - - Base is excluded by design — it is the source token for the - page-surface ladder, and locking it would distort the derived page - background and related surface levels. + Locks the 4 brand colors (primary, secondary, tertiary, action) + to one shared OKLCH L value (--sf-lumlocker, default 0.65 in + core/tokens.css), keeping each color's own hue and chroma. + Useful when a brand picker produces colors with wildly different + L values that look mismatched in weight. + + Neutral is excluded by design — it is semantically a desaturated + grey, and forcing it to the same L as saturated brand colors would + make it appear chromatic and break its design role. + Base is also excluded — it is the source token for the page-surface + ladder, and locking it would distort derived backgrounds. Default state: OFF. Without the attribute, every brand keeps its own L. Add :root[data-lumlocker] (or set via JS) to enable. @@ -83,6 +85,11 @@ The dark-side input falls back to -light when -dark isn't explicitly set, so this works even without per-mode overrides. + Section-level [data-theme] fix: the combinator rules below + re-apply the lock inside nested [data-theme] subtrees, which + would otherwise bypass the :root-level locked value because + light-dark() resolves at declaration time, not inheritance time. + Requires CSS relative color syntax (Chrome 119+, Safari 16.4+, Firefox 128+). Wrapped in @supports — unsupporting engines skip the block silently; brand colors remain unmodified. */ @@ -104,10 +111,25 @@ oklch(from var(--sf-color-action-light) var(--sf-lumlocker) c h), oklch(from var(--sf-color-action-dark, var(--sf-color-action-light)) var(--sf-lumlocker) c h) ); - --sf-color-neutral: light-dark( - oklch(from var(--sf-color-neutral-light) var(--sf-lumlocker) c h), - oklch(from var(--sf-color-neutral-dark, var(--sf-color-neutral-light)) var(--sf-lumlocker) c h) - ); + } + + /* Re-apply lock inside section-level [data-theme] subtrees. + The section re-theme block above (slashed.themes @supports) sets + brand colors from source tokens directly, bypassing the lumlocked + value on :root. These higher-specificity rules (2 attr selectors) + restore the lock for any [data-theme] descendant when lumlocker is + active. The -dark token falls back to -light if not set. */ + :root[data-lumlocker] [data-theme="dark"] { + --sf-color-primary: oklch(from var(--sf-color-primary-dark, var(--sf-color-primary-light)) var(--sf-lumlocker) c h); + --sf-color-secondary: oklch(from var(--sf-color-secondary-dark, var(--sf-color-secondary-light)) var(--sf-lumlocker) c h); + --sf-color-tertiary: oklch(from var(--sf-color-tertiary-dark, var(--sf-color-tertiary-light)) var(--sf-lumlocker) c h); + --sf-color-action: oklch(from var(--sf-color-action-dark, var(--sf-color-action-light)) var(--sf-lumlocker) c h); + } + :root[data-lumlocker] [data-theme="light"] { + --sf-color-primary: oklch(from var(--sf-color-primary-light) var(--sf-lumlocker) c h); + --sf-color-secondary: oklch(from var(--sf-color-secondary-light) var(--sf-lumlocker) c h); + --sf-color-tertiary: oklch(from var(--sf-color-tertiary-light) var(--sf-lumlocker) c h); + --sf-color-action: oklch(from var(--sf-color-action-light) var(--sf-lumlocker) c h); } } /* end @supports (color: oklch(from red l c h)) */ diff --git a/core/tokens.css b/core/tokens.css index 24480636..bdb620da 100644 --- a/core/tokens.css +++ b/core/tokens.css @@ -316,10 +316,11 @@ /* ---------------------------------------------------------- LumLocker — OKLCH L value used by the :root[data-lumlocker] override in core/themes.css. - Locks all 5 brand colors (primary, secondary, tertiary, - action, neutral) to one shared lightness while keeping their - individual hue and chroma. Base is excluded — it must remain - near-white in light mode for the page background. + Locks the 4 brand colors (primary, secondary, tertiary, action) + to one shared lightness while keeping their individual hue and + chroma. Neutral and base are excluded — neutral is a desaturated + grey (locking it to a brand L would make it chromatic) and base + must remain near-white in light mode for the page background. Override to change the locked lightness: :root { --sf-lumlocker: 0.55 } ---------------------------------------------------------- */ diff --git a/core/tokens.layout.css b/core/tokens.layout.css index 86d001c9..a5f71f9c 100644 --- a/core/tokens.layout.css +++ b/core/tokens.layout.css @@ -129,7 +129,7 @@ /* ---------------------------------------------------------- Bento grid ---------------------------------------------------------- */ - --sf-bento-cols-default: 3; + --sf-bento-cols-default: 4; --sf-bento-row-default: 10rem; --sf-bento-row-compact: 6rem; --sf-bento-row-tall: 16rem; diff --git a/dist/badge-essential.json b/dist/badge-essential.json index 4b76a77f..7aaea620 100644 --- a/dist/badge-essential.json +++ b/dist/badge-essential.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "label": "essential", - "message": "15.7 kB gzip", + "message": "54.9 kB gzip", "color": "brightgreen", "namedLogo": "css3" } diff --git a/dist/badge-optimal.json b/dist/badge-optimal.json index 46b854cc..fa2a4ce2 100644 --- a/dist/badge-optimal.json +++ b/dist/badge-optimal.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "label": "optimal", - "message": "19.5 kB gzip", + "message": "65.8 kB gzip", "color": "brightgreen", "namedLogo": "css3" } diff --git a/docs/api-index.json b/docs/api-index.json index b57664f6..5db1627a 100644 --- a/docs/api-index.json +++ b/docs/api-index.json @@ -29,14 +29,14 @@ "optimal-utilities" ], "counts": { - "total": 1046, + "total": 1051, "by_type": { - "class": 223, + "class": 228, "token": 823 }, "by_tier": { "INTERNAL": 1, - "PUBLIC": 908, + "PUBLIC": 913, "PUBLIC-ADVANCED": 137 }, "by_role": { @@ -44,15 +44,15 @@ "knob": 232 }, "tokens": 823, - "classes": 223, - "sf_classes": 174, + "classes": 228, + "sf_classes": 179, "is_classes": 40, "unprefixed_classes": 9, "by_category": { "Accessibility": 7, "Component tokens": 6, "Core tokens": 495, - "Layout primitives": 120, + "Layout primitives": 125, "Layout tokens": 48, "Macro classes": 36, "Macro tokens": 24, @@ -740,7 +740,7 @@ "area": "layout", "group": "Bento grid", "description": "Bento grid", - "value": "3", + "value": "4", "aliasOf": null, "registered": false, "animatable": false, @@ -15183,7 +15183,7 @@ "category": "Core tokens", "area": "core", "group": "LumLocker", - "description": "OKLCH L value used by the :root[data-lumlocker] override in core/themes.css. Locks all 5 brand colors (primary, secondary, tertiary, action, neutral) to one shared lightness while keeping their individual hue and chroma. Base is excluded — it must remain near-white in light…", + "description": "OKLCH L value used by the :root[data-lumlocker] override in core/themes.css. Locks the 4 brand colors (primary, secondary, tertiary, action) to one shared lightness while keeping their individual hue and chroma. Neutral and base are excluded — neutral is a desaturated grey…", "value": "0.65", "aliasOf": null, "registered": false, @@ -24960,7 +24960,7 @@ "category": "Layout primitives", "area": "layout", "group": "Bento grid", - "description": "Free-form grid with auto-flow dense, responsive via CQ. Override: style=\"--sf-bento-cols: 4; --sf-bento-row: 12rem\"", + "description": "Free-form grid with auto-flow dense, responsive via CQ. Default: 4 columns (4 divides evenly for 1+3, 2+2, 3+1, 2×2). Override: style=\"--sf-bento-cols: 6; --sf-bento-row: 12rem\" Column modifiers (on container): .sf-bento--2 → 2 columns .sf-bento--3 → 3 columns .sf-bento--6 → 6…", "isVariant": false, "baseClass": null, "optional": false, @@ -24986,7 +24986,33 @@ "category": "Layout primitives", "area": "layout", "group": "Bento grid", - "description": "CQ breakpoints S/L — 30em / 48em. Cannot use var() inside @container per CSS spec.", + "description": "Container column modifiers", + "isVariant": true, + "baseClass": "sf-bento", + "optional": false, + "layer": "slashed.layout", + "sourceFiles": [ + "core/layout.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, + { + "name": "sf-bento--3", + "type": "class", + "tier": "PUBLIC", + "selector": ".sf-bento--3", + "prefix": "sf", + "kind": "layout", + "category": "Layout primitives", + "area": "layout", + "group": "Bento grid", + "description": "Container column modifiers", "isVariant": true, "baseClass": "sf-bento", "optional": false, @@ -25003,16 +25029,16 @@ ] }, { - "name": "sf-bento--4", + "name": "sf-bento--6", "type": "class", "tier": "PUBLIC", - "selector": ".sf-bento--4", + "selector": ".sf-bento--6", "prefix": "sf", "kind": "layout", "category": "Layout primitives", "area": "layout", "group": "Bento grid", - "description": "CQ breakpoints S/L — 30em / 48em. Cannot use var() inside @container per CSS spec.", + "description": "Container column modifiers", "isVariant": true, "baseClass": "sf-bento", "optional": false, @@ -25038,7 +25064,7 @@ "category": "Layout primitives", "area": "layout", "group": "Bento grid", - "description": "CQ breakpoints S/L — 30em / 48em. Cannot use var() inside @container per CSS spec.", + "description": "Container row height modifiers", "isVariant": true, "baseClass": "sf-bento", "optional": false, @@ -25064,7 +25090,7 @@ "category": "Layout primitives", "area": "layout", "group": "Bento grid", - "description": "CQ breakpoints S/L — 30em / 48em. Cannot use var() inside @container per CSS spec.", + "description": "Container row height modifiers", "isVariant": true, "baseClass": "sf-bento", "optional": false, @@ -25080,6 +25106,110 @@ "optimal-utilities" ] }, + { + "name": "sf-bento-featured", + "type": "class", + "tier": "PUBLIC", + "selector": ".sf-bento-featured", + "prefix": "sf", + "kind": "layout", + "category": "Layout primitives", + "area": "layout", + "group": "Bento grid", + "description": "Child span modifiers — place on individual bento items. grid-auto-flow: dense on the parent fills gaps automatically.", + "isVariant": false, + "baseClass": null, + "optional": false, + "layer": "slashed.layout", + "sourceFiles": [ + "core/layout.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, + { + "name": "sf-bento-full", + "type": "class", + "tier": "PUBLIC", + "selector": ".sf-bento-full", + "prefix": "sf", + "kind": "layout", + "category": "Layout primitives", + "area": "layout", + "group": "Bento grid", + "description": "Child span modifiers — place on individual bento items. grid-auto-flow: dense on the parent fills gaps automatically.", + "isVariant": false, + "baseClass": null, + "optional": false, + "layer": "slashed.layout", + "sourceFiles": [ + "core/layout.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, + { + "name": "sf-bento-tall", + "type": "class", + "tier": "PUBLIC", + "selector": ".sf-bento-tall", + "prefix": "sf", + "kind": "layout", + "category": "Layout primitives", + "area": "layout", + "group": "Bento grid", + "description": "Child span modifiers — place on individual bento items. grid-auto-flow: dense on the parent fills gaps automatically.", + "isVariant": false, + "baseClass": null, + "optional": false, + "layer": "slashed.layout", + "sourceFiles": [ + "core/layout.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, + { + "name": "sf-bento-wide", + "type": "class", + "tier": "PUBLIC", + "selector": ".sf-bento-wide", + "prefix": "sf", + "kind": "layout", + "category": "Layout primitives", + "area": "layout", + "group": "Bento grid", + "description": "Child span modifiers — place on individual bento items. grid-auto-flow: dense on the parent fills gaps automatically.", + "isVariant": false, + "baseClass": null, + "optional": false, + "layer": "slashed.layout", + "sourceFiles": [ + "core/layout.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "sf-box", "type": "class", @@ -27143,8 +27273,8 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Fixed column grids (container-query responsive)", - "description": "Responsive fixed-column grids with no media queries. IMPORTANT: These classes use anonymous @container queries, so they react to the nearest ancestor that has a container context (container-type: inline-size). Without a container ancestor the queries never match and the grid…", + "group": "Single-column grid", + "description": "Plain single-column grid. No container context — it never needs CQ breakpoints (there's only one column). Use when you want consistent gap spacing without affecting container queries on child elements.", "isVariant": false, "baseClass": null, "optional": false, diff --git a/docs/api-index.md b/docs/api-index.md index f664ede2..374756ff 100644 --- a/docs/api-index.md +++ b/docs/api-index.md @@ -10,11 +10,11 @@ and a short description. The machine-readable companion (with all columns) is [registry.json](registry.json); for the tier contract see [architecture.md](architecture.md). -**1046 elements** — 823 tokens, 223 classes. +**1051 elements** — 823 tokens, 228 classes. | Tier | Count | Meaning | |---|---|---| -| PUBLIC | 908 | Everyday surface. SemVer-stable. | +| PUBLIC | 913 | Everyday surface. SemVer-stable. | | PUBLIC-ADVANCED | 137 | Same SemVer guarantee; niche/powerful. | | INTERNAL | 1 | Implementation detail; may change without a major bump. | @@ -381,7 +381,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-link-external-marker` | PUBLIC | knob | link | `" \\2197"` | Leading space is baked into the default so consumers can fully disable the indicator with `--sf-link-external-marker: ""` — without the space a bare "" still left a stray space after the link text. Override with your own glyph (include leading space if you want one): `:root {… | | `--sf-link-underline-offset` | PUBLIC | knob | link | `0.15em` | Underline geometry — consumed by a:link in core/base.css and by the .sf-link--* macros. `auto` defers to the font's own metrics; set an explicit length (e.g. 0.08em) for a uniform rule. | | `--sf-link-underline-thickness` | PUBLIC | knob | link | `auto` | Underline geometry — consumed by a:link in core/base.css and by the .sf-link--* macros. `auto` defers to the font's own metrics; set an explicit length (e.g. 0.08em) for a uniform rule. | -| `--sf-lumlocker` | PUBLIC-ADVANCED | knob | lumlocker | `0.65` | OKLCH L value used by the :root[data-lumlocker] override in core/themes.css. Locks all 5 brand colors (primary, secondary, tertiary, action, neutral) to one shared lightness while keeping their individual hue and chroma. Base is excluded — it must remain near-white in light… | +| `--sf-lumlocker` | PUBLIC-ADVANCED | knob | lumlocker | `0.65` | OKLCH L value used by the :root[data-lumlocker] override in core/themes.css. Locks the 4 brand colors (primary, secondary, tertiary, action) to one shared lightness while keeping their individual hue and chroma. Neutral and base are excluded — neutral is a desaturated grey… | | `--sf-mask-scrim-end` | PUBLIC-ADVANCED | consumption | mask | `var(--sf-space-l)` | edge-fade stops for scroll reels / overflow. Use in a mask-image gradient to fade content near an edge: mask-image: linear-gradient(to right, transparent 0, #000 var(--sf-mask-scrim-start), #000 calc(100% - var(--sf-mask-scrim-end)), transparent 100%); | | `--sf-mask-scrim-start` | PUBLIC-ADVANCED | consumption | mask | `var(--sf-space-l)` | edge-fade stops for scroll reels / overflow. Use in a mask-image gradient to fade content near an edge: mask-image: linear-gradient(to right, transparent 0, #000 var(--sf-mask-scrim-start), #000 calc(100% - var(--sf-mask-scrim-end)), transparent 100%); | | `--sf-motion-scale` | PUBLIC-ADVANCED | knob | motion | `1` | Scale multipliers | @@ -537,7 +537,7 @@ and a short description. The machine-readable companion (with all columns) is |---|---|---|---|---|---| | `--sf-alternate-gap` | PUBLIC | consumption | alternate | `var(--sf-space-content)` | Alternate (zigzag) | | `--sf-alternate-inner-gap` | PUBLIC | consumption | alternate | `var(--sf-space-gap)` | Alternate (zigzag) | -| `--sf-bento-cols-default` | PUBLIC | knob | bento | `3` | Bento grid | +| `--sf-bento-cols-default` | PUBLIC | knob | bento | `4` | Bento grid | | `--sf-bento-gap` | PUBLIC | consumption | bento | `var(--sf-space-gap)` | Bento grid | | `--sf-bento-row-compact` | PUBLIC | knob | bento | `6rem` | Bento grid | | `--sf-bento-row-default` | PUBLIC | knob | bento | `10rem` | Bento grid | @@ -873,7 +873,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-text-xs-max-width` | PUBLIC | knob | text | `60ch` | Override knobs for each body text size step. Defaults encode standard typographic conventions; override any value globally here or locally via CSS custom property on a scoped element. These tokens are NOT auto-applied — they are opt-in composable overrides. Wire them up in your… | | `--sf-text-xs-to-2xs` | PUBLIC-ADVANCED | consumption | text | `clamp(calc(var(--sf-text-base-min) * pow(var(--sf-text-ratio-min), -3) * 1rem), calc((var(--sf-text-base-max) * pow(var(--sf-text-ratio-max), -2) - var(--sf-text-base-min) * pow(var(--sf-text-ratio-min), -3)) / (var(--sf-fluid-max-vw) - var(--sf-fluid-min-vw)) * (100vw - var(--sf-fluid-min-vw) * 1rem) + var(--sf-text-base-min) * pow(var(--sf-text-ratio-min), -3) * 1rem), calc(var(--sf-text-base-max) * pow(var(--sf-text-ratio-max), -2) * 1rem))` | Full descending matrix: --sf-text-{larger}-to-{smaller} No --sf-text-scale multiplier — consistent with how the base text tokens are consumed by the text-bridge contract. | -## Classes (223) +## Classes (228) ### Accessibility (7) @@ -887,16 +887,21 @@ and a short description. The machine-readable companion (with all columns) is | `.sr-only` | PUBLIC | accessibility | Screen-reader-only. Atomic contract: a partial override | either exposes hidden content visually or hides intended content. All-or-nothing, so the whole set is hardened. | | `.sr-only-focusable` | PUBLIC | accessibility | Screen-reader-only. Atomic contract: a partial override | either exposes hidden content visually or hides intended content. All-or-nothing, so the whole set is hardened. | -### Layout primitives (120) +### Layout primitives (125) | Class | Tier | Kind | Group | Description | |---|---|---|---|---| | `.sf-alternate` | PUBLIC | layout | Alternate (zigzag / media-object) | Alternating two-column layouts (container-query responsive). Every other row reverses its children's order. Establishes a named container `sf-alternate` and binds the responsive query to that name — so a `.sf-alternate` nested inside another container (e.g. `.sf-bento`) still… | -| `.sf-bento` | PUBLIC | layout | Bento grid | Free-form grid with auto-flow dense, responsive via CQ. Override: style="--sf-bento-cols: 4; --sf-bento-row: 12rem" | -| `.sf-bento--2` | PUBLIC | layout | Bento grid | CQ breakpoints S/L — 30em / 48em. Cannot use var() inside @container per CSS spec. | -| `.sf-bento--4` | PUBLIC | layout | Bento grid | CQ breakpoints S/L — 30em / 48em. Cannot use var() inside @container per CSS spec. | -| `.sf-bento--compact` | PUBLIC | layout | Bento grid | CQ breakpoints S/L — 30em / 48em. Cannot use var() inside @container per CSS spec. | -| `.sf-bento--tall` | PUBLIC | layout | Bento grid | CQ breakpoints S/L — 30em / 48em. Cannot use var() inside @container per CSS spec. | +| `.sf-bento` | PUBLIC | layout | Bento grid | Free-form grid with auto-flow dense, responsive via CQ. Default: 4 columns (4 divides evenly for 1+3, 2+2, 3+1, 2×2). Override: style="--sf-bento-cols: 6; --sf-bento-row: 12rem" Column modifiers (on container): .sf-bento--2 → 2 columns .sf-bento--3 → 3 columns .sf-bento--6 → 6… | +| `.sf-bento--2` | PUBLIC | layout | Bento grid | Container column modifiers | +| `.sf-bento--3` | PUBLIC | layout | Bento grid | Container column modifiers | +| `.sf-bento--6` | PUBLIC | layout | Bento grid | Container column modifiers | +| `.sf-bento--compact` | PUBLIC | layout | Bento grid | Container row height modifiers | +| `.sf-bento--tall` | PUBLIC | layout | Bento grid | Container row height modifiers | +| `.sf-bento-featured` | PUBLIC | layout | Bento grid | Child span modifiers — place on individual bento items. grid-auto-flow: dense on the parent fills gaps automatically. | +| `.sf-bento-full` | PUBLIC | layout | Bento grid | Child span modifiers — place on individual bento items. grid-auto-flow: dense on the parent fills gaps automatically. | +| `.sf-bento-tall` | PUBLIC | layout | Bento grid | Child span modifiers — place on individual bento items. grid-auto-flow: dense on the parent fills gaps automatically. | +| `.sf-bento-wide` | PUBLIC | layout | Bento grid | Child span modifiers — place on individual bento items. grid-auto-flow: dense on the parent fills gaps automatically. | | `.sf-box` | PUBLIC | layout | Box | Isolated unit with padding and an optional border. Outline instead of border — doesn't disturb the box model when toggled. Override: style="--sf-box-padding: 1rem; --sf-box-border-width: 1px" | | `.sf-breakout` | PUBLIC | layout | Content grid (breakout pattern) | Full-width grid that lets items break out to breakout or full width. Children default to the content column. | | `.sf-center` | PUBLIC | layout | Center | Centers content with a max-inline-size and side gutters. content-box: max-inline-size applies to content only; padding is additive. Override: style="--sf-center-max: 60rem" | @@ -961,7 +966,7 @@ and a short description. The machine-readable companion (with all columns) is | `.sf-grid--s` | PUBLIC | layout | Grid (auto) | Auto-fill CSS grid with no breakpoints. .sf-grid--fit switches to auto-fit. Fixed-column variants live in .sf-grid-cols-N. auto-fill: empty tracks preserved, last item doesn't stretch. auto-fit (.sf-grid--fit): empty tracks collapsed, items stretch. Override:… | | `.sf-grid--xl` | PUBLIC | layout | Grid (auto) | Auto-fill CSS grid with no breakpoints. .sf-grid--fit switches to auto-fit. Fixed-column variants live in .sf-grid-cols-N. auto-fill: empty tracks preserved, last item doesn't stretch. auto-fit (.sf-grid--fit): empty tracks collapsed, items stretch. Override:… | | `.sf-grid--xs` | PUBLIC | layout | Grid (auto) | Auto-fill CSS grid with no breakpoints. .sf-grid--fit switches to auto-fit. Fixed-column variants live in .sf-grid-cols-N. auto-fill: empty tracks preserved, last item doesn't stretch. auto-fit (.sf-grid--fit): empty tracks collapsed, items stretch. Override:… | -| `.sf-grid-cols-1` | PUBLIC | layout | Fixed column grids (container-query responsive) | Responsive fixed-column grids with no media queries. IMPORTANT: These classes use anonymous @container queries, so they react to the nearest ancestor that has a container context (container-type: inline-size). Without a container ancestor the queries never match and the grid… | +| `.sf-grid-cols-1` | PUBLIC | layout | Single-column grid | Plain single-column grid. No container context — it never needs CQ breakpoints (there's only one column). Use when you want consistent gap spacing without affecting container queries on child elements. | | `.sf-grid-cols-1-2` | PUBLIC | layout | Ratio grids | Two-column ratio grids, container-query responsive. | | `.sf-grid-cols-1-3` | PUBLIC | layout | Ratio grids | Two-column ratio grids, container-query responsive. | | `.sf-grid-cols-2` | PUBLIC | layout | Fixed column grids (container-query responsive) | Responsive fixed-column grids with no media queries. IMPORTANT: These classes use anonymous @container queries, so they react to the nearest ancestor that has a container context (container-type: inline-size). Without a container ancestor the queries never match and the grid… | diff --git a/docs/classes.md b/docs/classes.md index 1e306f30..188d6901 100644 --- a/docs/classes.md +++ b/docs/classes.md @@ -3,21 +3,26 @@ > **Generated** from source by `scripts/gen-class-reference.js` — > run `npm run docs:classes` to refresh. Do not edit by hand. -**174 .sf-classes, 40 .is-classes.** Every `.sf-*` layout/macro class and `.is-*` state class. +**179 .sf-classes, 40 .is-classes.** Every `.sf-*` layout/macro class and `.is-*` state class. See [architecture.md](architecture.md) for layer order and naming conventions. ## Layout primitives (`core/layout.css`) -120 classes. +125 classes. | Class | |---| | `.sf-alternate` | | `.sf-bento` | | `.sf-bento--2` | -| `.sf-bento--4` | +| `.sf-bento--3` | +| `.sf-bento--6` | | `.sf-bento--compact` | | `.sf-bento--tall` | +| `.sf-bento-featured` | +| `.sf-bento-full` | +| `.sf-bento-tall` | +| `.sf-bento-wide` | | `.sf-box` | | `.sf-breakout` | | `.sf-center` | diff --git a/docs/demo.html b/docs/demo.html index 4529a144..1243db5c 100644 --- a/docs/demo.html +++ b/docs/demo.html @@ -2216,7 +2216,16 @@
Override: --sf-bento-cols (default 3), --sf-bento-row (row height). Modifiers: .sf-bento--2, .sf-bento--4, .sf-bento--compact, .sf-bento--tall
Override: --sf-bento-cols (default 4), --sf-bento-row (row height). Column modifiers: .sf-bento--2, .sf-bento--3, .sf-bento--6. Row modifiers: .sf-bento--compact, .sf-bento--tall. Child span modifiers: .sf-bento-wide (col span 2), .sf-bento-tall (row span 2), .sf-bento-featured (2×2), .sf-bento-full (full width).
Column modifiers below use .sf-bento--2, .sf-bento--3, .sf-bento--6