Field notes · Site 10 of 25

How VERDANT grows

The concept. A botanical atelier and seed archive, set on a greenhouse morning. The signature idea: the page itself is a garden bed — vines germinate as you scroll, leaves sprout from their nodes, blooms unfurl where the stems decide to celebrate. Everything here — foxglove plate, seed packets, season wheel, pressed specimens — is inline SVG or CSS. No images anywhere.

Vines that grow with you

Each vine is one long cubic-bézier path. JS measures it with getTotalLength(), sets stroke-dasharray to that length, and drives stroke-dashoffset inside a requestAnimationFrame loop. Target progress comes from the vine’s getBoundingClientRect() against the viewport; drawn progress lerps toward it at 5.5% per frame, so growth trails your scroll like sap, not a scrubber. Vines only grow — the target is monotonic — because plants don’t un-grow when you scroll back up.

Leaves are placed procedurally: getPointAtLength() samples node positions every ~70 units, the local tangent angles each petiole, and sides alternate like true phyllotaxis. When the growing tip passes a node, the leaf scales from zero with a hand-rolled ease-out-back — a little overshoot reads as “sprout.” Blooms live at declared fractions of the path: eight petals, each rotated then scaled with a 70 ms stagger, unfurling from the center. A small chartreuse bud now rides the leading edge of every vine as it draws, sampled at the same getPointAtLength() call each frame, so the ink reads as something advancing rather than a line wiping into view — it fades the moment a vine settles. And growth isn’t the end of it: once a leaf has sprouted, a nested group keeps a slow, randomised CSS rotate() keyframe running forever, so a fully grown vine still breathes — the difference between a screenshot and a garden.

Plates, wheels, presses

The hero foxglove is generated stroke by stroke — stem, bells, throat-spots, basal leaves — each path given pathLength="1" so one CSS rule (stroke-dasharray:1 → offset 0) draws it in, choreographed with per-path transition-delay. Terracotta washes fade up only once the ink dries. The season wheel is pure trigonometry: arcs from a polar helper, month labels counter-rotated below the equator so nothing reads upside down, season names on <textPath>, and a hand starting at today’s day-of-year angle, sweeping one revolution per 140 s. The herbarium reuses the dash-draw trick, triggered by IntersectionObserver.

The ambient layer

A fixed canvas (devicePixelRatio capped at 2) floats thirty pollen motes on layered sine drift, dropping a leaf every six to twelve seconds with sway, spin, and a bézier-drawn blade. The loop halts on document.hidden. On a mouse, a small loupe-ring cursor trails your hand at a 22% lerp — a lag, not a snap — widening over anything you can act on. It never replaces the system pointer, and stays off on touch or under reduced motion. Under prefers-reduced-motion, the canvas is removed, vines render fully grown with no travelling bud, the leaf-breeze stops, and the wheel’s hand simply points at today — composed, just still.

Passes. Structure and copy first; then the vine engine; a screenshot pass at 1440 and 390 to rebalance the packet grid and wheel type; a contrast and focus-state pass; then this motion pass — idle sway, a travelling growth-tip, the cursor — judged by one question: does the screen still move if I stop scrolling?