Design System

01ive-ds

alpha

A warm dual-canvas design system for a personal web app. The system anchors on a warm sand canvas (light) that flips to a deep warm-charcoal canvas (dark), with one olive-green primary and two warm accents (amber + rust). Brand voltage comes from the olive/sand pairing combined with tactile retro hardware — primary controls are 36px 3D keys whose ledge is contained inside their measured height. Type voice is JetBrains Mono for display headings, titles and code, paired with variable Noto Sans for body copy, labels and controls. ASCII-art panels and a terminal motif carry the technical character.

This page is generated from DESIGN.md (tokens) and the @workspace/ui barrel (components) — it stays in sync automatically.

Concepts

Dual canvas

A warm sand canvas in light flips to deep warm-charcoal in dark. Toggle the theme in the header — every token, swatch, and component below re-renders live.

The 3D key mechanic

Every primary control is a key resting on a colored ledge: it drops halfway on hover and levels flat on press. Tactile retro hardware, in pure CSS.

Focused mono voice

JetBrains Mono gives display headings, titles and code their technical character; Noto Sans keeps body copy, labels and controls clear and comfortable.

Terminal & ASCII

A terminal motif and animated ASCII panels carry the technical character across the surface.

Full written spec, do's and don'ts, and dark-mode mapping live in /DESIGN.md.

Application patterns

Command-driven rich text

Basketball's TipTap editor keeps its canvas clear: type / for insertions, @ for a player, select text for inline formatting, and focus a table cell for row and column actions. Uploads become inline image previews or file chips; YouTube and HoopsGeek links become responsive embeds, while the stored value remains portable Markdown.

No headerScrollable commandsPlayer mentionsSelection menuInline table actionsYouTube + HoopsGeek embedsPaste and drop upload

Mention treatment: @Šimon Svoboda

Tokens

Colors

14 semantic, role-named colors. Swatches use the live CSS variable, so they track the active theme; the hex shown is the light-mode value.

primary
#66722f
--primary
primary-active
#5b6730
--primary-active
on-primary
#fbfaf4
--on-primary
accent
#c2962f
--accent
on-accent
#211f15
--on-accent
danger
#b1583a
--danger
on-danger
#fbfaf4
--on-danger
canvas
#f2efe6
--canvas
surface
#fbfaf4
--surface
surface-2
#eae5d8
--surface-2
ink
#1b1a15
--ink
body
#423f36
--body
muted
#6f6b5d
--muted
muted-strong
#625f54
--muted-strong

Typography

display-xl
64px · 800
JetBrains Mono
The quick brown fox
display-lg
48px · 800
JetBrains Mono
The quick brown fox
heading
30px · 800
JetBrains Mono
The quick brown fox
title
18px · 500
JetBrains Mono
The quick brown fox
overline
12px · 500
Noto Sans
The quick brown fox
label
11px · 700
Noto Sans
The quick brown fox
body-lg
18px · 400
Noto Sans
The quick brown fox
body-md
16px · 400
Noto Sans
The quick brown fox
caption
14px · 400
Noto Sans
The quick brown fox
button
14px · 700
Noto Sans
The quick brown fox
code
13px · 400
JetBrains Mono
The quick brown fox

Radius

xs
4px
sm
6px
md
8px
lg
9px
xl
12px
pill
9999px
full
9999px

Spacing

xxs 4px
xs 8px
sm 12px
md 16px
lg 24px
xl 32px
xxl 48px
section 72px

Elevation

The ledge recipes that give controls their depth. Seen live on the 3D keys and elevated cards below.

ledge-rest0 4px 0 <ledge>
ledge-hover0 2px 0 <ledge>
ledge-pressed0 0 0 <ledge>
card-ledge0 4px 0 #dcd6c7
shadow-amb-lightrgba(40,36,22,0.18)
shadow-amb-darkrgba(0,0,0,0.4)

Motion

