From 9ecac6ddf1d8928be821c11257d9cb89a917ac2d Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Jun 2026 07:45:33 +0000 Subject: [PATCH 1/9] feat(layout): add .sf-cq and refactor .sf-equal to RAM pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add .sf-cq — a lightweight container-type: inline-size scope for enabling anonymous @container queries without .sf-container's max-width and centering. Addresses the API trap where sf-grid-cols-* ratio grids silently broke when no container ancestor was present. Refactor .sf-equal from a fixed-count grid (repeat(N, 1fr)) to the RAM pattern (repeat(auto-fit, minmax(min(var(--sf-equal-min-col), 100%), 1fr))). Columns now wrap intrinsically — no @container or @media required. The --sf-equal-cols token is replaced by --sf-equal-min-col and four sized presets (--sf-equal-min-col-2/3/4/6) in tokens.layout.css. BREAKING: --sf-equal-cols is removed. Update custom overrides to --sf-equal-min-col: (e.g. 14rem for a ~4-column layout). Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu --- core/layout.css | 35 ++++++++++++++++++++++++----------- core/tokens.layout.css | 14 ++++++++++---- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/core/layout.css b/core/layout.css index 1fcd0f76..7f1ec820 100644 --- a/core/layout.css +++ b/core/layout.css @@ -96,6 +96,18 @@ .sf-container--wide { max-width: var(--sf-container-wide); } .sf-container--full { max-width: var(--sf-container-full); } + /* -- Container query context -------------------------------- + Lightweight CQ scope. Establishes container-type: inline-size + so anonymous @container queries on descendants respond to THIS + element's width — without the max-width and centering of + .sf-container. No visual styles. + Use when .sf-container is not available in the ancestor tree + and a CQ-dependent primitive needs a container to query. + ---------------------------------------------------------- */ + .sf-cq { + container-type: inline-size; + } + /* -- Stack --------------------------------------------------- Flex column with even vertical spacing between children. Override: style="--sf-stack-gap: 2rem" @@ -505,22 +517,23 @@ .sf-grid-cols-3-1 { grid-template-columns: 3fr 1fr; } } - /* -- Fixed columns ------------------------------------------ - Fixed N-column grid. Column count NEVER collapses — unlike - .sf-grid-cols-N which stacks at narrow container widths. - Use when the layout must stay N columns at all widths; the - caller is responsible for overflow handling. - Override: style="--sf-equal-cols: 3" + /* -- Equal columns (intrinsically responsive) ---------------- + RAM-pattern grid (Repeat, Auto-fit, Minmax). Columns wrap + automatically when they would shrink below --sf-equal-min-col. + No container ancestor required — intrinsically responsive. + Modifiers set the target min-col width for ~N equal columns + at typical container widths; exact count emerges from layout. + Override: style="--sf-equal-min-col: 14rem" ---------------------------------------------------------- */ .sf-equal { display: grid; - grid-template-columns: repeat(var(--sf-equal-cols), 1fr); + grid-template-columns: repeat(auto-fit, minmax(min(var(--sf-equal-min-col), 100%), 1fr)); gap: var(--sf-equal-gap); } - .sf-equal--2 { --sf-equal-cols: 2; } - .sf-equal--3 { --sf-equal-cols: 3; } - .sf-equal--4 { --sf-equal-cols: 4; } - .sf-equal--6 { --sf-equal-cols: 6; } + .sf-equal--2 { --sf-equal-min-col: var(--sf-equal-min-col-2); } + .sf-equal--3 { --sf-equal-min-col: var(--sf-equal-min-col-3); } + .sf-equal--4 { --sf-equal-min-col: var(--sf-equal-min-col-4); } + .sf-equal--6 { --sf-equal-min-col: var(--sf-equal-min-col-6); } /* -- Content grid (breakout pattern) ------------------------- Full-width grid that lets items break out to breakout or full diff --git a/core/tokens.layout.css b/core/tokens.layout.css index a5f71f9c..7b9c4511 100644 --- a/core/tokens.layout.css +++ b/core/tokens.layout.css @@ -88,10 +88,16 @@ --sf-grid-min-2xl: 28rem; /* ---------------------------------------------------------- - Equal columns (fixed, non-responsive) - ---------------------------------------------------------- */ - --sf-equal-cols: 2; - --sf-equal-gap: var(--sf-space-gap); + Equal columns (intrinsically responsive RAM) + min-col-N: minimum column width for the N-column preset. + Exact column count emerges from container ÷ min-col. + ---------------------------------------------------------- */ + --sf-equal-min-col: 16rem; + --sf-equal-min-col-2: 28rem; + --sf-equal-min-col-3: 18rem; + --sf-equal-min-col-4: 13rem; + --sf-equal-min-col-6: 9rem; + --sf-equal-gap: var(--sf-space-gap); /* ---------------------------------------------------------- Cover From 8835d0e01954edaea9d913ea6325d45897e5a84b Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Jun 2026 08:02:08 +0000 Subject: [PATCH 2/9] =?UTF-8?q?fix(tokens,layout,macros):=20pre-freeze=20a?= =?UTF-8?q?udit=20fixes=20=E2=80=94=20overflow=20fallback,=20color=20@prop?= =?UTF-8?q?erty,=20radius-2xs,=20equal=20tokens?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit macros.css: add overflow-x: auto fallback before overflow-inline: auto in .sf-prose table (Safari < 18.2 compat — last missing instance). tokens.css: register computed color tokens (--sf-color-primary, --sf-color-secondary, -tertiary, -action, -neutral, -base, -success, -warning, -error, -info, -danger) with @property (initial-value = light mode) and add :root mirrors. Fixes the @supports dependency chain: in browsers supporting oklch(from) + sign() but NOT light-dark(), these tokens now resolve to valid light-mode colors rather than being undefined. User overrides to --sf-color-X or --sf-color-X-light always take precedence. tokens.css: add --sf-radius-2xs: calc(1px * var(--sf-radius-scale)) to complete the radius scale symmetry with text/space (2xs→4xl). Update token inventory comment to include 2xs. tokens.layout.css: correct --sf-equal-min-col-4 (13rem → 16rem) and --sf-equal-min-col-6 (9rem → 10rem) so the RAM-pattern grid produces ~4 and ~6 columns at a standard 72rem container, matching modifier intent. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu --- core/macros.css | 2 +- core/tokens.css | 36 +++++++++++++++++++++++++++++++++++- core/tokens.layout.css | 4 ++-- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/core/macros.css b/core/macros.css index bde4acad..5763240e 100644 --- a/core/macros.css +++ b/core/macros.css @@ -47,7 +47,7 @@ .sf-prose hr { margin-block: var(--sf-prose-hr-margin); } .sf-prose figure { margin-block: var(--sf-prose-figure-margin); } .sf-prose figcaption { font-size: var(--sf-prose-figcaption-size); color: var(--sf-color-text--muted); margin-block-start: var(--sf-prose-list-gap); } - .sf-prose table { margin-block: var(--sf-prose-block-margin); display: block; overflow-inline: auto; inline-size: 100%; max-inline-size: 100%; } + .sf-prose table { margin-block: var(--sf-prose-block-margin); display: block; overflow-x: auto; overflow-inline: auto; inline-size: 100%; max-inline-size: 100%; } .sf-prose :is(th, td) { padding: var(--sf-prose-table-pad); } .sf-prose video { margin-block: var(--sf-prose-media-margin); border-radius: var(--sf-prose-media-radius); } diff --git a/core/tokens.css b/core/tokens.css index 2902090f..266db11c 100644 --- a/core/tokens.css +++ b/core/tokens.css @@ -92,7 +92,7 @@ · border style (--sf-border-style) · border shorthands (--sf-border, --sf-border-subtle, --sf-border-strong) · divider (--sf-divider-{width,style,color,gap}) - · radius (--sf-radius-{none,xs,s,m,l,xl,2xl,3xl,4xl,full,pill}) + · radius (--sf-radius-{none,2xs,xs,s,m,l,xl,2xl,3xl,4xl,full,pill}) · duration (--sf-duration-{none,instant,fast,normal,slow,slower}) · easing (--sf-ease-{linear,out,in,in-out,spring,elastic,bounce,overshoot}) · transitions (--sf-transition-{colors,form-field,transform,opacity,shadow,fast,slow,enter,exit,overlay}) @@ -192,6 +192,22 @@ @property --sf-color-info-light { syntax: ""; inherits: true; initial-value: oklch(0.48 0.18 235); } @property --sf-color-danger-light { syntax: ""; inherits: true; initial-value: oklch(0.48 0.22 12); } + /* @property — COMPUTED COLOR TOKENS (brand + status) + initial-value = light-mode value. Acts as a valid fallback when + light-dark() is unsupported (the @supports block below won't apply). + User overrides to --sf-color-X or --sf-color-X-light always win. */ + @property --sf-color-primary { syntax: ""; inherits: true; initial-value: oklch(0.47 0.27 264); } + @property --sf-color-secondary { syntax: ""; inherits: true; initial-value: oklch(0.22 0.04 264); } + @property --sf-color-tertiary { syntax: ""; inherits: true; initial-value: oklch(0.42 0.22 295); } + @property --sf-color-action { syntax: ""; inherits: true; initial-value: oklch(0.50 0.22 235); } + @property --sf-color-neutral { syntax: ""; inherits: true; initial-value: oklch(0.52 0.025 260); } + @property --sf-color-base { syntax: ""; inherits: true; initial-value: oklch(0.96 0.006 250); } + @property --sf-color-success { syntax: ""; inherits: true; initial-value: oklch(0.50 0.16 145); } + @property --sf-color-warning { syntax: ""; inherits: true; initial-value: oklch(0.75 0.17 80); } + @property --sf-color-error { syntax: ""; inherits: true; initial-value: oklch(0.50 0.20 25); } + @property --sf-color-info { syntax: ""; inherits: true; initial-value: oklch(0.48 0.18 235); } + @property --sf-color-danger { syntax: ""; inherits: true; initial-value: oklch(0.48 0.22 12); } + /* Plain :root mirrors — character-for-character identical to each @property initial-value above. Engines lacking @property support read the token value from here. Do NOT edit these independently from the initial-value strings. */ @@ -209,6 +225,23 @@ --sf-color-danger-light: oklch(0.48 0.22 12); } + /* Plain :root mirrors for computed tokens — same values as @property initial-value. + Required for engines lacking @property support AND light-dark() support. + Overridden by the @supports block below whenever light-dark() is available. */ + :root { + --sf-color-primary: oklch(0.47 0.27 264); + --sf-color-secondary: oklch(0.22 0.04 264); + --sf-color-tertiary: oklch(0.42 0.22 295); + --sf-color-action: oklch(0.50 0.22 235); + --sf-color-neutral: oklch(0.52 0.025 260); + --sf-color-base: oklch(0.96 0.006 250); + --sf-color-success: oklch(0.50 0.16 145); + --sf-color-warning: oklch(0.75 0.17 80); + --sf-color-error: oklch(0.50 0.20 25); + --sf-color-info: oklch(0.48 0.18 235); + --sf-color-danger: oklch(0.48 0.22 12); + } + /* 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. */ @@ -1058,6 +1091,7 @@ large enough to clip to half the shorter edge for any realistic UI. ---------------------------------------------------------- */ --sf-radius-none: 0; + --sf-radius-2xs: calc(1px * var(--sf-radius-scale)); --sf-radius-xs: calc(2px * var(--sf-radius-scale)); --sf-radius-s: calc(4px * var(--sf-radius-scale)); --sf-radius-m: calc(8px * var(--sf-radius-scale)); diff --git a/core/tokens.layout.css b/core/tokens.layout.css index 7b9c4511..cb1f877b 100644 --- a/core/tokens.layout.css +++ b/core/tokens.layout.css @@ -95,8 +95,8 @@ --sf-equal-min-col: 16rem; --sf-equal-min-col-2: 28rem; --sf-equal-min-col-3: 18rem; - --sf-equal-min-col-4: 13rem; - --sf-equal-min-col-6: 9rem; + --sf-equal-min-col-4: 16rem; + --sf-equal-min-col-6: 10rem; --sf-equal-gap: var(--sf-space-gap); /* ---------------------------------------------------------- From 3ca5a274a925b7c46b03066bce6d7d441e959ef1 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Jun 2026 08:03:36 +0000 Subject: [PATCH 3/9] fix(tokens): computed color mirrors resolve via -light tokens, not hardcoded values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The :root mirror for computed color tokens (--sf-color-primary etc.) must point to var(--sf-color-X-light) — not a hardcoded oklch value — so user overrides to --sf-color-primary-light are respected in browsers lacking light-dark() support. The @property initial-value remains hardcoded (CSS spec requirement) and only activates when absolutely no declaration exists. The :root mirror is the effective default and the actual user-customisable path. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu --- core/tokens.css | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/core/tokens.css b/core/tokens.css index 266db11c..a6b3ecfd 100644 --- a/core/tokens.css +++ b/core/tokens.css @@ -225,21 +225,23 @@ --sf-color-danger-light: oklch(0.48 0.22 12); } - /* Plain :root mirrors for computed tokens — same values as @property initial-value. - Required for engines lacking @property support AND light-dark() support. - Overridden by the @supports block below whenever light-dark() is available. */ + /* Plain :root mirrors for computed tokens — resolve to the -light source token + so user overrides to --sf-color-X-light are respected in all browsers. + Overridden by the @supports block below whenever light-dark() is available. + (@property initial-value is a hardcoded last resort per CSS spec; this + declaration is the effective default that picks up user customisation.) */ :root { - --sf-color-primary: oklch(0.47 0.27 264); - --sf-color-secondary: oklch(0.22 0.04 264); - --sf-color-tertiary: oklch(0.42 0.22 295); - --sf-color-action: oklch(0.50 0.22 235); - --sf-color-neutral: oklch(0.52 0.025 260); - --sf-color-base: oklch(0.96 0.006 250); - --sf-color-success: oklch(0.50 0.16 145); - --sf-color-warning: oklch(0.75 0.17 80); - --sf-color-error: oklch(0.50 0.20 25); - --sf-color-info: oklch(0.48 0.18 235); - --sf-color-danger: oklch(0.48 0.22 12); + --sf-color-primary: var(--sf-color-primary-light); + --sf-color-secondary: var(--sf-color-secondary-light); + --sf-color-tertiary: var(--sf-color-tertiary-light); + --sf-color-action: var(--sf-color-action-light); + --sf-color-neutral: var(--sf-color-neutral-light); + --sf-color-base: var(--sf-color-base-light); + --sf-color-success: var(--sf-color-success-light); + --sf-color-warning: var(--sf-color-warning-light); + --sf-color-error: var(--sf-color-error-light); + --sf-color-info: var(--sf-color-info-light); + --sf-color-danger: var(--sf-color-danger-light); } /* Mode flag — drives formula direction for non-color dark overrides. From 40e80d36a5a1207d5f1cf3cead01a2cb72d9ca93 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Jun 2026 10:39:29 +0000 Subject: [PATCH 4/9] fix(tokens): remove @property registration for computed color tokens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Registering --sf-color-* (computed tokens) as via @property caused child [data-theme="dark"] elements to inherit :root's resolved LIGHT color instead of computing the dark override. The typed property prevented var(--sf-color-X-dark, oklch(from var(--sf-color-X-light) ...)) from resolving correctly on child elements. Removing these @property blocks restores unregistered custom-property behavior: raw text inheritance, correct theme scoping on nested elements, and baseline tests matching raw light-dark()/oklch() text values. The -light source tokens keep their @property registration (needed for @property animation and typed transitions). Computed tokens are plain custom properties resolved by the :root mirrors block. Also fixes: - sf-equal 3-col layout: --sf-equal-min-col-3 18rem → 15rem (900px ÷ 3 fit) - overflow-x/overflow-inline ordering in .sf-prose .sf-not-prose table - Add .sf-cq demo to docs/demo.html (coverage test) - Update token-api snapshot: remove --sf-equal-cols, add new equal/radius tokens - Rebuild registry, dist badges, and all generated docs Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu --- .../src/data/api-index.generated.json | 198 ++++++++++--- core/macros.css | 2 +- core/tokens.css | 20 +- core/tokens.layout.css | 2 +- dist/badge-essential.json | 2 +- dist/badge-optimal.json | 2 +- docs/api-index.json | 279 ++++++++++++++---- docs/api-index.md | 56 ++-- docs/classes.md | 5 +- docs/demo.html | 8 + docs/registry.json | 12 +- docs/token-index.json | 58 +++- docs/token-index.md | 15 +- docs/tokens.md | 13 +- tests/token-api.snapshot.json | 7 +- 15 files changed, 514 insertions(+), 165 deletions(-) diff --git a/configurator/src/data/api-index.generated.json b/configurator/src/data/api-index.generated.json index 7c359144..abad5c3b 100644 --- a/configurator/src/data/api-index.generated.json +++ b/configurator/src/data/api-index.generated.json @@ -2,7 +2,7 @@ "_sync": { "generatedBy": "configurator/scripts/sync-api.mjs", "source": "docs/api-index.json", - "tokensHash": "cc745d997aa1", + "tokensHash": "5e8904b7dfd6", "bundles": [ "essential", "full", @@ -11,15 +11,15 @@ "optimal-utilities" ], "counts": { - "tokens": 823, + "tokens": 828, "byTier": { - "PUBLIC": 685, + "PUBLIC": 690, "PUBLIC-ADVANCED": 137, "INTERNAL": 1 }, "byCategory": { - "Layout tokens": 48, - "Core tokens": 495, + "Layout tokens": 52, + "Core tokens": 496, "Macro tokens": 24, "Component tokens": 6, "Palette tokens": 142, @@ -1705,8 +1705,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "Resolved color tokens", - "description": "High-level semantic color aliases. Each resolves to the matching palette source token and adapts automatically between light and dark mode. Start here when applying your brand palette.", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", "note": "Primary interactive color. Applied to filled buttons, active indicators, and brand accent surfaces.", "value": "light-dark(var(--sf-color-action-light), var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -2523,8 +2523,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "Resolved color tokens", - "description": "High-level semantic color aliases. Each resolves to the matching palette source token and adapts automatically between light and dark mode. Start here when applying your brand palette.", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", "note": "Secondary interactive color for supporting actions and secondary buttons.", "value": "light-dark(var(--sf-color-base-light), var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)))", "aliasOf": null, @@ -3701,8 +3701,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "Resolved color tokens", - "description": "High-level semantic color aliases. Each resolves to the matching palette source token and adapts automatically between light and dark mode. Start here when applying your brand palette.", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", "note": "Destructive / danger state color. Used for delete actions, error alerts, and critical warnings.", "value": "light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -3845,8 +3845,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "Resolved color tokens", - "description": "High-level semantic color aliases. Each resolves to the matching palette source token and adapts automatically between light and dark mode. Start here when applying your brand palette.", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", "note": "Form validation error color. Typically same hue as danger but can be tuned independently.", "value": "light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -3989,8 +3989,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "Resolved color tokens", - "description": "High-level semantic color aliases. Each resolves to the matching palette source token and adapts automatically between light and dark mode. Start here when applying your brand palette.", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", "note": "Informational color for neutral tips, hints, and non-urgent notices.", "value": "light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -4349,8 +4349,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "Resolved color tokens", - "description": "High-level semantic color aliases. Each resolves to the matching palette source token and adapts automatically between light and dark mode. Start here when applying your brand palette.", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", "note": "Neutral interactive color for low-emphasis actions and tertiary buttons.", "value": "light-dark(var(--sf-color-neutral-light), var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -5191,8 +5191,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "Resolved color tokens", - "description": "High-level semantic color aliases. Each resolves to the matching palette source token and adapts automatically between light and dark mode. Start here when applying your brand palette.", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", "note": "Raw primary palette token aliased from the action role by default. Override to decouple primary from action.", "value": "light-dark(var(--sf-color-primary-light), var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -6057,8 +6057,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "Resolved color tokens", - "description": "High-level semantic color aliases. Each resolves to the matching palette source token and adapts automatically between light and dark mode. Start here when applying your brand palette.", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", "note": "Raw secondary palette token for the secondary brand color.", "value": "light-dark(var(--sf-color-secondary-light), var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -6923,8 +6923,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "Resolved color tokens", - "description": "High-level semantic color aliases. Each resolves to the matching palette source token and adapts automatically between light and dark mode. Start here when applying your brand palette.", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", "note": "Positive / success color for confirmation messages and completed-state indicators.", "value": "light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -7067,8 +7067,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "Resolved color tokens", - "description": "High-level semantic color aliases. Each resolves to the matching palette source token and adapts automatically between light and dark mode. Start here when applying your brand palette.", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", "note": "Raw tertiary palette token for the third brand color.", "value": "light-dark(var(--sf-color-tertiary-light), var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -8341,8 +8341,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "Resolved color tokens", - "description": "High-level semantic color aliases. Each resolves to the matching palette source token and adapts automatically between light and dark mode. Start here when applying your brand palette.", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", "note": "Warning / caution color for non-critical alerts and degraded-state indicators.", "value": "light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -9392,15 +9392,39 @@ ] }, { - "name": "--sf-equal-cols", + "name": "--sf-equal-gap", + "tier": "PUBLIC", + "role": "consumption", + "namespace": "equal", + "category": "Layout tokens", + "group": "Equal columns (intrinsically responsive RAM)", + "description": "min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col.", + "note": "Gap between equal columns.", + "value": "var(--sf-space-gap)", + "aliasOf": "--sf-space-gap", + "registered": false, + "syntax": null, + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, + { + "name": "--sf-equal-min-col", "tier": "PUBLIC", "role": "knob", "namespace": "equal", "category": "Layout tokens", - "group": "Equal columns (fixed, non-responsive)", - "description": "Configuration for a fixed N-column equal-width layout.", - "note": "Number of columns in the fixed equal-column layout.", - "value": "2", + "group": "Equal columns (intrinsically responsive RAM)", + "description": "min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col.", + "note": "", + "value": "16rem", "aliasOf": null, "registered": false, "syntax": null, @@ -9416,16 +9440,88 @@ ] }, { - "name": "--sf-equal-gap", + "name": "--sf-equal-min-col-2", "tier": "PUBLIC", - "role": "consumption", + "role": "knob", "namespace": "equal", "category": "Layout tokens", - "group": "Equal columns (fixed, non-responsive)", - "description": "Configuration for a fixed N-column equal-width layout.", - "note": "Gap between equal columns.", - "value": "var(--sf-space-gap)", - "aliasOf": "--sf-space-gap", + "group": "Equal columns (intrinsically responsive RAM)", + "description": "min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col.", + "note": "", + "value": "28rem", + "aliasOf": null, + "registered": false, + "syntax": null, + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, + { + "name": "--sf-equal-min-col-3", + "tier": "PUBLIC", + "role": "knob", + "namespace": "equal", + "category": "Layout tokens", + "group": "Equal columns (intrinsically responsive RAM)", + "description": "min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col.", + "note": "", + "value": "15rem", + "aliasOf": null, + "registered": false, + "syntax": null, + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, + { + "name": "--sf-equal-min-col-4", + "tier": "PUBLIC", + "role": "knob", + "namespace": "equal", + "category": "Layout tokens", + "group": "Equal columns (intrinsically responsive RAM)", + "description": "min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col.", + "note": "", + "value": "16rem", + "aliasOf": null, + "registered": false, + "syntax": null, + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, + { + "name": "--sf-equal-min-col-6", + "tier": "PUBLIC", + "role": "knob", + "namespace": "equal", + "category": "Layout tokens", + "group": "Equal columns (intrinsically responsive RAM)", + "description": "min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col.", + "note": "", + "value": "10rem", + "aliasOf": null, "registered": false, "syntax": null, "fallbackOnly": false, @@ -13452,6 +13548,30 @@ "optimal-utilities" ] }, + { + "name": "--sf-radius-2xs", + "tier": "PUBLIC", + "role": "consumption", + "namespace": "radius", + "category": "Core tokens", + "group": "Border radius", + "description": "Border-radius scale from xs hairline to full circle. Stick to this scale so UI elements share a consistent curvature language.", + "note": "", + "value": "calc(1px * var(--sf-radius-scale))", + "aliasOf": null, + "registered": false, + "syntax": null, + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-radius-3xl", "tier": "PUBLIC", diff --git a/core/macros.css b/core/macros.css index 5763240e..ddd4e231 100644 --- a/core/macros.css +++ b/core/macros.css @@ -72,7 +72,7 @@ .sf-prose .sf-not-prose img { margin-block: 0; border-radius: 0; } .sf-prose .sf-not-prose figure { margin-block: 0; } .sf-prose .sf-not-prose figcaption { font-size: inherit; color: inherit; margin-block-start: 0; } - .sf-prose .sf-not-prose table { margin-block: 0; display: revert; overflow-inline: revert; inline-size: revert; max-inline-size: revert; } + .sf-prose .sf-not-prose table { margin-block: 0; display: revert; overflow-x: revert; overflow-inline: revert; inline-size: revert; max-inline-size: revert; } .sf-prose .sf-not-prose :is(th,td) { padding: revert; } .sf-prose .sf-not-prose video { margin-block: 0; border-radius: 0; } diff --git a/core/tokens.css b/core/tokens.css index a6b3ecfd..b5a5d998 100644 --- a/core/tokens.css +++ b/core/tokens.css @@ -192,22 +192,6 @@ @property --sf-color-info-light { syntax: ""; inherits: true; initial-value: oklch(0.48 0.18 235); } @property --sf-color-danger-light { syntax: ""; inherits: true; initial-value: oklch(0.48 0.22 12); } - /* @property — COMPUTED COLOR TOKENS (brand + status) - initial-value = light-mode value. Acts as a valid fallback when - light-dark() is unsupported (the @supports block below won't apply). - User overrides to --sf-color-X or --sf-color-X-light always win. */ - @property --sf-color-primary { syntax: ""; inherits: true; initial-value: oklch(0.47 0.27 264); } - @property --sf-color-secondary { syntax: ""; inherits: true; initial-value: oklch(0.22 0.04 264); } - @property --sf-color-tertiary { syntax: ""; inherits: true; initial-value: oklch(0.42 0.22 295); } - @property --sf-color-action { syntax: ""; inherits: true; initial-value: oklch(0.50 0.22 235); } - @property --sf-color-neutral { syntax: ""; inherits: true; initial-value: oklch(0.52 0.025 260); } - @property --sf-color-base { syntax: ""; inherits: true; initial-value: oklch(0.96 0.006 250); } - @property --sf-color-success { syntax: ""; inherits: true; initial-value: oklch(0.50 0.16 145); } - @property --sf-color-warning { syntax: ""; inherits: true; initial-value: oklch(0.75 0.17 80); } - @property --sf-color-error { syntax: ""; inherits: true; initial-value: oklch(0.50 0.20 25); } - @property --sf-color-info { syntax: ""; inherits: true; initial-value: oklch(0.48 0.18 235); } - @property --sf-color-danger { syntax: ""; inherits: true; initial-value: oklch(0.48 0.22 12); } - /* Plain :root mirrors — character-for-character identical to each @property initial-value above. Engines lacking @property support read the token value from here. Do NOT edit these independently from the initial-value strings. */ @@ -227,9 +211,7 @@ /* Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. - Overridden by the @supports block below whenever light-dark() is available. - (@property initial-value is a hardcoded last resort per CSS spec; this - declaration is the effective default that picks up user customisation.) */ + Overridden by the @supports block below whenever light-dark() is available. */ :root { --sf-color-primary: var(--sf-color-primary-light); --sf-color-secondary: var(--sf-color-secondary-light); diff --git a/core/tokens.layout.css b/core/tokens.layout.css index cb1f877b..8339be42 100644 --- a/core/tokens.layout.css +++ b/core/tokens.layout.css @@ -94,7 +94,7 @@ ---------------------------------------------------------- */ --sf-equal-min-col: 16rem; --sf-equal-min-col-2: 28rem; - --sf-equal-min-col-3: 18rem; + --sf-equal-min-col-3: 15rem; --sf-equal-min-col-4: 16rem; --sf-equal-min-col-6: 10rem; --sf-equal-gap: var(--sf-space-gap); diff --git a/dist/badge-essential.json b/dist/badge-essential.json index b044f499..213d802a 100644 --- a/dist/badge-essential.json +++ b/dist/badge-essential.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "label": "essential", - "message": "55.0 kB gzip", + "message": "15.9 kB gzip", "color": "brightgreen", "namedLogo": "css3" } diff --git a/dist/badge-optimal.json b/dist/badge-optimal.json index 4a139e09..a8166dce 100644 --- a/dist/badge-optimal.json +++ b/dist/badge-optimal.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "label": "optimal", - "message": "65.9 kB gzip", + "message": "19.7 kB gzip", "color": "brightgreen", "namedLogo": "css3" } diff --git a/docs/api-index.json b/docs/api-index.json index c7f98664..dfd6e258 100644 --- a/docs/api-index.json +++ b/docs/api-index.json @@ -29,31 +29,31 @@ "optimal-utilities" ], "counts": { - "total": 1051, + "total": 1057, "by_type": { - "class": 228, - "token": 823 + "class": 229, + "token": 828 }, "by_tier": { "INTERNAL": 1, - "PUBLIC": 913, + "PUBLIC": 919, "PUBLIC-ADVANCED": 137 }, "by_role": { - "consumption": 591, - "knob": 232 + "consumption": 592, + "knob": 236 }, - "tokens": 823, - "classes": 228, - "sf_classes": 179, + "tokens": 828, + "classes": 229, + "sf_classes": 180, "is_classes": 40, "unprefixed_classes": 9, "by_category": { "Accessibility": 7, "Component tokens": 6, - "Core tokens": 495, - "Layout primitives": 125, - "Layout tokens": 48, + "Core tokens": 496, + "Layout primitives": 126, + "Layout tokens": 52, "Macro classes": 36, "Macro tokens": 24, "Motion / animation": 15, @@ -2121,8 +2121,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "Resolved color tokens", - "description": "auto-switch via light-dark(). 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…", + "group": "STATUS COLORS (-light source tokens)", + "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", "value": "light-dark(var(--sf-color-action-light), var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, "registered": false, @@ -3120,8 +3120,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "Resolved color tokens", - "description": "auto-switch via light-dark(). 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…", + "group": "STATUS COLORS (-light source tokens)", + "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", "value": "light-dark(var(--sf-color-base-light), var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)))", "aliasOf": null, "registered": false, @@ -4554,8 +4554,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "Resolved color tokens", - "description": "auto-switch via light-dark(). 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…", + "group": "STATUS COLORS (-light source tokens)", + "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", "value": "light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, "registered": false, @@ -4728,8 +4728,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "Resolved color tokens", - "description": "auto-switch via light-dark(). 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…", + "group": "STATUS COLORS (-light source tokens)", + "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", "value": "light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, "registered": false, @@ -4902,8 +4902,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "Resolved color tokens", - "description": "auto-switch via light-dark(). 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…", + "group": "STATUS COLORS (-light source tokens)", + "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", "value": "light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, "registered": false, @@ -5337,8 +5337,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "Resolved color tokens", - "description": "auto-switch via light-dark(). 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…", + "group": "STATUS COLORS (-light source tokens)", + "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", "value": "light-dark(var(--sf-color-neutral-light), var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, "registered": false, @@ -6365,8 +6365,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "Resolved color tokens", - "description": "auto-switch via light-dark(). 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…", + "group": "STATUS COLORS (-light source tokens)", + "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", "value": "light-dark(var(--sf-color-primary-light), var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, "registered": false, @@ -7422,8 +7422,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "Resolved color tokens", - "description": "auto-switch via light-dark(). 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…", + "group": "STATUS COLORS (-light source tokens)", + "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", "value": "light-dark(var(--sf-color-secondary-light), var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, "registered": false, @@ -8479,8 +8479,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "Resolved color tokens", - "description": "auto-switch via light-dark(). 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…", + "group": "STATUS COLORS (-light source tokens)", + "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", "value": "light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, "registered": false, @@ -8653,8 +8653,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "Resolved color tokens", - "description": "auto-switch via light-dark(). 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…", + "group": "STATUS COLORS (-light source tokens)", + "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", "value": "light-dark(var(--sf-color-tertiary-light), var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, "registered": false, @@ -10203,8 +10203,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "Resolved color tokens", - "description": "auto-switch via light-dark(). 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…", + "group": "STATUS COLORS (-light source tokens)", + "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", "value": "light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, "registered": false, @@ -11472,16 +11472,45 @@ ] }, { - "name": "--sf-equal-cols", + "name": "--sf-equal-gap", + "type": "token", + "tier": "PUBLIC", + "role": "consumption", + "namespace": "equal", + "category": "Layout tokens", + "area": "layout", + "group": "Equal columns (intrinsically responsive RAM)", + "description": "min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col.", + "value": "var(--sf-space-gap)", + "aliasOf": "--sf-space-gap", + "registered": false, + "animatable": false, + "syntax": null, + "inherits": null, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.layout.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, + { + "name": "--sf-equal-min-col", "type": "token", "tier": "PUBLIC", "role": "knob", "namespace": "equal", "category": "Layout tokens", "area": "layout", - "group": "Equal columns (fixed, non-responsive)", - "description": "Equal columns (fixed, non-responsive)", - "value": "2", + "group": "Equal columns (intrinsically responsive RAM)", + "description": "min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col.", + "value": "16rem", "aliasOf": null, "registered": false, "animatable": false, @@ -11501,17 +11530,104 @@ ] }, { - "name": "--sf-equal-gap", + "name": "--sf-equal-min-col-2", "type": "token", "tier": "PUBLIC", - "role": "consumption", + "role": "knob", "namespace": "equal", "category": "Layout tokens", "area": "layout", - "group": "Equal columns (fixed, non-responsive)", - "description": "Equal columns (fixed, non-responsive)", - "value": "var(--sf-space-gap)", - "aliasOf": "--sf-space-gap", + "group": "Equal columns (intrinsically responsive RAM)", + "description": "min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col.", + "value": "28rem", + "aliasOf": null, + "registered": false, + "animatable": false, + "syntax": null, + "inherits": null, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.layout.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, + { + "name": "--sf-equal-min-col-3", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "equal", + "category": "Layout tokens", + "area": "layout", + "group": "Equal columns (intrinsically responsive RAM)", + "description": "min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col.", + "value": "15rem", + "aliasOf": null, + "registered": false, + "animatable": false, + "syntax": null, + "inherits": null, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.layout.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, + { + "name": "--sf-equal-min-col-4", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "equal", + "category": "Layout tokens", + "area": "layout", + "group": "Equal columns (intrinsically responsive RAM)", + "description": "min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col.", + "value": "16rem", + "aliasOf": null, + "registered": false, + "animatable": false, + "syntax": null, + "inherits": null, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.layout.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, + { + "name": "--sf-equal-min-col-6", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "equal", + "category": "Layout tokens", + "area": "layout", + "group": "Equal columns (intrinsically responsive RAM)", + "description": "min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col.", + "value": "10rem", + "aliasOf": null, "registered": false, "animatable": false, "syntax": null, @@ -16382,6 +16498,35 @@ "optimal-utilities" ] }, + { + "name": "--sf-radius-2xs", + "type": "token", + "tier": "PUBLIC", + "role": "consumption", + "namespace": "radius", + "category": "Core tokens", + "area": "core", + "group": "Border radius", + "description": "--sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to…", + "value": "calc(1px * var(--sf-radius-scale))", + "aliasOf": null, + "registered": false, + "animatable": false, + "syntax": null, + "inherits": null, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-radius-3xl", "type": "token", @@ -25990,6 +26135,32 @@ "optimal-utilities" ] }, + { + "name": "sf-cq", + "type": "class", + "tier": "PUBLIC", + "selector": ".sf-cq", + "prefix": "sf", + "kind": "layout", + "category": "Layout primitives", + "area": "layout", + "group": "Container query context", + "description": "Lightweight CQ scope. Establishes container-type: inline-size so anonymous @container queries on descendants respond to THIS element's width — without the max-width and centering of .sf-container. No visual styles. Use when .sf-container is not available in the ancestor tree…", + "isVariant": false, + "baseClass": null, + "optional": false, + "layer": "slashed.layout", + "sourceFiles": [ + "core/layout.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "sf-divider", "type": "class", @@ -26337,8 +26508,8 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Fixed columns", - "description": "Fixed N-column grid. Column count NEVER collapses — unlike .sf-grid-cols-N which stacks at narrow container widths. Use when the layout must stay N columns at all widths; the caller is responsible for overflow handling. Override: style=\"--sf-equal-cols: 3\"", + "group": "Equal columns (intrinsically responsive)", + "description": "RAM-pattern grid (Repeat, Auto-fit, Minmax). Columns wrap automatically when they would shrink below --sf-equal-min-col. No container ancestor required — intrinsically responsive. Modifiers set the target min-col width for ~N equal columns at typical container widths; exact…", "isVariant": false, "baseClass": null, "optional": false, @@ -26363,8 +26534,8 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Fixed columns", - "description": "Fixed N-column grid. Column count NEVER collapses — unlike .sf-grid-cols-N which stacks at narrow container widths. Use when the layout must stay N columns at all widths; the caller is responsible for overflow handling. Override: style=\"--sf-equal-cols: 3\"", + "group": "Equal columns (intrinsically responsive)", + "description": "RAM-pattern grid (Repeat, Auto-fit, Minmax). Columns wrap automatically when they would shrink below --sf-equal-min-col. No container ancestor required — intrinsically responsive. Modifiers set the target min-col width for ~N equal columns at typical container widths; exact…", "isVariant": true, "baseClass": "sf-equal", "optional": false, @@ -26389,8 +26560,8 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Fixed columns", - "description": "Fixed N-column grid. Column count NEVER collapses — unlike .sf-grid-cols-N which stacks at narrow container widths. Use when the layout must stay N columns at all widths; the caller is responsible for overflow handling. Override: style=\"--sf-equal-cols: 3\"", + "group": "Equal columns (intrinsically responsive)", + "description": "RAM-pattern grid (Repeat, Auto-fit, Minmax). Columns wrap automatically when they would shrink below --sf-equal-min-col. No container ancestor required — intrinsically responsive. Modifiers set the target min-col width for ~N equal columns at typical container widths; exact…", "isVariant": true, "baseClass": "sf-equal", "optional": false, @@ -26415,8 +26586,8 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Fixed columns", - "description": "Fixed N-column grid. Column count NEVER collapses — unlike .sf-grid-cols-N which stacks at narrow container widths. Use when the layout must stay N columns at all widths; the caller is responsible for overflow handling. Override: style=\"--sf-equal-cols: 3\"", + "group": "Equal columns (intrinsically responsive)", + "description": "RAM-pattern grid (Repeat, Auto-fit, Minmax). Columns wrap automatically when they would shrink below --sf-equal-min-col. No container ancestor required — intrinsically responsive. Modifiers set the target min-col width for ~N equal columns at typical container widths; exact…", "isVariant": true, "baseClass": "sf-equal", "optional": false, @@ -26441,8 +26612,8 @@ "kind": "layout", "category": "Layout primitives", "area": "layout", - "group": "Fixed columns", - "description": "Fixed N-column grid. Column count NEVER collapses — unlike .sf-grid-cols-N which stacks at narrow container widths. Use when the layout must stay N columns at all widths; the caller is responsible for overflow handling. Override: style=\"--sf-equal-cols: 3\"", + "group": "Equal columns (intrinsically responsive)", + "description": "RAM-pattern grid (Repeat, Auto-fit, Minmax). Columns wrap automatically when they would shrink below --sf-equal-min-col. No container ancestor required — intrinsically responsive. Modifiers set the target min-col width for ~N equal columns at typical container widths; exact…", "isVariant": true, "baseClass": "sf-equal", "optional": false, diff --git a/docs/api-index.md b/docs/api-index.md index 78275e54..f1debc01 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). -**1051 elements** — 823 tokens, 228 classes. +**1057 elements** — 828 tokens, 229 classes. | Tier | Count | Meaning | |---|---|---| -| PUBLIC | 913 | Everyday surface. SemVer-stable. | +| PUBLIC | 919 | Everyday surface. SemVer-stable. | | PUBLIC-ADVANCED | 137 | Same SemVer guarantee; niche/powerful. | | INTERNAL | 1 | Implementation detail; may change without a major bump. | -## Tokens (823) +## Tokens (828) ### Component tokens (6) @@ -31,7 +31,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-field-padding-inline` | PUBLIC | consumption | field | `var(--sf-space-s)` | Override to give form fields a distinct visual language from buttons without touching global radius/spacing tokens. | | `--sf-field-radius` | PUBLIC | consumption | field | `var(--sf-radius-m)` | Override to give form fields a distinct visual language from buttons without touching global radius/spacing tokens. | -### Core tokens (495) +### Core tokens (496) | Token | Tier | Role | Namespace | Default | Description | |---|---|---|---|---|---| @@ -85,7 +85,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-col-width-l` | PUBLIC | knob | col | `32ch` | tokens for the `columns` layout property. column-width is ch-based (character units) so columns maintain a comfortable reading measure regardless of font-size. | | `--sf-col-width-m` | PUBLIC | knob | col | `24ch` | tokens for the `columns` layout property. column-width is ch-based (character units) so columns maintain a comfortable reading measure regardless of font-size. | | `--sf-col-width-s` | PUBLIC | knob | col | `16ch` | tokens for the `columns` layout property. column-width is ch-based (character units) so columns maintain a comfortable reading measure regardless of font-size. | -| `--sf-color-action` | PUBLIC | consumption | color | `light-dark(var(--sf-color-action-light), var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | auto-switch via light-dark(). 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… | +| `--sf-color-action` | PUBLIC | consumption | color | `light-dark(var(--sf-color-action-light), var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | | `--sf-color-action--active` | PUBLIC | consumption | color | `var(--sf-color-action-xdark)` | action | | `--sf-color-action--hover` | PUBLIC | consumption | color | `var(--sf-color-action-darker)` | action | | `--sf-color-action-darker` | PUBLIC | consumption | color | `var(--sf-color-action-600)` | action | @@ -98,7 +98,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-action-superlight` | PUBLIC | consumption | color | `var(--sf-color-action-50)` | action | | `--sf-color-action-xdark` | PUBLIC | consumption | color | `var(--sf-color-action-800)` | action | | `--sf-color-action-xlight` | PUBLIC | consumption | color | `var(--sf-color-action-200)` | action | -| `--sf-color-base` | PUBLIC | consumption | color | `light-dark(var(--sf-color-base-light), var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)))` | auto-switch via light-dark(). 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… | +| `--sf-color-base` | PUBLIC | consumption | color | `light-dark(var(--sf-color-base-light), var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | | `--sf-color-base--active` | PUBLIC | consumption | color | `var(--sf-color-base-xdark)` | base | | `--sf-color-base--hover` | PUBLIC | consumption | color | `var(--sf-color-base-darker)` | base | | `--sf-color-base-darker` | PUBLIC | consumption | color | `var(--sf-color-base-600)` | base | @@ -126,19 +126,19 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-border--translucent` | PUBLIC | consumption | color | `oklch(from var(--sf-color-neutral) l c h / 0.15)` | Border alpha tokens | | `--sf-color-code-bg` | PUBLIC | consumption | color | `var(--sf-color-inset)` | plain var aliases (ungated) | | `--sf-color-code-text` | PUBLIC | consumption | color | `oklch(from var(--sf-color-code-bg) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0)` | Inline-code text colour. Auto-contrasts with --sf-color-code-bg using the same luminance formula as --sf-color-text--on-*. This prevents invisible text when code appears inside inverted-colour containers (e.g. sf-imposter with a dark background where inherited colour is… | -| `--sf-color-danger` | PUBLIC | consumption | color | `light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | auto-switch via light-dark(). 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… | +| `--sf-color-danger` | PUBLIC | consumption | color | `light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | | `--sf-color-danger-light` | PUBLIC | knob | color | `oklch(0.48 0.22 12)` | STATUS COLORS (-light source tokens) | | `--sf-color-danger-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-danger) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-danger-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-danger-light) calc(l - 0.1) c h), oklch(from var(--sf-color-danger) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | | `--sf-color-danger-subtle` | PUBLIC | consumption | color | `oklch(from var(--sf-color-danger) l c h / 0.1)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-dim` | PUBLIC | knob | color | `oklch(0 0 0 / 0.5)` | Dim: classic semi-transparent black for modal backdrops, distinct from --sf-color-overlay | -| `--sf-color-error` | PUBLIC | consumption | color | `light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | auto-switch via light-dark(). 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… | +| `--sf-color-error` | PUBLIC | consumption | color | `light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | | `--sf-color-error-light` | PUBLIC | knob | color | `oklch(0.50 0.20 25)` | STATUS COLORS (-light source tokens) | | `--sf-color-error-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-error) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-error-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-error-light) calc(l - 0.1) c h), oklch(from var(--sf-color-error) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | | `--sf-color-error-subtle` | PUBLIC | consumption | color | `oklch(from var(--sf-color-error) l c h / 0.1)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-heading` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.05, calc(l - 0.4 - var(--sf-contrast-bias)), 0.35) c h), oklch(from var(--sf-color-neutral) clamp(0.70, calc(l + 0.25 + var(--sf-contrast-bias)), 1) c h) )` | light and dark require opposite formula directions, so each side of light-dark() references its source token. | -| `--sf-color-info` | PUBLIC | consumption | color | `light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | auto-switch via light-dark(). 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… | +| `--sf-color-info` | PUBLIC | consumption | color | `light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | | `--sf-color-info-light` | PUBLIC | knob | color | `oklch(0.48 0.18 235)` | STATUS COLORS (-light source tokens) | | `--sf-color-info-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-info) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-info-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-info-light) calc(l - 0.1) c h), oklch(from var(--sf-color-info) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | @@ -153,7 +153,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-link--visited` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-action) clamp(0, min(l - 0.07, 0.48), 1) c calc(h + 60)), oklch(from var(--sf-color-action) clamp(0.68, l, 1) c calc(h + 60)) )` | Visited link — 60° hue shift from action gives clearly distinct chroma without colliding with default tertiary (h ≈ 310). Same lightness clamp as the base link. If your brand puts action and tertiary close in hue, override directly: :root { --sf-color-link--visited: #6b46c1; } | | `--sf-color-mark-bg` | PUBLIC | consumption | color | `oklch(from var(--sf-color-warning) l c h / 0.25)` | Selection & mark | | `--sf-color-mark-text` | PUBLIC | knob | color | `inherit` | static values (ungated) | -| `--sf-color-neutral` | PUBLIC | consumption | color | `light-dark(var(--sf-color-neutral-light), var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | auto-switch via light-dark(). 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… | +| `--sf-color-neutral` | PUBLIC | consumption | color | `light-dark(var(--sf-color-neutral-light), var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | | `--sf-color-neutral--active` | PUBLIC | consumption | color | `var(--sf-color-neutral-xdark)` | neutral | | `--sf-color-neutral--hover` | PUBLIC | consumption | color | `var(--sf-color-neutral-darker)` | neutral | | `--sf-color-neutral-darker` | PUBLIC | consumption | color | `var(--sf-color-neutral-600)` | neutral | @@ -167,7 +167,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-neutral-xdark` | PUBLIC | consumption | color | `var(--sf-color-neutral-800)` | neutral | | `--sf-color-neutral-xlight` | PUBLIC | consumption | color | `var(--sf-color-neutral-200)` | neutral | | `--sf-color-overlay` | PUBLIC | consumption | color | `oklch(from var(--sf-color-base) l c h / 0.9)` | Overlay: high-opacity wash of the base color for light/dark mode safe layers | -| `--sf-color-primary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-primary-light), var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | auto-switch via light-dark(). 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… | +| `--sf-color-primary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-primary-light), var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | | `--sf-color-primary--active` | PUBLIC | consumption | color | `var(--sf-color-primary-xdark)` | primary | | `--sf-color-primary--hover` | PUBLIC | consumption | color | `var(--sf-color-primary-darker)` | primary | | `--sf-color-primary-darker` | PUBLIC | consumption | color | `var(--sf-color-primary-600)` | primary | @@ -182,7 +182,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-primary-xlight` | PUBLIC | consumption | color | `var(--sf-color-primary-200)` | primary | | `--sf-color-raised` | PUBLIC | consumption | color | `oklch(from var(--sf-color-base) calc(l + 0.04) c h)` | derived from --sf-color-base (auto-adapts) | | `--sf-color-scheme` | PUBLIC | knob | color | `light dark` | Color scheme | -| `--sf-color-secondary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-secondary-light), var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | auto-switch via light-dark(). 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… | +| `--sf-color-secondary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-secondary-light), var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | | `--sf-color-secondary--active` | PUBLIC | consumption | color | `var(--sf-color-secondary-xdark)` | secondary | | `--sf-color-secondary--hover` | PUBLIC | consumption | color | `var(--sf-color-secondary-darker)` | secondary | | `--sf-color-secondary-darker` | PUBLIC | consumption | color | `var(--sf-color-secondary-600)` | secondary | @@ -197,13 +197,13 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-secondary-xlight` | PUBLIC | consumption | color | `var(--sf-color-secondary-200)` | secondary | | `--sf-color-selection-bg` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-action-light) l c h / 0.28), oklch(from var(--sf-color-action-light) clamp(0.62, calc(0.93 - l * 0.4), 0.78) c h / 0.55) )` | Selection | | `--sf-color-selection-text` | PUBLIC | knob | color | `inherit` | static values (ungated) | -| `--sf-color-success` | PUBLIC | consumption | color | `light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | auto-switch via light-dark(). 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… | +| `--sf-color-success` | PUBLIC | consumption | color | `light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | | `--sf-color-success-light` | PUBLIC | knob | color | `oklch(0.50 0.16 145)` | STATUS COLORS (-light source tokens) | | `--sf-color-success-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-success) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-success-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-success-light) calc(l - 0.15) c h), oklch(from var(--sf-color-success) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | | `--sf-color-success-subtle` | PUBLIC | consumption | color | `oklch(from var(--sf-color-success) l c h / 0.12)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-surface` | PUBLIC | consumption | color | `var(--sf-color-base)` | Surface alias (plain var — no IACVT, stays ungated) | -| `--sf-color-tertiary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-tertiary-light), var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | auto-switch via light-dark(). 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… | +| `--sf-color-tertiary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-tertiary-light), var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | | `--sf-color-tertiary--active` | PUBLIC | consumption | color | `var(--sf-color-tertiary-xdark)` | tertiary | | `--sf-color-tertiary--hover` | PUBLIC | consumption | color | `var(--sf-color-tertiary-darker)` | tertiary | | `--sf-color-tertiary-darker` | PUBLIC | consumption | color | `var(--sf-color-tertiary-600)` | tertiary | @@ -235,7 +235,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-text--on-warning` | PUBLIC | consumption | color | `oklch(from var(--sf-color-warning) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0)` | sign(var(--sf-contrast-threshold) - l) * 999 is mode-agnostic: auto-selects light or dark text based on background luminance. Uses resolved tokens — works for any user-supplied color. CONTRAST NOTE: Guarantees ≥ 3:1 (WCAG AA Large Text / UI). Colors in the mid-luminance range… | | `--sf-color-text--placeholder` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.45, calc(l + 0.15), 0.75) c h), oklch(from var(--sf-color-neutral) clamp(0.35, calc(l - 0.1), 0.65) c h) )` | light and dark require opposite formula directions, so each side of light-dark() references its source token. | | `--sf-color-text--secondary` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.15, calc(l - 0.25 - var(--sf-contrast-bias)), 0.45) c h), oklch(from var(--sf-color-neutral) clamp(0.55, calc(l + 0.1 + var(--sf-contrast-bias)), 0.90) c h) )` | light and dark require opposite formula directions, so each side of light-dark() references its source token. | -| `--sf-color-warning` | PUBLIC | consumption | color | `light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | auto-switch via light-dark(). 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… | +| `--sf-color-warning` | PUBLIC | consumption | color | `light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | | `--sf-color-warning-light` | PUBLIC | knob | color | `oklch(0.75 0.17 80)` | STATUS COLORS (-light source tokens) | | `--sf-color-warning-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-warning) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-warning-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-warning-light) calc(l - 0.25) c h), oklch(from var(--sf-color-warning) clamp(0.70, calc(l + 0.05), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | @@ -399,6 +399,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-print-page-margin` | PUBLIC-ADVANCED | knob | print | `2cm` | Print | | `--sf-print-page-size` | PUBLIC-ADVANCED | knob | print | `a4` | Print | | `--sf-radius-2xl` | PUBLIC | consumption | radius | `calc(24px * var(--sf-radius-scale))` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | +| `--sf-radius-2xs` | PUBLIC | consumption | radius | `calc(1px * var(--sf-radius-scale))` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | | `--sf-radius-3xl` | PUBLIC | consumption | radius | `calc(32px * var(--sf-radius-scale))` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | | `--sf-radius-4xl` | PUBLIC | consumption | radius | `calc(48px * var(--sf-radius-scale))` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | | `--sf-radius-full` | PUBLIC | knob | radius | `9999px` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | @@ -531,7 +532,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-z-toast` | PUBLIC | consumption | z | `var(--sf-z-top)` | 500 menus — clear sticky + fixed | | `--sf-z-top` | PUBLIC | knob | z | `900` | Z-index | -### Layout tokens (48) +### Layout tokens (52) | Token | Tier | Role | Namespace | Default | Description | |---|---|---|---|---|---| @@ -554,8 +555,12 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-content-width` | PUBLIC | consumption | content | `var(--sf-container-default)` | Content grid (breakout pattern) | | `--sf-cover-min-height` | PUBLIC | knob | cover | `100dvh` | Cover | | `--sf-cover-padding` | PUBLIC | consumption | cover | `var(--sf-section-pad)` | Cover | -| `--sf-equal-cols` | PUBLIC | knob | equal | `2` | Equal columns (fixed, non-responsive) | -| `--sf-equal-gap` | PUBLIC | consumption | equal | `var(--sf-space-gap)` | Equal columns (fixed, non-responsive) | +| `--sf-equal-gap` | PUBLIC | consumption | equal | `var(--sf-space-gap)` | min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col. | +| `--sf-equal-min-col` | PUBLIC | knob | equal | `16rem` | min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col. | +| `--sf-equal-min-col-2` | PUBLIC | knob | equal | `28rem` | min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col. | +| `--sf-equal-min-col-3` | PUBLIC | knob | equal | `15rem` | min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col. | +| `--sf-equal-min-col-4` | PUBLIC | knob | equal | `16rem` | min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col. | +| `--sf-equal-min-col-6` | PUBLIC | knob | equal | `10rem` | min-col-N: minimum column width for the N-column preset. Exact column count emerges from container ÷ min-col. | | `--sf-frame-ratio` | PUBLIC | knob | frame | `16 / 9` | Frame | | `--sf-gap-size` | PUBLIC | consumption | gap | `var(--sf-space-gap)` | Gap | | `--sf-grid-gap` | PUBLIC | consumption | grid | `var(--sf-space-gap)` | Grid (auto-fill, breakpoint-free) | @@ -873,7 +878,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-text-xs-max-width` | PUBLIC | knob | text | `60ch` | Override knobs for each body text size step. Defaults encode standard typographic conventions; override any value globally here or locally via CSS custom property on a scoped element. These tokens are NOT auto-applied — they are opt-in composable overrides. Wire them up in your… | | `--sf-text-xs-to-2xs` | PUBLIC-ADVANCED | consumption | text | `clamp(calc(var(--sf-text-base-min) * pow(var(--sf-text-ratio-min), -3) * 1rem), calc((var(--sf-text-base-max) * pow(var(--sf-text-ratio-max), -2) - var(--sf-text-base-min) * pow(var(--sf-text-ratio-min), -3)) / (var(--sf-fluid-max-vw) - var(--sf-fluid-min-vw)) * (100vw - var(--sf-fluid-min-vw) * 1rem) + var(--sf-text-base-min) * pow(var(--sf-text-ratio-min), -3) * 1rem), calc(var(--sf-text-base-max) * pow(var(--sf-text-ratio-max), -2) * 1rem))` | Full descending matrix: --sf-text-{larger}-to-{smaller} No --sf-text-scale multiplier — consistent with how the base text tokens are consumed by the text-bridge contract. | -## Classes (228) +## Classes (229) ### Accessibility (7) @@ -887,7 +892,7 @@ and a short description. The machine-readable companion (with all columns) is | `.sr-only` | PUBLIC | accessibility | Screen-reader-only. Atomic contract: a partial override | either exposes hidden content visually or hides intended content. All-or-nothing, so the whole set is hardened. | | `.sr-only-focusable` | PUBLIC | accessibility | Screen-reader-only. Atomic contract: a partial override | either exposes hidden content visually or hides intended content. All-or-nothing, so the whole set is hardened. | -### Layout primitives (125) +### Layout primitives (126) | Class | Tier | Kind | Group | Description | |---|---|---|---|---| @@ -929,6 +934,7 @@ and a short description. The machine-readable companion (with all columns) is | `.sf-cover--min` | PUBLIC | layout | Cover | Full-height flex column. A .sf-cover__center child is vertically centered via margin-block: auto. Override: style="--sf-cover-min-height: 50dvh" | | `.sf-cover--padding-l` | PUBLIC | layout | Cover | --max intentionally sets min-height: 0 to override .sf-cover's token-driven minimum — the cover may collapse below the default min if content is short. Pair with padding-block or a min-content guard if collapsing is undesirable. | | `.sf-cover--padding-s` | PUBLIC | layout | Cover | --max intentionally sets min-height: 0 to override .sf-cover's token-driven minimum — the cover may collapse below the default min if content is short. Pair with padding-block or a min-content guard if collapsing is undesirable. | +| `.sf-cq` | PUBLIC | layout | Container query context | Lightweight CQ scope. Establishes container-type: inline-size so anonymous @container queries on descendants respond to THIS element's width — without the max-width and centering of .sf-container. No visual styles. Use when .sf-container is not available in the ancestor tree… | | `.sf-divider` | PUBLIC | layout | Divider | Standalone separator primitive. Token-driven; pairs with the `--sf-divider-*` tokens and mirrors the `hr` element default. | | `.sf-divider--dashed` | PUBLIC | layout | Divider | Style modifiers — retune the line itself via the same tokens the base rule reads, so they apply to horizontal and vertical alike. | | `.sf-divider--dotted` | PUBLIC | layout | Divider | Style modifiers — retune the line itself via the same tokens the base rule reads, so they apply to horizontal and vertical alike. | @@ -936,11 +942,11 @@ and a short description. The machine-readable companion (with all columns) is | `.sf-divider--soft` | PUBLIC | layout | Divider | Style modifiers — retune the line itself via the same tokens the base rule reads, so they apply to horizontal and vertical alike. | | `.sf-divider--strong` | PUBLIC | layout | Divider | Style modifiers — retune the line itself via the same tokens the base rule reads, so they apply to horizontal and vertical alike. | | `.sf-divider--vertical` | PUBLIC | layout | Divider | Standalone separator primitive. Token-driven; pairs with the `--sf-divider-*` tokens and mirrors the `hr` element default. | -| `.sf-equal` | PUBLIC | layout | Fixed columns | Fixed N-column grid. Column count NEVER collapses — unlike .sf-grid-cols-N which stacks at narrow container widths. Use when the layout must stay N columns at all widths; the caller is responsible for overflow handling. Override: style="--sf-equal-cols: 3" | -| `.sf-equal--2` | PUBLIC | layout | Fixed columns | Fixed N-column grid. Column count NEVER collapses — unlike .sf-grid-cols-N which stacks at narrow container widths. Use when the layout must stay N columns at all widths; the caller is responsible for overflow handling. Override: style="--sf-equal-cols: 3" | -| `.sf-equal--3` | PUBLIC | layout | Fixed columns | Fixed N-column grid. Column count NEVER collapses — unlike .sf-grid-cols-N which stacks at narrow container widths. Use when the layout must stay N columns at all widths; the caller is responsible for overflow handling. Override: style="--sf-equal-cols: 3" | -| `.sf-equal--4` | PUBLIC | layout | Fixed columns | Fixed N-column grid. Column count NEVER collapses — unlike .sf-grid-cols-N which stacks at narrow container widths. Use when the layout must stay N columns at all widths; the caller is responsible for overflow handling. Override: style="--sf-equal-cols: 3" | -| `.sf-equal--6` | PUBLIC | layout | Fixed columns | Fixed N-column grid. Column count NEVER collapses — unlike .sf-grid-cols-N which stacks at narrow container widths. Use when the layout must stay N columns at all widths; the caller is responsible for overflow handling. Override: style="--sf-equal-cols: 3" | +| `.sf-equal` | PUBLIC | layout | Equal columns (intrinsically responsive) | RAM-pattern grid (Repeat, Auto-fit, Minmax). Columns wrap automatically when they would shrink below --sf-equal-min-col. No container ancestor required — intrinsically responsive. Modifiers set the target min-col width for ~N equal columns at typical container widths; exact… | +| `.sf-equal--2` | PUBLIC | layout | Equal columns (intrinsically responsive) | RAM-pattern grid (Repeat, Auto-fit, Minmax). Columns wrap automatically when they would shrink below --sf-equal-min-col. No container ancestor required — intrinsically responsive. Modifiers set the target min-col width for ~N equal columns at typical container widths; exact… | +| `.sf-equal--3` | PUBLIC | layout | Equal columns (intrinsically responsive) | RAM-pattern grid (Repeat, Auto-fit, Minmax). Columns wrap automatically when they would shrink below --sf-equal-min-col. No container ancestor required — intrinsically responsive. Modifiers set the target min-col width for ~N equal columns at typical container widths; exact… | +| `.sf-equal--4` | PUBLIC | layout | Equal columns (intrinsically responsive) | RAM-pattern grid (Repeat, Auto-fit, Minmax). Columns wrap automatically when they would shrink below --sf-equal-min-col. No container ancestor required — intrinsically responsive. Modifiers set the target min-col width for ~N equal columns at typical container widths; exact… | +| `.sf-equal--6` | PUBLIC | layout | Equal columns (intrinsically responsive) | RAM-pattern grid (Repeat, Auto-fit, Minmax). Columns wrap automatically when they would shrink below --sf-equal-min-col. No container ancestor required — intrinsically responsive. Modifiers set the target min-col width for ~N equal columns at typical container widths; exact… | | `.sf-frame` | PUBLIC | layout | Frame | Aspect-ratio container. Media children: fill + cover. Override: style="--sf-frame-ratio: 4 / 3" | | `.sf-frame--3-2` | PUBLIC | layout | Frame | Aspect-ratio container. Media children: fill + cover. Override: style="--sf-frame-ratio: 4 / 3" | | `.sf-frame--4-3` | PUBLIC | layout | Frame | Aspect-ratio container. Media children: fill + cover. Override: style="--sf-frame-ratio: 4 / 3" | diff --git a/docs/classes.md b/docs/classes.md index 188d6901..fcb19f0d 100644 --- a/docs/classes.md +++ b/docs/classes.md @@ -3,12 +3,12 @@ > **Generated** from source by `scripts/gen-class-reference.js` — > run `npm run docs:classes` to refresh. Do not edit by hand. -**179 .sf-classes, 40 .is-classes.** Every `.sf-*` layout/macro class and `.is-*` state class. +**180 .sf-classes, 40 .is-classes.** Every `.sf-*` layout/macro class and `.is-*` state class. See [architecture.md](architecture.md) for layer order and naming conventions. ## Layout primitives (`core/layout.css`) -125 classes. +126 classes. | Class | |---| @@ -50,6 +50,7 @@ See [architecture.md](architecture.md) for layer order and naming conventions. | `.sf-cover--padding-l` | | `.sf-cover--padding-s` | | `.sf-cover__center` | +| `.sf-cq` | | `.sf-divider` | | `.sf-divider--dashed` | | `.sf-divider--dotted` | diff --git a/docs/demo.html b/docs/demo.html index 1243db5c..cd3d0a89 100644 --- a/docs/demo.html +++ b/docs/demo.html @@ -1597,6 +1597,14 @@

.sf-grid-cols-1 / Ratio grids

+

.sf-cq — container query scope

+

+ Establishes an inline-size container context so children can use container queries. +

+
+ container-type: inline-size +
+

.sf-equal — fixed N-column grid

Column count never collapses — unlike .sf-grid-* which uses container queries. diff --git a/docs/registry.json b/docs/registry.json index 4ba5c34a..c169f8c5 100644 --- a/docs/registry.json +++ b/docs/registry.json @@ -20,8 +20,8 @@ "optional/theme-example.css" ], "counts": { - "tokens": 823, - "sf_classes": 179, + "tokens": 828, + "sf_classes": 180, "is_classes": 40 } }, @@ -422,8 +422,12 @@ "--sf-ease-out", "--sf-ease-overshoot", "--sf-ease-spring", - "--sf-equal-cols", "--sf-equal-gap", + "--sf-equal-min-col", + "--sf-equal-min-col-2", + "--sf-equal-min-col-3", + "--sf-equal-min-col-4", + "--sf-equal-min-col-6", "--sf-field-block", "--sf-field-padding-block", "--sf-field-padding-inline", @@ -592,6 +596,7 @@ "--sf-prose-paragraph", "--sf-prose-table-pad", "--sf-radius-2xl", + "--sf-radius-2xs", "--sf-radius-3xl", "--sf-radius-4xl", "--sf-radius-full", @@ -893,6 +898,7 @@ "sf-cover--padding-l", "sf-cover--padding-s", "sf-cover__center", + "sf-cq", "sf-divider", "sf-divider--dashed", "sf-divider--dotted", diff --git a/docs/token-index.json b/docs/token-index.json index e24e73aa..8a147cc6 100644 --- a/docs/token-index.json +++ b/docs/token-index.json @@ -10,15 +10,15 @@ "optional/tokens.components.css" ], "counts": { - "tokens": 823, + "tokens": 828, "by_tier": { - "PUBLIC": 685, + "PUBLIC": 690, "PUBLIC-ADVANCED": 137, "INTERNAL": 1 }, "by_role": { - "knob": 232, - "consumption": 591 + "knob": 236, + "consumption": 592 } } }, @@ -3227,21 +3227,53 @@ ], "value": "linear(0, 0.5, 1.1, 0.95, 1.02, 1)" }, - "--sf-equal-cols": { + "--sf-equal-gap": { + "tier": "PUBLIC", + "role": "consumption", + "files": [ + "core/tokens.layout.css" + ], + "value": "var(--sf-space-gap)" + }, + "--sf-equal-min-col": { "tier": "PUBLIC", "role": "knob", "files": [ "core/tokens.layout.css" ], - "value": "2" + "value": "16rem" }, - "--sf-equal-gap": { + "--sf-equal-min-col-2": { "tier": "PUBLIC", - "role": "consumption", + "role": "knob", "files": [ "core/tokens.layout.css" ], - "value": "var(--sf-space-gap)" + "value": "28rem" + }, + "--sf-equal-min-col-3": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.layout.css" + ], + "value": "15rem" + }, + "--sf-equal-min-col-4": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.layout.css" + ], + "value": "16rem" + }, + "--sf-equal-min-col-6": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.layout.css" + ], + "value": "10rem" }, "--sf-field-block": { "tier": "PUBLIC", @@ -4587,6 +4619,14 @@ ], "value": "calc(24px * var(--sf-radius-scale))" }, + "--sf-radius-2xs": { + "tier": "PUBLIC", + "role": "consumption", + "files": [ + "core/tokens.css" + ], + "value": "calc(1px * var(--sf-radius-scale))" + }, "--sf-radius-3xl": { "tier": "PUBLIC", "role": "consumption", diff --git a/docs/token-index.md b/docs/token-index.md index eee44f60..27402a49 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). -**823 tokens** (deduplicated by name across the 6 token source files). +**828 tokens** (deduplicated by name across the 6 token source files). | Tier | Count | Meaning | |---|---|---| -| PUBLIC | 685 | Everyday knobs. SemVer-stable. | +| PUBLIC | 690 | Everyday knobs. SemVer-stable. | | PUBLIC-ADVANCED | 137 | 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 | 232 | Input you **set** to configure the system (a literal primitive: length, number, colour literal, keyword, font stack, easing curve …). | -| consumption | 591 | Ready-to-use output you **read**; derived from other tokens via `var(--sf-…)` (incl. `light-dark()`/`oklch(from …)`/`color-mix()`). | +| knob | 236 | Input you **set** to configure the system (a literal primitive: length, number, colour literal, keyword, font stack, easing curve …). | +| consumption | 592 | Ready-to-use output you **read**; derived from other tokens via `var(--sf-…)` (incl. `light-dark()`/`oklch(from …)`/`color-mix()`). | ## INTERNAL tokens @@ -569,8 +569,12 @@ declared value (a value that references `var(--sf-…)` is a derived output): | `--sf-ease-out` | PUBLIC | knob | Core | `cubic-bezier(0.25, 0, 0.15, 1)` | | `--sf-ease-overshoot` | PUBLIC | knob | Core | `linear(0, 0.6 30%, 1.08 55%, 0.98 75%, 1)` | | `--sf-ease-spring` | PUBLIC | knob | Core | `linear(0, 0.5, 1.1, 0.95, 1.02, 1)` | -| `--sf-equal-cols` | PUBLIC | knob | Layout | `2` | | `--sf-equal-gap` | PUBLIC | consumption | Layout | `var(--sf-space-gap)` | +| `--sf-equal-min-col` | PUBLIC | knob | Layout | `16rem` | +| `--sf-equal-min-col-2` | PUBLIC | knob | Layout | `28rem` | +| `--sf-equal-min-col-3` | PUBLIC | knob | Layout | `15rem` | +| `--sf-equal-min-col-4` | PUBLIC | knob | Layout | `16rem` | +| `--sf-equal-min-col-6` | PUBLIC | knob | Layout | `10rem` | | `--sf-field-block` | PUBLIC | consumption | Core | `var(--sf-space-l)` | | `--sf-field-padding-block` | PUBLIC | consumption | Components (optional, incomplete) | `var(--sf-space-xs)` | | `--sf-field-padding-inline` | PUBLIC | consumption | Components (optional, incomplete) | `var(--sf-space-s)` | @@ -739,6 +743,7 @@ declared value (a value that references `var(--sf-…)` is a derived output): | `--sf-prose-paragraph` | PUBLIC | consumption | Layout | `var(--sf-space-content)` | | `--sf-prose-table-pad` | PUBLIC | consumption | Macros | `var(--sf-space-xs)` | | `--sf-radius-2xl` | PUBLIC | consumption | Core | `calc(24px * var(--sf-radius-scale))` | +| `--sf-radius-2xs` | PUBLIC | consumption | Core | `calc(1px * var(--sf-radius-scale))` | | `--sf-radius-3xl` | PUBLIC | consumption | Core | `calc(32px * var(--sf-radius-scale))` | | `--sf-radius-4xl` | PUBLIC | consumption | Core | `calc(48px * var(--sf-radius-scale))` | | `--sf-radius-full` | PUBLIC | knob | Core | `9999px` | diff --git a/docs/tokens.md b/docs/tokens.md index 515ebe6d..b04d767c 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. -**859 tokens.** Every `--sf-*` custom property and its default value, grouped by source file. +**864 tokens.** Every `--sf-*` custom property and its default value, grouped by source file. Tokens defined in multiple files (e.g. shade aliases overridden in `optional/tokens.palette.css`) are listed once per section — so this count is higher than `docs/registry.json` (which deduplicates by name). See @@ -14,7 +14,7 @@ rebrand workflow. ## Core tokens (`core/tokens.css`) -495 tokens. +496 tokens. | Token | Default | |---|---| @@ -382,6 +382,7 @@ rebrand workflow. | `--sf-print-page-margin` | `2cm` | | `--sf-print-page-size` | `a4` | | `--sf-radius-2xl` | `calc(24px * var(--sf-radius-scale))` | +| `--sf-radius-2xs` | `calc(1px * var(--sf-radius-scale))` | | `--sf-radius-3xl` | `calc(32px * var(--sf-radius-scale))` | | `--sf-radius-4xl` | `calc(48px * var(--sf-radius-scale))` | | `--sf-radius-full` | `9999px` | @@ -516,7 +517,7 @@ rebrand workflow. ## Layout tokens (`core/tokens.layout.css`) -48 tokens. +52 tokens. | Token | Default | |---|---| @@ -539,8 +540,12 @@ rebrand workflow. | `--sf-content-width` | `var(--sf-container-default)` | | `--sf-cover-min-height` | `100dvh` | | `--sf-cover-padding` | `var(--sf-section-pad)` | -| `--sf-equal-cols` | `2` | | `--sf-equal-gap` | `var(--sf-space-gap)` | +| `--sf-equal-min-col` | `16rem` | +| `--sf-equal-min-col-2` | `28rem` | +| `--sf-equal-min-col-3` | `15rem` | +| `--sf-equal-min-col-4` | `16rem` | +| `--sf-equal-min-col-6` | `10rem` | | `--sf-frame-ratio` | `16 / 9` | | `--sf-gap-size` | `var(--sf-space-gap)` | | `--sf-grid-gap` | `var(--sf-space-gap)` | diff --git a/tests/token-api.snapshot.json b/tests/token-api.snapshot.json index 9f62f9e6..994f42a5 100644 --- a/tests/token-api.snapshot.json +++ b/tests/token-api.snapshot.json @@ -395,8 +395,12 @@ "--sf-ease-out", "--sf-ease-overshoot", "--sf-ease-spring", - "--sf-equal-cols", "--sf-equal-gap", + "--sf-equal-min-col", + "--sf-equal-min-col-2", + "--sf-equal-min-col-3", + "--sf-equal-min-col-4", + "--sf-equal-min-col-6", "--sf-field-block", "--sf-field-padding-block", "--sf-field-padding-inline", @@ -565,6 +569,7 @@ "--sf-prose-paragraph", "--sf-prose-table-pad", "--sf-radius-2xl", + "--sf-radius-2xs", "--sf-radius-3xl", "--sf-radius-4xl", "--sf-radius-full", From 4989a612e6bfba631c3e2bf3f4644a02a3405b87 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Jun 2026 12:04:05 +0000 Subject: [PATCH 5/9] fix(tokens,themes): re-enable @property for computed tokens via -dark source tokens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Registers computed color tokens (--sf-color-primary etc.) as @property to enable CSS transitions between light and dark values when [data-theme] toggles. The previous attempt broke child-element dark theming because var(--sf-color-X-dark, oklch(from var(--sf-color-X-light) ...)) fails type-checking when the outer var() has no match and the fallback contains a nested var() reference in a registered property. Fix: declare --sf-color-X-dark as plain :root tokens inside the @supports (color: oklch(...)) block in themes.css, using the same relative color formulas that were previously hidden in the var() fallbacks. [data-theme="dark"] now assigns var(--sf-color-X-dark) directly — a simple var reference that type-checks correctly on child elements. Dark values auto-compute from -light via relative color syntax, and --sf-color-X-dark is now a first-class user-overridable token. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu --- .../src/data/api-index.generated.json | 46 ++++---- core/themes.css | 42 ++++--- core/tokens.css | 21 +++- dist/badge-essential.json | 2 +- dist/badge-optimal.json | 2 +- docs/api-index.json | 110 +++++++++--------- docs/api-index.md | 22 ++-- 7 files changed, 140 insertions(+), 105 deletions(-) diff --git a/configurator/src/data/api-index.generated.json b/configurator/src/data/api-index.generated.json index abad5c3b..0765b609 100644 --- a/configurator/src/data/api-index.generated.json +++ b/configurator/src/data/api-index.generated.json @@ -2,7 +2,7 @@ "_sync": { "generatedBy": "configurator/scripts/sync-api.mjs", "source": "docs/api-index.json", - "tokensHash": "5e8904b7dfd6", + "tokensHash": "dec2227f08f1", "bundles": [ "essential", "full", @@ -1710,8 +1710,8 @@ "note": "Primary interactive color. Applied to filled buttons, active indicators, and brand accent surfaces.", "value": "light-dark(var(--sf-color-action-light), var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "syntax": null, + "registered": true, + "syntax": "", "fallbackOnly": false, "optional": false, "layer": "slashed.tokens", @@ -2528,8 +2528,8 @@ "note": "Secondary interactive color for supporting actions and secondary buttons.", "value": "light-dark(var(--sf-color-base-light), var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)))", "aliasOf": null, - "registered": false, - "syntax": null, + "registered": true, + "syntax": "", "fallbackOnly": false, "optional": false, "layer": "slashed.tokens", @@ -3706,8 +3706,8 @@ "note": "Destructive / danger state color. Used for delete actions, error alerts, and critical warnings.", "value": "light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "syntax": null, + "registered": true, + "syntax": "", "fallbackOnly": false, "optional": false, "layer": "slashed.tokens", @@ -3850,8 +3850,8 @@ "note": "Form validation error color. Typically same hue as danger but can be tuned independently.", "value": "light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "syntax": null, + "registered": true, + "syntax": "", "fallbackOnly": false, "optional": false, "layer": "slashed.tokens", @@ -3994,8 +3994,8 @@ "note": "Informational color for neutral tips, hints, and non-urgent notices.", "value": "light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "syntax": null, + "registered": true, + "syntax": "", "fallbackOnly": false, "optional": false, "layer": "slashed.tokens", @@ -4354,8 +4354,8 @@ "note": "Neutral interactive color for low-emphasis actions and tertiary buttons.", "value": "light-dark(var(--sf-color-neutral-light), var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "syntax": null, + "registered": true, + "syntax": "", "fallbackOnly": false, "optional": false, "layer": "slashed.tokens", @@ -5196,8 +5196,8 @@ "note": "Raw primary palette token aliased from the action role by default. Override to decouple primary from action.", "value": "light-dark(var(--sf-color-primary-light), var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "syntax": null, + "registered": true, + "syntax": "", "fallbackOnly": false, "optional": false, "layer": "slashed.tokens", @@ -6062,8 +6062,8 @@ "note": "Raw secondary palette token for the secondary brand color.", "value": "light-dark(var(--sf-color-secondary-light), var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "syntax": null, + "registered": true, + "syntax": "", "fallbackOnly": false, "optional": false, "layer": "slashed.tokens", @@ -6928,8 +6928,8 @@ "note": "Positive / success color for confirmation messages and completed-state indicators.", "value": "light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "syntax": null, + "registered": true, + "syntax": "", "fallbackOnly": false, "optional": false, "layer": "slashed.tokens", @@ -7072,8 +7072,8 @@ "note": "Raw tertiary palette token for the third brand color.", "value": "light-dark(var(--sf-color-tertiary-light), var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "syntax": null, + "registered": true, + "syntax": "", "fallbackOnly": false, "optional": false, "layer": "slashed.tokens", @@ -8346,8 +8346,8 @@ "note": "Warning / caution color for non-critical alerts and degraded-state indicators.", "value": "light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "syntax": null, + "registered": true, + "syntax": "", "fallbackOnly": false, "optional": false, "layer": "slashed.tokens", diff --git a/core/themes.css b/core/themes.css index 0379f2cf..66081cf8 100644 --- a/core/themes.css +++ b/core/themes.css @@ -162,24 +162,40 @@ @supports (color: oklch(from red l c h)) { + /* ── -dark source tokens — auto-computed from -light, user-overridable ── */ + :root { + --sf-color-primary-dark: oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h); + --sf-color-secondary-dark: oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h); + --sf-color-tertiary-dark: oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h); + --sf-color-action-dark: oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h); + --sf-color-neutral-dark: oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h); + --sf-color-base-dark: oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h); + --sf-color-success-dark: oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h); + --sf-color-warning-dark: oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h); + --sf-color-error-dark: oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h); + --sf-color-info-dark: oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h); + --sf-color-danger-dark: oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h); + } + /* ── [data-theme="dark"] — explicit dark values ──────────── */ [data-theme="dark"] { - /* Brand — dark formula or explicit -dark override */ - --sf-color-primary: var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)); - --sf-color-secondary: var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)); - --sf-color-tertiary: var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)); - --sf-color-action: var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)); - --sf-color-neutral: var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)); - --sf-color-base: var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)); + /* Brand — simple var reference; -dark tokens defined on :root above. + Override --sf-color-X-dark anywhere in the cascade to customise. */ + --sf-color-primary: var(--sf-color-primary-dark); + --sf-color-secondary: var(--sf-color-secondary-dark); + --sf-color-tertiary: var(--sf-color-tertiary-dark); + --sf-color-action: var(--sf-color-action-dark); + --sf-color-neutral: var(--sf-color-neutral-dark); + --sf-color-base: var(--sf-color-base-dark); --sf-color-surface: var(--sf-color-base); - /* Status — dark formula or explicit -dark override */ - --sf-color-success: var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)); - --sf-color-warning: var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)); - --sf-color-error: var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)); - --sf-color-info: var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)); - --sf-color-danger: var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)); + /* Status */ + --sf-color-success: var(--sf-color-success-dark); + --sf-color-warning: var(--sf-color-warning-dark); + --sf-color-error: var(--sf-color-error-dark); + --sf-color-info: var(--sf-color-info-dark); + --sf-color-danger: var(--sf-color-danger-dark); /* Text — dark formula (references --sf-color-neutral re-declared above) */ --sf-color-text: oklch(from var(--sf-color-neutral) clamp(0.70, calc(l + 0.25 + var(--sf-contrast-bias)), 1) c h); diff --git a/core/tokens.css b/core/tokens.css index b5a5d998..8bb27c79 100644 --- a/core/tokens.css +++ b/core/tokens.css @@ -209,9 +209,28 @@ --sf-color-danger-light: oklch(0.48 0.22 12); } + /* @property — COMPUTED COLOR TOKENS (brand + status) + Registers the computed tokens as typed so CSS transitions can + interpolate between light and dark values when [data-theme] changes. + initial-value = light-mode value (safe fallback if nothing sets the token). + Child-element theming works because [data-theme="dark"] in themes.css + assigns var(--sf-color-X-dark) — a simple var reference, not a + var()-in-fallback chain — which type-checks correctly on child elements. */ + @property --sf-color-primary { syntax: ""; inherits: true; initial-value: oklch(0.47 0.27 264); } + @property --sf-color-secondary { syntax: ""; inherits: true; initial-value: oklch(0.22 0.04 264); } + @property --sf-color-tertiary { syntax: ""; inherits: true; initial-value: oklch(0.42 0.22 295); } + @property --sf-color-action { syntax: ""; inherits: true; initial-value: oklch(0.50 0.22 235); } + @property --sf-color-neutral { syntax: ""; inherits: true; initial-value: oklch(0.52 0.025 260); } + @property --sf-color-base { syntax: ""; inherits: true; initial-value: oklch(0.96 0.006 250); } + @property --sf-color-success { syntax: ""; inherits: true; initial-value: oklch(0.50 0.16 145); } + @property --sf-color-warning { syntax: ""; inherits: true; initial-value: oklch(0.75 0.17 80); } + @property --sf-color-error { syntax: ""; inherits: true; initial-value: oklch(0.50 0.20 25); } + @property --sf-color-info { syntax: ""; inherits: true; initial-value: oklch(0.48 0.18 235); } + @property --sf-color-danger { syntax: ""; inherits: true; initial-value: oklch(0.48 0.22 12); } + /* Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. - Overridden by the @supports block below whenever light-dark() is available. */ + Overridden by the @supports block in themes.css whenever dark mode is active. */ :root { --sf-color-primary: var(--sf-color-primary-light); --sf-color-secondary: var(--sf-color-secondary-light); diff --git a/dist/badge-essential.json b/dist/badge-essential.json index 213d802a..17baa169 100644 --- a/dist/badge-essential.json +++ b/dist/badge-essential.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "label": "essential", - "message": "15.9 kB gzip", + "message": "16.0 kB gzip", "color": "brightgreen", "namedLogo": "css3" } diff --git a/dist/badge-optimal.json b/dist/badge-optimal.json index a8166dce..93927fc4 100644 --- a/dist/badge-optimal.json +++ b/dist/badge-optimal.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "label": "optimal", - "message": "19.7 kB gzip", + "message": "19.8 kB gzip", "color": "brightgreen", "namedLogo": "css3" } diff --git a/docs/api-index.json b/docs/api-index.json index dfd6e258..8e1a6da4 100644 --- a/docs/api-index.json +++ b/docs/api-index.json @@ -2122,13 +2122,13 @@ "category": "Core tokens", "area": "core", "group": "STATUS COLORS (-light source tokens)", - "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", + "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-action-light), var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "animatable": false, - "syntax": null, - "inherits": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, "optional": false, "layer": "slashed.tokens", "sourceFiles": [ @@ -3121,13 +3121,13 @@ "category": "Core tokens", "area": "core", "group": "STATUS COLORS (-light source tokens)", - "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", + "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-base-light), var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)))", "aliasOf": null, - "registered": false, - "animatable": false, - "syntax": null, - "inherits": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, "optional": false, "layer": "slashed.tokens", "sourceFiles": [ @@ -4555,13 +4555,13 @@ "category": "Core tokens", "area": "core", "group": "STATUS COLORS (-light source tokens)", - "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", + "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "animatable": false, - "syntax": null, - "inherits": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, "optional": false, "layer": "slashed.tokens", "sourceFiles": [ @@ -4729,13 +4729,13 @@ "category": "Core tokens", "area": "core", "group": "STATUS COLORS (-light source tokens)", - "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", + "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "animatable": false, - "syntax": null, - "inherits": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, "optional": false, "layer": "slashed.tokens", "sourceFiles": [ @@ -4903,13 +4903,13 @@ "category": "Core tokens", "area": "core", "group": "STATUS COLORS (-light source tokens)", - "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", + "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "animatable": false, - "syntax": null, - "inherits": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, "optional": false, "layer": "slashed.tokens", "sourceFiles": [ @@ -5338,13 +5338,13 @@ "category": "Core tokens", "area": "core", "group": "STATUS COLORS (-light source tokens)", - "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", + "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-neutral-light), var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "animatable": false, - "syntax": null, - "inherits": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, "optional": false, "layer": "slashed.tokens", "sourceFiles": [ @@ -6366,13 +6366,13 @@ "category": "Core tokens", "area": "core", "group": "STATUS COLORS (-light source tokens)", - "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", + "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-primary-light), var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "animatable": false, - "syntax": null, - "inherits": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, "optional": false, "layer": "slashed.tokens", "sourceFiles": [ @@ -7423,13 +7423,13 @@ "category": "Core tokens", "area": "core", "group": "STATUS COLORS (-light source tokens)", - "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", + "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-secondary-light), var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "animatable": false, - "syntax": null, - "inherits": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, "optional": false, "layer": "slashed.tokens", "sourceFiles": [ @@ -8480,13 +8480,13 @@ "category": "Core tokens", "area": "core", "group": "STATUS COLORS (-light source tokens)", - "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", + "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "animatable": false, - "syntax": null, - "inherits": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, "optional": false, "layer": "slashed.tokens", "sourceFiles": [ @@ -8654,13 +8654,13 @@ "category": "Core tokens", "area": "core", "group": "STATUS COLORS (-light source tokens)", - "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", + "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-tertiary-light), var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "animatable": false, - "syntax": null, - "inherits": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, "optional": false, "layer": "slashed.tokens", "sourceFiles": [ @@ -10204,13 +10204,13 @@ "category": "Core tokens", "area": "core", "group": "STATUS COLORS (-light source tokens)", - "description": "Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available.", + "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, - "registered": false, - "animatable": false, - "syntax": null, - "inherits": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, "optional": false, "layer": "slashed.tokens", "sourceFiles": [ diff --git a/docs/api-index.md b/docs/api-index.md index f1debc01..21969c43 100644 --- a/docs/api-index.md +++ b/docs/api-index.md @@ -85,7 +85,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-col-width-l` | PUBLIC | knob | col | `32ch` | tokens for the `columns` layout property. column-width is ch-based (character units) so columns maintain a comfortable reading measure regardless of font-size. | | `--sf-col-width-m` | PUBLIC | knob | col | `24ch` | tokens for the `columns` layout property. column-width is ch-based (character units) so columns maintain a comfortable reading measure regardless of font-size. | | `--sf-col-width-s` | PUBLIC | knob | col | `16ch` | tokens for the `columns` layout property. column-width is ch-based (character units) so columns maintain a comfortable reading measure regardless of font-size. | -| `--sf-color-action` | PUBLIC | consumption | color | `light-dark(var(--sf-color-action-light), var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | +| `--sf-color-action` | PUBLIC | consumption | color | `light-dark(var(--sf-color-action-light), var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-action--active` | PUBLIC | consumption | color | `var(--sf-color-action-xdark)` | action | | `--sf-color-action--hover` | PUBLIC | consumption | color | `var(--sf-color-action-darker)` | action | | `--sf-color-action-darker` | PUBLIC | consumption | color | `var(--sf-color-action-600)` | action | @@ -98,7 +98,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-action-superlight` | PUBLIC | consumption | color | `var(--sf-color-action-50)` | action | | `--sf-color-action-xdark` | PUBLIC | consumption | color | `var(--sf-color-action-800)` | action | | `--sf-color-action-xlight` | PUBLIC | consumption | color | `var(--sf-color-action-200)` | action | -| `--sf-color-base` | PUBLIC | consumption | color | `light-dark(var(--sf-color-base-light), var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | +| `--sf-color-base` | PUBLIC | consumption | color | `light-dark(var(--sf-color-base-light), var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-base--active` | PUBLIC | consumption | color | `var(--sf-color-base-xdark)` | base | | `--sf-color-base--hover` | PUBLIC | consumption | color | `var(--sf-color-base-darker)` | base | | `--sf-color-base-darker` | PUBLIC | consumption | color | `var(--sf-color-base-600)` | base | @@ -126,19 +126,19 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-border--translucent` | PUBLIC | consumption | color | `oklch(from var(--sf-color-neutral) l c h / 0.15)` | Border alpha tokens | | `--sf-color-code-bg` | PUBLIC | consumption | color | `var(--sf-color-inset)` | plain var aliases (ungated) | | `--sf-color-code-text` | PUBLIC | consumption | color | `oklch(from var(--sf-color-code-bg) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0)` | Inline-code text colour. Auto-contrasts with --sf-color-code-bg using the same luminance formula as --sf-color-text--on-*. This prevents invisible text when code appears inside inverted-colour containers (e.g. sf-imposter with a dark background where inherited colour is… | -| `--sf-color-danger` | PUBLIC | consumption | color | `light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | +| `--sf-color-danger` | PUBLIC | consumption | color | `light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-danger-light` | PUBLIC | knob | color | `oklch(0.48 0.22 12)` | STATUS COLORS (-light source tokens) | | `--sf-color-danger-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-danger) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-danger-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-danger-light) calc(l - 0.1) c h), oklch(from var(--sf-color-danger) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | | `--sf-color-danger-subtle` | PUBLIC | consumption | color | `oklch(from var(--sf-color-danger) l c h / 0.1)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-dim` | PUBLIC | knob | color | `oklch(0 0 0 / 0.5)` | Dim: classic semi-transparent black for modal backdrops, distinct from --sf-color-overlay | -| `--sf-color-error` | PUBLIC | consumption | color | `light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | +| `--sf-color-error` | PUBLIC | consumption | color | `light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-error-light` | PUBLIC | knob | color | `oklch(0.50 0.20 25)` | STATUS COLORS (-light source tokens) | | `--sf-color-error-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-error) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-error-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-error-light) calc(l - 0.1) c h), oklch(from var(--sf-color-error) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | | `--sf-color-error-subtle` | PUBLIC | consumption | color | `oklch(from var(--sf-color-error) l c h / 0.1)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-heading` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.05, calc(l - 0.4 - var(--sf-contrast-bias)), 0.35) c h), oklch(from var(--sf-color-neutral) clamp(0.70, calc(l + 0.25 + var(--sf-contrast-bias)), 1) c h) )` | light and dark require opposite formula directions, so each side of light-dark() references its source token. | -| `--sf-color-info` | PUBLIC | consumption | color | `light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | +| `--sf-color-info` | PUBLIC | consumption | color | `light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-info-light` | PUBLIC | knob | color | `oklch(0.48 0.18 235)` | STATUS COLORS (-light source tokens) | | `--sf-color-info-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-info) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-info-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-info-light) calc(l - 0.1) c h), oklch(from var(--sf-color-info) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | @@ -153,7 +153,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-link--visited` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-action) clamp(0, min(l - 0.07, 0.48), 1) c calc(h + 60)), oklch(from var(--sf-color-action) clamp(0.68, l, 1) c calc(h + 60)) )` | Visited link — 60° hue shift from action gives clearly distinct chroma without colliding with default tertiary (h ≈ 310). Same lightness clamp as the base link. If your brand puts action and tertiary close in hue, override directly: :root { --sf-color-link--visited: #6b46c1; } | | `--sf-color-mark-bg` | PUBLIC | consumption | color | `oklch(from var(--sf-color-warning) l c h / 0.25)` | Selection & mark | | `--sf-color-mark-text` | PUBLIC | knob | color | `inherit` | static values (ungated) | -| `--sf-color-neutral` | PUBLIC | consumption | color | `light-dark(var(--sf-color-neutral-light), var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | +| `--sf-color-neutral` | PUBLIC | consumption | color | `light-dark(var(--sf-color-neutral-light), var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-neutral--active` | PUBLIC | consumption | color | `var(--sf-color-neutral-xdark)` | neutral | | `--sf-color-neutral--hover` | PUBLIC | consumption | color | `var(--sf-color-neutral-darker)` | neutral | | `--sf-color-neutral-darker` | PUBLIC | consumption | color | `var(--sf-color-neutral-600)` | neutral | @@ -167,7 +167,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-neutral-xdark` | PUBLIC | consumption | color | `var(--sf-color-neutral-800)` | neutral | | `--sf-color-neutral-xlight` | PUBLIC | consumption | color | `var(--sf-color-neutral-200)` | neutral | | `--sf-color-overlay` | PUBLIC | consumption | color | `oklch(from var(--sf-color-base) l c h / 0.9)` | Overlay: high-opacity wash of the base color for light/dark mode safe layers | -| `--sf-color-primary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-primary-light), var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | +| `--sf-color-primary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-primary-light), var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-primary--active` | PUBLIC | consumption | color | `var(--sf-color-primary-xdark)` | primary | | `--sf-color-primary--hover` | PUBLIC | consumption | color | `var(--sf-color-primary-darker)` | primary | | `--sf-color-primary-darker` | PUBLIC | consumption | color | `var(--sf-color-primary-600)` | primary | @@ -182,7 +182,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-primary-xlight` | PUBLIC | consumption | color | `var(--sf-color-primary-200)` | primary | | `--sf-color-raised` | PUBLIC | consumption | color | `oklch(from var(--sf-color-base) calc(l + 0.04) c h)` | derived from --sf-color-base (auto-adapts) | | `--sf-color-scheme` | PUBLIC | knob | color | `light dark` | Color scheme | -| `--sf-color-secondary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-secondary-light), var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | +| `--sf-color-secondary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-secondary-light), var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-secondary--active` | PUBLIC | consumption | color | `var(--sf-color-secondary-xdark)` | secondary | | `--sf-color-secondary--hover` | PUBLIC | consumption | color | `var(--sf-color-secondary-darker)` | secondary | | `--sf-color-secondary-darker` | PUBLIC | consumption | color | `var(--sf-color-secondary-600)` | secondary | @@ -197,13 +197,13 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-secondary-xlight` | PUBLIC | consumption | color | `var(--sf-color-secondary-200)` | secondary | | `--sf-color-selection-bg` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-action-light) l c h / 0.28), oklch(from var(--sf-color-action-light) clamp(0.62, calc(0.93 - l * 0.4), 0.78) c h / 0.55) )` | Selection | | `--sf-color-selection-text` | PUBLIC | knob | color | `inherit` | static values (ungated) | -| `--sf-color-success` | PUBLIC | consumption | color | `light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | +| `--sf-color-success` | PUBLIC | consumption | color | `light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-success-light` | PUBLIC | knob | color | `oklch(0.50 0.16 145)` | STATUS COLORS (-light source tokens) | | `--sf-color-success-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-success) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-success-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-success-light) calc(l - 0.15) c h), oklch(from var(--sf-color-success) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | | `--sf-color-success-subtle` | PUBLIC | consumption | color | `oklch(from var(--sf-color-success) l c h / 0.12)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-surface` | PUBLIC | consumption | color | `var(--sf-color-base)` | Surface alias (plain var — no IACVT, stays ungated) | -| `--sf-color-tertiary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-tertiary-light), var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | +| `--sf-color-tertiary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-tertiary-light), var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-tertiary--active` | PUBLIC | consumption | color | `var(--sf-color-tertiary-xdark)` | tertiary | | `--sf-color-tertiary--hover` | PUBLIC | consumption | color | `var(--sf-color-tertiary-darker)` | tertiary | | `--sf-color-tertiary-darker` | PUBLIC | consumption | color | `var(--sf-color-tertiary-600)` | tertiary | @@ -235,7 +235,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-text--on-warning` | PUBLIC | consumption | color | `oklch(from var(--sf-color-warning) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0)` | sign(var(--sf-contrast-threshold) - l) * 999 is mode-agnostic: auto-selects light or dark text based on background luminance. Uses resolved tokens — works for any user-supplied color. CONTRAST NOTE: Guarantees ≥ 3:1 (WCAG AA Large Text / UI). Colors in the mid-luminance range… | | `--sf-color-text--placeholder` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.45, calc(l + 0.15), 0.75) c h), oklch(from var(--sf-color-neutral) clamp(0.35, calc(l - 0.1), 0.65) c h) )` | light and dark require opposite formula directions, so each side of light-dark() references its source token. | | `--sf-color-text--secondary` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.15, calc(l - 0.25 - var(--sf-contrast-bias)), 0.45) c h), oklch(from var(--sf-color-neutral) clamp(0.55, calc(l + 0.1 + var(--sf-contrast-bias)), 0.90) c h) )` | light and dark require opposite formula directions, so each side of light-dark() references its source token. | -| `--sf-color-warning` | PUBLIC | consumption | color | `light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | Plain :root mirrors for computed tokens — resolve to the -light source token so user overrides to --sf-color-X-light are respected in all browsers. Overridden by the @supports block below whenever light-dark() is available. | +| `--sf-color-warning` | PUBLIC | consumption | color | `light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-warning-light` | PUBLIC | knob | color | `oklch(0.75 0.17 80)` | STATUS COLORS (-light source tokens) | | `--sf-color-warning-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-warning) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-warning-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-warning-light) calc(l - 0.25) c h), oklch(from var(--sf-color-warning) clamp(0.70, calc(l + 0.05), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | From 68217d909923ca2a58827463155ccdaf84a12403 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Jun 2026 12:42:08 +0000 Subject: [PATCH 6/9] fix(tests): add 11 -dark @property tokens to token-api snapshot The @property registrations for --sf-color-{action,base,danger,error,info, neutral,primary,secondary,success,tertiary,warning}-dark in core/tokens.css are now surfaced in the TOKEN_FILES scan. Update the locked snapshot so the token-api spec does not flag them as unexpected additions. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu --- tests/token-api.snapshot.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/token-api.snapshot.json b/tests/token-api.snapshot.json index 994f42a5..dc6eea31 100644 --- a/tests/token-api.snapshot.json +++ b/tests/token-api.snapshot.json @@ -94,6 +94,7 @@ "--sf-color-action-a80", "--sf-color-action-a90", "--sf-color-action-a95", + "--sf-color-action-dark", "--sf-color-action-darker", "--sf-color-action-ghost", "--sf-color-action-light", @@ -129,6 +130,7 @@ "--sf-color-base-a80", "--sf-color-base-a90", "--sf-color-base-a95", + "--sf-color-base-dark", "--sf-color-base-darker", "--sf-color-base-ghost", "--sf-color-base-light", @@ -155,18 +157,21 @@ "--sf-color-code-bg", "--sf-color-code-text", "--sf-color-danger", + "--sf-color-danger-dark", "--sf-color-danger-light", "--sf-color-danger-muted", "--sf-color-danger-strong", "--sf-color-danger-subtle", "--sf-color-dim", "--sf-color-error", + "--sf-color-error-dark", "--sf-color-error-light", "--sf-color-error-muted", "--sf-color-error-strong", "--sf-color-error-subtle", "--sf-color-heading", "--sf-color-info", + "--sf-color-info-dark", "--sf-color-info-light", "--sf-color-info-muted", "--sf-color-info-strong", @@ -206,6 +211,7 @@ "--sf-color-neutral-a80", "--sf-color-neutral-a90", "--sf-color-neutral-a95", + "--sf-color-neutral-dark", "--sf-color-neutral-darker", "--sf-color-neutral-ghost", "--sf-color-neutral-light", @@ -242,6 +248,7 @@ "--sf-color-primary-a80", "--sf-color-primary-a90", "--sf-color-primary-a95", + "--sf-color-primary-dark", "--sf-color-primary-darker", "--sf-color-primary-ghost", "--sf-color-primary-light", @@ -279,6 +286,7 @@ "--sf-color-secondary-a80", "--sf-color-secondary-a90", "--sf-color-secondary-a95", + "--sf-color-secondary-dark", "--sf-color-secondary-darker", "--sf-color-secondary-ghost", "--sf-color-secondary-light", @@ -292,6 +300,7 @@ "--sf-color-selection-bg", "--sf-color-selection-text", "--sf-color-success", + "--sf-color-success-dark", "--sf-color-success-light", "--sf-color-success-muted", "--sf-color-success-strong", @@ -322,6 +331,7 @@ "--sf-color-tertiary-a80", "--sf-color-tertiary-a90", "--sf-color-tertiary-a95", + "--sf-color-tertiary-dark", "--sf-color-tertiary-darker", "--sf-color-tertiary-ghost", "--sf-color-tertiary-light", @@ -352,6 +362,7 @@ "--sf-color-text--placeholder", "--sf-color-text--secondary", "--sf-color-warning", + "--sf-color-warning-dark", "--sf-color-warning-light", "--sf-color-warning-muted", "--sf-color-warning-strong", From 7e1e21b90781a67d3967f6c7cf9a4bbad2071df6 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Jun 2026 12:43:11 +0000 Subject: [PATCH 7/9] fix(tokens,tests,docs): register -dark tokens as @property and update baselines Add @property registrations for all 11 -dark source tokens (primary, secondary, tertiary, action, neutral, base, success, warning, error, info, danger) so Chromium resolves them to typed absolute OKLCH values on :root. Without this, child elements with [data-theme="dark"] inherit the raw formula text and Chrome fails multi-level var() substitution inside registered properties, producing light colors in dark sections. Also: - Add --sf-radius-2xs to docs/token-annotations.json (configurator sync) - Update tests/baseline-modern.json to reflect registered @property behavior (source tokens now return absolute OKLCH; derived tokens return formula text with substituted absolute OKLCH for the registered vars) - Rebuild dist/ and docs/ (api-index, token-index, registry, badge scores) Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu --- .../src/data/api-index.generated.json | 286 +++++++++++++- core/tokens.css | 40 +- dist/badge-essential.json | 2 +- dist/badge-optimal.json | 2 +- docs/api-index.json | 359 +++++++++++++++++- docs/api-index.md | 41 +- docs/registry.json | 13 +- docs/token-annotations.json | 1 + docs/token-index.json | 94 ++++- docs/token-index.md | 17 +- docs/tokens.md | 15 +- tests/baseline-modern.json | 126 +++--- 12 files changed, 868 insertions(+), 128 deletions(-) diff --git a/configurator/src/data/api-index.generated.json b/configurator/src/data/api-index.generated.json index 0765b609..896c7cd4 100644 --- a/configurator/src/data/api-index.generated.json +++ b/configurator/src/data/api-index.generated.json @@ -2,7 +2,7 @@ "_sync": { "generatedBy": "configurator/scripts/sync-api.mjs", "source": "docs/api-index.json", - "tokensHash": "dec2227f08f1", + "tokensHash": "e8bd0fe746b0", "bundles": [ "essential", "full", @@ -11,15 +11,15 @@ "optimal-utilities" ], "counts": { - "tokens": 828, + "tokens": 839, "byTier": { - "PUBLIC": 690, + "PUBLIC": 701, "PUBLIC-ADVANCED": 137, "INTERNAL": 1 }, "byCategory": { "Layout tokens": 52, - "Core tokens": 496, + "Core tokens": 507, "Macro tokens": 24, "Component tokens": 6, "Palette tokens": 142, @@ -2277,6 +2277,30 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-action-dark", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "note": "", + "value": "oklch(0.70 0.198 235)", + "aliasOf": null, + "registered": true, + "syntax": "", + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-action-darker", "tier": "PUBLIC", @@ -3095,6 +3119,30 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-base-dark", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "note": "", + "value": "oklch(0.22 0.003 250)", + "aliasOf": null, + "registered": true, + "syntax": "", + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-base-darker", "tier": "PUBLIC", @@ -3719,6 +3767,30 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-danger-dark", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "note": "", + "value": "oklch(0.71 0.198 12)", + "aliasOf": null, + "registered": true, + "syntax": "", + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-danger-light", "tier": "PUBLIC", @@ -3863,6 +3935,30 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-error-dark", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "note": "", + "value": "oklch(0.70 0.18 25)", + "aliasOf": null, + "registered": true, + "syntax": "", + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-error-light", "tier": "PUBLIC", @@ -4007,6 +4103,30 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-info-dark", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "note": "", + "value": "oklch(0.71 0.162 235)", + "aliasOf": null, + "registered": true, + "syntax": "", + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-info-light", "tier": "PUBLIC", @@ -4921,6 +5041,30 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-neutral-dark", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "note": "", + "value": "oklch(0.69 0.0225 260)", + "aliasOf": null, + "registered": true, + "syntax": "", + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-neutral-darker", "tier": "PUBLIC", @@ -5763,6 +5907,30 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-primary-dark", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "note": "", + "value": "oklch(0.715 0.243 264)", + "aliasOf": null, + "registered": true, + "syntax": "", + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-primary-darker", "tier": "PUBLIC", @@ -6629,6 +6797,30 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-secondary-dark", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "note": "", + "value": "oklch(0.84 0.036 264)", + "aliasOf": null, + "registered": true, + "syntax": "", + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-secondary-darker", "tier": "PUBLIC", @@ -6941,6 +7133,30 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-success-dark", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "note": "", + "value": "oklch(0.70 0.144 145)", + "aliasOf": null, + "registered": true, + "syntax": "", + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-success-light", "tier": "PUBLIC", @@ -7639,6 +7855,30 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-tertiary-dark", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "note": "", + "value": "oklch(0.74 0.198 295)", + "aliasOf": null, + "registered": true, + "syntax": "", + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-tertiary-darker", "tier": "PUBLIC", @@ -8359,6 +8599,30 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-warning-dark", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "group": "STATUS COLORS (-light source tokens)", + "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "note": "", + "value": "oklch(0.65 0.153 80)", + "aliasOf": null, + "registered": true, + "syntax": "", + "fallbackOnly": false, + "optional": false, + "layer": "slashed.tokens", + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-warning-light", "tier": "PUBLIC", @@ -13556,7 +13820,7 @@ "category": "Core tokens", "group": "Border radius", "description": "Border-radius scale from xs hairline to full circle. Stick to this scale so UI elements share a consistent curvature language.", - "note": "", + "note": "Extra-extra-small radius (~1px). Minimal rounding for very tight UI elements.", "value": "calc(1px * var(--sf-radius-scale))", "aliasOf": null, "registered": false, @@ -13626,8 +13890,8 @@ "role": "knob", "namespace": "radius", "category": "Core tokens", - "group": "Border radius", - "description": "Border-radius scale from xs hairline to full circle. Stick to this scale so UI elements share a consistent curvature language.", + "group": "Full/pill", + "description": "topological constants, not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to half the…", "note": "Full rounding (50%). For circular elements like avatars.", "value": "9999px", "aliasOf": null, @@ -13722,8 +13986,8 @@ "role": "consumption", "namespace": "radius", "category": "Core tokens", - "group": "Border radius", - "description": "Border-radius scale from xs hairline to full circle. Stick to this scale so UI elements share a consistent curvature language.", + "group": "Full/pill", + "description": "Concentric helper — outer radius for a container that wraps content padded by --sf-component-pad with inner radius m. Keeps inner elements visually proportional inside a padded box. Override per use: .my-card { border-radius: var(--sf-radius-outer); } Maths: outer = inner +…", "note": "", "value": "calc(var(--sf-radius-m) + var(--sf-component-pad))", "aliasOf": null, @@ -13746,8 +14010,8 @@ "role": "consumption", "namespace": "radius", "category": "Core tokens", - "group": "Border radius", - "description": "Border-radius scale from xs hairline to full circle. Stick to this scale so UI elements share a consistent curvature language.", + "group": "Full/pill", + "description": "Pill — semantic alias of --sf-radius-full. Reach for this name on rectangles you want capsule-shaped (badges, tags, chips); use --sf-radius-full when you mean \"as round as topologically possible\".", "note": "Pill rounding (9999px). Tags, toggle pills, status badges.", "value": "var(--sf-radius-full)", "aliasOf": "--sf-radius-full", diff --git a/core/tokens.css b/core/tokens.css index 8bb27c79..8e65446b 100644 --- a/core/tokens.css +++ b/core/tokens.css @@ -209,13 +209,35 @@ --sf-color-danger-light: oklch(0.48 0.22 12); } + /* @property — DARK SOURCE TOKENS (-dark, animatable) + Registers the auto-computed dark counterparts as typed so their + resolved absolute value is inherited by child elements (e.g. a section + with [data-theme="dark"]). Without @property these tokens inherit as raw + text, and the nested var()-in-oklch-from chain fails type-checking on + registered child properties. + initial-value = dark-mode value derived from the formula in themes.css + (clamp(0.65, 0.95 - l*0.5, 0.88) for brand/status; inverted for base). + Consumers who set --sf-color-X-dark explicitly do not need to register it + — their override is a plain OKLCH literal and passes type-checking directly. */ + @property --sf-color-primary-dark { syntax: ""; inherits: true; initial-value: oklch(0.715 0.243 264); } + @property --sf-color-secondary-dark { syntax: ""; inherits: true; initial-value: oklch(0.84 0.036 264); } + @property --sf-color-tertiary-dark { syntax: ""; inherits: true; initial-value: oklch(0.74 0.198 295); } + @property --sf-color-action-dark { syntax: ""; inherits: true; initial-value: oklch(0.70 0.198 235); } + @property --sf-color-neutral-dark { syntax: ""; inherits: true; initial-value: oklch(0.69 0.0225 260); } + @property --sf-color-base-dark { syntax: ""; inherits: true; initial-value: oklch(0.22 0.003 250); } + @property --sf-color-success-dark { syntax: ""; inherits: true; initial-value: oklch(0.70 0.144 145); } + @property --sf-color-warning-dark { syntax: ""; inherits: true; initial-value: oklch(0.65 0.153 80); } + @property --sf-color-error-dark { syntax: ""; inherits: true; initial-value: oklch(0.70 0.18 25); } + @property --sf-color-info-dark { syntax: ""; inherits: true; initial-value: oklch(0.71 0.162 235); } + @property --sf-color-danger-dark { syntax: ""; inherits: true; initial-value: oklch(0.71 0.198 12); } + /* @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token). Child-element theming works because [data-theme="dark"] in themes.css - assigns var(--sf-color-X-dark) — a simple var reference, not a - var()-in-fallback chain — which type-checks correctly on child elements. */ + assigns var(--sf-color-X-dark) — now a registered typed whose + absolute value is inherited, so no multi-level var() resolution is needed. */ @property --sf-color-primary { syntax: ""; inherits: true; initial-value: oklch(0.47 0.27 264); } @property --sf-color-secondary { syntax: ""; inherits: true; initial-value: oklch(0.22 0.04 264); } @property --sf-color-tertiary { syntax: ""; inherits: true; initial-value: oklch(0.42 0.22 295); } @@ -1086,12 +1108,7 @@ --sf-divider-gap: var(--sf-space-m); /* ---------------------------------------------------------- - Border radius - --sf-radius-full: intentionally not scaled by --sf-radius-scale. - A pill/circle is a topological constant, not a relative size: - any --sf-radius-scale: 0 ("sharp" design system) should still - render pill buttons as pills. 9999px is a magic-number convention - large enough to clip to half the shorter edge for any realistic UI. + Border radius — scale ramp, all multiplied by --sf-radius-scale. ---------------------------------------------------------- */ --sf-radius-none: 0; --sf-radius-2xs: calc(1px * var(--sf-radius-scale)); @@ -1103,6 +1120,13 @@ --sf-radius-2xl: calc(24px * var(--sf-radius-scale)); --sf-radius-3xl: calc(32px * var(--sf-radius-scale)); --sf-radius-4xl: calc(48px * var(--sf-radius-scale)); + /* ---------------------------------------------------------- + Full/pill — topological constants, not scaled by --sf-radius-scale. + A pill/circle is a topological constant, not a relative size: + any --sf-radius-scale: 0 ("sharp" design system) should still + render pill buttons as pills. 9999px is a magic-number convention + large enough to clip to half the shorter edge for any realistic UI. + ---------------------------------------------------------- */ --sf-radius-full: 9999px; /* Pill — semantic alias of --sf-radius-full. Reach for this name on rectangles you want capsule-shaped (badges, tags, chips); use diff --git a/dist/badge-essential.json b/dist/badge-essential.json index 17baa169..bf542d11 100644 --- a/dist/badge-essential.json +++ b/dist/badge-essential.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "label": "essential", - "message": "16.0 kB gzip", + "message": "16.1 kB gzip", "color": "brightgreen", "namedLogo": "css3" } diff --git a/dist/badge-optimal.json b/dist/badge-optimal.json index 93927fc4..e118d881 100644 --- a/dist/badge-optimal.json +++ b/dist/badge-optimal.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "label": "optimal", - "message": "19.8 kB gzip", + "message": "19.9 kB gzip", "color": "brightgreen", "namedLogo": "css3" } diff --git a/docs/api-index.json b/docs/api-index.json index 8e1a6da4..3b8eb547 100644 --- a/docs/api-index.json +++ b/docs/api-index.json @@ -29,21 +29,21 @@ "optimal-utilities" ], "counts": { - "total": 1057, + "total": 1068, "by_type": { "class": 229, - "token": 828 + "token": 839 }, "by_tier": { "INTERNAL": 1, - "PUBLIC": 919, + "PUBLIC": 930, "PUBLIC-ADVANCED": 137 }, "by_role": { "consumption": 592, - "knob": 236 + "knob": 247 }, - "tokens": 828, + "tokens": 839, "classes": 229, "sf_classes": 180, "is_classes": 40, @@ -51,7 +51,7 @@ "by_category": { "Accessibility": 7, "Component tokens": 6, - "Core tokens": 496, + "Core tokens": 507, "Layout primitives": 126, "Layout tokens": 52, "Macro classes": 36, @@ -2816,6 +2816,35 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-action-dark", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "area": "core", + "group": "STATUS COLORS (-light source tokens)", + "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "value": "oklch(0.70 0.198 235)", + "aliasOf": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-action-darker", "type": "token", @@ -3815,6 +3844,35 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-base-dark", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "area": "core", + "group": "STATUS COLORS (-light source tokens)", + "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "value": "oklch(0.22 0.003 250)", + "aliasOf": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-base-darker", "type": "token", @@ -4575,6 +4633,35 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-danger-dark", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "area": "core", + "group": "STATUS COLORS (-light source tokens)", + "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "value": "oklch(0.71 0.198 12)", + "aliasOf": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-danger-light", "type": "token", @@ -4749,6 +4836,35 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-error-dark", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "area": "core", + "group": "STATUS COLORS (-light source tokens)", + "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "value": "oklch(0.70 0.18 25)", + "aliasOf": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-error-light", "type": "token", @@ -4923,6 +5039,35 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-info-dark", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "area": "core", + "group": "STATUS COLORS (-light source tokens)", + "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "value": "oklch(0.71 0.162 235)", + "aliasOf": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-info-light", "type": "token", @@ -6032,6 +6177,35 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-neutral-dark", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "area": "core", + "group": "STATUS COLORS (-light source tokens)", + "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "value": "oklch(0.69 0.0225 260)", + "aliasOf": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-neutral-darker", "type": "token", @@ -7060,6 +7234,35 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-primary-dark", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "area": "core", + "group": "STATUS COLORS (-light source tokens)", + "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "value": "oklch(0.715 0.243 264)", + "aliasOf": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-primary-darker", "type": "token", @@ -8117,6 +8320,35 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-secondary-dark", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "area": "core", + "group": "STATUS COLORS (-light source tokens)", + "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "value": "oklch(0.84 0.036 264)", + "aliasOf": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-secondary-darker", "type": "token", @@ -8500,6 +8732,35 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-success-dark", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "area": "core", + "group": "STATUS COLORS (-light source tokens)", + "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "value": "oklch(0.70 0.144 145)", + "aliasOf": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-success-light", "type": "token", @@ -9348,6 +9609,35 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-tertiary-dark", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "area": "core", + "group": "STATUS COLORS (-light source tokens)", + "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "value": "oklch(0.74 0.198 295)", + "aliasOf": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-tertiary-darker", "type": "token", @@ -10224,6 +10514,35 @@ "optimal-utilities" ] }, + { + "name": "--sf-color-warning-dark", + "type": "token", + "tier": "PUBLIC", + "role": "knob", + "namespace": "color", + "category": "Core tokens", + "area": "core", + "group": "STATUS COLORS (-light source tokens)", + "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "value": "oklch(0.65 0.153 80)", + "aliasOf": null, + "registered": true, + "animatable": true, + "syntax": "", + "inherits": true, + "optional": false, + "layer": "slashed.tokens", + "sourceFiles": [ + "core/tokens.css" + ], + "bundles": [ + "essential", + "full", + "optimal", + "optimal-components", + "optimal-utilities" + ] + }, { "name": "--sf-color-warning-light", "type": "token", @@ -16478,7 +16797,7 @@ "category": "Core tokens", "area": "core", "group": "Border radius", - "description": "--sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to…", + "description": "scale ramp, all multiplied by --sf-radius-scale.", "value": "calc(24px * var(--sf-radius-scale))", "aliasOf": null, "registered": false, @@ -16507,7 +16826,7 @@ "category": "Core tokens", "area": "core", "group": "Border radius", - "description": "--sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to…", + "description": "scale ramp, all multiplied by --sf-radius-scale.", "value": "calc(1px * var(--sf-radius-scale))", "aliasOf": null, "registered": false, @@ -16536,7 +16855,7 @@ "category": "Core tokens", "area": "core", "group": "Border radius", - "description": "--sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to…", + "description": "scale ramp, all multiplied by --sf-radius-scale.", "value": "calc(32px * var(--sf-radius-scale))", "aliasOf": null, "registered": false, @@ -16565,7 +16884,7 @@ "category": "Core tokens", "area": "core", "group": "Border radius", - "description": "--sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to…", + "description": "scale ramp, all multiplied by --sf-radius-scale.", "value": "calc(48px * var(--sf-radius-scale))", "aliasOf": null, "registered": false, @@ -16593,8 +16912,8 @@ "namespace": "radius", "category": "Core tokens", "area": "core", - "group": "Border radius", - "description": "--sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to…", + "group": "Full/pill", + "description": "topological constants, not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to half the…", "value": "9999px", "aliasOf": null, "registered": false, @@ -16623,7 +16942,7 @@ "category": "Core tokens", "area": "core", "group": "Border radius", - "description": "--sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to…", + "description": "scale ramp, all multiplied by --sf-radius-scale.", "value": "calc(12px * var(--sf-radius-scale))", "aliasOf": null, "registered": false, @@ -16652,7 +16971,7 @@ "category": "Core tokens", "area": "core", "group": "Border radius", - "description": "--sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to…", + "description": "scale ramp, all multiplied by --sf-radius-scale.", "value": "calc(8px * var(--sf-radius-scale))", "aliasOf": null, "registered": false, @@ -16681,7 +17000,7 @@ "category": "Core tokens", "area": "core", "group": "Border radius", - "description": "--sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to…", + "description": "scale ramp, all multiplied by --sf-radius-scale.", "value": "0", "aliasOf": null, "registered": false, @@ -16709,7 +17028,7 @@ "namespace": "radius", "category": "Core tokens", "area": "core", - "group": "Border radius", + "group": "Full/pill", "description": "Concentric helper — outer radius for a container that wraps content padded by --sf-component-pad with inner radius m. Keeps inner elements visually proportional inside a padded box. Override per use: .my-card { border-radius: var(--sf-radius-outer); } Maths: outer = inner +…", "value": "calc(var(--sf-radius-m) + var(--sf-component-pad))", "aliasOf": null, @@ -16738,7 +17057,7 @@ "namespace": "radius", "category": "Core tokens", "area": "core", - "group": "Border radius", + "group": "Full/pill", "description": "Pill — semantic alias of --sf-radius-full. Reach for this name on rectangles you want capsule-shaped (badges, tags, chips); use --sf-radius-full when you mean \"as round as topologically possible\".", "value": "var(--sf-radius-full)", "aliasOf": "--sf-radius-full", @@ -16768,7 +17087,7 @@ "category": "Core tokens", "area": "core", "group": "Border radius", - "description": "--sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to…", + "description": "scale ramp, all multiplied by --sf-radius-scale.", "value": "calc(4px * var(--sf-radius-scale))", "aliasOf": null, "registered": false, @@ -16826,7 +17145,7 @@ "category": "Core tokens", "area": "core", "group": "Border radius", - "description": "--sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to…", + "description": "scale ramp, all multiplied by --sf-radius-scale.", "value": "calc(16px * var(--sf-radius-scale))", "aliasOf": null, "registered": false, @@ -16855,7 +17174,7 @@ "category": "Core tokens", "area": "core", "group": "Border radius", - "description": "--sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 (\"sharp\" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to…", + "description": "scale ramp, all multiplied by --sf-radius-scale.", "value": "calc(2px * var(--sf-radius-scale))", "aliasOf": null, "registered": false, diff --git a/docs/api-index.md b/docs/api-index.md index 21969c43..57d2da4a 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). -**1057 elements** — 828 tokens, 229 classes. +**1068 elements** — 839 tokens, 229 classes. | Tier | Count | Meaning | |---|---|---| -| PUBLIC | 919 | Everyday surface. SemVer-stable. | +| PUBLIC | 930 | Everyday surface. SemVer-stable. | | PUBLIC-ADVANCED | 137 | Same SemVer guarantee; niche/powerful. | | INTERNAL | 1 | Implementation detail; may change without a major bump. | -## Tokens (828) +## Tokens (839) ### Component tokens (6) @@ -31,7 +31,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-field-padding-inline` | PUBLIC | consumption | field | `var(--sf-space-s)` | Override to give form fields a distinct visual language from buttons without touching global radius/spacing tokens. | | `--sf-field-radius` | PUBLIC | consumption | field | `var(--sf-radius-m)` | Override to give form fields a distinct visual language from buttons without touching global radius/spacing tokens. | -### Core tokens (496) +### Core tokens (507) | Token | Tier | Role | Namespace | Default | Description | |---|---|---|---|---|---| @@ -88,6 +88,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-action` | PUBLIC | consumption | color | `light-dark(var(--sf-color-action-light), var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-action--active` | PUBLIC | consumption | color | `var(--sf-color-action-xdark)` | action | | `--sf-color-action--hover` | PUBLIC | consumption | color | `var(--sf-color-action-darker)` | action | +| `--sf-color-action-dark` | PUBLIC | knob | color | `oklch(0.70 0.198 235)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | | `--sf-color-action-darker` | PUBLIC | consumption | color | `var(--sf-color-action-600)` | action | | `--sf-color-action-ghost` | PUBLIC | consumption | color | `oklch(from var(--sf-color-action) l c h / 0.05)` | action | | `--sf-color-action-light` | PUBLIC | knob | color | `oklch(0.50 0.22 235)` | Override these 6 tokens to rebrand — dark mode auto-derives. Optionally set --sf-color-X-dark (no @property) for full control. | @@ -101,6 +102,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-base` | PUBLIC | consumption | color | `light-dark(var(--sf-color-base-light), var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-base--active` | PUBLIC | consumption | color | `var(--sf-color-base-xdark)` | base | | `--sf-color-base--hover` | PUBLIC | consumption | color | `var(--sf-color-base-darker)` | base | +| `--sf-color-base-dark` | PUBLIC | knob | color | `oklch(0.22 0.003 250)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | | `--sf-color-base-darker` | PUBLIC | consumption | color | `var(--sf-color-base-600)` | base | | `--sf-color-base-ghost` | PUBLIC | consumption | color | `oklch(from var(--sf-color-base) l c h / 0.05)` | base | | `--sf-color-base-light` | PUBLIC | knob | color | `oklch(0.96 0.006 250)` | initial-value is 0.96 (not 0.99) so the +0.02/+0.04 surface offsets produce visually distinct levels in light mode. At 0.99 all lighter surfaces clamp to pure white and become indistinguishable. 0.96 gives: bg=0.98, inset=0.94, raised=1.0→white — all distinct. Consumers using… | @@ -127,18 +129,21 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-code-bg` | PUBLIC | consumption | color | `var(--sf-color-inset)` | plain var aliases (ungated) | | `--sf-color-code-text` | PUBLIC | consumption | color | `oklch(from var(--sf-color-code-bg) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0)` | Inline-code text colour. Auto-contrasts with --sf-color-code-bg using the same luminance formula as --sf-color-text--on-*. This prevents invisible text when code appears inside inverted-colour containers (e.g. sf-imposter with a dark background where inherited colour is… | | `--sf-color-danger` | PUBLIC | consumption | color | `light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | +| `--sf-color-danger-dark` | PUBLIC | knob | color | `oklch(0.71 0.198 12)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | | `--sf-color-danger-light` | PUBLIC | knob | color | `oklch(0.48 0.22 12)` | STATUS COLORS (-light source tokens) | | `--sf-color-danger-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-danger) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-danger-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-danger-light) calc(l - 0.1) c h), oklch(from var(--sf-color-danger) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | | `--sf-color-danger-subtle` | PUBLIC | consumption | color | `oklch(from var(--sf-color-danger) l c h / 0.1)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-dim` | PUBLIC | knob | color | `oklch(0 0 0 / 0.5)` | Dim: classic semi-transparent black for modal backdrops, distinct from --sf-color-overlay | | `--sf-color-error` | PUBLIC | consumption | color | `light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | +| `--sf-color-error-dark` | PUBLIC | knob | color | `oklch(0.70 0.18 25)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | | `--sf-color-error-light` | PUBLIC | knob | color | `oklch(0.50 0.20 25)` | STATUS COLORS (-light source tokens) | | `--sf-color-error-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-error) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-error-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-error-light) calc(l - 0.1) c h), oklch(from var(--sf-color-error) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | | `--sf-color-error-subtle` | PUBLIC | consumption | color | `oklch(from var(--sf-color-error) l c h / 0.1)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-heading` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.05, calc(l - 0.4 - var(--sf-contrast-bias)), 0.35) c h), oklch(from var(--sf-color-neutral) clamp(0.70, calc(l + 0.25 + var(--sf-contrast-bias)), 1) c h) )` | light and dark require opposite formula directions, so each side of light-dark() references its source token. | | `--sf-color-info` | PUBLIC | consumption | color | `light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | +| `--sf-color-info-dark` | PUBLIC | knob | color | `oklch(0.71 0.162 235)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | | `--sf-color-info-light` | PUBLIC | knob | color | `oklch(0.48 0.18 235)` | STATUS COLORS (-light source tokens) | | `--sf-color-info-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-info) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-info-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-info-light) calc(l - 0.1) c h), oklch(from var(--sf-color-info) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | @@ -156,6 +161,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-neutral` | PUBLIC | consumption | color | `light-dark(var(--sf-color-neutral-light), var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-neutral--active` | PUBLIC | consumption | color | `var(--sf-color-neutral-xdark)` | neutral | | `--sf-color-neutral--hover` | PUBLIC | consumption | color | `var(--sf-color-neutral-darker)` | neutral | +| `--sf-color-neutral-dark` | PUBLIC | knob | color | `oklch(0.69 0.0225 260)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | | `--sf-color-neutral-darker` | PUBLIC | consumption | color | `var(--sf-color-neutral-600)` | neutral | | `--sf-color-neutral-ghost` | PUBLIC | consumption | color | `oklch(from var(--sf-color-neutral) l c h / 0.05)` | neutral | | `--sf-color-neutral-light` | PUBLIC | knob | color | `oklch(0.52 0.025 260)` | Override these 6 tokens to rebrand — dark mode auto-derives. Optionally set --sf-color-X-dark (no @property) for full control. | @@ -170,6 +176,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-primary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-primary-light), var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-primary--active` | PUBLIC | consumption | color | `var(--sf-color-primary-xdark)` | primary | | `--sf-color-primary--hover` | PUBLIC | consumption | color | `var(--sf-color-primary-darker)` | primary | +| `--sf-color-primary-dark` | PUBLIC | knob | color | `oklch(0.715 0.243 264)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | | `--sf-color-primary-darker` | PUBLIC | consumption | color | `var(--sf-color-primary-600)` | primary | | `--sf-color-primary-ghost` | PUBLIC | consumption | color | `oklch(from var(--sf-color-primary) l c h / 0.05)` | primary | | `--sf-color-primary-light` | PUBLIC | knob | color | `oklch(0.47 0.27 264)` | Override these 6 tokens to rebrand — dark mode auto-derives. Optionally set --sf-color-X-dark (no @property) for full control. | @@ -185,6 +192,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-secondary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-secondary-light), var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-secondary--active` | PUBLIC | consumption | color | `var(--sf-color-secondary-xdark)` | secondary | | `--sf-color-secondary--hover` | PUBLIC | consumption | color | `var(--sf-color-secondary-darker)` | secondary | +| `--sf-color-secondary-dark` | PUBLIC | knob | color | `oklch(0.84 0.036 264)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | | `--sf-color-secondary-darker` | PUBLIC | consumption | color | `var(--sf-color-secondary-600)` | secondary | | `--sf-color-secondary-ghost` | PUBLIC | consumption | color | `oklch(from var(--sf-color-secondary) l c h / 0.05)` | secondary | | `--sf-color-secondary-light` | PUBLIC | knob | color | `oklch(0.22 0.04 264)` | Override these 6 tokens to rebrand — dark mode auto-derives. Optionally set --sf-color-X-dark (no @property) for full control. | @@ -198,6 +206,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-selection-bg` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-action-light) l c h / 0.28), oklch(from var(--sf-color-action-light) clamp(0.62, calc(0.93 - l * 0.4), 0.78) c h / 0.55) )` | Selection | | `--sf-color-selection-text` | PUBLIC | knob | color | `inherit` | static values (ungated) | | `--sf-color-success` | PUBLIC | consumption | color | `light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | +| `--sf-color-success-dark` | PUBLIC | knob | color | `oklch(0.70 0.144 145)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | | `--sf-color-success-light` | PUBLIC | knob | color | `oklch(0.50 0.16 145)` | STATUS COLORS (-light source tokens) | | `--sf-color-success-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-success) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-success-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-success-light) calc(l - 0.15) c h), oklch(from var(--sf-color-success) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | @@ -206,6 +215,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-tertiary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-tertiary-light), var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-tertiary--active` | PUBLIC | consumption | color | `var(--sf-color-tertiary-xdark)` | tertiary | | `--sf-color-tertiary--hover` | PUBLIC | consumption | color | `var(--sf-color-tertiary-darker)` | tertiary | +| `--sf-color-tertiary-dark` | PUBLIC | knob | color | `oklch(0.74 0.198 295)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | | `--sf-color-tertiary-darker` | PUBLIC | consumption | color | `var(--sf-color-tertiary-600)` | tertiary | | `--sf-color-tertiary-ghost` | PUBLIC | consumption | color | `oklch(from var(--sf-color-tertiary) l c h / 0.05)` | tertiary | | `--sf-color-tertiary-light` | PUBLIC | knob | color | `oklch(0.42 0.22 295)` | Override these 6 tokens to rebrand — dark mode auto-derives. Optionally set --sf-color-X-dark (no @property) for full control. | @@ -236,6 +246,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-text--placeholder` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.45, calc(l + 0.15), 0.75) c h), oklch(from var(--sf-color-neutral) clamp(0.35, calc(l - 0.1), 0.65) c h) )` | light and dark require opposite formula directions, so each side of light-dark() references its source token. | | `--sf-color-text--secondary` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.15, calc(l - 0.25 - var(--sf-contrast-bias)), 0.45) c h), oklch(from var(--sf-color-neutral) clamp(0.55, calc(l + 0.1 + var(--sf-contrast-bias)), 0.90) c h) )` | light and dark require opposite formula directions, so each side of light-dark() references its source token. | | `--sf-color-warning` | PUBLIC | consumption | color | `light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | +| `--sf-color-warning-dark` | PUBLIC | knob | color | `oklch(0.65 0.153 80)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | | `--sf-color-warning-light` | PUBLIC | knob | color | `oklch(0.75 0.17 80)` | STATUS COLORS (-light source tokens) | | `--sf-color-warning-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-warning) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-warning-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-warning-light) calc(l - 0.25) c h), oklch(from var(--sf-color-warning) clamp(0.70, calc(l + 0.05), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | @@ -398,20 +409,20 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-print-base-size` | PUBLIC-ADVANCED | knob | print | `11pt` | Print | | `--sf-print-page-margin` | PUBLIC-ADVANCED | knob | print | `2cm` | Print | | `--sf-print-page-size` | PUBLIC-ADVANCED | knob | print | `a4` | Print | -| `--sf-radius-2xl` | PUBLIC | consumption | radius | `calc(24px * var(--sf-radius-scale))` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | -| `--sf-radius-2xs` | PUBLIC | consumption | radius | `calc(1px * var(--sf-radius-scale))` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | -| `--sf-radius-3xl` | PUBLIC | consumption | radius | `calc(32px * var(--sf-radius-scale))` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | -| `--sf-radius-4xl` | PUBLIC | consumption | radius | `calc(48px * var(--sf-radius-scale))` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | -| `--sf-radius-full` | PUBLIC | knob | radius | `9999px` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | -| `--sf-radius-l` | PUBLIC | consumption | radius | `calc(12px * var(--sf-radius-scale))` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | -| `--sf-radius-m` | PUBLIC | consumption | radius | `calc(8px * var(--sf-radius-scale))` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | -| `--sf-radius-none` | PUBLIC | knob | radius | `0` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | +| `--sf-radius-2xl` | PUBLIC | consumption | radius | `calc(24px * var(--sf-radius-scale))` | scale ramp, all multiplied by --sf-radius-scale. | +| `--sf-radius-2xs` | PUBLIC | consumption | radius | `calc(1px * var(--sf-radius-scale))` | scale ramp, all multiplied by --sf-radius-scale. | +| `--sf-radius-3xl` | PUBLIC | consumption | radius | `calc(32px * var(--sf-radius-scale))` | scale ramp, all multiplied by --sf-radius-scale. | +| `--sf-radius-4xl` | PUBLIC | consumption | radius | `calc(48px * var(--sf-radius-scale))` | scale ramp, all multiplied by --sf-radius-scale. | +| `--sf-radius-full` | PUBLIC | knob | radius | `9999px` | topological constants, not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to half the… | +| `--sf-radius-l` | PUBLIC | consumption | radius | `calc(12px * var(--sf-radius-scale))` | scale ramp, all multiplied by --sf-radius-scale. | +| `--sf-radius-m` | PUBLIC | consumption | radius | `calc(8px * var(--sf-radius-scale))` | scale ramp, all multiplied by --sf-radius-scale. | +| `--sf-radius-none` | PUBLIC | knob | radius | `0` | scale ramp, all multiplied by --sf-radius-scale. | | `--sf-radius-outer` | PUBLIC-ADVANCED | consumption | radius | `calc(var(--sf-radius-m) + var(--sf-component-pad))` | Concentric helper — outer radius for a container that wraps content padded by --sf-component-pad with inner radius m. Keeps inner elements visually proportional inside a padded box. Override per use: .my-card { border-radius: var(--sf-radius-outer); } Maths: outer = inner +… | | `--sf-radius-pill` | PUBLIC | consumption | radius | `var(--sf-radius-full)` | Pill — semantic alias of --sf-radius-full. Reach for this name on rectangles you want capsule-shaped (badges, tags, chips); use --sf-radius-full when you mean "as round as topologically possible". | -| `--sf-radius-s` | PUBLIC | consumption | radius | `calc(4px * var(--sf-radius-scale))` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | +| `--sf-radius-s` | PUBLIC | consumption | radius | `calc(4px * var(--sf-radius-scale))` | scale ramp, all multiplied by --sf-radius-scale. | | `--sf-radius-scale` | PUBLIC-ADVANCED | knob | radius | `1` | Scale multipliers | -| `--sf-radius-xl` | PUBLIC | consumption | radius | `calc(16px * var(--sf-radius-scale))` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | -| `--sf-radius-xs` | PUBLIC | consumption | radius | `calc(2px * var(--sf-radius-scale))` | --sf-radius-full: intentionally not scaled by --sf-radius-scale. A pill/circle is a topological constant, not a relative size: any --sf-radius-scale: 0 ("sharp" design system) should still render pill buttons as pills. 9999px is a magic-number convention large enough to clip to… | +| `--sf-radius-xl` | PUBLIC | consumption | radius | `calc(16px * var(--sf-radius-scale))` | scale ramp, all multiplied by --sf-radius-scale. | +| `--sf-radius-xs` | PUBLIC | consumption | radius | `calc(2px * var(--sf-radius-scale))` | scale ramp, all multiplied by --sf-radius-scale. | | `--sf-ratio-3-2` | PUBLIC | knob | ratio | `3 / 2` | Aspect ratios | | `--sf-ratio-4-3` | PUBLIC | knob | ratio | `4 / 3` | Aspect ratios | | `--sf-ratio-cinema` | PUBLIC | knob | ratio | `21 / 9` | Aspect ratios | diff --git a/docs/registry.json b/docs/registry.json index c169f8c5..3eb17f8b 100644 --- a/docs/registry.json +++ b/docs/registry.json @@ -20,7 +20,7 @@ "optional/theme-example.css" ], "counts": { - "tokens": 828, + "tokens": 839, "sf_classes": 180, "is_classes": 40 } @@ -121,6 +121,7 @@ "--sf-color-action-a80", "--sf-color-action-a90", "--sf-color-action-a95", + "--sf-color-action-dark", "--sf-color-action-darker", "--sf-color-action-ghost", "--sf-color-action-light", @@ -156,6 +157,7 @@ "--sf-color-base-a80", "--sf-color-base-a90", "--sf-color-base-a95", + "--sf-color-base-dark", "--sf-color-base-darker", "--sf-color-base-ghost", "--sf-color-base-light", @@ -182,18 +184,21 @@ "--sf-color-code-bg", "--sf-color-code-text", "--sf-color-danger", + "--sf-color-danger-dark", "--sf-color-danger-light", "--sf-color-danger-muted", "--sf-color-danger-strong", "--sf-color-danger-subtle", "--sf-color-dim", "--sf-color-error", + "--sf-color-error-dark", "--sf-color-error-light", "--sf-color-error-muted", "--sf-color-error-strong", "--sf-color-error-subtle", "--sf-color-heading", "--sf-color-info", + "--sf-color-info-dark", "--sf-color-info-light", "--sf-color-info-muted", "--sf-color-info-strong", @@ -233,6 +238,7 @@ "--sf-color-neutral-a80", "--sf-color-neutral-a90", "--sf-color-neutral-a95", + "--sf-color-neutral-dark", "--sf-color-neutral-darker", "--sf-color-neutral-ghost", "--sf-color-neutral-light", @@ -269,6 +275,7 @@ "--sf-color-primary-a80", "--sf-color-primary-a90", "--sf-color-primary-a95", + "--sf-color-primary-dark", "--sf-color-primary-darker", "--sf-color-primary-ghost", "--sf-color-primary-light", @@ -306,6 +313,7 @@ "--sf-color-secondary-a80", "--sf-color-secondary-a90", "--sf-color-secondary-a95", + "--sf-color-secondary-dark", "--sf-color-secondary-darker", "--sf-color-secondary-ghost", "--sf-color-secondary-light", @@ -319,6 +327,7 @@ "--sf-color-selection-bg", "--sf-color-selection-text", "--sf-color-success", + "--sf-color-success-dark", "--sf-color-success-light", "--sf-color-success-muted", "--sf-color-success-strong", @@ -349,6 +358,7 @@ "--sf-color-tertiary-a80", "--sf-color-tertiary-a90", "--sf-color-tertiary-a95", + "--sf-color-tertiary-dark", "--sf-color-tertiary-darker", "--sf-color-tertiary-ghost", "--sf-color-tertiary-light", @@ -379,6 +389,7 @@ "--sf-color-text--placeholder", "--sf-color-text--secondary", "--sf-color-warning", + "--sf-color-warning-dark", "--sf-color-warning-light", "--sf-color-warning-muted", "--sf-color-warning-strong", diff --git a/docs/token-annotations.json b/docs/token-annotations.json index 4d042cb3..f5be09d5 100644 --- a/docs/token-annotations.json +++ b/docs/token-annotations.json @@ -264,6 +264,7 @@ "--sf-tracking-widest": "Widest letter-spacing for all-caps microcopy.", "--sf-font-numeric": "font-variant-numeric shorthand (e.g. tabular-nums) for aligned numeric data.", "--sf-radius-none": "Zero border radius — square corners.", + "--sf-radius-2xs": "Extra-extra-small radius (~1px). Minimal rounding for very tight UI elements.", "--sf-radius-xs": "Hairline radius (~2px). Subtle rounding for tight components.", "--sf-radius-s": "Small radius (~4px). Badges, chips, small buttons.", "--sf-radius-m": "Medium radius (~6–8px). Default — inputs, standard buttons, cards.", diff --git a/docs/token-index.json b/docs/token-index.json index 8a147cc6..4426c8f3 100644 --- a/docs/token-index.json +++ b/docs/token-index.json @@ -10,14 +10,14 @@ "optional/tokens.components.css" ], "counts": { - "tokens": 828, + "tokens": 839, "by_tier": { - "PUBLIC": 690, + "PUBLIC": 701, "PUBLIC-ADVANCED": 137, "INTERNAL": 1 }, "by_role": { - "knob": 236, + "knob": 247, "consumption": 592 } } @@ -783,6 +783,14 @@ ], "value": "oklch(from var(--sf-color-action) l c h / 0.95)" }, + "--sf-color-action-dark": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.css" + ], + "value": "oklch(0.70 0.198 235) (registered)" + }, "--sf-color-action-darker": { "tier": "PUBLIC", "role": "consumption", @@ -1069,6 +1077,14 @@ ], "value": "oklch(from var(--sf-color-base) l c h / 0.95)" }, + "--sf-color-base-dark": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.css" + ], + "value": "oklch(0.22 0.003 250) (registered)" + }, "--sf-color-base-darker": { "tier": "PUBLIC", "role": "consumption", @@ -1283,6 +1299,14 @@ ], "value": "light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))" }, + "--sf-color-danger-dark": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.css" + ], + "value": "oklch(0.71 0.198 12) (registered)" + }, "--sf-color-danger-light": { "tier": "PUBLIC", "role": "knob", @@ -1331,6 +1355,14 @@ ], "value": "light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))" }, + "--sf-color-error-dark": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.css" + ], + "value": "oklch(0.70 0.18 25) (registered)" + }, "--sf-color-error-light": { "tier": "PUBLIC", "role": "knob", @@ -1379,6 +1411,14 @@ ], "value": "light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))" }, + "--sf-color-info-dark": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.css" + ], + "value": "oklch(0.71 0.162 235) (registered)" + }, "--sf-color-info-light": { "tier": "PUBLIC", "role": "knob", @@ -1691,6 +1731,14 @@ ], "value": "oklch(from var(--sf-color-neutral) l c h / 0.95)" }, + "--sf-color-neutral-dark": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.css" + ], + "value": "oklch(0.69 0.0225 260) (registered)" + }, "--sf-color-neutral-darker": { "tier": "PUBLIC", "role": "consumption", @@ -1985,6 +2033,14 @@ ], "value": "oklch(from var(--sf-color-primary) l c h / 0.95)" }, + "--sf-color-primary-dark": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.css" + ], + "value": "oklch(0.715 0.243 264) (registered)" + }, "--sf-color-primary-darker": { "tier": "PUBLIC", "role": "consumption", @@ -2287,6 +2343,14 @@ ], "value": "oklch(from var(--sf-color-secondary) l c h / 0.95)" }, + "--sf-color-secondary-dark": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.css" + ], + "value": "oklch(0.84 0.036 264) (registered)" + }, "--sf-color-secondary-darker": { "tier": "PUBLIC", "role": "consumption", @@ -2397,6 +2461,14 @@ ], "value": "light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))" }, + "--sf-color-success-dark": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.css" + ], + "value": "oklch(0.70 0.144 145) (registered)" + }, "--sf-color-success-light": { "tier": "PUBLIC", "role": "knob", @@ -2637,6 +2709,14 @@ ], "value": "oklch(from var(--sf-color-tertiary) l c h / 0.95)" }, + "--sf-color-tertiary-dark": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.css" + ], + "value": "oklch(0.74 0.198 295) (registered)" + }, "--sf-color-tertiary-darker": { "tier": "PUBLIC", "role": "consumption", @@ -2883,6 +2963,14 @@ ], "value": "light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))" }, + "--sf-color-warning-dark": { + "tier": "PUBLIC", + "role": "knob", + "files": [ + "core/tokens.css" + ], + "value": "oklch(0.65 0.153 80) (registered)" + }, "--sf-color-warning-light": { "tier": "PUBLIC", "role": "knob", diff --git a/docs/token-index.md b/docs/token-index.md index 27402a49..ed832522 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). -**828 tokens** (deduplicated by name across the 6 token source files). +**839 tokens** (deduplicated by name across the 6 token source files). | Tier | Count | Meaning | |---|---|---| -| PUBLIC | 690 | Everyday knobs. SemVer-stable. | +| PUBLIC | 701 | Everyday knobs. SemVer-stable. | | PUBLIC-ADVANCED | 137 | Same SemVer guarantee; niche/powerful. | | INTERNAL | 1 | Implementation detail; may change without a major bump. | @@ -22,7 +22,7 @@ declared value (a value that references `var(--sf-…)` is a derived output): | Role | Count | Meaning | |---|---|---| -| knob | 236 | Input you **set** to configure the system (a literal primitive: length, number, colour literal, keyword, font stack, easing curve …). | +| knob | 247 | Input you **set** to configure the system (a literal primitive: length, number, colour literal, keyword, font stack, easing curve …). | | consumption | 592 | Ready-to-use output you **read**; derived from other tokens via `var(--sf-…)` (incl. `light-dark()`/`oklch(from …)`/`color-mix()`). | ## INTERNAL tokens @@ -268,6 +268,7 @@ declared value (a value that references `var(--sf-…)` is a derived output): | `--sf-color-action-a80` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-action) l c h / 0.80)` | | `--sf-color-action-a90` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-action) l c h / 0.90)` | | `--sf-color-action-a95` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-action) l c h / 0.95)` | +| `--sf-color-action-dark` | PUBLIC | knob | Core | `oklch(0.70 0.198 235) (registered)` | | `--sf-color-action-darker` | PUBLIC | consumption | Core + Palette (optional) | `var(--sf-color-action-600)` | | `--sf-color-action-ghost` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-action) l c h / 0.05)` | | `--sf-color-action-light` | PUBLIC | knob | Core | `oklch(0.50 0.22 235)` | @@ -303,6 +304,7 @@ declared value (a value that references `var(--sf-…)` is a derived output): | `--sf-color-base-a80` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-base) l c h / 0.80)` | | `--sf-color-base-a90` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-base) l c h / 0.90)` | | `--sf-color-base-a95` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-base) l c h / 0.95)` | +| `--sf-color-base-dark` | PUBLIC | knob | Core | `oklch(0.22 0.003 250) (registered)` | | `--sf-color-base-darker` | PUBLIC | consumption | Core + Palette (optional) | `var(--sf-color-base-600)` | | `--sf-color-base-ghost` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-base) l c h / 0.05)` | | `--sf-color-base-light` | PUBLIC | knob | Core | `oklch(0.96 0.006 250)` | @@ -329,18 +331,21 @@ declared value (a value that references `var(--sf-…)` is a derived output): | `--sf-color-code-bg` | PUBLIC | consumption | Core | `var(--sf-color-inset)` | | `--sf-color-code-text` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-code-bg) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0)` | | `--sf-color-danger` | PUBLIC | consumption | Core | `light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | +| `--sf-color-danger-dark` | PUBLIC | knob | Core | `oklch(0.71 0.198 12) (registered)` | | `--sf-color-danger-light` | PUBLIC | knob | Core | `oklch(0.48 0.22 12)` | | `--sf-color-danger-muted` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-danger) l c h / 0.3)` | | `--sf-color-danger-strong` | PUBLIC | consumption | Core | `light-dark( oklch(from var(--sf-color-danger-light) calc(l - 0.1) c h), oklch(from var(--sf-color-danger) clamp(0.70, calc(l + 0.15), 1) c h) )` | | `--sf-color-danger-subtle` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-danger) l c h / 0.1)` | | `--sf-color-dim` | PUBLIC | knob | Core | `oklch(0 0 0 / 0.5)` | | `--sf-color-error` | PUBLIC | consumption | Core | `light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | +| `--sf-color-error-dark` | PUBLIC | knob | Core | `oklch(0.70 0.18 25) (registered)` | | `--sf-color-error-light` | PUBLIC | knob | Core | `oklch(0.50 0.20 25)` | | `--sf-color-error-muted` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-error) l c h / 0.3)` | | `--sf-color-error-strong` | PUBLIC | consumption | Core | `light-dark( oklch(from var(--sf-color-error-light) calc(l - 0.1) c h), oklch(from var(--sf-color-error) clamp(0.70, calc(l + 0.15), 1) c h) )` | | `--sf-color-error-subtle` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-error) l c h / 0.1)` | | `--sf-color-heading` | PUBLIC | consumption | Core | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.05, calc(l - 0.4 - var(--sf-contrast-bias)), 0.35) c h), oklch(from var(--sf-color-neutral) clamp(0.70, calc(l + 0.25 + var(--sf-contrast-bias)), 1) c h) )` | | `--sf-color-info` | PUBLIC | consumption | Core | `light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | +| `--sf-color-info-dark` | PUBLIC | knob | Core | `oklch(0.71 0.162 235) (registered)` | | `--sf-color-info-light` | PUBLIC | knob | Core | `oklch(0.48 0.18 235)` | | `--sf-color-info-muted` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-info) l c h / 0.3)` | | `--sf-color-info-strong` | PUBLIC | consumption | Core | `light-dark( oklch(from var(--sf-color-info-light) calc(l - 0.1) c h), oklch(from var(--sf-color-info) clamp(0.70, calc(l + 0.15), 1) c h) )` | @@ -380,6 +385,7 @@ declared value (a value that references `var(--sf-…)` is a derived output): | `--sf-color-neutral-a80` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-neutral) l c h / 0.80)` | | `--sf-color-neutral-a90` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-neutral) l c h / 0.90)` | | `--sf-color-neutral-a95` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-neutral) l c h / 0.95)` | +| `--sf-color-neutral-dark` | PUBLIC | knob | Core | `oklch(0.69 0.0225 260) (registered)` | | `--sf-color-neutral-darker` | PUBLIC | consumption | Core + Palette (optional) | `var(--sf-color-neutral-600)` | | `--sf-color-neutral-ghost` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-neutral) l c h / 0.05)` | | `--sf-color-neutral-light` | PUBLIC | knob | Core | `oklch(0.52 0.025 260)` | @@ -416,6 +422,7 @@ declared value (a value that references `var(--sf-…)` is a derived output): | `--sf-color-primary-a80` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-primary) l c h / 0.80)` | | `--sf-color-primary-a90` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-primary) l c h / 0.90)` | | `--sf-color-primary-a95` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-primary) l c h / 0.95)` | +| `--sf-color-primary-dark` | PUBLIC | knob | Core | `oklch(0.715 0.243 264) (registered)` | | `--sf-color-primary-darker` | PUBLIC | consumption | Core + Palette (optional) | `var(--sf-color-primary-600)` | | `--sf-color-primary-ghost` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-primary) l c h / 0.05)` | | `--sf-color-primary-light` | PUBLIC | knob | Core | `oklch(0.47 0.27 264)` | @@ -453,6 +460,7 @@ declared value (a value that references `var(--sf-…)` is a derived output): | `--sf-color-secondary-a80` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-secondary) l c h / 0.80)` | | `--sf-color-secondary-a90` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-secondary) l c h / 0.90)` | | `--sf-color-secondary-a95` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-secondary) l c h / 0.95)` | +| `--sf-color-secondary-dark` | PUBLIC | knob | Core | `oklch(0.84 0.036 264) (registered)` | | `--sf-color-secondary-darker` | PUBLIC | consumption | Core + Palette (optional) | `var(--sf-color-secondary-600)` | | `--sf-color-secondary-ghost` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-secondary) l c h / 0.05)` | | `--sf-color-secondary-light` | PUBLIC | knob | Core | `oklch(0.22 0.04 264)` | @@ -466,6 +474,7 @@ declared value (a value that references `var(--sf-…)` is a derived output): | `--sf-color-selection-bg` | PUBLIC | consumption | Core | `light-dark( oklch(from var(--sf-color-action-light) l c h / 0.28), oklch(from var(--sf-color-action-light) clamp(0.62, calc(0.93 - l * 0.4), 0.78) c h / 0.55) )` | | `--sf-color-selection-text` | PUBLIC | knob | Core | `inherit` | | `--sf-color-success` | PUBLIC | consumption | Core | `light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | +| `--sf-color-success-dark` | PUBLIC | knob | Core | `oklch(0.70 0.144 145) (registered)` | | `--sf-color-success-light` | PUBLIC | knob | Core | `oklch(0.50 0.16 145)` | | `--sf-color-success-muted` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-success) l c h / 0.3)` | | `--sf-color-success-strong` | PUBLIC | consumption | Core | `light-dark( oklch(from var(--sf-color-success-light) calc(l - 0.15) c h), oklch(from var(--sf-color-success) clamp(0.70, calc(l + 0.15), 1) c h) )` | @@ -496,6 +505,7 @@ declared value (a value that references `var(--sf-…)` is a derived output): | `--sf-color-tertiary-a80` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-tertiary) l c h / 0.80)` | | `--sf-color-tertiary-a90` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-tertiary) l c h / 0.90)` | | `--sf-color-tertiary-a95` | PUBLIC | consumption | Palette (optional) | `oklch(from var(--sf-color-tertiary) l c h / 0.95)` | +| `--sf-color-tertiary-dark` | PUBLIC | knob | Core | `oklch(0.74 0.198 295) (registered)` | | `--sf-color-tertiary-darker` | PUBLIC | consumption | Core + Palette (optional) | `var(--sf-color-tertiary-600)` | | `--sf-color-tertiary-ghost` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-tertiary) l c h / 0.05)` | | `--sf-color-tertiary-light` | PUBLIC | knob | Core | `oklch(0.42 0.22 295)` | @@ -526,6 +536,7 @@ declared value (a value that references `var(--sf-…)` is a derived output): | `--sf-color-text--placeholder` | PUBLIC | consumption | Core | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.45, calc(l + 0.15), 0.75) c h), oklch(from var(--sf-color-neutral) clamp(0.35, calc(l - 0.1), 0.65) c h) )` | | `--sf-color-text--secondary` | PUBLIC | consumption | Core | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.15, calc(l - 0.25 - var(--sf-contrast-bias)), 0.45) c h), oklch(from var(--sf-color-neutral) clamp(0.55, calc(l + 0.1 + var(--sf-contrast-bias)), 0.90) c h) )` | | `--sf-color-warning` | PUBLIC | consumption | Core | `light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | +| `--sf-color-warning-dark` | PUBLIC | knob | Core | `oklch(0.65 0.153 80) (registered)` | | `--sf-color-warning-light` | PUBLIC | knob | Core | `oklch(0.75 0.17 80)` | | `--sf-color-warning-muted` | PUBLIC | consumption | Core | `oklch(from var(--sf-color-warning) l c h / 0.3)` | | `--sf-color-warning-strong` | PUBLIC | consumption | Core | `light-dark( oklch(from var(--sf-color-warning-light) calc(l - 0.25) c h), oklch(from var(--sf-color-warning) clamp(0.70, calc(l + 0.05), 1) c h) )` | diff --git a/docs/tokens.md b/docs/tokens.md index b04d767c..da6cc3ec 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. -**864 tokens.** Every `--sf-*` custom property and its default value, grouped by source file. +**875 tokens.** Every `--sf-*` custom property and its default value, grouped by source file. Tokens defined in multiple files (e.g. shade aliases overridden in `optional/tokens.palette.css`) are listed once per section — so this count is higher than `docs/registry.json` (which deduplicates by name). See @@ -14,7 +14,7 @@ rebrand workflow. ## Core tokens (`core/tokens.css`) -496 tokens. +507 tokens. | Token | Default | |---|---| @@ -71,6 +71,7 @@ rebrand workflow. | `--sf-color-action` | `light-dark(var(--sf-color-action-light), var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | | `--sf-color-action--active` | `var(--sf-color-action-xdark)` | | `--sf-color-action--hover` | `var(--sf-color-action-darker)` | +| `--sf-color-action-dark` | `oklch(0.70 0.198 235) *(registered)*` | | `--sf-color-action-darker` | `color-mix(in oklab, var(--sf-color-action) 82%, var(--sf-color-text))` | | `--sf-color-action-ghost` | `oklch(from var(--sf-color-action) l c h / 0.05)` | | `--sf-color-action-light` | `oklch(0.50 0.22 235)` | @@ -84,6 +85,7 @@ rebrand workflow. | `--sf-color-base` | `light-dark(var(--sf-color-base-light), var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)))` | | `--sf-color-base--active` | `var(--sf-color-base-xdark)` | | `--sf-color-base--hover` | `var(--sf-color-base-darker)` | +| `--sf-color-base-dark` | `oklch(0.22 0.003 250) *(registered)*` | | `--sf-color-base-darker` | `color-mix(in oklab, var(--sf-color-base) 82%, var(--sf-color-text))` | | `--sf-color-base-ghost` | `oklch(from var(--sf-color-base) l c h / 0.05)` | | `--sf-color-base-light` | `oklch(0.96 0.006 250)` | @@ -110,18 +112,21 @@ rebrand workflow. | `--sf-color-code-bg` | `var(--sf-color-inset)` | | `--sf-color-code-text` | `oklch(from var(--sf-color-code-bg) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0)` | | `--sf-color-danger` | `light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | +| `--sf-color-danger-dark` | `oklch(0.71 0.198 12) *(registered)*` | | `--sf-color-danger-light` | `oklch(0.48 0.22 12)` | | `--sf-color-danger-muted` | `oklch(from var(--sf-color-danger) l c h / 0.3)` | | `--sf-color-danger-strong` | `light-dark( oklch(from var(--sf-color-danger-light) calc(l - 0.1) c h), oklch(from var(--sf-color-danger) clamp(0.70, calc(l + 0.15), 1) c h) )` | | `--sf-color-danger-subtle` | `oklch(from var(--sf-color-danger) l c h / 0.1)` | | `--sf-color-dim` | `oklch(0 0 0 / 0.5)` | | `--sf-color-error` | `light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | +| `--sf-color-error-dark` | `oklch(0.70 0.18 25) *(registered)*` | | `--sf-color-error-light` | `oklch(0.50 0.20 25)` | | `--sf-color-error-muted` | `oklch(from var(--sf-color-error) l c h / 0.3)` | | `--sf-color-error-strong` | `light-dark( oklch(from var(--sf-color-error-light) calc(l - 0.1) c h), oklch(from var(--sf-color-error) clamp(0.70, calc(l + 0.15), 1) c h) )` | | `--sf-color-error-subtle` | `oklch(from var(--sf-color-error) l c h / 0.1)` | | `--sf-color-heading` | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.05, calc(l - 0.4 - var(--sf-contrast-bias)), 0.35) c h), oklch(from var(--sf-color-neutral) clamp(0.70, calc(l + 0.25 + var(--sf-contrast-bias)), 1) c h) )` | | `--sf-color-info` | `light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | +| `--sf-color-info-dark` | `oklch(0.71 0.162 235) *(registered)*` | | `--sf-color-info-light` | `oklch(0.48 0.18 235)` | | `--sf-color-info-muted` | `oklch(from var(--sf-color-info) l c h / 0.3)` | | `--sf-color-info-strong` | `light-dark( oklch(from var(--sf-color-info-light) calc(l - 0.1) c h), oklch(from var(--sf-color-info) clamp(0.70, calc(l + 0.15), 1) c h) )` | @@ -139,6 +144,7 @@ rebrand workflow. | `--sf-color-neutral` | `light-dark(var(--sf-color-neutral-light), var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | | `--sf-color-neutral--active` | `var(--sf-color-neutral-xdark)` | | `--sf-color-neutral--hover` | `var(--sf-color-neutral-darker)` | +| `--sf-color-neutral-dark` | `oklch(0.69 0.0225 260) *(registered)*` | | `--sf-color-neutral-darker` | `color-mix(in oklab, var(--sf-color-neutral) 82%, var(--sf-color-text))` | | `--sf-color-neutral-ghost` | `oklch(from var(--sf-color-neutral) l c h / 0.05)` | | `--sf-color-neutral-light` | `oklch(0.52 0.025 260)` | @@ -153,6 +159,7 @@ rebrand workflow. | `--sf-color-primary` | `light-dark(var(--sf-color-primary-light), var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | | `--sf-color-primary--active` | `var(--sf-color-primary-xdark)` | | `--sf-color-primary--hover` | `var(--sf-color-primary-darker)` | +| `--sf-color-primary-dark` | `oklch(0.715 0.243 264) *(registered)*` | | `--sf-color-primary-darker` | `color-mix(in oklab, var(--sf-color-primary) 82%, var(--sf-color-text))` | | `--sf-color-primary-ghost` | `oklch(from var(--sf-color-primary) l c h / 0.05)` | | `--sf-color-primary-light` | `oklch(0.47 0.27 264)` | @@ -168,6 +175,7 @@ rebrand workflow. | `--sf-color-secondary` | `light-dark(var(--sf-color-secondary-light), var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | | `--sf-color-secondary--active` | `var(--sf-color-secondary-xdark)` | | `--sf-color-secondary--hover` | `var(--sf-color-secondary-darker)` | +| `--sf-color-secondary-dark` | `oklch(0.84 0.036 264) *(registered)*` | | `--sf-color-secondary-darker` | `color-mix(in oklab, var(--sf-color-secondary) 82%, var(--sf-color-text))` | | `--sf-color-secondary-ghost` | `oklch(from var(--sf-color-secondary) l c h / 0.05)` | | `--sf-color-secondary-light` | `oklch(0.22 0.04 264)` | @@ -181,6 +189,7 @@ rebrand workflow. | `--sf-color-selection-bg` | `light-dark( oklch(from var(--sf-color-action-light) l c h / 0.28), oklch(from var(--sf-color-action-light) clamp(0.62, calc(0.93 - l * 0.4), 0.78) c h / 0.55) )` | | `--sf-color-selection-text` | `inherit` | | `--sf-color-success` | `light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | +| `--sf-color-success-dark` | `oklch(0.70 0.144 145) *(registered)*` | | `--sf-color-success-light` | `oklch(0.50 0.16 145)` | | `--sf-color-success-muted` | `oklch(from var(--sf-color-success) l c h / 0.3)` | | `--sf-color-success-strong` | `light-dark( oklch(from var(--sf-color-success-light) calc(l - 0.15) c h), oklch(from var(--sf-color-success) clamp(0.70, calc(l + 0.15), 1) c h) )` | @@ -189,6 +198,7 @@ rebrand workflow. | `--sf-color-tertiary` | `light-dark(var(--sf-color-tertiary-light), var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | | `--sf-color-tertiary--active` | `var(--sf-color-tertiary-xdark)` | | `--sf-color-tertiary--hover` | `var(--sf-color-tertiary-darker)` | +| `--sf-color-tertiary-dark` | `oklch(0.74 0.198 295) *(registered)*` | | `--sf-color-tertiary-darker` | `color-mix(in oklab, var(--sf-color-tertiary) 82%, var(--sf-color-text))` | | `--sf-color-tertiary-ghost` | `oklch(from var(--sf-color-tertiary) l c h / 0.05)` | | `--sf-color-tertiary-light` | `oklch(0.42 0.22 295)` | @@ -219,6 +229,7 @@ rebrand workflow. | `--sf-color-text--placeholder` | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.45, calc(l + 0.15), 0.75) c h), oklch(from var(--sf-color-neutral) clamp(0.35, calc(l - 0.1), 0.65) c h) )` | | `--sf-color-text--secondary` | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.15, calc(l - 0.25 - var(--sf-contrast-bias)), 0.45) c h), oklch(from var(--sf-color-neutral) clamp(0.55, calc(l + 0.1 + var(--sf-contrast-bias)), 0.90) c h) )` | | `--sf-color-warning` | `light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | +| `--sf-color-warning-dark` | `oklch(0.65 0.153 80) *(registered)*` | | `--sf-color-warning-light` | `oklch(0.75 0.17 80)` | | `--sf-color-warning-muted` | `oklch(from var(--sf-color-warning) l c h / 0.3)` | | `--sf-color-warning-strong` | `light-dark( oklch(from var(--sf-color-warning-light) calc(l - 0.25) c h), oklch(from var(--sf-color-warning) clamp(0.70, calc(l + 0.05), 1) c h) )` | diff --git a/tests/baseline-modern.json b/tests/baseline-modern.json index b6591af3..775d7f1f 100644 --- a/tests/baseline-modern.json +++ b/tests/baseline-modern.json @@ -1,68 +1,68 @@ { - "dark": { - "--sf-color-primary": "oklch(from oklch(0.47 0.27 264) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)", - "--sf-color-secondary": "oklch(from oklch(0.22 0.04 264) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)", - "--sf-color-tertiary": "oklch(from oklch(0.42 0.22 295) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)", - "--sf-color-action": "oklch(from oklch(0.5 0.22 235) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)", - "--sf-color-neutral": "oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)", - "--sf-color-base": "oklch(from oklch(0.96 0.006 250) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)", - "--sf-color-success": "oklch(from oklch(0.5 0.16 145) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)", - "--sf-color-warning": "oklch(from oklch(0.75 0.17 80) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)", - "--sf-color-error": "oklch(from oklch(0.5 0.2 25) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)", - "--sf-color-info": "oklch(from oklch(0.48 0.18 235) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)", - "--sf-color-danger": "oklch(from oklch(0.48 0.22 12) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)", - "--sf-color-bg": "oklch(from oklch(from oklch(0.96 0.006 250) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h) calc(l + 0.02) c h)", - "--sf-color-inset": "oklch(from oklch(from oklch(0.96 0.006 250) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h) calc(l - 0.02) c h)", - "--sf-color-raised": "oklch(from oklch(from oklch(0.96 0.006 250) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h) calc(l + 0.04) c h)", - "--sf-color-text": "oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) clamp(0.70, calc(l + 0.25 + 0), 1) c h)", - "--sf-color-text--secondary": "oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) clamp(0.55, calc(l + 0.1 + 0), 0.90) c h)", - "--sf-color-heading": "oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) clamp(0.70, calc(l + 0.25 + 0), 1) c h)", - "--sf-color-border": "oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) clamp(0.25, calc(l - 0.3), 0.55) 0.005 h)", - "--sf-color-border--subtle": "oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) clamp(0.20, calc(l - 0.38), 0.45) 0.005 h)", - "--sf-color-border--strong": "oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) clamp(0.38, calc(l - 0.1), 0.65) 0.02 h)", - "--sf-color-link": "oklch(from oklch(from oklch(0.5 0.22 235) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) clamp(0.68, l, 1) c h)", - "--sf-color-selection-bg": "oklch(from oklch(0.5 0.22 235) clamp(0.62, calc(0.93 - l * 0.4), 0.78) c h / 0.55)", - "--sf-color-success-strong": "oklch(from oklch(from oklch(0.5 0.16 145) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) clamp(0.70, calc(l + 0.15), 1) c h)", - "--sf-color-warning-strong": "oklch(from oklch(from oklch(0.75 0.17 80) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) clamp(0.70, calc(l + 0.05), 1) c h)", - "--sf-color-error-strong": "oklch(from oklch(from oklch(0.5 0.2 25) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) clamp(0.70, calc(l + 0.15), 1) c h)", - "--sf-color-info-strong": "oklch(from oklch(from oklch(0.48 0.18 235) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) clamp(0.70, calc(l + 0.15), 1) c h)", - "--sf-color-danger-strong": "oklch(from oklch(from oklch(0.48 0.22 12) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) clamp(0.70, calc(l + 0.15), 1) c h)", - "--sf-shadow-xs": "0 1px 2px 0 oklch(from oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 0.5), 0.7))", - "--sf-shadow-s": "0 1px 2px 0 oklch(from oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 0.5), 0.7)),\n 0 2px 6px 0 oklch(from oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) 0.15 c h) l c h / clamp(0, calc(0.08 + 1 * 0.17), 0.7))", - "--sf-shadow-m": "0 1px 3px 0 oklch(from oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 0.5), 0.7)),\n 0 4px 12px 0 oklch(from oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 2), 0.7))", - "--sf-shadow-l": "0 2px 4px 0 oklch(from oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 0.5), 0.7)),\n 0 8px 24px 0 oklch(from oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 3), 0.7)),\n 0 16px 48px 0 oklch(from oklch(from oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 2), 0.7))" - }, "light": { - "--sf-color-primary": "light-dark(oklch(0.47 0.27 264), oklch(from oklch(0.47 0.27 264) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h))", - "--sf-color-secondary": "light-dark(oklch(0.22 0.04 264), oklch(from oklch(0.22 0.04 264) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h))", - "--sf-color-tertiary": "light-dark(oklch(0.42 0.22 295), oklch(from oklch(0.42 0.22 295) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h))", - "--sf-color-action": "light-dark(oklch(0.5 0.22 235), oklch(from oklch(0.5 0.22 235) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h))", - "--sf-color-neutral": "light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h))", - "--sf-color-base": "light-dark(oklch(0.96 0.006 250), oklch(from oklch(0.96 0.006 250) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h))", - "--sf-color-success": "light-dark(oklch(0.5 0.16 145), oklch(from oklch(0.5 0.16 145) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h))", - "--sf-color-warning": "light-dark(oklch(0.75 0.17 80), oklch(from oklch(0.75 0.17 80) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h))", - "--sf-color-error": "light-dark(oklch(0.5 0.2 25), oklch(from oklch(0.5 0.2 25) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h))", - "--sf-color-info": "light-dark(oklch(0.48 0.18 235), oklch(from oklch(0.48 0.18 235) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h))", - "--sf-color-danger": "light-dark(oklch(0.48 0.22 12), oklch(from oklch(0.48 0.22 12) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h))", - "--sf-color-bg": "oklch(from light-dark(oklch(0.96 0.006 250), oklch(from oklch(0.96 0.006 250) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)) calc(l + 0.02) c h)", - "--sf-color-inset": "oklch(from light-dark(oklch(0.96 0.006 250), oklch(from oklch(0.96 0.006 250) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)) calc(l - 0.02) c h)", - "--sf-color-raised": "oklch(from light-dark(oklch(0.96 0.006 250), oklch(from oklch(0.96 0.006 250) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)) calc(l + 0.04) c h)", - "--sf-color-text": "light-dark(\n oklch(from oklch(0.52 0.025 260) clamp(0.05, calc(l - 0.4 - 0), 0.35) c h),\n oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) clamp(0.70, calc(l + 0.25 + 0), 1) c h)\n )", - "--sf-color-text--secondary": "light-dark(\n oklch(from oklch(0.52 0.025 260) clamp(0.15, calc(l - 0.25 - 0), 0.45) c h),\n oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) clamp(0.55, calc(l + 0.1 + 0), 0.90) c h)\n )", - "--sf-color-heading": "light-dark(\n oklch(from oklch(0.52 0.025 260) clamp(0.05, calc(l - 0.4 - 0), 0.35) c h),\n oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) clamp(0.70, calc(l + 0.25 + 0), 1) c h)\n )", - "--sf-color-border": "light-dark(\n oklch(from oklch(0.52 0.025 260) clamp(0.70, calc(l + 0.35), 0.95) 0.005 h),\n oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) clamp(0.25, calc(l - 0.3), 0.55) 0.005 h)\n )", - "--sf-color-border--subtle": "light-dark(\n oklch(from oklch(0.52 0.025 260) clamp(0.75, calc(l + 0.4), 0.97) 0.005 h),\n oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) clamp(0.20, calc(l - 0.38), 0.45) 0.005 h)\n )", - "--sf-color-border--strong": "light-dark(\n oklch(from oklch(0.52 0.025 260) clamp(0.55, calc(l + 0.1), 0.85) 0.02 h),\n oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) clamp(0.38, calc(l - 0.1), 0.65) 0.02 h)\n )", - "--sf-color-link": "light-dark(\n oklch(from light-dark(oklch(0.5 0.22 235), oklch(from oklch(0.5 0.22 235) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) clamp(0, min(l - 0.07, 0.48), 1) c h),\n oklch(from light-dark(oklch(0.5 0.22 235), oklch(from oklch(0.5 0.22 235) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) clamp(0.68, l, 1) c h)\n )", + "--sf-color-primary": "oklch(0.47 0.27 264)", + "--sf-color-secondary": "oklch(0.22 0.04 264)", + "--sf-color-tertiary": "oklch(0.42 0.22 295)", + "--sf-color-action": "oklch(0.5 0.22 235)", + "--sf-color-neutral": "oklch(0.52 0.025 260)", + "--sf-color-base": "oklch(0.96 0.006 250)", + "--sf-color-success": "oklch(0.5 0.16 145)", + "--sf-color-warning": "oklch(0.75 0.17 80)", + "--sf-color-error": "oklch(0.5 0.2 25)", + "--sf-color-info": "oklch(0.48 0.18 235)", + "--sf-color-danger": "oklch(0.48 0.22 12)", + "--sf-color-bg": "oklch(from oklch(0.96 0.006 250) calc(l + 0.02) c h)", + "--sf-color-inset": "oklch(from oklch(0.96 0.006 250) calc(l - 0.02) c h)", + "--sf-color-raised": "oklch(from oklch(0.96 0.006 250) calc(l + 0.04) c h)", + "--sf-color-text": "light-dark(\n oklch(from oklch(0.52 0.025 260) clamp(0.05, calc(l - 0.4 - 0), 0.35) c h),\n oklch(from oklch(0.52 0.025 260) clamp(0.70, calc(l + 0.25 + 0), 1) c h)\n )", + "--sf-color-text--secondary": "light-dark(\n oklch(from oklch(0.52 0.025 260) clamp(0.15, calc(l - 0.25 - 0), 0.45) c h),\n oklch(from oklch(0.52 0.025 260) clamp(0.55, calc(l + 0.1 + 0), 0.90) c h)\n )", + "--sf-color-heading": "light-dark(\n oklch(from oklch(0.52 0.025 260) clamp(0.05, calc(l - 0.4 - 0), 0.35) c h),\n oklch(from oklch(0.52 0.025 260) clamp(0.70, calc(l + 0.25 + 0), 1) c h)\n )", + "--sf-color-border": "light-dark(\n oklch(from oklch(0.52 0.025 260) clamp(0.70, calc(l + 0.35), 0.95) 0.005 h),\n oklch(from oklch(0.52 0.025 260) clamp(0.25, calc(l - 0.3), 0.55) 0.005 h)\n )", + "--sf-color-border--subtle": "light-dark(\n oklch(from oklch(0.52 0.025 260) clamp(0.75, calc(l + 0.4), 0.97) 0.005 h),\n oklch(from oklch(0.52 0.025 260) clamp(0.20, calc(l - 0.38), 0.45) 0.005 h)\n )", + "--sf-color-border--strong": "light-dark(\n oklch(from oklch(0.52 0.025 260) clamp(0.55, calc(l + 0.1), 0.85) 0.02 h),\n oklch(from oklch(0.52 0.025 260) clamp(0.38, calc(l - 0.1), 0.65) 0.02 h)\n )", + "--sf-color-link": "light-dark(\n oklch(from oklch(0.5 0.22 235) clamp(0, min(l - 0.07, 0.48), 1) c h),\n oklch(from oklch(0.5 0.22 235) clamp(0.68, l, 1) c h)\n )", "--sf-color-selection-bg": "light-dark(\n oklch(from oklch(0.5 0.22 235) l c h / 0.28),\n oklch(from oklch(0.5 0.22 235) clamp(0.62, calc(0.93 - l * 0.4), 0.78) c h / 0.55)\n )", - "--sf-color-success-strong": "light-dark(\n oklch(from oklch(0.5 0.16 145) calc(l - 0.15) c h),\n oklch(from light-dark(oklch(0.5 0.16 145), oklch(from oklch(0.5 0.16 145) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) clamp(0.70, calc(l + 0.15), 1) c h)\n )", - "--sf-color-warning-strong": "light-dark(\n oklch(from oklch(0.75 0.17 80) calc(l - 0.25) c h),\n oklch(from light-dark(oklch(0.75 0.17 80), oklch(from oklch(0.75 0.17 80) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) clamp(0.70, calc(l + 0.05), 1) c h)\n )", - "--sf-color-error-strong": "light-dark(\n oklch(from oklch(0.5 0.2 25) calc(l - 0.1) c h),\n oklch(from light-dark(oklch(0.5 0.2 25), oklch(from oklch(0.5 0.2 25) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) clamp(0.70, calc(l + 0.15), 1) c h)\n )", - "--sf-color-info-strong": "light-dark(\n oklch(from oklch(0.48 0.18 235) calc(l - 0.1) c h),\n oklch(from light-dark(oklch(0.48 0.18 235), oklch(from oklch(0.48 0.18 235) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) clamp(0.70, calc(l + 0.15), 1) c h)\n )", - "--sf-color-danger-strong": "light-dark(\n oklch(from oklch(0.48 0.22 12) calc(l - 0.1) c h),\n oklch(from light-dark(oklch(0.48 0.22 12), oklch(from oklch(0.48 0.22 12) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) clamp(0.70, calc(l + 0.15), 1) c h)\n )", - "--sf-shadow-xs": "0 1px 2px 0 oklch(from oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 0.5), 0.7))", - "--sf-shadow-s": "0 1px 2px 0 oklch(from oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 0.5), 0.7)),\n 0 2px 6px 0 oklch(from oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) 0.15 c h) l c h / clamp(0, calc(0.08 + 0 * 0.17), 0.7))", - "--sf-shadow-m": "0 1px 3px 0 oklch(from oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 0.5), 0.7)),\n 0 4px 12px 0 oklch(from oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 2), 0.7))", - "--sf-shadow-l": "0 2px 4px 0 oklch(from oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 0.5), 0.7)),\n 0 8px 24px 0 oklch(from oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 3), 0.7)),\n 0 16px 48px 0 oklch(from oklch(from light-dark(oklch(0.52 0.025 260), oklch(from oklch(0.52 0.025 260) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 2), 0.7))" + "--sf-color-success-strong": "light-dark(\n oklch(from oklch(0.5 0.16 145) calc(l - 0.15) c h),\n oklch(from oklch(0.5 0.16 145) clamp(0.70, calc(l + 0.15), 1) c h)\n )", + "--sf-color-warning-strong": "light-dark(\n oklch(from oklch(0.75 0.17 80) calc(l - 0.25) c h),\n oklch(from oklch(0.75 0.17 80) clamp(0.70, calc(l + 0.05), 1) c h)\n )", + "--sf-color-error-strong": "light-dark(\n oklch(from oklch(0.5 0.2 25) calc(l - 0.1) c h),\n oklch(from oklch(0.5 0.2 25) clamp(0.70, calc(l + 0.15), 1) c h)\n )", + "--sf-color-info-strong": "light-dark(\n oklch(from oklch(0.48 0.18 235) calc(l - 0.1) c h),\n oklch(from oklch(0.48 0.18 235) clamp(0.70, calc(l + 0.15), 1) c h)\n )", + "--sf-color-danger-strong": "light-dark(\n oklch(from oklch(0.48 0.22 12) calc(l - 0.1) c h),\n oklch(from oklch(0.48 0.22 12) clamp(0.70, calc(l + 0.15), 1) c h)\n )", + "--sf-shadow-xs": "0 1px 2px 0 oklch(from oklch(from oklch(0.52 0.025 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 0.5), 0.7))", + "--sf-shadow-s": "0 1px 2px 0 oklch(from oklch(from oklch(0.52 0.025 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 0.5), 0.7)),\n 0 2px 6px 0 oklch(from oklch(from oklch(0.52 0.025 260) 0.15 c h) l c h / clamp(0, calc(0.08 + 0 * 0.17), 0.7))", + "--sf-shadow-m": "0 1px 3px 0 oklch(from oklch(from oklch(0.52 0.025 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 0.5), 0.7)),\n 0 4px 12px 0 oklch(from oklch(from oklch(0.52 0.025 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 2), 0.7))", + "--sf-shadow-l": "0 2px 4px 0 oklch(from oklch(from oklch(0.52 0.025 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 0.5), 0.7)),\n 0 8px 24px 0 oklch(from oklch(from oklch(0.52 0.025 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 3), 0.7)),\n 0 16px 48px 0 oklch(from oklch(from oklch(0.52 0.025 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 0 * 0.17) * 2), 0.7))" + }, + "dark": { + "--sf-color-primary": "oklch(0.715 0.243 264)", + "--sf-color-secondary": "oklch(0.84 0.036 264)", + "--sf-color-tertiary": "oklch(0.74 0.198 295)", + "--sf-color-action": "oklch(0.7 0.198 235)", + "--sf-color-neutral": "oklch(0.69 0.0225 260)", + "--sf-color-base": "oklch(0.22 0.003 250)", + "--sf-color-success": "oklch(0.7 0.144 145)", + "--sf-color-warning": "oklch(0.65 0.153 80)", + "--sf-color-error": "oklch(0.7 0.18 25)", + "--sf-color-info": "oklch(0.71 0.162 235)", + "--sf-color-danger": "oklch(0.71 0.198 12)", + "--sf-color-bg": "oklch(from oklch(0.22 0.003 250) calc(l + 0.02) c h)", + "--sf-color-inset": "oklch(from oklch(0.22 0.003 250) calc(l - 0.02) c h)", + "--sf-color-raised": "oklch(from oklch(0.22 0.003 250) calc(l + 0.04) c h)", + "--sf-color-text": "oklch(from oklch(0.69 0.0225 260) clamp(0.70, calc(l + 0.25 + 0), 1) c h)", + "--sf-color-text--secondary": "oklch(from oklch(0.69 0.0225 260) clamp(0.55, calc(l + 0.1 + 0), 0.90) c h)", + "--sf-color-heading": "oklch(from oklch(0.69 0.0225 260) clamp(0.70, calc(l + 0.25 + 0), 1) c h)", + "--sf-color-border": "oklch(from oklch(0.69 0.0225 260) clamp(0.25, calc(l - 0.3), 0.55) 0.005 h)", + "--sf-color-border--subtle": "oklch(from oklch(0.69 0.0225 260) clamp(0.20, calc(l - 0.38), 0.45) 0.005 h)", + "--sf-color-border--strong": "oklch(from oklch(0.69 0.0225 260) clamp(0.38, calc(l - 0.1), 0.65) 0.02 h)", + "--sf-color-link": "oklch(from oklch(0.7 0.198 235) clamp(0.68, l, 1) c h)", + "--sf-color-selection-bg": "oklch(from oklch(0.5 0.22 235) clamp(0.62, calc(0.93 - l * 0.4), 0.78) c h / 0.55)", + "--sf-color-success-strong": "oklch(from oklch(0.7 0.144 145) clamp(0.70, calc(l + 0.15), 1) c h)", + "--sf-color-warning-strong": "oklch(from oklch(0.65 0.153 80) clamp(0.70, calc(l + 0.05), 1) c h)", + "--sf-color-error-strong": "oklch(from oklch(0.7 0.18 25) clamp(0.70, calc(l + 0.15), 1) c h)", + "--sf-color-info-strong": "oklch(from oklch(0.71 0.162 235) clamp(0.70, calc(l + 0.15), 1) c h)", + "--sf-color-danger-strong": "oklch(from oklch(0.71 0.198 12) clamp(0.70, calc(l + 0.15), 1) c h)", + "--sf-shadow-xs": "0 1px 2px 0 oklch(from oklch(from oklch(0.69 0.0225 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 0.5), 0.7))", + "--sf-shadow-s": "0 1px 2px 0 oklch(from oklch(from oklch(0.69 0.0225 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 0.5), 0.7)),\n 0 2px 6px 0 oklch(from oklch(from oklch(0.69 0.0225 260) 0.15 c h) l c h / clamp(0, calc(0.08 + 1 * 0.17), 0.7))", + "--sf-shadow-m": "0 1px 3px 0 oklch(from oklch(from oklch(0.69 0.0225 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 0.5), 0.7)),\n 0 4px 12px 0 oklch(from oklch(from oklch(0.69 0.0225 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 2), 0.7))", + "--sf-shadow-l": "0 2px 4px 0 oklch(from oklch(from oklch(0.69 0.0225 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 0.5), 0.7)),\n 0 8px 24px 0 oklch(from oklch(from oklch(0.69 0.0225 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 3), 0.7)),\n 0 16px 48px 0 oklch(from oklch(from oklch(0.69 0.0225 260) 0.15 c h) l c h / clamp(0, calc(calc(0.08 + 1 * 0.17) * 2), 0.7))" } } From e60b0d94c352557b8a79d6646553b0474b61b827 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Jun 2026 15:16:15 +0000 Subject: [PATCH 8/9] fix(themes): re-declare surface and on-colour tokens in [data-theme="dark"] Unregistered custom properties bake their var() substitutions at the element that declares them (here: :root in light mode). Child elements scoped with [data-theme="dark"] inherit the pre-substituted light values for --sf-color-bg, --sf-color-inset, --sf-color-raised, --sf-color-overlay, --sf-color-inverse and all --sf-color-text--on-* tokens, so neither the demo a11y-panel probes nor real scoped dark sections showed correct dark surface colours. Fix: explicitly re-declare every affected token inside [data-theme="dark"] so the cascade produces the correct dark values at that element's scope rather than inheriting the root's baked light text. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu --- core/themes.css | 25 +++++++++++++++++++++++++ dist/badge-essential.json | 2 +- dist/badge-optimal.json | 2 +- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/core/themes.css b/core/themes.css index 66081cf8..1aeeccc0 100644 --- a/core/themes.css +++ b/core/themes.css @@ -190,6 +190,14 @@ --sf-color-base: var(--sf-color-base-dark); --sf-color-surface: var(--sf-color-base); + /* Surface scale — re-derive from dark --sf-color-base so scoped dark + sections are not stuck with the light-baked var() text from :root. */ + --sf-color-bg: oklch(from var(--sf-color-base) calc(l + 0.02) c h); + --sf-color-inset: oklch(from var(--sf-color-base) calc(l - 0.02) c h); + --sf-color-raised: oklch(from var(--sf-color-base) calc(l + 0.04) c h); + --sf-color-overlay: oklch(from var(--sf-color-base) l c h / 0.9); + --sf-color-inverse: oklch(from var(--sf-color-base) calc(1 - l) c h); + /* Status */ --sf-color-success: var(--sf-color-success-dark); --sf-color-warning: var(--sf-color-warning-dark); @@ -278,4 +286,21 @@ } /* end @supports (color: oklch(from red l c h)) */ + /* On-colour text tokens need sign() in addition to relative-color syntax. */ + @supports (color: oklch(from red l c h)) and (width: calc(1px * sign(1))) { + [data-theme="dark"] { + --sf-color-text--on-primary: oklch(from var(--sf-color-primary) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-secondary: oklch(from var(--sf-color-secondary) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-tertiary: oklch(from var(--sf-color-tertiary) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-action: oklch(from var(--sf-color-action) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-neutral: oklch(from var(--sf-color-neutral) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-success: oklch(from var(--sf-color-success) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-warning: oklch(from var(--sf-color-warning) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-error: oklch(from var(--sf-color-error) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-info: oklch(from var(--sf-color-info) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-danger: oklch(from var(--sf-color-danger) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-inverse: oklch(from var(--sf-color-inverse) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + } + } + } diff --git a/dist/badge-essential.json b/dist/badge-essential.json index bf542d11..d6727ee4 100644 --- a/dist/badge-essential.json +++ b/dist/badge-essential.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "label": "essential", - "message": "16.1 kB gzip", + "message": "16.3 kB gzip", "color": "brightgreen", "namedLogo": "css3" } diff --git a/dist/badge-optimal.json b/dist/badge-optimal.json index e118d881..f9294cc7 100644 --- a/dist/badge-optimal.json +++ b/dist/badge-optimal.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "label": "optimal", - "message": "19.9 kB gzip", + "message": "20.1 kB gzip", "color": "brightgreen", "namedLogo": "css3" } From ee352be049cfb7f94af57e9382f50b9ab6019923 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Jun 2026 15:33:42 +0000 Subject: [PATCH 9/9] fix(themes,tokens): add [data-theme="light"] scoped token re-declarations and correct -dark token group Symmetric fix for the same baking problem solved in [data-theme="dark"]: when :root is in dark mode (OS preference or explicit attribute) and a child section uses [data-theme="light"], surface tokens (--sf-color-bg etc.) and on-color text tokens (--sf-color-text--on-*) inherited the dark-mode-baked values from :root. Add explicit re-declarations of all five surface tokens and all eleven on-color tokens to [data-theme="light"] so scoped light sections always derive from the correct light brand colors regardless of root mode. Also fixes mislabeled group metadata for the eleven --sf-color-*-dark @property tokens: split the multiline comment in tokens.css into a recognised single-line sub-header so gen-api-index.js assigns the group "DARK SOURCE TOKENS (-dark, animatable)" instead of inheriting the previous "STATUS COLORS (-light source tokens)" banner. Added matching _groups entry to token-annotations.json. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01AfvcWkL8FcHEqjPkuZvEWu --- .../src/data/api-index.generated.json | 94 +++++++++---------- core/themes.css | 21 +++++ core/tokens.css | 4 +- docs/api-index.json | 68 +++++++------- docs/api-index.md | 22 ++--- docs/token-annotations.json | 1 + 6 files changed, 116 insertions(+), 94 deletions(-) diff --git a/configurator/src/data/api-index.generated.json b/configurator/src/data/api-index.generated.json index 896c7cd4..33be5d0b 100644 --- a/configurator/src/data/api-index.generated.json +++ b/configurator/src/data/api-index.generated.json @@ -2,7 +2,7 @@ "_sync": { "generatedBy": "configurator/scripts/sync-api.mjs", "source": "docs/api-index.json", - "tokensHash": "e8bd0fe746b0", + "tokensHash": "3786ee1fa572", "bundles": [ "essential", "full", @@ -1705,8 +1705,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "Primary interactive color. Applied to filled buttons, active indicators, and brand accent surfaces.", "value": "light-dark(var(--sf-color-action-light), var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -2283,8 +2283,8 @@ "role": "knob", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "", "value": "oklch(0.70 0.198 235)", "aliasOf": null, @@ -2547,8 +2547,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "Secondary interactive color for supporting actions and secondary buttons.", "value": "light-dark(var(--sf-color-base-light), var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)))", "aliasOf": null, @@ -3125,8 +3125,8 @@ "role": "knob", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "", "value": "oklch(0.22 0.003 250)", "aliasOf": null, @@ -3749,8 +3749,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "Destructive / danger state color. Used for delete actions, error alerts, and critical warnings.", "value": "light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -3773,8 +3773,8 @@ "role": "knob", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "", "value": "oklch(0.71 0.198 12)", "aliasOf": null, @@ -3917,8 +3917,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "Form validation error color. Typically same hue as danger but can be tuned independently.", "value": "light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -3941,8 +3941,8 @@ "role": "knob", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "", "value": "oklch(0.70 0.18 25)", "aliasOf": null, @@ -4085,8 +4085,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "Informational color for neutral tips, hints, and non-urgent notices.", "value": "light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -4109,8 +4109,8 @@ "role": "knob", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "", "value": "oklch(0.71 0.162 235)", "aliasOf": null, @@ -4469,8 +4469,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "Neutral interactive color for low-emphasis actions and tertiary buttons.", "value": "light-dark(var(--sf-color-neutral-light), var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -5047,8 +5047,8 @@ "role": "knob", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "", "value": "oklch(0.69 0.0225 260)", "aliasOf": null, @@ -5335,8 +5335,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "Raw primary palette token aliased from the action role by default. Override to decouple primary from action.", "value": "light-dark(var(--sf-color-primary-light), var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -5913,8 +5913,8 @@ "role": "knob", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "", "value": "oklch(0.715 0.243 264)", "aliasOf": null, @@ -6225,8 +6225,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "Raw secondary palette token for the secondary brand color.", "value": "light-dark(var(--sf-color-secondary-light), var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -6803,8 +6803,8 @@ "role": "knob", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "", "value": "oklch(0.84 0.036 264)", "aliasOf": null, @@ -7115,8 +7115,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "Positive / success color for confirmation messages and completed-state indicators.", "value": "light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -7139,8 +7139,8 @@ "role": "knob", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "", "value": "oklch(0.70 0.144 145)", "aliasOf": null, @@ -7283,8 +7283,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "Raw tertiary palette token for the third brand color.", "value": "light-dark(var(--sf-color-tertiary-light), var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -7861,8 +7861,8 @@ "role": "knob", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "", "value": "oklch(0.74 0.198 295)", "aliasOf": null, @@ -8581,8 +8581,8 @@ "role": "consumption", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "Warning / caution color for non-critical alerts and degraded-state indicators.", "value": "light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -8605,8 +8605,8 @@ "role": "knob", "namespace": "color", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "", "value": "oklch(0.65 0.153 80)", "aliasOf": null, @@ -12532,8 +12532,8 @@ "role": "knob", "namespace": "is", "category": "Core tokens", - "group": "STATUS COLORS (-light source tokens)", - "description": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "note": "", "value": "0", "aliasOf": null, diff --git a/core/themes.css b/core/themes.css index 1aeeccc0..de1ed649 100644 --- a/core/themes.css +++ b/core/themes.css @@ -247,6 +247,14 @@ --sf-color-base: var(--sf-color-base-light); --sf-color-surface: var(--sf-color-base); + /* Surface scale — re-derive from light --sf-color-base so scoped light + sections inside a dark root are not stuck with the dark-baked value. */ + --sf-color-bg: oklch(from var(--sf-color-base) calc(l + 0.02) c h); + --sf-color-inset: oklch(from var(--sf-color-base) calc(l - 0.02) c h); + --sf-color-raised: oklch(from var(--sf-color-base) calc(l + 0.04) c h); + --sf-color-overlay: oklch(from var(--sf-color-base) l c h / 0.9); + --sf-color-inverse: oklch(from var(--sf-color-base) calc(1 - l) c h); + /* Status — explicit light values */ --sf-color-success: var(--sf-color-success-light); --sf-color-warning: var(--sf-color-warning-light); @@ -301,6 +309,19 @@ --sf-color-text--on-danger: oklch(from var(--sf-color-danger) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); --sf-color-text--on-inverse: oklch(from var(--sf-color-inverse) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); } + [data-theme="light"] { + --sf-color-text--on-primary: oklch(from var(--sf-color-primary) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-secondary: oklch(from var(--sf-color-secondary) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-tertiary: oklch(from var(--sf-color-tertiary) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-action: oklch(from var(--sf-color-action) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-neutral: oklch(from var(--sf-color-neutral) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-success: oklch(from var(--sf-color-success) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-warning: oklch(from var(--sf-color-warning) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-error: oklch(from var(--sf-color-error) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-info: oklch(from var(--sf-color-info) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-danger: oklch(from var(--sf-color-danger) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + --sf-color-text--on-inverse: oklch(from var(--sf-color-inverse) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0); + } } } diff --git a/core/tokens.css b/core/tokens.css index 8e65446b..3c1d7a0c 100644 --- a/core/tokens.css +++ b/core/tokens.css @@ -209,8 +209,8 @@ --sf-color-danger-light: oklch(0.48 0.22 12); } - /* @property — DARK SOURCE TOKENS (-dark, animatable) - Registers the auto-computed dark counterparts as typed so their + /* @property — DARK SOURCE TOKENS (-dark, animatable) */ + /* Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails type-checking on diff --git a/docs/api-index.json b/docs/api-index.json index 3b8eb547..9c89b1ef 100644 --- a/docs/api-index.json +++ b/docs/api-index.json @@ -2121,7 +2121,7 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", + "group": "DARK SOURCE TOKENS (-dark, animatable)", "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-action-light), var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -2824,8 +2824,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", - "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails…", "value": "oklch(0.70 0.198 235)", "aliasOf": null, "registered": true, @@ -3149,7 +3149,7 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", + "group": "DARK SOURCE TOKENS (-dark, animatable)", "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-base-light), var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)))", "aliasOf": null, @@ -3852,8 +3852,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", - "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails…", "value": "oklch(0.22 0.003 250)", "aliasOf": null, "registered": true, @@ -4612,7 +4612,7 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", + "group": "DARK SOURCE TOKENS (-dark, animatable)", "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -4641,8 +4641,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", - "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails…", "value": "oklch(0.71 0.198 12)", "aliasOf": null, "registered": true, @@ -4815,7 +4815,7 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", + "group": "DARK SOURCE TOKENS (-dark, animatable)", "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -4844,8 +4844,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", - "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails…", "value": "oklch(0.70 0.18 25)", "aliasOf": null, "registered": true, @@ -5018,7 +5018,7 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", + "group": "DARK SOURCE TOKENS (-dark, animatable)", "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -5047,8 +5047,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", - "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails…", "value": "oklch(0.71 0.162 235)", "aliasOf": null, "registered": true, @@ -5482,7 +5482,7 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", + "group": "DARK SOURCE TOKENS (-dark, animatable)", "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-neutral-light), var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -6185,8 +6185,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", - "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails…", "value": "oklch(0.69 0.0225 260)", "aliasOf": null, "registered": true, @@ -6539,7 +6539,7 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", + "group": "DARK SOURCE TOKENS (-dark, animatable)", "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-primary-light), var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -7242,8 +7242,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", - "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails…", "value": "oklch(0.715 0.243 264)", "aliasOf": null, "registered": true, @@ -7625,7 +7625,7 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", + "group": "DARK SOURCE TOKENS (-dark, animatable)", "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-secondary-light), var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -8328,8 +8328,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", - "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails…", "value": "oklch(0.84 0.036 264)", "aliasOf": null, "registered": true, @@ -8711,7 +8711,7 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", + "group": "DARK SOURCE TOKENS (-dark, animatable)", "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -8740,8 +8740,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", - "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails…", "value": "oklch(0.70 0.144 145)", "aliasOf": null, "registered": true, @@ -8914,7 +8914,7 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", + "group": "DARK SOURCE TOKENS (-dark, animatable)", "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-tertiary-light), var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -9617,8 +9617,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", - "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails…", "value": "oklch(0.74 0.198 295)", "aliasOf": null, "registered": true, @@ -10493,7 +10493,7 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", + "group": "DARK SOURCE TOKENS (-dark, animatable)", "description": "@property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).…", "value": "light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))", "aliasOf": null, @@ -10522,8 +10522,8 @@ "namespace": "color", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", - "description": "@property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and…", + "group": "DARK SOURCE TOKENS (-dark, animatable)", + "description": "Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme=\"dark\"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails…", "value": "oklch(0.65 0.153 80)", "aliasOf": null, "registered": true, @@ -15269,7 +15269,7 @@ "namespace": "is", "category": "Core tokens", "area": "core", - "group": "STATUS COLORS (-light source tokens)", + "group": "DARK SOURCE TOKENS (-dark, animatable)", "description": "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.", "value": "0", "aliasOf": null, diff --git a/docs/api-index.md b/docs/api-index.md index 57d2da4a..ad080ae4 100644 --- a/docs/api-index.md +++ b/docs/api-index.md @@ -88,7 +88,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-action` | PUBLIC | consumption | color | `light-dark(var(--sf-color-action-light), var(--sf-color-action-dark, oklch(from var(--sf-color-action-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-action--active` | PUBLIC | consumption | color | `var(--sf-color-action-xdark)` | action | | `--sf-color-action--hover` | PUBLIC | consumption | color | `var(--sf-color-action-darker)` | action | -| `--sf-color-action-dark` | PUBLIC | knob | color | `oklch(0.70 0.198 235)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | +| `--sf-color-action-dark` | PUBLIC | knob | color | `oklch(0.70 0.198 235)` | Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails… | | `--sf-color-action-darker` | PUBLIC | consumption | color | `var(--sf-color-action-600)` | action | | `--sf-color-action-ghost` | PUBLIC | consumption | color | `oklch(from var(--sf-color-action) l c h / 0.05)` | action | | `--sf-color-action-light` | PUBLIC | knob | color | `oklch(0.50 0.22 235)` | Override these 6 tokens to rebrand — dark mode auto-derives. Optionally set --sf-color-X-dark (no @property) for full control. | @@ -102,7 +102,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-base` | PUBLIC | consumption | color | `light-dark(var(--sf-color-base-light), var(--sf-color-base-dark, oklch(from var(--sf-color-base-light) clamp(0.16, calc(1.18 - l), 0.24) calc(c * 0.5) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-base--active` | PUBLIC | consumption | color | `var(--sf-color-base-xdark)` | base | | `--sf-color-base--hover` | PUBLIC | consumption | color | `var(--sf-color-base-darker)` | base | -| `--sf-color-base-dark` | PUBLIC | knob | color | `oklch(0.22 0.003 250)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | +| `--sf-color-base-dark` | PUBLIC | knob | color | `oklch(0.22 0.003 250)` | Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails… | | `--sf-color-base-darker` | PUBLIC | consumption | color | `var(--sf-color-base-600)` | base | | `--sf-color-base-ghost` | PUBLIC | consumption | color | `oklch(from var(--sf-color-base) l c h / 0.05)` | base | | `--sf-color-base-light` | PUBLIC | knob | color | `oklch(0.96 0.006 250)` | initial-value is 0.96 (not 0.99) so the +0.02/+0.04 surface offsets produce visually distinct levels in light mode. At 0.99 all lighter surfaces clamp to pure white and become indistinguishable. 0.96 gives: bg=0.98, inset=0.94, raised=1.0→white — all distinct. Consumers using… | @@ -129,21 +129,21 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-code-bg` | PUBLIC | consumption | color | `var(--sf-color-inset)` | plain var aliases (ungated) | | `--sf-color-code-text` | PUBLIC | consumption | color | `oklch(from var(--sf-color-code-bg) clamp(0.1, sign(var(--sf-contrast-threshold) - l) * 999, 0.95) 0 0)` | Inline-code text colour. Auto-contrasts with --sf-color-code-bg using the same luminance formula as --sf-color-text--on-*. This prevents invisible text when code appears inside inverted-colour containers (e.g. sf-imposter with a dark background where inherited colour is… | | `--sf-color-danger` | PUBLIC | consumption | color | `light-dark(var(--sf-color-danger-light), var(--sf-color-danger-dark, oklch(from var(--sf-color-danger-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | -| `--sf-color-danger-dark` | PUBLIC | knob | color | `oklch(0.71 0.198 12)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | +| `--sf-color-danger-dark` | PUBLIC | knob | color | `oklch(0.71 0.198 12)` | Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails… | | `--sf-color-danger-light` | PUBLIC | knob | color | `oklch(0.48 0.22 12)` | STATUS COLORS (-light source tokens) | | `--sf-color-danger-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-danger) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-danger-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-danger-light) calc(l - 0.1) c h), oklch(from var(--sf-color-danger) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | | `--sf-color-danger-subtle` | PUBLIC | consumption | color | `oklch(from var(--sf-color-danger) l c h / 0.1)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-dim` | PUBLIC | knob | color | `oklch(0 0 0 / 0.5)` | Dim: classic semi-transparent black for modal backdrops, distinct from --sf-color-overlay | | `--sf-color-error` | PUBLIC | consumption | color | `light-dark(var(--sf-color-error-light), var(--sf-color-error-dark, oklch(from var(--sf-color-error-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | -| `--sf-color-error-dark` | PUBLIC | knob | color | `oklch(0.70 0.18 25)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | +| `--sf-color-error-dark` | PUBLIC | knob | color | `oklch(0.70 0.18 25)` | Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails… | | `--sf-color-error-light` | PUBLIC | knob | color | `oklch(0.50 0.20 25)` | STATUS COLORS (-light source tokens) | | `--sf-color-error-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-error) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-error-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-error-light) calc(l - 0.1) c h), oklch(from var(--sf-color-error) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | | `--sf-color-error-subtle` | PUBLIC | consumption | color | `oklch(from var(--sf-color-error) l c h / 0.1)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-heading` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.05, calc(l - 0.4 - var(--sf-contrast-bias)), 0.35) c h), oklch(from var(--sf-color-neutral) clamp(0.70, calc(l + 0.25 + var(--sf-contrast-bias)), 1) c h) )` | light and dark require opposite formula directions, so each side of light-dark() references its source token. | | `--sf-color-info` | PUBLIC | consumption | color | `light-dark(var(--sf-color-info-light), var(--sf-color-info-dark, oklch(from var(--sf-color-info-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | -| `--sf-color-info-dark` | PUBLIC | knob | color | `oklch(0.71 0.162 235)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | +| `--sf-color-info-dark` | PUBLIC | knob | color | `oklch(0.71 0.162 235)` | Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails… | | `--sf-color-info-light` | PUBLIC | knob | color | `oklch(0.48 0.18 235)` | STATUS COLORS (-light source tokens) | | `--sf-color-info-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-info) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-info-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-info-light) calc(l - 0.1) c h), oklch(from var(--sf-color-info) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | @@ -161,7 +161,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-neutral` | PUBLIC | consumption | color | `light-dark(var(--sf-color-neutral-light), var(--sf-color-neutral-dark, oklch(from var(--sf-color-neutral-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-neutral--active` | PUBLIC | consumption | color | `var(--sf-color-neutral-xdark)` | neutral | | `--sf-color-neutral--hover` | PUBLIC | consumption | color | `var(--sf-color-neutral-darker)` | neutral | -| `--sf-color-neutral-dark` | PUBLIC | knob | color | `oklch(0.69 0.0225 260)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | +| `--sf-color-neutral-dark` | PUBLIC | knob | color | `oklch(0.69 0.0225 260)` | Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails… | | `--sf-color-neutral-darker` | PUBLIC | consumption | color | `var(--sf-color-neutral-600)` | neutral | | `--sf-color-neutral-ghost` | PUBLIC | consumption | color | `oklch(from var(--sf-color-neutral) l c h / 0.05)` | neutral | | `--sf-color-neutral-light` | PUBLIC | knob | color | `oklch(0.52 0.025 260)` | Override these 6 tokens to rebrand — dark mode auto-derives. Optionally set --sf-color-X-dark (no @property) for full control. | @@ -176,7 +176,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-primary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-primary-light), var(--sf-color-primary-dark, oklch(from var(--sf-color-primary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-primary--active` | PUBLIC | consumption | color | `var(--sf-color-primary-xdark)` | primary | | `--sf-color-primary--hover` | PUBLIC | consumption | color | `var(--sf-color-primary-darker)` | primary | -| `--sf-color-primary-dark` | PUBLIC | knob | color | `oklch(0.715 0.243 264)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | +| `--sf-color-primary-dark` | PUBLIC | knob | color | `oklch(0.715 0.243 264)` | Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails… | | `--sf-color-primary-darker` | PUBLIC | consumption | color | `var(--sf-color-primary-600)` | primary | | `--sf-color-primary-ghost` | PUBLIC | consumption | color | `oklch(from var(--sf-color-primary) l c h / 0.05)` | primary | | `--sf-color-primary-light` | PUBLIC | knob | color | `oklch(0.47 0.27 264)` | Override these 6 tokens to rebrand — dark mode auto-derives. Optionally set --sf-color-X-dark (no @property) for full control. | @@ -192,7 +192,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-secondary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-secondary-light), var(--sf-color-secondary-dark, oklch(from var(--sf-color-secondary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-secondary--active` | PUBLIC | consumption | color | `var(--sf-color-secondary-xdark)` | secondary | | `--sf-color-secondary--hover` | PUBLIC | consumption | color | `var(--sf-color-secondary-darker)` | secondary | -| `--sf-color-secondary-dark` | PUBLIC | knob | color | `oklch(0.84 0.036 264)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | +| `--sf-color-secondary-dark` | PUBLIC | knob | color | `oklch(0.84 0.036 264)` | Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails… | | `--sf-color-secondary-darker` | PUBLIC | consumption | color | `var(--sf-color-secondary-600)` | secondary | | `--sf-color-secondary-ghost` | PUBLIC | consumption | color | `oklch(from var(--sf-color-secondary) l c h / 0.05)` | secondary | | `--sf-color-secondary-light` | PUBLIC | knob | color | `oklch(0.22 0.04 264)` | Override these 6 tokens to rebrand — dark mode auto-derives. Optionally set --sf-color-X-dark (no @property) for full control. | @@ -206,7 +206,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-selection-bg` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-action-light) l c h / 0.28), oklch(from var(--sf-color-action-light) clamp(0.62, calc(0.93 - l * 0.4), 0.78) c h / 0.55) )` | Selection | | `--sf-color-selection-text` | PUBLIC | knob | color | `inherit` | static values (ungated) | | `--sf-color-success` | PUBLIC | consumption | color | `light-dark(var(--sf-color-success-light), var(--sf-color-success-dark, oklch(from var(--sf-color-success-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | -| `--sf-color-success-dark` | PUBLIC | knob | color | `oklch(0.70 0.144 145)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | +| `--sf-color-success-dark` | PUBLIC | knob | color | `oklch(0.70 0.144 145)` | Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails… | | `--sf-color-success-light` | PUBLIC | knob | color | `oklch(0.50 0.16 145)` | STATUS COLORS (-light source tokens) | | `--sf-color-success-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-success) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-success-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-success-light) calc(l - 0.15) c h), oklch(from var(--sf-color-success) clamp(0.70, calc(l + 0.15), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | @@ -215,7 +215,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-tertiary` | PUBLIC | consumption | color | `light-dark(var(--sf-color-tertiary-light), var(--sf-color-tertiary-dark, oklch(from var(--sf-color-tertiary-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | | `--sf-color-tertiary--active` | PUBLIC | consumption | color | `var(--sf-color-tertiary-xdark)` | tertiary | | `--sf-color-tertiary--hover` | PUBLIC | consumption | color | `var(--sf-color-tertiary-darker)` | tertiary | -| `--sf-color-tertiary-dark` | PUBLIC | knob | color | `oklch(0.74 0.198 295)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | +| `--sf-color-tertiary-dark` | PUBLIC | knob | color | `oklch(0.74 0.198 295)` | Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails… | | `--sf-color-tertiary-darker` | PUBLIC | consumption | color | `var(--sf-color-tertiary-600)` | tertiary | | `--sf-color-tertiary-ghost` | PUBLIC | consumption | color | `oklch(from var(--sf-color-tertiary) l c h / 0.05)` | tertiary | | `--sf-color-tertiary-light` | PUBLIC | knob | color | `oklch(0.42 0.22 295)` | Override these 6 tokens to rebrand — dark mode auto-derives. Optionally set --sf-color-X-dark (no @property) for full control. | @@ -246,7 +246,7 @@ and a short description. The machine-readable companion (with all columns) is | `--sf-color-text--placeholder` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.45, calc(l + 0.15), 0.75) c h), oklch(from var(--sf-color-neutral) clamp(0.35, calc(l - 0.1), 0.65) c h) )` | light and dark require opposite formula directions, so each side of light-dark() references its source token. | | `--sf-color-text--secondary` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-neutral-light) clamp(0.15, calc(l - 0.25 - var(--sf-contrast-bias)), 0.45) c h), oklch(from var(--sf-color-neutral) clamp(0.55, calc(l + 0.1 + var(--sf-contrast-bias)), 0.90) c h) )` | light and dark require opposite formula directions, so each side of light-dark() references its source token. | | `--sf-color-warning` | PUBLIC | consumption | color | `light-dark(var(--sf-color-warning-light), var(--sf-color-warning-dark, oklch(from var(--sf-color-warning-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)))` | @property — COMPUTED COLOR TOKENS (brand + status) Registers the computed tokens as typed so CSS transitions can interpolate between light and dark values when [data-theme] changes. initial-value = light-mode value (safe fallback if nothing sets the token).… | -| `--sf-color-warning-dark` | PUBLIC | knob | color | `oklch(0.65 0.153 80)` | @property — DARK SOURCE TOKENS (-dark, animatable) Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and… | +| `--sf-color-warning-dark` | PUBLIC | knob | color | `oklch(0.65 0.153 80)` | Registers the auto-computed dark counterparts as typed so their resolved absolute value is inherited by child elements (e.g. a section with [data-theme="dark"]). Without @property these tokens inherit as raw text, and the nested var()-in-oklch-from chain fails… | | `--sf-color-warning-light` | PUBLIC | knob | color | `oklch(0.75 0.17 80)` | STATUS COLORS (-light source tokens) | | `--sf-color-warning-muted` | PUBLIC | consumption | color | `oklch(from var(--sf-color-warning) l c h / 0.3)` | subtle/muted (alpha variants) bg/border use same formula both modes | | `--sf-color-warning-strong` | PUBLIC | consumption | color | `light-dark( oklch(from var(--sf-color-warning-light) calc(l - 0.25) c h), oklch(from var(--sf-color-warning) clamp(0.70, calc(l + 0.05), 1) c h) )` | strong (direction-dependent, uses light-dark) error = form validation, input errors danger = destructive actions (delete, remove) | diff --git a/docs/token-annotations.json b/docs/token-annotations.json index f5be09d5..ebebad8d 100644 --- a/docs/token-annotations.json +++ b/docs/token-annotations.json @@ -9,6 +9,7 @@ "Core tokens | tertiary": "Semantic tertiary-color scale derived from --sf-color-tertiary.", "Core tokens | BRAND COLORS (-light source tokens, animatable)": "OKLCH lightness source tokens for each brand role. Animating these drives smooth color-scheme transitions without re-painting every dependent token.", "Core tokens | STATUS COLORS (-light source tokens)": "OKLCH lightness sources for status colors (danger, error, info, success, warning). Same animation mechanism as brand light tokens.", + "Core tokens | DARK SOURCE TOKENS (-dark, animatable)": "OKLCH dark source tokens for brand and status colors. Registered as typed so scoped [data-theme=\"dark\"] sections inherit correct absolute values rather than an unresolved var() text string.", "Core tokens | Status triplets": "Three-shade status triplets (subtle / muted / strong) for each status role. Use subtle for backgrounds, muted for fills, strong for text on light surfaces.", "Core tokens | Text": "Semantic text colors for every content role. All tokens adapt to light and dark mode automatically.", "Core tokens | Surfaces": "Background surface tokens from page-level to raised cards. Layer these to communicate visual depth.",