All interface styles

Neo-brutalism

Thick black borders, offset hard shadows and flat blocks of colour, with nothing softened and nothing pretending to be a physical material.

Also called: brutalist, neubrutalism, hard shadow, raw web, anti-design

Neo-brutalism specimen

The shadow has no blur — it is a solid offset copy of the block. Press or focus the buttons and the block travels into its own shadow, so the state change is a position change, not a colour change.

Every style in this collection renders the same markup — one navigation row, one headline and action, one labelled input, a selected and an unselected control, a card with a status and a data row, and a secondary action. Colour and type come from the active design kit; the style decides the rendering.

What you see

The perceptual fingerprint, in the order you notice it.

  • Heavy 2–3px borders on everything, in one uniform colour
  • Hard-edged offset shadows with no blur, as if a copy sat behind the block
  • Flat saturated fills with no gradient anywhere
  • Square or barely-rounded corners, tight and consistent
  • Oversized type that treats headings as graphic objects

Best for

  • Launches, campaigns and portfolios that want to be remembered rather than trusted
  • Products with a stated point of view, where visible confidence is the message
  • Interfaces where state must be unmissable — the borders carry it for free

Avoid when

  • Financial, medical or enterprise contexts where the visual argument is calm competence
  • Long-form reading — the border density fights sustained text
  • Dense data tables, where every rule line multiplies into visual noise

Accessibility

Where this style tends to fail an audit, and what fixes it.

  • The border colour is a non-text element and needs 3:1 against both the fill and the page — the usual failure is a black border on a dark section.
  • Offset shadows must not be the only difference between resting and pressed; move the block and change the border weight together.
  • Large flat colour blocks make text contrast a per-block calculation. Check every fill, not just the page background.

Built for

The site archetypes this render grammar suits. Each opens the catalog on that lane.

Matching design kits

A style is a render grammar. A design kit supplies the colour, type and personality it paints.

Raw, loud, confrontational: hard zero-blur offset shadows, thick solid borders, square corners, flat clashing fills.

Implementation bundle

What an agent needs in order to actually build Neo-brutalism on top of your design kit — surface rules, per-component behaviour, responsive behaviour, fallbacks and QA.

Surface rules

The declarations that make the render grammar, stated as CSS.

  • Border: `2px solid hsl(var(--foreground))` on every surface, control and input. One weight, no exceptions — variation reads as a mistake.
  • Shadow: `box-shadow: 4px 4px 0 0 hsl(var(--foreground))`. Zero blur, zero spread; the offset IS the shadow.
  • Radius: `--radius: 0` or a flat 4px cap. Mixed radii break the drawn-object illusion.
  • Fills are flat `--primary`, `--accent`, `--secondary` and `--card` at full opacity. No gradient, no alpha, no tint layers.
  • Type: headings at 700–900 weight and tight tracking (`letter-spacing: -0.02em`), body left at kit defaults so the page stays readable.

Component rules

Nav, action, input, selection, card and status, one rule each.

  • Nav is a bordered bar with the active item inverted (foreground fill, background text) rather than underlined.
  • Primary action: `--primary` fill, foreground border, 4px offset shadow; on `:active` translate 4px down-right and drop the shadow to 0 so the block lands.
  • Inputs get the same border and a 2px inset shadow; the label sits above in uppercase at small size, never as a placeholder.
  • Selected state inverts the chip (foreground fill, background text) AND keeps the border. Unselected chips keep the border and lose the fill.
  • Cards are bordered blocks with a bordered header strip; the status sits in that strip as text on a flat fill.
  • Secondary action drops the fill, keeps the border and shadow — the hierarchy is fill, not size.

Responsive rules

What has to change as the viewport narrows for the style to survive.

  • Below 640px reduce the shadow offset to 3px and the border to 2px so blocks do not eat the gutters.
  • Blocks stack to a single column with a full 16px gutter; the offset shadow needs clearance or it clips against the viewport edge.
  • Oversized headings switch to `clamp()` with a floor near 28px — brutalist type overflows narrow screens before anything else does.

Fallbacks

The degraded paths: unsupported effects, weak shadows, reduced motion.

  • `prefers-reduced-motion`: keep the `:active` translate (it is a 1-frame position change, not an animation) but remove any transition timing.
  • In dark mode invert the border to `--foreground` as resolved by the kit; do not hardcode black, or the borders vanish on dark surfaces.
  • On forced-colors, drop the offset shadow and rely on `border` — hard shadows are not rendered in forced-colors mode.

QA checks

What to verify before shipping an interface in this style.

  • Every border clears 3:1 against the fill it sits on AND the surface behind it.
  • Press a button with the keyboard: the block moves and the focus ring is still visible outside the border.
  • Text on each coloured fill clears 4.5:1 — brand fills are where this fails.
  • At 320px no offset shadow is clipped by the viewport edge.

Agent tags

The vocabulary a coding agent can match this style on.

  • hard-shadow
  • thick-border
  • flat-fill
  • offset-block
  • high-contrast