press-transitiontransform .08s ease, box-shadow .08s ease
hover-droptranslateY(2px)
press-leveltranslateY(4px)
theme-transitionbackground .25s ease, color .25s ease
cursor-blinkblink 1.1s steps(1) infinite
progress-fillwidth .3s ease
overlay-fadeopacity .16s ease
sheet-slidetransform .2s ease-out

Component tokens

38 component recipes mapping the primitives above onto concrete parts.

button-primarybackgroundColor: {colors.primary} · textColor: {colors.on-primary} · typography: {typography.button} · rounded: {rounded.lg} · padding: 0 16px · height: 36px
button-primary-pressedbackgroundColor: {colors.primary-active} · textColor: {colors.on-primary}
button-accentbackgroundColor: {colors.accent} · textColor: {colors.on-accent} · typography: {typography.button} · rounded: {rounded.lg} · padding: 0 16px · height: 36px
button-dangerbackgroundColor: {colors.danger} · textColor: {colors.on-danger} · typography: {typography.button} · rounded: {rounded.lg} · padding: 0 16px · height: 36px
button-secondarybackgroundColor: {colors.surface} · textColor: {colors.ink} · typography: {typography.button} · rounded: {rounded.lg} · padding: 0 16px · height: 36px
button-ghostbackgroundColor: transparent · textColor: {colors.primary} · typography: {typography.button} · rounded: {rounded.lg} · padding: 0 16px · height: 36px
button-disabledbackgroundColor: {colors.surface-2} · textColor: {colors.muted-strong} · typography: {typography.button} · rounded: {rounded.lg} · padding: 0 16px
switchbackgroundColor: {colors.surface-2} · textColor: {colors.ink} · rounded: {rounded.pill} · width: 56px · height: 36px
tabsbackgroundColor: {colors.surface-2} · textColor: {colors.body} · typography: {typography.label} · rounded: {rounded.lg} · height: 36px
dropdownbackgroundColor: {colors.surface} · textColor: {colors.body} · typography: {typography.caption} · rounded: {rounded.lg} · padding: 5px
selectbackgroundColor: {colors.canvas} · textColor: {colors.ink} · typography: {typography.caption} · rounded: {rounded.md} · height: 36px
checkboxbackgroundColor: {colors.canvas} · textColor: {colors.ink} · rounded: {rounded.sm} · width: 20px · height: 20px
radiobackgroundColor: {colors.canvas} · textColor: {colors.ink} · rounded: {rounded.full} · width: 20px · height: 20px
mention-tagbackgroundColor: {colors.accent} · textColor: {colors.ink} · typography: {typography.caption} · rounded: {rounded.pill} · padding: 1px 6px
progress-barbackgroundColor: {colors.surface-2} · textColor: {colors.ink} · typography: {typography.label} · rounded: {rounded.pill} · height: 24px
segmented-progressbackgroundColor: {colors.surface-2} · textColor: {colors.ink} · typography: {typography.label} · rounded: {rounded.pill} · height: 20px
stepper-fieldbackgroundColor: {colors.canvas} · textColor: {colors.ink} · typography: {typography.caption} · rounded: {rounded.lg} · height: 36px
sheetbackgroundColor: {colors.surface} · textColor: {colors.body} · rounded: {rounded.xl} · padding: 20px
dialogbackgroundColor: {colors.surface} · textColor: {colors.body} · rounded: {rounded.xl} · padding: 24px
text-inputbackgroundColor: {colors.canvas} · textColor: {colors.ink} · typography: {typography.caption} · rounded: {rounded.md} · padding: 0 12px · height: 36px
textareabackgroundColor: {colors.canvas} · textColor: {colors.ink} · typography: {typography.caption} · rounded: {rounded.md} · padding: 11px 14px · height: 112px
cardbackgroundColor: {colors.surface} · textColor: {colors.body} · rounded: {rounded.xl} · padding: 26px
card-elevatedbackgroundColor: {colors.surface} · textColor: {colors.body} · rounded: {rounded.xl} · padding: 26px
ascii-panelbackgroundColor: {colors.surface} · textColor: {colors.primary} · typography: {typography.code} · rounded: {rounded.xl} · padding: 18px
terminal-cardbackgroundColor: {colors.surface} · textColor: {colors.body} · rounded: {rounded.xl}
terminal-titlebarbackgroundColor: {colors.surface-2} · textColor: {colors.body} · typography: {typography.code} · padding: 11px 16px
badge-pillbackgroundColor: {colors.surface-2} · textColor: {colors.body} · typography: {typography.label} · rounded: {rounded.pill} · padding: 5px 11px
badge-primarybackgroundColor: {colors.primary} · textColor: {colors.on-primary} · typography: {typography.label} · rounded: {rounded.pill} · padding: 5px 11px
badge-accentbackgroundColor: {colors.accent} · textColor: {colors.on-accent} · typography: {typography.label} · rounded: {rounded.pill} · padding: 5px 11px
badge-dangerbackgroundColor: {colors.danger} · textColor: {colors.on-danger} · typography: {typography.label} · rounded: {rounded.pill} · padding: 5px 11px
status-dotbackgroundColor: {colors.primary} · rounded: {rounded.full} · size: 8px
top-navbackgroundColor: {colors.canvas} · textColor: {colors.ink} · typography: {typography.label} · height: 56px
product-shellbackgroundColor: {colors.canvas} · textColor: {colors.body} · typography: {typography.body-md}
product-nav-linkbackgroundColor: {colors.surface} · textColor: {colors.ink} · typography: {typography.button} · rounded: {rounded.lg} · height: 36px
breadcrumbsbackgroundColor: {colors.canvas} · textColor: {colors.muted} · typography: {typography.caption} · padding: 0
footerbackgroundColor: {colors.surface} · textColor: {colors.muted} · typography: {typography.caption} · padding: 40px 32px
tablebackgroundColor: {colors.surface} · textColor: {colors.body} · typography: {typography.body-md} · rounded: {rounded.xl} · padding: 12px 16px
table-headerbackgroundColor: {colors.surface-2} · textColor: {colors.muted} · typography: {typography.label} · padding: 12px 16px

