SLASHED — Roadmap
Current version: 0.7.30
Before v1.0
All pre-v1.0 items are complete as of v0.6.0. The API is frozen for non-additive changes; the v0.6.x series focuses on the components layer.
Post-1.0
- Components layer — the
slashed.componentslayer is declared and its first tranche is now live:.sf-btnand.sf-cardshipped in v0.7.0 (#493 / #494), including the outline.sf-btn--outlinevariant (#486), a button size scale, and.sf-cardmodifiers. The remaining.sf-*components (badge, tag, alert, avatar, modal, skeleton) stay staged inoptional/components.cssand land incrementally in later minors. Tracked in #384 (consolidated tranche). ✓ Done — spacing (@propertyfor spacing/shadow tokens--sf-radius-*,--sf-space-*, semantic spacing) and shadow (--sf-shadow-*,--sf-text-shadow-*,--sf-drop-shadow-*) tokens are already registered via@propertyincore/tokens.css, alongside the existing colour registrations. Transitions on layout values and DevTools inspection both work.- Consolidate named surfaces onto
.sf-surface— the 10.sf-surface--*variants could become one-line--sf-surface-colorpresets of the generic primitive, once a fallback story for the precomputedtokens.color-fallbacks.csspath is settled. - Curated core utility set — visibility/display, text-alignment,
flex/grid item-alignment, gap, and content-width (default/wide/full)
utilities, shipped enabled (not staged) in a new
slashed.utilitieslayer incore/— distinct from the staged, opt-inoptional/utilities.css. Tracked in #248.
Under consideration
- Per-layer opt-in bundle via
@import— already possible today via the granularcore/optionalfiles (core/layers.cssfirst); needs docs, not code. - Native CSS custom functions (
@function) — anoptional/functions.cssmodule exposing a true--fluid(min, max)(and friends), once cross-engine support for@functionexists. Until then the documentedclamp()recipe covers ad-hoc fluid values without a build step. - Heading helper utilities — activate
.sf-h1–.sf-h6inoptional/utilities.cssso elements can take heading typography without changing document semantics. - Skeleton shape component — ship
.sf-skeletonplus shape modifiers such as.sf-skeleton--text,.sf-skeleton--line,.sf-skeleton--avatar, and.sf-skeleton--rectin the optional components layer. Item 8 of #384. Naming decision (resolved, #575):.sf-skeletonkeeps the industry-standard component name. The shimmer state was renamed.sf-is-skeleton→.sf-is-shimmerahead of the component (shipped standalone in Unreleased — seedocs/migration.md), decoupling that one breaking rename from the component work so.sf-skeletoncan land purely additively. “skeleton” now means exactly one thing — the component, which will compose with.sf-is-shimmerfor the shimmer effect. Shape modifiers must not reuse component names: the card-like placeholder shape is--rect(geometric), never--card, to avoid implying parity with.sf-card’s token set. - Z-index utilities — expose the named z-index scale as
.sf-z-*classes (for example.sf-z-modaland.sf-z-tooltip) inoptional/utilities.css. - First component tranche —
.sf-btnand.sf-cardshipped in v0.7.0 (see Post-1.0 note);.sf-badgeand.sf-tagare next, usingoptional/tokens.components.cssand existing.sf-is-*states where appropriate. Tracked in #384. - Standalone table pattern — add
.sf-table,.sf-table-scroll, and compact variants such as striped, bordered, and compact tables without changing globaltablestyles or.sf-prose tablebehaviour. - Form layout helpers — complement
optional/forms.csswith opt-in structure classes such as.sf-field,.sf-field__label,.sf-field__hint,.sf-field__error,.sf-form-row,.sf-form-col, and.sf-form-inline. - Remaining optional components — after the first component tranche, complete
.sf-alert,.sf-avatar, and.sf-modalwith token-driven variants and native<dialog>compatibility where applicable. Items 5–7 of #384. Outline button variant✓ Done (0.7.0) — the border-only.sf-btn--outlinestyle shipped with the first component tranche. The gradient-border version shipped as the real.sf-btn--gradientmodifier in 0.7.7 (fill + outline, core-4 brand families), replacing the earlier copy-paste recipe indocs/components.md. Tracked in #486 / #571.- Decorative animation utility classes — the keyframes for
sf-spin,sf-shimmer,sf-ping,sf-blink, andsf-floatare already defined incore/motion.css; they need corresponding.sf-spin,.sf-shimmer, etc. utility classes inoptional/utilities.cssto be usable from markup. Hover-transform utility classes✓ Done —.sf-hover-grow,-shrink,-float,-sink,-slide-start,-slide-endare written and documented, staged (commented out) inoptional/utilities.cssalongside the other opt-in utilities, pending activation. Tracked in #487.Overflow-detection debug utility✓ Done —.sf-debug-overflowvisually flags the element(s) causing horizontal page overflow, staged (commented out) inoptional/utilities.csspending activation. Tracked in #495.Divide-between-children macro✓ Done —.sf-divide(+--vertical) applies a border between direct children in one class, reusing.sf-divider’s width/style/color tokens. Shipped (active) incore/layout.css. Tracked in #537.Global media radius✓ Done —--sf-media-radius(0 by default, off) applied via:where(img, figure)incore/base.css; opt in globally by setting the token, without fighting.sf-bg-layeror a component’s own radius (layer order + zero specificity). Tracked in #529.Scroll-out (exit) effects✓ Done —.sf-exit--fade/-fade-up/ -fade-down/-fade-left/-fade-right/-scale-downmirror.sf-entrance--*usinganimation-timeline: view()with acover 70%→exit 100%range. Unlike entrance,animation-nameis set only inside@supports (animation-timeline: view()), so engines without scroll-driven animation support leave the element visible instead of fading it out unconditionally. Shipped (active) incore/motion.css. Tracked in #527.Small utilities:✓ Done — both written and staged (commented out) in.sf-list-none/.sf-selection--altoptional/utilities.csspending activation, alongside the other opt-in utilities..sf-selection--altoverrides--sf-color-selection-bg/-textvia new--sf-color-selection-*--alttokens. Tracked in #540.Sticky positioning utility✓ Done —.sf-stickyplus--s/-m/-loffset modifiers, active inoptional/utilities.css, layering extra gap on top of the existing--sf-sticky-offsetfluid offset. This is now the sole sticky mechanism — the redundant sticky state class was removed (position: stickyis conditional by nature and needs no runtime toggle). Tracked in #542.- Interactive
drives Nexploration — turn the configurator’s passive dependency-count badge into a keyboard-accessible popover/list that navigates to dependent tokens. - Motion configurator UX expansion — extend the existing motion domain with
richer previews, motion presets,
--sf-motion-scaleaffordances, animation tokens, and transition-token editing. - Configurator: live hover preview in CheatsheetPanel — hovering a
class/token entry in
CheatsheetPanel.sveltelive-previews it against the currentPreviewPanelelement, reverting on mouseleave. Tracked in #470. - Design-token export formats — CSS and SLASHED theme JSON already exist; consider Figma Tokens, W3C Design Tokens, and Style Dictionary export/import if design-tool workflows become a priority. DTCG/W3C export specifically tracked in #361.
- Versioned token manifest + JSON Schema — promote
docs/api-index.jsonto a versioned, published artifact with a companion JSON Schema so external tools (WP plugin, configurator, editors, linters) can consume the token/class catalogue against a stable contract, validated in CI. Tracked in #360. - Consumer-facing Stylelint plugin/config — a shippable, separately
published Stylelint config that lints consumer projects using SLASHED
(
@layerorder,sf-/sf-is-reserved-name collisions, raw values that should be tokens). Tracked in #363. - Distilled AI-assistant context file (
llms.txt) — a compact, build-generated distillation ofdocs/llm-guide.mdfor consumers to drop into their own AI coding assistant’s context. Tracked in #472. - MCP server for live token/class data — explore an MCP server exposing
the generated token/class/API-index data as live tools/resources
(
search_tokens,get_class_info, etc.) for AI coding assistants, as a live alternative to the staticllms.txt. Tracked in #473. Concave/inverted corner utility✗ Not planned — shipped as.sf-corner-scoop(mask-based radial-gradient cut with 4 single-corner position variants) and then removed before 1.0. Judged too niche for the public API relative to its cost: a single absolute--sf-corner-scoop-sizeneeds per-element tuning to read well across button-sized and hero-sized boxes, and the mask clipsbox-shadow/borderand can’t compose with the other mask-based macros (.sf-overflow-fade,.sf-scroll-shadow) on the same element. (A two-corner “pair variant” for U-shaped cutouts had already been dropped earlier — WebKit’smask-compositehas a bug with no viable workaround.) Tracked in #484.Boxed-section layout primitive✗ Not planned — a.sf-boxedsection macro was implemented and then dropped after review; judged too thin a wrapper over existing primitives (.sf-section+ border/shadow/ radius tokens) to justify a dedicated class. Tracked in #485.Flex-based grid alternative✓ Done — shipped as.sf-grid-flex(+ size/gap/--centervariants) alongside.sf-grid/.sf-equal/.sf-grid-cols-*, documented for the uneven-item-count case. Tracked in #488.Unified background media overlay macro✓ Done — resolved as composition guidance rather than a new macro:.sf-scrimcomposed with the existing.sf-bg-layerbackground-media primitive already layers a color/gradient overlay with correct automatic stacking; documented indocs/macros.mdinstead of adding a redundant class. Tracked in #489.- Concrete recipe macros — partially done. Shipped:
.sf-overlap/.sf-overlap-host(overlap + card-container recipes). Two corner-recipe macros were built and then cut before 1.0 —.sf-corner-scoop(mask-based concave cut, tracked as #484 above) and a.sf-cornerslogical-corner recipe (with a--leafasymmetric variant) — both judged too niche for the public API relative to their long-term maintenance cost. Tracked in #490. - Container-relative fluid scale — the
--sf-text-*/--sf-space-*fluid scales are100vw-driven and don’t respond to@containerwidth the way the layout primitives do; investigate acqi-based opt-in variant for nested/narrow contexts (sidebars, cards) without replacing the viewport-based page-level default. A technique spike was posted as an issue comment; no code shipped yet. Tracked in #497. - Hero recipe / alias — document or optionally add a
.sf-heroconvenience pattern that composes existing.sf-coverand.sf-scrimbehaviour. - Scroll progress bar recipe — consider an optional JS-assisted or scroll-timeline-enhanced reading progress pattern once fallback expectations are clear.
- Auto-grid ratio helper — evaluate whether a ratio-driven auto-grid adds
enough value beyond the existing
--sf-grid-min/.sf-grid--fitAPI. - Animated link effects — extend existing link variants with opt-in effects such as underline growth or fade behaviours while preserving accessible reduced-motion fallbacks.
Out of scope
- A full utility-first API — SLASHED remains BEM-first and token-first. Small,
token-backed, single-purpose helpers may be considered in
optional/utilities.css, but a broad Tailwind-style utility surface is out of scope.
The following are permanently excluded — deliberate architectural decisions, not backlog. They should not be re-proposed or picked up by accident:
- Runtime JavaScript in the framework core — the core ships zero runtime JS and
will keep doing so. Viewport-triggered “reveal on scroll / on-visible” behaviour
that depends on an
IntersectionObserveris out of scope forcore/; the supported surfaces are the CSS-only.sf-visibleutility hook (optional/utilities.css) and scroll-timelineview()entrance animations. Any observer-driven JS belongs to host/integration layers, never to the framework bundle. - A consumer-facing preprocessor layer (mixins / functions) — SLASHED is authored
and shipped as plain CSS with no build step for consumers. We will not expose an
@include/@function-style mixin or helper-function authoring API. Native CSS (calc(),pow(),color-mix(), relative colour syntax, and — when it lands — CSS@function) is the intended substitute. - Prefix-based automatic component styling — the framework will not auto-style
arbitrary classes by name pattern (e.g. “style everything matching
*--primaryor.btn-*”). Components are explicit BEM classes (.sf-*); there is deliberately no “style anything that matches this prefix” mechanism. - Viewport-breakpoint utilities / breakpoint mixins — responsiveness is expressed
with container queries and intrinsic, breakpoint-free techniques. A media-query
breakpoint utility or mixin system (viewport
--l-/--md:suffixes,breakpoint()-style helpers) is out of scope. - Snippet-expansion (“recipe”) syntax — a
?name-style token that expands into a CSS block requires a preprocessor or builder pass, which the pure-CSS framework will not implement. Editor/builder integrations may offer their own snippets; that is an integration concern, not acore/feature. - Selector-list-driven rule generation — the framework will not read a user-supplied list of selectors and graft component rules onto them (e.g. “apply these card styles to this selector list”). Consumers opt in by applying the component class itself.
- Per-channel colour partials (
-h/-s/-l,-r/-g/-b) — the colour system is built on OKLCH, relative colour syntax, andcolor-mix(). We will not ship per-channel HSL/RGB partial tokens for manual recomposition; relative colour syntax covers those cases. - Placeholder-content and script-wrapper helpers — generating dummy/lorem text or
<script>boilerplate is not a styling concern and is out of scope for a CSS framework.