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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<p align="center">
A cascade-layer CSS framework you never compile.<br>
747 design tokens, automatic dark mode, fluid type &amp; spacing — no build step, no Node, no JavaScript.
741 design tokens, automatic dark mode, fluid type &amp; spacing — no build step, no Node, no JavaScript.
</p>

<p align="center">
Expand Down Expand Up @@ -67,7 +67,7 @@ Every letter of SLASHED is a design commitment, and each one is checkable agains

## What's inside

- **747 design tokens** (`--sf-*`) covering color, typography, spacing, layout, borders, shadows, motion, and z-index — catalogued in a machine-readable [API index](docs/api-index.json).
- **741 design tokens** (`--sf-*`) covering color, typography, spacing, layout, borders, shadows, motion, and z-index — catalogued in a machine-readable [API index](docs/api-index.json).
- **Layout primitives** — `.sf-container`, `.sf-stack`, `.sf-grid`, `.sf-cluster`, `.sf-sidebar`, `.sf-switcher`, `.sf-cover`, `.sf-center`, `.sf-frame`, `.sf-reel`, `.sf-bento`, and more ([docs/layout.md](docs/layout.md)).
- **Macros** — recipes like `.sf-prose`, `.sf-flow`, `.sf-truncate`, `.sf-aspect`, `.sf-scroll-shadow`, `.sf-surface` ([docs/macros.md](docs/macros.md)).
- **State classes** — `.sf-is-*` classes mapped to ARIA semantics ([docs/states.md](docs/states.md)).
Expand Down
2 changes: 1 addition & 1 deletion badges/badge-optimal.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"schemaVersion": 1,
"label": "optimal",
"message": "19.6 kB gzip",
"message": "19.4 kB gzip",
"color": "brightgreen",
"namedLogo": "css3"
}
9 changes: 0 additions & 9 deletions configurator/src/components/panels/EffectsPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
let blur = $derived(parseNum(overrides["--sf-blur"], 12, "px"));
let opacityMuted = $derived(parseNum(overrides["--sf-opacity-muted"], 0.5));
let opacityDisabled = $derived(parseNum(overrides["--sf-opacity-disabled"], 0.45));
let pendingOpacity = $derived(parseNum(overrides["--sf-state-pending-opacity"], 0.7));
let scrollbarThumb = $derived(overrides["--sf-scrollbar-thumb"] ?? "");
let scrollbarTrack = $derived(overrides["--sf-scrollbar-track"] ?? "");

Expand Down Expand Up @@ -84,19 +83,11 @@
onChange={(v) => onSet("--sf-opacity-disabled", String(v))}
onReset={() => onReset("--sf-opacity-disabled")}
/>
<SliderRow
label="Pending opacity" value={pendingOpacity} min={0.1} max={1} step={0.05}
help="--sf-state-pending-opacity — opacity of elements in loading/pending state"
overridden={"--sf-state-pending-opacity" in overrides}
onChange={(v) => onSet("--sf-state-pending-opacity", String(v))}
onReset={() => onReset("--sf-state-pending-opacity")}
/>
<!-- Opacity preview -->
<div class="bg-black/4 dark:bg-white/4 rounded-xl border border-black/8 dark:border-white/8 p-3 space-y-2">
{#each [
{ label: "muted", token: "--sf-opacity-muted", val: opacityMuted },
{ label: "disabled", token: "--sf-opacity-disabled", val: opacityDisabled },
{ label: "pending", token: "--sf-state-pending-opacity", val: pendingOpacity },
] as row (row.label)}
<div class="flex items-center gap-3">
<span class="text-[9px] text-slate-400 dark:text-slate-600 w-14">{row.label}</span>
Expand Down
34 changes: 3 additions & 31 deletions configurator/src/components/panels/MiscPanel.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<script lang="ts">
import SliderRow from '../inputs/SliderRow.svelte';
import ColorInput from '../inputs/ColorInput.svelte';
import Toggle from '../inputs/Toggle.svelte';
import Section from '../inputs/Section.svelte';
import { SIZE_SCALE } from '../../lib/variableScales';

Expand Down Expand Up @@ -60,7 +59,7 @@
let showObjectFit = $state(false);
let showPrint = $state(false);
let showSafeArea = $state(false);
let showStateFlags = $state(false);
let showFieldMarker = $state(false);

