From 902a1612743c942871e5402f340e69d3c558a676 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 2 Jul 2026 06:04:51 +0000 Subject: [PATCH 1/3] docs(core): clean up core css comments (SL-001..005) Comment-only changes across core/*.css, no selector/property/value diffs (verified: npm run build's badge-optimal.json is byte-identical). - SL-001: cross-link the duplicated dark/light OKLCH clamp() derivation formula between core/tokens.css:364-373 (inside light-dark()) and core/themes.css's SECTION-LEVEL THEMING block (flat re-declaration for [data-theme] overrides on non-:root elements). Left unmerged per the audit's open question - themes.css genuinely needs flat values outside light-dark(), so this may be intentional; deferred to the maintainer. - SL-002: doc-comment above .sf-clickable-parent warning against applying it to large (100+ node) grids, since its selectors combine multiple :has() branches. - SL-003: strengthen --sf-is-dark's "internal, don't set directly" comment to be unmistakable against the immediately-following --sf-is-active/-current/-pressed/-open block's "public hooks" comment - same --sf-is-* naming pattern, opposite contract. Grepped every var(--sf-is-dark) read site first to confirm nothing external sets it. - SL-004: add short section labels to core/layout.css's 11 previously unlabeled blank-line section dividers, matching sibling files' style. - SL-005: consolidate the "var() not allowed inside @container" note (previously stated at only 1 of 4 @container sites) into one comment near the top of core/layout.css. Adding SL-004's /* Section */ label directly above .sf-section shadowed gen-api-index.js's fallback-to-previous-description logic for the uncommented .sf-section--guttered sitting in the same section (its description regenerated as the literal string "Section" instead of its existing curated text). Fixed by promoting that description into docs/token-annotations.json's classes overlay - the durable, intended mechanism for exactly this - rather than removing the section label. Verified: lint:css, build, test:unit, check:llm-guide, audit:check all pass; docs/api-index.json, docs/api-index.md, and the configurator's generated data files are byte-identical to base after the fix. --- core/accessibility.css | 5 +++++ core/layout.css | 19 ++++++++++++++++--- core/themes.css | 6 +++++- core/tokens.css | 22 ++++++++++++++++------ docs/token-annotations.json | 1 + 5 files changed, 43 insertions(+), 10 deletions(-) diff --git a/core/accessibility.css b/core/accessibility.css index 8bb09193..bc822562 100644 --- a/core/accessibility.css +++ b/core/accessibility.css @@ -157,6 +157,11 @@ } /* Clickable-parent */ + /* Perf note (SL-002): the two selector groups below each combine multiple + :has()-bearing branches, forcing subtree re-evaluation on DOM mutation + inside .sf-clickable-parent. Fine for typical card/list-item usage; avoid + applying this class to large (100+ node) grids or lists without profiling + first. */ .sf-clickable-parent { --sf-clickable-overlay-z: 1; position: relative; diff --git a/core/layout.css b/core/layout.css index ef3bbefa..c482b527 100644 --- a/core/layout.css +++ b/core/layout.css @@ -1,11 +1,15 @@ /* SLASHED — core/layout.css @layer slashed.layout Layout primitives: section, container, stack, cluster, grid, sidebar, switcher, frame. - Prefix: .sf-*; local rhythm via --sf-*-gap / sizing tokens. */ + Prefix: .sf-*; local rhythm via --sf-*-gap / sizing tokens. + SL-005: every @container query in this file hardcodes its breakpoint + instead of referencing a --sf-* token — var() is not allowed inside an + @container condition per the CSS spec. This applies framework-wide to + every @container site below; not re-explained at each one. */ @layer slashed.layout { - + /* Section */ .sf-section { padding-block: var(--sf-section-pad); } .sf-section--xs { --sf-section-pad: var(--sf-section-pad--xs); } .sf-section--s { --sf-section-pad: var(--sf-section-pad--s); } @@ -52,6 +56,7 @@ } + /* Container */ .sf-container { container: sf-layout / inline-size; width: 100%; @@ -71,6 +76,7 @@ } + /* Stack & gap */ .sf-stack { display: flex; flex-direction: column; @@ -96,12 +102,14 @@ .sf-gap--2xl { gap: var(--sf-space-2xl); } + /* Box */ .sf-box { padding: var(--sf-box-padding); outline: var(--sf-box-border-width) solid var(--sf-box-border-color); } + /* Center */ .sf-center { box-sizing: content-box; width: auto; @@ -117,6 +125,7 @@ } + /* Cluster */ .sf-cluster { display: flex; flex-wrap: wrap; @@ -137,6 +146,7 @@ .sf-cluster--between { justify-content: space-between; } + /* Sidebar */ .sf-sidebar { display: flex; flex-wrap: wrap; @@ -169,6 +179,7 @@ .sf-sidebar--wide { --sf-sidebar-width: 26rem; } + /* Switcher */ .sf-switcher { display: flex; flex-wrap: wrap; @@ -184,6 +195,7 @@ .sf-switcher--vertical { flex-direction: column; } + /* Grid & icon */ .sf-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(var(--sf-grid-min), 100%), 1fr)); @@ -229,6 +241,7 @@ } + /* Cover */ .sf-cover { display: flex; flex-direction: column; @@ -247,6 +260,7 @@ .sf-cover--padding-l { padding-block: var(--sf-space-4xl); } + /* Frame */ .sf-frame { aspect-ratio: var(--sf-frame-ratio); overflow: hidden; @@ -395,7 +409,6 @@ container: sf-grid / inline-size; } - /* Cannot use var() inside @container per CSS spec — breakpoints hardcoded. */ @container (min-width: 30em) { .sf-grid-cols-4 { grid-template-columns: repeat(2, 1fr); } .sf-grid-cols-6 { grid-template-columns: repeat(3, 1fr); } diff --git a/core/themes.css b/core/themes.css index a0bb707f..0cddf3dd 100644 --- a/core/themes.css +++ b/core/themes.css @@ -58,7 +58,11 @@ /* SECTION-LEVEL THEMING */ /* light-dark() bakes at :root declaration time; re-declarations on [data-theme] - elements are required for section-level theming to work. */ + elements are required for section-level theming to work. + SL-001: the clamp() derivation formula below is the same one used inside + tokens.css's light-dark() block (core/tokens.css:364-373) — duplicated + here, not shared, because this file needs flat values outside light-dark(). + Keep both copies in sync if the formula ever changes. */ @supports (color: oklch(from red l c h)) { :root { diff --git a/core/tokens.css b/core/tokens.css index 4bc09994..35613a14 100644 --- a/core/tokens.css +++ b/core/tokens.css @@ -101,14 +101,20 @@ --sf-color-danger: var(--sf-color-danger-source-light); } - /* Mode flag — drives formula direction for non-color dark overrides. - Set by themes.css via [data-theme="dark"] and the prefers-color-scheme - media query. Do not set directly. */ + /* Mode flag — INTERNAL, not a public hook (SL-003: same "--sf-is-*" naming + pattern as the public flags below, opposite contract — read here, don't + set). Drives formula direction for non-color dark overrides. Set only by + themes.css via [data-theme="dark"] and the prefers-color-scheme media + query; every other read site (core/tokens.css, the configurator's power + knobs) only reads it inside calc() expressions. Setting it directly + desyncs it from color-scheme/[data-theme] and produces an inconsistent + theme. */ @property --sf-is-dark { syntax: ""; inherits: true; initial-value: 0; } /* @property — INTERACTION STATE FLAGS */ - /* Public hooks for Style Queries. Allow components to react to states - toggled on ancestors via .is-* classes. */ + /* PUBLIC hooks for Style Queries — safe to set from consumer code, unlike + --sf-is-dark above. Allow components to react to states toggled on + ancestors via .is-* classes. */ @property --sf-is-active { syntax: ""; inherits: true; initial-value: 0; } @property --sf-is-current { syntax: ""; inherits: true; initial-value: 0; } @property --sf-is-pressed { syntax: ""; inherits: true; initial-value: 0; } @@ -366,7 +372,11 @@ Dark auto-derivation formula (brand + status): clamp(0.65, 0.95 - l*0.5, 0.88) lightens dark-mode value relative to the light source. Surface inverts: clamp(0.16, 1.18 - l, 0.24) — near-white flips to near-dark. - Override any --sf-color-X-dark to take full per-mode control. */ + Override any --sf-color-X-dark to take full per-mode control. + SL-001: this same clamp() formula is re-declared flat in themes.css + (SECTION-LEVEL THEMING) so [data-theme] overrides on non-:root elements + still resolve correctly — light-dark() only bakes at :root. Keep both + copies in sync if the formula ever changes. */ --sf-color-primary: light-dark(var(--sf-color-primary-source-light), var(--sf-color-primary-source-dark, oklch(from var(--sf-color-primary-source-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h))); --sf-color-secondary: light-dark(var(--sf-color-secondary-source-light), var(--sf-color-secondary-source-dark, oklch(from var(--sf-color-secondary-source-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h))); --sf-color-tertiary: light-dark(var(--sf-color-tertiary-source-light), var(--sf-color-tertiary-source-dark, oklch(from var(--sf-color-tertiary-source-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h))); diff --git a/docs/token-annotations.json b/docs/token-annotations.json index 21de16de..2b323ccf 100644 --- a/docs/token-annotations.json +++ b/docs/token-annotations.json @@ -802,6 +802,7 @@ }, "classes": { "no-motion": "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-section--guttered": "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-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": "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": "Forwards focus-visible styling to this container when any descendant is keyboard-focused. Useful for custom controls that wrap a visually-hidden .", From c6cdb3d79322f693a73791ba797c4c40d5406348 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 2 Jul 2026 06:13:22 +0000 Subject: [PATCH 2/3] docs(core): replace hardcoded line-number citation in SL-001 comment core/themes.css's cross-link to core/tokens.css cited a specific line range (364-373) that will drift as either file is edited independently. Replaced with a stable text anchor (the section's own comment text) to search for instead, matching how the tokens.css side already referenced themes.css by section name (SECTION-LEVEL THEMING) rather than by line number. Caught by Qodo's review on PR 475. --- badges/badge-optimal.json | 7 ------- core/themes.css | 5 +++-- 2 files changed, 3 insertions(+), 9 deletions(-) delete mode 100644 badges/badge-optimal.json diff --git a/badges/badge-optimal.json b/badges/badge-optimal.json deleted file mode 100644 index 1536a71b..00000000 --- a/badges/badge-optimal.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "schemaVersion": 1, - "label": "optimal", - "message": "17.5 kB gzip", - "color": "brightgreen", - "namedLogo": "css3" -} diff --git a/core/themes.css b/core/themes.css index 0cddf3dd..8f501eba 100644 --- a/core/themes.css +++ b/core/themes.css @@ -60,8 +60,9 @@ /* light-dark() bakes at :root declaration time; re-declarations on [data-theme] elements are required for section-level theming to work. SL-001: the clamp() derivation formula below is the same one used inside - tokens.css's light-dark() block (core/tokens.css:364-373) — duplicated - here, not shared, because this file needs flat values outside light-dark(). + tokens.css's "Resolved color tokens — auto-switch via light-dark()" + block (search core/tokens.css for that comment) — duplicated here, not + shared, because this file needs flat values outside light-dark(). Keep both copies in sync if the formula ever changes. */ @supports (color: oklch(from red l c h)) { From 0b402677e240bb9f3f876dc13100d6cf5d8a2250 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 2 Jul 2026 06:13:58 +0000 Subject: [PATCH 3/3] chore: restore badges/badge-optimal.json accidentally deleted by prior commit A stray 'rm -rf badges' before rebuilding removed the tracked badge-optimal.json along with the gitignored bundle files, and the subsequent commit picked up the deletion. Restoring it unchanged - no content difference, it was regenerated identically by npm run build. --- badges/badge-optimal.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 badges/badge-optimal.json diff --git a/badges/badge-optimal.json b/badges/badge-optimal.json new file mode 100644 index 00000000..1536a71b --- /dev/null +++ b/badges/badge-optimal.json @@ -0,0 +1,7 @@ +{ + "schemaVersion": 1, + "label": "optimal", + "message": "17.5 kB gzip", + "color": "brightgreen", + "namedLogo": "css3" +}