Components

39 components from @workspace/ui/olive. This list is driven by the barrel exports; a component can't ship without appearing here.

Primitives

<Badge />Primitives

Pill-shaped uppercase tag in the UI sans; variants map to semantic tokens.

DefaultPrimaryAccentDanger
<Badge>Default</Badge>
<Badge variant="primary">Primary</Badge>
<Button />Primitives

One 36px footprint across every semantic and icon variant. Ledged buttons use a 32px face plus 4px of reserved travel, so hover and press move the whole key without changing layout height.

// Variants
<Button variant="primary">Primary</Button>

// With icon (base gap spaces icon ↔ label)
<Button><Plus /> Add item</Button>

// Icon only (square — pass an aria-label)
<Button size="icon" aria-label="Search"><Search /></Button>

// ThemeToggle composes this Button primitive
<ThemeToggle />
<Card />Primitives

Rounded, hairline-bordered surface panel; `elevated` adds the 6px ledge.

Flat

A resting surface panel.

Elevated

Raised on the hairline ledge.

<Card>…</Card>
<Card elevated>…</Card>
<CardTitle />Primitives

Sans uppercase overline for card headers.

Section label

Pairs with any Card body.

<CardTitle>Section label</CardTitle>
<Checkbox />Primitives

Native checkbox behavior in a compact Olive control with checked, focus, description, and disabled states.

<Checkbox
  label="Include archived items"
  checked={checked}
  onChange={(event) => setChecked(event.target.checked)}
/>
<Dropdown />Primitives

Shared command and context menu shell with normal-weight labels, optional icons and hints, bounded scrolling, active state, footer, separators, and danger actions.


3 commands
<Dropdown floating role="listbox">
  <Dropdown.List ref={listRef}>
    <Dropdown.Item icon={<Search />} active trailing="⌘K">Search</Dropdown.Item>
    <Dropdown.Separator />
    <Dropdown.Item tone="danger">Delete</Dropdown.Item>
  </Dropdown.List>
  <Dropdown.Footer>3 commands</Dropdown.Footer>
