// design system / v0.3 reference

dieter/ds.
a kit, not a library.

A small, honest design system. Rams' restraint, applied as code. Every token earns its place. Every component has a code. The interface, treated like an instrument.

// systemdieter/ds
// version0.3
// editionv0.3 / rams
// tokens58 / css vars
// primitives46
// statusproduction-ready
// 00 / principles

design discipline.

// six rules. derived from rams' ten. they govern every decision below.

// 01 / metaphorThe kit, not the app.

Components are instruments, not widgets. Each carries a product code, like po-12 or tx-6. This gives them object-permanence and quiet confidence. "Use b-001" beats "use the dark button".

// 02 / palettePaper dominant. One accent.

Warm off-white surfaces. Near-black ink. One chromatic accent per surface — never two strong colors competing. Rams' "as little design as possible" — one knob, one purpose.

// 03 / lowercaseLowercase everywhere.

Capital letters announce themselves. Lowercase trusts you to find it. Even product names: dieter/ds. Quietness as a brand signal.

// 04 / honestyNo decoration beyond function.

No gradients. No drop shadows (one exception: the device frame). No icons without meaning. No animation without purpose. Rams' principle six, enforced as code.

// 05 / hardwareSoftware, dressed as instrument.

Knobs. LEDs. LCD readouts. Status codes. The interface borrows hardware vocabulary not as costume but as cognitive scaffold — it tells the user this is a real thing, not yet another screen.

// 06 / longevityBuilt to last, not to dazzle.

Square corners, hairline borders, monospace metadata. Nothing about this system will look dated in five years because nothing about it is fashionable now. Rams' principle seven: long-lasting design.

// 01 / foundations

color system.

// thirteen colors. seven neutrals form the surface and type; six chromatics are device-class accents — orange leads, the rest signal category or state.

paper / ink neutrals

// p-001
paper#f5f4f0--paper
paper-2#ecebe5--paper-2
paper-3#e0ddd2--paper-3
line#d6d2c4--line
dim#a09e96--dim
mid#6b6962--mid
ink#1a1a1a--ink

night palette

// p-003 / theme-night
night#16140f--night · bg
night-2#201d17--night-2
night-3#2b2720--night-3
line-n#322e25--line-n
milk-dim#5e5b54--milk-dim
milk-mid#8a8880--milk-mid
milk#f0eee6--milk · fg

day / night side-by-side

// th-002 / inversion holds
// day · :root
modules
04
shared
02
sync
ok
// night · :root.theme-night
modules
04
shared
02
sync
ok

chromatic accents

// p-002 / one per device class
orange#ff6b1a--orange · primary
yellow#ffcc1f--yellow · warn
red#e62833--red · danger
blue#2864e8--blue · link
green#6abe4f--green · ok
pink#ff7eb6--pink · accessory
// 02 / foundations

type system.

// two voices. inter for human language — tight tracking, heavy display weights. jetbrains mono for everything the machine says — codes, meta, kbd, system labels.

display inter

// fm-001
--t-hero48–96 / 800dieter/ds.
--t-4242 / 800a kit, not a library.
--t-2828 / 700your kit. today.
--t-2222 / 700module catalog
--t-1818 / 700section heading
--t-1515 / 400A personal operating system designed like a piece of measuring equipment.
--t-1313 / 400 · baseThe household as a kit of small instruments — each module a tool you actually pick up.

mono jetbrains mono

// fm-002 / system voice
--t-1212 / 500m-001 · shared list · live sync
--t-1111 / 500// eyebrow / accent
--t-1010 / 500// s-001 / boot · 00:01
--t-99 / 500m-001 · m-002 · m-003
--t-88 / 500modules · shared · pending · sync
// 03 / foundations

space & matter.

// 2px base unit. hairline borders. mostly square corners. motion exists only to clarify cause and effect.

spacing scale

