Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions core/accessibility.css
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@
}

/* Clickable-parent */
/* Perf note (SL-002): the two selector groups below each combine multiple
:has()-bearing branches, forcing subtree re-evaluation on DOM mutation
inside .sf-clickable-parent. Fine for typical card/list-item usage; avoid
applying this class to large (100+ node) grids or lists without profiling
first. */
.sf-clickable-parent {
--sf-clickable-overlay-z: 1;
position: relative;
Expand Down
19 changes: 16 additions & 3 deletions core/layout.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
/* SLASHED — core/layout.css
@layer slashed.layout
Layout primitives: section, container, stack, cluster, grid, sidebar, switcher, frame.
Prefix: .sf-*; local rhythm via --sf-*-gap / sizing tokens. */
Prefix: .sf-*; local rhythm via --sf-*-gap / sizing tokens.
SL-005: every @container query in this file hardcodes its breakpoint
instead of referencing a --sf-* token — var() is not allowed inside an
@container condition per the CSS spec. This applies framework-wide to
every @container site below; not re-explained at each one. */

@layer slashed.layout {


/* Section */
.sf-section { padding-block: var(--sf-section-pad); }
.sf-section--xs { --sf-section-pad: var(--sf-section-pad--xs); }
.sf-section--s { --sf-section-pad: var(--sf-section-pad--s); }
Expand Down Expand Up @@ -52,6 +56,7 @@
}


/* Container */
.sf-container {
container: sf-layout / inline-size;
width: 100%;
Expand All @@ -71,6 +76,7 @@
}


/* Stack & gap */
.sf-stack {
display: flex;
flex-direction: column;
Expand All @@ -96,12 +102,14 @@
.sf-gap--2xl { gap: var(--sf-space-2xl); }


/* Box */
.sf-box {
padding: var(--sf-box-padding);
outline: var(--sf-box-border-width) solid var(--sf-box-border-color);
}


/* Center */
.sf-center {
box-sizing: content-box;
width: auto;
Expand All @@ -117,6 +125,7 @@
}


/* Cluster */
.sf-cluster {
display: flex;
flex-wrap: wrap;
Expand All @@ -137,6 +146,7 @@
.sf-cluster--between { justify-content: space-between; }


/* Sidebar */
.sf-sidebar {
display: flex;
flex-wrap: wrap;
Expand Down Expand Up @@ -169,6 +179,7 @@
.sf-sidebar--wide { --sf-sidebar-width: 26rem; }


/* Switcher */
.sf-switcher {
display: flex;
flex-wrap: wrap;
Expand All @@ -184,6 +195,7 @@
.sf-switcher--vertical { flex-direction: column; }


/* Grid & icon */
.sf-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(var(--sf-grid-min), 100%), 1fr));
Expand Down Expand Up @@ -229,6 +241,7 @@
}


/* Cover */
.sf-cover {
display: flex;
flex-direction: column;
Expand All @@ -247,6 +260,7 @@
.sf-cover--padding-l { padding-block: var(--sf-space-4xl); }


/* Frame */
.sf-frame {
aspect-ratio: var(--sf-frame-ratio);
overflow: hidden;
Expand Down Expand Up @@ -395,7 +409,6 @@
container: sf-grid / inline-size;
}

/* Cannot use var() inside @container per CSS spec — breakpoints hardcoded. */
@container (min-width: 30em) {
.sf-grid-cols-4 { grid-template-columns: repeat(2, 1fr); }
.sf-grid-cols-6 { grid-template-columns: repeat(3, 1fr); }
Expand Down
7 changes: 6 additions & 1 deletion core/themes.css
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@

/* SECTION-LEVEL THEMING */
/* light-dark() bakes at :root declaration time; re-declarations on [data-theme]
elements are required for section-level theming to work. */
elements are required for section-level theming to work.
SL-001: the clamp() derivation formula below is the same one used inside
tokens.css's "Resolved color tokens — auto-switch via light-dark()"
block (search core/tokens.css for that comment) — duplicated here, not
shared, because this file needs flat values outside light-dark().
Keep both copies in sync if the formula ever changes. */
@supports (color: oklch(from red l c h)) {

:root {
Expand Down
22 changes: 16 additions & 6 deletions core/tokens.css
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,20 @@
--sf-color-danger: var(--sf-color-danger-source-light);
}

/* Mode flag — drives formula direction for non-color dark overrides.
Set by themes.css via [data-theme="dark"] and the prefers-color-scheme
media query. Do not set directly. */
/* Mode flag — INTERNAL, not a public hook (SL-003: same "--sf-is-*" naming
pattern as the public flags below, opposite contract — read here, don't
set). Drives formula direction for non-color dark overrides. Set only by
themes.css via [data-theme="dark"] and the prefers-color-scheme media
query; every other read site (core/tokens.css, the configurator's power
knobs) only reads it inside calc() expressions. Setting it directly
desyncs it from color-scheme/[data-theme] and produces an inconsistent
theme. */
@property --sf-is-dark { syntax: "<integer>"; inherits: true; initial-value: 0; }

/* @property — INTERACTION STATE FLAGS */
/* Public hooks for Style Queries. Allow components to react to states
toggled on ancestors via .is-* classes. */
/* PUBLIC hooks for Style Queries — safe to set from consumer code, unlike
--sf-is-dark above. Allow components to react to states toggled on
ancestors via .is-* classes. */
@property --sf-is-active { syntax: "<integer>"; inherits: true; initial-value: 0; }
@property --sf-is-current { syntax: "<integer>"; inherits: true; initial-value: 0; }
@property --sf-is-pressed { syntax: "<integer>"; inherits: true; initial-value: 0; }
Expand Down Expand Up @@ -366,7 +372,11 @@
Dark auto-derivation formula (brand + status):
clamp(0.65, 0.95 - l*0.5, 0.88) lightens dark-mode value relative to the light source.
Surface inverts: clamp(0.16, 1.18 - l, 0.24) — near-white flips to near-dark.
Override any --sf-color-X-dark to take full per-mode control. */
Override any --sf-color-X-dark to take full per-mode control.
SL-001: this same clamp() formula is re-declared flat in themes.css
(SECTION-LEVEL THEMING) so [data-theme] overrides on non-:root elements
still resolve correctly — light-dark() only bakes at :root. Keep both
copies in sync if the formula ever changes. */
--sf-color-primary: light-dark(var(--sf-color-primary-source-light), var(--sf-color-primary-source-dark, oklch(from var(--sf-color-primary-source-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)));
--sf-color-secondary: light-dark(var(--sf-color-secondary-source-light), var(--sf-color-secondary-source-dark, oklch(from var(--sf-color-secondary-source-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)));
--sf-color-tertiary: light-dark(var(--sf-color-tertiary-source-light), var(--sf-color-tertiary-source-dark, oklch(from var(--sf-color-tertiary-source-light) clamp(0.65, calc(0.95 - l * 0.5), 0.88) calc(c * 0.9) h)));
Expand Down
1 change: 1 addition & 0 deletions docs/token-annotations.json
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,7 @@
},
"classes": {
"no-motion": "Suppresses all animations and transitions within the subtree. Apply to a container to create a reduced-motion zone without relying on the system preference.",
"sf-section--guttered": "Adds horizontal page gutters directly to a section — use when you want to skip a separate .sf-container wrapper (gutterless layout inside section). Neutralises container gutter to prevent double padding.",
"sf-clickable-parent": "Makes the entire card or list-item clickable via an absolutely-positioned child overlay link. Apply to the container; place sf-clickable-parent__overlay on the <a>.",
"sf-clickable-parent__overlay": "The full-bleed overlay link inside an sf-clickable-parent. Stretches to cover the parent and uses pointer-events to let interactive children keep their own clicks.",
"sf-focus-parent": "Forwards focus-visible styling to this container when any descendant is keyboard-focused. Useful for custom controls that wrap a visually-hidden <input>.",
Expand Down