</Dropdown>
<Input />Primitives

Sans text input with the system's single focus ring; optional label.

<Input label="Email" placeholder="you@example.com" />
<ProgressBar />Primitives

Determinate semantic progress bar with primary, accent, or danger fill and an optional centered label.

63% (5/8)
<ProgressBar value={5} max={8} tone="accent" label="63% (5/8)" />
<Radio />Primitives

Native radio behavior with the same geometry, focus treatment, and ledged selected state as Checkbox.

<Radio name="cadence" label="Weekly" value="weekly" />
<SegmentedProgress />Primitives

Two-to-four independently valued progress segments that double as navigation for a short ordered workflow.

<SegmentedProgress
  activeId="work"
  items={[
    { id: "prepare", label: "Prepare", value: 4, max: 4, tone: "accent" },
    { id: "work", label: "Work", value: 3, max: 8, tone: "primary" },
  ]}
  onSelect={setStage}
/>
<Select />Primitives

A 36px single-value Select whose popup uses the shared Dropdown surface and item behavior.

<Select
  value={status}
  onValueChange={setStatus}
  options={[{ value: "active", label: "Active" }]}
/>
<StatusDot />Primitives

A colored status dot (online/idle/offline) with an optional label.

onlineidleoffline
<StatusDot status="online" label="online" />
<StepperField />Primitives

Directly editable 36px numeric input with adjacent decrement and increment controls; supports decimal or numeric keyboards.

<StepperField
  label="Weight (kg)"
  value={weight}
  onChange={setWeight}
  onDecrease={() => nudge(-0.5)}
  onIncrease={() => nudge(0.5)}
/>
<Switch />Primitives

Wide, Apple-like 36px switch with an Olive active track, sliding thumb, disabled state, and shared focus ring.

Disabled
<Switch
  checked={enabled}
  onCheckedChange={setEnabled}
  aria-label="Enable feature"
/>
<Tabs />Primitives

Controlled 36px segmented row with a subtly ledged active tab that slides between selections; supports text-only, icon-only, and icon-plus-text items.

<Tabs
  aria-label="Sets"
  activeId={activeId}
  items={[{ id: "home", label: "Home", icon: <Home /> }, { id: "search", icon: <Search />, ariaLabel: "Search" }]}
  onChange={setActiveId}
/>
<Textarea />Primitives

Multiline Olive form control with the shared label and focus treatment.

<Textarea label="Description" placeholder="Add a few useful details…" />

Terminal & ASCII

<AsciiField />Terminal & ASCII

Full-bleed animated ASCII background that fills its parent; honors reduced-motion.

<div className="relative h-40 overflow-hidden">
  <AsciiField pattern="rain" />
</div>
<AsciiPanel />Terminal & ASCII

Bordered, elevated ASCII-art panel (wave / grid / noise).

<AsciiPanel pattern="wave" />
<TerminalCard />Terminal & ASCII

Faux terminal window — traffic-light titlebar over a mono body.

~/peterhq — zsh

$ whoami

peter

<TerminalCard title="~/peterhq — zsh">
  <p>$ whoami</p>
</TerminalCard>
<Wordmark />Terminal & ASCII

The peter/hq wordmark with the slash in olive primary.

peter/hq
<Wordmark />

Motion

<Reveal />Motion

Fade + slide a block into view on first paint; `delay` staggers a group.

Reveals on mount.
Staggered by delay.
<Reveal delay={0.15}>
  <Card>…</Card>
</Reveal>
<Typewriter />Motion

Types out text, then an olive accent, followed by a blinking caret.

<Typewriter text="Hello there" accent="…" />

Layout

<Breadcrumbs />Layout

Compact nested-page hierarchy with scroll-safe mobile behavior and current-page semantics.

<Breadcrumbs items={[
  { label: "Apps", href: "/dashboard" },
  { label: "Basketball", href: "/basketball" },
  { label: "Players", href: "/basketball/players" },
  { label: "Peter Dzuruš" },
]} />
<Dialog />Layout