// s-001
--s-44px
--s-88px
--s-1212px
--s-1616px
--s-2424px
--s-3232px
--s-4848px
--s-6464px
--s-8080px
// l-001 / line
hairline border
1px var(--line) — the system's primary dividing line
// r-001 / radius
square by default
radius reserved for circles (knobs, dots, avatars) and the device shell
// el-001 / elevation
no shadows
depth is communicated by border + surface tone, never by shadow — one exception: the device frame
card · paper · 1px line
// mo-001 / motion
snap → quick → base
90ms / 150ms / 220ms · cubic-bezier(0.2, 0, 0, 1) · functional only
// 04 / components

the instruments.

// fourteen primitives. each carries a product code. each does one thing. they compose into the patterns below.

button primary / ghost

// b-001 · b-002

input command-style

// i-001
describe a custom module... ⌘ k

tabs underline

// tb-001
all family health travel home

badge / dot / avatar signals

// bd-001 · d-001 · av-001
sync 2 new pending offline m-001 c y

knob control affordance

// k-001 / faux-hardware

lcd display system readout

// l-001
syncready
storeready
brainempty
modules0 / 25
last error

stat strip data readout

// st-001
modules
04
shared
02
pending
03
sync
ok

card base / selected / featured

// c-001 · c-002 · c-003
birthdaysm-004
dates · gift ideas
shared listm-001
live sync · multi-user

meta panel key/value

// mp-001
// productcrate/os
// version0.1 beta
// platformios · android · web
// statusclosed beta
// 05 / primitives

forms & inputs.

// native controls, styled. labels above the input, helper / error below. semantic html — the browser stays in charge of accessibility.

field text input

// i-002
// used only for system notifications
// not a valid address

textarea / select multi-line, single-choice

// ta-001 · sl-001
// biological growth phase

checkbox / radio / toggle choice

// cb-001 · r-001 · tg-001

range / search slider · query

// rg-001 · sr-001
// current 1180 u.a. · cap 1100 en phv
// 06 / primitives

feedback & status.

// banners, tooltips, progress, spinners, skeletons, empty states, modals. one accent per state — never two strong colors competing.

banner info / warn / danger / ok

// bn-001

tooltip contextual hint

// tt-001
// b-001 / primary action sync · ready pending 3 items awaiting review

progress / spinner in-flight indicators

// pr-001 · spn-001
// determinate · 72%
// indeterminate
// sm · md · lg

skeleton loading placeholder

// sk-001

empty state no data + guidance

// em-001
no modules yet
// pick a module from the catalog or describe what you need. the system will compose it from primitives.
// 07 / primitives

data display.

// kpi tiles, chips, tables, list rows. tabular-nums everywhere. numbers stay readable in a column even when characters change.

kpi tile metric

// kp-001
modules
04
+ 1 this week
maturation
81% pah
+ 2.4 vs q4
charge 7j
1180u.a.
+ 80 vs cap
build size
42kb
− 2.1 kb

chip interactive pill

// ch-001
all family health travel home work × add filter

table data grid

// tbl-001
// code // module // status // items // updated
m-001shared listsync122h ago
m-002sport matches2 new3515min
m-003medical logpending071d ago
m-004birthdaysdraft145d ago

list row settings-style

// lr-001
notifications
// push · email · in-app
appearance
// theme + reduced motion
night →
api keys
// 3 active · last used 2h ago
manage →
// 08 / primitives

navigation controls.

// breadcrumb, pagination, stepper, segmented, dropdown menu, sidebar. predictable back, deep linking, keyboard accessible.

breadcrumb trail

// bc-001

pagination page navigator

// pg-001

stepper multi-step indicator

// stp-001
01 identity 02 vitals 03 charts 04 review

segmented control

// sg-001

menu dropdown

// mu-001
// 09 / primitives

content blocks.

// code, quotes, kbd, dividers. the prose-level primitives. paragraph rhythm, mono accents, no decorative typography.

code block · inline

// cd-001

link the stylesheet with <link rel="stylesheet"> and apply .theme-night on the root.

/* override an accent */
:root.theme-pitch {
  --accent: var(--green);
  --on-accent: var(--ink);
}

quote blockquote

// qu-001
Good design is as little design as possible. Less, but better — because it concentrates on the essential aspects, and the products are not burdened with non-essentials. // dieter rams · principle ten

kbd keyboard shortcut

