Spark

Styleguide

Design System

Spark's design system is the shared foundation for every site in the monorepo. It packages design tokens, semantic roles, and ready-made utilities for colour, typography, spacing, surfaces, and motion so designers and developers work from the same source of truth. Import @spark/design-system once in your root layout, then apply CSS variables, Tailwind classes, or named utility classes across pages and components.

This styleguide walks through those foundations with live demos — browse tokens, semantic roles, and utility classes, then see them applied on real components. Tokens originate in @spark/design-system, flow into Tailwind v4's @theme layer, and reach each app from there, keeping web and studio visually aligned without maintaining parallel CSS.

Import

@spark/design-system

Structure

tokenssemanticbaseutilities

Apply

text-displaybtn-primarypage-x

Browse

Foundations

Tokens, utilities, and patterns shared across every Spark site. Pick a section to browse values, classes, and usage notes.

Colors

The colour system centres on a cool zinc grey scale from white to near-black. Lighter steps suit backgrounds, borders, and subtle fills; darker steps carry text hierarchy and emphasis, while the semantic roles below map UI parts to consistent colours. In code, use bg-neutral-* and text-neutral-* utilities, --color-neutral-* from tokens.css, or named roles from semantic.css.

Neutral palette

Thirteen steps from white to near-black. Lighter shades suit backgrounds and borders; darker shades carry text and emphasis. Copy an OKLCH value or use --color-neutral-{step} with matching Tailwind classes.

NameVariableOKLCH
black--color-black
oklch(14.48% 0 0)
white--color-white
oklch(100% 0 0)
neutral-50--color-neutral-50
oklch(98.51% 0 0)
neutral-100--color-neutral-100
oklch(96.74% 0.0013 286.38)
neutral-200--color-neutral-200
oklch(91.97% 0.004 286.32)
neutral-300--color-neutral-300
oklch(87.11% 0.0055 286.29)
neutral-400--color-neutral-400
oklch(71.18% 0.0129 286.07)
neutral-500--color-neutral-500
oklch(55.17% 0.0138 285.94)
neutral-600--color-neutral-600
oklch(44.19% 0.0146 285.79)
neutral-700--color-neutral-700
oklch(37.03% 0.0119 285.81)
neutral-800--color-neutral-800
oklch(27.39% 0.0055 286.03)
neutral-900--color-neutral-900
oklch(21.03% 0.0059 285.89)
neutral-950--color-neutral-950
oklch(14.08% 0.0044 285.82)

Semantic colors

Named roles tie UI parts to the palette so themes stay consistent. Apply bg-background, text-foreground, border-border, or the --color-* variables in semantic.css.

NameVariableMaps to
background--color-backgroundwhite
foreground--color-foregroundneutral-900
muted--color-mutedneutral-500
muted-subtle--color-muted-subtleneutral-400
border--color-borderneutral-200
border-subtle--color-border-subtleneutral-100

Typography

A responsive type scale separates hero headlines from body copy and labels. Apply text-display, text-heading, text-body, and siblings, or rely on base h1–h6 styles from base.css.

Type scale

Each step has a clear job. Display draws attention, body carries reading text, and labels organise metadata. Pick the utility that matches the content role.

Displaytext-display
3rem → 4.8remsemibold

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Headingtext-heading
2.4rem → 3.6remsemibold

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Titletext-title
1.8remnormal weight

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Body largetext-body-lg
2remnormal weight

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Bodytext-body
1.6rem → 1.8rem

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Captiontext-caption
1.4rem

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Labeltext-label
1.2remuppercase, widest tracking

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

HTML headings

Use semantic h1–h6 tags for accessible document outline. base.css gives every heading the same sans face, semibold weight, and tight leading; font size is not set there. Add a Tailwind text utility on the token scale below (text-4xl on h1 down to text-base on h6) to step from page title to the smallest section label. Each specimen lists the paired class with rem and px sizes.

<h1>text-4xl
2.25rem / 36px--text-4xllh 1.11semibold

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

<h2>text-3xl
1.875rem / 30px--text-3xllh 1.2semibold

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

<h3>text-2xl
1.5rem / 24px--text-2xllh 1.33semibold

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

<h4>text-xl
1.25rem / 20px--text-xllh 1.4semibold

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