Adaptive modal: a bottom sheet on mobile and centered dialog on larger screens, with the same accessible overlay behavior.

<AnimatePresence>
  {open ? <Dialog title="Confirm change" onClose={() => setOpen(false)}>…</Dialog> : null}
</AnimatePresence>
<OnThisPage />Layout

Auto-generated, scroll-spy table of contents; reads [data-toc] elements from the live DOM — shown live in this page's sidebar.

Live in the sidebar

The numbered index on the left of this page is a live OnThisPage. It discovers every [data-toc] heading at runtime — no second copy to maintain.

<OnThisPage label="On this page" />
// mark headings with: <h2 id="…" data-toc data-level="2">
<ProductShell />Layout

Authenticated product chrome with an inset app-name sidebar, a top-attached backed breadcrumb header with optional global actions, a collapsible desktop rail, and mobile profile dock.

Product content
<ProductShell
  appName="Workout"
  appIcon="🏋️"
  navigation={<ProductNavLink active>Training week</ProductNavLink>}
  appSwitcher={<ProductNavLink>All apps</ProductNavLink>}
  headerActions={<FeedbackButton />}
>
  {children}
</ProductShell>
<Sheet />Layout

Animated bottom sheet with a standard scrim, flat X close control, focus trap/restoration, Escape and backdrop dismissal, safe-area padding, and body-scroll lock.

<AnimatePresence>
  {open ? <Sheet title="Details" onClose={() => setOpen(false)}>…</Sheet> : null}
</AnimatePresence>
<TopNav />Layout

Sticky, blurred header — brand + overline on the left, controls + theme toggle on the right.

peter/hq
<TopNav overline="v0.1 · alpha" />

Content

<Callout />Content

Highlighted aside with a colored left rule; tone picks a semantic token.

Note

Primary-toned aside.

Careful

Danger-toned aside.

<Callout tone="primary" title="Note">…</Callout>
<StatTiles />Content

Responsive KPI tile row; headline value colored by accent.

13
Color tokens
semantic roles
11
Type styles
mono + sans
33
Components
in @workspace/ui
<StatTiles columns={3} stats={[{ value: "13", label: "Color tokens" }]} />
<Table />Content

The standardized bordered data table used across the site — Notion-style header, hairline rows, an emphasized first column, two-axis constrained scrolling, optional sticky headings, and accessible whole-row activation. Data-driven via head/rows (with optional align, zebra, mono).

TokenValueUse
primary#66722fBrand / primary actions
accent#c2962fSecondary emphasis
danger#b1583aDestructive actions
<Table
  head={["Token", "Value", "Use"]}
  rows={[
    ["primary", "#66722f", "Brand / primary actions"],
    ["accent", "#c2962f", "Secondary emphasis"],
  ]}
/>

Charts

<BarChart />Charts

Dependency-free, theme-aware SVG bar chart; recolorable per datum.

Weekly bars01835537032Mon48Tue26Wed61Thu44Fri
<BarChart data={[{ label: "Mon", value: 32 }]} />
<BubbleChart />Charts

SVG scatter / bubble chart with linear or log x-scale.

0123452k4k8k16kreachimpactAlphaBetaGamma
<BubbleChart data={[{ label: "Alpha", x: 2000, y: 3, size: 20 }]} />
<DonutChart />Charts

SVG donut with a legend; values sum to a ring.

  • Primary52%
  • Accent30%
  • Danger18%
<DonutChart data={[{ label: "Primary", value: 52 }]} unit="%" />
<HBarChart />Charts

Horizontal bar chart (div-based, crisp labels).

Research
72%
Design
54%
Build
38%
<HBarChart data={[{ label: "Research", value: 72 }]} unit="%" />
<LineChart />Charts

Multi-series SVG line chart; palette cycles per series.

Two series03060JanFebMarAprMay
<LineChart labels={["Jan","Feb"]} series={[{ name: "A", points: [20, 42] }]} />