Accent call-out
bg: token:primary · text: contrast:AAA vs bg · border: rule:complement(primary)
Tweak a single base color, type scale, or spacing unit and watch every surface, every component, every proportion respond in real time. Export to your framework of choice.
This whole section sits on .surface-secondary. Headings, body copy, links, and button labels auto-pick the right tokens through the cascade — no per-element overrides required.
Every surface in LSD carries its own background color. When you place content on a surface, text/heading/link/border colors automatically re-resolve to ensure contrast passes. Watch the colors shift as you scroll.
Toggle the theme in the topbar — watch the neutrals re-anchor while role tokens stay bound.The outer surface is primary; the inner surface is elevated. Each level re-resolves its own --*--current tokens, so heading, body, link, and border colors shift with the nesting — no per-element overrides.
Every descendant picks its --*--on-primary variant automatically…
A ladder is a convenient seed, not a constraint. Any tier's bg / text / border / link / button can pull from a different token, a different rule, or a freeform hex. Three compositions below — each coordinates colors that come from three different sources.
bg: token:primary · text: contrast:AAA vs bg · border: rule:complement(primary)
bg inherits from .surface-elevated, link reads token:secondary, the callout border uses token:warning. No single "theme" owns this card.
bg: freeform hex #0a0e1a · text: #c9d1e0 · link: token:primary. The ladder stays in OKLCH-material-mode globally; this one surface opts out because a code block needs near-black.
The takeaway: a surface is a collection of independent tiers. Each tier's role layers can come from anywhere. The ladder's stepL / strategy just seeds sensible defaults — override any role on any tier to mix sources.
A surface paints itself and a narrow set of structural descendants. Drop plain HTML into .surface-primary (or any colored factory) and the structural markup picks up treatment — blockquote rails, pre/code pills, hr separators. No wrapper classes, no inline styles, no authored CSS. The rules live in the surface's descendantRules config, seeded by the factory defaults.
One class on the wrapper. The heading, body copy, and inline code pick up their paint from the surface alone.
No authored CSS. Only the factory surface defaults are in play.
Drop a Markdown render in. No wrapper classes on the children.
Surfaces don't need the markup to be polite. Pasted documents still pick up the paint.
$ lsd export --target css
wrote: dist/surfaces.css
ready.
Blockquote rail, pre well, and code pill all come from surface-primary's seeded descendantRules.
Same markup on any colored surface picks up the correct palette tint.
The surfaceLegacy API is scheduled for removal in v2027.1.
defaultSurfaceStacks()emitLegacySurface() importslsd migrate --surfaces to rewrite referencesSee the migration guide for full details.
Inline code, list markers, and the <hr> separator all follow the danger palette.
Grammar is narrow by design: single tags, tag-lists (h1, h2, h3), :first-of-type positions, and > :nth-child(n) direct-child indexes. No *, no attribute selectors, no descendant combinators — enough reach for structural markup, not enough to make a mess.
Every active surface emits .surface-<id>-t<n> classes for each tier. Give an element an id and hook the tier class in a selector — that's the whole story. Each example below shows the exact markup and the exact CSS that produced it. Copy either verbatim.
Sits on .surface-primary-t2. The local rule lifts only this anchor — try the beta →. Tier emission is untouched.
One-off glow on .surface-secondary-t1. Every other tier-1 block on the page stays flat.
uptime across the last 90 days
A single pricing card lifts and rings by targeting its tier. No variant class, no duplicated surface.
Authored rail on the inline-start edge, scoped to #ex-doc. The tier carries the fill; the ID adds the accent strip.
Reuse pattern: give callouts their own IDs and paint them against the same tier — one rule per flavor.
When one element needs to bend the rules, you don't need a new token or a new surface — just an id and a selector. The emitted tier classes become anchor points for authored CSS.
Fluid type using clamp(). Resize the preview to watch it breathe.
Body text — Design tokens are the single source of truth for your visual language. They describe colors, typography, spacing, and elevation in a way that can be shared across platforms and frameworks. When the tokens change, the entire interface adapts in a single, coherent motion.
Buttons, badges, and cards share the token language.
Every brand starts with color. Your palette propagates automatically to every surface.
Fluid scales keep your hierarchy responsive across devices without media-query gymnastics.
A unified spacing scale enforces rhythm across components and layouts.
The same .card markup, placed inside different surface contexts. Headings, body text, and buttons auto-select the right role tokens through the cascade.
This card sits on a primary background. All text, headings, and button labels pick their on-primary variants automatically.
Same markup, different context. The secondary surface cascade remaps every role token — no per-element overrides.
Card hover patterns — headline visible by default, description revealed on hover.
Description fades into view with a subtle gradient backdrop when the card is hovered.
Connecting cross-functional teams through clear systems and shared design tokens.
Media containers at proportions derived from --aspect-* tokens.
Drag the right edge of any stage — or tap a preset — and watch the component reflow via @container queries. Presets are pulled live from the canvasWidths tokens. Add a new width token in the Tokens tab and its preset button shows up here automatically.
.lt-author · @container lt (min-width: 520px)
.lt-cta · split at 560px
v0.6 · ship-ready
Export tokens to CSS, Tailwind, or any framework you already use.
.lt-img · media+caption → overlay
.lt-bento · 1 → 2 → 4 cols
.lsd-slideshow · 1 → 2 → 3 visible via container query · dogfooded block
CSS-first .lsd-slideshow block — scroll-snap + anchor navigation work without JS. The lsd-slideshow.js enhancer layers autoplay, looping, and active-dot sync on top.
Viewport-triggered entrance animations. Scroll back up to retrigger where supported.
Default entrance — element rises and fades in as it enters the viewport.
Gentle zoom-in for hero callouts and key statistics.
Quiet option — opacity without movement, for dense content.
Combine with delay utilities to cascade multiple tiles.
Motion
Every preset is transition-driven or keyframed CSS — drop a class on any element. Copy the chain, the data-lsd-fx attribute, or the raw CSS for any build stack.
Mouseover, focus, and transition patterns — each demo is live. Hover the element, then click “Copy CSS” to take the snippet.
Feature tiles pairing iconography with short copy.
Every component reads from the same spacing, color, and type scale.
Flip between Tailwind, Bootstrap, Foundation, or pure CSS output.
Neutral ramp auto-inverts with a single attribute flip.
Copy section HTML with or without resolved inline styles.
| Token | Category | Purpose |
|---|---|---|
--color-primary | Color | Primary brand accent |
--text-h1 | Typography | Fluid heading level 1 |
--space-lg | Spacing | Default vertical rhythm |
--radius-md | Shape | Standard component radius |
--shadow-md | Elevation | Raised surface |
Three tiers, one token system. The featured plan inherits the primary color.
What teams say after wiring their design system to a single source of truth.
LSD collapsed three days of palette bikeshedding into a 20-minute working session. We left with tokens our engineers actually shipped.
Being able to swap frameworks live and watch the same showcase respond is the demo that finally got our director to greenlight the rebrand.
The exporter output dropped straight into our Tailwind config. No translation layer, no design-to-code handoff doc.
Status messaging styled by semantic color tokens, plus a token-aware code surface.
A new version of the exporter is available in the drawer.
Your preset “Brand v3” was written to local storage.
Body text on surface fails WCAG AA. Consider darkening the text token.
Could not parse pasted CSS. Check that variables use the --color-* prefix.
import { createStore, resolveTokens } from './state';
const store = createStore(defaultState);
store.subscribe((state) => {
const tokens = resolveTokens(state);
applyToIframe(tokens, state.framework);
});
store.patch({ tokens: { colors: { primary: '#7c5cff' } } });
Answers to the questions we hear most often from teams evaluating LSD.
Yes. Paste your existing CSS variables into the import panel and LSD will parse them into editable tokens. From there, every change re-exports cleanly back to your chosen framework.
All three plus a framework-agnostic CSS variables mode. Swap the target from the drawer and the preview re-renders with the matching stylesheet loaded live.
Presets can be saved locally for personal iteration, or pushed to the shared Bun server. Teams on the Pro plan get cloud sync so everyone stays on the same tokens.
LSD ships exporters for CSS variables, SCSS, Tailwind config, Bootstrap overrides, and Foundation settings. Pick a target and copy the output straight into your repo.
The MCP server exposes your tokens and presets to Claude and other agents, so you can ask for "a fintech palette with tighter spacing" and let the agent draft a preset you can then refine by hand.
A snapshot of how the LSD showcase has evolved.
Vite shell lands. The 26-template HSLA-difference palette engine is preserved verbatim from the legacy tool and wrapped in a typed ColorToken layer.
Token editors, six exporters, copy-HTML bridge, dark-mode variants, OKLCH contrast badges, and per-section copy ship together.
A local Bun HTTP server backs shared presets, and an MCP stdio server exposes the same surface to Claude and other AI agents.
Natural-language token generation and live HTML authoring land, letting designers describe a brand and watch the showcase converge on it.
A few vanity metrics to show how trend indicators and display type react to token changes.
Live preview of each --gradient-* token. Click any swatch to copy its variable.
Live reference of every CSS custom property emitted by LSD. Click any row to copy the var(...) expression.