Skip to content
Dirework

Design System

Dirework's design tokens, the dw-* utility layer, and shared UI primitives.

Dirework ships a small, generated design system so the web app, the docs site, and the OBS overlays all speak the same visual language. The source of truth is a single JSON file; everything else is generated from it.

Source of truth

design-system/
  tokens.json          # canonical tokens — edit this
  scripts/generate.ts  # bun script that emits per-platform outputs
  README.md            # full reference
  components/          # markdown catalog (one .md per primitive)

Regenerate the outputs from the repo root:

bun run tokens

This writes one committed file:

OutputConsumed by
apps/fumadocs/src/app/(home)/_widgets/overlay-themes.generated.tsLanding-page theme gallery

CI verifies the outputs are in sync: bun run tokens && git diff --exit-code. Never edit a generated file by hand.

Shared overlay geometry and clock formatting (roundedRectPath, roundedRectPerimeter, formatClock, SQUIRCLE_RADIUS) live in the workspace package @dirework/overlay-kit (packages/overlay-kit), used by both the real OBS overlays and the docs mocks. A unit test in the web app keeps tokens.json in sync with the Theme Center presets and SQUIRCLE_RADIUS.

Focus Console

The visual language is Focus Console — a dark-first instrument panel. Dark mode is the hero: a MrDemonWolf midnight-navy base (the #091533 family) with cool-white text. Light mode is fully supported (cool paper with a navy cast).

  • Brand primary: Cerulean #00ACED — the accent, used sparingly (buttons, links, active rings).
  • Secondary accent: Cornflower #6B8BF5.
  • Twitch: #9146FF is reserved for "Sign in / Connect with Twitch" actions only.
  • Phase colors: work = emerald #34C759, break = cerulean, long break = cornflower, paused = amber #FF9F0A.
  • State: emerald = live / connected, amber = paused / warning (LED-style chips).

Type:

  • Display / headings: Montserrat (--font-display)
  • Body: IBM Plex Sans (--font-body)
  • Labels & numerals: IBM Plex Mono (--font-mono) — timer digits use tabular-nums

Tokens

Structural tokens (spacing, radius, motion, shadow, and the type scale) come from the generated --ds-* layer. The Focus Console color and font choices live in apps/fumadocs/src/app/global.css, mirroring the web app's apps/web/src/index.css, and are exposed through a thin semantic layer the docs surfaces read from.

NamespaceVariable patternExample
Brand--brand-500 / --brand-600 / --brand-50--brand-500: #00ACED (cerulean)
Phase--phase-{work,break,long-break,paused}timer ring + status accents
Partner--color-twitch, --color-liveTwitch actions / live state
Surface--bg-base / --bg-surface / --bg-elevlight/dark aware
Text--txt-1 / --txt-2, --hairlinelight/dark aware
Fonts--font-display / --font-body / --font-monoMontserrat / Plex Sans / Plex Mono
Space--ds-space-{0…11}4px-based scale (generated)
Radius--ds-radius-{xs…2xl,pill}--ds-radius-pill: 9999px (generated)
Motion--ds-motion-duration-*, --ds-motion-easing-*fast: 150ms (generated)

Dark-mode values are swapped under .dark automatically.

The dw-* utility layer

The marketing and docs surfaces use a thin set of utility classes (defined in apps/fumadocs/src/app/global.css) that read the tokens. They keep the landing page token-backed without pulling in a component framework.

ClassPurpose
dw-display / dw-monoMontserrat heading + Plex Mono label styles
dw-text-1 / dw-text-2 / dw-text-brandText hierarchy
dw-bg-base / dw-bg-surface / dw-bg-elevSurfaces
panel / panel-hero / panel-insetFlat instrument panels (workhorse / gradient hero / recessed well)
console-label / console-ruleMono section label + labeled hairline rule
dw-chip + dw-chip-{accent,live,warn}LED-style status chips
dw-kicker + dw-kicker-numNumbered section kicker (01 · …)
dw-card / dw-card-hoverContent container
dw-btn + dw-btn-{primary,secondary,twitch,ghost}Buttons
dw-pillMetadata / trust chip
dw-codeCode well
bg-grain / bg-checkerModule grain / OBS transparency preview
dw-reveal-{1,2,3} / animate-led-pulseStaggered entrance + LED pulse

Component catalog

Shared primitives are documented one-per-file under design-system/components/:

  • Button, Card, Glass Card, Pill — console chrome
  • Timer Ring — the overlay progress ring (circle + squircle), mirroring apps/web/src/lib/timer-utils.ts
  • Task Card — the grouped task overlay, mirroring task-list-display.tsx
  • Chat Bubble — the Twitch command preview
  • Theme Swatch — the overlay theme gallery, driven by the generated OVERLAY_THEMES

Overlay themes

overlay.themes in tokens.json mirrors the 6 presets in apps/web/src/lib/theme-presets.ts, holding the four swatch colors each exposes (bg, accent, text, username). That data is generated into a typed module the landing-page gallery renders. When a preset's preview colors change, update tokens.json and run bun run tokens.

Accessibility rules

  • Two themes, always. Every surface must read in light and dark.
  • Never color alone. Done tasks use strike-through and a dimmed color.
  • Honor reduced motion. Animated primitives stop under prefers-reduced-motion: reduce.
  • Real interactive elements. Buttons and links are <button>/<a>, never clickable <div>s.

On this page