Kauz mark

Kauz Design System

A showcase of the rules, the tokens, and the components.

This page is the design system, used to document the design system. Every section is built from the same classless HTML and the same handful of CSS variables your projects link in. No extra styling, no marketing chrome. If a thing looks a certain way here, you get the same thing in your project by writing the same semantic HTML.

01 · Philosophy

Form follows function.

The system is intentionally small. It captures one strong opinion (minimal, classless, semantic, sharp-cornered) and applies it everywhere. Most of the design lives in the browser's defaults plus a tight set of CSS variables. There is no component library to learn, no token sprawl to memorize, just a stylesheet, a font stack, and a color. The principles are older than the code: Reyner Banham's 1955 brutalism manifesto asked buildings for memorability as image, clear exhibition of structure, and valuation of materials as found. The same three apply here.

Classless first. If you can write the page with <header>, <main>, <section>, <table>, <form>, <details>, do that. Reach for a class only when the HTML genuinely can't say it.
One accent. Ember rust (#C85A3A) is the only warm color on the page. Everything else is a stop on the neutral ramp. Adding a second accent is a brand violation.
Sharp corners, no shadows. Brutalism doesn't bevel and it doesn't float. Elevation is conveyed by background lightness and 2 px borders.
System type. No webfont by default. The page loads instantly and looks native on the user's OS. Opt into a designed family only when you mean it.
02 · Color · neutral ramp

Seven stops of soot, one drop of ember.

The whole palette is a 7-stop neutral ramp from soot (#0A0A0A) to bone (#ECECEC), plus a single accent (ember) and four rarely-used signal colors. Do not introduce a second hue. If you find yourself reaching for one, it's almost always solvable with a stop on the ramp.

TokenHexRole
--soot-0#0A0A0APage background. The default canvas.
--soot-1#1A1A1AElevated surface: code blocks, drop-zones, inputs.
--soot-2#2A2A2AHover surface on dark; dividers.
--soot-3#4A4A4AHeavier dividers; disabled-on-dark.
--soot-4#7A7A7AMuted text, captions, <figcaption>.
--soot-5#C8C8C8Light dividers; secondary on dark.
--soot-6#ECECECPrimary text; primary structural border.
--ember#C85A3AThe single accent. Links, focus rings, <mark>, the heart.
--ember-2#E07050Hover-on-ember. Used sparingly.

Each stop has a defined job and a material analogue. Soot is the concrete in shadow, bone is the same concrete in light, and ember is the rust-iron weep that runs down the side of a 1970s slab. --soot-1 is for elevated surfaces, --soot-4 for muted text, full stop. The ramp is small enough to memorize and strict enough that you never need to invent a custom gray.

03 · Color · signals (rare)

Four signals that share ember's family resemblance.

Signal colors are tuned to share luminance and saturation with ember, so when they appear they read like cousins, not like the Bootstrap default palette. They are reached for only when the UI genuinely needs to signal state. Never as decoration, never as a second accent, never two at once.

--criticaldestructive confirmation · validation
--warningpre-destructive · expiring
--successpost-action · saved
--infoneutral notice · hint

Usage in context

Demolition permit filed. Charité submitted the application for the Mäusebunker. The objection window closes in 14 days.
Survey overdue. The Pallasseum facade has not been inspected since 2024-08-03.
Listed. Hygieneinstitut and Mäusebunker registered as cultural monuments, 2023-05-26.
Tip. Tag #SOSBrutalism on social media and the DAM curators will check the building for inclusion.

Same family of hue and value as ember keeps the page visually coherent even when it has to flash a warning. Ember is still the dominant accent by far. If a screen contains a signal color and ember next to each other, ember wins the focal point.

04 · Color · light mode

Light mode exists, but dark is the brand.

A complete light mirror is shipped as an opt-in via <html data-theme="light">. Most pages should still ship dark; that is the brand identity. Use the toggle in the floating panel (bottom-right) to see the whole page repaint in real time. It is the same tokens, just remapped.

Dark · default

--color-bg#0A0A0A
--color-fg#ECECEC
--color-bg-elev#1A1A1A
--color-border#ECECEC

Light · opt-in

--color-bg#ECECEC
--color-fg#0A0A0A
--color-bg-elev#FFFFFF
--color-border#0A0A0A
05 · Typography · stack & scale

System fonts, set with intent.

The default stack is the user's native UI font: Apple's San Francisco on Mac and iOS, Segoe UI on Windows, Roboto on Android. It loads instantly, costs zero bytes, and is hard to make ugly. Monospace follows the same idea: SF Mono first, then the best-available installed mono.

--font-sans

-apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif

--font-mono

"SF Mono", "Monaco", "Cascadia Code", "Roboto Mono", "Courier New", monospace

Type scale

Headings shrink fluidly with viewport width. Body sits at 14–15 px and uses a relaxed line height. Nothing scales below 12 px.

--fs-h1 A heading walks into a bar clamp 28→44 px
--fs-h2 A heading walks into a bar clamp 22→30 px
--fs-h3 A heading walks into a bar 20 px
--fs-h4 A heading walks into a bar 17 px
--fs-base A heading walks into a bar clamp 14→15 px
--fs-sm A heading walks into a bar 13 px
--fs-xs A heading walks into a bar 12 px

Body and runs of text

The body is set with line-height: 1.7 and text-wrap: pretty, which trims off orphaned single-word last lines. Headings get text-wrap: balance so multi-line titles fall in pleasing chunks. Tracking is slightly tight on display sizes and slightly loose on UPPERCASE labels; the eye reads each at its best.

He proposed three criteria for a building to qualify: memorability as image, clear exhibition of structure, and valuation of materials as found. No ornament. No plaster. What the building does, you can see. What it's made of, you can touch.
On Reyner Banham, The New Brutalism, Architectural Review, December 1955

Webfonts are a tax: bytes, layout shift, FOIT. The system stack pays none of it and reads native on every OS. Reach for a designed family only when the project specifically needs one. See the next section.

06 · Typography · optional presets

Two opt-in font families.

If a project benefits from a designed family (usually marketing pages, not utility tools), link one of the presets in fonts/ after kauz.css. The preset overrides the family and enables the font's stylistic sets, ligatures, and tabular numerals. Everything else in the design system is unchanged.

fonts/plex.css

IBM Plex Sans & Plex Mono

Humanist, slightly engineered. The most "Kauz".

<link rel="stylesheet" href="fonts/plex.css">

fonts/dm.css

DM Sans & DM Mono

Geometric, screen-optimized. Crisp at small sizes.

<link rel="stylesheet" href="fonts/dm.css">

Try a preset live with the font switcher in the floating panel. The page will reflow as the family swaps; everything else stays put.

07 · Spacing

One unit. Multiples only.

Everything that takes up space uses a multiple of --space-unit, which is 0.5rem (8 px). The set of allowed sizes is small on purpose: 8, 16, 24, 32, 48, 64. No half-units. No 12, no 20. If the design wants 14 px between two elements, the answer is 16.

--space-18 px
--space-216 px
--space-324 px
--space-432 px
--space-648 px
--space-864 px

A single unit is what makes the system feel coherent. You can change --space-unit in :root and every margin in the system scales with it. Try setting it to 0.375rem in the config panel and watch the entire page tighten up.

08 · Borders & corners

Three weights, no radius, ever.

border-radius: 0 everywhere. Buttons, inputs, cards, code blocks, images, even checkboxes. This is the loudest brand signal the system has and the easiest to violate by accident. If you see a rounded corner in a Kauz product, something has gone wrong.

--border-thin

1 px, soft. Inline things: code, kbd, swatch outlines.

--border-normal

2 px, soft. The default. Sections, fieldsets, forms, cards.

--border-heavy

4 px, bone. The structural accent. Left rule on blockquote, pre, .why blocks.

The heavy rule is reserved. When you see it on the left of a block, the page is saying "this is structural; pay attention". Don't apply it casually or it loses its weight.

09 · Elevation

No shadows. Lightness is elevation.

The system has no box-shadow. None. Surfaces that need to feel raised step up the neutral ramp instead: page is --soot-0, elevated surface is --soot-1, hover is --soot-2. If a card feels flat, the answer is more contrast or a 2 px border, never a drop shadow.

--soot-0

Page background. The canvas.

--soot-1

One step up: code blocks, drop-zones, the elevated card.

--soot-2

Two steps up: hover-on-dark.

Card uses --soot-1 + --border-normal. Clearly different from the page, no haze around it.

Same card with a soft drop shadow. The page is haunted now. Delete it.

Looks bad on purpose.
10 · Layout

One centered column. Two opt-outs.

The default body is a centered single column at max-width: 960px, with 20 px of padding. Sections separate themselves with a 2 px top border and 40 px of margin. There are no fixed headers, no sticky bars, no sidebars. The page reads top to bottom; that is on purpose.

Default

<body>
  <header> ... </header>
  <main> ... </main>
  <footer> ... </footer>
</body>

Centered, 960 px max. The reading layout.

Full-bleed opt-in

<body data-full-bleed>
  ...
</body>

Width fills the viewport. For dashboards and tool surfaces.

11 · Components · buttons

Tracked, uppercased, hard-edged.

Buttons are short, dense, and uppercase. They invert on hover (background fills with foreground, text becomes background) with no transition. Brutalism does not bounce.

Hover state

DEFAULT

HOVER

Inverting on hover is louder than a fill-tint and reads from across the room. No transition keeps it brutal; the button is either at rest or active, never in between.

12 · Components · inputs

Honest inputs. Hard borders. Native behavior.

Text fields sit at --color-bg-elev, with a 2 px soft border. No placeholder grays, no floating labels, no inset shadow. The cursor lands and the field is obviously the field.

13 · Components · checkboxes & radios

Both are squares.

The system renders checkboxes and radios as identical 16 px sharp squares with hand-built indicators: a rotated tick for checked, a filled inner square for radio. The semantic difference (multi-select vs exclusive) lives in HTML, not in the shape. Brutalism doesn't bow to the radio-is-round convention.

Buildings to feature
Export format

Indeterminate state is supported too: set el.indeterminate = true in JS and the box renders an ember bar instead of a tick.

14 · Components · range & output

Sharp ember thumb. Native progress.

The range slider is a 14×22 px ember rectangle on a 1 px bordered track. The filled portion uses a tiny variable, --_pct, which kauz.js updates on input. A paired <output> element (matched via for="…" or as a direct sibling) is kept in sync automatically.

64
12
40

Drag a slider. The output updates as you go.

15 · Components · forms

Group with fieldset. Caption with legend.

Forms group related inputs in a <fieldset> with a <legend>. There are no card wrappers and no floating helper text; the legend explains the group, the label explains the field, and that is the whole structure.

New entry
16 · Components · lists

Three lists for three relationships.

Unordered

  • Memorability as image.
  • Clear exhibition of structure.
  • Valuation of materials as found.

Ordered

  1. Visit the site.
  2. Photograph the elevations.
  3. File the survey.

Definition

Béton brut
French for "raw concrete". Le Corbusier's term for unfinished, board-formed cast surfaces.
Reyner Banham
British critic. Wrote The New Brutalism in Architectural Review, December 1955.
Soot
The color of the page background.

<ul> uses a square bullet: Unicode via list-style: square. That square is the only decoration the bullet ever gets. No custom icons, no gradient discs.

17 · Components · tables

Caption it. Header it. Read it top to bottom.

German brutalist architecture, a partial set
BuildingYearLocationStatus
Corbusierhaus1958BerlinListed (1996)
Ruhr-Universität1965BochumListed (2015)
St. Agnes1967BerlinGallery since 2015
Mariendom1968NevigesIn use
Bensberg Rathaus1969Bergisch GladbachListed
ICC Berlin1979BerlinListed (2019), closed
Mäusebunker1981BerlinListed (2023)

The caption is UPPERCASE and tracked, the same affordance as a button label. It says "this is a table about X" before your eye gets to the headers, and it doesn't waste a paragraph of body copy to do it.

18 · Components · quotes & code

Heavy left rule means "structural".

Both blockquote and pre get a 4 px bone rule on the left. That rule is the visual handle that says "this content is lifted out of the page flow". The same rule appears on .why blocks; it never appears on anything else.

It is our intention to have the structure exposed entirely, without interior finishes, wherever practicable.
Alison Smithson, 1953
// frame.js: drop an image, get a bordered frame
function applyFrame(img, { thickness = 64, blur = 12 } = {}) {
  const canvas = document.createElement('canvas');
  canvas.width  = img.width  + thickness * 2;
  canvas.height = img.height + thickness * 2;
  const ctx = canvas.getContext('2d');
  ctx.filter = `blur(${blur}px)`;
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  ctx.filter = 'none';
  ctx.drawImage(img, thickness, thickness);
  return canvas;
}

Inline things use the thin border instead: npm install soot.css, git push origin main, & the occasional 404 NOT FOUND in samp.

19 · Components · details

Spoilers without JS.

<details> is the system's only collapsible affordance. It is native, accessible, and survives JS being off. The marker is the browser default; the chrome around it is the system's.

How did the Mäusebunker get saved?

Charité applied for a demolition permit in 2020. Felix Torkar and Gunnar Klack started a petition, and Berlin's preservationists rallied. Three years and 10,683 signatures later, the State Monuments Office listed both the Mäusebunker and its sibling Hygieneinstitut as cultural monuments.

  • December 2020: demolition permit applied for.
  • 2020–2023: campaign, petition, press.
  • May 2023: Mäusebunker and Hygieneinstitut listed.
  • Result: 10,683 signatures, two saved buildings.
SOS Brutalism, by the numbers (open by default)

Started in 2015 by the Deutsches Architekturmuseum and the Wüstenrot Foundation. As of 2025 the database holds 2,300+ entries, with roughly 175 on the RED LIST as threatened. Tag #SOSBrutalism on social media and the curators will check the building for inclusion.

21 · Imagery

Grayscale, full-bleed, untouched.

The system uses very little photography. When it does, it is desaturated or near-desaturated, high-contrast, often architectural. The placeholder service of choice is picsum.photos/...?grayscale. Ember is the page's only warm note; never a warm photo.

Brutalist building from an inner yard
Brutalist buildings often have a fortress-like appearance, with heavy, blocky forms.
Brutalist spiral staircase
Function and material first; decoration second, if at all.
22 · Iconography

Mostly, don't.

The brand is anti-decoration, and most icons are decoration. The system prefers text labels, semantic HTML, and the occasional Unicode shape. There is exactly one sanctioned glyph () and it lives in the footer signature.

Use <button>DOWNLOAD</button>. The word is unambiguous and reads everywhere.

Use a download arrow glyph with no label. Now I have to guess.

Use <kbd>Esc</kbd> for shortcut hints; it renders as a small bordered cap.

Esc Clear

Use a rocket emoji to indicate "launch". This is a design system, not a startup pitch deck.

If a screen genuinely needs an iconic affordance (and you have argued yourself out of every alternative), use Lucide at stroke-width="1.5", sized at 1em, stroked with currentColor, inline at the start of a label. Document it as a deviation.

23 · Logo system

One letter, on the same soot square, forever.

There is no wordmark and no separate glyph mark. Every product gets a single character (Helvetica Bold, ember on soot) on a square. The favicon is the logo and the logo is the favicon. New project under brutalist.systems? It gets a new letter. That's it.

Kauz mark · K
kauz
brutalist.systems mark · B
brutalist
soot.css mark · S
soot
frame mark · F
frame
favicons mark · F
favicons
rebalance mark · R
rebalance
accounts mark · A
accounts
kauz inverse: ember on bone
kauz · inverse
kauz mono: bone on soot
kauz · mono
24 · Configuration

The full set of variables.

Everything below is overridable from :root in your own stylesheet. The system is built around the assumption that you will override a few of these per project: most likely --color-accent never, --space-unit rarely, and --max-content-width if you opt out of the centered layout. The floating panel (bottom-right) edits a handful of these live so you can feel the consequence.

Color

TokenDefaultUsed for
--color-bg#0A0A0APage background.
--color-bg-elev#1A1A1AElevated surface: inputs, code, drop-zone.
--color-bg-hover#2A2A2AHover state on dark.
--color-fg#ECECECPrimary text.
--color-fg-muted#7A7A7ASecondary text, captions.
--color-fg-dim#4A4A4ATertiary, very quiet.
--color-accent#C85A3ALinks, focus rings, <mark>, the heart.
--color-accent-2#E07050Hover-on-ember.
--color-border#ECECECHeavy / structural border (4 px rule).
--color-border-softrgba(236,236,236,0.10)Default border on dark.
--color-mark-bg · --color-mark-fgember / soot<mark> fill and text.
--critical#C8332ESignal · danger.
--warning#C8902ESignal · expiring.
--success#5C9C72Signal · saved.
--info#5C84A5Signal · neutral notice.

Type

TokenDefaultUsed for
--font-sans-apple-system, …Body, headings, UI.
--font-mono"SF Mono", …code, kbd, pre, output.
--fs-baseclamp(0.875rem, 1vw + 0.75rem, 0.9375rem)Body fluid size: 14→15 px.
--fs-sm · --fs-xs0.8125rem · 0.75remCaptions, eyebrows, mono tags.
--fs-h1clamp(1.75rem, 3.5vw + 0.5rem, 2.75rem)Page title.
--fs-h2clamp(1.375rem, 2vw + 0.5rem, 1.875rem)Section heading.
--fs-h3 · --fs-h41.25rem · 1.0625remSub-headings.
--lh-base · --lh-relaxed · --lh-tight1.6 · 1.7 · 1.2UI / body / headings.
--tracking-loose0.04emUPPERCASE labels, captions.
--tracking-tight-0.01emLarge display headings.

Spacing & borders

TokenDefaultUsed for
--space-unit0.5remThe atom. Change this and the page scales.
--space-1--space-88 · 16 · 24 · 32 · 48 · 64 pxAll gaps, margins, paddings.
--border-thin1px solid var(--color-border-soft)Inline elements.
--border-normal2px solid var(--color-border-soft)Default. Sections, forms.
--border-heavy4px solid var(--color-border)Structural left rule.
--border-radius0Always zero. Don't change.
--max-content-width960pxCentered-column cap.

Example override

:root {
  /* a project under brutalist.systems that wants tighter density */
  --space-unit: 0.375rem;
  --max-content-width: 1200px;
}

/* opt out of the centered layout for a dashboard */
<body data-full-bleed>

The system intentionally exposes few variables. If a project finds itself overriding more than three or four, that's usually a sign the project should be its own brand, not a fork of Kauz.

25 · Anti-patterns

If you do these, the brand breaks.

Sharp corners, everywhere.

A card

Rounded corners. Never. Not on buttons, not on cards, not on inputs.

A card with rounded corners

Flat background colors.

Solid soot

Gradient backgrounds. No diagonals, no gloss, no "cosmic" anything.

Synthwave is not a security aesthetic

One accent: ember. Links, focus, marks, the heart.

Read the engagement scope

A second accent. Indigo for "primary", ember for "destructive"? No. Pick one.

Read the engagement scope

Text labels on buttons.

Emoji as UI. Not in buttons. Not in nav. Not in headings.

Honest, first-person copy.

I built this so I'd stop reaching for the same five tabs every time someone asked about a Böhm.

Marketing voice. "Empower", "leverage", "revolutionary", exclamation marks.

Empower your team to unlock revolutionary outcomes!