StealThis .dev
Pages Medium

DIY — Woodworking Shop Landing

A warm kraft-paper landing page for a fictional woodworking shop and school, built with plain HTML, CSS and vanilla JavaScript. It pairs a self-drawing SVG bench cut-plan with dimension lines, a row of isometric project cards carrying skill badges and board-feet chips, a live cut-list calculator that prices stock by species, a hoverable tool strip with line-art icons, a wood-species selector that recolors a CSS grain preview, workshop cards with seats-left meters, and a newsletter footer.

Open in Lab
html css vanilla-js
Targets: JS HTML

Code

Woodworking Shop Landing

Grainhouse Woodworks is a fictional shop-and-school landing page set on a kraft-paper background of layered gradients. The hero pairs an italic serif headline and dual CTAs with a framed technical drawing: a Roubo-style bench in orthographic view, complete with burnt-orange dimension lines, arrowheads and mono callouts, that inks itself in when it scrolls into view.

Below it, four project cards each carry an isometric SVG piece on a hatched kraft plate, a colour-coded skill badge, and mono chips for board feet and build time. The cut-list calculator takes width, length, quantity and nominal thickness and recomputes board feet and estimated cost on every keystroke — priced against whichever species is currently selected, so the two sections stay in sync. The species swatches are a proper ARIA radiogroup with arrow-key navigation; picking one recolours the CSS wood-grain preview panel and animates the Janka hardness meter.

The tools strip reveals shop notes on hover, focus or click, the workshop cards decrement their seats-left meters when you hold a seat (turning burnt-orange under two seats and locking to a waitlist at zero), and the footer newsletter validates inline. Every action confirms through one shared toast() helper.

How this look is built

The paper and the wood are both pure CSS: stacked repeating-linear-gradient layers at slightly off-axis angles (92deg, 3deg, 97deg) fake fibre and grain far more cheaply than any texture image, and the grain panel swaps only two custom properties — --t and --t2 — so a species change is a single background-color transition instead of a repaint of four gradient stops. The hero drawing uses the classic stroke-dasharray/stroke-dashoffset trick, but the path lengths are measured at runtime with getTotalLength() and written back as a --len custom property, so the CSS keyframe stays generic and every path finishes at the same time regardless of length; an IntersectionObserver gates the animation until it is visible rather than firing it on load. Watch two things: only stroke-dashoffset, transform, opacity and width are animated (all compositor- or paint-cheap), and prefers-reduced-motion both snaps the drawing to its finished state and swaps smooth anchor scrolling for instant jumps.

Illustrative UI only — always follow real safety guidance when working with tools, electronics, or repairs.