Formwerk
Remix this template to create a similar design — same sections, layout, animations, colors, and typography.
A landing page for an acetate eyewear brand. Crisp white canvas, vivid red and grey accents, clean display over body sans.
Palette
Typography
clamp(2.4rem,6.4vw,5.7rem)
26px
18px
28px
14px
13px
10px
Spacing & Shape
| Token | Value | Preview |
|---|---|---|
| xs | 4px | |
| sm | 8px | |
| md | 16px | |
| lg | 24px | |
| xl | 32px | |
| gutter | 24px | |
| maxWidth | 1320px |
Border Radius
| Token | Value | Preview |
|---|---|---|
| none | 0px |
design.md
tokens (raw)
name: formwerk-design
version: alpha
description: >
Formwerk is a black-on-white technical-drawing eyewear catalogue: a pure white
page (#FFFFFF) ruled by full-strength black (#000000) hairlines, a strict
12-column grid with 24px gutters, and a single red voltage (#E2231A) reserved
for the active filter and link hover. Helvetica Now Display/Text carries
everything — tight tracking on bold display, an uppercase 10px label face with
0.08em tracking and tabular numerals everywhere measurements appear. The
signature move is engineering dimension lines (CSS-drawn rules with tick caps
and floating MM labels) that draw themselves across product images on scroll.
Zero radius, zero shadow — depth is made entirely of hairline borders.
colors:
# Surface
page: '#FFFFFF' # body background (bg-white)
# Text / Ink
ink: '#000000' # headings, body, all hairlines (text-black)
grey: '#7F7F7F' # .grey — muted labels, captions, secondary numerals
# Brand / Voltage
red: '#E2231A' # .red — active filter border+text, link hover
# Hairlines
hairline: '#000000' # primary section/grid borders (border-black)
hairline-15: 'rgba(0,0,0,0.15)' # internal divider rules (border-black/15)
hairline-25: 'rgba(0,0,0,0.25)' # inactive filter chip borders (border-black/25)
hairline-10: 'rgba(0,0,0,0.10)' # footer list dividers (border-black/10)
on-ink: '#FFFFFF' # white text on black button hover (hover:text-white)
typography:
display:
fontFamily: "'Helvetica Now Display','Helvetica Neue',Helvetica,Arial,sans-serif"
fontSize: clamp(2.4rem,6.4vw,5.7rem)
fontWeight: 700
lineHeight: 0.92
letterSpacing: -0.03em
display-md:
fontFamily: "'Helvetica Now Display','Helvetica Neue',Helvetica,Arial,sans-serif"
fontSize: 26px
fontWeight: 700
lineHeight: 1.05
letterSpacing: -0.01em
product-name:
fontFamily: "'Helvetica Now Display','Helvetica Neue',Helvetica,Arial,sans-serif"
fontSize: 18px
fontWeight: 700
price-lg:
fontFamily: "'Helvetica Now Display','Helvetica Neue',Helvetica,Arial,sans-serif"
fontSize: 28px
fontWeight: 700
lineHeight: 1
body:
fontFamily: "'Helvetica Now Text','Helvetica Neue',Helvetica,Arial,sans-serif"
fontSize: 14px
fontWeight: 400
lineHeight: 1.625
body-sm:
fontFamily: "'Helvetica Now Text','Helvetica Neue',Helvetica,Arial,sans-serif"
fontSize: 13px
fontWeight: 400
lineHeight: 1.375
label:
fontFamily: "'Helvetica Now Text','Helvetica Neue',Helvetica,Arial,sans-serif"
fontSize: 10px
fontWeight: 400
lineHeight: 1
letterSpacing: 0.08em
textTransform: uppercase
rounded: # no radius anywhere — pure rectilinear
none: 0px
spacing: # base unit 4px; Tailwind scale
xs: 4px
sm: 8px
md: 16px
lg: 24px
xl: 32px
gutter: 24px # grid12 column-gap
maxWidth: 1320px # page container max-width
components:
header:
backgroundColor: '{colors.page}'
borderBottom: '1px solid {colors.hairline}'
typography: '{typography.label}'
padding: '12px 24px'
wordmark:
textColor: '{colors.ink}'
typography: '{typography.product-name}'
note: 'FORMWERK with grey ® superscript in normal text face'
navLink:
textColor: '{colors.ink}'
typography: '{typography.label}'
hoverColor: '{colors.red}'
filterChipActive:
backgroundColor: '{colors.page}'
textColor: '{colors.red}'
border: '1px solid {colors.red}'
typography: '{typography.label}'
rounded: '{rounded.none}'
padding: '6px 12px'
label: 'ALL'
filterChipInactive:
backgroundColor: '{colors.page}'
textColor: '{colors.grey}'
border: '1px solid {colors.hairline-25}'
typography: '{typography.label}'
rounded: '{rounded.none}'
padding: '6px 12px'
hover: 'border + text go to {colors.ink}'
catalogCard:
backgroundColor: '{colors.page}'
border: '1px solid {colors.hairline}'
rounded: '{rounded.none}'
padding: '24px'
note: 'col-span-6; image then hairline-topped name/price row; name in display bold, spec in tabular-nums'
specRow:
typography: '{typography.label}'
textColor: '{colors.grey}'
valueColor: '{colors.ink}'
borderTop: '1px solid {colors.hairline}'
note: 'grey label left, tabular-nums value right, e.g. LENS / 52.0 MM'
table:
typography: '{typography.body}'
headerColor: '{colors.grey}'
headerBorder: '1px solid {colors.hairline}'
rowBorder: '1px solid {colors.hairline-15}'
note: 'model column in display bold; numeric cells right-aligned tabular-nums'
buttonOutline:
backgroundColor: '{colors.page}'
textColor: '{colors.ink}'
border: '1px solid {colors.ink}'
typography: '{typography.label}'
rounded: '{rounded.none}'
padding: '12px 32px'
hover: 'bg {colors.ink} / text {colors.on-ink}'
label: 'VIEW FULL CATALOG →'
dimensionLine:
color: '{colors.ink}'
note: '1px black rule with 9px tick caps at each end; floating white-backed MM label in label face + tabular-nums'
motion:
engine: 'GSAP 3 + ScrollTrigger (jsDelivr CDN)'
heroDimDraw: 'hero dimension lines scaleX 0→1, ease none, 0.7s, stagger 0.12, trigger top 75%'
heroDimY: 'vertical dimension line scaleY 0→1, ease none, 0.7s'
dimLabels: 'MM labels fade opacity 0→1, 0.3s, delay 0.6s, stagger 0.12'
catalogReveal: 'cat-cells from opacity 0 / y 18, power1.out, 0.5s, stagger 0.08, trigger top 70%'
portraitDim: 'portrait dimension line scaleX 0→1, 0.7s + label fade'
reducedMotion: 'prefers-reduced-motion forces all dimension lines to scale 1 (drawn, no animation)'
icons:
library: none
style: 'no icon set; arrows are literal → glyphs, superscript ® is text'
color: '{colors.ink}'Formwerk
formwerk-design · alpha
Design spec — version alpha. Source: static HTML (
index.html); tokens read from inline styles + class rules. Fictional/sample product; described factually.
Overview
Formwerk is an eyewear catalogue rendered as a machinist's drawing. The page is
pure white (#FFFFFF) with black text (#000000), and every structural line —
section dividers, the grid, card edges, table rules — is a real 1px black
hairline, so the whole layout reads like a dimensioned technical sheet. A strict
12-column CSS grid (.grid12, repeat(12, minmax(0,1fr)) with a 24px
column-gap) governs every section inside a max-w-[1320px] container. Type is all
Helvetica Now (Display for bold headings, Text for body), with one repeated
device: the .lab label face — 10px, uppercase, 0.08em tracking — used for
nav, captions, filters and spec labels, paired with .tnum tabular numerals so
every measurement column aligns. The single accent is a Swiss red (#E2231A,
.red) reserved for the active catalogue filter and link hover. The signature
move is engineering dimension lines: CSS-drawn 1px rules with 9px tick
caps (.dimx / .dimy) and floating white-backed MM labels that GSAP draws
across the hero and portrait images on scroll. There is no radius and no shadow
anywhere — depth is made entirely from hairlines.
Colors
Surface. One surface only: page #FFFFFF (bg-white), used edge to edge;
the footer explicitly re-declares bg-white.
Ink / Text. ink #000000 (text-black) is the default for headings, body
and every hairline. grey #7F7F7F (.grey) is the muted tone for labels,
captions, secondary numerals and the ® superscript.
Brand / Voltage. red #E2231A (.red) is the lone accent — it draws the
active "ALL" filter chip (border + text) and is the hover color for header nav
links (hover:red).
Hairlines. Full-strength hairline #000000 (border-black) for primary
section, grid and card borders; hairline-15 rgba(0,0,0,0.15) for internal
divider rules and table rows; hairline-25 rgba(0,0,0,0.25) for inactive
filter chip outlines; hairline-10 rgba(0,0,0,0.10) for footer list dividers.
On-ink. on-ink #FFFFFF appears only as the text color when the outline
button inverts on hover (hover:bg-black hover:text-white).
Typography
Two faces, both from the Helvetica Now superfamily with a system Helvetica/
Arial fallback chain — .font-display = 'Helvetica Now Display', .font-text
= 'Helvetica Now Text'. Helvetica Now is a licensed commercial face and is not
bundled (no @import/CDN); it falls back to Helvetica Neue → Helvetica → Arial.
Closest open-source substitutes: Inter or Helvetica-like Arimo / Roboto
for the text face, and a tight grotesque such as Inter Display for display.
Tabular numerals (.tnum, font-variant-numeric: tabular-nums) are applied to
every spec value, price and measurement table.
| Token | Size | Weight | Line-height | Tracking | Usage |
|---|---|---|---|---|---|
| display | clamp(2.4rem,6.4vw,5.7rem) | 700 | 0.92 | -0.03em | Hero H1 |
| display-md | 26px | 700 | 1.05 | tight | Section pull-quote ("Designed for faces…") |
| product-name | 18px | 700 | — | — | Catalogue card names, wordmark |
| price-lg | 28px | 700 | 1 | — | Hero "FROM" price (CHF 290) |
| body | 14px | 400 | 1.625 | — | Body copy, table cells |
| body-sm | 13px | 400 | 1.375 | — | Card descriptions, footer text |
| label (.lab) | 10px | 400 | 1 | 0.08em | Nav, filters, spec labels, captions — UPPERCASE |
Layout
Base unit is 4px (Tailwind scale); recurring steps are 12px header padding,
24px (px-6 / gutter), 32px and larger section paddings (py-12, py-14,
pt-14). Every section is wrapped in mx-auto max-w-[1320px] px-6 and laid out
on .grid12 — a real 12-column grid with 24px column-gap. Signature structural
moves: the hero splits col-span-9 headline + col-span-2 spec stack over a
4-up dimension strip (LENS/BRIDGE/TEMPLE/WEIGHT), then a col-span-9 dimensioned
image beside a col-span-3 left-bordered data column. The catalogue is a 2-up
grid of col-span-6 cards bounded by shared black borders. A comparative
measurements <table> and a two-up "worn by" portrait/text split follow. The
footer is a 4×col-span-3 directory with index-numbered link lists. Whitespace
is generous and architectural; the page never escapes its hairline frame.
Elevation & Depth
No box-shadow, no backdrop-filter, no glow, no glass anywhere. Depth is built
entirely from hairlines at four opacities (#000, 15%, 25%, 10%) — borders
separate, stack and frame instead of shadows. The catalogue cards share single
black borders so the grid reads as one ruled sheet. The only "lift" is the
GSAP catalogue reveal (cards translate up 18px into place).
Shapes
Strictly rectilinear. The radius scale has a single value: rounded.none = 0.
There are no rounded-* classes, no pills, no circles — every card, chip,
button, image and table cell is a hard rectangle, matching the technical-drawing
concept.
Components
- Header — white bar,
border-b border-black,12px×24pxpadding; wordmarkcol-span-4,.labnavcol-span-5, "EST. 2019 · ZÜRICH"col-span-3grey. - Wordmark —
FORMWERKin display bold with a grey normal-weight®. - Nav link —
.labuppercase, black,hover:red. - Filter chip (active) — white fill,
#E2231Aborder + text,6px×12px, square; labelALL. - Filter chip (inactive) — white fill,
rgba(0,0,0,0.25)border, grey text; hover sends border and text to black. - Catalogue card —
col-span-6, single black border,24pxpadding; image inoverflow-hidden, then aborder-t border-blackrow with display-bold name- grey
.labmaterial, right-alignedCHF 290price over grey52□18-145.
- grey
- Spec row — grey
.lablabel left, tabular-nums value right (e.g.LENS / 52.0 MM),border-t border-black/15. - Measurements table —
border-collapse, grey.labheaders under a black header rule,border-black/15row rules; model in display bold, numbers right-aligned tabular-nums. - Outline button — white fill,
1pxblack border,.lab,12px×32px; inverts to black fill / white text on hover; labelVIEW FULL CATALOG →. - Dimension line —
.dimx/.dimy:1pxblack rule with9pxtick caps at each end, plus a white-backed.dimlabelshowing the measurement in.lab+ tabular-nums (e.g.52.0 MM,145 MM,FRONT 138 MM).
Motion
GSAP 3 with ScrollTrigger (loaded from jsDelivr). The hallmark motion is the
dimension-line draw: hero horizontal lines animate scaleX 0→1 (ease none,
0.7s, stagger 0.12, fired at top 75%), the vertical line scaleY 0→1, and
their MM labels fade in (0.3s, delay 0.6s). Catalogue cards animate from
opacity 0 / y 18 with power1.out, 0.5s, stagger 0.08 at top 70%. The
portrait dimension line repeats the draw + label fade. prefers-reduced-motion
forces every dimension line to scale 1 (fully drawn, no animation) via both CSS
and a JS guard.
Iconography
No icon library. Arrows are literal → glyphs in button labels; the ® is a
text superscript. All such marks inherit ink #000000 (or grey for the ®).
Do's and Don'ts
- Do keep everything inside the 12-column grid and the
1320pxcontainer. - Do use real
1pxblack hairlines (and the 10/15/25% tints) for all separation — never reach for a shadow. - Do set every measurement, price and table number in tabular-nums.
- Do reserve
#E2231Afor the active filter and link hover only. - Don't add border-radius, shadows, gradients or glass — the system is flat and rectilinear by definition.
- Don't introduce a second accent color or use red for body text.
- Don't mix in an icon font; arrows and marks stay as text glyphs.
Known Gaps
- Helvetica Now Display/Text is a licensed commercial superfamily with no
@import/CDN in the file; it renders via the Helvetica Neue → Helvetica → Arial fallback for most users. Substitute Inter / Inter Display (or Arimo) for an open-source build. Theurlfor both type tokens is empty for this reason. - Spacing/padding tokens are inferred from Tailwind utility classes; the file defines no explicit spacing scale.
- Dimension-line tick geometry (
9pxcaps,-4pxoffsets) and GSAP timings are read directly from the CSS/JS; exact rendered positions of the percentage-based inlineleft/top/widthvalues depend on each image's box.