diff --git a/CHANGELOG.md b/CHANGELOG.md index 01472c8d..28223162 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ### Breaking Changes - **tokens:** removed the fixed `--sf-animation-delay-1…5` stagger tokens, superseded by the new `.sf-stagger` utility + `--sf-stagger-step` knob. Replace `style="animation-delay: var(--sf-animation-delay-N)"` on hand-indexed children with a single `.sf-stagger` class on their parent (see `docs/motion.md`); to keep a fixed manual delay, use a literal (e.g. `animation-delay: 150ms`). +- **macros:** removed `.sf-corner-scoop` (and its `--top-left`/`--top-right`/`--bottom-left`/`--bottom-right` modifiers and `--sf-corner-scoop-size`/`--sf-corner-scoop-at` knobs). Judged too niche for the public API relative to its cost — the single absolute cut size needed per-element tuning across control- vs hero-sized boxes, and the mask clipped `box-shadow`/`border` and could not compose with the other mask-based macros. To keep a concave corner, apply the mask directly on the element: `style="-webkit-mask-image: radial-gradient(circle at 100% 0, transparent 24px, black 24.5px); mask-image: radial-gradient(circle at 100% 0, transparent 24px, black 24.5px)"`. - **layout:** renamed `.sf-bento--compact` / `.sf-bento--tall` (container row-height modifiers) to `.sf-bento--row-compact` / `.sf-bento--row-tall`, matching the `--sf-bento-row-*` tokens they set. The old names collided visually with the unrelated child modifier `.sf-bento-tall` (spans one item over 2 rows) — same word, one dash apart. Child span classes (`.sf-bento-wide/-full/-tall/-featured`) are unchanged. See `docs/migration.md`. ### Bug Fixes diff --git a/badges/badge-optimal.json b/badges/badge-optimal.json index 31ef54a3..46b854cc 100644 --- a/badges/badge-optimal.json +++ b/badges/badge-optimal.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "label": "optimal", - "message": "19.6 kB gzip", + "message": "19.5 kB gzip", "color": "brightgreen", "namedLogo": "css3" } diff --git a/configurator/src/data/api-index.generated.json b/configurator/src/data/api-index.generated.json index c4fa4e18..22ada5fb 100644 --- a/configurator/src/data/api-index.generated.json +++ b/configurator/src/data/api-index.generated.json @@ -2,22 +2,22 @@ "_sync": { "generatedBy": "configurator/scripts/sync-api.mjs", "source": "docs/api-index.json", - "tokensHash": "2733b25b05b9", + "tokensHash": "5a5ec9f40624", "bundles": [ "full", "optimal" ], "counts": { - "tokens": 756, + "tokens": 754, "byTier": { - "PUBLIC": 695, + "PUBLIC": 693, "PUBLIC-ADVANCED": 60, "INTERNAL": 1 }, "byCategory": { "Layout tokens": 53, "Core tokens": 623, - "Macro tokens": 34, + "Macro tokens": 32, "Component tokens": 46 } } @@ -7750,48 +7750,6 @@ "optimal" ] }, - { - "name": "--sf-corner-scoop-at", - "tier": "PUBLIC", - "role": "knob", - "namespace": "corner", - "category": "Macro tokens", - "group": "Concave corner", - "description": "Corner the .sf-corner-scoop mask cuts, as a radial-gradient origin (e.g. '100% 0' = top-right). Default: 100% 0.", - "note": "Corner the .sf-corner-scoop mask cuts, as a radial-gradient origin (e.g. '100% 0' = top-right). Default: 100% 0.", - "value": "100% 0", - "aliasOf": null, - "registered": false, - "syntax": null, - "fallbackOnly": false, - "optional": false, - "layer": "slashed.tokens", - "bundles": [ - "full", - "optimal" - ] - }, - { - "name": "--sf-corner-scoop-size", - "tier": "PUBLIC", - "role": "consumption", - "namespace": "corner", - "category": "Macro tokens", - "group": "Concave corner", - "description": "Cut radius of the .sf-corner-scoop mask. Default: var(--sf-radius-2xl).", - "note": "Cut radius of the .sf-corner-scoop mask. Default: var(--sf-radius-2xl).", - "value": "var(--sf-radius-2xl)", - "aliasOf": "--sf-radius-2xl", - "registered": false, - "syntax": null, - "fallbackOnly": false, - "optional": false, - "layer": "slashed.tokens", - "bundles": [ - "full", - "optimal" - ] - }, { "name": "--sf-cover-min-height", "tier": "PUBLIC", diff --git a/configurator/src/data/classes.generated.json b/configurator/src/data/classes.generated.json index d9632de9..c35a0c06 100644 --- a/configurator/src/data/classes.generated.json +++ b/configurator/src/data/classes.generated.json @@ -9,7 +9,7 @@ "selector": ".no-motion", "kind": "accessibility", "category": "Accessibility", - "group": "Reduced motion. Token override helps components that read", + "group": "", "description": "Suppresses all animations and transitions within the subtree. Apply to a container to create a reduced-motion zone without relying on the system preference.", "optional": false, "layer": "slashed.accessibility" @@ -19,7 +19,7 @@ "selector": ".no-print", "kind": "print", "category": "Print", - "group": "Print visibility utilities", + "group": "", "description": "Hides the element in @media print. Use on sidebars, navigation bars, and decorative elements that should not appear on paper.", "optional": false, "layer": "slashed.print" @@ -29,7 +29,7 @@ "selector": ".print-color-exact", "kind": "print", "category": "Print", - "group": "Opt-in colour treatment", + "group": "", "description": "Forces exact color rendering in print (print-color-adjust: exact). Use on charts and colored badges that must preserve their fill colors in print.", "optional": false, "layer": "slashed.print" @@ -39,7 +39,7 @@ "selector": ".print-no-color", "kind": "print", "category": "Print", - "group": "Opt-in colour treatment", + "group": "", "description": "Strips color information in print (print-color-adjust: economy). Defers to the printer's ink-saving mode for backgrounds and non-critical color fills.", "optional": false, "layer": "slashed.print" @@ -49,7 +49,7 @@ "selector": ".print-only", "kind": "print", "category": "Print", - "group": "Print visibility utilities", + "group": "", "description": "Hides the element on screen (display: none) but shows it in @media print. Use for print-only headers, footers, and supplementary content not needed on screen.", "optional": false, "layer": "slashed.print" @@ -59,7 +59,7 @@ "selector": ".sf-alternate", "kind": "layout", "category": "Layout primitives", - "group": "Alternate (zigzag / media-object)", + "group": "", "description": "Zigzag / alternating two-column layout. Even children align image-left/text-right; odd children flip. Collapses to a single column below the breakpoint.", "optional": false, "layer": "slashed.layout" @@ -69,7 +69,7 @@ "selector": ".sf-aspect", "kind": "macro", "category": "Macro classes", - "group": "Aspect", + "group": "", "description": "Sets aspect-ratio from a --sf-aspect-ratio scoped token. Override the token inline to get any ratio without a new class.", "optional": false, "layer": "slashed.macros" @@ -79,7 +79,7 @@ "selector": ".sf-bento", "kind": "layout", "category": "Layout primitives", - "group": ".sf-card", + "group": "", "description": "Auto-fill bento grid for card dashboards. Children span 1 column by default; use span modifiers (sf-bento-wide, sf-bento-tall, sf-bento-full, sf-bento-featured) to break the grid.", "optional": false, "layer": "slashed.layout" @@ -89,7 +89,7 @@ "selector": ".sf-bento--2", "kind": "layout", "category": "Layout primitives", - "group": "Bento grid", + "group": "", "description": "Bento grid variant with a 2-column base layout.", "optional": false, "layer": "slashed.layout" @@ -99,7 +99,7 @@ "selector": ".sf-bento--3", "kind": "layout", "category": "Layout primitives", - "group": "Bento grid", + "group": "", "description": "Bento grid variant with a 3-column base layout.", "optional": false, "layer": "slashed.layout" @@ -109,7 +109,7 @@ "selector": ".sf-bento--6", "kind": "layout", "category": "Layout primitives", - "group": "Bento grid", + "group": "", "description": "Bento grid variant with a 6-column base layout.", "optional": false, "layer": "slashed.layout" @@ -139,7 +139,7 @@ "selector": ".sf-bento-featured", "kind": "layout", "category": "Layout primitives", - "group": "Bento grid", + "group": "", "description": "Span modifier for a bento item: takes up 2×2 cells (featured hero placement).", "optional": false, "layer": "slashed.layout" @@ -149,7 +149,7 @@ "selector": ".sf-bento-full", "kind": "layout", "category": "Layout primitives", - "group": "Bento grid", + "group": "", "description": "Span modifier for a bento item: stretches across all columns (full-width banner).", "optional": false, "layer": "slashed.layout" @@ -159,7 +159,7 @@ "selector": ".sf-bento-tall", "kind": "layout", "category": "Layout primitives", - "group": "Bento grid", + "group": "", "description": "Span modifier for a bento item: doubles the row height (tall card).", "optional": false, "layer": "slashed.layout" @@ -169,7 +169,7 @@ "selector": ".sf-bento-wide", "kind": "layout", "category": "Layout primitives", - "group": "Bento grid", + "group": "", "description": "Span modifier for a bento item: spans 2 columns (wide card).", "optional": false, "layer": "slashed.layout" @@ -189,7 +189,7 @@ "selector": ".sf-box", "kind": "layout", "category": "Layout primitives", - "group": "Box", + "group": "", "description": "Minimal padding container that applies --sf-component-pad on all sides. The simplest layout primitive for adding breathing room.", "optional": false, "layer": "slashed.layout" @@ -199,7 +199,7 @@ "selector": ".sf-breakout", "kind": "layout", "category": "Layout primitives", - "group": "Content grid (breakout pattern)", + "group": "", "description": "Breaks a child element out of a parent sf-content-grid, spanning full bleed (or a named grid area) regardless of the parent column. Useful for full-width sections inside constrained prose.", "optional": false, "layer": "slashed.layout" @@ -509,7 +509,7 @@ "selector": ".sf-center", "kind": "layout", "category": "Layout primitives", - "group": ".sf-card", + "group": "", "description": "Centers children both horizontally and vertically using flexbox. Optionally add sf-center--intrinsic to size the container to its content.", "optional": false, "layer": "slashed.layout" @@ -519,7 +519,7 @@ "selector": ".sf-center--intrinsic", "kind": "layout", "category": "Layout primitives", - "group": "Center", + "group": "", "description": "Modifier for sf-center: constrains the container to the natural width of its children (no stretching to fill available space).", "optional": false, "layer": "slashed.layout" @@ -529,7 +529,7 @@ "selector": ".sf-clickable-parent", "kind": "accessibility", "category": "Accessibility", - "group": "Clickable-parent", + "group": "", "description": "Makes the entire card or list-item clickable via an absolutely-positioned child overlay link. Apply to the container; place sf-clickable-parent__overlay on the .", "optional": false, "layer": "slashed.accessibility" @@ -539,7 +539,7 @@ "selector": ".sf-clickable-parent__overlay", "kind": "accessibility", "category": "Accessibility", - "group": "Clickable-parent", + "group": "", "description": "The full-bleed overlay link inside an sf-clickable-parent. Stretches to cover the parent and uses pointer-events to let interactive children keep their own clicks.", "optional": false, "layer": "slashed.accessibility" @@ -549,7 +549,7 @@ "selector": ".sf-cluster", "kind": "layout", "category": "Layout primitives", - "group": ".sf-card", + "group": "", "description": "Flex-wrap row of variable-width items with automatic gap. Children wrap when the container is too narrow. Use for tag lists, button groups, and icon rows.", "optional": false, "layer": "slashed.layout" @@ -559,7 +559,7 @@ "selector": ".sf-cluster--2xl", "kind": "layout", "category": "Layout primitives", - "group": "Cluster", + "group": "", "description": "Cluster variant with 2xl gap between items.", "optional": false, "layer": "slashed.layout" @@ -569,7 +569,7 @@ "selector": ".sf-cluster--between", "kind": "layout", "category": "Layout primitives", - "group": "Cluster", + "group": "", "description": "Cluster variant that distributes items with space-between alignment.", "optional": false, "layer": "slashed.layout" @@ -579,7 +579,7 @@ "selector": ".sf-cluster--center", "kind": "layout", "category": "Layout primitives", - "group": "Cluster", + "group": "", "description": "Cluster variant that centers the item row horizontally.", "optional": false, "layer": "slashed.layout" @@ -589,7 +589,7 @@ "selector": ".sf-cluster--end", "kind": "layout", "category": "Layout primitives", - "group": "Cluster", + "group": "", "description": "Cluster variant that aligns items to the inline end (right in LTR).", "optional": false, "layer": "slashed.layout" @@ -599,7 +599,7 @@ "selector": ".sf-cluster--l", "kind": "layout", "category": "Layout primitives", - "group": "Cluster", + "group": "", "description": "Cluster variant with large (l) gap between items.", "optional": false, "layer": "slashed.layout" @@ -609,7 +609,7 @@ "selector": ".sf-cluster--m", "kind": "layout", "category": "Layout primitives", - "group": "Cluster", + "group": "", "description": "Cluster variant with medium (m) gap between items.", "optional": false, "layer": "slashed.layout" @@ -619,7 +619,7 @@ "selector": ".sf-cluster--no-wrap", "kind": "layout", "category": "Layout primitives", - "group": "Cluster", + "group": "", "description": "Cluster variant that prevents item wrapping (single-line row).", "optional": false, "layer": "slashed.layout" @@ -629,7 +629,7 @@ "selector": ".sf-cluster--s", "kind": "layout", "category": "Layout primitives", - "group": "Cluster", + "group": "", "description": "Cluster variant with small (s) gap between items.", "optional": false, "layer": "slashed.layout" @@ -639,7 +639,7 @@ "selector": ".sf-cluster--xl", "kind": "layout", "category": "Layout primitives", - "group": "Cluster", + "group": "", "description": "Cluster variant with xl gap between items.", "optional": false, "layer": "slashed.layout" @@ -649,7 +649,7 @@ "selector": ".sf-cluster--xs", "kind": "layout", "category": "Layout primitives", - "group": "Cluster", + "group": "", "description": "Cluster variant with xs gap between items.", "optional": false, "layer": "slashed.layout" @@ -659,7 +659,7 @@ "selector": ".sf-color-pulse", "kind": "motion", "category": "Motion / animation", - "group": "@property color animation", + "group": "", "description": "Applies a gentle color-pulse animation to draw attention to a dynamic value change (e.g. a counter updating). Scoped to users who have not requested reduced motion.", "optional": false, "layer": "slashed.motion" @@ -669,7 +669,7 @@ "selector": ".sf-container", "kind": "layout", "category": "Layout primitives", - "group": "Section", + "group": "", "description": "Max-width page container, centered with auto side gutters. Establishes a named inline-size container (cq-container) for container queries. Default width is --sf-container-m.", "optional": false, "layer": "slashed.layout" @@ -679,7 +679,7 @@ "selector": ".sf-container--full", "kind": "layout", "category": "Layout primitives", - "group": "Container", + "group": "", "description": "Container variant that spans the full viewport width (no max-width cap).", "optional": false, "layer": "slashed.layout" @@ -689,7 +689,7 @@ "selector": ".sf-container--narrow", "kind": "layout", "category": "Layout primitives", - "group": "Container", + "group": "", "description": "Container variant with a narrower max-width (--sf-container-s). Use for single-column prose and forms.", "optional": false, "layer": "slashed.layout" @@ -699,7 +699,7 @@ "selector": ".sf-container--prose", "kind": "layout", "category": "Layout primitives", - "group": "Container", + "group": "", "description": "Container variant with a prose-optimised max-width (--sf-container-prose). Ideal for long-form reading content.", "optional": false, "layer": "slashed.layout" @@ -709,7 +709,7 @@ "selector": ".sf-container--wide", "kind": "layout", "category": "Layout primitives", - "group": "Container", + "group": "", "description": "Container variant with a wider max-width (--sf-container-l). Use for dashboards and wide media.", "optional": false, "layer": "slashed.layout" @@ -719,7 +719,7 @@ "selector": ".sf-content-auto", "kind": "macro", "category": "Macro classes", - "group": "Content visibility", + "group": "", "description": "Sets content-visibility: auto on the element. The browser skips rendering off-screen content, improving LCP for long pages.", "optional": false, "layer": "slashed.macros" @@ -729,67 +729,17 @@ "selector": ".sf-content-grid", "kind": "layout", "category": "Layout primitives", - "group": "Content grid (breakout pattern)", + "group": "", "description": "Holy-grail content grid with named areas: full-bleed, popout, and content columns. Use sf-breakout on children to escape the content column.", "optional": false, "layer": "slashed.layout" }, - { - "name": "sf-corner-scoop", - "selector": ".sf-corner-scoop", - "kind": "macro", - "category": "Macro classes", - "group": "", - "description": "Concave \"scooped\" corner cut with a radial-gradient mask; defaults to the top-right corner (--sf-corner-scoop-at). Add a placement modifier to move it.", - "optional": false, - "layer": "slashed.macros" - }, - { - "name": "sf-corner-scoop--bottom-left", - "selector": ".sf-corner-scoop--bottom-left", - "kind": "macro", - "category": "Macro classes", - "group": "", - "description": "Places the concave corner scoop at the bottom-left corner.", - "optional": false, - "layer": "slashed.macros" - }, - { - "name": "sf-corner-scoop--bottom-right", - "selector": ".sf-corner-scoop--bottom-right", - "kind": "macro", - "category": "Macro classes", - "group": "", - "description": "Places the concave corner scoop at the bottom-right corner.", - "optional": false, - "layer": "slashed.macros" - }, - { - "name": "sf-corner-scoop--top-left", - "selector": ".sf-corner-scoop--top-left", - "kind": "macro", - "category": "Macro classes", - "group": "", - "description": "Places the concave corner scoop at the top-left corner.", - "optional": false, - "layer": "slashed.macros" - }, - { - "name": "sf-corner-scoop--top-right", - "selector": ".sf-corner-scoop--top-right", - "kind": "macro", - "category": "Macro classes", - "group": "", - "description": "Places the concave corner scoop at the top-right corner.", - "optional": false, - "layer": "slashed.macros" - }, { "name": "sf-cover", "selector": ".sf-cover", "kind": "layout", "category": "Layout primitives", - "group": ".sf-card", + "group": "", "description": "Vertically stretches to at least a viewport height with a centered element (sf-cover__center). Typical use: hero sections.", "optional": false, "layer": "slashed.layout" @@ -799,7 +749,7 @@ "selector": ".sf-cover__center", "kind": "layout", "category": "Layout primitives", - "group": "Cover", + "group": "", "description": "The centered focal element inside an sf-cover. Stays vertically centered even when the cover content is shorter than the viewport.", "optional": false, "layer": "slashed.layout" @@ -809,7 +759,7 @@ "selector": ".sf-cover--max", "kind": "layout", "category": "Layout primitives", - "group": "Cover", + "group": "", "description": "Cover variant that uses a max-height instead of min-height for the viewport constraint.", "optional": false, "layer": "slashed.layout" @@ -819,7 +769,7 @@ "selector": ".sf-cover--min", "kind": "layout", "category": "Layout primitives", - "group": "Cover", + "group": "", "description": "Cover variant that reduces the minimum height to half a viewport.", "optional": false, "layer": "slashed.layout" @@ -829,7 +779,7 @@ "selector": ".sf-cover--padding-l", "kind": "layout", "category": "Layout primitives", - "group": "Cover", + "group": "", "description": "Cover variant with large vertical padding above and below the centered content.", "optional": false, "layer": "slashed.layout" @@ -839,7 +789,7 @@ "selector": ".sf-cover--padding-s", "kind": "layout", "category": "Layout primitives", - "group": "Cover", + "group": "", "description": "Cover variant with small vertical padding above and below the centered content.", "optional": false, "layer": "slashed.layout" @@ -849,7 +799,7 @@ "selector": ".sf-cq", "kind": "layout", "category": "Layout primitives", - "group": "Container query context", + "group": "", "description": "Assigns an inline-size container context to any element. Children can then use @container rules or container-query-aware tokens.", "optional": false, "layer": "slashed.layout" @@ -859,7 +809,7 @@ "selector": ".sf-divide", "kind": "layout", "category": "Layout primitives", - "group": "Divide", + "group": "", "description": "Rules between direct children (a border on each child after the first), reusing .sf-divider's tokens — no per-gap markup needed.", "optional": false, "layer": "slashed.layout" @@ -869,7 +819,7 @@ "selector": ".sf-divide--vertical", "kind": "layout", "category": "Layout primitives", - "group": "Divide", + "group": "", "description": "Vertical rules between direct children (inline-start borders), for row/horizontal layouts.", "optional": false, "layer": "slashed.layout" @@ -879,7 +829,7 @@ "selector": ".sf-divider", "kind": "layout", "category": "Layout primitives", - "group": "Divider", + "group": "", "description": "Horizontal rule (divider line). Uses --sf-divider-* tokens for color, width, and style. Modifiers change dash style or orientation.", "optional": false, "layer": "slashed.layout" @@ -889,7 +839,7 @@ "selector": ".sf-divider--dashed", "kind": "layout", "category": "Layout primitives", - "group": "Divider", + "group": "", "description": "Divider variant with a dashed stroke.", "optional": false, "layer": "slashed.layout" @@ -899,7 +849,7 @@ "selector": ".sf-divider--dotted", "kind": "layout", "category": "Layout primitives", - "group": "Divider", + "group": "", "description": "Divider variant with a dotted stroke.", "optional": false, "layer": "slashed.layout" @@ -909,7 +859,7 @@ "selector": ".sf-divider--gradient", "kind": "layout", "category": "Layout primitives", - "group": "Divider", + "group": "", "description": "Divider variant rendered as a gradient that fades to transparent at both ends.", "optional": false, "layer": "slashed.layout" @@ -919,7 +869,7 @@ "selector": ".sf-divider--soft", "kind": "layout", "category": "Layout primitives", - "group": "Divider", + "group": "", "description": "Divider variant with reduced opacity (subtle separator).", "optional": false, "layer": "slashed.layout" @@ -929,7 +879,7 @@ "selector": ".sf-divider--strong", "kind": "layout", "category": "Layout primitives", - "group": "Divider", + "group": "", "description": "Divider variant with stronger/darker color for a more prominent separator.", "optional": false, "layer": "slashed.layout" @@ -939,7 +889,7 @@ "selector": ".sf-divider--vertical", "kind": "layout", "category": "Layout primitives", - "group": "Divider", + "group": "", "description": "Divider variant rendered as a vertical line. Use inside flex or grid containers.", "optional": false, "layer": "slashed.layout" @@ -999,7 +949,7 @@ "selector": ".sf-entrance--fade", "kind": "motion", "category": "Motion / animation", - "group": "Scroll-driven entrances", + "group": "", "description": "Scroll-driven entrance: element fades in as it enters the viewport. Animation tied to scroll progress via animation-timeline.", "optional": false, "layer": "slashed.motion" @@ -1009,7 +959,7 @@ "selector": ".sf-entrance--fade-down", "kind": "motion", "category": "Motion / animation", - "group": "Scroll-driven entrances", + "group": "", "description": "Scroll-driven entrance: element fades in while moving downward into position.", "optional": false, "layer": "slashed.motion" @@ -1019,7 +969,7 @@ "selector": ".sf-entrance--fade-left", "kind": "motion", "category": "Motion / animation", - "group": "Scroll-driven entrances", + "group": "", "description": "Scroll-driven entrance: element fades in while moving from the right toward the left.", "optional": false, "layer": "slashed.motion" @@ -1029,7 +979,7 @@ "selector": ".sf-entrance--fade-right", "kind": "motion", "category": "Motion / animation", - "group": "Scroll-driven entrances", + "group": "", "description": "Scroll-driven entrance: element fades in while moving from the left toward the right.", "optional": false, "layer": "slashed.motion" @@ -1039,7 +989,7 @@ "selector": ".sf-entrance--fade-up", "kind": "motion", "category": "Motion / animation", - "group": "Scroll-driven entrances", + "group": "", "description": "Scroll-driven entrance: element fades in while moving upward into position.", "optional": false, "layer": "slashed.motion" @@ -1049,7 +999,7 @@ "selector": ".sf-entrance--scale-up", "kind": "motion", "category": "Motion / animation", - "group": "Scroll-driven entrances", + "group": "", "description": "Scroll-driven entrance: element fades in while scaling up from a slightly smaller size.", "optional": false, "layer": "slashed.motion" @@ -1059,7 +1009,7 @@ "selector": ".sf-equal", "kind": "layout", "category": "Layout primitives", - "group": "Equal columns (intrinsically responsive)", + "group": "", "description": "Flowing CSS multi-column layout (not a grid) — content distributes across columns like a newspaper instead of sitting in fixed cells. Reach for .sf-grid/.sf-grid--fit for discrete grid cells instead.", "optional": false, "layer": "slashed.layout" @@ -1069,7 +1019,7 @@ "selector": ".sf-equal--2", "kind": "layout", "category": "Layout primitives", - "group": "Equal columns (intrinsically responsive)", + "group": "", "description": "Equal-columns variant locked to column-count: 2.", "optional": false, "layer": "slashed.layout" @@ -1079,7 +1029,7 @@ "selector": ".sf-equal--3", "kind": "layout", "category": "Layout primitives", - "group": "Equal columns (intrinsically responsive)", + "group": "", "description": "Equal-columns variant locked to column-count: 3.", "optional": false, "layer": "slashed.layout" @@ -1089,7 +1039,7 @@ "selector": ".sf-equal--4", "kind": "layout", "category": "Layout primitives", - "group": "Equal columns (intrinsically responsive)", + "group": "", "description": "Equal-columns variant locked to column-count: 4.", "optional": false, "layer": "slashed.layout" @@ -1099,7 +1049,7 @@ "selector": ".sf-equal--6", "kind": "layout", "category": "Layout primitives", - "group": "Equal columns (intrinsically responsive)", + "group": "", "description": "Equal-columns variant locked to column-count: 6.", "optional": false, "layer": "slashed.layout" @@ -1109,7 +1059,7 @@ "selector": ".sf-equal-height", "kind": "macro", "category": "Macro classes", - "group": "Equal height", + "group": "", "description": "Forces all flex children to equal height (align-items: stretch). Use on a flex row to make cards in a grid share the tallest card's height.", "optional": false, "layer": "slashed.macros" @@ -1179,7 +1129,7 @@ "selector": ".sf-fade-in", "kind": "motion", "category": "Motion / animation", - "group": "Animation presets", + "group": "", "description": "One-shot fade-in animation (opacity 0 → 1). Scoped to no-preference so it stops automatically for reduced-motion users.", "optional": false, "layer": "slashed.motion" @@ -1189,7 +1139,7 @@ "selector": ".sf-fade-out", "kind": "motion", "category": "Motion / animation", - "group": "Animation presets", + "group": "", "description": "One-shot fade-out animation (opacity 1 → 0). Scoped to no-preference.", "optional": false, "layer": "slashed.motion" @@ -1199,7 +1149,7 @@ "selector": ".sf-flow", "kind": "macro", "category": "Macro classes", - "group": "Flow", + "group": "", "description": "Applies --sf-flow-space as margin-block-start to all direct children except the first. Establishes consistent vertical rhythm in prose-like containers.", "optional": false, "layer": "slashed.macros" @@ -1219,7 +1169,7 @@ "selector": ".sf-focus-parent", "kind": "accessibility", "category": "Accessibility", - "group": "Focus-parent", + "group": "", "description": "Forwards focus-visible styling to this container when any descendant is keyboard-focused. Useful for custom controls that wrap a visually-hidden .", "optional": false, "layer": "slashed.accessibility" @@ -1229,7 +1179,7 @@ "selector": ".sf-focus-shadow", "kind": "accessibility", "category": "Accessibility", - "group": "Focus-shadow opt-in", + "group": "", "description": "Applies the standard focus ring as a box-shadow to any element. Use on custom controls where the native :focus-visible ring doesn't render correctly.", "optional": false, "layer": "slashed.accessibility" @@ -1239,7 +1189,7 @@ "selector": ".sf-frame", "kind": "layout", "category": "Layout primitives", - "group": ".sf-card", + "group": "", "description": "Aspect-ratio container for media (images, video, maps). Children fill and cover the fixed-ratio box. Default ratio is 16:9.", "optional": false, "layer": "slashed.layout" @@ -1249,7 +1199,7 @@ "selector": ".sf-frame--3-2", "kind": "layout", "category": "Layout primitives", - "group": "Frame", + "group": "", "description": "Frame variant locked to a 3:2 aspect ratio.", "optional": false, "layer": "slashed.layout" @@ -1259,7 +1209,7 @@ "selector": ".sf-frame--4-3", "kind": "layout", "category": "Layout primitives", - "group": "Frame", + "group": "", "description": "Frame variant locked to a 4:3 aspect ratio.", "optional": false, "layer": "slashed.layout" @@ -1269,7 +1219,7 @@ "selector": ".sf-frame--cinema", "kind": "layout", "category": "Layout primitives", - "group": "Frame", + "group": "", "description": "Frame variant locked to a cinematic 21:9 aspect ratio.", "optional": false, "layer": "slashed.layout" @@ -1279,7 +1229,7 @@ "selector": ".sf-frame--golden", "kind": "layout", "category": "Layout primitives", - "group": "Frame", + "group": "", "description": "Frame variant locked to the golden ratio (1.618:1).", "optional": false, "layer": "slashed.layout" @@ -1289,7 +1239,7 @@ "selector": ".sf-frame--portrait", "kind": "layout", "category": "Layout primitives", - "group": "Frame", + "group": "", "description": "Frame variant locked to a portrait 2:3 aspect ratio.", "optional": false, "layer": "slashed.layout" @@ -1299,7 +1249,7 @@ "selector": ".sf-frame--square", "kind": "layout", "category": "Layout primitives", - "group": "Frame", + "group": "", "description": "Frame variant locked to a square 1:1 aspect ratio.", "optional": false, "layer": "slashed.layout" @@ -1309,7 +1259,7 @@ "selector": ".sf-frame--video", "kind": "layout", "category": "Layout primitives", - "group": "Frame", + "group": "", "description": "Frame variant locked to the standard 16:9 video aspect ratio.", "optional": false, "layer": "slashed.layout" @@ -1319,7 +1269,7 @@ "selector": ".sf-full-bleed", "kind": "layout", "category": "Layout primitives", - "group": "Content grid (breakout pattern)", + "group": "", "description": "Forces an element to span the full viewport width, breaking out of any centered container. Use for full-bleed images and section backgrounds.", "optional": false, "layer": "slashed.layout" @@ -1329,7 +1279,7 @@ "selector": ".sf-gap", "kind": "layout", "category": "Layout primitives", - "group": "Gap", + "group": "", "description": "Injects the default --sf-gap into an existing flex or grid container without imposing display:flex itself. Use when the parent is already a flex or grid.", "optional": false, "layer": "slashed.layout" @@ -1339,7 +1289,7 @@ "selector": ".sf-gap--2xl", "kind": "layout", "category": "Layout primitives", - "group": "Gap", + "group": "", "description": "Gap injection variant with 2xl gap value.", "optional": false, "layer": "slashed.layout" @@ -1349,7 +1299,7 @@ "selector": ".sf-gap--l", "kind": "layout", "category": "Layout primitives", - "group": "Gap", + "group": "", "description": "Gap injection variant with large (l) gap value.", "optional": false, "layer": "slashed.layout" @@ -1359,7 +1309,7 @@ "selector": ".sf-gap--m", "kind": "layout", "category": "Layout primitives", - "group": "Gap", + "group": "", "description": "Gap injection variant with medium (m) gap value.", "optional": false, "layer": "slashed.layout" @@ -1369,7 +1319,7 @@ "selector": ".sf-gap--s", "kind": "layout", "category": "Layout primitives", - "group": "Gap", + "group": "", "description": "Gap injection variant with small (s) gap value.", "optional": false, "layer": "slashed.layout" @@ -1379,7 +1329,7 @@ "selector": ".sf-gap--xl", "kind": "layout", "category": "Layout primitives", - "group": "Gap", + "group": "", "description": "Gap injection variant with xl gap value.", "optional": false, "layer": "slashed.layout" @@ -1389,7 +1339,7 @@ "selector": ".sf-gap--xs", "kind": "layout", "category": "Layout primitives", - "group": "Gap", + "group": "", "description": "Gap injection variant with xs gap value.", "optional": false, "layer": "slashed.layout" @@ -1399,7 +1349,7 @@ "selector": ".sf-grid", "kind": "layout", "category": "Layout primitives", - "group": ".sf-card", + "group": "", "description": "Auto-fill CSS grid. Columns are sized with RAM pattern (Repeat, Auto-fill, Minmax) and wrap automatically. Default column min-width is --sf-grid-min-col.", "optional": false, "layer": "slashed.layout" @@ -1409,7 +1359,7 @@ "selector": ".sf-grid--2xl", "kind": "layout", "category": "Layout primitives", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with a 2xl minimum column width.", "optional": false, "layer": "slashed.layout" @@ -1419,7 +1369,7 @@ "selector": ".sf-grid--dense", "kind": "layout", "category": "Layout primitives", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with grid-auto-flow: dense, allowing the grid to fill holes created by span modifiers.", "optional": false, "layer": "slashed.layout" @@ -1429,7 +1379,7 @@ "selector": ".sf-grid--fit", "kind": "layout", "category": "Layout primitives", - "group": "Grid (auto)", + "group": "", "description": "Grid variant that switches from auto-fill to auto-fit, collapsing empty columns.", "optional": false, "layer": "slashed.layout" @@ -1439,7 +1389,7 @@ "selector": ".sf-grid--l", "kind": "layout", "category": "Layout primitives", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with a large (l) minimum column width.", "optional": false, "layer": "slashed.layout" @@ -1449,7 +1399,7 @@ "selector": ".sf-grid--m", "kind": "layout", "category": "Layout primitives", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with a medium (m) minimum column width.", "optional": false, "layer": "slashed.layout" @@ -1459,7 +1409,7 @@ "selector": ".sf-grid--s", "kind": "layout", "category": "Layout primitives", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with a small (s) minimum column width.", "optional": false, "layer": "slashed.layout" @@ -1469,7 +1419,7 @@ "selector": ".sf-grid--xl", "kind": "layout", "category": "Layout primitives", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with an xl minimum column width.", "optional": false, "layer": "slashed.layout" @@ -1479,7 +1429,7 @@ "selector": ".sf-grid--xs", "kind": "layout", "category": "Layout primitives", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with an xs minimum column width.", "optional": false, "layer": "slashed.layout" @@ -1489,7 +1439,7 @@ "selector": ".sf-grid-cols-1", "kind": "layout", "category": "Layout primitives", - "group": "Single-column grid", + "group": "", "description": "Single-column layout (forces all children to one column).", "optional": false, "layer": "slashed.layout" @@ -1499,7 +1449,7 @@ "selector": ".sf-grid-cols-1-2", "kind": "layout", "category": "Layout primitives", - "group": "Ratio grids", + "group": "", "description": "Two-column ratio grid: first child takes 1fr, second takes 2fr. Container-query responsive.", "optional": false, "layer": "slashed.layout" @@ -1509,7 +1459,7 @@ "selector": ".sf-grid-cols-1-3", "kind": "layout", "category": "Layout primitives", - "group": "Ratio grids", + "group": "", "description": "Two-column ratio grid: first child takes 1fr, second takes 3fr. Container-query responsive.", "optional": false, "layer": "slashed.layout" @@ -1519,7 +1469,7 @@ "selector": ".sf-grid-cols-2", "kind": "layout", "category": "Layout primitives", - "group": "Fixed column grids (container-query responsive)", + "group": "", "description": "Responsive 2-column fixed grid. Uses container queries to collapse to one column on narrow containers.", "optional": false, "layer": "slashed.layout" @@ -1529,7 +1479,7 @@ "selector": ".sf-grid-cols-2-1", "kind": "layout", "category": "Layout primitives", - "group": "Ratio grids", + "group": "", "description": "Two-column ratio grid: first child takes 2fr, second takes 1fr. Container-query responsive.", "optional": false, "layer": "slashed.layout" @@ -1539,7 +1489,7 @@ "selector": ".sf-grid-cols-3", "kind": "layout", "category": "Layout primitives", - "group": "Fixed column grids (container-query responsive)", + "group": "", "description": "Responsive 3-column fixed grid. Collapses progressively on narrow containers.", "optional": false, "layer": "slashed.layout" @@ -1549,7 +1499,7 @@ "selector": ".sf-grid-cols-3-1", "kind": "layout", "category": "Layout primitives", - "group": "Ratio grids", + "group": "", "description": "Two-column ratio grid: first child takes 3fr, second takes 1fr. Container-query responsive.", "optional": false, "layer": "slashed.layout" @@ -1559,7 +1509,7 @@ "selector": ".sf-grid-cols-4", "kind": "layout", "category": "Layout primitives", - "group": "Fixed column grids (container-query responsive)", + "group": "", "description": "Responsive 4-column fixed grid. Collapses progressively on narrow containers.", "optional": false, "layer": "slashed.layout" @@ -1569,7 +1519,7 @@ "selector": ".sf-grid-cols-6", "kind": "layout", "category": "Layout primitives", - "group": "Fixed column grids (container-query responsive)", + "group": "", "description": "Responsive 6-column fixed grid. Collapses progressively on narrow containers.", "optional": false, "layer": "slashed.layout" @@ -1579,7 +1529,7 @@ "selector": ".sf-grid-flex", "kind": "layout", "category": "Layout primitives", - "group": ".sf-card", + "group": "", "description": "Flexbox alternative to .sf-grid for item counts that don't divide evenly: leftover last-row items stretch to fill the row by default, or stay fixed-width and centered with --center.", "optional": false, "layer": "slashed.layout" @@ -1589,7 +1539,7 @@ "selector": ".sf-grid-flex--2xl", "kind": "layout", "category": "Layout primitives", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant with a 2xl minimum item width.", "optional": false, "layer": "slashed.layout" @@ -1599,7 +1549,7 @@ "selector": ".sf-grid-flex--center", "kind": "layout", "category": "Layout primitives", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant that keeps last-row leftover items fixed-width and centered instead of stretching.", "optional": false, "layer": "slashed.layout" @@ -1609,7 +1559,7 @@ "selector": ".sf-grid-flex--l", "kind": "layout", "category": "Layout primitives", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant with a large (l) minimum item width.", "optional": false, "layer": "slashed.layout" @@ -1619,7 +1569,7 @@ "selector": ".sf-grid-flex--m", "kind": "layout", "category": "Layout primitives", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant with a medium (m) minimum item width.", "optional": false, "layer": "slashed.layout" @@ -1629,7 +1579,7 @@ "selector": ".sf-grid-flex--s", "kind": "layout", "category": "Layout primitives", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant with a small (s) minimum item width.", "optional": false, "layer": "slashed.layout" @@ -1639,7 +1589,7 @@ "selector": ".sf-grid-flex--xl", "kind": "layout", "category": "Layout primitives", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant with an xl minimum item width.", "optional": false, "layer": "slashed.layout" @@ -1649,7 +1599,7 @@ "selector": ".sf-grid-flex--xs", "kind": "layout", "category": "Layout primitives", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant with an xs minimum item width.", "optional": false, "layer": "slashed.layout" @@ -1829,7 +1779,7 @@ "selector": ".sf-icon", "kind": "layout", "category": "Layout primitives", - "group": "Icon", + "group": "", "description": "Inline icon sizing primitive. Sets width and height to --sf-icon-m via em-based tokens so the icon scales with the surrounding text.", "optional": false, "layer": "slashed.layout" @@ -1839,7 +1789,7 @@ "selector": ".sf-icon--2xl", "kind": "layout", "category": "Layout primitives", - "group": "Icon", + "group": "", "description": "Icon variant sized to --sf-icon-2xl (extra-extra-large).", "optional": false, "layer": "slashed.layout" @@ -1849,7 +1799,7 @@ "selector": ".sf-icon--boxed", "kind": "layout", "category": "Layout primitives", - "group": "Icon", + "group": "", "description": "Icon variant with a square bordered box background. Useful for standalone icon buttons and feature icons.", "optional": false, "layer": "slashed.layout" @@ -1859,7 +1809,7 @@ "selector": ".sf-icon--l", "kind": "layout", "category": "Layout primitives", - "group": "Icon", + "group": "", "description": "Icon variant sized to --sf-icon-l (large).", "optional": false, "layer": "slashed.layout" @@ -1869,7 +1819,7 @@ "selector": ".sf-icon--m", "kind": "layout", "category": "Layout primitives", - "group": "Icon", + "group": "", "description": "Icon variant sized to --sf-icon-m (medium, same as base sf-icon).", "optional": false, "layer": "slashed.layout" @@ -1879,7 +1829,7 @@ "selector": ".sf-icon--s", "kind": "layout", "category": "Layout primitives", - "group": "Icon", + "group": "", "description": "Icon variant sized to --sf-icon-s (small).", "optional": false, "layer": "slashed.layout" @@ -1889,7 +1839,7 @@ "selector": ".sf-icon--xl", "kind": "layout", "category": "Layout primitives", - "group": "Icon", + "group": "", "description": "Icon variant sized to --sf-icon-xl (extra-large).", "optional": false, "layer": "slashed.layout" @@ -1899,7 +1849,7 @@ "selector": ".sf-icon--xs", "kind": "layout", "category": "Layout primitives", - "group": "Icon", + "group": "", "description": "Icon variant sized to --sf-icon-xs (extra-small).", "optional": false, "layer": "slashed.layout" @@ -1909,7 +1859,7 @@ "selector": ".sf-imposter", "kind": "layout", "category": "Layout primitives", - "group": "Imposter", + "group": "", "description": "Absolutely positions an element at the center of its nearest positioned ancestor. Use for overlays, badges, and floating labels.", "optional": false, "layer": "slashed.layout" @@ -1919,7 +1869,7 @@ "selector": ".sf-imposter--contain", "kind": "layout", "category": "Layout primitives", - "group": "Imposter", + "group": "", "description": "Imposter variant that clamps the element within the bounds of its parent using overflow:hidden on the parent.", "optional": false, "layer": "slashed.layout" @@ -1929,7 +1879,7 @@ "selector": ".sf-imposter--fixed", "kind": "layout", "category": "Layout primitives", - "group": "Imposter", + "group": "", "description": "Imposter variant that uses position:fixed instead of absolute. Use for viewport-level overlays and modals.", "optional": false, "layer": "slashed.layout" @@ -2219,7 +2169,7 @@ "selector": ".sf-line-clamp-2", "kind": "macro", "category": "Macro classes", - "group": "Truncate / line-clamp", + "group": "", "description": "Clamps text to 2 lines with an ellipsis. Applies -webkit-line-clamp: 2.", "optional": false, "layer": "slashed.macros" @@ -2229,7 +2179,7 @@ "selector": ".sf-line-clamp-3", "kind": "macro", "category": "Macro classes", - "group": "Truncate / line-clamp", + "group": "", "description": "Clamps text to 3 lines with an ellipsis. Applies -webkit-line-clamp: 3.", "optional": false, "layer": "slashed.macros" @@ -2239,7 +2189,7 @@ "selector": ".sf-line-clamp-N", "kind": "macro", "category": "Macro classes", - "group": "Truncate / line-clamp", + "group": "", "description": "Clamps text to a custom N lines. Set --sf-line-clamp on the element to control the number of visible lines.", "optional": false, "layer": "slashed.macros" @@ -2249,7 +2199,7 @@ "selector": ".sf-link--reverse", "kind": "macro", "category": "Macro classes", - "group": "Link variants", + "group": "", "description": "Link color modifier: reverses the default link color to work on dark/inverted backgrounds. Sets color to --sf-color-text--inverse.", "optional": false, "layer": "slashed.macros" @@ -2259,7 +2209,7 @@ "selector": ".sf-link--subtle", "kind": "macro", "category": "Macro classes", - "group": "Link variants", + "group": "", "description": "Link color modifier: renders the link in the body text color instead of the default action color. Underline still indicates the link on hover.", "optional": false, "layer": "slashed.macros" @@ -2269,7 +2219,7 @@ "selector": ".sf-link-external", "kind": "macro", "category": "Macro classes", - "group": "External link indication", + "group": "", "description": "Automatically appends an external-link icon (via ::after content) to indicate the link opens in a new tab or goes to an external domain.", "optional": false, "layer": "slashed.macros" @@ -2339,7 +2289,7 @@ "selector": ".sf-no-tap-highlight", "kind": "macro", "category": "Macro classes", - "group": "No tap highlight", + "group": "", "description": "Removes the mobile tap highlight color (-webkit-tap-highlight-color: transparent). Use on interactive elements with a custom active state.", "optional": false, "layer": "slashed.macros" @@ -2349,7 +2299,7 @@ "selector": ".sf-not-prose", "kind": "macro", "category": "Macro classes", - "group": "Prose", + "group": "", "description": "Opt-out of sf-prose typography styles within a prose block. Apply to an element that should keep default browser or component styles.", "optional": false, "layer": "slashed.macros" @@ -2359,7 +2309,7 @@ "selector": ".sf-overflow-fade", "kind": "macro", "category": "Macro classes", - "group": "Overflow fade", + "group": "", "description": "Adds a gradient fade at the inline-end of an overflowing element to hint at hidden content. Use inside sf-reel or any scroll container.", "optional": false, "layer": "slashed.macros" @@ -2489,7 +2439,7 @@ "selector": ".sf-pancake", "kind": "layout", "category": "Layout primitives", - "group": "Pancake (sticky footer)", + "group": "", "description": "Three-row layout (header, main, footer) where main takes all remaining vertical space via flex-grow. The footer always sticks to the bottom on tall viewports.", "optional": false, "layer": "slashed.layout" @@ -2509,7 +2459,7 @@ "selector": ".sf-reel", "kind": "layout", "category": "Layout primitives", - "group": ".sf-card", + "group": "", "description": "Horizontally scrollable row of fixed-height items with snap scrolling. Children don't shrink below their intrinsic width, creating a card carousel effect.", "optional": false, "layer": "slashed.layout" @@ -2519,7 +2469,7 @@ "selector": ".sf-scale-down", "kind": "motion", "category": "Motion / animation", - "group": "Animation presets", + "group": "", "description": "One-shot scale-down animation (element shrinks from full size). Scoped to no-preference.", "optional": false, "layer": "slashed.motion" @@ -2529,7 +2479,7 @@ "selector": ".sf-scale-up", "kind": "motion", "category": "Motion / animation", - "group": "Animation presets", + "group": "", "description": "One-shot scale-up animation (element grows from smaller size). Scoped to no-preference.", "optional": false, "layer": "slashed.motion" @@ -2539,7 +2489,7 @@ "selector": ".sf-scrim", "kind": "macro", "category": "Macro classes", - "group": "Scrim", + "group": "", "description": "Overlay container with a gradient darkening scrim behind text placed on an image or colored background.", "optional": false, "layer": "slashed.macros" @@ -2549,7 +2499,7 @@ "selector": ".sf-scrim__content", "kind": "macro", "category": "Macro classes", - "group": "Scrim", + "group": "", "description": "Content area inside an sf-scrim. Positioned above the gradient overlay layer.", "optional": false, "layer": "slashed.macros" @@ -2559,7 +2509,7 @@ "selector": ".sf-scrim--bottom", "kind": "macro", "category": "Macro classes", - "group": "Scrim", + "group": "", "description": "Scrim variant with the gradient emanating from the bottom edge (bottom-to-top fade).", "optional": false, "layer": "slashed.macros" @@ -2569,7 +2519,7 @@ "selector": ".sf-scrim--full", "kind": "macro", "category": "Macro classes", - "group": "Scrim", + "group": "", "description": "Scrim variant that covers the entire surface with a uniform translucent overlay.", "optional": false, "layer": "slashed.macros" @@ -2579,7 +2529,7 @@ "selector": ".sf-scrim--top", "kind": "macro", "category": "Macro classes", - "group": "Scrim", + "group": "", "description": "Scrim variant with the gradient emanating from the top edge (top-to-bottom fade).", "optional": false, "layer": "slashed.macros" @@ -2589,7 +2539,7 @@ "selector": ".sf-scroll-shadow", "kind": "macro", "category": "Macro classes", - "group": "Scroll shadow", + "group": "", "description": "Adds inset box-shadows at the top and bottom of a scrollable container to indicate hidden overflow above or below.", "optional": false, "layer": "slashed.macros" @@ -2599,7 +2549,7 @@ "selector": ".sf-scroll-snap", "kind": "macro", "category": "Macro classes", - "group": "Scroll snap", + "group": "", "description": "Enables CSS scroll-snap-type: x mandatory on a horizontal scroll container. Children should have scroll-snap-align.", "optional": false, "layer": "slashed.macros" @@ -2609,7 +2559,7 @@ "selector": ".sf-section", "kind": "layout", "category": "Layout primitives", - "group": "Section", + "group": "", "description": "Full-width page section with vertical padding (--sf-section-pad-default). Use to create visually distinct content bands.", "optional": false, "layer": "slashed.layout" @@ -2619,7 +2569,7 @@ "selector": ".sf-section--2xl", "kind": "layout", "category": "Layout primitives", - "group": "Section", + "group": "", "description": "Section variant with 2xl vertical padding.", "optional": false, "layer": "slashed.layout" @@ -2629,7 +2579,7 @@ "selector": ".sf-section--collapse", "kind": "layout", "category": "Layout primitives", - "group": "Collapse modifier", + "group": "", "description": "Section variant that removes vertical padding (zero-padding section for adjacent same-color blocks).", "optional": false, "layer": "slashed.layout" @@ -2639,7 +2589,7 @@ "selector": ".sf-section--guttered", "kind": "layout", "category": "Layout primitives", - "group": "Section", + "group": "", "description": "Adds horizontal page gutters directly to a section — use when you want to skip a separate .sf-container wrapper (gutterless layout inside section). Neutralises container gutter to prevent double padding.", "optional": false, "layer": "slashed.layout" @@ -2649,7 +2599,7 @@ "selector": ".sf-section--l", "kind": "layout", "category": "Layout primitives", - "group": "Section", + "group": "", "description": "Section variant with large (l) vertical padding.", "optional": false, "layer": "slashed.layout" @@ -2659,7 +2609,7 @@ "selector": ".sf-section--m", "kind": "layout", "category": "Layout primitives", - "group": "Section", + "group": "", "description": "Section variant with medium (m) vertical padding.", "optional": false, "layer": "slashed.layout" @@ -2669,7 +2619,7 @@ "selector": ".sf-section--s", "kind": "layout", "category": "Layout primitives", - "group": "Section", + "group": "", "description": "Section variant with small (s) vertical padding.", "optional": false, "layer": "slashed.layout" @@ -2679,7 +2629,7 @@ "selector": ".sf-section--xl", "kind": "layout", "category": "Layout primitives", - "group": "Section", + "group": "", "description": "Section variant with xl vertical padding.", "optional": false, "layer": "slashed.layout" @@ -2689,7 +2639,7 @@ "selector": ".sf-section--xs", "kind": "layout", "category": "Layout primitives", - "group": "Section", + "group": "", "description": "Section variant with xs vertical padding.", "optional": false, "layer": "slashed.layout" @@ -2699,7 +2649,7 @@ "selector": ".sf-section-group", "kind": "layout", "category": "Layout primitives", - "group": "Section", + "group": "", "description": "Groups adjacent sf-section elements so their combined padding collapses correctly at the top and bottom edges.", "optional": false, "layer": "slashed.layout" @@ -2719,7 +2669,7 @@ "selector": ".sf-sidebar", "kind": "layout", "category": "Layout primitives", - "group": ".sf-card", + "group": "", "description": "Two-column sidebar layout: first child is the sidebar, second child is main content. The sidebar collapses below the breakpoint (--sf-sidebar-min-width). Default sidebar on the left.", "optional": false, "layer": "slashed.layout" @@ -2729,7 +2679,7 @@ "selector": ".sf-sidebar--narrow", "kind": "layout", "category": "Layout primitives", - "group": "Sidebar", + "group": "", "description": "Sidebar variant with a narrower sidebar column.", "optional": false, "layer": "slashed.layout" @@ -2739,7 +2689,7 @@ "selector": ".sf-sidebar--right", "kind": "layout", "category": "Layout primitives", - "group": "Sidebar", + "group": "", "description": "Sidebar variant with the sidebar on the right (second child becomes the sidebar).", "optional": false, "layer": "slashed.layout" @@ -2749,7 +2699,7 @@ "selector": ".sf-sidebar--wide", "kind": "layout", "category": "Layout primitives", - "group": "Sidebar", + "group": "", "description": "Sidebar variant with a wider sidebar column.", "optional": false, "layer": "slashed.layout" @@ -2759,7 +2709,7 @@ "selector": ".sf-slide-in-down", "kind": "motion", "category": "Motion / animation", - "group": "Animation presets", + "group": "", "description": "One-shot slide-in-from-above animation. Scoped to no-preference.", "optional": false, "layer": "slashed.motion" @@ -2769,7 +2719,7 @@ "selector": ".sf-slide-in-left", "kind": "motion", "category": "Motion / animation", - "group": "Animation presets", + "group": "", "description": "One-shot slide-in-from-right animation (slides to the left). Scoped to no-preference.", "optional": false, "layer": "slashed.motion" @@ -2779,7 +2729,7 @@ "selector": ".sf-slide-in-right", "kind": "motion", "category": "Motion / animation", - "group": "Animation presets", + "group": "", "description": "One-shot slide-in-from-left animation (slides to the right). Scoped to no-preference.", "optional": false, "layer": "slashed.motion" @@ -2789,7 +2739,7 @@ "selector": ".sf-slide-in-up", "kind": "motion", "category": "Motion / animation", - "group": "Animation presets", + "group": "", "description": "One-shot slide-in-from-below animation. Scoped to no-preference.", "optional": false, "layer": "slashed.motion" @@ -2799,7 +2749,7 @@ "selector": ".sf-stack", "kind": "layout", "category": "Layout primitives", - "group": ".sf-card", + "group": "", "description": "Flex column with even vertical spacing between children (--sf-stack-gap). Stacking context for vertical rhythm.", "optional": false, "layer": "slashed.layout" @@ -2809,7 +2759,7 @@ "selector": ".sf-stack--2xl", "kind": "layout", "category": "Layout primitives", - "group": "Stack", + "group": "", "description": "Stack variant with 2xl gap between children.", "optional": false, "layer": "slashed.layout" @@ -2819,7 +2769,7 @@ "selector": ".sf-stack--center", "kind": "layout", "category": "Layout primitives", - "group": "Stack", + "group": "", "description": "Stack variant that centers children on the cross axis.", "optional": false, "layer": "slashed.layout" @@ -2829,7 +2779,7 @@ "selector": ".sf-stack--end", "kind": "layout", "category": "Layout primitives", - "group": "Stack", + "group": "", "description": "Stack variant that aligns children to the cross-axis end (right in LTR).", "optional": false, "layer": "slashed.layout" @@ -2839,7 +2789,7 @@ "selector": ".sf-stack--l", "kind": "layout", "category": "Layout primitives", - "group": "Stack", + "group": "", "description": "Stack variant with large (l) gap between children.", "optional": false, "layer": "slashed.layout" @@ -2849,7 +2799,7 @@ "selector": ".sf-stack--m", "kind": "layout", "category": "Layout primitives", - "group": "Stack", + "group": "", "description": "Stack variant with medium (m) gap between children.", "optional": false, "layer": "slashed.layout" @@ -2859,7 +2809,7 @@ "selector": ".sf-stack--s", "kind": "layout", "category": "Layout primitives", - "group": "Stack", + "group": "", "description": "Stack variant with small (s) gap between children.", "optional": false, "layer": "slashed.layout" @@ -2869,7 +2819,7 @@ "selector": ".sf-stack--stretch", "kind": "layout", "category": "Layout primitives", - "group": "Stack", + "group": "", "description": "Stack variant that stretches children to fill the full available width.", "optional": false, "layer": "slashed.layout" @@ -2879,7 +2829,7 @@ "selector": ".sf-stack--xl", "kind": "layout", "category": "Layout primitives", - "group": "Stack", + "group": "", "description": "Stack variant with xl gap between children.", "optional": false, "layer": "slashed.layout" @@ -2889,7 +2839,7 @@ "selector": ".sf-stack--xs", "kind": "layout", "category": "Layout primitives", - "group": "Stack", + "group": "", "description": "Stack variant with xs gap between children.", "optional": false, "layer": "slashed.layout" @@ -2949,7 +2899,7 @@ "selector": ".sf-subgrid", "kind": "layout", "category": "Layout primitives", - "group": "Subgrid", + "group": "", "description": "Passes the parent grid columns through to children via subgrid. Place on a grid item that should align its own children to the outer grid columns.", "optional": false, "layer": "slashed.layout" @@ -2959,7 +2909,7 @@ "selector": ".sf-subgrid-rows", "kind": "layout", "category": "Layout primitives", - "group": "Subgrid", + "group": "", "description": "Passes the parent grid rows through to children via subgrid. Place on a grid item that should align its own children to the outer grid rows.", "optional": false, "layer": "slashed.layout" @@ -2969,7 +2919,7 @@ "selector": ".sf-surface", "kind": "macro", "category": "Macro classes", - "group": "Surface", + "group": "", "description": "Generic semantic surface: applies --sf-surface-color as the background and automatically sets a contrasting text color. Tone variants (--primary, --action, etc.) activate preset palettes.", "optional": false, "layer": "slashed.macros" @@ -2979,7 +2929,7 @@ "selector": ".sf-surface--action", "kind": "macro", "category": "Macro classes", - "group": "Surface", + "group": "", "description": "Surface variant using the action color palette (button/CTA primary color).", "optional": false, "layer": "slashed.macros" @@ -2989,7 +2939,7 @@ "selector": ".sf-surface--danger", "kind": "macro", "category": "Macro classes", - "group": "Surface", + "group": "", "description": "Surface variant using the danger status palette.", "optional": false, "layer": "slashed.macros" @@ -2999,7 +2949,7 @@ "selector": ".sf-surface--info", "kind": "macro", "category": "Macro classes", - "group": "Surface", + "group": "", "description": "Surface variant using the info status palette.", "optional": false, "layer": "slashed.macros" @@ -3009,7 +2959,7 @@ "selector": ".sf-surface--inverse", "kind": "macro", "category": "Macro classes", - "group": "Surface", + "group": "", "description": "Surface variant that inverts light/dark, creating an always-dark surface in light mode and always-light in dark mode.", "optional": false, "layer": "slashed.macros" @@ -3019,7 +2969,7 @@ "selector": ".sf-surface--neutral", "kind": "macro", "category": "Macro classes", - "group": "Surface", + "group": "", "description": "Surface variant using the neutral palette (muted/gray).", "optional": false, "layer": "slashed.macros" @@ -3029,7 +2979,7 @@ "selector": ".sf-surface--primary", "kind": "macro", "category": "Macro classes", - "group": "Surface", + "group": "", "description": "Surface variant using the primary brand color palette.", "optional": false, "layer": "slashed.macros" @@ -3039,7 +2989,7 @@ "selector": ".sf-surface--secondary", "kind": "macro", "category": "Macro classes", - "group": "Surface", + "group": "", "description": "Surface variant using the secondary brand color palette.", "optional": false, "layer": "slashed.macros" @@ -3049,7 +2999,7 @@ "selector": ".sf-surface--success", "kind": "macro", "category": "Macro classes", - "group": "Surface", + "group": "", "description": "Surface variant using the success status palette.", "optional": false, "layer": "slashed.macros" @@ -3059,7 +3009,7 @@ "selector": ".sf-surface--tertiary", "kind": "macro", "category": "Macro classes", - "group": "Surface", + "group": "", "description": "Surface variant using the tertiary brand color palette.", "optional": false, "layer": "slashed.macros" @@ -3069,7 +3019,7 @@ "selector": ".sf-surface--warning", "kind": "macro", "category": "Macro classes", - "group": "Surface", + "group": "", "description": "Surface variant using the warning status palette.", "optional": false, "layer": "slashed.macros" @@ -3089,7 +3039,7 @@ "selector": ".sf-switcher", "kind": "layout", "category": "Layout primitives", - "group": ".sf-card", + "group": "", "description": "Flex layout that switches from a horizontal row to a vertical column when the container is narrower than --sf-switcher-threshold.", "optional": false, "layer": "slashed.layout" @@ -3099,7 +3049,7 @@ "selector": ".sf-switcher--no-wrap", "kind": "layout", "category": "Layout primitives", - "group": "Switcher", + "group": "", "description": "Switcher variant that stays horizontal and never wraps (single-line regardless of container width).", "optional": false, "layer": "slashed.layout" @@ -3109,7 +3059,7 @@ "selector": ".sf-switcher--vertical", "kind": "layout", "category": "Layout primitives", - "group": "Switcher", + "group": "", "description": "Switcher variant that starts in the vertical (stacked) direction on all sizes.", "optional": false, "layer": "slashed.layout" @@ -3119,7 +3069,7 @@ "selector": ".sf-tabular-nums", "kind": "macro", "category": "Macro classes", - "group": "Tabular figures", + "group": "", "description": "Forces tabular (monospaced) number rendering. Use on price tables, counters, and anywhere numbers need to align vertically across rows.", "optional": false, "layer": "slashed.macros" @@ -3169,7 +3119,7 @@ "selector": ".sf-text-gradient", "kind": "macro", "category": "Macro classes", - "group": "Text gradient", + "group": "", "description": "Applies a brand gradient to inline text. Sets the background to the gradient, clips it to the text, and makes the text color transparent.", "optional": false, "layer": "slashed.macros" @@ -3199,7 +3149,7 @@ "selector": ".sf-text-protect", "kind": "macro", "category": "Macro classes", - "group": "Text protect", + "group": "", "description": "Wraps text in a translucent dark gradient overlay to ensure legibility when placed over a light or variable background image.", "optional": false, "layer": "slashed.macros" @@ -3259,7 +3209,7 @@ "selector": ".sf-theme-transition", "kind": "theme", "category": "Theme utilities", - "group": "OPT-IN THEME CROSS-FADE", + "group": "", "description": "Opt-in animated light/dark theme crossfade. Apply to (or a subtree) so color tokens transition smoothly when [data-theme] changes. Duration controlled by --sf-theme-transition-duration.", "optional": false, "layer": "slashed.themes" @@ -3269,7 +3219,7 @@ "selector": ".sf-truncate", "kind": "macro", "category": "Macro classes", - "group": "Truncate / line-clamp", + "group": "", "description": "Single-line text overflow with ellipsis. Equivalent to the classic text-overflow: ellipsis trio (white-space nowrap, overflow hidden, text-overflow ellipsis).", "optional": false, "layer": "slashed.macros" @@ -3279,7 +3229,7 @@ "selector": ".skip-link", "kind": "accessibility", "category": "Accessibility", - "group": "Skip link", + "group": "", "description": "Accessible skip-navigation link. Hidden until focused; jumps keyboard users past repeated navigation blocks. Place as the very first element in .", "optional": false, "layer": "slashed.accessibility" @@ -3289,7 +3239,7 @@ "selector": ".sr-only", "kind": "accessibility", "category": "Accessibility", - "group": "Screen-reader-only. Atomic contract: a partial override", + "group": "", "description": "Visually hides content while keeping it accessible to screen readers. Use for labels, descriptions, and off-screen text that assistive technology needs.", "optional": false, "layer": "slashed.accessibility" @@ -3299,7 +3249,7 @@ "selector": ".sr-only-focusable", "kind": "accessibility", "category": "Accessibility", - "group": "Screen-reader-only. Atomic contract: a partial override", + "group": "", "description": "Extends sr-only — also reveals the element when it receives keyboard focus. Typical use: skip links and visually-hidden focus targets.", "optional": false, "layer": "slashed.accessibility" diff --git a/configurator/src/data/domain-patterns.json b/configurator/src/data/domain-patterns.json index 7ecddd0b..8fda785b 100644 --- a/configurator/src/data/domain-patterns.json +++ b/configurator/src/data/domain-patterns.json @@ -1,5 +1,5 @@ { - "macros": ["prose", "flow-space", "line-clamp", "aspect", "scroll-shadow", "scrim", "surface-color", "surface-bg", "content-intrinsic", "corner-scoop", "overlap-"], + "macros": ["prose", "flow-space", "line-clamp", "aspect", "scroll-shadow", "scrim", "surface-color", "surface-bg", "content-intrinsic", "overlap-"], "colors": ["color", "contrast", "palette-mix", "lumlocker", "gradient"], "typography": ["font", "--sf-text", "leading", "tracking", "weight", "body-font", "heading-font", "body-em", "body-text", "heading-text", "display-l-", "display-m-", diff --git a/configurator/src/data/token-registry.generated.json b/configurator/src/data/token-registry.generated.json index 9aacaf4f..2899b694 100644 --- a/configurator/src/data/token-registry.generated.json +++ b/configurator/src/data/token-registry.generated.json @@ -2883,11 +2883,13 @@ }, { "id": 710, - "name": "--sf-corner-scoop-at" + "name": "--sf-corner-scoop-at", + "removed": true }, { "id": 711, - "name": "--sf-corner-scoop-size" + "name": "--sf-corner-scoop-size", + "removed": true }, { "id": 712, diff --git a/configurator/src/lib/preview/sections.ts b/configurator/src/lib/preview/sections.ts index 67499224..4a31e9fd 100644 --- a/configurator/src/lib/preview/sections.ts +++ b/configurator/src/lib/preview/sections.ts @@ -604,21 +604,6 @@ export function macros(): string { // Text gradient. const textGradient = well(`

