Werkstatt
Remix this template to create a similar design — same sections, layout, animations, colors, and typography.
A landing page for an ethical AI cooperative. Primer-cream canvas, primary red, blue and yellow accents, bold Archivo Black with geometric motifs.
Palette
Typography
clamp(40px, 5.5vw, 72px)
clamp(52px, 8.5vw, 110px)
clamp(40px, 5.2vw, 74px)
42px
11px
12px
13px
15px
Spacing & Shape
| Token | Value | Preview |
|---|---|---|
| xs | 4px | |
| sm | 6px | |
| md | 12px | |
| lg | 24px | |
| xl | 32px | |
| xxl | 48px |
Border Radius
| Token | Value | Preview |
|---|---|---|
| none | 0px | |
| hairline | 1px | |
| pill | 9999px |
design.md
tokens (raw)
name: werkstatt-design
version: alpha
description: >
A Bauhaus / Swiss-brutalist landing page for a fictional worker-owned AI
cooperative. The surface is a warm cream "primer" (#F2EED4) ruled into hard
3px-ink grids; the voltage is the Bauhaus primary triad — signal red
(#C41818), Prussian blue (#2A4A7A), and a hot ochre yellow (#E8C420) — used as
full-bleed color blocks, not accents. Archivo Black sets oversized,
tightly-tracked display type; Space Mono carries every label, eyebrow, and
caption in uppercase wide-tracked mono; Jost handles the little body copy.
Signature moves: a split-clip hero seam with a color-split wordmark, an
animated Albers nested-square / orbital geometry stage, a black ticker
marquee, a scroll-locked SVG profit-flow diagram, and a horizontal pin-scroll
client rail. Zero border-radius except deliberate circles/pills.
colors:
# Brand (Bauhaus primary triad)
red: '#C41818' # primary voltage — hero-left block, red panel, accent type, button hover, focus underline
blue: '#2A4A7A' # secondary — blue tool panel, diagram nodes, logo circle, geo accents
yellow: '#E8C420' # tertiary — yellow tool panel, triangles, marquee stars, checkmark, accent bars
# Surface
primer: '#F2EED4' # warm cream page background, text on dark/colored fills
ink: '#0E0E0C' # near-black — text, 3px borders, dark sections (clients/footer/marquee/button)
# Hairlines (on dark)
hairline-primer-20: 'rgba(242,238,212,0.2)' # 3px dividers inside dark clients band
hairline-primer-15: 'rgba(242,238,212,0.15)' # 1px footer-top divider
hairline-primer-12: 'rgba(242,238,212,0.12)' # 1px footer column dividers
hairline-ink-40: 'rgba(14,14,12,0.4)' # client-card right border
# Grid textures
grid-ink-18: 'rgba(14,14,12,0.18)' # crosshatch fine grid on hero-left geo stage
grid-ink-07: 'rgba(14,14,12,0.07)' # faint clients scroll-budget background grid
typography:
display:
fontFamily: "'Archivo Black', sans-serif"
fontSize: clamp(40px, 5.5vw, 72px)
fontWeight: 400
lineHeight: 0.9
letterSpacing: -0.04em
wordmark:
fontFamily: "'Archivo Black', sans-serif"
fontSize: clamp(52px, 8.5vw, 110px)
fontWeight: 400
lineHeight: 1
letterSpacing: -0.05em
statement:
fontFamily: "'Archivo Black', sans-serif"
fontSize: clamp(40px, 5.2vw, 74px)
fontWeight: 400
lineHeight: 0.88
letterSpacing: -0.045em
tool-name:
fontFamily: "'Archivo Black', sans-serif"
fontSize: 42px
fontWeight: 400
lineHeight: 0.9
letterSpacing: -0.04em
eyebrow:
fontFamily: "'Space Mono', monospace"
fontSize: 11px
fontWeight: 400
lineHeight: 1.6
letterSpacing: 0.25em
textTransform: uppercase
nav-link:
fontFamily: "'Space Mono', monospace"
fontSize: 12px
fontWeight: 400
letterSpacing: 0.2em
textTransform: uppercase
mono-body:
fontFamily: "'Space Mono', monospace"
fontSize: 13px
fontWeight: 400
lineHeight: 1.7
body:
fontFamily: "'Jost', sans-serif"
fontSize: 15px
fontWeight: 400
lineHeight: 1.6
rounded: # near-zero radius; circles/pills are explicit only
none: 0px
hairline: 1px # wire-bar smoothing
pill: 9999px # circles (logo dot, diagram dots, morphed button) via border-radius:50%
spacing: # base unit 8px; common increments used in markup
xs: 4px
sm: 6px
md: 12px
lg: 24px
xl: 32px
xxl: 48px
components:
nav:
backgroundColor: '{colors.primer}'
textColor: '{colors.ink}'
typography: '{typography.nav-link}'
border: '3px solid {colors.ink} (bottom + cell dividers)'
padding: '14px 24px (logo) / 0 32px (links)'
nav-badge:
backgroundColor: '{colors.ink}'
textColor: '{colors.primer}'
typography: '{typography.nav-link}'
padding: '0 24px'
# label: "Worker-Owned · Est. 2019"
tool-panel:
backgroundColor: '{colors.yellow} | {colors.blue} | {colors.red}'
textColor: '{colors.ink} (yellow) | {colors.primer} (blue/red)'
typography: '{typography.tool-name}'
rounded: '{rounded.none}'
border: '3px solid {colors.ink} (right divider)'
padding: '32px'
wire-mock:
backgroundColor: '{colors.primer}'
textColor: '{colors.ink}'
border: '2px solid {colors.ink}'
padding: '14px'
diagram-node:
backgroundColor: '{colors.ink} | {colors.blue} | {colors.red} | {colors.yellow}'
textColor: '{colors.primer} (dark) | {colors.ink} (yellow)'
typography: '{typography.mono-body}'
padding: '12px 14px'
# yellow node carries 2px ink border
client-card:
backgroundColor: '{colors.red} | {colors.yellow} | {colors.blue}'
textColor: '{colors.primer} | {colors.ink}'
typography: '{typography.display}'
border: '3px solid {colors.hairline-ink-40} (right)'
padding: '28px'
# hover reveals an ink overlay with mono stat
form-input:
backgroundColor: 'transparent'
textColor: '{colors.ink}'
typography: '{typography.mono-body}'
border: '0 0 3px 0 solid {colors.ink}; focus → {colors.red}'
padding: '10px 0'
submit-button:
backgroundColor: '{colors.ink}; hover → {colors.red}'
textColor: '{colors.primer}'
typography: '{typography.nav-link}'
rounded: '{rounded.none}; morphs to {rounded.pill} (circle) on submit'
padding: '16px 32px'
# label: "Submit application"
marquee:
backgroundColor: '{colors.ink}'
textColor: '{colors.primer}'
typography: '{typography.nav-link}'
# stars in {colors.yellow}; 28s linear scroll, pause on hover
motion:
hero-split-reveal: 'left/right halves clip-path inset 0→full over 1.2s cubic-bezier(.86,0,.07,1), right delayed 0.08s'
geo-stage: 'staggered scale/opacity entrances; orbitSpin 38s & orbitSpinCCW 26s linear infinite; centerPulse 6s; triWobble 7s; ringPulse 5s; dotSlide 8s; halfRot 18s'
wordmark-detrack: 'letter-spacing 0.4em→-0.05em + opacity 0.15→1 over 1s ease 0.9s'
hero-pull-apart: 'JS scroll — halves translateX ±(scrollY*0.10), overlay clip boundary tracks'
statement-rise: 'three lines translateY 110%→0, 0.9s cubic-bezier(.86,0,.07,1), staggered 0.8/0.95/1.1s'
heading-wipe: 'sec-h2 clip-path inset(0 100% 0 0)→0 on is-visible, 0.9s; clients-h2 mask via scaleX pseudo-element'
marquee: 'translateX 0→-50%, 28s linear infinite, paused on hover'
diagram-draw: 'scroll-locked: page freezes, 7 SVG paths draw via strokeDashoffset + 7 nodes pop over 3200ms, then unlocks'
client-pin: 'JS pin-scroll — 200vh outer, track translateX driven by scroll progress'
button-morph: 'rounded pill + 56px square morph 0.4s, then yellow checkmark stroke-draws 500ms'
icons:
library: inline SVG + CSS-shape primitives
style: geometric (square / circle / triangle), filled
stroke: 2-3px (diagram paths, checkmark)
sizes: { sm: 18px, md: 22px, lg: 48px }
color: '{colors.red} | {colors.blue} | {colors.yellow} | {colors.ink}'werkstatt.coop
werkstatt-design · alpha
Design spec — version alpha. Source: static HTML (
index.html); tokens read from inline styles +:rootrules. Fictional/sample product; described factually.
Overview
werkstatt is a Bauhaus-meets-Swiss-brutalist landing page for a fictional
worker-owned ethical-AI cooperative. The whole page sits on a warm cream
"primer" surface (#F2EED4) ruled into hard cells by a single recurring stroke:
3px solid var(--ink) (#0E0E0C). Color is structural, not decorative — the
Bauhaus primary triad of signal red (#C41818), Prussian blue (#2A4A7A), and
hot ochre yellow (#E8C420) appears as full-bleed panels and color blocks. The
type story is three-voice: Archivo Black for oversized, negatively-tracked
display headlines (down to -0.05em); Space Mono uppercase with wide tracking
(0.2–0.25em) for every eyebrow, nav link, label and caption; and Jost for
the small amount of running body text. The signature moves are theatrical: a
split-clip hero whose red and primer halves wipe open over a color-split
wordmark sitting on the seam; an animated geometry stage of nested Albers
squares, slow counter-rotating orbital rings, a wobbling triangle and a sliding
dot; a black ticker marquee; a scroll-locked SVG profit-flow diagram that
freezes the page while it draws; and a horizontal pin-scroll rail of client
cards. Geometry is rectilinear and sharp — radius is 0 everywhere except
intentional circles and one button that morphs into a pill.
Colors
Brand (Bauhaus primary triad). red #C41818 is the primary voltage: the
hero-left block, the red tool/client panels, the join-left panel, accent
headline lines, the submit-button hover, and the form-input focus underline.
blue #2A4A7A is secondary — the blue tool panel, several diagram nodes, the
logo circle, and geo-stage rings/circle. yellow #E8C420 is tertiary — the
yellow tool panel, every triangle, marquee stars, the success checkmark, and
accent tick/bar marks.
Surface. primer #F2EED4 is the warm cream page background and the text
color on every dark or saturated fill. ink #0E0E0C is the near-black used
for body text, the universal 3px borders, and the dark sections (marquee,
clients band, footer, default submit button).
Hairlines. On dark surfaces, primer is dropped to translucent dividers:
rgba(242,238,212,0.2) for the 3px dividers in the clients band,
rgba(242,238,212,0.15) for the 1px footer-top rule, and
rgba(242,238,212,0.12) for footer column dividers. Client cards divide with
rgba(14,14,12,0.4).
Grid textures. Two faint ink grids supply texture: rgba(14,14,12,0.18) for
the crosshatch over the hero geometry stage, and rgba(14,14,12,0.07) for the
clients scroll-budget background grid (80–120px cells).
Typography
Three Google Fonts, loaded via a single fonts.googleapis.com/css2 import:
Archivo Black (display), Jost 400/500/700 (body), and Space Mono 400/700
(mono labels). All are open-source, so no substitution is needed. The display
voice is heavy, set tight (-0.04em to -0.05em) with sub-1 line-heights down
to 0.88. Mono labels are uppercase with 0.2–0.25em tracking. Jost runs only
in small body copy at 15px.
| Token | Size | Weight | Line-height | Tracking | Usage |
|---|---|---|---|---|---|
| display | clamp(40px,5.5vw,72px) | 400 | 0.9 | -0.04em | section H2s, footer/stat values |
| wordmark | clamp(52px,8.5vw,110px) | 400 | 1 | -0.05em | hero seam wordmark |
| statement | clamp(40px,5.2vw,74px) | 400 | 0.88 | -0.045em | hero right oversized statement |
| tool-name | 42px | 400 | 0.9 | -0.04em | tool-panel names |
| eyebrow | 11px | 400 | 1.6 | 0.25em | uppercase eyebrows / coords |
| nav-link | 12px | 400 | — | 0.2em | nav links, badge, marquee, button |
| mono-body | 13px | 400 | 1.7 | — | tool/intro/join body, diagram nodes |
| body | 15px | 400 | 1.6 | — | default page body (Jost) |
Layout
Base unit is effectively 8px, with common increments of 4 / 6 / 12 / 24 / 32 /
48px read directly from padding and gaps. The page is a single column of
full-bleed sections, each separated by a 3px ink rule, and most sections are
themselves cut into cells by the same stroke. The dominant structural primitive
is the 3fr / 9fr header band (a mono label cell beside a giant headline) and
equal-fraction grids: tools is repeat(3,1fr), the membership stat row is
repeat(4,1fr), the join section is 1fr 1fr, and the footer is
repeat(4,1fr). The hero is a 58% / 42% horizontal split. There is no centered
max-width container — content runs edge to edge and the grid lines do the
framing. Whitespace is generous inside cells (32–48px padding) but the cells
themselves butt directly against the hard borders.
Elevation & Depth
There are no drop shadows, blurs, or glass anywhere. Depth is created entirely by
the 3px ink borders, by stacking saturated color blocks, and by the nested
Albers squares and orbital rings in the hero geometry. Layering is literal
z-stacking of opaque shapes; the only translucency is in the faint grid textures
and the on-dark hairline dividers.
Shapes
Rectilinear and sharp. border-radius is 0 for every panel, card, input,
button, and mock — the brutalist default. Circles are explicit and intentional:
the logo dot and footer dot (border-radius:50%), diagram/geo dots, the orbital
rings, and the half-circle (60px 60px 0 0). The lone exception is the submit
button, which morphs from a sharp rectangle into a 56px circle (50%) on
submit. Triangles are made with CSS borders, not radius.
Components
- nav — sticky, primer fill,
3pxink bottom + cell dividers; logo = red square + blue circle + yellow triangle glyphs beside an Archivo Black wordmark; Space Mono uppercase links; right "nav-badge" in ink/primer reading "Worker-Owned · Est. 2019". - tool-panel — full-color cell (yellow/blue/red),
3pxink right divider,32pxpadding; Archivo Black stacked name, a2px-ink wireframe mock on primer, mono description, and aborder-topfooter "$0 / mo · members →". - wire-mock — primer card,
2pxink border,14pxpadding; ink bars (7pxtall,1pxradius),2pxoutlined cells/buttons, and a vertical bar chart — all monochrome ink. - diagram-node — solid ink/blue/red/yellow tag, mono label, Archivo Black
value; the yellow node carries a
2pxink border for contrast. - client-card —
360pxsaturated card with a giant Archivo Black name; hover reveals a full ink overlay with mono sector + Archivo Black outcome stat. - form-input — transparent field with only a
3pxink bottom border that turns red on focus; mono text, ink placeholder at 35% opacity. - submit-button — ink fill, primer mono label "Submit application", hovers to red, then morphs to a circle and draws a yellow checkmark.
- marquee — ink band, primer mono items, yellow
★separators, 28s scroll.
Motion
Motion is the centerpiece. On load the hero halves wipe open (clip-path inset,
1.2s cubic-bezier(.86,0,.07,1), right delayed 0.08s) while the seam wordmark
de-tracks from 0.4em to -0.05em and fades in. The geometry stage runs a suite
of infinite CSS keyframe loops: orbital rings (orbitSpin 38s / orbitSpinCCW
26s), centerPulse 6s, triWobble 7s, ringPulse 5s, dotSlide 8s, halfRot
18s. On scroll, JS drives a hero pull-apart (translateX ±scrollY*0.10), a
horizontal client pin-scroll over a 200vh budget, and the headline wipes
(clip-path/scaleX). The hallmark is the membership diagram: an
IntersectionObserver freezes the page (position:fixed body lock) and runs a
timed 3200ms animation drawing seven SVG paths via strokeDashoffset and popping
seven nodes, then unlocks scroll. The submit button morph (0.4s) plus a 500ms
checkmark stroke-draw closes the form.
Iconography
No icon font. Icons are inline SVG (orbital rings, the profit-flow diagram paths,
the checkmark) and CSS-shape primitives (squares, circles via border-radius:50%,
triangles via border tricks). Style is flat geometric Bauhaus; strokes are
2–3px and stroke-linecap:square. Sizes range from 18px logo glyphs to
22px checkmark to 48px footer shapes. Colors draw from the triad and ink —
decorative shapes are color-coded, the only true UI icons are the checkmark
(yellow) and the directional → / ↳ / ↓ arrows in mono text.
Do's and Don'ts
- Do keep the
3px solid #0E0E0Cborder as the universal divider — it is the grid that holds the whole layout together. - Do use the red/blue/yellow triad as full color blocks, paired with primer or ink text, never as small accents.
- Do set display type in Archivo Black with negative tracking and sub-1 line-height; set all labels in uppercase Space Mono with wide tracking.
- Don't introduce border-radius on panels, cards, inputs, or buttons — circles and the morph button are the only curves.
- Don't add drop shadows, gradients, or glass; depth comes from borders and flat color stacking only.
- Don't dilute the cream surface or the saturated triad with off-palette tints or pastel variants.
Known Gaps
- Font weights for Archivo Black and Space Mono in display use are rendered at
their single available weight (Archivo Black is 400-as-black; Space Mono 400),
noted as weight
400though they read visually heavy. - The spacing scale is inferred from the most common padding/gap values in the markup (4/6/12/24/32/48px); there is no formal token scale in the source.
- Exact animation easings/durations are taken verbatim from CSS where present; the JS-driven scroll factors (pull-apart 0.10, pin-scroll budget) are read from the script, not from declarative tokens.