From 64aa9c2201c34c9338b31446da7cf919358b38a8 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 16 Jul 2026 21:40:59 +0000 Subject: [PATCH 1/2] refactor(overlap): drop inline-axis directional variants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove `.sf-overlap--start` and `.sf-overlap--end`. The horizontal-overlap variants had no demonstrated real-world use case (negative inline margins overlapping a sibling is rarely what you want versus absolute positioning) and inflated the public API on the same axis the framework was deliberately disciplined about elsewhere (the corner recipes cut before 1.0). Keeps the base pair `.sf-overlap` (pull-up) + `.sf-overlap-host` — the recipe's real value (isolated stacking context + automatic padding compensation) — plus the block-axis `.sf-overlap--down` variant. Updated CSS, macro docs, annotations, tests, configurator preview, and the demo coverage gallery; regenerated derived docs/registry/API index. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Q1XiJo184xVAv18qsyVvDH --- badges/badge-optimal.json | 2 +- configurator/src/data/classes.generated.json | 20 ------- configurator/src/lib/preview/sections.ts | 5 +- core/macros.css | 6 +- demo/index.html | 10 +--- docs/api-index.json | 58 ++------------------ docs/api-index.md | 10 ++-- docs/classes.md | 6 +- docs/macros.md | 2 - docs/registry.json | 4 +- docs/token-annotations.json | 2 - tests/macros.spec.js | 2 - 12 files changed, 18 insertions(+), 109 deletions(-) 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/classes.generated.json b/configurator/src/data/classes.generated.json index c35a0c06..75ca9a4c 100644 --- a/configurator/src/data/classes.generated.json +++ b/configurator/src/data/classes.generated.json @@ -2394,26 +2394,6 @@ "optional": false, "layer": "slashed.macros" }, - { - "name": "sf-overlap--end", - "selector": ".sf-overlap--end", - "kind": "macro", - "category": "Macro classes", - "group": "", - "description": "Overlap recipe — pulls the element toward the inline-end (negative inline-end margin) to overlap horizontally.", - "optional": false, - "layer": "slashed.macros" - }, - { - "name": "sf-overlap--start", - "selector": ".sf-overlap--start", - "kind": "macro", - "category": "Macro classes", - "group": "", - "description": "Overlap recipe — pulls the element toward the inline-start (negative inline-start margin) to overlap horizontally.", - "optional": false, - "layer": "slashed.macros" - }, { "name": "sf-overlap-host", "selector": ".sf-overlap-host", diff --git a/configurator/src/lib/preview/sections.ts b/configurator/src/lib/preview/sections.ts index 4a31e9fd..d332b067 100644 --- a/configurator/src/lib/preview/sections.ts +++ b/configurator/src/lib/preview/sections.ts @@ -607,7 +607,7 @@ export function macros(): string { // 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 - // remaining directional variants on their own swatches. + // two block-axis directional variants on their own swatches. const avatar = `
`; const overlapHost = frame(`
${avatar}
@@ -617,8 +617,7 @@ export function macros(): string { 10, ...([ ["", "sf-overlap (pulls up)"], - ["--start", "sf-overlap--start"], - ["--end", "sf-overlap--end"], + ["--down", "sf-overlap--down (pulls down)"], ] as const).map(([m, label]) => specimen(label, `
`), ), diff --git a/core/macros.css b/core/macros.css index 78aaed19..68b0aeaa 100644 --- a/core/macros.css +++ b/core/macros.css @@ -392,16 +392,12 @@ logical margin + a raised stacking context. Directional variants are standalone (margins are distinct properties, not a re-pointable knob). */ .sf-overlap, - .sf-overlap--down, - .sf-overlap--start, - .sf-overlap--end { + .sf-overlap--down { position: relative; z-index: var(--sf-z-raised); } .sf-overlap { margin-block-start: calc(-1 * var(--sf-overlap-pull)); } .sf-overlap--down { margin-block-end: calc(-1 * var(--sf-overlap-pull)); } - .sf-overlap--start { margin-inline-start: calc(-1 * var(--sf-overlap-pull)); } - .sf-overlap--end { margin-inline-end: calc(-1 * var(--sf-overlap-pull)); } /* Card-container recipe — the receiving side of an overlap: an isolated stacking context with block-start padding compensation so in-flow diff --git a/demo/index.html b/demo/index.html index c0a05469..8733dafa 100644 --- a/demo/index.html +++ b/demo/index.html @@ -2850,7 +2850,7 @@

.sf-overlap / .sf-overlap-host — content clears the badge above

-

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

+

Directional variant: .sf-overlap--down (pulls into the next element).

Macros in action — a composed profile card

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

@@ -3741,14 +3741,6 @@

Macros & effects
.sf-overlap--down public

Overlap recipe — pulls following content up (negative block-end margin) so this element overlaps the sibling below it.

1
overlap
-
-
.sf-overlap--end public

Overlap recipe — pulls the element toward the inline-end (negative inline-end margin) to overlap horizontally.

-
1
overlap
-
-
-
.sf-overlap--start public

Overlap recipe — pulls the element toward the inline-start (negative inline-start margin) to overlap horizontally.

-
1
overlap
-
.sf-overlap-host public

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.

1
overlap
diff --git a/docs/api-index.json b/docs/api-index.json index 56b4f147..94174023 100644 --- a/docs/api-index.json +++ b/docs/api-index.json @@ -25,14 +25,14 @@ "optimal" ], "counts": { - "total": 1071, + "total": 1069, "by_type": { - "class": 325, + "class": 323, "token": 746 }, "by_tier": { "INTERNAL": 1, - "PUBLIC": 1018, + "PUBLIC": 1016, "PUBLIC-ADVANCED": 52 }, "by_role": { @@ -40,8 +40,8 @@ "knob": 257 }, "tokens": 746, - "classes": 325, - "sf_classes": 289, + "classes": 323, + "sf_classes": 287, "is_classes": 28, "unprefixed_classes": 8, "by_category": { @@ -52,7 +52,7 @@ "Forms": 1, "Layout primitives": 145, "Layout tokens": 53, - "Macro classes": 53, + "Macro classes": 51, "Macro tokens": 32, "Motion / animation": 22, "Print": 4, @@ -24893,52 +24893,6 @@ "optimal" ] }, - { - "name": "sf-overlap--end", - "type": "class", - "tier": "PUBLIC", - "selector": ".sf-overlap--end", - "prefix": "sf", - "kind": "macro", - "category": "Macro classes", - "area": "macros", - "group": "", - "description": "Overlap recipe — pulls the element toward the inline-end (negative inline-end margin) to overlap horizontally.", - "isVariant": true, - "baseClass": "sf-overlap", - "optional": false, - "layer": "slashed.macros", - "sourceFiles": [ - "core/macros.css" - ], - "bundles": [ - "full", - "optimal" - ] - }, - { - "name": "sf-overlap--start", - "type": "class", - "tier": "PUBLIC", - "selector": ".sf-overlap--start", - "prefix": "sf", - "kind": "macro", - "category": "Macro classes", - "area": "macros", - "group": "", - "description": "Overlap recipe — pulls the element toward the inline-start (negative inline-start margin) to overlap horizontally.", - "isVariant": true, - "baseClass": "sf-overlap", - "optional": false, - "layer": "slashed.macros", - "sourceFiles": [ - "core/macros.css" - ], - "bundles": [ - "full", - "optimal" - ] - }, { "name": "sf-overlap-host", "type": "class", diff --git a/docs/api-index.md b/docs/api-index.md index fa63420c..a35265c5 100644 --- a/docs/api-index.md +++ b/docs/api-index.md @@ -10,11 +10,11 @@ and a short description. The machine-readable companion (with all columns) is [registry.json](registry.json); for the tier contract see [architecture.md](architecture.md). -**1071 elements** — 746 tokens, 325 classes. +**1069 elements** — 746 tokens, 323 classes. | Tier | Count | Meaning | |---|---|---| -| PUBLIC | 1018 | Everyday surface. SemVer-stable. | +| PUBLIC | 1016 | Everyday surface. SemVer-stable. | | PUBLIC-ADVANCED | 52 | Same SemVer guarantee; niche/powerful. | | INTERNAL | 1 | Implementation detail; may change without a major bump. | @@ -786,7 +786,7 @@ 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 (325) +## Classes (323) ### Accessibility (8) @@ -992,7 +992,7 @@ and a short description. The machine-readable companion (with all columns) is | `.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 (53) +### Macro classes (51) | Class | Tier | Kind | Group | Description | |---|---|---|---|---| @@ -1022,8 +1022,6 @@ and a short description. The machine-readable companion (with all columns) is | `.sf-overflow-fade--top` | PUBLIC | macro | — | Overflow fade variant: fades the top (block-start) edge. | | `.sf-overlap` | PUBLIC | macro | — | Overlap recipe — pulls the element upward (negative block-start margin) so it overlaps the previous sibling by --sf-overlap-pull. | | `.sf-overlap--down` | PUBLIC | macro | — | Overlap recipe — pulls following content up (negative block-end margin) so this element overlaps the sibling below it. | -| `.sf-overlap--end` | PUBLIC | macro | — | Overlap recipe — pulls the element toward the inline-end (negative inline-end margin) to overlap horizontally. | -| `.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 | — | Overlay container with a gradient darkening scrim behind text placed on an image or colored background. | diff --git a/docs/classes.md b/docs/classes.md index ca662734..67de1232 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. -**289 .sf-classes, 28 .sf-is-classes.** Every `.sf-*` layout/macro class and `.sf-is-*` state class. +**287 .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,7 +160,7 @@ See [architecture.md](architecture.md) for layer order and naming conventions. ## Macro classes (`core/macros.css`) -53 classes. +51 classes. | Class | |---| @@ -190,8 +190,6 @@ See [architecture.md](architecture.md) for layer order and naming conventions. | `.sf-overflow-fade--top` | | `.sf-overlap` | | `.sf-overlap--down` | -| `.sf-overlap--end` | -| `.sf-overlap--start` | | `.sf-overlap-host` | | `.sf-prose` | | `.sf-scrim` | diff --git a/docs/macros.md b/docs/macros.md index 6e3d16c7..c4503c0b 100644 --- a/docs/macros.md +++ b/docs/macros.md @@ -753,8 +753,6 @@ since each moves a different margin): |---|---| | `.sf-overlap` | pulls up over the previous element (default) | | `.sf-overlap--down` | pulls down over the next element | -| `.sf-overlap--start` | pulls into the inline-start side | -| `.sf-overlap--end` | pulls into the inline-end side | Tokens: diff --git a/docs/registry.json b/docs/registry.json index 44f78c39..a120f71f 100644 --- a/docs/registry.json +++ b/docs/registry.json @@ -20,7 +20,7 @@ ], "counts": { "tokens": 746, - "sf_classes": 289, + "sf_classes": 287, "is_classes": 28 } }, @@ -979,8 +979,6 @@ "sf-overflow-fade--top", "sf-overlap", "sf-overlap--down", - "sf-overlap--end", - "sf-overlap--start", "sf-overlap-host", "sf-overlay", "sf-pancake", diff --git a/docs/token-annotations.json b/docs/token-annotations.json index e2ae2770..4eed4de5 100644 --- a/docs/token-annotations.json +++ b/docs/token-annotations.json @@ -1168,8 +1168,6 @@ "sf-marker--action": "Colours list ::markers with the action colour.", "sf-overlap": "Overlap recipe — pulls the element upward (negative block-start margin) so it overlaps the previous sibling by --sf-overlap-pull.", "sf-overlap--down": "Overlap recipe — pulls following content up (negative block-end margin) so this element overlaps the sibling below it.", - "sf-overlap--start": "Overlap recipe — pulls the element toward the inline-start (negative inline-start margin) to overlap horizontally.", - "sf-overlap--end": "Overlap recipe — pulls the element toward the inline-end (negative inline-end margin) to overlap horizontally.", "sf-sticky": "position: sticky pinned at the header-aware --sf-sticky-offset.", "sf-sticky--s": "Sticky positioning with an extra small gap (--sf-space-s) above the header-aware offset.", "sf-sticky--m": "Sticky positioning with an extra medium gap (--sf-space-m) above the header-aware offset.", diff --git a/tests/macros.spec.js b/tests/macros.spec.js index 17512d16..83958687 100644 --- a/tests/macros.spec.js +++ b/tests/macros.spec.js @@ -462,8 +462,6 @@ test.describe('macro: .sf-overlap / .sf-overlap-host', () => { for (const [cls, prop] of [ ['sf-overlap--down', 'marginBottom'], - ['sf-overlap--start', 'marginLeft'], - ['sf-overlap--end', 'marginRight'], ]) { test(`.${cls} sets a negative ${prop}`, async ({ page }) => { await setup(page, `
x
`); From 06da4b196a30e9de772cac80df636cbb251c9638 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 17 Jul 2026 01:08:52 +0000 Subject: [PATCH 2/2] fix(demo): drop removed overlap variants from cov-data coverage blob The embedded #cov-data JSON still listed sf-overlap--start and sf-overlap--end in its classes array, so the demo's live class counter drifted from every other artifact (reporting the two removed classes as still present). Remove both entries to match the pruned gallery and the regenerated docs/registry. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Q1XiJo184xVAv18qsyVvDH --- demo/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/index.html b/demo/index.html index 8733dafa..b269f8f2 100644 --- a/demo/index.html +++ b/demo/index.html @@ -5017,7 +5017,7 @@

Design tokens 7
--sf-z-tooltip
- +