Gradient headline

`); - // Corner scoop — the notch reveals whatever sits behind the element, so - // the card sits on a contrasting frame. - const scoopCard = (mods: string) => - `
`; - const cornerScoop = frame( - `
${[ - ["sf-corner-scoop", "default (top-right)"], - ["sf-corner-scoop sf-corner-scoop--top-left", "top-left"], - ["sf-corner-scoop sf-corner-scoop--bottom-left", "bottom-left"], - ["sf-corner-scoop sf-corner-scoop--bottom-right", "bottom-right"], - ] - .map(([mods, label]) => specimen(label, scoopCard(mods))) - .join("")}
`, - ); - // Overlap — an avatar pulled down over the card that follows it // (.sf-overlap--down; the plain .sf-overlap pulls UP onto whatever // precedes it instead — not what a leading avatar needs here), plus the @@ -665,7 +650,6 @@ export function macros(): string { section("Named background preset (sf-surface-bg)", surfaceBg), section("Text protect (sf-text-protect)", well(textProtect)), section("Text gradient (sf-text-gradient)", textGradient), - section("Corner scoop (sf-corner-scoop + corner modifiers)", cornerScoop), section("Overlap (sf-overlap, sf-overlap-host)", well(stack("m", overlapHost, overlapDirections))), section("No tap highlight (sf-no-tap-highlight)", noTapHighlight), ); diff --git a/core/macros.css b/core/macros.css index d574b189..78aaed19 100644 --- a/core/macros.css +++ b/core/macros.css @@ -387,27 +387,6 @@ text-decoration-line: none; } - /* Concave corner — a corner that curves AWAY from the box (revealing - whatever sits behind it), via a radial-gradient mask. Physical corner - names (mask geometry has no logical form, same rationale as - .sf-overflow-fade's physical directions). Cuts the element's full - paint at that corner — box-shadow/border don't survive the cut there; - put shadows on a wrapper if needed. Named to mirror the future - `corner-shape: scoop` keyword for an easy @supports migration. */ - .sf-corner-scoop { - /* stylelint-disable-next-line property-no-vendor-prefix -- required for Safari < 18 */ - -webkit-mask-image: radial-gradient(circle at var(--sf-corner-scoop-at), - transparent var(--sf-corner-scoop-size), - black calc(var(--sf-corner-scoop-size) + 0.5px)); - mask-image: radial-gradient(circle at var(--sf-corner-scoop-at), - transparent var(--sf-corner-scoop-size), - black calc(var(--sf-corner-scoop-size) + 0.5px)); - } - .sf-corner-scoop--top-left { --sf-corner-scoop-at: 0 0; } - .sf-corner-scoop--top-right { --sf-corner-scoop-at: 100% 0; } - .sf-corner-scoop--bottom-left { --sf-corner-scoop-at: 0 100%; } - .sf-corner-scoop--bottom-right { --sf-corner-scoop-at: 100% 100%; } - /* Overlap recipe — one element intentionally overlapping the previous one (e.g. an image pulled up over the card below it), via a negative logical margin + a raised stacking context. Directional variants are diff --git a/core/tokens.macros.css b/core/tokens.macros.css index 22eb8a5c..90c41876 100644 --- a/core/tokens.macros.css +++ b/core/tokens.macros.css @@ -120,14 +120,6 @@ --sf-surface-bg-attachment: scroll; --sf-surface-bg-animation: none; - /* ---------------------------------------------------------- - Concave corner — radius and corner position for .sf-corner-scoop. - Override per element: style="--sf-corner-scoop-size: var(--sf-radius-3xl)" - (cut radius) or style="--sf-corner-scoop-at: 0 0" (which corner). - ---------------------------------------------------------- */ - --sf-corner-scoop-size: var(--sf-radius-2xl); - --sf-corner-scoop-at: 100% 0; - /* ---------------------------------------------------------- Overlap recipe — how far .sf-overlap pulls into the adjacent element. .sf-overlap-host's padding compensation defaults to this diff --git a/demo-audit.html b/demo-audit.html new file mode 100644 index 00000000..48e9d5bd --- /dev/null +++ b/demo-audit.html @@ -0,0 +1,816 @@ + + + + + +SLASHED .sf-* Class Coverage Audit + + + + + +
+
+

This page is a hand-authored coverage audit for the SLASHED framework. Every + .sf-* class documented in docs/classes.md is applied to + real, visible markup below, organised by source file. It loads only + dist/slashed.full.css — no custom CSS, no scripts, no third-party + resources. .sf-box's border is opt-in via its + --sf-box-border-width custom property (0 by default); it's set to + 1px once here on <body> — a documented public token, + inherited like any CSS custom property — purely so every box demo below is + visible at a glance.

+
+
+ + +
+
+

Layout primitives (core/layout.css)

+

Breakpoint-free, container-query-driven layout building blocks. Each demo below +exercises one primitive (and its size/variant modifiers) with realistic children.

+ +

Section rhythm & section-group

+
+
section--xs
+
section--s
+
section--m (default)
+
section--l
+
section--xl
+
section--2xl + section--collapse (shares padding with neighbour)
+
+
+

section--guttered adds inline gutters without a container

+
+ +

Header padding rhythm

+
header--xs
+
header--s
+
header--m
+
header--l
+
header--xl
+ +

Containers & container-query scopes

+

default .sf-container

+

container--narrow

+

container--prose

+

container--wide

+

container--full

+
sf-cq scope, col 1
col 2 — resizes by container width, not viewport
+

sf-fluid-cq — children interpolate type/space against this box's own inline size rather than the viewport.

+ +

Box & centering

+
sf-box — isolated padded unit with an outline
+
sf-center — intrinsic centering with gutters
+
sf-center--intrinsic
+ +

Stack — vertical flow

+
+

xs

gap

+

s

gap

+

m

gap (default)

+

l

gap

+

xl

gap

+

2xl

gap

+
+
+
+
+
+
+ +

Cluster — wrapping inline group

+
+
xsgap
+
sgap
+
mgap (default)
+
lgap
+
xlgap
+
2xlgap
+
no-wrapstayson one line
+
cluster--between: leftright
+
cluster--center
+
cluster--end
+
+ +

Gap — inject gap into an existing container

+
gap xs
a
b
+
gap s
a
b
+
gap m
a
b
+
gap l
a
b
+
gap xl
a
b
+
gap 2xl
a
b
+ +

Sidebar

+
Main content wraps below when narrow
+
Main
+
sidebar--right panel
+
Main
+ +

Switcher

+
A
B
C
+
A
B
C
+
A
B
C
+ +

Grid — auto-fill responsive

+
xs
min col
width
+
s
min col
width
+
m
min col
width
+
l
min col
width
+
xl
min col
width
+
2xl
min col
width
+
fit
stretches to fill row
+
dense
packing
fills gaps
+ +

Grid — fixed columns & ratios

+
grid-cols-1
+
grid-cols-2 a
b
+
grid-cols-3 a
b
c
+
1
2
3
4
+
1
2
3
4
5
6
+
1fr
2fr
+
2fr
1fr
+
1fr
3fr
+
3fr
1fr
+ +

Grid-flex

+
xs
item
item
+
s
item
item
+
m
item
item
+
l
item
item
+
xl
item
item
+
2xl
item
item
+
center
last row
stays fixed
+ +

Bento — dense free-form grid

+
+ +
bento-wide (span 2)
+
bento-tall (row span 2)
+
normal cell
+
bento-full (full width)
+
+
bento--2
bento--row-compact rows
+
bento--6
bento--row-tall rows
c
d
e
f
+ +

Alternate — zigzag two-column

+
+
+

Feature one

Text column reverses order on alternate rows.

+
placeholder
+
+
+

Feature two

Second row — image/text order swaps automatically.

+
placeholder
+
+
+ +

Pancake — sticky-footer grid

+
+
+
+
Pancake header
+
Pancake main (1fr)
+
Pancake footer
+
+
+ +

Content-grid — breakout & full-bleed

+
+

Regular content-width paragraph inside .sf-content-grid.

+
sf-breakout — wider than content, narrower than viewport
+
sf-full-bleed — spans the whole viewport width
+
+ +

Cover — full-height centered region

+

cover--min + cover__center

+

cover--max + cover--padding-s

+

cover--padding-l

+ +

Frame — aspect-ratio media box

+
+
default 16:9
+
square
+
video
+
cinema
+
portrait
+
4:3
+
3:2
+
golden
+
+ +

Background layer

+
+ +

sf-bg-layer fills behind this text; the parent auto-positions itself.

+
+ +

Reel — horizontal scroll strip

+
+
1
2
3
+
4
5
6
+
+ +

Imposter — absolutely-centered overlay

+
+

Host box (positioning context)

+ imposter (centered) +
+
+

Host box (transform creates a containing block so the fixed-positioned imposter stays inside it)

+ imposter--fixed +
+
+
imposter--contain: constrained + scrollable long content that overflows the imposter box on purpose to show the scrollbar in action.
+
+ +

Overlay helper

+
+

Base content

+
+
+ +

Subgrid

+
+
+
subgrid a
subgrid b
subgrid c
+
+
+
+
+
subgrid-rows row 1
subgrid-rows row 2
+
+
+ +

Divider & divide

+
+
+
+
+
+
+
Left
Right
+

One

Two (divide adds a border between siblings)

Three

+
XYZ
+ +

Equal — CSS multi-column flow

+

Newspaper-style flowing columns, 2 target columns. Text flows down one column, then continues at the top of the next, unlike grid cells.

+

Three target columns of flowing text content for a denser magazine layout.

+

Four target columns for a very dense flowing layout of short list items.

+

Six target columns, useful for long tag/keyword lists that should flow.

+ +

Icon sizing

+
+ + + + + + + +
+ +
+
+ + +
+
+

Macro classes (core/macros.css)

+

Recipes that answer "what does this element do/look like?" — composable on top of layout primitives.

+ +

Prose & not-prose

+
+

Article heading

+

Paragraph one of long-form text with automatic vertical rhythm between children.

+

Paragraph two — automatically spaced from the previous one.

+
  • Bullet one
  • Bullet two
+
This region opts out of prose spacing/list rules (sf-not-prose).
+

More article body after the opted-out region.

+
+ +

Flow

+
+

One

+

Two — gets margin-block-start from the flow rhythm.

+

Three — same.

+
+ +

Truncate & line-clamp

+

This very long sentence about the SLASHED framework will be cut off with an ellipsis after exactly one line because the box has a finite inline size.

+

Two-line clamp: SLASHED ships breakpoint-free, container-query-driven layout primitives that respond to their own container's width instead of the viewport, which keeps components portable across sidebars, cards, and full-width sections alike.

+

Three-line clamp: token-driven design system with a fluid type and space engine computed at runtime from a handful of input scalars, so retuning one number recalibrates the whole scale without a rebuild step or any SCSS preprocessing.

+

Five-line clamp via the N variant and the --sf-line-clamp custom property: this paragraph is intentionally long so the clamp is visible — it keeps going and going, describing layout primitives, macros, state classes, motion utilities and components until it is cut off after five lines with an ellipsis, no matter how much more text follows this point in the source.

+ +

Equal-height flex children

+
+
Short
+
Two
lines
+
Three
lines
here
+
+ +

Aspect ratio

+
sf-aspect at 4/3 via the --sf-aspect custom property
+ +

Scroll shadow & scroll snap

+
+

Long scrolling content fades near the top/bottom edges of this box.

+

Line two.

Line three.

Line four.

Line five.

Line six.

+
+
+
Snap A
+
Snap B
+
Snap C
+
+ +

Overflow fade

+
+ tagtagtagtag +
+
+ rightfadedemotags +
+
+ leftfadedemotags +
+

Top-fade content. Line 2.

Line 3.

Line 4.

+

Bottom-fade content. Line 2.

Line 3.

Line 4.

+

Both block edges fade. Line 2.

Line 3.

Line 4.

+
+ inlinefadebothedges +
+ +

No tap highlight

+
Link with suppressed mobile tap-highlight overlay + +

Content-visibility auto

+
Offscreen rendering is skipped until this section nears the viewport (content-visibility: auto).
+ +

Tabular numbers

+ + + +
Invoice #1024$1,204.50
Invoice #999$88.00
+ +

Drop shadows

+
+ xs shadow + s shadow + m shadow + l shadow + xl shadow +
+ +

Surfaces

+
+
sf-surface (generic, tinted)
+
surface--primary
+
surface--secondary
+
surface--tertiary
+
surface--action
+
surface--neutral
+
surface--inverse
+
surface--success
+
surface--warning
+
surface--info
+
surface--danger
+
+
sf-surface-bg — named background preset (colour fallback layer shown here)
+ +

Text gradient & text protect

+

Gradient headline

+
+ +

Legible text over a busy photo

+
+ +

Link helpers

+

+ External link · + Subtle link (underline on hover) · + Reverse link (underline at rest) +

+ +

Scrim over media

+
+ +
+

scrim--bottom + scrim__content

+
+
+
+ +
+

scrim--top

+
+
+
+ +
+

scrim--full

+
+
+ +

Entrance & exit scroll animations

+
+
entrance--fade
+
entrance--fade-up
+
entrance--fade-down
+
entrance--fade-left
+
entrance--fade-right
+
entrance--scale-up
+
exit--fade
+
exit--fade-up
+
exit--fade-down
+
exit--fade-left
+
exit--fade-right
+
exit--scale-down
+
+ +

Stagger

+ + +

Overlap & overlap-host

+
+
+ badge +
overlap (pulls up) + overlap-host reserves space
+
+
+
Host for overlap--down
+ badge +
+
+
Host
+ badge +
+
+ badge +
Host
+
+
+ +
+
+ + +
+
+

State classes (core/states.css)

+

Runtime-condition classes, applied statically here on realistic hosts so each visual treatment is visible.

+ +
+
is-hidden (removed from layout — you should not see this box)
+
is-invisible (keeps its box, invisible)
+
is-visible
+ +
+
is-loading (spinner replaces content)
+
is-pending (content stays usable)
+ +
+ +
  • is-selected list item
+ is-current nav item + +
is-highlighted
+
is-open panel
+
is-collapsed panel
+ +
+ +

Form validation states

+
+
+
Please enter a valid email
+
+ +

Feedback states

+
+

is-success: saved successfully

+ +

is-warning: quota nearly reached

+

is-info: new version available

+ +
+ +

Drag & drop

+
+
is-draggable item
+
is-dragging item
+
is-drop-target zone
+
+ +

Empty state

+ + +
+
+ + +
+
+

Accessibility (core/accessibility.css)

+

Focus and clickable-area helpers.

+ +
+

sf-focus-parent — this whole box rings when a descendant has keyboard focus.

+ +
+ +
+ +
+
+

sf-clickable-parent

+

The whole card is a single click target via the overlay link below.

+ Read more +
+
+ +
+
+ + +
+
+

Motion / entrances (core/motion.css)

+

Looping and one-shot animation classes applied to visible elements (final/initial state may render statically depending on browser support).

+ +
+
fade-in
+
fade-out
+
scale-up
+
scale-down
+
slide-in-up
+
slide-in-down
+
slide-in-left
+
slide-in-right
+
+ +

Colour pulse

+
sf-color-pulse — animates the primary hue lightness
+ +
+
+ + +
+
+

Print utilities (core/print.css)

+

Print rules key off classes already used elsewhere on the page for other purposes — .sf-link-external also +gains print-specific treatment (its href is expanded next to the link text when the page is printed).

+

This external link also exercises the print stylesheet — see the "Link helpers" demo above for the on-screen version of the same class.

+
+
+ + +
+
+

Theme utilities (core/themes.css)

+

Forcing light/dark on a region, plus the smooth-transition helper.

+ +
+
sf-theme-dark — forces dark palette on this region
+
sf-theme-light — forces light palette on this region
+
+
sf-theme-transition — cross-fades registered colour tokens when a theme toggle script flips data-theme on this element (normally applied to <html>; shown here on a scoped region since this page has no toggle script).
+
+
+ + +
+
+

Forms (optional/forms.css)

+

Classless form controls, styled without any .sf-* class needed on the inputs themselves — the one opt-in +utility here is .sf-live-validate, which enables native :user-invalid/:user-valid border feedback +after a submit attempt.

+ +
+
+ Contact details + + + + + + + +
+ +
+ +
+
+ + +
+
+

Components — Buttons (optional/components.css)

+

All colour families, style treatments, gradient axis, sizes, width, and state modifiers for .sf-btn.

+ +

Colour families

+
+ + + + + + + + + + + +
+ +

Style treatments

+
+ + + + +
+ +

Gradient axis

+
+ + + +
+ +

Sizes

+
+ + + + + +
+ +

Width

+ +
+ +
+ +

States

+
+ + +
+ +
+
+ + +
+
+

Components — Cards (optional/components.css)

+ +
+
+ +
+ +

Default card

+
+
+

Body content with header, media, avatar and title slots.

+
+
+ +
+
+ +
+

card--bordered: flat, outlined, no shadow.

+
+ +
+

card--elevated: floating shadow, no border.

+
+ + +

card--interactive: lifts on hover/focus.

+
+ +
+

Card in an is-loading state.

+
+ +
+

Card in an is-disabled state.

+
+ +
+

Standalone card__body composed with sf-flow for spacing.

+

Second paragraph.

+
+ +
+ New + Popular +
+
+ +
+
+ + +
+
+

Utilities (optional/utilities.css)

+ +

Heading helper classes

+
+
Visually H1 (div)
+
Visually H2 (div)
+
Visually H3 (div)
+
Visually H4 (div)
+
Visually H5 (div)
+
Visually H6 (div)
+
+ +

Text-size utilities

+
+

2xs — legal / metadata copy

+

xs — fine print

+

s — secondary copy

+

m — body copy

+

l — larger body copy

+

xl — lede paragraph

+

2xl — subheading

+

3xl — heading

+

4xl — display heading

+
+ +

Hover transforms

+
+
hover-grow
+
hover-shrink
+ hover-float + hover-sink +
hover-slide-start
+
hover-slide-end
+
+ +

List reset & marker colours

+ + + + + + +

Selection colour

+

Select this text — sf-selection--alt swaps the ::selection colours for a surface with poor default contrast.

+ +

Sticky positioning

+

--sf-sticky-offset normally reads the page's fixed header height (0 here, +since this page has none) — set to 0 per demo box below so the base case +sticks flush to each isolated scroll container's own top edge; scroll each box to see +it hold in place.

+
+
sf-sticky (base offset)
+

Scroll content…

More…

More…

More…

More…

+
+
+
sf-sticky--s (extra gap)
+

Scroll content…

More…

More…

More…

More…

+
+
+
sf-sticky--m
+

Scroll content…

More…

More…

More…

More…

+
+
+
sf-sticky--l
+

Scroll content…

More…

More…

More…

More…

+
+ +
+
+ + + diff --git a/demos/full-api-demo-with-overrides.html b/demos/full-api-demo-with-overrides.html index 8bec27b9..91f44be2 100644 --- a/demos/full-api-demo-with-overrides.html +++ b/demos/full-api-demo-with-overrides.html @@ -122,7 +122,7 @@

SLASHED Full API Demo

-

v0.7.16 · full bundle from jsDelivr CDN · 330 classes · 756 tokens (266 configurable)

+

v0.7.16 · full bundle from jsDelivr CDN · 325 classes · 754 tokens (265 configurable)

ultimate-override.css is ACTIVE. Every value below is recomputed from perturbed knob tokens — toggle it off in the toolbar, or compare against the un-overridden page.
@@ -754,7 +754,7 @@

Layout primitives 145

-

Macro classes 58

+

Macro classes 53

.sf-aspect
@@ -764,26 +764,6 @@

Macro classes 58

.sf-content-auto
content-auto
-
-
.sf-corner-scoop
-
corner-scoop
-
-
-
.sf-corner-scoop--bottom-left
-
corner-scoop--bottom-left
-
-
-
.sf-corner-scoop--bottom-right
-
corner-scoop--bottom-right
-
-
-
.sf-corner-scoop--top-left
-
corner-scoop--top-left
-
-
-
.sf-corner-scoop--top-right
-
corner-scoop--top-right
-
.sf-drop-shadow-l
drop-shadow-l
@@ -1277,7 +1257,7 @@

Theme 3

-

Part 2 — Complete token reference 756 tokens · live values

+

Part 2 — Complete token reference 754 tokens · live values

Every --sf-* token — knob and consumption, all tiers — with its live computed value (filled by JS). Toggle the theme or the override in the toolbar and watch every value recompute. Tokens that resolve to a colour, length, shadow, gradient, type or motion value also show a visual.

color 255

--sf-color-action
--sf-color-action--active
--sf-color-action--hover
--sf-color-action-100
--sf-color-action-200
--sf-color-action-300
--sf-color-action-400
--sf-color-action-50
--sf-color-action-500
--sf-color-action-600
--sf-color-action-700
--sf-color-action-800
--sf-color-action-900
--sf-color-action-950
--sf-color-action-a10
--sf-color-action-a30
--sf-color-action-a5
--sf-color-action-a50
--sf-color-action-a80
--sf-color-action-darker
--sf-color-action-lighter
--sf-color-action-muted
--sf-color-action-source-dark
--sf-color-action-source-light
--sf-color-action-subtle
--sf-color-action-superdark
--sf-color-action-superlight
--sf-color-action-tint
--sf-color-action-xdark
--sf-color-action-xlight
--sf-color-base
--sf-color-base--active
--sf-color-base--hover
--sf-color-base-100
--sf-color-base-200
--sf-color-base-300
--sf-color-base-400
--sf-color-base-50
--sf-color-base-500
--sf-color-base-600
--sf-color-base-700
--sf-color-base-800
--sf-color-base-900
--sf-color-base-950
--sf-color-base-a10
--sf-color-base-a30
--sf-color-base-a5
--sf-color-base-a50
--sf-color-base-a80
--sf-color-base-muted
--sf-color-base-source-dark
--sf-color-base-source-light
--sf-color-base-subtle
--sf-color-base-tint
--sf-color-bg
--sf-color-bg--active
--sf-color-bg--disabled
--sf-color-bg--focus
--sf-color-bg--hover
--sf-color-bg--selected
--sf-color-black
--sf-color-border
--sf-color-border--disabled
--sf-color-border--focus
--sf-color-border--strong
--sf-color-border--subtle
--sf-color-border--translucent
--sf-color-code-bg
--sf-color-code-text
--sf-color-danger
--sf-color-danger-muted
--sf-color-danger-source-dark
--sf-color-danger-source-light
--sf-color-danger-strong
--sf-color-danger-subtle
--sf-color-danger-tint
--sf-color-dim
--sf-color-heading
--sf-color-info
--sf-color-info-muted
--sf-color-info-source-dark
--sf-color-info-source-light
--sf-color-info-strong
--sf-color-info-subtle
--sf-color-info-tint
--sf-color-inset
--sf-color-inverse
--sf-color-link
--sf-color-link--active
--sf-color-link--disabled
--sf-color-link--hover
--sf-color-link--underline
--sf-color-link--visited
--sf-color-mark-bg
--sf-color-mark-text
--sf-color-neutral
--sf-color-neutral--active
--sf-color-neutral--hover
--sf-color-neutral-100
--sf-color-neutral-200
--sf-color-neutral-300
--sf-color-neutral-400
--sf-color-neutral-50
--sf-color-neutral-500
--sf-color-neutral-600
--sf-color-neutral-700
--sf-color-neutral-800
--sf-color-neutral-900
--sf-color-neutral-950
--sf-color-neutral-a10
--sf-color-neutral-a30
--sf-color-neutral-a5
--sf-color-neutral-a50
--sf-color-neutral-a80
--sf-color-neutral-darker
--sf-color-neutral-lighter
--sf-color-neutral-muted
--sf-color-neutral-source-dark
--sf-color-neutral-source-light
--sf-color-neutral-subtle
--sf-color-neutral-superdark
--sf-color-neutral-superlight
--sf-color-neutral-tint
--sf-color-neutral-xdark
--sf-color-neutral-xlight
--sf-color-overlay
--sf-color-primary
--sf-color-primary--active
--sf-color-primary--hover
--sf-color-primary-100
--sf-color-primary-200
--sf-color-primary-300
--sf-color-primary-400
--sf-color-primary-50
--sf-color-primary-500
--sf-color-primary-600
--sf-color-primary-700
--sf-color-primary-800
--sf-color-primary-900
--sf-color-primary-950
--sf-color-primary-a10
--sf-color-primary-a30
--sf-color-primary-a5
--sf-color-primary-a50
--sf-color-primary-a80
--sf-color-primary-darker
--sf-color-primary-lighter
--sf-color-primary-muted
--sf-color-primary-source-dark
--sf-color-primary-source-light
--sf-color-primary-subtle
--sf-color-primary-superdark
--sf-color-primary-superlight
--sf-color-primary-tint
--sf-color-primary-xdark
--sf-color-primary-xlight
--sf-color-raised
--sf-color-scheme
--sf-color-secondary
--sf-color-secondary--active
--sf-color-secondary--hover
--sf-color-secondary-100
--sf-color-secondary-200
--sf-color-secondary-300
--sf-color-secondary-400
--sf-color-secondary-50
--sf-color-secondary-500
--sf-color-secondary-600
--sf-color-secondary-700
--sf-color-secondary-800
--sf-color-secondary-900
--sf-color-secondary-950
--sf-color-secondary-a10
--sf-color-secondary-a30
--sf-color-secondary-a5
--sf-color-secondary-a50
--sf-color-secondary-a80
--sf-color-secondary-darker
--sf-color-secondary-lighter
--sf-color-secondary-muted
--sf-color-secondary-source-dark
--sf-color-secondary-source-light
--sf-color-secondary-subtle
--sf-color-secondary-superdark
--sf-color-secondary-superlight
--sf-color-secondary-tint
--sf-color-secondary-xdark
--sf-color-secondary-xlight
--sf-color-selection-bg
--sf-color-selection-bg--alt
--sf-color-selection-text
--sf-color-selection-text--alt
--sf-color-success
--sf-color-success-muted
--sf-color-success-source-dark
--sf-color-success-source-light
--sf-color-success-strong
--sf-color-success-subtle
--sf-color-success-tint
--sf-color-surface
--sf-color-tertiary
--sf-color-tertiary--active
--sf-color-tertiary--hover
--sf-color-tertiary-100
--sf-color-tertiary-200
--sf-color-tertiary-300
--sf-color-tertiary-400
--sf-color-tertiary-50
--sf-color-tertiary-500
--sf-color-tertiary-600
--sf-color-tertiary-700
--sf-color-tertiary-800
--sf-color-tertiary-900
--sf-color-tertiary-950
--sf-color-tertiary-a10
--sf-color-tertiary-a30
--sf-color-tertiary-a5
--sf-color-tertiary-a50
--sf-color-tertiary-a80
--sf-color-tertiary-darker
--sf-color-tertiary-lighter
--sf-color-tertiary-muted
--sf-color-tertiary-source-dark
--sf-color-tertiary-source-light
--sf-color-tertiary-subtle
--sf-color-tertiary-superdark
--sf-color-tertiary-superlight
--sf-color-tertiary-tint
--sf-color-tertiary-xdark
--sf-color-tertiary-xlight
--sf-color-text
--sf-color-text--disabled
--sf-color-text--inverse
--sf-color-text--muted
--sf-color-text--on-action
--sf-color-text--on-base
--sf-color-text--on-danger
--sf-color-text--on-info
--sf-color-text--on-inverse
--sf-color-text--on-neutral
--sf-color-text--on-primary
--sf-color-text--on-secondary
--sf-color-text--on-success
--sf-color-text--on-tertiary
--sf-color-text--on-warning
--sf-color-text--placeholder
--sf-color-text--secondary
--sf-color-warning
--sf-color-warning-muted
--sf-color-warning-source-dark
--sf-color-warning-source-light
--sf-color-warning-strong
--sf-color-warning-subtle
--sf-color-warning-tint
--sf-color-white
@@ -1353,8 +1333,6 @@

content 3

--sf-content-gap
--sf-content-intrinsic-size
--sf-content-width

contrast 2

--sf-contrast-bias adv
--sf-contrast-threshold adv
-

corner 2

-
--sf-corner-scoop-at
--sf-corner-scoop-size

cover 2

--sf-cover-min-height
--sf-cover-padding

current 1

diff --git a/demos/full-api-demo.html b/demos/full-api-demo.html index 795cf3b7..48594959 100644 --- a/demos/full-api-demo.html +++ b/demos/full-api-demo.html @@ -121,7 +121,7 @@

SLASHED Full API Demo

-

v0.7.16 · full bundle from jsDelivr CDN · 330 classes · 756 tokens (266 configurable)

+

v0.7.16 · full bundle from jsDelivr CDN · 325 classes · 754 tokens (265 configurable)

Baseline render with default tokens. Use the toolbar to switch theme, toggle the ultimate override live, or replay motion. The always-on override variant is full-api-demo-with-overrides.html.
@@ -753,7 +753,7 @@

Layout primitives 145

-

Macro classes 58

+

Macro classes 53

.sf-aspect
@@ -763,26 +763,6 @@

Macro classes 58

.sf-content-auto
content-auto
-
-
.sf-corner-scoop
-
corner-scoop
-
-
-
.sf-corner-scoop--bottom-left
-
corner-scoop--bottom-left
-
-
-
.sf-corner-scoop--bottom-right
-
corner-scoop--bottom-right
-
-
-
.sf-corner-scoop--top-left
-
corner-scoop--top-left
-
-
-
.sf-corner-scoop--top-right
-
corner-scoop--top-right
-
.sf-drop-shadow-l
drop-shadow-l
@@ -1276,7 +1256,7 @@

Theme 3

-

Part 2 — Complete token reference 756 tokens · live values

+

Part 2 — Complete token reference 754 tokens · live values

Every --sf-* token — knob and consumption, all tiers — with its live computed value (filled by JS). Toggle the theme or the override in the toolbar and watch every value recompute. Tokens that resolve to a colour, length, shadow, gradient, type or motion value also show a visual.

color 255

--sf-color-action
--sf-color-action--active
--sf-color-action--hover
--sf-color-action-100
--sf-color-action-200
--sf-color-action-300
--sf-color-action-400
--sf-color-action-50
--sf-color-action-500
--sf-color-action-600
--sf-color-action-700
--sf-color-action-800
--sf-color-action-900
--sf-color-action-950
--sf-color-action-a10
--sf-color-action-a30
--sf-color-action-a5
--sf-color-action-a50
--sf-color-action-a80
--sf-color-action-darker
--sf-color-action-lighter
--sf-color-action-muted
--sf-color-action-source-dark
--sf-color-action-source-light
--sf-color-action-subtle
--sf-color-action-superdark
--sf-color-action-superlight
--sf-color-action-tint
--sf-color-action-xdark
--sf-color-action-xlight
--sf-color-base
--sf-color-base--active
--sf-color-base--hover
--sf-color-base-100
--sf-color-base-200
--sf-color-base-300
--sf-color-base-400
--sf-color-base-50
--sf-color-base-500
--sf-color-base-600
--sf-color-base-700
--sf-color-base-800
--sf-color-base-900
--sf-color-base-950
--sf-color-base-a10
--sf-color-base-a30
--sf-color-base-a5
--sf-color-base-a50
--sf-color-base-a80
--sf-color-base-muted
--sf-color-base-source-dark
--sf-color-base-source-light
--sf-color-base-subtle
--sf-color-base-tint
--sf-color-bg
--sf-color-bg--active
--sf-color-bg--disabled
--sf-color-bg--focus
--sf-color-bg--hover
--sf-color-bg--selected
--sf-color-black
--sf-color-border
--sf-color-border--disabled
--sf-color-border--focus
--sf-color-border--strong
--sf-color-border--subtle
--sf-color-border--translucent
--sf-color-code-bg
--sf-color-code-text
--sf-color-danger
--sf-color-danger-muted
--sf-color-danger-source-dark
--sf-color-danger-source-light
--sf-color-danger-strong
--sf-color-danger-subtle
--sf-color-danger-tint
--sf-color-dim
--sf-color-heading
--sf-color-info
--sf-color-info-muted
--sf-color-info-source-dark
--sf-color-info-source-light
--sf-color-info-strong
--sf-color-info-subtle
--sf-color-info-tint
--sf-color-inset
--sf-color-inverse
--sf-color-link
--sf-color-link--active
--sf-color-link--disabled
--sf-color-link--hover
--sf-color-link--underline
--sf-color-link--visited
--sf-color-mark-bg
--sf-color-mark-text
--sf-color-neutral
--sf-color-neutral--active
--sf-color-neutral--hover
--sf-color-neutral-100
--sf-color-neutral-200
--sf-color-neutral-300
--sf-color-neutral-400
--sf-color-neutral-50
--sf-color-neutral-500
--sf-color-neutral-600
--sf-color-neutral-700
--sf-color-neutral-800
--sf-color-neutral-900
--sf-color-neutral-950
--sf-color-neutral-a10
--sf-color-neutral-a30
--sf-color-neutral-a5
--sf-color-neutral-a50
--sf-color-neutral-a80
--sf-color-neutral-darker
--sf-color-neutral-lighter
--sf-color-neutral-muted
--sf-color-neutral-source-dark
--sf-color-neutral-source-light
--sf-color-neutral-subtle
--sf-color-neutral-superdark
--sf-color-neutral-superlight
--sf-color-neutral-tint
--sf-color-neutral-xdark
--sf-color-neutral-xlight
--sf-color-overlay
--sf-color-primary
--sf-color-primary--active
--sf-color-primary--hover
--sf-color-primary-100
--sf-color-primary-200
--sf-color-primary-300
--sf-color-primary-400
--sf-color-primary-50
--sf-color-primary-500
--sf-color-primary-600
--sf-color-primary-700
--sf-color-primary-800
--sf-color-primary-900
--sf-color-primary-950
--sf-color-primary-a10
--sf-color-primary-a30
--sf-color-primary-a5
--sf-color-primary-a50
--sf-color-primary-a80
--sf-color-primary-darker
--sf-color-primary-lighter
--sf-color-primary-muted
--sf-color-primary-source-dark
--sf-color-primary-source-light
--sf-color-primary-subtle
--sf-color-primary-superdark
--sf-color-primary-superlight
--sf-color-primary-tint
--sf-color-primary-xdark
--sf-color-primary-xlight
--sf-color-raised
--sf-color-scheme
--sf-color-secondary
--sf-color-secondary--active
--sf-color-secondary--hover
--sf-color-secondary-100
--sf-color-secondary-200
--sf-color-secondary-300
--sf-color-secondary-400
--sf-color-secondary-50
--sf-color-secondary-500
--sf-color-secondary-600
--sf-color-secondary-700
--sf-color-secondary-800
--sf-color-secondary-900
--sf-color-secondary-950
--sf-color-secondary-a10
--sf-color-secondary-a30
--sf-color-secondary-a5
--sf-color-secondary-a50
--sf-color-secondary-a80
--sf-color-secondary-darker
--sf-color-secondary-lighter
--sf-color-secondary-muted
--sf-color-secondary-source-dark
--sf-color-secondary-source-light
--sf-color-secondary-subtle
--sf-color-secondary-superdark
--sf-color-secondary-superlight
--sf-color-secondary-tint
--sf-color-secondary-xdark
--sf-color-secondary-xlight
--sf-color-selection-bg
--sf-color-selection-bg--alt
--sf-color-selection-text
--sf-color-selection-text--alt
--sf-color-success
--sf-color-success-muted
--sf-color-success-source-dark
--sf-color-success-source-light
--sf-color-success-strong
--sf-color-success-subtle
--sf-color-success-tint
--sf-color-surface
--sf-color-tertiary
--sf-color-tertiary--active
--sf-color-tertiary--hover
--sf-color-tertiary-100
--sf-color-tertiary-200
--sf-color-tertiary-300
--sf-color-tertiary-400
--sf-color-tertiary-50
--sf-color-tertiary-500
--sf-color-tertiary-600
--sf-color-tertiary-700
--sf-color-tertiary-800
--sf-color-tertiary-900
--sf-color-tertiary-950
--sf-color-tertiary-a10
--sf-color-tertiary-a30
--sf-color-tertiary-a5
--sf-color-tertiary-a50
--sf-color-tertiary-a80
--sf-color-tertiary-darker
--sf-color-tertiary-lighter
--sf-color-tertiary-muted
--sf-color-tertiary-source-dark
--sf-color-tertiary-source-light
--sf-color-tertiary-subtle
--sf-color-tertiary-superdark
--sf-color-tertiary-superlight
--sf-color-tertiary-tint
--sf-color-tertiary-xdark
--sf-color-tertiary-xlight
--sf-color-text
--sf-color-text--disabled
--sf-color-text--inverse
--sf-color-text--muted
--sf-color-text--on-action
--sf-color-text--on-base
--sf-color-text--on-danger
--sf-color-text--on-info
--sf-color-text--on-inverse
--sf-color-text--on-neutral
--sf-color-text--on-primary
--sf-color-text--on-secondary
--sf-color-text--on-success
--sf-color-text--on-tertiary
--sf-color-text--on-warning
--sf-color-text--placeholder
--sf-color-text--secondary
--sf-color-warning
--sf-color-warning-muted
--sf-color-warning-source-dark
--sf-color-warning-source-light
--sf-color-warning-strong
--sf-color-warning-subtle
--sf-color-warning-tint
--sf-color-white
@@ -1352,8 +1332,6 @@

content 3

--sf-content-gap
--sf-content-intrinsic-size
--sf-content-width

contrast 2

--sf-contrast-bias adv
--sf-contrast-threshold adv
-

corner 2

-
--sf-corner-scoop-at
--sf-corner-scoop-size

cover 2

--sf-cover-min-height
--sf-cover-padding

current 1

diff --git a/demos/generate.mjs b/demos/generate.mjs index f53b19a9..f8850063 100644 --- a/demos/generate.mjs +++ b/demos/generate.mjs @@ -134,7 +134,6 @@ const CURATED = { '--sf-link-underline-thickness': '3px', '--sf-link-external-marker': '" \\2192"', '--sf-link-external-label': '"leaves this site"', - '--sf-corner-scoop-at': '30% 70%', '--sf-field-required-marker': '" \\2737"', '--sf-color-mark-text': 'oklch(0.45 0.27 320)', '--sf-color-selection-text': 'oklch(0.98 0 0)', diff --git a/demos/ultimate-override.css b/demos/ultimate-override.css index 0681332b..9aa90655 100644 --- a/demos/ultimate-override.css +++ b/demos/ultimate-override.css @@ -5,7 +5,7 @@ Perturbs every CONFIGURABLE (role: "knob") token to a valid, visibly-distinct value so full-api-demo.html can prove each one is wired end to end. - Coverage: 238 of 266 knob tokens overridden. + Coverage: 237 of 265 knob tokens overridden. 28 knobs are intentionally NOT perturbed (structural / meta / sentinel) — listed with reasons at the bottom of this file. ============================================================================ */ @@ -117,9 +117,6 @@ --sf-contrast-bias: 0.12; /* was: 0 */ --sf-contrast-threshold: 0.45; /* was: 0.6 */ - /* corner */ - --sf-corner-scoop-at: 30% 70%; /* was: 100% 0 */ - /* cover */ --sf-cover-min-height: 160dvh; /* was: 100dvh */ diff --git a/dist/css-custom-data.json b/dist/css-custom-data.json index be9a3401..9859c871 100644 --- a/dist/css-custom-data.json +++ b/dist/css-custom-data.json @@ -1851,16 +1851,6 @@ "description": "OKLCH lightness crossover for auto-contrast on colored surfaces. Colors with L above this get dark text; below get light text. Default 0.6.\n\nDefault: `0.6`\n\n(advanced token)", "syntax": "*" }, - { - "name": "--sf-corner-scoop-at", - "description": "Corner the .sf-corner-scoop mask cuts, as a radial-gradient origin (e.g. '100% 0' = top-right). Default: 100% 0.\n\nDefault: `100% 0`", - "syntax": "*" - }, - { - "name": "--sf-corner-scoop-size", - "description": "Cut radius of the .sf-corner-scoop mask. Default: var(--sf-radius-2xl).\n\nDefault: `var(--sf-radius-2xl)`", - "syntax": "*" - }, { "name": "--sf-cover-min-height", "description": "Minimum height of the cover layout (typically 100svh).\n\nDefault: `100dvh`", diff --git a/docs/api-index.json b/docs/api-index.json index 94d03f77..001980db 100644 --- a/docs/api-index.json +++ b/docs/api-index.json @@ -25,23 +25,23 @@ "optimal" ], "counts": { - "total": 1086, + "total": 1079, "by_type": { - "class": 330, - "token": 756 + "class": 325, + "token": 754 }, "by_tier": { "INTERNAL": 1, - "PUBLIC": 1025, + "PUBLIC": 1018, "PUBLIC-ADVANCED": 60 }, "by_role": { - "consumption": 490, - "knob": 266 + "consumption": 489, + "knob": 265 }, - "tokens": 756, - "classes": 330, - "sf_classes": 294, + "tokens": 754, + "classes": 325, + "sf_classes": 289, "is_classes": 28, "unprefixed_classes": 8, "by_category": { @@ -52,8 +52,8 @@ "Forms": 1, "Layout primitives": 145, "Layout tokens": 53, - "Macro classes": 58, - "Macro tokens": 34, + "Macro classes": 53, + "Macro tokens": 32, "Motion / animation": 22, "Print": 4, "State classes": 28, @@ -9666,58 +9666,6 @@ "optimal" ] }, - { - "name": "--sf-corner-scoop-at", - "type": "token", - "tier": "PUBLIC", - "role": "knob", - "namespace": "corner", - "category": "Macro tokens", - "area": "macros", - "group": "Concave corner", - "description": "Corner the .sf-corner-scoop mask cuts, as a radial-gradient origin (e.g. '100% 0' = top-right). Default: 100% 0.", - "value": "100% 0", - "aliasOf": null, - "registered": false, - "animatable": false, - "syntax": null, - "inherits": null, - "optional": false, - "layer": "slashed.tokens", - "sourceFiles": [ - "core/tokens.macros.css" - ], - "bundles": [ - "full", - "optimal" - ] - }, - { - "name": "--sf-corner-scoop-size", - "type": "token", - "tier": "PUBLIC", - "role": "consumption", - "namespace": "corner", - "category": "Macro tokens", - "area": "macros", - "group": "Concave corner", - "description": "Cut radius of the .sf-corner-scoop mask. Default: var(--sf-radius-2xl).", - "value": "var(--sf-radius-2xl)", - "aliasOf": "--sf-radius-2xl", - "registered": false, - "animatable": false, - "syntax": null, - "inherits": null, - "optional": false, - "layer": "slashed.tokens", - "sourceFiles": [ - "core/tokens.macros.css" - ], - "bundles": [ - "full", - "optimal" - ] - }, { "name": "--sf-cover-min-height", "type": "token", @@ -19708,7 +19656,7 @@ "kind": "accessibility", "category": "Accessibility", "area": "accessibility", - "group": "Reduced motion. Token override helps components that read", + "group": "", "description": "Suppresses all animations and transitions within the subtree. Apply to a container to create a reduced-motion zone without relying on the system preference.", "isVariant": false, "baseClass": null, @@ -19731,7 +19679,7 @@ "kind": "print", "category": "Print", "area": "print", - "group": "Print visibility utilities", + "group": "", "description": "Hides the element in @media print. Use on sidebars, navigation bars, and decorative elements that should not appear on paper.", "isVariant": false, "baseClass": null, @@ -19754,7 +19702,7 @@ "kind": "print", "category": "Print", "area": "print", - "group": "Opt-in colour treatment", + "group": "", "description": "Forces exact color rendering in print (print-color-adjust: exact). Use on charts and colored badges that must preserve their fill colors in print.", "isVariant": false, "baseClass": null, @@ -19777,7 +19725,7 @@ "kind": "print", "category": "Print", "area": "print", - "group": "Opt-in colour treatment", + "group": "", "description": "Strips color information in print (print-color-adjust: economy). Defers to the printer's ink-saving mode for backgrounds and non-critical color fills.", "isVariant": false, "baseClass": null, @@ -19800,7 +19748,7 @@ "kind": "print", "category": "Print", "area": "print", - "group": "Print visibility utilities", + "group": "", "description": "Hides the element on screen (display: none) but shows it in @media print. Use for print-only headers, footers, and supplementary content not needed on screen.", "isVariant": false, "baseClass": null, @@ -19823,7 +19771,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Alternate (zigzag / media-object)", + "group": "", "description": "Zigzag / alternating two-column layout. Even children align image-left/text-right; odd children flip. Collapses to a single column below the breakpoint.", "isVariant": false, "baseClass": null, @@ -19846,7 +19794,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Aspect", + "group": "", "description": "Sets aspect-ratio from a --sf-aspect-ratio scoped token. Override the token inline to get any ratio without a new class.", "isVariant": false, "baseClass": null, @@ -19869,7 +19817,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": ".sf-card", + "group": "", "description": "Auto-fill bento grid for card dashboards. Children span 1 column by default; use span modifiers (sf-bento-wide, sf-bento-tall, sf-bento-full, sf-bento-featured) to break the grid.", "isVariant": false, "baseClass": null, @@ -19892,7 +19840,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Bento grid", + "group": "", "description": "Bento grid variant with a 2-column base layout.", "isVariant": true, "baseClass": "sf-bento", @@ -19915,7 +19863,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Bento grid", + "group": "", "description": "Bento grid variant with a 3-column base layout.", "isVariant": true, "baseClass": "sf-bento", @@ -19938,7 +19886,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Bento grid", + "group": "", "description": "Bento grid variant with a 6-column base layout.", "isVariant": true, "baseClass": "sf-bento", @@ -20007,7 +19955,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Bento grid", + "group": "", "description": "Span modifier for a bento item: takes up 2×2 cells (featured hero placement).", "isVariant": false, "baseClass": null, @@ -20030,7 +19978,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Bento grid", + "group": "", "description": "Span modifier for a bento item: stretches across all columns (full-width banner).", "isVariant": false, "baseClass": null, @@ -20053,7 +20001,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Bento grid", + "group": "", "description": "Span modifier for a bento item: doubles the row height (tall card).", "isVariant": false, "baseClass": null, @@ -20076,7 +20024,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Bento grid", + "group": "", "description": "Span modifier for a bento item: spans 2 columns (wide card).", "isVariant": false, "baseClass": null, @@ -20122,7 +20070,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Box", + "group": "", "description": "Minimal padding container that applies --sf-component-pad on all sides. The simplest layout primitive for adding breathing room.", "isVariant": false, "baseClass": null, @@ -20145,7 +20093,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Content grid (breakout pattern)", + "group": "", "description": "Breaks a child element out of a parent sf-content-grid, spanning full bleed (or a named grid area) regardless of the parent column. Useful for full-width sections inside constrained prose.", "isVariant": false, "baseClass": null, @@ -20828,7 +20776,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": ".sf-card", + "group": "", "description": "Centers children both horizontally and vertically using flexbox. Optionally add sf-center--intrinsic to size the container to its content.", "isVariant": false, "baseClass": null, @@ -20851,7 +20799,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Center", + "group": "", "description": "Modifier for sf-center: constrains the container to the natural width of its children (no stretching to fill available space).", "isVariant": true, "baseClass": "sf-center", @@ -20874,7 +20822,7 @@ "kind": "accessibility", "category": "Accessibility", "area": "accessibility", - "group": "Clickable-parent", + "group": "", "description": "Makes the entire card or list-item clickable via an absolutely-positioned child overlay link. Apply to the container; place sf-clickable-parent__overlay on the .", "isVariant": false, "baseClass": null, @@ -20897,7 +20845,7 @@ "kind": "accessibility", "category": "Accessibility", "area": "accessibility", - "group": "Clickable-parent", + "group": "", "description": "The full-bleed overlay link inside an sf-clickable-parent. Stretches to cover the parent and uses pointer-events to let interactive children keep their own clicks.", "isVariant": false, "baseClass": null, @@ -20920,7 +20868,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": ".sf-card", + "group": "", "description": "Flex-wrap row of variable-width items with automatic gap. Children wrap when the container is too narrow. Use for tag lists, button groups, and icon rows.", "isVariant": false, "baseClass": null, @@ -20943,7 +20891,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cluster", + "group": "", "description": "Cluster variant with 2xl gap between items.", "isVariant": true, "baseClass": "sf-cluster", @@ -20966,7 +20914,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cluster", + "group": "", "description": "Cluster variant that distributes items with space-between alignment.", "isVariant": true, "baseClass": "sf-cluster", @@ -20989,7 +20937,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cluster", + "group": "", "description": "Cluster variant that centers the item row horizontally.", "isVariant": true, "baseClass": "sf-cluster", @@ -21012,7 +20960,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cluster", + "group": "", "description": "Cluster variant that aligns items to the inline end (right in LTR).", "isVariant": true, "baseClass": "sf-cluster", @@ -21035,7 +20983,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cluster", + "group": "", "description": "Cluster variant with large (l) gap between items.", "isVariant": true, "baseClass": "sf-cluster", @@ -21058,7 +21006,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cluster", + "group": "", "description": "Cluster variant with medium (m) gap between items.", "isVariant": true, "baseClass": "sf-cluster", @@ -21081,7 +21029,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cluster", + "group": "", "description": "Cluster variant that prevents item wrapping (single-line row).", "isVariant": true, "baseClass": "sf-cluster", @@ -21104,7 +21052,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cluster", + "group": "", "description": "Cluster variant with small (s) gap between items.", "isVariant": true, "baseClass": "sf-cluster", @@ -21127,7 +21075,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cluster", + "group": "", "description": "Cluster variant with xl gap between items.", "isVariant": true, "baseClass": "sf-cluster", @@ -21150,7 +21098,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cluster", + "group": "", "description": "Cluster variant with xs gap between items.", "isVariant": true, "baseClass": "sf-cluster", @@ -21173,7 +21121,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "@property color animation", + "group": "", "description": "Applies a gentle color-pulse animation to draw attention to a dynamic value change (e.g. a counter updating). Scoped to users who have not requested reduced motion.", "isVariant": false, "baseClass": null, @@ -21196,7 +21144,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Section", + "group": "", "description": "Max-width page container, centered with auto side gutters. Establishes a named inline-size container (cq-container) for container queries. Default width is --sf-container-m.", "isVariant": false, "baseClass": null, @@ -21219,7 +21167,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Container", + "group": "", "description": "Container variant that spans the full viewport width (no max-width cap).", "isVariant": true, "baseClass": "sf-container", @@ -21242,7 +21190,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Container", + "group": "", "description": "Container variant with a narrower max-width (--sf-container-s). Use for single-column prose and forms.", "isVariant": true, "baseClass": "sf-container", @@ -21265,7 +21213,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Container", + "group": "", "description": "Container variant with a prose-optimised max-width (--sf-container-prose). Ideal for long-form reading content.", "isVariant": true, "baseClass": "sf-container", @@ -21288,7 +21236,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Container", + "group": "", "description": "Container variant with a wider max-width (--sf-container-l). Use for dashboards and wide media.", "isVariant": true, "baseClass": "sf-container", @@ -21311,7 +21259,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Content visibility", + "group": "", "description": "Sets content-visibility: auto on the element. The browser skips rendering off-screen content, improving LCP for long pages.", "isVariant": false, "baseClass": null, @@ -21334,7 +21282,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Content grid (breakout pattern)", + "group": "", "description": "Holy-grail content grid with named areas: full-bleed, popout, and content columns. Use sf-breakout on children to escape the content column.", "isVariant": false, "baseClass": null, @@ -21348,121 +21296,6 @@ "optimal" ] }, - { - "name": "sf-corner-scoop", - "type": "class", - "tier": "PUBLIC", - "selector": ".sf-corner-scoop", - "prefix": "sf", - "kind": "macro", - "category": "Macro classes", - "area": "macros", - "group": "", - "description": "Concave \"scooped\" corner cut with a radial-gradient mask; defaults to the top-right corner (--sf-corner-scoop-at). Add a placement modifier to move it.", - "isVariant": false, - "baseClass": null, - "optional": false, - "layer": "slashed.macros", - "sourceFiles": [ - "core/macros.css" - ], - "bundles": [ - "full", - "optimal" - ] - }, - { - "name": "sf-corner-scoop--bottom-left", - "type": "class", - "tier": "PUBLIC", - "selector": ".sf-corner-scoop--bottom-left", - "prefix": "sf", - "kind": "macro", - "category": "Macro classes", - "area": "macros", - "group": "", - "description": "Places the concave corner scoop at the bottom-left corner.", - "isVariant": true, - "baseClass": "sf-corner-scoop", - "optional": false, - "layer": "slashed.macros", - "sourceFiles": [ - "core/macros.css" - ], - "bundles": [ - "full", - "optimal" - ] - }, - { - "name": "sf-corner-scoop--bottom-right", - "type": "class", - "tier": "PUBLIC", - "selector": ".sf-corner-scoop--bottom-right", - "prefix": "sf", - "kind": "macro", - "category": "Macro classes", - "area": "macros", - "group": "", - "description": "Places the concave corner scoop at the bottom-right corner.", - "isVariant": true, - "baseClass": "sf-corner-scoop", - "optional": false, - "layer": "slashed.macros", - "sourceFiles": [ - "core/macros.css" - ], - "bundles": [ - "full", - "optimal" - ] - }, - { - "name": "sf-corner-scoop--top-left", - "type": "class", - "tier": "PUBLIC", - "selector": ".sf-corner-scoop--top-left", - "prefix": "sf", - "kind": "macro", - "category": "Macro classes", - "area": "macros", - "group": "", - "description": "Places the concave corner scoop at the top-left corner.", - "isVariant": true, - "baseClass": "sf-corner-scoop", - "optional": false, - "layer": "slashed.macros", - "sourceFiles": [ - "core/macros.css" - ], - "bundles": [ - "full", - "optimal" - ] - }, - { - "name": "sf-corner-scoop--top-right", - "type": "class", - "tier": "PUBLIC", - "selector": ".sf-corner-scoop--top-right", - "prefix": "sf", - "kind": "macro", - "category": "Macro classes", - "area": "macros", - "group": "", - "description": "Places the concave corner scoop at the top-right corner.", - "isVariant": true, - "baseClass": "sf-corner-scoop", - "optional": false, - "layer": "slashed.macros", - "sourceFiles": [ - "core/macros.css" - ], - "bundles": [ - "full", - "optimal" - ] - }, { "name": "sf-cover", "type": "class", @@ -21472,7 +21305,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": ".sf-card", + "group": "", "description": "Vertically stretches to at least a viewport height with a centered element (sf-cover__center). Typical use: hero sections.", "isVariant": false, "baseClass": null, @@ -21495,7 +21328,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cover", + "group": "", "description": "The centered focal element inside an sf-cover. Stays vertically centered even when the cover content is shorter than the viewport.", "isVariant": false, "baseClass": null, @@ -21518,7 +21351,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cover", + "group": "", "description": "Cover variant that uses a max-height instead of min-height for the viewport constraint.", "isVariant": true, "baseClass": "sf-cover", @@ -21541,7 +21374,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cover", + "group": "", "description": "Cover variant that reduces the minimum height to half a viewport.", "isVariant": true, "baseClass": "sf-cover", @@ -21564,7 +21397,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cover", + "group": "", "description": "Cover variant with large vertical padding above and below the centered content.", "isVariant": true, "baseClass": "sf-cover", @@ -21587,7 +21420,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Cover", + "group": "", "description": "Cover variant with small vertical padding above and below the centered content.", "isVariant": true, "baseClass": "sf-cover", @@ -21610,7 +21443,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Container query context", + "group": "", "description": "Assigns an inline-size container context to any element. Children can then use @container rules or container-query-aware tokens.", "isVariant": false, "baseClass": null, @@ -21633,7 +21466,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Divide", + "group": "", "description": "Rules between direct children (a border on each child after the first), reusing .sf-divider's tokens — no per-gap markup needed.", "isVariant": false, "baseClass": null, @@ -21656,7 +21489,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Divide", + "group": "", "description": "Vertical rules between direct children (inline-start borders), for row/horizontal layouts.", "isVariant": true, "baseClass": "sf-divide", @@ -21679,7 +21512,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Divider", + "group": "", "description": "Horizontal rule (divider line). Uses --sf-divider-* tokens for color, width, and style. Modifiers change dash style or orientation.", "isVariant": false, "baseClass": null, @@ -21702,7 +21535,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Divider", + "group": "", "description": "Divider variant with a dashed stroke.", "isVariant": true, "baseClass": "sf-divider", @@ -21725,7 +21558,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Divider", + "group": "", "description": "Divider variant with a dotted stroke.", "isVariant": true, "baseClass": "sf-divider", @@ -21748,7 +21581,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Divider", + "group": "", "description": "Divider variant rendered as a gradient that fades to transparent at both ends.", "isVariant": true, "baseClass": "sf-divider", @@ -21771,7 +21604,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Divider", + "group": "", "description": "Divider variant with reduced opacity (subtle separator).", "isVariant": true, "baseClass": "sf-divider", @@ -21794,7 +21627,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Divider", + "group": "", "description": "Divider variant with stronger/darker color for a more prominent separator.", "isVariant": true, "baseClass": "sf-divider", @@ -21817,7 +21650,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Divider", + "group": "", "description": "Divider variant rendered as a vertical line. Use inside flex or grid containers.", "isVariant": true, "baseClass": "sf-divider", @@ -21955,7 +21788,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Scroll-driven entrances", + "group": "", "description": "Scroll-driven entrance: element fades in as it enters the viewport. Animation tied to scroll progress via animation-timeline.", "isVariant": true, "baseClass": "sf-entrance", @@ -21978,7 +21811,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Scroll-driven entrances", + "group": "", "description": "Scroll-driven entrance: element fades in while moving downward into position.", "isVariant": true, "baseClass": "sf-entrance", @@ -22001,7 +21834,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Scroll-driven entrances", + "group": "", "description": "Scroll-driven entrance: element fades in while moving from the right toward the left.", "isVariant": true, "baseClass": "sf-entrance", @@ -22024,7 +21857,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Scroll-driven entrances", + "group": "", "description": "Scroll-driven entrance: element fades in while moving from the left toward the right.", "isVariant": true, "baseClass": "sf-entrance", @@ -22047,7 +21880,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Scroll-driven entrances", + "group": "", "description": "Scroll-driven entrance: element fades in while moving upward into position.", "isVariant": true, "baseClass": "sf-entrance", @@ -22070,7 +21903,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Scroll-driven entrances", + "group": "", "description": "Scroll-driven entrance: element fades in while scaling up from a slightly smaller size.", "isVariant": true, "baseClass": "sf-entrance", @@ -22093,7 +21926,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Equal columns (intrinsically responsive)", + "group": "", "description": "Flowing CSS multi-column layout (not a grid) — content distributes across columns like a newspaper instead of sitting in fixed cells. Reach for .sf-grid/.sf-grid--fit for discrete grid cells instead.", "isVariant": false, "baseClass": null, @@ -22116,7 +21949,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Equal columns (intrinsically responsive)", + "group": "", "description": "Equal-columns variant locked to column-count: 2.", "isVariant": true, "baseClass": "sf-equal", @@ -22139,7 +21972,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Equal columns (intrinsically responsive)", + "group": "", "description": "Equal-columns variant locked to column-count: 3.", "isVariant": true, "baseClass": "sf-equal", @@ -22162,7 +21995,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Equal columns (intrinsically responsive)", + "group": "", "description": "Equal-columns variant locked to column-count: 4.", "isVariant": true, "baseClass": "sf-equal", @@ -22185,7 +22018,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Equal columns (intrinsically responsive)", + "group": "", "description": "Equal-columns variant locked to column-count: 6.", "isVariant": true, "baseClass": "sf-equal", @@ -22208,7 +22041,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Equal height", + "group": "", "description": "Forces all flex children to equal height (align-items: stretch). Use on a flex row to make cards in a grid share the tallest card's height.", "isVariant": false, "baseClass": null, @@ -22369,7 +22202,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Animation presets", + "group": "", "description": "One-shot fade-in animation (opacity 0 → 1). Scoped to no-preference so it stops automatically for reduced-motion users.", "isVariant": false, "baseClass": null, @@ -22392,7 +22225,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Animation presets", + "group": "", "description": "One-shot fade-out animation (opacity 1 → 0). Scoped to no-preference.", "isVariant": false, "baseClass": null, @@ -22415,7 +22248,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Flow", + "group": "", "description": "Applies --sf-flow-space as margin-block-start to all direct children except the first. Establishes consistent vertical rhythm in prose-like containers.", "isVariant": false, "baseClass": null, @@ -22461,7 +22294,7 @@ "kind": "accessibility", "category": "Accessibility", "area": "accessibility", - "group": "Focus-parent", + "group": "", "description": "Forwards focus-visible styling to this container when any descendant is keyboard-focused. Useful for custom controls that wrap a visually-hidden .", "isVariant": false, "baseClass": null, @@ -22484,7 +22317,7 @@ "kind": "accessibility", "category": "Accessibility", "area": "accessibility", - "group": "Focus-shadow opt-in", + "group": "", "description": "Applies the standard focus ring as a box-shadow to any element. Use on custom controls where the native :focus-visible ring doesn't render correctly.", "isVariant": false, "baseClass": null, @@ -22507,7 +22340,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": ".sf-card", + "group": "", "description": "Aspect-ratio container for media (images, video, maps). Children fill and cover the fixed-ratio box. Default ratio is 16:9.", "isVariant": false, "baseClass": null, @@ -22530,7 +22363,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Frame", + "group": "", "description": "Frame variant locked to a 3:2 aspect ratio.", "isVariant": true, "baseClass": "sf-frame", @@ -22553,7 +22386,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Frame", + "group": "", "description": "Frame variant locked to a 4:3 aspect ratio.", "isVariant": true, "baseClass": "sf-frame", @@ -22576,7 +22409,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Frame", + "group": "", "description": "Frame variant locked to a cinematic 21:9 aspect ratio.", "isVariant": true, "baseClass": "sf-frame", @@ -22599,7 +22432,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Frame", + "group": "", "description": "Frame variant locked to the golden ratio (1.618:1).", "isVariant": true, "baseClass": "sf-frame", @@ -22622,7 +22455,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Frame", + "group": "", "description": "Frame variant locked to a portrait 2:3 aspect ratio.", "isVariant": true, "baseClass": "sf-frame", @@ -22645,7 +22478,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Frame", + "group": "", "description": "Frame variant locked to a square 1:1 aspect ratio.", "isVariant": true, "baseClass": "sf-frame", @@ -22668,7 +22501,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Frame", + "group": "", "description": "Frame variant locked to the standard 16:9 video aspect ratio.", "isVariant": true, "baseClass": "sf-frame", @@ -22691,7 +22524,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Content grid (breakout pattern)", + "group": "", "description": "Forces an element to span the full viewport width, breaking out of any centered container. Use for full-bleed images and section backgrounds.", "isVariant": false, "baseClass": null, @@ -22714,7 +22547,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Gap", + "group": "", "description": "Injects the default --sf-gap into an existing flex or grid container without imposing display:flex itself. Use when the parent is already a flex or grid.", "isVariant": false, "baseClass": null, @@ -22737,7 +22570,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Gap", + "group": "", "description": "Gap injection variant with 2xl gap value.", "isVariant": true, "baseClass": "sf-gap", @@ -22760,7 +22593,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Gap", + "group": "", "description": "Gap injection variant with large (l) gap value.", "isVariant": true, "baseClass": "sf-gap", @@ -22783,7 +22616,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Gap", + "group": "", "description": "Gap injection variant with medium (m) gap value.", "isVariant": true, "baseClass": "sf-gap", @@ -22806,7 +22639,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Gap", + "group": "", "description": "Gap injection variant with small (s) gap value.", "isVariant": true, "baseClass": "sf-gap", @@ -22829,7 +22662,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Gap", + "group": "", "description": "Gap injection variant with xl gap value.", "isVariant": true, "baseClass": "sf-gap", @@ -22852,7 +22685,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Gap", + "group": "", "description": "Gap injection variant with xs gap value.", "isVariant": true, "baseClass": "sf-gap", @@ -22875,7 +22708,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": ".sf-card", + "group": "", "description": "Auto-fill CSS grid. Columns are sized with RAM pattern (Repeat, Auto-fill, Minmax) and wrap automatically. Default column min-width is --sf-grid-min-col.", "isVariant": false, "baseClass": null, @@ -22898,7 +22731,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with a 2xl minimum column width.", "isVariant": true, "baseClass": "sf-grid", @@ -22921,7 +22754,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with grid-auto-flow: dense, allowing the grid to fill holes created by span modifiers.", "isVariant": true, "baseClass": "sf-grid", @@ -22944,7 +22777,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (auto)", + "group": "", "description": "Grid variant that switches from auto-fill to auto-fit, collapsing empty columns.", "isVariant": true, "baseClass": "sf-grid", @@ -22967,7 +22800,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with a large (l) minimum column width.", "isVariant": true, "baseClass": "sf-grid", @@ -22990,7 +22823,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with a medium (m) minimum column width.", "isVariant": true, "baseClass": "sf-grid", @@ -23013,7 +22846,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with a small (s) minimum column width.", "isVariant": true, "baseClass": "sf-grid", @@ -23036,7 +22869,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with an xl minimum column width.", "isVariant": true, "baseClass": "sf-grid", @@ -23059,7 +22892,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (auto)", + "group": "", "description": "Grid variant with an xs minimum column width.", "isVariant": true, "baseClass": "sf-grid", @@ -23082,7 +22915,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Single-column grid", + "group": "", "description": "Single-column layout (forces all children to one column).", "isVariant": false, "baseClass": null, @@ -23105,7 +22938,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Ratio grids", + "group": "", "description": "Two-column ratio grid: first child takes 1fr, second takes 2fr. Container-query responsive.", "isVariant": false, "baseClass": null, @@ -23128,7 +22961,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Ratio grids", + "group": "", "description": "Two-column ratio grid: first child takes 1fr, second takes 3fr. Container-query responsive.", "isVariant": false, "baseClass": null, @@ -23151,7 +22984,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Fixed column grids (container-query responsive)", + "group": "", "description": "Responsive 2-column fixed grid. Uses container queries to collapse to one column on narrow containers.", "isVariant": false, "baseClass": null, @@ -23174,7 +23007,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Ratio grids", + "group": "", "description": "Two-column ratio grid: first child takes 2fr, second takes 1fr. Container-query responsive.", "isVariant": false, "baseClass": null, @@ -23197,7 +23030,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Fixed column grids (container-query responsive)", + "group": "", "description": "Responsive 3-column fixed grid. Collapses progressively on narrow containers.", "isVariant": false, "baseClass": null, @@ -23220,7 +23053,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Ratio grids", + "group": "", "description": "Two-column ratio grid: first child takes 3fr, second takes 1fr. Container-query responsive.", "isVariant": false, "baseClass": null, @@ -23243,7 +23076,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Fixed column grids (container-query responsive)", + "group": "", "description": "Responsive 4-column fixed grid. Collapses progressively on narrow containers.", "isVariant": false, "baseClass": null, @@ -23266,7 +23099,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Fixed column grids (container-query responsive)", + "group": "", "description": "Responsive 6-column fixed grid. Collapses progressively on narrow containers.", "isVariant": false, "baseClass": null, @@ -23289,7 +23122,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": ".sf-card", + "group": "", "description": "Flexbox alternative to .sf-grid for item counts that don't divide evenly: leftover last-row items stretch to fill the row by default, or stay fixed-width and centered with --center.", "isVariant": false, "baseClass": null, @@ -23312,7 +23145,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant with a 2xl minimum item width.", "isVariant": true, "baseClass": "sf-grid-flex", @@ -23335,7 +23168,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant that keeps last-row leftover items fixed-width and centered instead of stretching.", "isVariant": true, "baseClass": "sf-grid-flex", @@ -23358,7 +23191,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant with a large (l) minimum item width.", "isVariant": true, "baseClass": "sf-grid-flex", @@ -23381,7 +23214,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant with a medium (m) minimum item width.", "isVariant": true, "baseClass": "sf-grid-flex", @@ -23404,7 +23237,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant with a small (s) minimum item width.", "isVariant": true, "baseClass": "sf-grid-flex", @@ -23427,7 +23260,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant with an xl minimum item width.", "isVariant": true, "baseClass": "sf-grid-flex", @@ -23450,7 +23283,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Grid (flex)", + "group": "", "description": "Grid-flex variant with an xs minimum item width.", "isVariant": true, "baseClass": "sf-grid-flex", @@ -23852,7 +23685,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Icon", + "group": "", "description": "Inline icon sizing primitive. Sets width and height to --sf-icon-m via em-based tokens so the icon scales with the surrounding text.", "isVariant": false, "baseClass": null, @@ -23875,7 +23708,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Icon", + "group": "", "description": "Icon variant sized to --sf-icon-2xl (extra-extra-large).", "isVariant": true, "baseClass": "sf-icon", @@ -23898,7 +23731,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Icon", + "group": "", "description": "Icon variant with a square bordered box background. Useful for standalone icon buttons and feature icons.", "isVariant": true, "baseClass": "sf-icon", @@ -23921,7 +23754,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Icon", + "group": "", "description": "Icon variant sized to --sf-icon-l (large).", "isVariant": true, "baseClass": "sf-icon", @@ -23944,7 +23777,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Icon", + "group": "", "description": "Icon variant sized to --sf-icon-m (medium, same as base sf-icon).", "isVariant": true, "baseClass": "sf-icon", @@ -23967,7 +23800,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Icon", + "group": "", "description": "Icon variant sized to --sf-icon-s (small).", "isVariant": true, "baseClass": "sf-icon", @@ -23990,7 +23823,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Icon", + "group": "", "description": "Icon variant sized to --sf-icon-xl (extra-large).", "isVariant": true, "baseClass": "sf-icon", @@ -24013,7 +23846,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Icon", + "group": "", "description": "Icon variant sized to --sf-icon-xs (extra-small).", "isVariant": true, "baseClass": "sf-icon", @@ -24036,7 +23869,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Imposter", + "group": "", "description": "Absolutely positions an element at the center of its nearest positioned ancestor. Use for overlays, badges, and floating labels.", "isVariant": false, "baseClass": null, @@ -24059,7 +23892,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Imposter", + "group": "", "description": "Imposter variant that clamps the element within the bounds of its parent using overflow:hidden on the parent.", "isVariant": true, "baseClass": "sf-imposter", @@ -24082,7 +23915,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Imposter", + "group": "", "description": "Imposter variant that uses position:fixed instead of absolute. Use for viewport-level overlays and modals.", "isVariant": true, "baseClass": "sf-imposter", @@ -24752,7 +24585,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Truncate / line-clamp", + "group": "", "description": "Clamps text to 2 lines with an ellipsis. Applies -webkit-line-clamp: 2.", "isVariant": false, "baseClass": null, @@ -24775,7 +24608,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Truncate / line-clamp", + "group": "", "description": "Clamps text to 3 lines with an ellipsis. Applies -webkit-line-clamp: 3.", "isVariant": false, "baseClass": null, @@ -24798,7 +24631,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Truncate / line-clamp", + "group": "", "description": "Clamps text to a custom N lines. Set --sf-line-clamp on the element to control the number of visible lines.", "isVariant": false, "baseClass": null, @@ -24821,7 +24654,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Link variants", + "group": "", "description": "Link color modifier: reverses the default link color to work on dark/inverted backgrounds. Sets color to --sf-color-text--inverse.", "isVariant": true, "baseClass": "sf-link", @@ -24844,7 +24677,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Link variants", + "group": "", "description": "Link color modifier: renders the link in the body text color instead of the default action color. Underline still indicates the link on hover.", "isVariant": true, "baseClass": "sf-link", @@ -24867,7 +24700,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "External link indication", + "group": "", "description": "Automatically appends an external-link icon (via ::after content) to indicate the link opens in a new tab or goes to an external domain.", "isVariant": false, "baseClass": null, @@ -25024,7 +24857,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "No tap highlight", + "group": "", "description": "Removes the mobile tap highlight color (-webkit-tap-highlight-color: transparent). Use on interactive elements with a custom active state.", "isVariant": false, "baseClass": null, @@ -25047,7 +24880,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Prose", + "group": "", "description": "Opt-out of sf-prose typography styles within a prose block. Apply to an element that should keep default browser or component styles.", "isVariant": false, "baseClass": null, @@ -25070,7 +24903,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Overflow fade", + "group": "", "description": "Adds a gradient fade at the inline-end of an overflowing element to hint at hidden content. Use inside sf-reel or any scroll container.", "isVariant": false, "baseClass": null, @@ -25369,7 +25202,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Pancake (sticky footer)", + "group": "", "description": "Three-row layout (header, main, footer) where main takes all remaining vertical space via flex-grow. The footer always sticks to the bottom on tall viewports.", "isVariant": false, "baseClass": null, @@ -25416,7 +25249,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": ".sf-card", + "group": "", "description": "Horizontally scrollable row of fixed-height items with snap scrolling. Children don't shrink below their intrinsic width, creating a card carousel effect.", "isVariant": false, "baseClass": null, @@ -25439,7 +25272,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Animation presets", + "group": "", "description": "One-shot scale-down animation (element shrinks from full size). Scoped to no-preference.", "isVariant": false, "baseClass": null, @@ -25462,7 +25295,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Animation presets", + "group": "", "description": "One-shot scale-up animation (element grows from smaller size). Scoped to no-preference.", "isVariant": false, "baseClass": null, @@ -25485,7 +25318,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Scrim", + "group": "", "description": "Overlay container with a gradient darkening scrim behind text placed on an image or colored background.", "isVariant": false, "baseClass": null, @@ -25508,7 +25341,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Scrim", + "group": "", "description": "Content area inside an sf-scrim. Positioned above the gradient overlay layer.", "isVariant": false, "baseClass": null, @@ -25531,7 +25364,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Scrim", + "group": "", "description": "Scrim variant with the gradient emanating from the bottom edge (bottom-to-top fade).", "isVariant": true, "baseClass": "sf-scrim", @@ -25554,7 +25387,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Scrim", + "group": "", "description": "Scrim variant that covers the entire surface with a uniform translucent overlay.", "isVariant": true, "baseClass": "sf-scrim", @@ -25577,7 +25410,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Scrim", + "group": "", "description": "Scrim variant with the gradient emanating from the top edge (top-to-bottom fade).", "isVariant": true, "baseClass": "sf-scrim", @@ -25600,7 +25433,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Scroll shadow", + "group": "", "description": "Adds inset box-shadows at the top and bottom of a scrollable container to indicate hidden overflow above or below.", "isVariant": false, "baseClass": null, @@ -25623,7 +25456,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Scroll snap", + "group": "", "description": "Enables CSS scroll-snap-type: x mandatory on a horizontal scroll container. Children should have scroll-snap-align.", "isVariant": false, "baseClass": null, @@ -25646,7 +25479,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Section", + "group": "", "description": "Full-width page section with vertical padding (--sf-section-pad-default). Use to create visually distinct content bands.", "isVariant": false, "baseClass": null, @@ -25669,7 +25502,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Section", + "group": "", "description": "Section variant with 2xl vertical padding.", "isVariant": true, "baseClass": "sf-section", @@ -25692,7 +25525,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Collapse modifier", + "group": "", "description": "Section variant that removes vertical padding (zero-padding section for adjacent same-color blocks).", "isVariant": true, "baseClass": "sf-section", @@ -25715,7 +25548,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Section", + "group": "", "description": "Adds horizontal page gutters directly to a section — use when you want to skip a separate .sf-container wrapper (gutterless layout inside section). Neutralises container gutter to prevent double padding.", "isVariant": true, "baseClass": "sf-section", @@ -25738,7 +25571,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Section", + "group": "", "description": "Section variant with large (l) vertical padding.", "isVariant": true, "baseClass": "sf-section", @@ -25761,7 +25594,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Section", + "group": "", "description": "Section variant with medium (m) vertical padding.", "isVariant": true, "baseClass": "sf-section", @@ -25784,7 +25617,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Section", + "group": "", "description": "Section variant with small (s) vertical padding.", "isVariant": true, "baseClass": "sf-section", @@ -25807,7 +25640,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Section", + "group": "", "description": "Section variant with xl vertical padding.", "isVariant": true, "baseClass": "sf-section", @@ -25830,7 +25663,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Section", + "group": "", "description": "Section variant with xs vertical padding.", "isVariant": true, "baseClass": "sf-section", @@ -25853,7 +25686,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Section", + "group": "", "description": "Groups adjacent sf-section elements so their combined padding collapses correctly at the top and bottom edges.", "isVariant": false, "baseClass": null, @@ -25898,7 +25731,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": ".sf-card", + "group": "", "description": "Two-column sidebar layout: first child is the sidebar, second child is main content. The sidebar collapses below the breakpoint (--sf-sidebar-min-width). Default sidebar on the left.", "isVariant": false, "baseClass": null, @@ -25921,7 +25754,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Sidebar", + "group": "", "description": "Sidebar variant with a narrower sidebar column.", "isVariant": true, "baseClass": "sf-sidebar", @@ -25944,7 +25777,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Sidebar", + "group": "", "description": "Sidebar variant with the sidebar on the right (second child becomes the sidebar).", "isVariant": true, "baseClass": "sf-sidebar", @@ -25967,7 +25800,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Sidebar", + "group": "", "description": "Sidebar variant with a wider sidebar column.", "isVariant": true, "baseClass": "sf-sidebar", @@ -25990,7 +25823,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Animation presets", + "group": "", "description": "One-shot slide-in-from-above animation. Scoped to no-preference.", "isVariant": false, "baseClass": null, @@ -26013,7 +25846,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Animation presets", + "group": "", "description": "One-shot slide-in-from-right animation (slides to the left). Scoped to no-preference.", "isVariant": false, "baseClass": null, @@ -26036,7 +25869,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Animation presets", + "group": "", "description": "One-shot slide-in-from-left animation (slides to the right). Scoped to no-preference.", "isVariant": false, "baseClass": null, @@ -26059,7 +25892,7 @@ "kind": "motion", "category": "Motion / animation", "area": "motion", - "group": "Animation presets", + "group": "", "description": "One-shot slide-in-from-below animation. Scoped to no-preference.", "isVariant": false, "baseClass": null, @@ -26082,7 +25915,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": ".sf-card", + "group": "", "description": "Flex column with even vertical spacing between children (--sf-stack-gap). Stacking context for vertical rhythm.", "isVariant": false, "baseClass": null, @@ -26105,7 +25938,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Stack", + "group": "", "description": "Stack variant with 2xl gap between children.", "isVariant": true, "baseClass": "sf-stack", @@ -26128,7 +25961,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Stack", + "group": "", "description": "Stack variant that centers children on the cross axis.", "isVariant": true, "baseClass": "sf-stack", @@ -26151,7 +25984,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Stack", + "group": "", "description": "Stack variant that aligns children to the cross-axis end (right in LTR).", "isVariant": true, "baseClass": "sf-stack", @@ -26174,7 +26007,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Stack", + "group": "", "description": "Stack variant with large (l) gap between children.", "isVariant": true, "baseClass": "sf-stack", @@ -26197,7 +26030,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Stack", + "group": "", "description": "Stack variant with medium (m) gap between children.", "isVariant": true, "baseClass": "sf-stack", @@ -26220,7 +26053,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Stack", + "group": "", "description": "Stack variant with small (s) gap between children.", "isVariant": true, "baseClass": "sf-stack", @@ -26243,7 +26076,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Stack", + "group": "", "description": "Stack variant that stretches children to fill the full available width.", "isVariant": true, "baseClass": "sf-stack", @@ -26266,7 +26099,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Stack", + "group": "", "description": "Stack variant with xl gap between children.", "isVariant": true, "baseClass": "sf-stack", @@ -26289,7 +26122,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Stack", + "group": "", "description": "Stack variant with xs gap between children.", "isVariant": true, "baseClass": "sf-stack", @@ -26423,7 +26256,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Subgrid", + "group": "", "description": "Passes the parent grid columns through to children via subgrid. Place on a grid item that should align its own children to the outer grid columns.", "isVariant": false, "baseClass": null, @@ -26446,7 +26279,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Subgrid", + "group": "", "description": "Passes the parent grid rows through to children via subgrid. Place on a grid item that should align its own children to the outer grid rows.", "isVariant": false, "baseClass": null, @@ -26469,7 +26302,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Surface", + "group": "", "description": "Generic semantic surface: applies --sf-surface-color as the background and automatically sets a contrasting text color. Tone variants (--primary, --action, etc.) activate preset palettes.", "isVariant": false, "baseClass": null, @@ -26492,7 +26325,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Surface", + "group": "", "description": "Surface variant using the action color palette (button/CTA primary color).", "isVariant": true, "baseClass": "sf-surface", @@ -26515,7 +26348,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Surface", + "group": "", "description": "Surface variant using the danger status palette.", "isVariant": true, "baseClass": "sf-surface", @@ -26538,7 +26371,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Surface", + "group": "", "description": "Surface variant using the info status palette.", "isVariant": true, "baseClass": "sf-surface", @@ -26561,7 +26394,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Surface", + "group": "", "description": "Surface variant that inverts light/dark, creating an always-dark surface in light mode and always-light in dark mode.", "isVariant": true, "baseClass": "sf-surface", @@ -26584,7 +26417,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Surface", + "group": "", "description": "Surface variant using the neutral palette (muted/gray).", "isVariant": true, "baseClass": "sf-surface", @@ -26607,7 +26440,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Surface", + "group": "", "description": "Surface variant using the primary brand color palette.", "isVariant": true, "baseClass": "sf-surface", @@ -26630,7 +26463,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Surface", + "group": "", "description": "Surface variant using the secondary brand color palette.", "isVariant": true, "baseClass": "sf-surface", @@ -26653,7 +26486,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Surface", + "group": "", "description": "Surface variant using the success status palette.", "isVariant": true, "baseClass": "sf-surface", @@ -26676,7 +26509,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Surface", + "group": "", "description": "Surface variant using the tertiary brand color palette.", "isVariant": true, "baseClass": "sf-surface", @@ -26699,7 +26532,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Surface", + "group": "", "description": "Surface variant using the warning status palette.", "isVariant": true, "baseClass": "sf-surface", @@ -26745,7 +26578,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": ".sf-card", + "group": "", "description": "Flex layout that switches from a horizontal row to a vertical column when the container is narrower than --sf-switcher-threshold.", "isVariant": false, "baseClass": null, @@ -26768,7 +26601,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Switcher", + "group": "", "description": "Switcher variant that stays horizontal and never wraps (single-line regardless of container width).", "isVariant": true, "baseClass": "sf-switcher", @@ -26791,7 +26624,7 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Switcher", + "group": "", "description": "Switcher variant that starts in the vertical (stacked) direction on all sizes.", "isVariant": true, "baseClass": "sf-switcher", @@ -26814,7 +26647,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Tabular figures", + "group": "", "description": "Forces tabular (monospaced) number rendering. Use on price tables, counters, and anywhere numbers need to align vertically across rows.", "isVariant": false, "baseClass": null, @@ -26925,7 +26758,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Text gradient", + "group": "", "description": "Applies a brand gradient to inline text. Sets the background to the gradient, clips it to the text, and makes the text color transparent.", "isVariant": false, "baseClass": null, @@ -26993,7 +26826,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Text protect", + "group": "", "description": "Wraps text in a translucent dark gradient overlay to ensure legibility when placed over a light or variable background image.", "isVariant": false, "baseClass": null, @@ -27128,7 +26961,7 @@ "kind": "theme", "category": "Theme utilities", "area": "theme", - "group": "OPT-IN THEME CROSS-FADE", + "group": "", "description": "Opt-in animated light/dark theme crossfade. Apply to (or a subtree) so color tokens transition smoothly when [data-theme] changes. Duration controlled by --sf-theme-transition-duration.", "isVariant": false, "baseClass": null, @@ -27151,7 +26984,7 @@ "kind": "macro", "category": "Macro classes", "area": "macros", - "group": "Truncate / line-clamp", + "group": "", "description": "Single-line text overflow with ellipsis. Equivalent to the classic text-overflow: ellipsis trio (white-space nowrap, overflow hidden, text-overflow ellipsis).", "isVariant": false, "baseClass": null, @@ -27174,7 +27007,7 @@ "kind": "accessibility", "category": "Accessibility", "area": "accessibility", - "group": "Skip link", + "group": "", "description": "Accessible skip-navigation link. Hidden until focused; jumps keyboard users past repeated navigation blocks. Place as the very first element in .", "isVariant": false, "baseClass": null, @@ -27197,7 +27030,7 @@ "kind": "accessibility", "category": "Accessibility", "area": "accessibility", - "group": "Screen-reader-only. Atomic contract: a partial override", + "group": "", "description": "Visually hides content while keeping it accessible to screen readers. Use for labels, descriptions, and off-screen text that assistive technology needs.", "isVariant": false, "baseClass": null, @@ -27220,7 +27053,7 @@ "kind": "accessibility", "category": "Accessibility", "area": "accessibility", - "group": "Screen-reader-only. Atomic contract: a partial override", + "group": "", "description": "Extends sr-only — also reveals the element when it receives keyboard focus. Typical use: skip links and visually-hidden focus targets.", "isVariant": false, "baseClass": null, diff --git a/docs/api-index.md b/docs/api-index.md index f50abde2..a87508b9 100644 --- a/docs/api-index.md +++ b/docs/api-index.md @@ -10,15 +10,15 @@ 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). -**1086 elements** — 756 tokens, 330 classes. +**1079 elements** — 754 tokens, 325 classes. | Tier | Count | Meaning | |---|---|---| -| PUBLIC | 1025 | Everyday surface. SemVer-stable. | +| PUBLIC | 1018 | Everyday surface. SemVer-stable. | | PUBLIC-ADVANCED | 60 | Same SemVer guarantee; niche/powerful. | | INTERNAL | 1 | Implementation detail; may change without a major bump. | -## Tokens (756) +## Tokens (754) ### Component tokens (46) @@ -757,14 +757,12 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-switcher-gap` | PUBLIC | consumption | switcher | `var(--sf-gap)` | Gap between switcher columns / rows. | | `--sf-switcher-threshold` | PUBLIC | knob | switcher | `30rem` | Inline-size threshold below which the switcher flips from horizontal to vertical. | -### Macro tokens (34) +### Macro tokens (32) | Token | Tier | Role | Namespace | Default | Description | |---|---|---|---|---|---| | `--sf-aspect` | PUBLIC | knob | aspect | `16 / 9` | Aspect ratio value for the .aspect-ratio macro. | | `--sf-content-intrinsic-size` | PUBLIC | knob | content | `500px` | Intrinsic-size hint for content-visibility: auto (prevents layout shift on first reveal). | -| `--sf-corner-scoop-at` | PUBLIC | knob | corner | `100% 0` | Corner the .sf-corner-scoop mask cuts, as a radial-gradient origin (e.g. '100% 0' = top-right). Default: 100% 0. | -| `--sf-corner-scoop-size` | PUBLIC | consumption | corner | `var(--sf-radius-2xl)` | Cut radius of the .sf-corner-scoop mask. Default: var(--sf-radius-2xl). | | `--sf-flow-space` | PUBLIC | consumption | flow | `var(--sf-content-gap)` | Margin-block-start applied to all flow children except the first. | | `--sf-line-clamp` | PUBLIC | knob | line | `3` | Number of visible lines before text is clipped with an ellipsis. | | `--sf-overlap-pull` | PUBLIC | consumption | overlap | `var(--sf-space-xl)` | how far .sf-overlap pulls into the adjacent element. .sf-overlap-host's padding compensation defaults to this same value via a var() fallback in the rule itself (not aliased here — see core/macros.css), so one override on the host tunes both unless --sf-overlap-host-pad is set… | @@ -796,20 +794,20 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-surface-bg-size` | PUBLIC | knob | surface | `cover` | background-size for the .sf-surface-bg image. Default: cover. | | `--sf-surface-color` | PUBLIC | consumption | surface | `var(--sf-color-base)` | Input for the generic .sf-surface macro. Set any color (including palette shades); the macro derives background, auto-contrast foreground, and the contextual token set from it. | -## Classes (330) +## Classes (325) ### Accessibility (8) | Class | Tier | Kind | Group | Description | |---|---|---|---|---| -| `.no-motion` | PUBLIC | accessibility | Reduced motion. Token override helps components that read | Suppresses all animations and transitions within the subtree. Apply to a container to create a reduced-motion zone without relying on the system preference. | -| `.sf-clickable-parent` | PUBLIC | accessibility | Clickable-parent | Makes the entire card or list-item clickable via an absolutely-positioned child overlay link. Apply to the container; place sf-clickable-parent__overlay on the . | -| `.sf-clickable-parent__overlay` | PUBLIC | accessibility | Clickable-parent | The full-bleed overlay link inside an sf-clickable-parent. Stretches to cover the parent and uses pointer-events to let interactive children keep their own clicks. | -| `.sf-focus-parent` | PUBLIC | accessibility | Focus-parent | Forwards focus-visible styling to this container when any descendant is keyboard-focused. Useful for custom controls that wrap a visually-hidden . | -| `.sf-focus-shadow` | PUBLIC | accessibility | Focus-shadow opt-in | Applies the standard focus ring as a box-shadow to any element. Use on custom controls where the native :focus-visible ring doesn't render correctly. | -| `.skip-link` | PUBLIC | accessibility | Skip link | Accessible skip-navigation link. Hidden until focused; jumps keyboard users past repeated navigation blocks. Place as the very first element in . | -| `.sr-only` | PUBLIC | accessibility | Screen-reader-only. Atomic contract: a partial override | Visually hides content while keeping it accessible to screen readers. Use for labels, descriptions, and off-screen text that assistive technology needs. | -| `.sr-only-focusable` | PUBLIC | accessibility | Screen-reader-only. Atomic contract: a partial override | Extends sr-only — also reveals the element when it receives keyboard focus. Typical use: skip links and visually-hidden focus targets. | +| `.no-motion` | PUBLIC | accessibility | — | Suppresses all animations and transitions within the subtree. Apply to a container to create a reduced-motion zone without relying on the system preference. | +| `.sf-clickable-parent` | PUBLIC | accessibility | — | Makes the entire card or list-item clickable via an absolutely-positioned child overlay link. Apply to the container; place sf-clickable-parent__overlay on the . | +| `.sf-clickable-parent__overlay` | PUBLIC | accessibility | — | The full-bleed overlay link inside an sf-clickable-parent. Stretches to cover the parent and uses pointer-events to let interactive children keep their own clicks. | +| `.sf-focus-parent` | PUBLIC | accessibility | — | Forwards focus-visible styling to this container when any descendant is keyboard-focused. Useful for custom controls that wrap a visually-hidden . | +| `.sf-focus-shadow` | PUBLIC | accessibility | — | Applies the standard focus ring as a box-shadow to any element. Use on custom controls where the native :focus-visible ring doesn't render correctly. | +| `.skip-link` | PUBLIC | accessibility | — | Accessible skip-navigation link. Hidden until focused; jumps keyboard users past repeated navigation blocks. Place as the very first element in . | +| `.sr-only` | PUBLIC | accessibility | — | Visually hides content while keeping it accessible to screen readers. Use for labels, descriptions, and off-screen text that assistive technology needs. | +| `.sr-only-focusable` | PUBLIC | accessibility | — | Extends sr-only — also reveals the element when it receives keyboard focus. Typical use: skip links and visually-hidden focus targets. | ### Components (30) @@ -856,179 +854,174 @@ and a short description. The machine-readable companion (with all columns) is | Class | Tier | Kind | Group | Description | |---|---|---|---|---| -| `.sf-alternate` | PUBLIC | layout | Alternate (zigzag / media-object) | Zigzag / alternating two-column layout. Even children align image-left/text-right; odd children flip. Collapses to a single column below the breakpoint. | -| `.sf-bento` | PUBLIC | layout | .sf-card | Auto-fill bento grid for card dashboards. Children span 1 column by default; use span modifiers (sf-bento-wide, sf-bento-tall, sf-bento-full, sf-bento-featured) to break the grid. | -| `.sf-bento--2` | PUBLIC | layout | Bento grid | Bento grid variant with a 2-column base layout. | -| `.sf-bento--3` | PUBLIC | layout | Bento grid | Bento grid variant with a 3-column base layout. | -| `.sf-bento--6` | PUBLIC | layout | Bento grid | Bento grid variant with a 6-column base layout. | +| `.sf-alternate` | PUBLIC | layout | — | Zigzag / alternating two-column layout. Even children align image-left/text-right; odd children flip. Collapses to a single column below the breakpoint. | +| `.sf-bento` | PUBLIC | layout | — | Auto-fill bento grid for card dashboards. Children span 1 column by default; use span modifiers (sf-bento-wide, sf-bento-tall, sf-bento-full, sf-bento-featured) to break the grid. | +| `.sf-bento--2` | PUBLIC | layout | — | Bento grid variant with a 2-column base layout. | +| `.sf-bento--3` | PUBLIC | layout | — | Bento grid variant with a 3-column base layout. | +| `.sf-bento--6` | PUBLIC | layout | — | Bento grid variant with a 6-column base layout. | | `.sf-bento--row-compact` | PUBLIC | layout | — | Bento grid variant with shorter default row height. | | `.sf-bento--row-tall` | PUBLIC | layout | — | Bento grid variant with taller default row height. | -| `.sf-bento-featured` | PUBLIC | layout | Bento grid | Span modifier for a bento item: takes up 2×2 cells (featured hero placement). | -| `.sf-bento-full` | PUBLIC | layout | Bento grid | Span modifier for a bento item: stretches across all columns (full-width banner). | -| `.sf-bento-tall` | PUBLIC | layout | Bento grid | Span modifier for a bento item: doubles the row height (tall card). | -| `.sf-bento-wide` | PUBLIC | layout | Bento grid | Span modifier for a bento item: spans 2 columns (wide card). | +| `.sf-bento-featured` | PUBLIC | layout | — | Span modifier for a bento item: takes up 2×2 cells (featured hero placement). | +| `.sf-bento-full` | PUBLIC | layout | — | Span modifier for a bento item: stretches across all columns (full-width banner). | +| `.sf-bento-tall` | PUBLIC | layout | — | Span modifier for a bento item: doubles the row height (tall card). | +| `.sf-bento-wide` | PUBLIC | layout | — | Span modifier for a bento item: spans 2 columns (wide card). | | `.sf-bg-layer` | PUBLIC | layout | — | Background layer — absolutely-positioned cover media that sits behind a parent's content. The parent is auto-promoted to a positioned, isolated stacking context via :has(), so .sf-bg-layer composes natively under .sf-scrim (background → scrim gradient → content). Works as a bare or as a wrapper with a nested > img / > video / > picture. | -| `.sf-box` | PUBLIC | layout | Box | Minimal padding container that applies --sf-component-pad on all sides. The simplest layout primitive for adding breathing room. | -| `.sf-breakout` | PUBLIC | layout | Content grid (breakout pattern) | Breaks a child element out of a parent sf-content-grid, spanning full bleed (or a named grid area) regardless of the parent column. Useful for full-width sections inside constrained prose. | -| `.sf-center` | PUBLIC | layout | .sf-card | Centers children both horizontally and vertically using flexbox. Optionally add sf-center--intrinsic to size the container to its content. | -| `.sf-center--intrinsic` | PUBLIC | layout | Center | Modifier for sf-center: constrains the container to the natural width of its children (no stretching to fill available space). | -| `.sf-cluster` | PUBLIC | layout | .sf-card | Flex-wrap row of variable-width items with automatic gap. Children wrap when the container is too narrow. Use for tag lists, button groups, and icon rows. | -| `.sf-cluster--2xl` | PUBLIC | layout | Cluster | Cluster variant with 2xl gap between items. | -| `.sf-cluster--between` | PUBLIC | layout | Cluster | Cluster variant that distributes items with space-between alignment. | -| `.sf-cluster--center` | PUBLIC | layout | Cluster | Cluster variant that centers the item row horizontally. | -| `.sf-cluster--end` | PUBLIC | layout | Cluster | Cluster variant that aligns items to the inline end (right in LTR). | -| `.sf-cluster--l` | PUBLIC | layout | Cluster | Cluster variant with large (l) gap between items. | -| `.sf-cluster--m` | PUBLIC | layout | Cluster | Cluster variant with medium (m) gap between items. | -| `.sf-cluster--no-wrap` | PUBLIC | layout | Cluster | Cluster variant that prevents item wrapping (single-line row). | -| `.sf-cluster--s` | PUBLIC | layout | Cluster | Cluster variant with small (s) gap between items. | -| `.sf-cluster--xl` | PUBLIC | layout | Cluster | Cluster variant with xl gap between items. | -| `.sf-cluster--xs` | PUBLIC | layout | Cluster | Cluster variant with xs gap between items. | -| `.sf-container` | PUBLIC | layout | Section | Max-width page container, centered with auto side gutters. Establishes a named inline-size container (cq-container) for container queries. Default width is --sf-container-m. | -| `.sf-container--full` | PUBLIC | layout | Container | Container variant that spans the full viewport width (no max-width cap). | -| `.sf-container--narrow` | PUBLIC | layout | Container | Container variant with a narrower max-width (--sf-container-s). Use for single-column prose and forms. | -| `.sf-container--prose` | PUBLIC | layout | Container | Container variant with a prose-optimised max-width (--sf-container-prose). Ideal for long-form reading content. | -| `.sf-container--wide` | PUBLIC | layout | Container | Container variant with a wider max-width (--sf-container-l). Use for dashboards and wide media. | -| `.sf-content-grid` | PUBLIC | layout | Content grid (breakout pattern) | Holy-grail content grid with named areas: full-bleed, popout, and content columns. Use sf-breakout on children to escape the content column. | -| `.sf-cover` | PUBLIC | layout | .sf-card | Vertically stretches to at least a viewport height with a centered element (sf-cover__center). Typical use: hero sections. | -| `.sf-cover__center` | PUBLIC | layout | Cover | The centered focal element inside an sf-cover. Stays vertically centered even when the cover content is shorter than the viewport. | -| `.sf-cover--max` | PUBLIC | layout | Cover | Cover variant that uses a max-height instead of min-height for the viewport constraint. | -| `.sf-cover--min` | PUBLIC | layout | Cover | Cover variant that reduces the minimum height to half a viewport. | -| `.sf-cover--padding-l` | PUBLIC | layout | Cover | Cover variant with large vertical padding above and below the centered content. | -| `.sf-cover--padding-s` | PUBLIC | layout | Cover | Cover variant with small vertical padding above and below the centered content. | -| `.sf-cq` | PUBLIC | layout | Container query context | Assigns an inline-size container context to any element. Children can then use @container rules or container-query-aware tokens. | -| `.sf-divide` | PUBLIC | layout | Divide | Rules between direct children (a border on each child after the first), reusing .sf-divider's tokens — no per-gap markup needed. | -| `.sf-divide--vertical` | PUBLIC | layout | Divide | Vertical rules between direct children (inline-start borders), for row/horizontal layouts. | -| `.sf-divider` | PUBLIC | layout | Divider | Horizontal rule (divider line). Uses --sf-divider-* tokens for color, width, and style. Modifiers change dash style or orientation. | -| `.sf-divider--dashed` | PUBLIC | layout | Divider | Divider variant with a dashed stroke. | -| `.sf-divider--dotted` | PUBLIC | layout | Divider | Divider variant with a dotted stroke. | -| `.sf-divider--gradient` | PUBLIC | layout | Divider | Divider variant rendered as a gradient that fades to transparent at both ends. | -| `.sf-divider--soft` | PUBLIC | layout | Divider | Divider variant with reduced opacity (subtle separator). | -| `.sf-divider--strong` | PUBLIC | layout | Divider | Divider variant with stronger/darker color for a more prominent separator. | -| `.sf-divider--vertical` | PUBLIC | layout | Divider | Divider variant rendered as a vertical line. Use inside flex or grid containers. | -| `.sf-equal` | PUBLIC | layout | Equal columns (intrinsically responsive) | Flowing CSS multi-column layout (not a grid) — content distributes across columns like a newspaper instead of sitting in fixed cells. Reach for .sf-grid/.sf-grid--fit for discrete grid cells instead. | -| `.sf-equal--2` | PUBLIC | layout | Equal columns (intrinsically responsive) | Equal-columns variant locked to column-count: 2. | -| `.sf-equal--3` | PUBLIC | layout | Equal columns (intrinsically responsive) | Equal-columns variant locked to column-count: 3. | -| `.sf-equal--4` | PUBLIC | layout | Equal columns (intrinsically responsive) | Equal-columns variant locked to column-count: 4. | -| `.sf-equal--6` | PUBLIC | layout | Equal columns (intrinsically responsive) | Equal-columns variant locked to column-count: 6. | +| `.sf-box` | PUBLIC | layout | — | Minimal padding container that applies --sf-component-pad on all sides. The simplest layout primitive for adding breathing room. | +| `.sf-breakout` | PUBLIC | layout | — | Breaks a child element out of a parent sf-content-grid, spanning full bleed (or a named grid area) regardless of the parent column. Useful for full-width sections inside constrained prose. | +| `.sf-center` | PUBLIC | layout | — | Centers children both horizontally and vertically using flexbox. Optionally add sf-center--intrinsic to size the container to its content. | +| `.sf-center--intrinsic` | PUBLIC | layout | — | Modifier for sf-center: constrains the container to the natural width of its children (no stretching to fill available space). | +| `.sf-cluster` | PUBLIC | layout | — | Flex-wrap row of variable-width items with automatic gap. Children wrap when the container is too narrow. Use for tag lists, button groups, and icon rows. | +| `.sf-cluster--2xl` | PUBLIC | layout | — | Cluster variant with 2xl gap between items. | +| `.sf-cluster--between` | PUBLIC | layout | — | Cluster variant that distributes items with space-between alignment. | +| `.sf-cluster--center` | PUBLIC | layout | — | Cluster variant that centers the item row horizontally. | +| `.sf-cluster--end` | PUBLIC | layout | — | Cluster variant that aligns items to the inline end (right in LTR). | +| `.sf-cluster--l` | PUBLIC | layout | — | Cluster variant with large (l) gap between items. | +| `.sf-cluster--m` | PUBLIC | layout | — | Cluster variant with medium (m) gap between items. | +| `.sf-cluster--no-wrap` | PUBLIC | layout | — | Cluster variant that prevents item wrapping (single-line row). | +| `.sf-cluster--s` | PUBLIC | layout | — | Cluster variant with small (s) gap between items. | +| `.sf-cluster--xl` | PUBLIC | layout | — | Cluster variant with xl gap between items. | +| `.sf-cluster--xs` | PUBLIC | layout | — | Cluster variant with xs gap between items. | +| `.sf-container` | PUBLIC | layout | — | Max-width page container, centered with auto side gutters. Establishes a named inline-size container (cq-container) for container queries. Default width is --sf-container-m. | +| `.sf-container--full` | PUBLIC | layout | — | Container variant that spans the full viewport width (no max-width cap). | +| `.sf-container--narrow` | PUBLIC | layout | — | Container variant with a narrower max-width (--sf-container-s). Use for single-column prose and forms. | +| `.sf-container--prose` | PUBLIC | layout | — | Container variant with a prose-optimised max-width (--sf-container-prose). Ideal for long-form reading content. | +| `.sf-container--wide` | PUBLIC | layout | — | Container variant with a wider max-width (--sf-container-l). Use for dashboards and wide media. | +| `.sf-content-grid` | PUBLIC | layout | — | Holy-grail content grid with named areas: full-bleed, popout, and content columns. Use sf-breakout on children to escape the content column. | +| `.sf-cover` | PUBLIC | layout | — | Vertically stretches to at least a viewport height with a centered element (sf-cover__center). Typical use: hero sections. | +| `.sf-cover__center` | PUBLIC | layout | — | The centered focal element inside an sf-cover. Stays vertically centered even when the cover content is shorter than the viewport. | +| `.sf-cover--max` | PUBLIC | layout | — | Cover variant that uses a max-height instead of min-height for the viewport constraint. | +| `.sf-cover--min` | PUBLIC | layout | — | Cover variant that reduces the minimum height to half a viewport. | +| `.sf-cover--padding-l` | PUBLIC | layout | — | Cover variant with large vertical padding above and below the centered content. | +| `.sf-cover--padding-s` | PUBLIC | layout | — | Cover variant with small vertical padding above and below the centered content. | +| `.sf-cq` | PUBLIC | layout | — | Assigns an inline-size container context to any element. Children can then use @container rules or container-query-aware tokens. | +| `.sf-divide` | PUBLIC | layout | — | Rules between direct children (a border on each child after the first), reusing .sf-divider's tokens — no per-gap markup needed. | +| `.sf-divide--vertical` | PUBLIC | layout | — | Vertical rules between direct children (inline-start borders), for row/horizontal layouts. | +| `.sf-divider` | PUBLIC | layout | — | Horizontal rule (divider line). Uses --sf-divider-* tokens for color, width, and style. Modifiers change dash style or orientation. | +| `.sf-divider--dashed` | PUBLIC | layout | — | Divider variant with a dashed stroke. | +| `.sf-divider--dotted` | PUBLIC | layout | — | Divider variant with a dotted stroke. | +| `.sf-divider--gradient` | PUBLIC | layout | — | Divider variant rendered as a gradient that fades to transparent at both ends. | +| `.sf-divider--soft` | PUBLIC | layout | — | Divider variant with reduced opacity (subtle separator). | +| `.sf-divider--strong` | PUBLIC | layout | — | Divider variant with stronger/darker color for a more prominent separator. | +| `.sf-divider--vertical` | PUBLIC | layout | — | Divider variant rendered as a vertical line. Use inside flex or grid containers. | +| `.sf-equal` | PUBLIC | layout | — | Flowing CSS multi-column layout (not a grid) — content distributes across columns like a newspaper instead of sitting in fixed cells. Reach for .sf-grid/.sf-grid--fit for discrete grid cells instead. | +| `.sf-equal--2` | PUBLIC | layout | — | Equal-columns variant locked to column-count: 2. | +| `.sf-equal--3` | PUBLIC | layout | — | Equal-columns variant locked to column-count: 3. | +| `.sf-equal--4` | PUBLIC | layout | — | Equal-columns variant locked to column-count: 4. | +| `.sf-equal--6` | PUBLIC | layout | — | Equal-columns variant locked to column-count: 6. | | `.sf-fluid-cq` | PUBLIC | layout | — | .sf-fluid-cq: opt a subtree into a CONTAINER-relative fluid scale (issue #497). By default --sf-text-* / --sf-space-* interpolate against 100vw (the viewport); inside .sf-fluid-cq they interpolate against 100cqi (this box's inline size), so type + spacing track the container… | -| `.sf-frame` | PUBLIC | layout | .sf-card | Aspect-ratio container for media (images, video, maps). Children fill and cover the fixed-ratio box. Default ratio is 16:9. | -| `.sf-frame--3-2` | PUBLIC | layout | Frame | Frame variant locked to a 3:2 aspect ratio. | -| `.sf-frame--4-3` | PUBLIC | layout | Frame | Frame variant locked to a 4:3 aspect ratio. | -| `.sf-frame--cinema` | PUBLIC | layout | Frame | Frame variant locked to a cinematic 21:9 aspect ratio. | -| `.sf-frame--golden` | PUBLIC | layout | Frame | Frame variant locked to the golden ratio (1.618:1). | -| `.sf-frame--portrait` | PUBLIC | layout | Frame | Frame variant locked to a portrait 2:3 aspect ratio. | -| `.sf-frame--square` | PUBLIC | layout | Frame | Frame variant locked to a square 1:1 aspect ratio. | -| `.sf-frame--video` | PUBLIC | layout | Frame | Frame variant locked to the standard 16:9 video aspect ratio. | -| `.sf-full-bleed` | PUBLIC | layout | Content grid (breakout pattern) | Forces an element to span the full viewport width, breaking out of any centered container. Use for full-bleed images and section backgrounds. | -| `.sf-gap` | PUBLIC | layout | Gap | Injects the default --sf-gap into an existing flex or grid container without imposing display:flex itself. Use when the parent is already a flex or grid. | -| `.sf-gap--2xl` | PUBLIC | layout | Gap | Gap injection variant with 2xl gap value. | -| `.sf-gap--l` | PUBLIC | layout | Gap | Gap injection variant with large (l) gap value. | -| `.sf-gap--m` | PUBLIC | layout | Gap | Gap injection variant with medium (m) gap value. | -| `.sf-gap--s` | PUBLIC | layout | Gap | Gap injection variant with small (s) gap value. | -| `.sf-gap--xl` | PUBLIC | layout | Gap | Gap injection variant with xl gap value. | -| `.sf-gap--xs` | PUBLIC | layout | Gap | Gap injection variant with xs gap value. | -| `.sf-grid` | PUBLIC | layout | .sf-card | Auto-fill CSS grid. Columns are sized with RAM pattern (Repeat, Auto-fill, Minmax) and wrap automatically. Default column min-width is --sf-grid-min-col. | -| `.sf-grid--2xl` | PUBLIC | layout | Grid (auto) | Grid variant with a 2xl minimum column width. | -| `.sf-grid--dense` | PUBLIC | layout | Grid (auto) | Grid variant with grid-auto-flow: dense, allowing the grid to fill holes created by span modifiers. | -| `.sf-grid--fit` | PUBLIC | layout | Grid (auto) | Grid variant that switches from auto-fill to auto-fit, collapsing empty columns. | -| `.sf-grid--l` | PUBLIC | layout | Grid (auto) | Grid variant with a large (l) minimum column width. | -| `.sf-grid--m` | PUBLIC | layout | Grid (auto) | Grid variant with a medium (m) minimum column width. | -| `.sf-grid--s` | PUBLIC | layout | Grid (auto) | Grid variant with a small (s) minimum column width. | -| `.sf-grid--xl` | PUBLIC | layout | Grid (auto) | Grid variant with an xl minimum column width. | -| `.sf-grid--xs` | PUBLIC | layout | Grid (auto) | Grid variant with an xs minimum column width. | -| `.sf-grid-cols-1` | PUBLIC | layout | Single-column grid | Single-column layout (forces all children to one column). | -| `.sf-grid-cols-1-2` | PUBLIC | layout | Ratio grids | Two-column ratio grid: first child takes 1fr, second takes 2fr. Container-query responsive. | -| `.sf-grid-cols-1-3` | PUBLIC | layout | Ratio grids | Two-column ratio grid: first child takes 1fr, second takes 3fr. Container-query responsive. | -| `.sf-grid-cols-2` | PUBLIC | layout | Fixed column grids (container-query responsive) | Responsive 2-column fixed grid. Uses container queries to collapse to one column on narrow containers. | -| `.sf-grid-cols-2-1` | PUBLIC | layout | Ratio grids | Two-column ratio grid: first child takes 2fr, second takes 1fr. Container-query responsive. | -| `.sf-grid-cols-3` | PUBLIC | layout | Fixed column grids (container-query responsive) | Responsive 3-column fixed grid. Collapses progressively on narrow containers. | -| `.sf-grid-cols-3-1` | PUBLIC | layout | Ratio grids | Two-column ratio grid: first child takes 3fr, second takes 1fr. Container-query responsive. | -| `.sf-grid-cols-4` | PUBLIC | layout | Fixed column grids (container-query responsive) | Responsive 4-column fixed grid. Collapses progressively on narrow containers. | -| `.sf-grid-cols-6` | PUBLIC | layout | Fixed column grids (container-query responsive) | Responsive 6-column fixed grid. Collapses progressively on narrow containers. | -| `.sf-grid-flex` | PUBLIC | layout | .sf-card | Flexbox alternative to .sf-grid for item counts that don't divide evenly: leftover last-row items stretch to fill the row by default, or stay fixed-width and centered with --center. | -| `.sf-grid-flex--2xl` | PUBLIC | layout | Grid (flex) | Grid-flex variant with a 2xl minimum item width. | -| `.sf-grid-flex--center` | PUBLIC | layout | Grid (flex) | Grid-flex variant that keeps last-row leftover items fixed-width and centered instead of stretching. | -| `.sf-grid-flex--l` | PUBLIC | layout | Grid (flex) | Grid-flex variant with a large (l) minimum item width. | -| `.sf-grid-flex--m` | PUBLIC | layout | Grid (flex) | Grid-flex variant with a medium (m) minimum item width. | -| `.sf-grid-flex--s` | PUBLIC | layout | Grid (flex) | Grid-flex variant with a small (s) minimum item width. | -| `.sf-grid-flex--xl` | PUBLIC | layout | Grid (flex) | Grid-flex variant with an xl minimum item width. | -| `.sf-grid-flex--xs` | PUBLIC | layout | Grid (flex) | Grid-flex variant with an xs minimum item width. | +| `.sf-frame` | PUBLIC | layout | — | Aspect-ratio container for media (images, video, maps). Children fill and cover the fixed-ratio box. Default ratio is 16:9. | +| `.sf-frame--3-2` | PUBLIC | layout | — | Frame variant locked to a 3:2 aspect ratio. | +| `.sf-frame--4-3` | PUBLIC | layout | — | Frame variant locked to a 4:3 aspect ratio. | +| `.sf-frame--cinema` | PUBLIC | layout | — | Frame variant locked to a cinematic 21:9 aspect ratio. | +| `.sf-frame--golden` | PUBLIC | layout | — | Frame variant locked to the golden ratio (1.618:1). | +| `.sf-frame--portrait` | PUBLIC | layout | — | Frame variant locked to a portrait 2:3 aspect ratio. | +| `.sf-frame--square` | PUBLIC | layout | — | Frame variant locked to a square 1:1 aspect ratio. | +| `.sf-frame--video` | PUBLIC | layout | — | Frame variant locked to the standard 16:9 video aspect ratio. | +| `.sf-full-bleed` | PUBLIC | layout | — | Forces an element to span the full viewport width, breaking out of any centered container. Use for full-bleed images and section backgrounds. | +| `.sf-gap` | PUBLIC | layout | — | Injects the default --sf-gap into an existing flex or grid container without imposing display:flex itself. Use when the parent is already a flex or grid. | +| `.sf-gap--2xl` | PUBLIC | layout | — | Gap injection variant with 2xl gap value. | +| `.sf-gap--l` | PUBLIC | layout | — | Gap injection variant with large (l) gap value. | +| `.sf-gap--m` | PUBLIC | layout | — | Gap injection variant with medium (m) gap value. | +| `.sf-gap--s` | PUBLIC | layout | — | Gap injection variant with small (s) gap value. | +| `.sf-gap--xl` | PUBLIC | layout | — | Gap injection variant with xl gap value. | +| `.sf-gap--xs` | PUBLIC | layout | — | Gap injection variant with xs gap value. | +| `.sf-grid` | PUBLIC | layout | — | Auto-fill CSS grid. Columns are sized with RAM pattern (Repeat, Auto-fill, Minmax) and wrap automatically. Default column min-width is --sf-grid-min-col. | +| `.sf-grid--2xl` | PUBLIC | layout | — | Grid variant with a 2xl minimum column width. | +| `.sf-grid--dense` | PUBLIC | layout | — | Grid variant with grid-auto-flow: dense, allowing the grid to fill holes created by span modifiers. | +| `.sf-grid--fit` | PUBLIC | layout | — | Grid variant that switches from auto-fill to auto-fit, collapsing empty columns. | +| `.sf-grid--l` | PUBLIC | layout | — | Grid variant with a large (l) minimum column width. | +| `.sf-grid--m` | PUBLIC | layout | — | Grid variant with a medium (m) minimum column width. | +| `.sf-grid--s` | PUBLIC | layout | — | Grid variant with a small (s) minimum column width. | +| `.sf-grid--xl` | PUBLIC | layout | — | Grid variant with an xl minimum column width. | +| `.sf-grid--xs` | PUBLIC | layout | — | Grid variant with an xs minimum column width. | +| `.sf-grid-cols-1` | PUBLIC | layout | — | Single-column layout (forces all children to one column). | +| `.sf-grid-cols-1-2` | PUBLIC | layout | — | Two-column ratio grid: first child takes 1fr, second takes 2fr. Container-query responsive. | +| `.sf-grid-cols-1-3` | PUBLIC | layout | — | Two-column ratio grid: first child takes 1fr, second takes 3fr. Container-query responsive. | +| `.sf-grid-cols-2` | PUBLIC | layout | — | Responsive 2-column fixed grid. Uses container queries to collapse to one column on narrow containers. | +| `.sf-grid-cols-2-1` | PUBLIC | layout | — | Two-column ratio grid: first child takes 2fr, second takes 1fr. Container-query responsive. | +| `.sf-grid-cols-3` | PUBLIC | layout | — | Responsive 3-column fixed grid. Collapses progressively on narrow containers. | +| `.sf-grid-cols-3-1` | PUBLIC | layout | — | Two-column ratio grid: first child takes 3fr, second takes 1fr. Container-query responsive. | +| `.sf-grid-cols-4` | PUBLIC | layout | — | Responsive 4-column fixed grid. Collapses progressively on narrow containers. | +| `.sf-grid-cols-6` | PUBLIC | layout | — | Responsive 6-column fixed grid. Collapses progressively on narrow containers. | +| `.sf-grid-flex` | PUBLIC | layout | — | Flexbox alternative to .sf-grid for item counts that don't divide evenly: leftover last-row items stretch to fill the row by default, or stay fixed-width and centered with --center. | +| `.sf-grid-flex--2xl` | PUBLIC | layout | — | Grid-flex variant with a 2xl minimum item width. | +| `.sf-grid-flex--center` | PUBLIC | layout | — | Grid-flex variant that keeps last-row leftover items fixed-width and centered instead of stretching. | +| `.sf-grid-flex--l` | PUBLIC | layout | — | Grid-flex variant with a large (l) minimum item width. | +| `.sf-grid-flex--m` | PUBLIC | layout | — | Grid-flex variant with a medium (m) minimum item width. | +| `.sf-grid-flex--s` | PUBLIC | layout | — | Grid-flex variant with a small (s) minimum item width. | +| `.sf-grid-flex--xl` | PUBLIC | layout | — | Grid-flex variant with an xl minimum item width. | +| `.sf-grid-flex--xs` | PUBLIC | layout | — | Grid-flex variant with an xs minimum item width. | | `.sf-header--l` | PUBLIC | layout | — | Header block padding at the l step (--sf-space-l). | | `.sf-header--m` | PUBLIC | layout | — | Header block padding at the m step (--sf-space-m). | | `.sf-header--s` | PUBLIC | layout | — | Header block padding at the s step (--sf-space-s). | | `.sf-header--xl` | PUBLIC | layout | — | Header block padding at the xl step (--sf-space-xl). | | `.sf-header--xs` | PUBLIC | layout | — | Header block padding at the xs step (--sf-space-xs). | -| `.sf-icon` | PUBLIC | layout | Icon | Inline icon sizing primitive. Sets width and height to --sf-icon-m via em-based tokens so the icon scales with the surrounding text. | -| `.sf-icon--2xl` | PUBLIC | layout | Icon | Icon variant sized to --sf-icon-2xl (extra-extra-large). | -| `.sf-icon--boxed` | PUBLIC | layout | Icon | Icon variant with a square bordered box background. Useful for standalone icon buttons and feature icons. | -| `.sf-icon--l` | PUBLIC | layout | Icon | Icon variant sized to --sf-icon-l (large). | -| `.sf-icon--m` | PUBLIC | layout | Icon | Icon variant sized to --sf-icon-m (medium, same as base sf-icon). | -| `.sf-icon--s` | PUBLIC | layout | Icon | Icon variant sized to --sf-icon-s (small). | -| `.sf-icon--xl` | PUBLIC | layout | Icon | Icon variant sized to --sf-icon-xl (extra-large). | -| `.sf-icon--xs` | PUBLIC | layout | Icon | Icon variant sized to --sf-icon-xs (extra-small). | -| `.sf-imposter` | PUBLIC | layout | Imposter | Absolutely positions an element at the center of its nearest positioned ancestor. Use for overlays, badges, and floating labels. | -| `.sf-imposter--contain` | PUBLIC | layout | Imposter | Imposter variant that clamps the element within the bounds of its parent using overflow:hidden on the parent. | -| `.sf-imposter--fixed` | PUBLIC | layout | Imposter | Imposter variant that uses position:fixed instead of absolute. Use for viewport-level overlays and modals. | +| `.sf-icon` | PUBLIC | layout | — | Inline icon sizing primitive. Sets width and height to --sf-icon-m via em-based tokens so the icon scales with the surrounding text. | +| `.sf-icon--2xl` | PUBLIC | layout | — | Icon variant sized to --sf-icon-2xl (extra-extra-large). | +| `.sf-icon--boxed` | PUBLIC | layout | — | Icon variant with a square bordered box background. Useful for standalone icon buttons and feature icons. | +| `.sf-icon--l` | PUBLIC | layout | — | Icon variant sized to --sf-icon-l (large). | +| `.sf-icon--m` | PUBLIC | layout | — | Icon variant sized to --sf-icon-m (medium, same as base sf-icon). | +| `.sf-icon--s` | PUBLIC | layout | — | Icon variant sized to --sf-icon-s (small). | +| `.sf-icon--xl` | PUBLIC | layout | — | Icon variant sized to --sf-icon-xl (extra-large). | +| `.sf-icon--xs` | PUBLIC | layout | — | Icon variant sized to --sf-icon-xs (extra-small). | +| `.sf-imposter` | PUBLIC | layout | — | Absolutely positions an element at the center of its nearest positioned ancestor. Use for overlays, badges, and floating labels. | +| `.sf-imposter--contain` | PUBLIC | layout | — | Imposter variant that clamps the element within the bounds of its parent using overflow:hidden on the parent. | +| `.sf-imposter--fixed` | PUBLIC | layout | — | Imposter variant that uses position:fixed instead of absolute. Use for viewport-level overlays and modals. | | `.sf-overlay` | PUBLIC | layout | — | Overlay layout helper — absolutely fills its positioned parent (`position: absolute; inset: 0`) for overlays, backdrops, and media scrims. | -| `.sf-pancake` | PUBLIC | layout | Pancake (sticky footer) | Three-row layout (header, main, footer) where main takes all remaining vertical space via flex-grow. The footer always sticks to the bottom on tall viewports. | -| `.sf-reel` | PUBLIC | layout | .sf-card | Horizontally scrollable row of fixed-height items with snap scrolling. Children don't shrink below their intrinsic width, creating a card carousel effect. | -| `.sf-section` | PUBLIC | layout | Section | Full-width page section with vertical padding (--sf-section-pad-default). Use to create visually distinct content bands. | -| `.sf-section--2xl` | PUBLIC | layout | Section | Section variant with 2xl vertical padding. | -| `.sf-section--collapse` | PUBLIC | layout | Collapse modifier | Section variant that removes vertical padding (zero-padding section for adjacent same-color blocks). | -| `.sf-section--guttered` | PUBLIC | layout | Section | Adds horizontal page gutters directly to a section — use when you want to skip a separate .sf-container wrapper (gutterless layout inside section). Neutralises container gutter to prevent double padding. | -| `.sf-section--l` | PUBLIC | layout | Section | Section variant with large (l) vertical padding. | -| `.sf-section--m` | PUBLIC | layout | Section | Section variant with medium (m) vertical padding. | -| `.sf-section--s` | PUBLIC | layout | Section | Section variant with small (s) vertical padding. | -| `.sf-section--xl` | PUBLIC | layout | Section | Section variant with xl vertical padding. | -| `.sf-section--xs` | PUBLIC | layout | Section | Section variant with xs vertical padding. | -| `.sf-section-group` | PUBLIC | layout | Section | Groups adjacent sf-section elements so their combined padding collapses correctly at the top and bottom edges. | -| `.sf-sidebar` | PUBLIC | layout | .sf-card | Two-column sidebar layout: first child is the sidebar, second child is main content. The sidebar collapses below the breakpoint (--sf-sidebar-min-width). Default sidebar on the left. | -| `.sf-sidebar--narrow` | PUBLIC | layout | Sidebar | Sidebar variant with a narrower sidebar column. | -| `.sf-sidebar--right` | PUBLIC | layout | Sidebar | Sidebar variant with the sidebar on the right (second child becomes the sidebar). | -| `.sf-sidebar--wide` | PUBLIC | layout | Sidebar | Sidebar variant with a wider sidebar column. | -| `.sf-stack` | PUBLIC | layout | .sf-card | Flex column with even vertical spacing between children (--sf-stack-gap). Stacking context for vertical rhythm. | -| `.sf-stack--2xl` | PUBLIC | layout | Stack | Stack variant with 2xl gap between children. | -| `.sf-stack--center` | PUBLIC | layout | Stack | Stack variant that centers children on the cross axis. | -| `.sf-stack--end` | PUBLIC | layout | Stack | Stack variant that aligns children to the cross-axis end (right in LTR). | -| `.sf-stack--l` | PUBLIC | layout | Stack | Stack variant with large (l) gap between children. | -| `.sf-stack--m` | PUBLIC | layout | Stack | Stack variant with medium (m) gap between children. | -| `.sf-stack--s` | PUBLIC | layout | Stack | Stack variant with small (s) gap between children. | -| `.sf-stack--stretch` | PUBLIC | layout | Stack | Stack variant that stretches children to fill the full available width. | -| `.sf-stack--xl` | PUBLIC | layout | Stack | Stack variant with xl gap between children. | -| `.sf-stack--xs` | PUBLIC | layout | Stack | Stack variant with xs gap between children. | -| `.sf-subgrid` | PUBLIC | layout | Subgrid | Passes the parent grid columns through to children via subgrid. Place on a grid item that should align its own children to the outer grid columns. | -| `.sf-subgrid-rows` | PUBLIC | layout | Subgrid | Passes the parent grid rows through to children via subgrid. Place on a grid item that should align its own children to the outer grid rows. | -| `.sf-switcher` | PUBLIC | layout | .sf-card | Flex layout that switches from a horizontal row to a vertical column when the container is narrower than --sf-switcher-threshold. | -| `.sf-switcher--no-wrap` | PUBLIC | layout | Switcher | Switcher variant that stays horizontal and never wraps (single-line regardless of container width). | -| `.sf-switcher--vertical` | PUBLIC | layout | Switcher | Switcher variant that starts in the vertical (stacked) direction on all sizes. | +| `.sf-pancake` | PUBLIC | layout | — | Three-row layout (header, main, footer) where main takes all remaining vertical space via flex-grow. The footer always sticks to the bottom on tall viewports. | +| `.sf-reel` | PUBLIC | layout | — | Horizontally scrollable row of fixed-height items with snap scrolling. Children don't shrink below their intrinsic width, creating a card carousel effect. | +| `.sf-section` | PUBLIC | layout | — | Full-width page section with vertical padding (--sf-section-pad-default). Use to create visually distinct content bands. | +| `.sf-section--2xl` | PUBLIC | layout | — | Section variant with 2xl vertical padding. | +| `.sf-section--collapse` | PUBLIC | layout | — | Section variant that removes vertical padding (zero-padding section for adjacent same-color blocks). | +| `.sf-section--guttered` | PUBLIC | layout | — | Adds horizontal page gutters directly to a section — use when you want to skip a separate .sf-container wrapper (gutterless layout inside section). Neutralises container gutter to prevent double padding. | +| `.sf-section--l` | PUBLIC | layout | — | Section variant with large (l) vertical padding. | +| `.sf-section--m` | PUBLIC | layout | — | Section variant with medium (m) vertical padding. | +| `.sf-section--s` | PUBLIC | layout | — | Section variant with small (s) vertical padding. | +| `.sf-section--xl` | PUBLIC | layout | — | Section variant with xl vertical padding. | +| `.sf-section--xs` | PUBLIC | layout | — | Section variant with xs vertical padding. | +| `.sf-section-group` | PUBLIC | layout | — | Groups adjacent sf-section elements so their combined padding collapses correctly at the top and bottom edges. | +| `.sf-sidebar` | PUBLIC | layout | — | Two-column sidebar layout: first child is the sidebar, second child is main content. The sidebar collapses below the breakpoint (--sf-sidebar-min-width). Default sidebar on the left. | +| `.sf-sidebar--narrow` | PUBLIC | layout | — | Sidebar variant with a narrower sidebar column. | +| `.sf-sidebar--right` | PUBLIC | layout | — | Sidebar variant with the sidebar on the right (second child becomes the sidebar). | +| `.sf-sidebar--wide` | PUBLIC | layout | — | Sidebar variant with a wider sidebar column. | +| `.sf-stack` | PUBLIC | layout | — | Flex column with even vertical spacing between children (--sf-stack-gap). Stacking context for vertical rhythm. | +| `.sf-stack--2xl` | PUBLIC | layout | — | Stack variant with 2xl gap between children. | +| `.sf-stack--center` | PUBLIC | layout | — | Stack variant that centers children on the cross axis. | +| `.sf-stack--end` | PUBLIC | layout | — | Stack variant that aligns children to the cross-axis end (right in LTR). | +| `.sf-stack--l` | PUBLIC | layout | — | Stack variant with large (l) gap between children. | +| `.sf-stack--m` | PUBLIC | layout | — | Stack variant with medium (m) gap between children. | +| `.sf-stack--s` | PUBLIC | layout | — | Stack variant with small (s) gap between children. | +| `.sf-stack--stretch` | PUBLIC | layout | — | Stack variant that stretches children to fill the full available width. | +| `.sf-stack--xl` | PUBLIC | layout | — | Stack variant with xl gap between children. | +| `.sf-stack--xs` | PUBLIC | layout | — | Stack variant with xs gap between children. | +| `.sf-subgrid` | PUBLIC | layout | — | Passes the parent grid columns through to children via subgrid. Place on a grid item that should align its own children to the outer grid columns. | +| `.sf-subgrid-rows` | PUBLIC | layout | — | Passes the parent grid rows through to children via subgrid. Place on a grid item that should align its own children to the outer grid rows. | +| `.sf-switcher` | PUBLIC | layout | — | Flex layout that switches from a horizontal row to a vertical column when the container is narrower than --sf-switcher-threshold. | +| `.sf-switcher--no-wrap` | PUBLIC | layout | — | Switcher variant that stays horizontal and never wraps (single-line regardless of container width). | +| `.sf-switcher--vertical` | PUBLIC | layout | — | Switcher variant that starts in the vertical (stacked) direction on all sizes. | -### Macro classes (58) +### Macro classes (53) | Class | Tier | Kind | Group | Description | |---|---|---|---|---| -| `.sf-aspect` | PUBLIC | macro | Aspect | Sets aspect-ratio from a --sf-aspect-ratio scoped token. Override the token inline to get any ratio without a new class. | -| `.sf-content-auto` | PUBLIC | macro | Content visibility | Sets content-visibility: auto on the element. The browser skips rendering off-screen content, improving LCP for long pages. | -| `.sf-corner-scoop` | PUBLIC | macro | — | Concave "scooped" corner cut with a radial-gradient mask; defaults to the top-right corner (--sf-corner-scoop-at). Add a placement modifier to move it. | -| `.sf-corner-scoop--bottom-left` | PUBLIC | macro | — | Places the concave corner scoop at the bottom-left corner. | -| `.sf-corner-scoop--bottom-right` | PUBLIC | macro | — | Places the concave corner scoop at the bottom-right corner. | -| `.sf-corner-scoop--top-left` | PUBLIC | macro | — | Places the concave corner scoop at the top-left corner. | -| `.sf-corner-scoop--top-right` | PUBLIC | macro | — | Places the concave corner scoop at the top-right corner. | +| `.sf-aspect` | PUBLIC | macro | — | Sets aspect-ratio from a --sf-aspect-ratio scoped token. Override the token inline to get any ratio without a new class. | +| `.sf-content-auto` | PUBLIC | macro | — | Sets content-visibility: auto on the element. The browser skips rendering off-screen content, improving LCP for long pages. | | `.sf-drop-shadow-l` | PUBLIC | macro | — | Large filter drop-shadow — follows the element's alpha shape (--sf-drop-shadow-l). | | `.sf-drop-shadow-m` | PUBLIC | macro | — | Medium filter drop-shadow — follows the element's alpha shape (--sf-drop-shadow-m). | | `.sf-drop-shadow-s` | PUBLIC | macro | — | Small filter drop-shadow — follows the element's alpha shape (--sf-drop-shadow-s). | | `.sf-drop-shadow-xl` | PUBLIC | macro | — | Extra-large filter drop-shadow — follows the element's alpha shape (--sf-drop-shadow-xl). | | `.sf-drop-shadow-xs` | PUBLIC | macro | — | Extra-small filter drop-shadow — follows the element's alpha shape (--sf-drop-shadow-xs). | -| `.sf-equal-height` | PUBLIC | macro | Equal height | Forces all flex children to equal height (align-items: stretch). Use on a flex row to make cards in a grid share the tallest card's height. | -| `.sf-flow` | PUBLIC | macro | Flow | Applies --sf-flow-space as margin-block-start to all direct children except the first. Establishes consistent vertical rhythm in prose-like containers. | -| `.sf-line-clamp-2` | PUBLIC | macro | Truncate / line-clamp | Clamps text to 2 lines with an ellipsis. Applies -webkit-line-clamp: 2. | -| `.sf-line-clamp-3` | PUBLIC | macro | Truncate / line-clamp | Clamps text to 3 lines with an ellipsis. Applies -webkit-line-clamp: 3. | -| `.sf-line-clamp-N` | PUBLIC | macro | Truncate / line-clamp | Clamps text to a custom N lines. Set --sf-line-clamp on the element to control the number of visible lines. | -| `.sf-link--reverse` | PUBLIC | macro | Link variants | Link color modifier: reverses the default link color to work on dark/inverted backgrounds. Sets color to --sf-color-text--inverse. | -| `.sf-link--subtle` | PUBLIC | macro | Link variants | Link color modifier: renders the link in the body text color instead of the default action color. Underline still indicates the link on hover. | -| `.sf-link-external` | PUBLIC | macro | External link indication | Automatically appends an external-link icon (via ::after content) to indicate the link opens in a new tab or goes to an external domain. | -| `.sf-no-tap-highlight` | PUBLIC | macro | No tap highlight | Removes the mobile tap highlight color (-webkit-tap-highlight-color: transparent). Use on interactive elements with a custom active state. | -| `.sf-not-prose` | PUBLIC | macro | Prose | Opt-out of sf-prose typography styles within a prose block. Apply to an element that should keep default browser or component styles. | -| `.sf-overflow-fade` | PUBLIC | macro | Overflow fade | Adds a gradient fade at the inline-end of an overflowing element to hint at hidden content. Use inside sf-reel or any scroll container. | +| `.sf-equal-height` | PUBLIC | macro | — | Forces all flex children to equal height (align-items: stretch). Use on a flex row to make cards in a grid share the tallest card's height. | +| `.sf-flow` | PUBLIC | macro | — | Applies --sf-flow-space as margin-block-start to all direct children except the first. Establishes consistent vertical rhythm in prose-like containers. | +| `.sf-line-clamp-2` | PUBLIC | macro | — | Clamps text to 2 lines with an ellipsis. Applies -webkit-line-clamp: 2. | +| `.sf-line-clamp-3` | PUBLIC | macro | — | Clamps text to 3 lines with an ellipsis. Applies -webkit-line-clamp: 3. | +| `.sf-line-clamp-N` | PUBLIC | macro | — | Clamps text to a custom N lines. Set --sf-line-clamp on the element to control the number of visible lines. | +| `.sf-link--reverse` | PUBLIC | macro | — | Link color modifier: reverses the default link color to work on dark/inverted backgrounds. Sets color to --sf-color-text--inverse. | +| `.sf-link--subtle` | PUBLIC | macro | — | Link color modifier: renders the link in the body text color instead of the default action color. Underline still indicates the link on hover. | +| `.sf-link-external` | PUBLIC | macro | — | Automatically appends an external-link icon (via ::after content) to indicate the link opens in a new tab or goes to an external domain. | +| `.sf-no-tap-highlight` | PUBLIC | macro | — | Removes the mobile tap highlight color (-webkit-tap-highlight-color: transparent). Use on interactive elements with a custom active state. | +| `.sf-not-prose` | PUBLIC | macro | — | Opt-out of sf-prose typography styles within a prose block. Apply to an element that should keep default browser or component styles. | +| `.sf-overflow-fade` | PUBLIC | macro | — | Adds a gradient fade at the inline-end of an overflowing element to hint at hidden content. Use inside sf-reel or any scroll container. | | `.sf-overflow-fade--block` | PUBLIC | macro | — | Overflow fade variant: fades both the top and bottom edges simultaneously (block axis). | | `.sf-overflow-fade--bottom` | PUBLIC | macro | — | Overflow fade variant: fades the bottom (block-end) edge. | | `.sf-overflow-fade--inline` | PUBLIC | macro | — | Overflow fade variant: fades both the left and right edges simultaneously (inline axis). | @@ -1041,65 +1034,65 @@ and a short description. The machine-readable companion (with all columns) is | `.sf-overlap--start` | PUBLIC | macro | — | Overlap recipe — pulls the element toward the inline-start (negative inline-start margin) to overlap horizontally. | | `.sf-overlap-host` | PUBLIC | macro | — | Card-container recipe — the receiving side of an overlap: an isolated stacking context with block-start padding compensation so in-flow content clears an element intruding from above. The padding knob defaults to the pull knob so one override tunes both. | | `.sf-prose` | PUBLIC | macro | LIST MARKER COLOUR (.sf-marker--*) | Opinionated typographic defaults for long-form content: heading hierarchy, paragraph spacing, blockquote, code, and list styling. Override with sf-not-prose. | -| `.sf-scrim` | PUBLIC | macro | Scrim | Overlay container with a gradient darkening scrim behind text placed on an image or colored background. | -| `.sf-scrim__content` | PUBLIC | macro | Scrim | Content area inside an sf-scrim. Positioned above the gradient overlay layer. | -| `.sf-scrim--bottom` | PUBLIC | macro | Scrim | Scrim variant with the gradient emanating from the bottom edge (bottom-to-top fade). | -| `.sf-scrim--full` | PUBLIC | macro | Scrim | Scrim variant that covers the entire surface with a uniform translucent overlay. | -| `.sf-scrim--top` | PUBLIC | macro | Scrim | Scrim variant with the gradient emanating from the top edge (top-to-bottom fade). | -| `.sf-scroll-shadow` | PUBLIC | macro | Scroll shadow | Adds inset box-shadows at the top and bottom of a scrollable container to indicate hidden overflow above or below. | -| `.sf-scroll-snap` | PUBLIC | macro | Scroll snap | Enables CSS scroll-snap-type: x mandatory on a horizontal scroll container. Children should have scroll-snap-align. | -| `.sf-surface` | PUBLIC | macro | Surface | Generic semantic surface: applies --sf-surface-color as the background and automatically sets a contrasting text color. Tone variants (--primary, --action, etc.) activate preset palettes. | -| `.sf-surface--action` | PUBLIC | macro | Surface | Surface variant using the action color palette (button/CTA primary color). | -| `.sf-surface--danger` | PUBLIC | macro | Surface | Surface variant using the danger status palette. | -| `.sf-surface--info` | PUBLIC | macro | Surface | Surface variant using the info status palette. | -| `.sf-surface--inverse` | PUBLIC | macro | Surface | Surface variant that inverts light/dark, creating an always-dark surface in light mode and always-light in dark mode. | -| `.sf-surface--neutral` | PUBLIC | macro | Surface | Surface variant using the neutral palette (muted/gray). | -| `.sf-surface--primary` | PUBLIC | macro | Surface | Surface variant using the primary brand color palette. | -| `.sf-surface--secondary` | PUBLIC | macro | Surface | Surface variant using the secondary brand color palette. | -| `.sf-surface--success` | PUBLIC | macro | Surface | Surface variant using the success status palette. | -| `.sf-surface--tertiary` | PUBLIC | macro | Surface | Surface variant using the tertiary brand color palette. | -| `.sf-surface--warning` | PUBLIC | macro | Surface | Surface variant using the warning status palette. | +| `.sf-scrim` | PUBLIC | macro | — | Overlay container with a gradient darkening scrim behind text placed on an image or colored background. | +| `.sf-scrim__content` | PUBLIC | macro | — | Content area inside an sf-scrim. Positioned above the gradient overlay layer. | +| `.sf-scrim--bottom` | PUBLIC | macro | — | Scrim variant with the gradient emanating from the bottom edge (bottom-to-top fade). | +| `.sf-scrim--full` | PUBLIC | macro | — | Scrim variant that covers the entire surface with a uniform translucent overlay. | +| `.sf-scrim--top` | PUBLIC | macro | — | Scrim variant with the gradient emanating from the top edge (top-to-bottom fade). | +| `.sf-scroll-shadow` | PUBLIC | macro | — | Adds inset box-shadows at the top and bottom of a scrollable container to indicate hidden overflow above or below. | +| `.sf-scroll-snap` | PUBLIC | macro | — | Enables CSS scroll-snap-type: x mandatory on a horizontal scroll container. Children should have scroll-snap-align. | +| `.sf-surface` | PUBLIC | macro | — | Generic semantic surface: applies --sf-surface-color as the background and automatically sets a contrasting text color. Tone variants (--primary, --action, etc.) activate preset palettes. | +| `.sf-surface--action` | PUBLIC | macro | — | Surface variant using the action color palette (button/CTA primary color). | +| `.sf-surface--danger` | PUBLIC | macro | — | Surface variant using the danger status palette. | +| `.sf-surface--info` | PUBLIC | macro | — | Surface variant using the info status palette. | +| `.sf-surface--inverse` | PUBLIC | macro | — | Surface variant that inverts light/dark, creating an always-dark surface in light mode and always-light in dark mode. | +| `.sf-surface--neutral` | PUBLIC | macro | — | Surface variant using the neutral palette (muted/gray). | +| `.sf-surface--primary` | PUBLIC | macro | — | Surface variant using the primary brand color palette. | +| `.sf-surface--secondary` | PUBLIC | macro | — | Surface variant using the secondary brand color palette. | +| `.sf-surface--success` | PUBLIC | macro | — | Surface variant using the success status palette. | +| `.sf-surface--tertiary` | PUBLIC | macro | — | Surface variant using the tertiary brand color palette. | +| `.sf-surface--warning` | PUBLIC | macro | — | Surface variant using the warning status palette. | | `.sf-surface-bg` | PUBLIC | macro | — | Named background surface preset (issue #523). Composes the --sf-surface-bg-* token set (see tokens.macros.css) into one reusable, named background: base colour + image/gradient/pattern, sizing, an optional overlay layered above the image, and an optional animation. Inert until… | -| `.sf-tabular-nums` | PUBLIC | macro | Tabular figures | Forces tabular (monospaced) number rendering. Use on price tables, counters, and anywhere numbers need to align vertically across rows. | -| `.sf-text-gradient` | PUBLIC | macro | Text gradient | Applies a brand gradient to inline text. Sets the background to the gradient, clips it to the text, and makes the text color transparent. | -| `.sf-text-protect` | PUBLIC | macro | Text protect | Wraps text in a translucent dark gradient overlay to ensure legibility when placed over a light or variable background image. | -| `.sf-truncate` | PUBLIC | macro | Truncate / line-clamp | Single-line text overflow with ellipsis. Equivalent to the classic text-overflow: ellipsis trio (white-space nowrap, overflow hidden, text-overflow ellipsis). | +| `.sf-tabular-nums` | PUBLIC | macro | — | Forces tabular (monospaced) number rendering. Use on price tables, counters, and anywhere numbers need to align vertically across rows. | +| `.sf-text-gradient` | PUBLIC | macro | — | Applies a brand gradient to inline text. Sets the background to the gradient, clips it to the text, and makes the text color transparent. | +| `.sf-text-protect` | PUBLIC | macro | — | Wraps text in a translucent dark gradient overlay to ensure legibility when placed over a light or variable background image. | +| `.sf-truncate` | PUBLIC | macro | — | Single-line text overflow with ellipsis. Equivalent to the classic text-overflow: ellipsis trio (white-space nowrap, overflow hidden, text-overflow ellipsis). | ### Motion / animation (22) | Class | Tier | Kind | Group | Description | |---|---|---|---|---| -| `.sf-color-pulse` | PUBLIC | motion | @property color animation | Applies a gentle color-pulse animation to draw attention to a dynamic value change (e.g. a counter updating). Scoped to users who have not requested reduced motion. | -| `.sf-entrance--fade` | PUBLIC | motion | Scroll-driven entrances | Scroll-driven entrance: element fades in as it enters the viewport. Animation tied to scroll progress via animation-timeline. | -| `.sf-entrance--fade-down` | PUBLIC | motion | Scroll-driven entrances | Scroll-driven entrance: element fades in while moving downward into position. | -| `.sf-entrance--fade-left` | PUBLIC | motion | Scroll-driven entrances | Scroll-driven entrance: element fades in while moving from the right toward the left. | -| `.sf-entrance--fade-right` | PUBLIC | motion | Scroll-driven entrances | Scroll-driven entrance: element fades in while moving from the left toward the right. | -| `.sf-entrance--fade-up` | PUBLIC | motion | Scroll-driven entrances | Scroll-driven entrance: element fades in while moving upward into position. | -| `.sf-entrance--scale-up` | PUBLIC | motion | Scroll-driven entrances | Scroll-driven entrance: element fades in while scaling up from a slightly smaller size. | +| `.sf-color-pulse` | PUBLIC | motion | — | Applies a gentle color-pulse animation to draw attention to a dynamic value change (e.g. a counter updating). Scoped to users who have not requested reduced motion. | +| `.sf-entrance--fade` | PUBLIC | motion | — | Scroll-driven entrance: element fades in as it enters the viewport. Animation tied to scroll progress via animation-timeline. | +| `.sf-entrance--fade-down` | PUBLIC | motion | — | Scroll-driven entrance: element fades in while moving downward into position. | +| `.sf-entrance--fade-left` | PUBLIC | motion | — | Scroll-driven entrance: element fades in while moving from the right toward the left. | +| `.sf-entrance--fade-right` | PUBLIC | motion | — | Scroll-driven entrance: element fades in while moving from the left toward the right. | +| `.sf-entrance--fade-up` | PUBLIC | motion | — | Scroll-driven entrance: element fades in while moving upward into position. | +| `.sf-entrance--scale-up` | PUBLIC | motion | — | Scroll-driven entrance: element fades in while scaling up from a slightly smaller size. | | `.sf-exit--fade` | PUBLIC | motion | — | Scroll-out exit animation: fades the element out in place (sf-fade-out). | | `.sf-exit--fade-down` | PUBLIC | motion | — | Scroll-out exit animation: fades out while sliding downward (sf-slide-out-down). | | `.sf-exit--fade-left` | PUBLIC | motion | — | Scroll-out exit animation: fades out while sliding to the left (sf-slide-out-left). | | `.sf-exit--fade-right` | PUBLIC | motion | — | Scroll-out exit animation: fades out while sliding to the right (sf-slide-out-right). | | `.sf-exit--fade-up` | PUBLIC | motion | — | Scroll-out exit animation: fades out while sliding upward (sf-slide-out-up). | | `.sf-exit--scale-down` | PUBLIC | motion | — | Scroll-out exit animation: fades out while shrinking (sf-scale-down). | -| `.sf-fade-in` | PUBLIC | motion | Animation presets | One-shot fade-in animation (opacity 0 → 1). Scoped to no-preference so it stops automatically for reduced-motion users. | -| `.sf-fade-out` | PUBLIC | motion | Animation presets | One-shot fade-out animation (opacity 1 → 0). Scoped to no-preference. | -| `.sf-scale-down` | PUBLIC | motion | Animation presets | One-shot scale-down animation (element shrinks from full size). Scoped to no-preference. | -| `.sf-scale-up` | PUBLIC | motion | Animation presets | One-shot scale-up animation (element grows from smaller size). Scoped to no-preference. | -| `.sf-slide-in-down` | PUBLIC | motion | Animation presets | One-shot slide-in-from-above animation. Scoped to no-preference. | -| `.sf-slide-in-left` | PUBLIC | motion | Animation presets | One-shot slide-in-from-right animation (slides to the left). Scoped to no-preference. | -| `.sf-slide-in-right` | PUBLIC | motion | Animation presets | One-shot slide-in-from-left animation (slides to the right). Scoped to no-preference. | -| `.sf-slide-in-up` | PUBLIC | motion | Animation presets | One-shot slide-in-from-below animation. Scoped to no-preference. | +| `.sf-fade-in` | PUBLIC | motion | — | One-shot fade-in animation (opacity 0 → 1). Scoped to no-preference so it stops automatically for reduced-motion users. | +| `.sf-fade-out` | PUBLIC | motion | — | One-shot fade-out animation (opacity 1 → 0). Scoped to no-preference. | +| `.sf-scale-down` | PUBLIC | motion | — | One-shot scale-down animation (element shrinks from full size). Scoped to no-preference. | +| `.sf-scale-up` | PUBLIC | motion | — | One-shot scale-up animation (element grows from smaller size). Scoped to no-preference. | +| `.sf-slide-in-down` | PUBLIC | motion | — | One-shot slide-in-from-above animation. Scoped to no-preference. | +| `.sf-slide-in-left` | PUBLIC | motion | — | One-shot slide-in-from-right animation (slides to the left). Scoped to no-preference. | +| `.sf-slide-in-right` | PUBLIC | motion | — | One-shot slide-in-from-left animation (slides to the right). Scoped to no-preference. | +| `.sf-slide-in-up` | PUBLIC | motion | — | One-shot slide-in-from-below animation. Scoped to no-preference. | | `.sf-stagger` | PUBLIC | motion | — | Stagger — choreography, not the animation itself. Put .sf-stagger on a PARENT; every direct child gets an incrementing animation-delay so a time-based entrance (.sf-fade-in / .sf-slide-in-*) plays in sequence. Children WITHOUT an animation just carry an inert delay (no-op), so… | ### Print (4) | Class | Tier | Kind | Group | Description | |---|---|---|---|---| -| `.no-print` | PUBLIC | print | Print visibility utilities | Hides the element in @media print. Use on sidebars, navigation bars, and decorative elements that should not appear on paper. | -| `.print-color-exact` | PUBLIC | print | Opt-in colour treatment | Forces exact color rendering in print (print-color-adjust: exact). Use on charts and colored badges that must preserve their fill colors in print. | -| `.print-no-color` | PUBLIC | print | Opt-in colour treatment | Strips color information in print (print-color-adjust: economy). Defers to the printer's ink-saving mode for backgrounds and non-critical color fills. | -| `.print-only` | PUBLIC | print | Print visibility utilities | Hides the element on screen (display: none) but shows it in @media print. Use for print-only headers, footers, and supplementary content not needed on screen. | +| `.no-print` | PUBLIC | print | — | Hides the element in @media print. Use on sidebars, navigation bars, and decorative elements that should not appear on paper. | +| `.print-color-exact` | PUBLIC | print | — | Forces exact color rendering in print (print-color-adjust: exact). Use on charts and colored badges that must preserve their fill colors in print. | +| `.print-no-color` | PUBLIC | print | — | Strips color information in print (print-color-adjust: economy). Defers to the printer's ink-saving mode for backgrounds and non-critical color fills. | +| `.print-only` | PUBLIC | print | — | Hides the element on screen (display: none) but shows it in @media print. Use for print-only headers, footers, and supplementary content not needed on screen. | ### State classes (28) @@ -1140,7 +1133,7 @@ and a short description. The machine-readable companion (with all columns) is |---|---|---|---|---| | `.sf-theme-dark` | PUBLIC | theme | — | Forces dark colour scheme on the element and its subtree (class alias of [data-theme="dark"]). | | `.sf-theme-light` | PUBLIC | theme | — | Forces light colour scheme on the element and its subtree (class alias of [data-theme="light"]). | -| `.sf-theme-transition` | PUBLIC | theme | OPT-IN THEME CROSS-FADE | Opt-in animated light/dark theme crossfade. Apply to (or a subtree) so color tokens transition smoothly when [data-theme] changes. Duration controlled by --sf-theme-transition-duration. | +| `.sf-theme-transition` | PUBLIC | theme | — | Opt-in animated light/dark theme crossfade. Apply to (or a subtree) so color tokens transition smoothly when [data-theme] changes. Duration controlled by --sf-theme-transition-duration. | ### Utilities (31) diff --git a/docs/classes.md b/docs/classes.md index b91f3a19..ca662734 100644 --- a/docs/classes.md +++ b/docs/classes.md @@ -3,7 +3,7 @@ > **Generated** from source by `scripts/gen-class-reference.js` — > run `npm run docs:classes` to refresh. Do not edit by hand. -**294 .sf-classes, 28 .sf-is-classes.** Every `.sf-*` layout/macro class and `.sf-is-*` state class. +**289 .sf-classes, 28 .sf-is-classes.** Every `.sf-*` layout/macro class and `.sf-is-*` state class. See [architecture.md](architecture.md) for layer order and naming conventions. ## Layout primitives (`core/layout.css`) @@ -160,17 +160,12 @@ See [architecture.md](architecture.md) for layer order and naming conventions. ## Macro classes (`core/macros.css`) -58 classes. +53 classes. | Class | |---| | `.sf-aspect` | | `.sf-content-auto` | -| `.sf-corner-scoop` | -| `.sf-corner-scoop--bottom-left` | -| `.sf-corner-scoop--bottom-right` | -| `.sf-corner-scoop--top-left` | -| `.sf-corner-scoop--top-right` | | `.sf-drop-shadow-l` | | `.sf-drop-shadow-m` | | `.sf-drop-shadow-s` | diff --git a/docs/demo.html b/docs/demo.html index 39ab5557..c268b0df 100644 --- a/docs/demo.html +++ b/docs/demo.html @@ -2802,15 +2802,6 @@