<h5>text-lg
1.125rem / 18px--text-lglh 1.56semibold
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<h6>text-base
1rem / 16px--text-baselh 1.5semibold
Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Buttons

Four styles signal priority, from primary actions through to ghost links. Use btn-primary or the classes below; a shared @spark/ui Button is planned.

Variants & states

Primary fills the main action; secondary outlines it; tertiary sits on muted surfaces; ghost handles low-emphasis links. Disabled variants reduce opacity and block interaction.

PrimarySecondaryTertiaryGhost
Default
Disabled

btn-primary utility

Named utility in utilities.css — dark fill, uppercase label, and subtle hover fade via duration-fast. Secondary, tertiary, and ghost use equivalent Tailwind classes until shared utilities ship.

btn-primary

Apply directly on a <button> or link. A shared @spark/ui Button component is planned.

Surfaces

Surfaces are layered backgrounds that set section mood and keep typography readable. Most pages read on bg-background with text-foreground; cards and headers step up to bg-white with border-border, while sidebars and secondary chrome stay quieter on muted fills such as bg-neutral-100. When a footer, feature band, or CTA needs more presence, reach for surface-dark. The layout demos below show how those layers stack on light and dark pages — hover a region to reveal its tokens.

Light surfaces

bg-backgroundtext-foreground
bg-background

Dark surfaces

bg-backgroundtext-foreground
bg-background

Spacing & layout

A numbered scale keeps padding and gaps consistent across breakpoints. Use Tailwind spacing utilities (gap-200, m-100, p-300, space-x-150) or --spacing-* CSS variables; grid gap and margin tokens (--spacing-grid-gap, --spacing-grid-margin) are listed under Grid spacing — apply page-x for responsive horizontal page gutters.

PreviewTokenVariableValue
0--spacing-00px
25--spacing-251px
50--spacing-502px
75--spacing-754px
100--spacing-1008px
150--spacing-15012px
200--spacing-20016px
300--spacing-30024px
400--spacing-40032px
450--spacing-45044px
500--spacing-50048px
600--spacing-60064px
700--spacing-70080px
800--spacing-80096px
900--spacing-900128px
Grid spacing
grid-gap200--spacing-grid-gap16pxgap-grid-gap
grid-margin200--spacing-grid-margin16pxpx-grid-margin, mx-grid-margin

Motion

Motion should feel immediate and intentional, clarifying change without slowing frequent interactions. A three-step duration scale (fast, normal, slow) works with purpose-built easing curves (--duration-* and --ease-*): ease-out for enters and exits, ease-in-out for reversible states, ease-drawer for sliding panels. The live demo below lets you compare pacing and curves side by side.

Tokens

Semantic duration names map to interaction types. Easing curves are custom — stronger than built-in CSS easings.

Duration
  • --duration-fast150ms

    Button press, tooltips, micro-feedback

  • --duration-normal200ms

    Dropdowns, hovers, color transitions

  • --duration-slow300ms

    Modals, drawers, panel transitions

Easing
  • --ease-outcubic-bezier(0.23, 1, 0.32, 1)

    Default for enters and exits — starts fast, feels responsive

  • --ease-in-outcubic-bezier(0.77, 0, 0.175, 1)

    On-screen movement and morphing between positions

  • --ease-drawercubic-bezier(0.32, 0.72, 0, 1)

    Drawers and sheet transitions (iOS-like curve)

Live demo

Interactive examples — press feedback, duration pacing, and easing comparison. Respects prefers-reduced-motion.

Press feedback

Hold the button — transform scales to 0.97 with duration-fast and ease-out. Specify exact properties, never transition: all.

Duration

Press Replay — all three tracks fill together with the same ease-out curve. Each row uses a different duration token so 150ms finishes before 200ms, then 300ms.

duration-fast150ms
duration-normal200ms
duration-slow300ms
Easing

Time maps to progress on the curve. Compare how each easing moves the traveler on the same track.

Easing curve preview
cubic-bezier(0.23, 1, 0.32, 1)

Starts fast, settles gently

Default for enters and exits — elements arrive with energy, then decelerate into place.

Linear time →

Reduced motion

Transform animations use motion-safe: so they respect prefers-reduced-motion. Keep opacity and color transitions that aid comprehension.