Nº 097 of 520
Bauhaus design language kit
A full Bauhaus UI dialect on one sheet: red, yellow, blue and ink on paper, circle/square/triangle grammar, Josefin Sans lowercase headlines, hard-shadow controls.
Preview
Use it
Free to use · credit appreciated1 Once, in your project
npx skills add SusanAcharya/Design-Lounge 2 Then ask
Using the Design Lounge skill, build "Bauhaus design language kit" (piece bauhaus-style) in my stack. Match its brief; restyle it onto my product's theme.
No skill? Paste the brief instead. It carries the numbers, tokens and behaviour.
<!-- Design Lounge Nº 097 · "Bauhaus design language kit" · www.designlounge.live -->
# Bauhaus design language kit
> **Build brief for a coding agent.** Rebuild this piece in the reader's stack. If they haven't said which stack, ask once, then default to semantic HTML + CSS + a little vanilla JS. Match the numbers below; don't "improve" them.
## What it is
A kit sheet for "formhaus", a fictional Bauhaus-revival furniture brand, that doubles as a style guide you can apply to a whole product. The page is a 12-column grid of paper cells separated by 3px ink rules (the grid's `gap` shows the black body behind it). The first row is a live landing hero for "Regal 25" modular shelving, with a red circle, blue square, yellow triangle, ink bar and ink dot composed on the right, next to a type specimen with a 150px "Aa". The second row holds the palette with roles, buttons in four states, tags, inputs and a product card; the third row states the shape grammar (circle acts, square holds, triangle points, rule divides). The detail worth copying: **shape carries meaning**. Circles are only ever actions or status, squares are containers, triangles point; nothing is rounded unless it is a circle.
## Reference behaviour
1. Initial state: header bar (56px) with a three-shape mark, "formhaus / design language 01", four section anchors and "Kit v1.4 · Weimar · Oct 2026". Below it the sheet; the first 800px show the hero, specimen and the whole component row.
2. Hover any rectangular button: it lifts `translate(-3px, -3px)` and gains a hard `3px 3px 0` ink shadow over 120ms. Press: it drops back to 0/0 with no shadow. The "States" strip shows Rest / Hover / Pressed / Disabled statically using forced classes, so the states are readable without interacting.
3. Click the yellow round button in the hero's bottom-right corner ("Recompose"): the five shapes move to arrangement 2 over 520ms with expo-out easing (circle shrinks to .62 and drops left, square rotates 90° and grows to 1.3, triangle flips 180°, bar goes horizontal, dot grows). Click again: arrangement 3. Again: back to 1. The copy column never moves.
4. Focus a text input or the select: a 5px yellow offset block appears behind it, outlined by a 2px ink edge (a "printed" focus shadow). No radius, no glow.
5. The email field ships in its error state: red 2px border, pale red fill `#F6DDD6`, 12px red message under it, `aria-invalid="true"`.
6. Click the checkbox: a 10px red square scales from 0 → 1 in 120ms. Click a radio: a 10px blue disc does the same.
7. Click the switch: the track fills yellow and the knob slides 24px right **and morphs from an ink square to a red circle** (240ms expo-out). Off again: back to an ink square.
8. Hover the product card: it lifts 4px with a 4px hard ink shadow.
9. Header anchors jump to sections; their hover state is a 2px red underline.
## Structure
```
1280 × 800 first frame (sheet continues to ≈ 1000px; body scrolls)
┌──────────────────────────────────────────────────────────────────────────────┐
│ ●■▲ formhaus / design language 01 TYPE COLOUR CONTROLS GRAMMAR Kit v1.4│ 56 + 3px rule
├───────────────────────────────────────────────┬──────────────────────────────┤
│ formhaus möbel Kollektion Werkstatt Journal [Cart 2] │ ● 01 TYPE SPECIMEN│
│ REGAL 25 · MODULAR SHELVING ● ( red circle 290 ) │ Aa (150px) Josefin…│
│ build it ━━━━━━━━ │ ─────────────────────│
│ in squares. (76px) ■ (150) ▲ (180×156) │ Display 76 form follows│
│ body 15px │ H2 26 / H3 18 / Body 15 │
│ [Configure Regal 25 →] [1925 drawings] (↻) │ Label 11 │
│ From €640 · ships in 3 weeks cols 1–7 · 424h │ cols 8–12 · 424h │
├───────────┬───────────┬───────────┬──────────────────────────────────────────┤
│02 PALETTE │03 BUTTONS │04 INPUTS │05 CARD │
│ 5 swatches│ 3 buttons │ postcode │ [blue art 118h, yellow circle, NEW tag] │
│ 46px rows │ 4 states │ email err │ Stuhl B3 · €1,180 [Add] │
… 171 more lines. Copy or download for the full brief. Loading the source…Brief
211 linesBuild brief for a coding agent. Rebuild this piece in the reader’s stack. If they haven’t said which stack, ask once, then default to semantic HTML + CSS + a little vanilla JS. Match the numbers below; don’t “improve” them.
What it is
A kit sheet for “formhaus”, a fictional Bauhaus-revival furniture brand, that doubles as a style guide you can apply to a whole product. The page is a 12-column grid of paper cells separated by 3px ink rules (the grid’s gap shows the black body behind it). The first row is a live landing hero for “Regal 25” modular shelving, with a red circle, blue square, yellow triangle, ink bar and ink dot composed on the right, next to a type specimen with a 150px “Aa”. The second row holds the palette with roles, buttons in four states, tags, inputs and a product card; the third row states the shape grammar (circle acts, square holds, triangle points, rule divides). The detail worth copying: shape carries meaning. Circles are only ever actions or status, squares are containers, triangles point; nothing is rounded unless it is a circle.
Reference behaviour
- Initial state: header bar (56px) with a three-shape mark, “formhaus / design language 01”, four section anchors and “Kit v1.4 · Weimar · Oct 2026”. Below it the sheet; the first 800px show the hero, specimen and the whole component row.
- Hover any rectangular button: it lifts
translate(-3px, -3px)and gains a hard3px 3px 0ink shadow over 120ms. Press: it drops back to 0/0 with no shadow. The “States” strip shows Rest / Hover / Pressed / Disabled statically using forced classes, so the states are readable without interacting. - Click the yellow round button in the hero’s bottom-right corner (“Recompose”): the five shapes move to arrangement 2 over 520ms with expo-out easing (circle shrinks to .62 and drops left, square rotates 90° and grows to 1.3, triangle flips 180°, bar goes horizontal, dot grows). Click again: arrangement 3. Again: back to 1. The copy column never moves.
- Focus a text input or the select: a 5px yellow offset block appears behind it, outlined by a 2px ink edge (a “printed” focus shadow). No radius, no glow.
- The email field ships in its error state: red 2px border, pale red fill
#F6DDD6, 12px red message under it,aria-invalid="true". - Click the checkbox: a 10px red square scales from 0 → 1 in 120ms. Click a radio: a 10px blue disc does the same.
- Click the switch: the track fills yellow and the knob slides 24px right and morphs from an ink square to a red circle (240ms expo-out). Off again: back to an ink square.
- Hover the product card: it lifts 4px with a 4px hard ink shadow.
- Header anchors jump to sections; their hover state is a 2px red underline.
Structure
1280 × 800 first frame (sheet continues to ≈ 1000px; body scrolls)
┌──────────────────────────────────────────────────────────────────────────────┐
│ ●■▲ formhaus / design language 01 TYPE COLOUR CONTROLS GRAMMAR Kit v1.4│ 56 + 3px rule
├───────────────────────────────────────────────┬──────────────────────────────┤
│ formhaus möbel Kollektion Werkstatt Journal [Cart 2] │ ● 01 TYPE SPECIMEN│
│ REGAL 25 · MODULAR SHELVING ● ( red circle 290 ) │ Aa (150px) Josefin…│
│ build it ━━━━━━━━ │ ─────────────────────│
│ in squares. (76px) ■ (150) ▲ (180×156) │ Display 76 form follows│
│ body 15px │ H2 26 / H3 18 / Body 15 │
│ [Configure Regal 25 →] [1925 drawings] (↻) │ Label 11 │
│ From €640 · ships in 3 weeks cols 1–7 · 424h │ cols 8–12 · 424h │
├───────────┬───────────┬───────────┬──────────────────────────────────────────┤
│02 PALETTE │03 BUTTONS │04 INPUTS │05 CARD │
│ 5 swatches│ 3 buttons │ postcode │ [blue art 118h, yellow circle, NEW tag] │
│ 46px rows │ 4 states │ email err │ Stuhl B3 · €1,180 [Add] │
│ ratio bar │ 5 tags │ ☐ ◉ ○ sw │ │
│ cols 1–3 │ cols 4–6 │ cols 7–9 │ cols 10–12 ≈ 254h │
├───────────┴───────────┴───────────┴──────────────────────────────────────────┤
│ ● Circle acts │ ■ Square holds │ ▲ Triangle points │ ━ Rule divides (span 3 each)
│ footer strip: kit summary · "Click the round button to recompose" │
└──────────────────────────────────────────────────────────────────────────────┘
<header class="top">:.mark(three 16px shapes, 4px gap),.brand,<nav aria-label="Kit sections">with four anchors,.ver.<main class="sheet">:display: grid; grid-template-columns: repeat(12, 1fr); gap: 3px; background: var(--ink). Every child is a.cellwith paper background and 20px padding; the gap is the rule..hero(<section>, cols 1–7, 424px,overflow: hidden,data-comp="1|2|3"): five absolutely positioned.shapedivs, a.mininav, a.copyblock (eyebrow,<h1>,<p>, two buttons, meta line) and the round.recompbutton..spec(cols 8–12, 424px):<h2 class="lbl">,.aarow (glyph + two family notes),<ul class="scale">of five rows (<em>meta + sample)..pal,.ctl,.inp,.crd: span 3 columns each..gram× 4 span 3 each..footspans 12.- Section labels are
<h2 class="lbl">with a 9px shape before them; the shape class (c,s,t) picks circle/red, square/blue or triangle/yellow.
Tokens
:root {
/* colour: paper + ink + three primaries */
--paper: #f0ebe0; /* surface, 60 % of any screen */
--paper-2: #e4dccb; /* inner list rules, disabled fill */
--ink: #151412; /* text, all borders, hard shadows, 20 % */
--ink-2: #4a463f; /* secondary text */
--ink-3: #6e685d; /* meta labels, disabled text */
--red: #d52b1e; /* primary action, circles, errors (8 %) */
--yellow: #f3b61f; /* highlight, focus fill, "new" (7 %) */
--blue: #1d4f9c; /* info, links, focus ring, secondary action (5 %) */
--on-color: #f0ebe0; /* text on red / blue */
--error-fill: #f6ddd6;
/* type */
--display: "Josefin Sans", Futura, "Century Gothic", sans-serif;
--text: "Work Sans", system-ui, sans-serif;
--fs-display: 76px; --fs-aa: 150px; --fs-h2: 26px; --fs-h3: 18px; --fs-body: 15px; --fs-ui: 14px; --fs-label: 11px; --fs-meta: 10px;
/* geometry */
--rule: 3px; /* between regions */
--line: 2px; /* around controls */
--pad: 20px; /* cell padding */
--ctl: 44px; /* control height */
--radius: 0; /* the only exception is a full circle (50 %) */
--lift: 3px; /* button hover lift; cards use 4px */
--shadow-hard: 3px 3px 0 var(--ink);
--focus-block: 5px 5px 0 var(--yellow), 5px 5px 0 2px var(--ink);
--space: 4px 8px 12px 16px 20px 24px 32px;
/* motion */
--t-micro: 120ms;
--t-switch: 240ms;
--t-shape: 520ms;
--ease: cubic-bezier(.2, .7, .2, 1);
--expo: cubic-bezier(.16, 1, .3, 1);
}
Typography
| Role | Family | Size | Weight | Line-height | Tracking | Case |
|---|---|---|---|---|---|---|
| Hero headline | Josefin Sans | 76px | 700 | .88 | −0.025em | lowercase (universal-lowercase nod) |
| Specimen glyph | Josefin Sans | 150px | 700 | .8 | −0.04em | “Aa” |
| H2 | Josefin Sans | 26px | 700 | 1.1 | −0.01em | sentence |
| H3 / card title | Josefin Sans | 18–22px | 600–700 | 1.1–1.3 | 0 | sentence |
| Brand | Josefin Sans | 19px | 700 + 400 | 1 | −0.01em | lowercase |
| Body | Work Sans | 15px | 400 | 1.5 | 0 | sentence, --ink-2 |
| Button | Work Sans | 14px | 600 | 1 | +0.01em | sentence |
| Section label / eyebrow | Work Sans | 11px | 600 | 1 | +0.16em | UPPERCASE |
| Meta / state captions | Work Sans | 10px | 500 | 1 | +0.08–0.1em | UPPERCASE |
| Tag | Work Sans | 10px | 600 | 1 | +0.14em | UPPERCASE |
Josefin Sans sits low in its em box; add padding-top: 2–4px to any Josefin text that is vertically centred against a box (brand, card title, price) so it looks optically centred.
Motion
| Element | Trigger | Property | From → To | Duration | Easing |
|---|---|---|---|---|---|
.btn | hover | transform, box-shadow | 0,0 / none → −3px,−3px / 3px 3px 0 ink | 120ms | --ease |
.btn | active | transform, box-shadow | lifted → 0,0 / none | 120ms | --ease |
.card | hover | transform, box-shadow | → −4px,−4px / 4px 4px 0 ink | 120ms | --ease |
.shape × 5 | Recompose click | transform | arrangement n → n+1 (values below) | 520ms | --expo |
| checkbox/radio mark | change | transform: scale | 0 → 1 | 120ms | --expo |
| switch knob | toggle | translateX, border-radius, bg | 0 / 0 / ink → 24px / 50 % / red | 240ms | --expo |
| switch track | toggle | background | paper → yellow | 120ms | linear |
| input focus | focus | box-shadow | none → --focus-block | 120ms | --ease |
Arrangement 2: circle translate(-230px,120px) scale(.62), square translate(170px,-200px) rotate(90deg) scale(1.3), triangle translate(-40px,-210px) rotate(180deg), bar rotate(0) translate(40px,150px), dot translate(200px,240px) scale(1.6). Arrangement 3: circle translate(20px,-90px) scale(1.25), square translate(-30px,-30px) rotate(45deg), triangle translate(-200px,0) rotate(-90deg) scale(.8), bar rotate(-90deg) translate(-40px,-40px), dot translate(-40px,190px). Arrangement 1 is the untransformed layout.
Reduced motion: every transition 1ms. Recompose still swaps arrangements, instantly.
States
- Button rest: 44px tall, 2px ink border, 0 radius. Primary red / on-color text; secondary blue / on-color; neutral paper / ink; round = 44px yellow circle with an ink arrow.
- Hover: lifted 3px up-left with a 3px hard ink shadow. Pressed: flat, no shadow. Disabled:
--paper-2fill,--ink-3text and border, no lift,cursor: not-allowed. - Focus-visible (everything):
outline: 3px solid var(--blue); outline-offset: 3px. Inputs replace this with--focus-block. - Input error: border
--red, fill--error-fill, message 12px/500 red below,aria-invalid+aria-describedby. - Checkbox checked: red 10px square inside the 20px box. Radio checked: blue 10px disc inside a 20px circle.
- Switch on: yellow track, red circular knob at the right. Off: paper track, ink square knob at the left.
- Tags: 26px, 2px ink border, 8px leading shape. Yellow “New” (square), red “Sale” (circle), blue “Info” (square), ink “Last 3” (triangle, paper text), plain “Birch”.
- Nav link hover: 2px red bottom border.
Accessibility
- Header
<nav aria-label="Kit sections">; each kit cell is a<section>labelled by its<h2>; the hero is labelled “Composition: product landing hero”. - All decorative shapes (
.shape, card art, grammar glyphs, the mark) arearia-hidden="true". - The static state specimens are
aria-hiddenwithtabindex="-1"so they don’t add four extra tab stops. - Recompose is an icon button with
aria-labelthat reports the arrangement (“arrangement 2 of 3”). - The switch is
<button role="switch" aria-checked>; checkboxes and radios are native inputs visually hidden, with focus drawn on the replacement<i>. - Contrast: ink on paper 16.4:1; ink-2 on paper 8.1:1; paper on red 5.7:1; paper on blue 6.6:1; ink on yellow 10.9:1. Red text on paper (eyebrow, error message) is 4.9:1 and only used at ≥ 11px/600.
- Hit targets: controls 44px; the switch is 52 × 28 but its whole label is clickable.
Responsive rules
- ≥ 1280: as drawn; the sheet continues to ≈ 1000px and the body scrolls.
- 1024–1279: same grid; the hero shapes are pinned to the right edge so they crop instead of colliding with the copy.
- 700–1100: hero and specimen each span 12 columns; component cells and grammar cells span 6; header anchors hide.
- < 700: every cell spans 12; hero becomes 520px tall with a 56px headline and the circle pushed below the copy; specimen height becomes auto.
- Applying the language to a product: keep 3px region rules on any layout, 2px on controls, never introduce a radius between 0 and 50 %.
Acceptance checklist
- Only five colours appear (paper, ink, red, yellow, blue) plus
--paper-2,--ink-2/3and the error fill. - Regions are separated by a 3px ink grid gap, not by borders on each cell.
- No border-radius anywhere except true circles (round button, radio, switch knob when on, red circle shapes).
- Hero headline is Josefin Sans 700, 76px, line-height .88, lowercase.
- Buttons are 44px tall with a 2px ink border and lift 3px with a hard 3px shadow on hover, flatten on press.
- The States strip shows rest, hover, pressed and disabled at once without interaction.
- Recompose cycles three shape arrangements over 520ms expo-out; the copy never moves.
- Input focus draws a 5px yellow offset block with a 2px ink edge; error state uses red border, pale fill and a described message.
- The switch knob is a square when off and a circle when on, and
aria-checkedflips. - Section labels carry a 9px circle, square or triangle that matches their colour role.
- Focus is visible on every link, button and input (3px blue, 3px offset).
- With reduced motion, all state changes still happen instantly.
- No font other than Josefin Sans and Work Sans is loaded.
Implementation notes
Rules from the grid gap. Paint the grid container ink and let each paper cell sit on it; every region boundary is then exactly 3px and never doubles up:
.sheet { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--rule); background: var(--ink); }
.cell { background: var(--paper); padding: var(--pad); min-width: 0; }
.hero { grid-column: 1 / 8; height: 424px; overflow: hidden; padding: 0; }
Square-to-circle switch. The knob morphs geometry as it travels, which is the language’s whole argument in one control:
.sw-t button { width: 52px; height: 28px; border: 2px solid var(--ink); background: var(--paper); position: relative; }
.sw-t button::after { content: ""; position: absolute; left: 3px; top: 3px; width: 18px; height: 18px; background: var(--ink);
transition: transform var(--t-switch) var(--expo), border-radius var(--t-switch) var(--expo), background var(--t-switch); }
.sw-t button[aria-checked="true"] { background: var(--yellow); }
.sw-t button[aria-checked="true"]::after { transform: translateX(24px); border-radius: 50%; background: var(--red); }
Recompose is data-attribute driven; the shapes have one transition and three transform sets:
let c = 1;
recomp.addEventListener('click', () => {
c = c % 3 + 1; hero.dataset.comp = c;
recomp.setAttribute('aria-label', `Recompose shapes, arrangement ${c} of 3`);
});
Triangles are clip-path: polygon(50% 0, 100% 100%, 0 100%) on a div, not SVG, so they share the same transition as the other shapes. Common mistakes: adding an 8px radius “for friendliness” (it destroys the grammar); using soft blurred shadows (only hard, zero-blur offsets exist here); putting red on body text; centring Josefin Sans by line-height alone (it rides high; add 2–4px top padding).
Details
- Palette
- Type
- Josefin Sans · Work Sans
- Motion
- Subtle motion
- Build
- One session
- Tags
On the shelves