.sf-bg-layer — -

.sf-corner-scoop — concave corner

-

A corner that curves away from the box, revealing the page behind it, via a mask-image radial gradient.

-
-
-
-
-
-
-

.sf-overlap / .sf-overlap-host — intentional overlap recipe

One element pulled up over the next, which reserves clearance for it automatically.

@@ -2822,9 +2813,9 @@

.sf-overlap / Directional variants: .sf-overlap--down (pulls into the next element), .sf-overlap--start / .sf-overlap--end (pulls into the inline edge).

Macros in action — a composed profile card

-

Both recipes together on one realistic card: a notched banner (.sf-corner-scoop) with an avatar overlapping into the body below (.sf-overlap / .sf-overlap-host).

+

A realistic card built from the overlap recipe: a banner with an avatar overlapping into the body below (.sf-overlap / .sf-overlap-host).

-
+
Jamie Chen diff --git a/docs/llm-guide.md b/docs/llm-guide.md index 296a7409..eaf5b3c0 100644 --- a/docs/llm-guide.md +++ b/docs/llm-guide.md @@ -903,10 +903,6 @@ Each primitive has its own knobs. Override locally (`style="--sf-cluster-gap: 2r --sf-surface-bg-attachment: scroll --sf-surface-bg-animation: none /* optional animation shorthand */ -/* Concave corner (.sf-corner-scoop) */ ---sf-corner-scoop-size: var(--sf-radius-2xl) ---sf-corner-scoop-at: 100% 0 - /* Overlap recipe (.sf-overlap / .sf-overlap-host) */ --sf-overlap-pull: var(--sf-space-xl) ``` diff --git a/docs/macros.md b/docs/macros.md index de99c0a5..9394d549 100644 --- a/docs/macros.md +++ b/docs/macros.md @@ -733,44 +733,6 @@ Lives in `core/motion.css`, layer `slashed.motion`. --- -## `.sf-corner-scoop` - -A corner that curves **away** from the box (a concave "notch"), instead -of the normal convex `border-radius`. Reveals whatever sits behind the -element at that corner via a `mask-image` radial gradient. Default -corner is top-right. - -```html -
- Panel with a corner that curves away -
-``` - -Variants: - -| Class | Effect | -|---|---| -| `.sf-corner-scoop--top-left` | scoop at the top-left corner | -| `.sf-corner-scoop--top-right` | scoop at the top-right corner | -| `.sf-corner-scoop--bottom-left` | scoop at the bottom-left corner | -| `.sf-corner-scoop--bottom-right` | scoop at the bottom-right corner | - -Tokens: - -| Token | Default | What it controls | -|---|---|---| -| `--sf-corner-scoop-size` | `var(--sf-radius-2xl)` | radius of the concave cut | -| `--sf-corner-scoop-at` | `100% 0` | position of the cut (set by the variants above) | - -**Limitations:** masking cuts the element's entire paint at that -corner — `box-shadow`/`border` don't survive the cut there (put shadows -on a wrapper element if needed). Only one scoop per element — a second -mask layer would fill the first hole rather than adding a second cut. -Doesn't compose with other mask-based macros (`.sf-overflow-fade`, -`.sf-scroll-shadow`) on the same element — the last `mask-image` wins. - ---- - ## `.sf-overlap` and `.sf-overlap-host` A recipe for one element intentionally overlapping the element before diff --git a/docs/migration.md b/docs/migration.md index 0888e764..9594d29d 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -187,6 +187,33 @@ families read distinctly: `sf-bento--row-compact` and `sf-bento--tall` → `sf-bento--row-tall` on any `.sf-bento` container element. +### `.sf-corner-scoop` removed (breaking) + +The `.sf-corner-scoop` macro — a concave "notch" cut into one corner via a +`mask-image` radial gradient — and its four placement modifiers +(`--top-left` / `--top-right` / `--bottom-left` / `--bottom-right`) plus the +`--sf-corner-scoop-size` / `--sf-corner-scoop-at` knobs have been removed. +It was judged too niche for the public API relative to its cost: the single +absolute `--sf-corner-scoop-size` needed per-element tuning to read well +across control-sized and hero-sized boxes (no size tier), and the mask clipped +`box-shadow` / `border` at the cut and could not compose with the other +mask-based macros (`.sf-overflow-fade`, `.sf-scroll-shadow`) on the same +element. + +**What changed for you:** elements that carried `.sf-corner-scoop*` now render +with square (un-masked) corners. To keep the concave corner, apply the mask +directly on the element — the same declaration the macro used to emit: + +```html +
+ Panel with a top-right corner that curves away +
+``` + +Change the `at ` (e.g. `0 0` = top-left, `100% 100%` = bottom-right) +to move the cut, and the two radii to resize it. + ## SLASHED 0.7.6 → 0.7.7 ### `.sf-btn` axes reworked (breaking) diff --git a/docs/registry.json b/docs/registry.json index ed5c75b5..63394ad6 100644 --- a/docs/registry.json +++ b/docs/registry.json @@ -19,8 +19,8 @@ "optional/utilities.css" ], "counts": { - "tokens": 756, - "sf_classes": 294, + "tokens": 754, + "sf_classes": 289, "is_classes": 28 } }, @@ -395,8 +395,6 @@ "--sf-content-width", "--sf-contrast-bias", "--sf-contrast-threshold", - "--sf-corner-scoop-at", - "--sf-corner-scoop-size", "--sf-cover-min-height", "--sf-cover-padding", "--sf-current-font-weight", @@ -851,11 +849,6 @@ "sf-container--wide", "sf-content-auto", "sf-content-grid", - "sf-corner-scoop", - "sf-corner-scoop--bottom-left", - "sf-corner-scoop--bottom-right", - "sf-corner-scoop--top-left", - "sf-corner-scoop--top-right", "sf-cover", "sf-cover--max", "sf-cover--min", diff --git a/docs/roadmap.md b/docs/roadmap.md index b55cc3bf..e6178eca 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -161,12 +161,16 @@ non-additive changes; the v0.6.x series focuses on the components layer.* (`search_tokens`, `get_class_info`, etc.) for AI coding assistants, as a live alternative to the static `llms.txt`. Tracked in [#473](https://github.com/codeslash-dev/SLASHED/issues/473). -- ~~**Concave/inverted corner utility**~~ ✓ **Done** — shipped as - `.sf-corner-scoop` (mask-based radial-gradient cut) with 4 single-corner - position variants (`--top-left`/`--top-right`/`--bottom-left`/`--bottom-right`). - A two-corner "pair variant" (for U-shaped cutouts) was explored and - dropped — WebKit's `mask-composite` implementation has a bug with no - viable workaround found. +- ~~**Concave/inverted corner utility**~~ ✗ **Not planned** — shipped as + `.sf-corner-scoop` (mask-based radial-gradient cut with 4 single-corner + position variants) and then removed before 1.0. Judged too niche for the + public API relative to its cost: a single absolute `--sf-corner-scoop-size` + needs per-element tuning to read well across button-sized and hero-sized + boxes, and the mask clips `box-shadow`/`border` and can't compose with the + other mask-based macros (`.sf-overflow-fade`, `.sf-scroll-shadow`) on the + same element. (A two-corner "pair variant" for U-shaped cutouts had already + been dropped earlier — WebKit's `mask-composite` has a bug with no viable + workaround.) Tracked in [#484](https://github.com/codeslash-dev/SLASHED/issues/484). - ~~**Boxed-section layout primitive**~~ ✗ **Not planned** — a `.sf-boxed` section macro was implemented and then dropped after review; judged too @@ -183,12 +187,12 @@ non-additive changes; the v0.6.x series focuses on the components layer.* color/gradient overlay with correct automatic stacking; documented in `docs/macros.md` instead of adding a redundant class. Tracked in [#489](https://github.com/codeslash-dev/SLASHED/issues/489). -- **Concrete recipe macros** — **partially done**. Shipped: `.sf-corner-scoop` - (border-radius-style recipe, tracked as #484 above) and `.sf-overlap`/ - `.sf-overlap-host` (overlap + card-container recipes). A `.sf-corners` - logical-corner recipe (with a `--leaf` asymmetric variant) was also built - and then cut — judged too niche for the public API relative to its - long-term maintenance cost. +- **Concrete recipe macros** — **partially done**. Shipped: `.sf-overlap`/ + `.sf-overlap-host` (overlap + card-container recipes). Two corner-recipe + macros were built and then cut before 1.0 — `.sf-corner-scoop` (mask-based + concave cut, tracked as #484 above) and a `.sf-corners` logical-corner + recipe (with a `--leaf` asymmetric variant) — both judged too niche for the + public API relative to their long-term maintenance cost. Tracked in [#490](https://github.com/codeslash-dev/SLASHED/issues/490). - **Container-relative fluid scale** — the `--sf-text-*`/`--sf-space-*` fluid scales are `100vw`-driven and don't respond to `@container` width the way diff --git a/docs/test-coverage-6-token-reference.html b/docs/test-coverage-6-token-reference.html index 97fd56ee..515f2b8b 100644 --- a/docs/test-coverage-6-token-reference.html +++ b/docs/test-coverage-6-token-reference.html @@ -109,7 +109,7 @@

Full token reference — tokens

else apply(next); }); - var TOKENS = ["--sf-alternate-gap","--sf-alternate-inner-gap","--sf-animation-blink","--sf-animation-color-pulse","--sf-animation-fade-in","--sf-animation-fade-out","--sf-animation-float","--sf-animation-ping","--sf-animation-scale-down","--sf-animation-scale-up","--sf-animation-shimmer","--sf-animation-slide-in-down","--sf-animation-slide-in-left","--sf-animation-slide-in-right","--sf-animation-slide-in-up","--sf-animation-slide-out-down","--sf-animation-slide-out-left","--sf-animation-slide-out-right","--sf-animation-slide-out-up","--sf-animation-spin","--sf-aspect","--sf-bento-cols-default","--sf-bento-gap","--sf-bento-row-compact","--sf-bento-row-default","--sf-bento-row-tall","--sf-bg-layer-fit","--sf-bg-layer-inset","--sf-bg-layer-position","--sf-bg-layer-radius","--sf-bg-layer-z","--sf-blur","--sf-body-color","--sf-body-em-style","--sf-body-font-family","--sf-body-font-size","--sf-body-font-weight","--sf-body-line-height","--sf-body-strong-weight","--sf-body-text-wrap","--sf-border","--sf-border-scale","--sf-border-strong","--sf-border-style","--sf-border-subtle","--sf-border-width-1","--sf-border-width-2","--sf-border-width-3","--sf-border-width-4","--sf-border-width-hairline","--sf-box-border-color","--sf-box-border-width","--sf-box-padding","--sf-breakout-width","--sf-btn-border-width","--sf-btn-font-scale","--sf-btn-font-size","--sf-btn-font-weight","--sf-btn-gap","--sf-btn-l-font-size","--sf-btn-l-min-height","--sf-btn-l-padding-block","--sf-btn-l-padding-inline","--sf-btn-m-font-size","--sf-btn-m-min-height","--sf-btn-m-padding-block","--sf-btn-m-padding-inline","--sf-btn-min-height","--sf-btn-padding-block","--sf-btn-padding-inline","--sf-btn-radius","--sf-btn-s-font-size","--sf-btn-s-min-height","--sf-btn-s-padding-block","--sf-btn-s-padding-inline","--sf-btn-xl-font-size","--sf-btn-xl-min-height","--sf-btn-xl-padding-block","--sf-btn-xl-padding-inline","--sf-btn-xs-font-size","--sf-btn-xs-min-height","--sf-btn-xs-padding-block","--sf-btn-xs-padding-inline","--sf-card-avatar-size","--sf-card-bg","--sf-card-border-color","--sf-card-border-width","--sf-card-gap","--sf-card-heading-size","--sf-card-media-radius","--sf-card-media-ratio","--sf-card-padding","--sf-card-radius","--sf-card-radius-outer","--sf-card-shadow","--sf-card-shadow--elevated","--sf-card-shadow--hover","--sf-caret-color","--sf-center-gutter","--sf-center-max","--sf-cluster-align","--sf-cluster-gap","--sf-cluster-justify","--sf-code-font-size","--sf-color-action","--sf-color-action--active","--sf-color-action--hover","--sf-color-action-100","--sf-color-action-200","--sf-color-action-300","--sf-color-action-400","--sf-color-action-50","--sf-color-action-500","--sf-color-action-600","--sf-color-action-700","--sf-color-action-800","--sf-color-action-900","--sf-color-action-950","--sf-color-action-a10","--sf-color-action-a30","--sf-color-action-a5","--sf-color-action-a50","--sf-color-action-a80","--sf-color-action-darker","--sf-color-action-lighter","--sf-color-action-muted","--sf-color-action-source-dark","--sf-color-action-source-light","--sf-color-action-subtle","--sf-color-action-superdark","--sf-color-action-superlight","--sf-color-action-tint","--sf-color-action-xdark","--sf-color-action-xlight","--sf-color-base","--sf-color-base--active","--sf-color-base--hover","--sf-color-base-100","--sf-color-base-200","--sf-color-base-300","--sf-color-base-400","--sf-color-base-50","--sf-color-base-500","--sf-color-base-600","--sf-color-base-700","--sf-color-base-800","--sf-color-base-900","--sf-color-base-950","--sf-color-base-a10","--sf-color-base-a30","--sf-color-base-a5","--sf-color-base-a50","--sf-color-base-a80","--sf-color-base-muted","--sf-color-base-source-dark","--sf-color-base-source-light","--sf-color-base-subtle","--sf-color-base-tint","--sf-color-bg","--sf-color-bg--active","--sf-color-bg--disabled","--sf-color-bg--focus","--sf-color-bg--hover","--sf-color-bg--selected","--sf-color-black","--sf-color-border","--sf-color-border--disabled","--sf-color-border--focus","--sf-color-border--strong","--sf-color-border--subtle","--sf-color-border--translucent","--sf-color-code-bg","--sf-color-code-text","--sf-color-danger","--sf-color-danger-muted","--sf-color-danger-source-dark","--sf-color-danger-source-light","--sf-color-danger-strong","--sf-color-danger-subtle","--sf-color-danger-tint","--sf-color-dim","--sf-color-heading","--sf-color-info","--sf-color-info-muted","--sf-color-info-source-dark","--sf-color-info-source-light","--sf-color-info-strong","--sf-color-info-subtle","--sf-color-info-tint","--sf-color-inset","--sf-color-inverse","--sf-color-link","--sf-color-link--active","--sf-color-link--disabled","--sf-color-link--hover","--sf-color-link--underline","--sf-color-link--visited","--sf-color-mark-bg","--sf-color-mark-text","--sf-color-neutral","--sf-color-neutral--active","--sf-color-neutral--hover","--sf-color-neutral-100","--sf-color-neutral-200","--sf-color-neutral-300","--sf-color-neutral-400","--sf-color-neutral-50","--sf-color-neutral-500","--sf-color-neutral-600","--sf-color-neutral-700","--sf-color-neutral-800","--sf-color-neutral-900","--sf-color-neutral-950","--sf-color-neutral-a10","--sf-color-neutral-a30","--sf-color-neutral-a5","--sf-color-neutral-a50","--sf-color-neutral-a80","--sf-color-neutral-darker","--sf-color-neutral-lighter","--sf-color-neutral-muted","--sf-color-neutral-source-dark","--sf-color-neutral-source-light","--sf-color-neutral-subtle","--sf-color-neutral-superdark","--sf-color-neutral-superlight","--sf-color-neutral-tint","--sf-color-neutral-xdark","--sf-color-neutral-xlight","--sf-color-overlay","--sf-color-primary","--sf-color-primary--active","--sf-color-primary--hover","--sf-color-primary-100","--sf-color-primary-200","--sf-color-primary-300","--sf-color-primary-400","--sf-color-primary-50","--sf-color-primary-500","--sf-color-primary-600","--sf-color-primary-700","--sf-color-primary-800","--sf-color-primary-900","--sf-color-primary-950","--sf-color-primary-a10","--sf-color-primary-a30","--sf-color-primary-a5","--sf-color-primary-a50","--sf-color-primary-a80","--sf-color-primary-darker","--sf-color-primary-lighter","--sf-color-primary-muted","--sf-color-primary-source-dark","--sf-color-primary-source-light","--sf-color-primary-subtle","--sf-color-primary-superdark","--sf-color-primary-superlight","--sf-color-primary-tint","--sf-color-primary-xdark","--sf-color-primary-xlight","--sf-color-raised","--sf-color-scheme","--sf-color-secondary","--sf-color-secondary--active","--sf-color-secondary--hover","--sf-color-secondary-100","--sf-color-secondary-200","--sf-color-secondary-300","--sf-color-secondary-400","--sf-color-secondary-50","--sf-color-secondary-500","--sf-color-secondary-600","--sf-color-secondary-700","--sf-color-secondary-800","--sf-color-secondary-900","--sf-color-secondary-950","--sf-color-secondary-a10","--sf-color-secondary-a30","--sf-color-secondary-a5","--sf-color-secondary-a50","--sf-color-secondary-a80","--sf-color-secondary-darker","--sf-color-secondary-lighter","--sf-color-secondary-muted","--sf-color-secondary-source-dark","--sf-color-secondary-source-light","--sf-color-secondary-subtle","--sf-color-secondary-superdark","--sf-color-secondary-superlight","--sf-color-secondary-tint","--sf-color-secondary-xdark","--sf-color-secondary-xlight","--sf-color-selection-bg","--sf-color-selection-bg--alt","--sf-color-selection-text","--sf-color-selection-text--alt","--sf-color-success","--sf-color-success-muted","--sf-color-success-source-dark","--sf-color-success-source-light","--sf-color-success-strong","--sf-color-success-subtle","--sf-color-success-tint","--sf-color-surface","--sf-color-tertiary","--sf-color-tertiary--active","--sf-color-tertiary--hover","--sf-color-tertiary-100","--sf-color-tertiary-200","--sf-color-tertiary-300","--sf-color-tertiary-400","--sf-color-tertiary-50","--sf-color-tertiary-500","--sf-color-tertiary-600","--sf-color-tertiary-700","--sf-color-tertiary-800","--sf-color-tertiary-900","--sf-color-tertiary-950","--sf-color-tertiary-a10","--sf-color-tertiary-a30","--sf-color-tertiary-a5","--sf-color-tertiary-a50","--sf-color-tertiary-a80","--sf-color-tertiary-darker","--sf-color-tertiary-lighter","--sf-color-tertiary-muted","--sf-color-tertiary-source-dark","--sf-color-tertiary-source-light","--sf-color-tertiary-subtle","--sf-color-tertiary-superdark","--sf-color-tertiary-superlight","--sf-color-tertiary-tint","--sf-color-tertiary-xdark","--sf-color-tertiary-xlight","--sf-color-text","--sf-color-text--disabled","--sf-color-text--inverse","--sf-color-text--muted","--sf-color-text--on-action","--sf-color-text--on-base","--sf-color-text--on-danger","--sf-color-text--on-info","--sf-color-text--on-inverse","--sf-color-text--on-neutral","--sf-color-text--on-primary","--sf-color-text--on-secondary","--sf-color-text--on-success","--sf-color-text--on-tertiary","--sf-color-text--on-warning","--sf-color-text--placeholder","--sf-color-text--secondary","--sf-color-warning","--sf-color-warning-muted","--sf-color-warning-source-dark","--sf-color-warning-source-light","--sf-color-warning-strong","--sf-color-warning-subtle","--sf-color-warning-tint","--sf-color-white","--sf-component-pad","--sf-container-default","--sf-container-full","--sf-container-narrow","--sf-container-prose","--sf-container-wide","--sf-content-gap","--sf-content-intrinsic-size","--sf-content-width","--sf-contrast-bias","--sf-contrast-threshold","--sf-corner-scoop-at","--sf-corner-scoop-size","--sf-cover-min-height","--sf-cover-padding","--sf-current-font-weight","--sf-density","--sf-display-l-line-height","--sf-display-m-line-height","--sf-display-s-line-height","--sf-divider-color","--sf-divider-gap","--sf-divider-style","--sf-divider-width","--sf-drop-shadow-l","--sf-drop-shadow-m","--sf-drop-shadow-s","--sf-drop-shadow-xl","--sf-drop-shadow-xs","--sf-duration-fast","--sf-duration-instant","--sf-duration-none","--sf-duration-normal","--sf-duration-slow","--sf-duration-slower","--sf-ease-bounce","--sf-ease-elastic","--sf-ease-in","--sf-ease-in-out","--sf-ease-linear","--sf-ease-out","--sf-ease-overshoot","--sf-ease-spring","--sf-equal-gap","--sf-equal-min-col","--sf-equal-rule-color","--sf-equal-rule-style","--sf-equal-rule-width","--sf-field-block","--sf-field-padding-block","--sf-field-padding-inline","--sf-field-radius","--sf-field-required-marker","--sf-flow-space","--sf-fluid-max-vw","--sf-fluid-min-vw","--sf-fluid-width","--sf-focus-ring-color","--sf-focus-ring-offset","--sf-focus-ring-shadow","--sf-focus-ring-style","--sf-focus-ring-width","--sf-font-body","--sf-font-display","--sf-font-features","--sf-font-geometric","--sf-font-heading","--sf-font-humanist","--sf-font-mono","--sf-font-numeric","--sf-font-slab","--sf-font-variation","--sf-font-weight-body","--sf-font-weight-bold","--sf-font-weight-display","--sf-font-weight-heading","--sf-font-weight-interactive","--sf-font-weight-light","--sf-font-weight-medium","--sf-font-weight-normal","--sf-font-weight-semibold","--sf-font-weight-strong","--sf-frame-ratio","--sf-gap","--sf-gradient-action","--sf-gradient-brand","--sf-gradient-fade--b","--sf-gradient-fade--l","--sf-gradient-fade--r","--sf-gradient-fade--t","--sf-gradient-primary","--sf-gradient-secondary","--sf-gradient-surface","--sf-gradient-tertiary","--sf-grid-gap","--sf-grid-min","--sf-grid-min-2xl","--sf-grid-min-l","--sf-grid-min-m","--sf-grid-min-s","--sf-grid-min-xl","--sf-grid-min-xs","--sf-gutter","--sf-h1-font-weight","--sf-h1-letter-spacing","--sf-h1-line-height","--sf-h1-max-width","--sf-h1-size","--sf-h2-font-weight","--sf-h2-letter-spacing","--sf-h2-line-height","--sf-h2-max-width","--sf-h2-size","--sf-h3-font-weight","--sf-h3-letter-spacing","--sf-h3-line-height","--sf-h3-max-width","--sf-h3-size","--sf-h4-font-weight","--sf-h4-letter-spacing","--sf-h4-line-height","--sf-h4-max-width","--sf-h4-size","--sf-h5-font-weight","--sf-h5-letter-spacing","--sf-h5-line-height","--sf-h5-max-width","--sf-h5-size","--sf-h6-font-weight","--sf-h6-letter-spacing","--sf-h6-line-height","--sf-h6-max-width","--sf-h6-size","--sf-header-height","--sf-header-height-desktop","--sf-header-height-mobile","--sf-heading-color","--sf-heading-font-family","--sf-heading-text-wrap","--sf-hover-grow-scale","--sf-hover-lift","--sf-hover-shrink-scale","--sf-hover-slide","--sf-icon-2xl","--sf-icon-box-bg","--sf-icon-box-border","--sf-icon-box-pad","--sf-icon-box-radius","--sf-icon-l","--sf-icon-m","--sf-icon-s","--sf-icon-xl","--sf-icon-xs","--sf-imposter-margin","--sf-is-active","--sf-is-current","--sf-is-dark","--sf-is-open","--sf-is-pressed","--sf-leading-normal","--sf-leading-relaxed","--sf-leading-snug","--sf-leading-taper","--sf-leading-tight","--sf-line-clamp","--sf-link-external-label","--sf-link-external-marker","--sf-link-underline-offset","--sf-link-underline-thickness","--sf-lumlocker","--sf-mask-scrim-end","--sf-mask-scrim-start","--sf-media-radius","--sf-motion-scale","--sf-object-fit","--sf-object-position","--sf-opacity-disabled","--sf-opacity-muted","--sf-optical-sizing","--sf-overlap-pull","--sf-palette-mix-100","--sf-palette-mix-200","--sf-palette-mix-300","--sf-palette-mix-400","--sf-palette-mix-50","--sf-palette-mix-600","--sf-palette-mix-700","--sf-palette-mix-800","--sf-palette-mix-900","--sf-palette-mix-950","--sf-print-base-size","--sf-print-page-margin","--sf-print-page-size","--sf-prose-block-margin","--sf-prose-blockquote-border","--sf-prose-blockquote-padding","--sf-prose-figcaption-size","--sf-prose-figure-margin","--sf-prose-heading-gap","--sf-prose-hr-margin","--sf-prose-list-gap","--sf-prose-marker-color","--sf-prose-media-margin","--sf-prose-media-radius","--sf-prose-nested-list-gap","--sf-prose-paragraph","--sf-prose-table-pad","--sf-radius-2xl","--sf-radius-2xs","--sf-radius-3xl","--sf-radius-4xl","--sf-radius-full","--sf-radius-l","--sf-radius-m","--sf-radius-none","--sf-radius-outer","--sf-radius-pill","--sf-radius-s","--sf-radius-scale","--sf-radius-xl","--sf-radius-xs","--sf-ratio-3-2","--sf-ratio-4-3","--sf-ratio-cinema","--sf-ratio-golden","--sf-ratio-portrait","--sf-ratio-square","--sf-ratio-video","--sf-reel-gap","--sf-reel-height","--sf-reel-item-width","--sf-safe-bottom","--sf-safe-left","--sf-safe-right","--sf-safe-top","--sf-scrim-color","--sf-scrim-direction","--sf-scrim-gradient","--sf-scrim-text-shadow","--sf-scroll-shadow-size","--sf-scroll-timeline-range-end","--sf-scroll-timeline-range-exit-end","--sf-scroll-timeline-range-exit-start","--sf-scroll-timeline-range-start","--sf-scrollbar-thumb","--sf-scrollbar-track","--sf-section-pad","--sf-section-pad--2xl","--sf-section-pad--l","--sf-section-pad--m","--sf-section-pad--s","--sf-section-pad--xl","--sf-section-pad--xs","--sf-section-scale","--sf-shadow-2xl","--sf-shadow-color","--sf-shadow-glow","--sf-shadow-glow-color","--sf-shadow-inner","--sf-shadow-l","--sf-shadow-lightness","--sf-shadow-m","--sf-shadow-none","--sf-shadow-s","--sf-shadow-strength","--sf-shadow-xl","--sf-shadow-xs","--sf-sidebar-gap","--sf-sidebar-min-width","--sf-sidebar-width","--sf-size-l","--sf-size-m","--sf-size-s","--sf-size-xl","--sf-size-xs","--sf-space-2xl","--sf-space-2xs","--sf-space-3xl","--sf-space-4xl","--sf-space-base-max","--sf-space-base-min","--sf-space-l","--sf-space-m","--sf-space-none","--sf-space-px","--sf-space-ratio-max","--sf-space-ratio-min","--sf-space-s","--sf-space-scale","--sf-space-xl","--sf-space-xs","--sf-stack-gap","--sf-stagger-step","--sf-state-pending-opacity","--sf-sticky-offset","--sf-sticky-offset-desktop","--sf-sticky-offset-mobile","--sf-surface-bg-animation","--sf-surface-bg-attachment","--sf-surface-bg-color","--sf-surface-bg-image","--sf-surface-bg-overlay","--sf-surface-bg-position","--sf-surface-bg-repeat","--sf-surface-bg-size","--sf-surface-color","--sf-switcher-gap","--sf-switcher-threshold","--sf-text-2xl","--sf-text-2xl-font-weight","--sf-text-2xl-letter-spacing","--sf-text-2xl-line-height","--sf-text-2xl-max-width","--sf-text-2xs","--sf-text-2xs-font-weight","--sf-text-2xs-letter-spacing","--sf-text-2xs-line-height","--sf-text-2xs-max-width","--sf-text-3xl","--sf-text-3xl-font-weight","--sf-text-3xl-letter-spacing","--sf-text-3xl-line-height","--sf-text-3xl-max-width","--sf-text-4xl","--sf-text-4xl-font-weight","--sf-text-4xl-letter-spacing","--sf-text-4xl-line-height","--sf-text-4xl-max-width","--sf-text-base-max","--sf-text-base-min","--sf-text-display-base-max","--sf-text-display-base-min","--sf-text-display-l","--sf-text-display-m","--sf-text-display-s","--sf-text-display-scale","--sf-text-l","--sf-text-l-font-weight","--sf-text-l-letter-spacing","--sf-text-l-line-height","--sf-text-l-max-width","--sf-text-m","--sf-text-m-font-weight","--sf-text-m-letter-spacing","--sf-text-m-line-height","--sf-text-m-max-width","--sf-text-ratio-max","--sf-text-ratio-min","--sf-text-s","--sf-text-s-font-weight","--sf-text-s-letter-spacing","--sf-text-s-line-height","--sf-text-s-max-width","--sf-text-scale","--sf-text-shadow-l","--sf-text-shadow-m","--sf-text-shadow-none","--sf-text-shadow-s","--sf-text-shadow-xl","--sf-text-shadow-xs","--sf-text-xl","--sf-text-xl-font-weight","--sf-text-xl-letter-spacing","--sf-text-xl-line-height","--sf-text-xl-max-width","--sf-text-xs","--sf-text-xs-font-weight","--sf-text-xs-letter-spacing","--sf-text-xs-line-height","--sf-text-xs-max-width","--sf-theme-transition-duration","--sf-touch-target","--sf-tracking-normal","--sf-tracking-tight","--sf-tracking-wide","--sf-tracking-wider","--sf-tracking-widest","--sf-transition-colors","--sf-transition-enter","--sf-transition-exit","--sf-transition-fast","--sf-transition-form-field","--sf-transition-opacity","--sf-transition-overlay","--sf-transition-shadow","--sf-transition-slow","--sf-transition-transform","--sf-z-base","--sf-z-below","--sf-z-dropdown","--sf-z-fixed","--sf-z-modal","--sf-z-overlay","--sf-z-raised","--sf-z-sticky","--sf-z-toast","--sf-z-tooltip"]; + var TOKENS = ["--sf-alternate-gap","--sf-alternate-inner-gap","--sf-animation-blink","--sf-animation-color-pulse","--sf-animation-fade-in","--sf-animation-fade-out","--sf-animation-float","--sf-animation-ping","--sf-animation-scale-down","--sf-animation-scale-up","--sf-animation-shimmer","--sf-animation-slide-in-down","--sf-animation-slide-in-left","--sf-animation-slide-in-right","--sf-animation-slide-in-up","--sf-animation-slide-out-down","--sf-animation-slide-out-left","--sf-animation-slide-out-right","--sf-animation-slide-out-up","--sf-animation-spin","--sf-aspect","--sf-bento-cols-default","--sf-bento-gap","--sf-bento-row-compact","--sf-bento-row-default","--sf-bento-row-tall","--sf-bg-layer-fit","--sf-bg-layer-inset","--sf-bg-layer-position","--sf-bg-layer-radius","--sf-bg-layer-z","--sf-blur","--sf-body-color","--sf-body-em-style","--sf-body-font-family","--sf-body-font-size","--sf-body-font-weight","--sf-body-line-height","--sf-body-strong-weight","--sf-body-text-wrap","--sf-border","--sf-border-scale","--sf-border-strong","--sf-border-style","--sf-border-subtle","--sf-border-width-1","--sf-border-width-2","--sf-border-width-3","--sf-border-width-4","--sf-border-width-hairline","--sf-box-border-color","--sf-box-border-width","--sf-box-padding","--sf-breakout-width","--sf-btn-border-width","--sf-btn-font-scale","--sf-btn-font-size","--sf-btn-font-weight","--sf-btn-gap","--sf-btn-l-font-size","--sf-btn-l-min-height","--sf-btn-l-padding-block","--sf-btn-l-padding-inline","--sf-btn-m-font-size","--sf-btn-m-min-height","--sf-btn-m-padding-block","--sf-btn-m-padding-inline","--sf-btn-min-height","--sf-btn-padding-block","--sf-btn-padding-inline","--sf-btn-radius","--sf-btn-s-font-size","--sf-btn-s-min-height","--sf-btn-s-padding-block","--sf-btn-s-padding-inline","--sf-btn-xl-font-size","--sf-btn-xl-min-height","--sf-btn-xl-padding-block","--sf-btn-xl-padding-inline","--sf-btn-xs-font-size","--sf-btn-xs-min-height","--sf-btn-xs-padding-block","--sf-btn-xs-padding-inline","--sf-card-avatar-size","--sf-card-bg","--sf-card-border-color","--sf-card-border-width","--sf-card-gap","--sf-card-heading-size","--sf-card-media-radius","--sf-card-media-ratio","--sf-card-padding","--sf-card-radius","--sf-card-radius-outer","--sf-card-shadow","--sf-card-shadow--elevated","--sf-card-shadow--hover","--sf-caret-color","--sf-center-gutter","--sf-center-max","--sf-cluster-align","--sf-cluster-gap","--sf-cluster-justify","--sf-code-font-size","--sf-color-action","--sf-color-action--active","--sf-color-action--hover","--sf-color-action-100","--sf-color-action-200","--sf-color-action-300","--sf-color-action-400","--sf-color-action-50","--sf-color-action-500","--sf-color-action-600","--sf-color-action-700","--sf-color-action-800","--sf-color-action-900","--sf-color-action-950","--sf-color-action-a10","--sf-color-action-a30","--sf-color-action-a5","--sf-color-action-a50","--sf-color-action-a80","--sf-color-action-darker","--sf-color-action-lighter","--sf-color-action-muted","--sf-color-action-source-dark","--sf-color-action-source-light","--sf-color-action-subtle","--sf-color-action-superdark","--sf-color-action-superlight","--sf-color-action-tint","--sf-color-action-xdark","--sf-color-action-xlight","--sf-color-base","--sf-color-base--active","--sf-color-base--hover","--sf-color-base-100","--sf-color-base-200","--sf-color-base-300","--sf-color-base-400","--sf-color-base-50","--sf-color-base-500","--sf-color-base-600","--sf-color-base-700","--sf-color-base-800","--sf-color-base-900","--sf-color-base-950","--sf-color-base-a10","--sf-color-base-a30","--sf-color-base-a5","--sf-color-base-a50","--sf-color-base-a80","--sf-color-base-muted","--sf-color-base-source-dark","--sf-color-base-source-light","--sf-color-base-subtle","--sf-color-base-tint","--sf-color-bg","--sf-color-bg--active","--sf-color-bg--disabled","--sf-color-bg--focus","--sf-color-bg--hover","--sf-color-bg--selected","--sf-color-black","--sf-color-border","--sf-color-border--disabled","--sf-color-border--focus","--sf-color-border--strong","--sf-color-border--subtle","--sf-color-border--translucent","--sf-color-code-bg","--sf-color-code-text","--sf-color-danger","--sf-color-danger-muted","--sf-color-danger-source-dark","--sf-color-danger-source-light","--sf-color-danger-strong","--sf-color-danger-subtle","--sf-color-danger-tint","--sf-color-dim","--sf-color-heading","--sf-color-info","--sf-color-info-muted","--sf-color-info-source-dark","--sf-color-info-source-light","--sf-color-info-strong","--sf-color-info-subtle","--sf-color-info-tint","--sf-color-inset","--sf-color-inverse","--sf-color-link","--sf-color-link--active","--sf-color-link--disabled","--sf-color-link--hover","--sf-color-link--underline","--sf-color-link--visited","--sf-color-mark-bg","--sf-color-mark-text","--sf-color-neutral","--sf-color-neutral--active","--sf-color-neutral--hover","--sf-color-neutral-100","--sf-color-neutral-200","--sf-color-neutral-300","--sf-color-neutral-400","--sf-color-neutral-50","--sf-color-neutral-500","--sf-color-neutral-600","--sf-color-neutral-700","--sf-color-neutral-800","--sf-color-neutral-900","--sf-color-neutral-950","--sf-color-neutral-a10","--sf-color-neutral-a30","--sf-color-neutral-a5","--sf-color-neutral-a50","--sf-color-neutral-a80","--sf-color-neutral-darker","--sf-color-neutral-lighter","--sf-color-neutral-muted","--sf-color-neutral-source-dark","--sf-color-neutral-source-light","--sf-color-neutral-subtle","--sf-color-neutral-superdark","--sf-color-neutral-superlight","--sf-color-neutral-tint","--sf-color-neutral-xdark","--sf-color-neutral-xlight","--sf-color-overlay","--sf-color-primary","--sf-color-primary--active","--sf-color-primary--hover","--sf-color-primary-100","--sf-color-primary-200","--sf-color-primary-300","--sf-color-primary-400","--sf-color-primary-50","--sf-color-primary-500","--sf-color-primary-600","--sf-color-primary-700","--sf-color-primary-800","--sf-color-primary-900","--sf-color-primary-950","--sf-color-primary-a10","--sf-color-primary-a30","--sf-color-primary-a5","--sf-color-primary-a50","--sf-color-primary-a80","--sf-color-primary-darker","--sf-color-primary-lighter","--sf-color-primary-muted","--sf-color-primary-source-dark","--sf-color-primary-source-light","--sf-color-primary-subtle","--sf-color-primary-superdark","--sf-color-primary-superlight","--sf-color-primary-tint","--sf-color-primary-xdark","--sf-color-primary-xlight","--sf-color-raised","--sf-color-scheme","--sf-color-secondary","--sf-color-secondary--active","--sf-color-secondary--hover","--sf-color-secondary-100","--sf-color-secondary-200","--sf-color-secondary-300","--sf-color-secondary-400","--sf-color-secondary-50","--sf-color-secondary-500","--sf-color-secondary-600","--sf-color-secondary-700","--sf-color-secondary-800","--sf-color-secondary-900","--sf-color-secondary-950","--sf-color-secondary-a10","--sf-color-secondary-a30","--sf-color-secondary-a5","--sf-color-secondary-a50","--sf-color-secondary-a80","--sf-color-secondary-darker","--sf-color-secondary-lighter","--sf-color-secondary-muted","--sf-color-secondary-source-dark","--sf-color-secondary-source-light","--sf-color-secondary-subtle","--sf-color-secondary-superdark","--sf-color-secondary-superlight","--sf-color-secondary-tint","--sf-color-secondary-xdark","--sf-color-secondary-xlight","--sf-color-selection-bg","--sf-color-selection-bg--alt","--sf-color-selection-text","--sf-color-selection-text--alt","--sf-color-success","--sf-color-success-muted","--sf-color-success-source-dark","--sf-color-success-source-light","--sf-color-success-strong","--sf-color-success-subtle","--sf-color-success-tint","--sf-color-surface","--sf-color-tertiary","--sf-color-tertiary--active","--sf-color-tertiary--hover","--sf-color-tertiary-100","--sf-color-tertiary-200","--sf-color-tertiary-300","--sf-color-tertiary-400","--sf-color-tertiary-50","--sf-color-tertiary-500","--sf-color-tertiary-600","--sf-color-tertiary-700","--sf-color-tertiary-800","--sf-color-tertiary-900","--sf-color-tertiary-950","--sf-color-tertiary-a10","--sf-color-tertiary-a30","--sf-color-tertiary-a5","--sf-color-tertiary-a50","--sf-color-tertiary-a80","--sf-color-tertiary-darker","--sf-color-tertiary-lighter","--sf-color-tertiary-muted","--sf-color-tertiary-source-dark","--sf-color-tertiary-source-light","--sf-color-tertiary-subtle","--sf-color-tertiary-superdark","--sf-color-tertiary-superlight","--sf-color-tertiary-tint","--sf-color-tertiary-xdark","--sf-color-tertiary-xlight","--sf-color-text","--sf-color-text--disabled","--sf-color-text--inverse","--sf-color-text--muted","--sf-color-text--on-action","--sf-color-text--on-base","--sf-color-text--on-danger","--sf-color-text--on-info","--sf-color-text--on-inverse","--sf-color-text--on-neutral","--sf-color-text--on-primary","--sf-color-text--on-secondary","--sf-color-text--on-success","--sf-color-text--on-tertiary","--sf-color-text--on-warning","--sf-color-text--placeholder","--sf-color-text--secondary","--sf-color-warning","--sf-color-warning-muted","--sf-color-warning-source-dark","--sf-color-warning-source-light","--sf-color-warning-strong","--sf-color-warning-subtle","--sf-color-warning-tint","--sf-color-white","--sf-component-pad","--sf-container-default","--sf-container-full","--sf-container-narrow","--sf-container-prose","--sf-container-wide","--sf-content-gap","--sf-content-intrinsic-size","--sf-content-width","--sf-contrast-bias","--sf-contrast-threshold","--sf-cover-min-height","--sf-cover-padding","--sf-current-font-weight","--sf-density","--sf-display-l-line-height","--sf-display-m-line-height","--sf-display-s-line-height","--sf-divider-color","--sf-divider-gap","--sf-divider-style","--sf-divider-width","--sf-drop-shadow-l","--sf-drop-shadow-m","--sf-drop-shadow-s","--sf-drop-shadow-xl","--sf-drop-shadow-xs","--sf-duration-fast","--sf-duration-instant","--sf-duration-none","--sf-duration-normal","--sf-duration-slow","--sf-duration-slower","--sf-ease-bounce","--sf-ease-elastic","--sf-ease-in","--sf-ease-in-out","--sf-ease-linear","--sf-ease-out","--sf-ease-overshoot","--sf-ease-spring","--sf-equal-gap","--sf-equal-min-col","--sf-equal-rule-color","--sf-equal-rule-style","--sf-equal-rule-width","--sf-field-block","--sf-field-padding-block","--sf-field-padding-inline","--sf-field-radius","--sf-field-required-marker","--sf-flow-space","--sf-fluid-max-vw","--sf-fluid-min-vw","--sf-fluid-width","--sf-focus-ring-color","--sf-focus-ring-offset","--sf-focus-ring-shadow","--sf-focus-ring-style","--sf-focus-ring-width","--sf-font-body","--sf-font-display","--sf-font-features","--sf-font-geometric","--sf-font-heading","--sf-font-humanist","--sf-font-mono","--sf-font-numeric","--sf-font-slab","--sf-font-variation","--sf-font-weight-body","--sf-font-weight-bold","--sf-font-weight-display","--sf-font-weight-heading","--sf-font-weight-interactive","--sf-font-weight-light","--sf-font-weight-medium","--sf-font-weight-normal","--sf-font-weight-semibold","--sf-font-weight-strong","--sf-frame-ratio","--sf-gap","--sf-gradient-action","--sf-gradient-brand","--sf-gradient-fade--b","--sf-gradient-fade--l","--sf-gradient-fade--r","--sf-gradient-fade--t","--sf-gradient-primary","--sf-gradient-secondary","--sf-gradient-surface","--sf-gradient-tertiary","--sf-grid-gap","--sf-grid-min","--sf-grid-min-2xl","--sf-grid-min-l","--sf-grid-min-m","--sf-grid-min-s","--sf-grid-min-xl","--sf-grid-min-xs","--sf-gutter","--sf-h1-font-weight","--sf-h1-letter-spacing","--sf-h1-line-height","--sf-h1-max-width","--sf-h1-size","--sf-h2-font-weight","--sf-h2-letter-spacing","--sf-h2-line-height","--sf-h2-max-width","--sf-h2-size","--sf-h3-font-weight","--sf-h3-letter-spacing","--sf-h3-line-height","--sf-h3-max-width","--sf-h3-size","--sf-h4-font-weight","--sf-h4-letter-spacing","--sf-h4-line-height","--sf-h4-max-width","--sf-h4-size","--sf-h5-font-weight","--sf-h5-letter-spacing","--sf-h5-line-height","--sf-h5-max-width","--sf-h5-size","--sf-h6-font-weight","--sf-h6-letter-spacing","--sf-h6-line-height","--sf-h6-max-width","--sf-h6-size","--sf-header-height","--sf-header-height-desktop","--sf-header-height-mobile","--sf-heading-color","--sf-heading-font-family","--sf-heading-text-wrap","--sf-hover-grow-scale","--sf-hover-lift","--sf-hover-shrink-scale","--sf-hover-slide","--sf-icon-2xl","--sf-icon-box-bg","--sf-icon-box-border","--sf-icon-box-pad","--sf-icon-box-radius","--sf-icon-l","--sf-icon-m","--sf-icon-s","--sf-icon-xl","--sf-icon-xs","--sf-imposter-margin","--sf-is-active","--sf-is-current","--sf-is-dark","--sf-is-open","--sf-is-pressed","--sf-leading-normal","--sf-leading-relaxed","--sf-leading-snug","--sf-leading-taper","--sf-leading-tight","--sf-line-clamp","--sf-link-external-label","--sf-link-external-marker","--sf-link-underline-offset","--sf-link-underline-thickness","--sf-lumlocker","--sf-mask-scrim-end","--sf-mask-scrim-start","--sf-media-radius","--sf-motion-scale","--sf-object-fit","--sf-object-position","--sf-opacity-disabled","--sf-opacity-muted","--sf-optical-sizing","--sf-overlap-pull","--sf-palette-mix-100","--sf-palette-mix-200","--sf-palette-mix-300","--sf-palette-mix-400","--sf-palette-mix-50","--sf-palette-mix-600","--sf-palette-mix-700","--sf-palette-mix-800","--sf-palette-mix-900","--sf-palette-mix-950","--sf-print-base-size","--sf-print-page-margin","--sf-print-page-size","--sf-prose-block-margin","--sf-prose-blockquote-border","--sf-prose-blockquote-padding","--sf-prose-figcaption-size","--sf-prose-figure-margin","--sf-prose-heading-gap","--sf-prose-hr-margin","--sf-prose-list-gap","--sf-prose-marker-color","--sf-prose-media-margin","--sf-prose-media-radius","--sf-prose-nested-list-gap","--sf-prose-paragraph","--sf-prose-table-pad","--sf-radius-2xl","--sf-radius-2xs","--sf-radius-3xl","--sf-radius-4xl","--sf-radius-full","--sf-radius-l","--sf-radius-m","--sf-radius-none","--sf-radius-outer","--sf-radius-pill","--sf-radius-s","--sf-radius-scale","--sf-radius-xl","--sf-radius-xs","--sf-ratio-3-2","--sf-ratio-4-3","--sf-ratio-cinema","--sf-ratio-golden","--sf-ratio-portrait","--sf-ratio-square","--sf-ratio-video","--sf-reel-gap","--sf-reel-height","--sf-reel-item-width","--sf-safe-bottom","--sf-safe-left","--sf-safe-right","--sf-safe-top","--sf-scrim-color","--sf-scrim-direction","--sf-scrim-gradient","--sf-scrim-text-shadow","--sf-scroll-shadow-size","--sf-scroll-timeline-range-end","--sf-scroll-timeline-range-exit-end","--sf-scroll-timeline-range-exit-start","--sf-scroll-timeline-range-start","--sf-scrollbar-thumb","--sf-scrollbar-track","--sf-section-pad","--sf-section-pad--2xl","--sf-section-pad--l","--sf-section-pad--m","--sf-section-pad--s","--sf-section-pad--xl","--sf-section-pad--xs","--sf-section-scale","--sf-shadow-2xl","--sf-shadow-color","--sf-shadow-glow","--sf-shadow-glow-color","--sf-shadow-inner","--sf-shadow-l","--sf-shadow-lightness","--sf-shadow-m","--sf-shadow-none","--sf-shadow-s","--sf-shadow-strength","--sf-shadow-xl","--sf-shadow-xs","--sf-sidebar-gap","--sf-sidebar-min-width","--sf-sidebar-width","--sf-size-l","--sf-size-m","--sf-size-s","--sf-size-xl","--sf-size-xs","--sf-space-2xl","--sf-space-2xs","--sf-space-3xl","--sf-space-4xl","--sf-space-base-max","--sf-space-base-min","--sf-space-l","--sf-space-m","--sf-space-none","--sf-space-px","--sf-space-ratio-max","--sf-space-ratio-min","--sf-space-s","--sf-space-scale","--sf-space-xl","--sf-space-xs","--sf-stack-gap","--sf-stagger-step","--sf-state-pending-opacity","--sf-sticky-offset","--sf-sticky-offset-desktop","--sf-sticky-offset-mobile","--sf-surface-bg-animation","--sf-surface-bg-attachment","--sf-surface-bg-color","--sf-surface-bg-image","--sf-surface-bg-overlay","--sf-surface-bg-position","--sf-surface-bg-repeat","--sf-surface-bg-size","--sf-surface-color","--sf-switcher-gap","--sf-switcher-threshold","--sf-text-2xl","--sf-text-2xl-font-weight","--sf-text-2xl-letter-spacing","--sf-text-2xl-line-height","--sf-text-2xl-max-width","--sf-text-2xs","--sf-text-2xs-font-weight","--sf-text-2xs-letter-spacing","--sf-text-2xs-line-height","--sf-text-2xs-max-width","--sf-text-3xl","--sf-text-3xl-font-weight","--sf-text-3xl-letter-spacing","--sf-text-3xl-line-height","--sf-text-3xl-max-width","--sf-text-4xl","--sf-text-4xl-font-weight","--sf-text-4xl-letter-spacing","--sf-text-4xl-line-height","--sf-text-4xl-max-width","--sf-text-base-max","--sf-text-base-min","--sf-text-display-base-max","--sf-text-display-base-min","--sf-text-display-l","--sf-text-display-m","--sf-text-display-s","--sf-text-display-scale","--sf-text-l","--sf-text-l-font-weight","--sf-text-l-letter-spacing","--sf-text-l-line-height","--sf-text-l-max-width","--sf-text-m","--sf-text-m-font-weight","--sf-text-m-letter-spacing","--sf-text-m-line-height","--sf-text-m-max-width","--sf-text-ratio-max","--sf-text-ratio-min","--sf-text-s","--sf-text-s-font-weight","--sf-text-s-letter-spacing","--sf-text-s-line-height","--sf-text-s-max-width","--sf-text-scale","--sf-text-shadow-l","--sf-text-shadow-m","--sf-text-shadow-none","--sf-text-shadow-s","--sf-text-shadow-xl","--sf-text-shadow-xs","--sf-text-xl","--sf-text-xl-font-weight","--sf-text-xl-letter-spacing","--sf-text-xl-line-height","--sf-text-xl-max-width","--sf-text-xs","--sf-text-xs-font-weight","--sf-text-xs-letter-spacing","--sf-text-xs-line-height","--sf-text-xs-max-width","--sf-theme-transition-duration","--sf-touch-target","--sf-tracking-normal","--sf-tracking-tight","--sf-tracking-wide","--sf-tracking-wider","--sf-tracking-widest","--sf-transition-colors","--sf-transition-enter","--sf-transition-exit","--sf-transition-fast","--sf-transition-form-field","--sf-transition-opacity","--sf-transition-overlay","--sf-transition-shadow","--sf-transition-slow","--sf-transition-transform","--sf-z-base","--sf-z-below","--sf-z-dropdown","--sf-z-fixed","--sf-z-modal","--sf-z-overlay","--sf-z-raised","--sf-z-sticky","--sf-z-toast","--sf-z-tooltip"]; document.getElementById('tok-count').textContent = TOKENS.length; var grid = document.getElementById('tok-grid'); var filter = document.getElementById('token-filter'); diff --git a/docs/token-annotations.json b/docs/token-annotations.json index f7053ea5..ba6aef20 100644 --- a/docs/token-annotations.json +++ b/docs/token-annotations.json @@ -861,8 +861,6 @@ "--sf-animation-slide-out-down": "Ready-made animation shorthand: slides the element out downward (sf-slide-out-down) at the normal duration with ease-in.", "--sf-animation-slide-out-left": "Ready-made animation shorthand: slides the element out to the left (sf-slide-out-left) at the normal duration with ease-in.", "--sf-animation-slide-out-right": "Ready-made animation shorthand: slides the element out to the right (sf-slide-out-right) at the normal duration with ease-in.", - "--sf-corner-scoop-size": "Cut radius of the .sf-corner-scoop mask. Default: var(--sf-radius-2xl).", - "--sf-corner-scoop-at": "Corner the .sf-corner-scoop mask cuts, as a radial-gradient origin (e.g. '100% 0' = top-right). Default: 100% 0.", "--sf-scroll-timeline-range-exit-start": "Scroll-timeline range at which a scroll-out exit animation begins. Default: cover 70%.", "--sf-scroll-timeline-range-exit-end": "Scroll-timeline range at which a scroll-out exit animation finishes. Default: exit 100%.", "--sf-color-selection-bg--alt": "Alt selection background — the inverse-scheme highlight fill for surfaces that deliberately flip colour scheme (e.g. a dark hero in light mode).", @@ -1162,11 +1160,6 @@ "sf-exit--fade-left": "Scroll-out exit animation: fades out while sliding to the left (sf-slide-out-left).", "sf-exit--fade-right": "Scroll-out exit animation: fades out while sliding to the right (sf-slide-out-right).", "sf-exit--scale-down": "Scroll-out exit animation: fades out while shrinking (sf-scale-down).", - "sf-corner-scoop": "Concave \"scooped\" corner cut with a radial-gradient mask; defaults to the top-right corner (--sf-corner-scoop-at). Add a placement modifier to move it.", - "sf-corner-scoop--top-left": "Places the concave corner scoop at the top-left corner.", - "sf-corner-scoop--top-right": "Places the concave corner scoop at the top-right corner.", - "sf-corner-scoop--bottom-left": "Places the concave corner scoop at the bottom-left corner.", - "sf-corner-scoop--bottom-right": "Places the concave corner scoop at the bottom-right corner.", "sf-drop-shadow-xs": "Extra-small filter drop-shadow — follows the element's alpha shape (--sf-drop-shadow-xs).", "sf-drop-shadow-s": "Small filter drop-shadow — follows the element's alpha shape (--sf-drop-shadow-s).", "sf-drop-shadow-m": "Medium filter drop-shadow — follows the element's alpha shape (--sf-drop-shadow-m).", diff --git a/docs/token-index.json b/docs/token-index.json index 3239988b..360cae07 100644 --- a/docs/token-index.json +++ b/docs/token-index.json @@ -8,15 +8,15 @@ "optional/tokens.components.css" ], "counts": { - "tokens": 756, + "tokens": 754, "by_tier": { - "PUBLIC": 695, + "PUBLIC": 693, "PUBLIC-ADVANCED": 60, "INTERNAL": 1 }, "by_role": { - "knob": 266, - "consumption": 490 + "knob": 265, + "consumption": 489 } } }, @@ -2981,22 +2981,6 @@ ], "value": "0.6" }, - "--sf-corner-scoop-at": { - "tier": "PUBLIC", - "role": "knob", - "files": [ - "core/tokens.macros.css" - ], - "value": "100% 0" - }, - "--sf-corner-scoop-size": { - "tier": "PUBLIC", - "role": "consumption", - "files": [ - "core/tokens.macros.css" - ], - "value": "var(--sf-radius-2xl)" - }, "--sf-cover-min-height": { "tier": "PUBLIC", "role": "knob", diff --git a/docs/token-index.md b/docs/token-index.md index 1198278d..d00e8582 100644 --- a/docs/token-index.md +++ b/docs/token-index.md @@ -8,11 +8,11 @@ A cross-reference of every `--sf-*` custom property by **source file** and for the flat name list see [registry.json](registry.json); for the tier contract and naming rules see [architecture.md](architecture.md). -**756 tokens** (deduplicated by name across the 4 token source files). +**754 tokens** (deduplicated by name across the 4 token source files). | Tier | Count | Meaning | |---|---|---| -| PUBLIC | 695 | Everyday knobs. SemVer-stable. | +| PUBLIC | 693 | Everyday knobs. SemVer-stable. | | PUBLIC-ADVANCED | 60 | Same SemVer guarantee; niche/powerful. | | INTERNAL | 1 | Implementation detail; may change without a major bump. | @@ -22,8 +22,8 @@ declared value (a value that references `var(--sf-…)` is a derived output): | Role | Count | Meaning | |---|---|---| -| knob | 266 | Input you **set** to configure the system (a literal primitive: length, number, colour literal, keyword, font stack, easing curve …). | -| consumption | 490 | Ready-to-use output you **read**; derived from other tokens via `var(--sf-…)` (incl. `light-dark()`/`oklch(from …)`/`color-mix()`). | +| knob | 265 | Input you **set** to configure the system (a literal primitive: length, number, colour literal, keyword, font stack, easing curve …). | +| consumption | 489 | Ready-to-use output you **read**; derived from other tokens via `var(--sf-…)` (incl. `light-dark()`/`oklch(from …)`/`color-mix()`). | ## INTERNAL tokens @@ -466,8 +466,6 @@ declared value (a value that references `var(--sf-…)` is a derived output): | `--sf-content-width` | PUBLIC | consumption | Layout | `var(--sf-container-default)` | | `--sf-contrast-bias` | PUBLIC-ADVANCED | knob | Core | `0` | | `--sf-contrast-threshold` | PUBLIC-ADVANCED | knob | Core | `0.6` | -| `--sf-corner-scoop-at` | PUBLIC | knob | Macros | `100% 0` | -| `--sf-corner-scoop-size` | PUBLIC | consumption | Macros | `var(--sf-radius-2xl)` | | `--sf-cover-min-height` | PUBLIC | knob | Layout | `100dvh` | | `--sf-cover-padding` | PUBLIC | consumption | Layout | `var(--sf-section-pad)` | | `--sf-current-font-weight` | PUBLIC | consumption | Core | `var(--sf-font-weight-bold)` | diff --git a/docs/tokens.md b/docs/tokens.md index c2c3ac7b..938d4f73 100644 --- a/docs/tokens.md +++ b/docs/tokens.md @@ -3,7 +3,7 @@ > **Generated** from source by `scripts/gen-token-reference.js` — > run `npm run docs:tokens` to refresh. Do not edit by hand. -**756 tokens.** Every `--sf-*` custom property and its default value, grouped by source file. +**754 tokens.** Every `--sf-*` custom property and its default value, grouped by source file. If a token is defined in multiple files, it is listed once per section — so this count can be higher than `docs/registry.json` (which deduplicates by name). See [architecture.md](architecture.md) for the PUBLIC / PUBLIC-ADVANCED / INTERNAL @@ -703,14 +703,12 @@ rebrand workflow. ## Macro tokens (`core/tokens.macros.css`) -34 tokens. +32 tokens. | Token | Default | |---|---| | `--sf-aspect` | `16 / 9` | | `--sf-content-intrinsic-size` | `500px` | -| `--sf-corner-scoop-at` | `100% 0` | -| `--sf-corner-scoop-size` | `var(--sf-radius-2xl)` | | `--sf-flow-space` | `var(--sf-content-gap)` | | `--sf-line-clamp` | `3` | | `--sf-overlap-pull` | `var(--sf-space-xl)` | diff --git a/reports/full-api-audit/results/tokens-report.json b/reports/full-api-audit/results/tokens-report.json index 7fed84ca..6762463e 100644 --- a/reports/full-api-audit/results/tokens-report.json +++ b/reports/full-api-audit/results/tokens-report.json @@ -1,7 +1,7 @@ { "summary": { - "totalTokens": 756, - "rendered": 756, + "totalTokens": 754, + "rendered": 754, "consoleErrors": 0, "requestFailures": 0, "empties": 48, @@ -4914,32 +4914,6 @@ "darkComputed": "0.6", "changedInDark": false }, - { - "name": "--sf-corner-scoop-at", - "tier": "PUBLIC", - "role": "knob", - "category": "Macro tokens", - "declared": "100% 0", - "aliasOf": null, - "issues": [], - "computed": "100% 0", - "shown": "100% 0", - "darkComputed": "100% 0", - "changedInDark": false - }, - { - "name": "--sf-corner-scoop-size", - "tier": "PUBLIC", - "role": "consumption", - "category": "Macro tokens", - "declared": "var(--sf-radius-2xl)", - "aliasOf": "--sf-radius-2xl", - "issues": [], - "computed": "24px", - "shown": "24px", - "darkComputed": "24px", - "changedInDark": false - }, { "name": "--sf-cover-min-height", "tier": "PUBLIC", diff --git a/tests/macros.spec.js b/tests/macros.spec.js index 1320f861..17512d16 100644 --- a/tests/macros.spec.js +++ b/tests/macros.spec.js @@ -436,37 +436,6 @@ test.describe('macro: .sf-exit--fade', () => { }); }); -test.describe('macro: .sf-corner-scoop', () => { - test('sets a radial-gradient mask', async ({ page }) => { - await setup(page, `
`); - const mask = await page.locator('#t').evaluate(el => getComputedStyle(el).maskImage); - expect(mask).toContain('radial-gradient'); - }); - - for (const [cls, at] of [ - ['sf-corner-scoop--top-left', '0 0'], - ['sf-corner-scoop--top-right', '100% 0'], - ['sf-corner-scoop--bottom-left', '0 100%'], - ['sf-corner-scoop--bottom-right', '100% 100%'], - ]) { - test(`.${cls} points the cut at ${at}`, async ({ page }) => { - await setup(page, `
`); - const value = await page.locator('#t').evaluate(el => - getComputedStyle(el).getPropertyValue('--sf-corner-scoop-at').trim() - ); - expect(value).toBe(at); - }); - } - - test('--sf-corner-scoop-size override changes the resolved cut radius', async ({ page }) => { - await setup(page, `
`); - const size = await page.locator('#t').evaluate(el => - getComputedStyle(el).getPropertyValue('--sf-corner-scoop-size').trim() - ); - expect(size).toBe('40px'); - }); -}); - test.describe('macro: .sf-overlap / .sf-overlap-host', () => { test('pulls the element up over the previous sibling by --sf-overlap-pull', async ({ page }) => { await setup(page, ` diff --git a/tests/parse-lib.test.js b/tests/parse-lib.test.js index 7b84ed9a..8212fccd 100644 --- a/tests/parse-lib.test.js +++ b/tests/parse-lib.test.js @@ -120,16 +120,19 @@ describe('readFile vs requireFile — missing-file behavior', () => { }); describe('collectComments / describe — directive comments never become descriptions', () => { - // Reproduces the .sf-corner-scoop--* leak: a stylelint-disable comment sits - // right above a vendor-prefixed declaration inside the base rule, with no - // comment of their own governing the variant selectors that follow. + // Synthetic reproduction of a historical directive-comment leak: a + // stylelint-disable comment sits right above a vendor-prefixed declaration + // inside the base rule, with no comment of their own governing the variant + // selectors that follow — those variants must fall back to the base rule's + // governing note, never inherit the stylelint-disable directive as a + // description. const css = ` - /* Concave corner — a corner that curves away from the box. */ - .sf-corner-scoop { + /* Masked shape — an element clipped by a radial-gradient mask. */ + .sf-mask-cut { /* stylelint-disable-next-line property-no-vendor-prefix -- required for Safari < 18 */ -webkit-mask-image: radial-gradient(circle, transparent 1rem, black 1rem); } - .sf-corner-scoop--top-left { --sf-corner-scoop-at: 0 0; } + .sf-mask-cut--top-left { --sf-mask-cut-at: 0 0; } `; test('a stylelint-disable comment is classified as a directive, not a note', () => { @@ -141,10 +144,10 @@ describe('collectComments / describe — directive comments never become descrip test('a variant selector with no comment of its own falls back to the governing note, not the directive', () => { const comments = collectComments(css); - const idx = css.indexOf('.sf-corner-scoop--top-left'); + const idx = css.indexOf('.sf-mask-cut--top-left'); const { description } = describeElement(comments, idx); assert.ok(!description.includes('stylelint-disable')); - assert.match(description, /concave corner/i); + assert.match(description, /masked shape/i); }); }); diff --git a/tests/token-api.snapshot.json b/tests/token-api.snapshot.json index bef23631..64fd35fd 100644 --- a/tests/token-api.snapshot.json +++ b/tests/token-api.snapshot.json @@ -369,8 +369,6 @@ "--sf-content-width", "--sf-contrast-bias", "--sf-contrast-threshold", - "--sf-corner-scoop-at", - "--sf-corner-scoop-size", "--sf-cover-min-height", "--sf-cover-padding", "--sf-current-font-weight", diff --git a/token-registry.json b/token-registry.json index 9aacaf4f..2899b694 100644 --- a/token-registry.json +++ b/token-registry.json @@ -2883,11 +2883,13 @@ }, { "id": 710, - "name": "--sf-corner-scoop-at" + "name": "--sf-corner-scoop-at", + "removed": true }, { "id": 711, - "name": "--sf-corner-scoop-size" + "name": "--sf-corner-scoop-size", + "removed": true }, { "id": 712,