function getSizeValue(t: typeof SIZE_TOKENS[0]): number {
return parseNum(overrides[t.token]?.replace("rem",""), t.default);
Expand Down Expand Up @@ -456,35 +455,8 @@

<div class="h-px bg-black/6 dark:bg-white/6"></div>

<!-- STATE FLAGS -->
<Section title="State flags" bind:open={showStateFlags}>
<p class="text-[10px] text-slate-400 dark:text-slate-600 leading-relaxed">
Boolean CSS custom property flags (0 = off, 1 = on). Components toggle these to activate state-specific styles.
Overriding globally forces all matching elements into that state — useful for testing and demos.
</p>
<div class="space-y-1.5">
{#each [
{ label: "sf-is-active", token: "--sf-is-active", note: "Active/selected state" },
{ label: "sf-is-current", token: "--sf-is-current", note: "Current page/item" },
{ label: "sf-is-open", token: "--sf-is-open", note: "Open/expanded state" },
{ label: "sf-is-pressed", token: "--sf-is-pressed", note: "Pressed/depressed state" },
] as f (f.token)}
{@const cur = overrides[f.token] ?? "0"}
<div class="flex items-center gap-2 py-0.5">
<Toggle
size="sm"
checked={cur === "1"}
ariaLabel={f.label}
onToggle={() => cur === "1" ? onReset(f.token) : onSet(f.token, "1")}
/>
<span class="text-[9px] font-mono text-slate-700 dark:text-slate-300 w-24 shrink-0">{f.label}</span>
<span class="text-[9px] text-slate-400 dark:text-slate-600 flex-1">{f.note}</span>
{#if f.token in overrides}
<button onclick={() => onReset(f.token)} class="text-[8px] text-slate-500 hover:text-rose-600 dark:hover:text-rose-400 cursor-pointer shrink-0">reset</button>
{/if}
</div>
{/each}
</div>
<!-- FIELD MARKER -->
<Section title="Field marker" bind:open={showFieldMarker}>
<div class="flex items-center gap-2 pt-1">
<span class="text-[10px] font-semibold text-slate-600 dark:text-slate-400 w-24 shrink-0">Required marker</span>
<input
Expand Down
2 changes: 1 addition & 1 deletion configurator/src/components/panels/WcagPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

const TEXT_OPTS: ColorOpt[] = [
{ label: "Text", expr: "var(--sf-color-text)" },
{ label: "Text secondary", expr: "var(--sf-color-text--secondary)" },
{ label: "Text secondary", expr: "var(--sf-color-text--subtle)" },
{ label: "Text muted", expr: "var(--sf-color-text--muted)" },
{ label: "White", expr: "#ffffff" },
{ label: "Black", expr: "#000000" },
Expand Down
142 changes: 8 additions & 134 deletions configurator/src/data/api-index.generated.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
"_sync": {
"generatedBy": "configurator/scripts/sync-api.mjs",
"source": "docs/api-index.json",
"tokensHash": "2d7e174d5d83",
"tokensHash": "d99951a174ca",
"bundles": [
"full",
"optimal"
],
"counts": {
"tokens": 747,
"tokens": 741,
"byTier": {
"PUBLIC": 693,
"PUBLIC-ADVANCED": 53,
"PUBLIC": 691,
"PUBLIC-ADVANCED": 49,
"INTERNAL": 1
},
"byCategory": {
"Layout tokens": 53,
"Core tokens": 616,
"Core tokens": 610,
"Macro tokens": 32,
"Component tokens": 46
}
Expand Down Expand Up @@ -7331,14 +7331,14 @@
]
},
{
"name": "--sf-color-text--secondary",
"name": "--sf-color-text--subtle",
"tier": "PUBLIC",
"role": "consumption",
"namespace": "color",
"category": "Core tokens",
"group": "Text",
"description": "Semantic text colors for every content role. All tokens adapt to light and dark mode automatically.",
"note": "De-emphasised secondary text (captions, labels, supporting copy).",
"note": "De-emphasised, lower-emphasis text (captions, labels, supporting copy). Second tier below --sf-color-text; sits between it and --sf-color-text--muted.",
"value": "light-dark( oklch(from var(--sf-color-neutral-source-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) )",
"aliasOf": null,
"registered": false,
Expand Down Expand Up @@ -7792,27 +7792,6 @@
"optimal"
]
},
{
"name": "--sf-current-font-weight",
"tier": "PUBLIC",
"role": "consumption",
"namespace": "current",
"category": "Core tokens",
"group": "Font weights",
"description": "Numeric font-weight scale plus named aliases for common roles.",
"note": "Inherits the current font-weight from context. Useful as a reset.",
"value": "var(--sf-font-weight-bold)",
"aliasOf": "--sf-font-weight-bold",
"registered": false,
"syntax": null,
"fallbackOnly": false,
"optional": false,
"layer": "slashed.tokens",
"bundles": [
"full",
"optimal"
]
},
{
"name": "--sf-density",
"tier": "PUBLIC-ADVANCED",
Expand Down Expand Up @@ -10708,48 +10687,6 @@
"optimal"
]
},
{
"name": "--sf-is-active",
"tier": "PUBLIC-ADVANCED",
"role": "knob",
"namespace": "is",
"category": "Core tokens",
"group": "INTERACTION STATE FLAGS",
"description": "Integer flags toggled by JS or CSS :has() to drive numeric branching in calc() expressions. Set to 1 to activate the state; 0 is the default off state.",
"note": "Integer state flag for the active state. Set to 1 (via JS or .sf-is-active) to drive branching calc() expressions. 0 = default (inactive).",
"value": "0",
"aliasOf": null,
"registered": true,
"syntax": "<integer>",
"fallbackOnly": false,
"optional": false,
"layer": "slashed.tokens",
"bundles": [
"full",
"optimal"
]
},
{
"name": "--sf-is-current",
"tier": "PUBLIC-ADVANCED",
"role": "knob",
"namespace": "is",
"category": "Core tokens",
"group": "INTERACTION STATE FLAGS",
"description": "Integer flags toggled by JS or CSS :has() to drive numeric branching in calc() expressions. Set to 1 to activate the state; 0 is the default off state.",
"note": "Integer state flag for the current/selected state. Set to 1 (via .sf-is-current) to drive branching calc() expressions. 0 = default.",
"value": "0",
"aliasOf": null,
"registered": true,
"syntax": "<integer>",
"fallbackOnly": false,
"optional": false,
"layer": "slashed.tokens",
"bundles": [
"full",
"optimal"
]
},
{
"name": "--sf-is-dark",
"tier": "INTERNAL",
Expand All @@ -10771,48 +10708,6 @@
"optimal"
]
},
{
"name": "--sf-is-open",
"tier": "PUBLIC-ADVANCED",
"role": "knob",
"namespace": "is",
"category": "Core tokens",
"group": "INTERACTION STATE FLAGS",
"description": "Integer flags toggled by JS or CSS :has() to drive numeric branching in calc() expressions. Set to 1 to activate the state; 0 is the default off state.",
"note": "Integer state flag for the open/expanded state. Set to 1 (via .sf-is-open) to drive branching calc() expressions. 0 = default (closed).",
"value": "0",
"aliasOf": null,
"registered": true,
"syntax": "<integer>",
"fallbackOnly": false,
"optional": false,
"layer": "slashed.tokens",
"bundles": [
"full",
"optimal"
]
},
{
"name": "--sf-is-pressed",
"tier": "PUBLIC-ADVANCED",
"role": "knob",
"namespace": "is",
"category": "Core tokens",
"group": "INTERACTION STATE FLAGS",
"description": "Integer flags toggled by JS or CSS :has() to drive numeric branching in calc() expressions. Set to 1 to activate the state; 0 is the default off state.",
"note": "Integer state flag for the pressed state. Set to 1 (via .sf-is-pressed) to drive branching calc() expressions. 0 = default.",
"value": "0",
"aliasOf": null,
"registered": true,
"syntax": "<integer>",
"fallbackOnly": false,
"optional": false,
"layer": "slashed.tokens",
"bundles": [
"full",
"optimal"
]
},
{
"name": "--sf-leading-normal",
"tier": "PUBLIC",
Expand Down Expand Up @@ -11198,7 +11093,7 @@
"namespace": "opacity",
"category": "Core tokens",
"group": "Opacity",
"description": "Opacity tokens for specific UI states: --sf-opacity-disabled dims non-interactive elements; --sf-state-pending-opacity dims elements in an async/loading state.",
"description": "Opacity tokens for specific UI states: --sf-opacity-disabled dims non-interactive elements.",
"note": "Opacity for disabled UI elements (typically 0.4–0.5).",
"value": "0.45",
"aliasOf": null,
Expand Down Expand Up @@ -13480,27 +13375,6 @@
"optimal"
]
},
{
"name": "--sf-state-pending-opacity",
"tier": "PUBLIC",
"role": "knob",
"namespace": "state",
"category": "Core tokens",
"group": "Opacity",
"description": "Opacity tokens for specific UI states: --sf-opacity-disabled dims non-interactive elements; --sf-state-pending-opacity dims elements in an async/loading state.",
"note": "Opacity for pending / loading state elements.",
"value": "0.7",
"aliasOf": null,
"registered": false,
"syntax": null,
"fallbackOnly": false,
"optional": false,
"layer": "slashed.tokens",
"bundles": [
"full",
"optimal"
]
},
{
"name": "--sf-sticky-offset",
"tier": "PUBLIC",
Expand Down
Loading