Communitygithub.com

salveignis/bauhaus-geometry

Builds websites and UI with Bauhaus-inspired geometric form in 2D and 3D, from landing pages to e-commerce listings, product pages, carts, checkouts and dashboards. Covers tile fields, custom shape construction, line bundles, isometric scenes, hairline grids, widgets and sections, grounded in the school's architecture and graphic design theory. Use when the user asks for Bauhaus, constructivist, modernist, Swiss-adjacent, geometric, primary-colour or shape-based web design, geometric patterns or heroes, isometric CSS/WebGL scenes, a geometric online store or catalog, or wants to add geometric identity to a site or component, in plain HTML or any framework.

What is bauhaus-geometry?

bauhaus-geometry is a Claude Code agent skill that builds websites and UI with Bauhaus-inspired geometric form in 2D and 3D, from landing pages to e-commerce listings, product pages, carts, checkouts and dashboards. Covers tile fields, custom shape construction, line bundles, isometric scenes, hairline grids, widgets and sections, grounded in the school's architecture and graphic design theory. Use when the user asks for Bauhaus, constructivist, modernist, Swiss-adjacent, geometric, primary-colour or shape-based web design, geometric patterns or heroes, isometric CSS/WebGL scenes, a geometric online store or catalog, or wants to add geometric identity to a site or component, in plain HTML or any framework.

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/salveignis/bauhaus-geometry/tree/main/skills/bauhaus-geometry

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Bauhaus Geometry

Geometry here is a building system, not decoration. Every shape on the page must do a job, and the page must still work if the shapes are removed. It must also never get in the way of the page's job. Follow this workflow in order.

1. Route by page type

Start from what the page must do, not how it should look. Read the matching guide, which sets the geometry limit and the acceptance checklist.

The page isReadIntensity limit
Home, brand, launch, landing, editorialpage-storefront.md3
Category, search results, catalogpage-plp.md1
Product detailpage-pdp.md1, or 2 behind the gallery
Cart, checkoutpage-checkout.md0
Dashboard, admin, account, settingspage-app.md0 to 1

A brand brief never raises this limit. A shop's home page may be a poster, and its checkout may not. For a whole site, set the limits per page before designing any of them.

Then ask what size it must reach: 9 products and 900 need different structures. Build for the real catalogue, and test with the largest expected size.

2. Set the brief

Decide these three things before writing markup. Infer them from the project; ask only if the brand truly leaves them open.

Geometry intensity. Default to the lowest level that expresses the brand, within the page's limit.

LevelNameGeometry coversFits
0TypeNothing. Scale and grey value do the workManifestos, law, long reads
1MarkerSmall shapes encode category or stateSaaS, dashboards, science, finance
2StructureGrid is visible; one composition per screenStudios, culture, editorial
3PosterA composition dominates one sectionLaunches, events, brand pages

A page has at most one level 3 section.

Depth tier. D0 is the default. Add depth only when "parts assembling" or "layers" is the actual message.

TierTechniqueCostUse
D0Flat tiles and linesCSS onlyAlmost everywhere
D1Hard offset (.bh-offset)CSS onlyButtons, cards, emphasis
D2Oblique extrusion (.bh-extrude)CSS filterIcon sets, pictograms
D3Isometric slabs (.bh-iso)CSS 3DHeroes, process, architecture of a product
D4WebGL (bh-three.js)three.js, GPUOne interactive centrepiece only

Palette. Set data-bh-palette on <html> or any section: primary, mono, signal, ember, pop, lab, night. For a brand, override the six role tokens (--bh-bg, --bh-fg, --bh-a1 to --bh-a4) and run the contrast check in step 5. Red, blue and yellow are a historical convention, not a requirement.

3. Place before you draw

Read placement.md before placing any shape. It maps each page slot to what belongs there and gives numeric budgets: one composition per page, one shape family per block, one tile size, forms joining across edges, no holes, no figure nested in a figure, data outside art. The tile list says what exists; this file says where it goes.

For a hero, choose an art mode there (block, stack, frieze, lines or cells). Default to a block built with composeBlock:

node scripts/generate.mjs block --cols 3 --rows 4 --seed 7 --colors fg,a1,a3,a2

For other sections, composition.md gives rules and failure modes for each archetype. Many are poster methods, so check the slot map first.

If the user supplies references, measure them with the method in reference-decoding.md before building, then compare your page with the same numbers.

Read the theory in theory.md when the user wants rationale, when a decision is contested, or when writing about the design.

4. Load the parts

Copy from assets/ into the project. Do not rewrite them from memory.

  • bauhaus-geometry.css: tokens, tiles, fields, depth, motion. Always include. It is safe beside an existing design system because everything sits in cascade layers and is prefixed bh-.
  • bauhaus-ui.css: widgets and sections. Skip it when the project has its own components, and apply tiles and tokens to those components instead.
  • bauhaus-commerce.css with bh-commerce.js: listings, filters, product pages, cart and checkout. Use for any shop.
  • bh-shapes.js: custom shapes as data, including <bh-shape>.
  • bh-geometry.js: generators and optional custom elements <bh-field>, <bh-bundle>, <bh-construct>.
  • bh-three.js: D4 only. templates/construct-webgl.html shows the wiring.
  • templates/landing.html: a complete marketing page to start from.
  • bh-audit.js: an in-browser check for step 6.