// kr-001
+k open palette ++n new module esc close navigate confirm

divider horizontal · labeled

// dv-001

section above

heavy separator (2px)
// section divider with label
section below
// 10 / primitives

chat & dialog.

// extracted from the spark/rag demo. message turns, citations, source cards, conversation rows, the composer. compose them into chat shells or any q&a interface.

message chat turn · role + content

// msg-001
c // claire · 10:42

How do I override the --accent color in dieter for a specific section?

s // spark · 10:42

Apply a class on :root and redefine --accent inside — every component that reads var(--accent) flips automatically 12.

s // streaming
retrieving 4 sources…

citation inline numbered reference

// cite-001
The override pattern is documented in the install reference1 and exemplified in pitch-v423. The accent token cascades to LED pulses, badges, active tabs4, and any component reading var(--accent) downstream.

source card retrieved document

// src-001 + scr-001
1 0.94
tokens · semantic mapping
/dieter_ds/tokens.css#L33
--accent: var(--orange); /* one chromatic per surface */ --on-accent: var(--invert-fg);
2 0.82
pitch · theme-pitch override
/pitch-v4.html#L24
:root.theme-pitch { --accent: var(--green); --on-accent: var(--ink); }

conversation row sidebar item

// conv-001
how to override --accent 2m
spacing scale reference 18m
night theme contrast pairs 1h

composer chat input + tools + send

// cp-002

mark inline highlight

// mk-001
Highlight key terms with accent-tinted background. Uses semantic <mark> element or .mark class. The fill is color-mix(--accent 25%, transparent) — translucent so it works in both day and night themes.
// 11 / patterns

composed arrangements.

// primitives, assembled. these are the canonical compositions — copy them, don't reinvent them.

faux-device card software-as-instrument

// pt-001
// dieter/ds · ko-001
syncready
storeready
brainempty
modules0 / 25

Why it works: the screen mock-up tells the user "this is a real thing" before they read a single word of copy. LED + LCD + knobs are inherited cognitive scaffolds from physical instruments.

Composed from: card--raised + lcd + knob-grid + dot--led. No new components introduced.

When to use: first-boot screens, system status overlays, anywhere the software needs to feel like an object you pick up.

kit overview stat + list

// pt-002
// claire / node 01
your kit today.
tue 13 may · week 19
c
modules
04
shared
02
pending
03
sync
ok
max's matchesm-002
3 upcoming next sat 18 2 new
japan · junem-004
t-47d 4 nodes sync

Anatomy: identity row (greet + name + date + avatar), stat strip in inverted ink for instant scan, section label with mono-cased count, list of card + item rows.

Color discipline: the inverted ink strip is the only large dark surface. The orange stat-value is the only chromatic accent in the viewport at once — principle 02 in action.

Substitution: module categories rotate accent color (yellow / blue / red / pink). Never two saturated icons next to each other.

// 12 / demos

working references.

// the system in production. each demo composes the primitives documented above into a real interface. open, read the source, copy what you need.

spark · rag — retrieval augmented chat
// dm-001 · 3-col shell · message turns · citations · source cards · composer
// 13 / usage

how to install.

// two stylesheets. no build step. drop them in and write semantic html with the component classes documented above.

// u-001 / link
link the stylesheets
tokens.css imports first — system.css consumes the variables
<link rel="stylesheet"   href="tokens.css"> <link rel="stylesheet"   href="system.css">
// u-002 / fonts
load the typefaces
inter (400–900), jetbrains mono (400–700), noto sans jp (optional)
fonts.googleapis.com/css2 ?family=Inter:wght@400..900 &family=JetBrains+Mono:wght@400..700 &family=Noto+Sans+JP:wght@400..500
// u-003 / compose
stack primitives, don't fork
every pattern composes from the 14 primitives — if you need a new one, write a new primitive with a code
.card   .item     .item-icon.col-orange     .item-content       .item-row     .badge.badge--ok
// u-004 / extend
override via tokens
theming = swap variables on :root. never edit component css to "tweak" — change the token instead
:root.theme-night {   --paper: #16140f;   --ink: #f5f4f0;   --accent: var(--yellow); }