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 31ef54a3a..46b854cca 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 c35a0c062..75ca9a4c4 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 4a31e9fdb..d332b0678 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 78aaed198..68b0aeaaa 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 c0a054693..8733dafac 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 56b4f147f..94174023d 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 fa63420cc..a35265c50 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 ca6627345..67de12328 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 6e3d16c7d..c4503c0b5 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 44f78c39f..a120f71fb 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 e2ae27709..4eed4de55 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 17512d167..839586870 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 8733dafac..b269f8f2f 100644 --- a/demo/index.html +++ b/demo/index.html @@ -5017,7 +5017,7 @@

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