Prefer static markup so the page needs no runtime JS:

node scripts/generate.mjs field --preset bloom --cols 6 --rows 3 --seed 4
node scripts/generate.mjs bundle --preset u --n 9 --gap 5
node scripts/generate.mjs construct --preset pinwheel
node scripts/generate.mjs shape --name bean --size 64

Try several seeds and keep the best; a generated field is a draft, so swap individual tiles by hand where the composition is weak.

5. Build

The tile is the atom. One element, one primitive, one quarter-turn rotation:

<i class="bh-t" data-s="quarter" data-f="a1" data-g="bg" data-r="90"></i>
  • data-s shape: solid disc dot quarter half arch leaf tri peak diamond cross x stair octa ring notch bite bars slash arcs rings burst dots dotfan checker void
  • data-f figure and data-g ground: bg fg a1 a2 a3 a4, or set --f and --g directly
  • data-r: 90 180 270
  • Layout: .bh-field with --cols, .bh-cells for a drawn grid, data-span="2" for scale contrast

Need a shape the list lacks? Read shapes.md first and describe it to bh-shapes.js as data. Do not hand-draw SVG paths or stroke details on top of a silhouette.

Find ready-made markup, then adapt its copy and tokens:

  • commerce.md: product card and its states, variants, cart line, order summary, checkout fields
  • sections.md: heroes, bento, stats, process, CTA, footer
  • widgets.md: cards, stats, price plans, charts, graph, accordion, form, tabs
  • grids.md: the module, layout recipes, responsive rules
  • depth-3d.md: spec format for constructs, D3 and D4
  • motion.md: entrance, scroll and kinetic recipes

Frameworks. Classes and attributes port directly. In JSX, write className and style={{ "--cols": 6 }}. With Tailwind, keep the core stylesheet and use arbitrary values for layout around it. Render generated markup at build time where possible.

6. Verify

Run these and fix what they report before finishing:

node scripts/check-contrast.mjs            # bundled palettes
node scripts/check-contrast.mjs --bg "#f2ede1" --fg "#191816" --a1 "#d3341b" --a2 "#1d4fa3"
node scripts/shape-lint.mjs src/index.html # any file containing inline SVG

Then, in a browser at 375px and 1280px, run the audit and work through the page guide's acceptance list:

const { audit } = await import("./assets/bh-audit.js");
console.table(audit({ card: ".bh-product", name: ".bh-product__name", price: ".bh-price" }));

Also check:

  • Count the hero: one shape family, one size, no holes, and forms that join. Put it beside your references and compare the numbers.
  • Remove all geometry mentally: is the hierarchy still clear?
  • Each shape has a nameable job: mark, divide, frame, encode, navigate or anchor.
  • Decorative compositions have aria-hidden="true"; data shapes have a text alternative.
  • No horizontal scroll, and tiles stay square.
  • Text never sits on a pattern tile (bars, arcs, dots, burst).
  • Colour is never the only carrier of meaning. a3 and a4 are decorative unless labelled.
  • Motion stops under prefers-reduced-motion, and only one thing loops per view.
  • Interactive targets are at least 44px tall, with visible focus.

Hard rules

Rights. Use the style, never the works. See rights.md before naming, adding imagery or adapting a reference.

  • Never reproduce a specific artwork, poster, logo or composition, whether historic or contemporary. A reference image informs principles only: change the structure, not just the colours.
  • Never use the 1922 Bauhaus signet, museum logos, or photos of historic buildings, furniture or people unless the user supplies licensed files.
  • Do not brand a client's product "Bauhaus", or imply affiliation with any Bauhaus institution or company.
  • Fonts: default to the bundled stacks, which reference open-licensed Jost, Archivo and Space Grotesk (SIL OFL). Do not ship commercial revivals without a licence.

Form.

  • Flat fills, hairlines and hard edges. No gradients on figures, soft shadows, glassmorphism or rounded cards. Curves come from geometry, not border-radius on containers.
  • Asymmetric layout: flush-left type and off-centre weight. Avoid a centred hero with shapes floating around it.
  • One saturated accent should dominate each view. Three equal primaries read as a toy.
  • Scale contrast is required: pair a very large form with very small ones.
  • Vary the vocabulary by restricting it. Five shapes used well beat all twenty-five at once.

Scale. Never judge a listing from a nine-item demo. Try many items, long names, missing images and an empty result before calling it done.

Common failures.

FailureFix
Random shapes scattered around contentBuild one block with composeBlock, and delete the rest
Figure nested in a figureMake the object itself the form, spanning 2×2
Hairlines on every sectionFrame one section, and use space for the others
Equal tiles covering everything, like wallpaperAdd a large span, add voids, reduce the area
Primary colours on every elementUse one accent; the rest are ink and paper
Geometry fights the copyLower the intensity one level
"Bauhaus" font everywhereUse a neutral grotesque for text, geometric sans for display only
Isometric scene that says nothingUse D0 unless the parts map to real concepts
Shape with a stray stub or sliverRebuild it with bh-shapes.js: a cut, not a stroke
Editorial layout applied to a shopRoute by page type: price and action first
One-tap add picks a variant nobody choseLink to options when there is more than one

Related Skills