Nineteen choices, four layers, and the trade-off each one carries. Pick a layer to narrow the view, open a technology to read why it is here and what it costs.
01Layers
Select a layer to filter, then open any technology for the reasoning behind it.
Every layer at once — the whole build, top to bottom.
02Technologies
18 of 18 shown
next 16.2.10
The frame: App Router, server components, one build, one deploy.
Shared with Equilibrium
react 19.2.4react-dom 19.2.4
The UI runtime — server components for the shell, client components for anything with a hand on it.
Shared with Equilibrium
tailwindcss ^4
The design system: five palettes generated from one set of semantic tokens.
Shared with Equilibrium
framer-motion ^12.42.2
Every animation on the site, from the headline reveals to the cards that open on this page.
Shared with Equilibrium
lenis ^1.3.25
Smooth scrolling — the inertia under every page.
Shared with Equilibrium
three ^0.185.1@react-three/fiber ^9.6.1
The 3D terrain, written as React components instead of imperative scene code.
Shared with Equilibrium
next-themes ^0.4.6
Palette switching — Paper, Meadow, Forest, Night and Nocturne — as a class on the document.
This site only
lucide-react ^1.23.0
The icon set: arrows, chevrons and status marks.
This site only
clsx ^2.1.1tailwind-merge ^3.6.0
Conditional class names, with later utilities correctly beating earlier ones.
This site only
Platform
Hosting, CDN and deploys. A push to the main branch is a production release.
Shared with Equilibrium
@vercel/blob ^2.6.1
The private store holding the published content document and the studio's uploaded photographs.
Shared with Equilibrium
Built in-house
Editing on the live site: sign in, click any sentence, rewrite it in both languages, publish.
This site only
next-auth ^4.24.14
The Google sign-in that guards the editor — an allowlist of exactly one address.
This site only
typescript ^5
The language everything is written in — including the shape of the content document.
Shared with Equilibrium
eslint ^9eslint-config-next 16.2.10
The lint gate, running the framework's own rule set before every pull request.
This site only
@tailwindcss/postcss ^4
The single build step between the stylesheet and the browser.
Types for the libraries that ship none of their own.
Shared with Equilibrium
Repository scripts
Node scripts that drive a headless browser: language rendering, 3D mounting, performance runs.
This site only
Version numbers on this page are read out of the repository's package.json when the site is built, so they cannot drift from what is actually installed.
03Constraints
The rules underneath the list
01One animation library. Never a second one beside it.
02Colours are named after their role, never after a hex code — that is how five palettes come out of one set of components.
03Every animation has a still version. Reduced motion is a supported way to read this site, not a degraded one.
04Every control carries a visible word. Nothing here is an icon you have to decode.
05Both languages are real addresses, not a switch in the browser — Dutch pages can be found, linked and indexed.
06Nothing merges until the type check, the linter and the production build are all silent.
The same manifest is kept byte-identical in the Equilibrium repository, so either site can be checked against the other. Convergence is the plan; the version gap is the work.
11/18 of these also run on Equilibrium
04Evolution
The making of this site, kept rather than remembered.
Everything above is what this is built with. What follows is how it got here — the questions, the decisions and the things that had to be undone.
13/13 milestones · 96 steps
Foundation
Craft
Commerce
2026 · 08 · 27/Research/In progress/PR #87
This timeline
The record of how the site got here, joined to the record of what it is built with.
Context
The day logs in docs/log/ hold the reasoning behind almost every decision on this site, and no visitor could ever see them. The stack page answers what; nothing answered how or why.
Implementation
An internal archive under TIMEVAULT/, this typed event list, and an Evolution section on the stack page — desktop first, at the owner's instruction, with the full experience established before it is translated to smaller screens.
Result
You are reading it.
Decision
One archive in the repository, one curated timeline on the site, and the same technology keys joining it to the stack.
Why A public history that is written separately from the real one becomes marketing. Sourcing both from the same events means the page can only say what the archive says.
Trade-off The archive has to be updated with the work rather than after it, or the timeline quietly falls behind.
AUG 27The archive: eleven documents, thirteen entries#87
AUG 27Provenance on every event — verified, or reconstructed#87
AUG 27The survey line, with labels in lanes so nothing collides#87
AUG 27The join with the stack, in both directions#87
AUG 27↺Marks that were unclickable, found by a test (a reversal)#87
AUG 27↺Ember as small text at 2.82:1, found by axe (a reversal)#87
2026 · 07 · 10 — 07 · 19
A site from nothing
Ten days from empty repository to a live site on its own domain.
The studio had a name, a logo and no website. The brief was a marketing site that could carry real work later without being rebuilt for it.
Architecture · Reconstructed
2026 · 07 · 20
The studio gets an editor
Click-to-edit on the live site, behind one Google account — instead of a CMS.
Every word on the site was in TypeScript. The owner could not fix a typo without a developer, which is a bad place for a one-person studio to be.
Architecture · Verified
2026 · 07 · 21
The phone stops being a small desktop
Fifteen pull requests in one day, all about the thumb.
Most visitors arrive on a phone. The site was a desktop layout that shrank, with a header nobody could reach one-handed.
UX · Verified
2026 · 07 · 26 — 07 · 27
Fast enough to keep, findable in Dutch
The 3D layer learned to wait, and Dutch got URLs of its own.
The terrain was beautiful and expensive: it built on every page load whether or not anyone would scroll to it. And the Dutch site — the language of nearly every customer — existed only as a client-side switch, so search engines never saw it.
Performance · Verified
2026 · 07 · 30 — 07 · 31
Colour gets a machine to answer to
Ten palettes, and a script that refuses to let any of them fail.
Palettes were being added by eye. A palette that reads well on the designer's screen can still fail a contrast threshold, and nothing on the site was checking.
Accessibility · Verified
2026 · 08 · 01
The build becomes explorable
A stack page you can open, not a list of dependencies.
The sister site had an engine section that named its technologies. The owner asked for something "more interactive and intuitive" — a list of package names says nothing a package.json could not.
Technology · Verified
2026 · 08 · 01
A gate that runs a real browser
Types, lint, contrast, build, and tests that actually open the page.
Two defects had shipped from "it builds". Building is not evidence that anything works.
Architecture · Verified
2026 · 08 · 02
Installed, and continuous
The project you click becomes the page you land on.
Clicking a project card threw the visitor to a new page and made them find their place again. And the site, added to a home screen, was still a browser tab in disguise.
UX · Verified
2026 · 08 · 03
Work that shows its figures
Outcomes, a before-and-after slider, and the client's own words.
The projects were photographs with captions. An ecological garden's argument is what changed — water held, species returned — and none of that was on the page.
Design · Verified
2026 · 08 · 22 — 08 · 24
Found by search, run from a phone
Real structured data, and quotes and invoices behind one sign-in.
The Dutch pages carried English metadata, and the studio's paperwork lived in a spreadsheet.
Architecture · Verified
2026 · 08 · 25
Prices in the open
A page and a from-price per service, and a postcode check that says no.
Seasonal work is standardised and datable, so hiding its price behind a quote form costs the studio the customers who were ready to book.
Design · Verified
2026 · 08 · 25 — 08 · 27
One tree, three renderings
Eleven pull requests to make every menu read the same source.
Eleven services had arrived and the menus could not hold them. The bar, the phone dock and the footer each kept their own list, and the three had already drifted apart.
UX · Verified
2026 · 08 · 27
This timeline
The record of how the site got here, joined to the record of what it is built with.
The day logs in docs/log/ hold the reasoning behind almost every decision on this site, and no visitor could ever see them. The stack page answers what; nothing answered how or why.
Research · In progress
The same history, counted
Measured 2026-08-27 · not typed
Pull requests merged
62
Across 15 days that had a commit in them, between 2026-07-20 and 2026-08-27.
Lines written
63,905
Every insertion this repository has ever recorded, counted across all commits rather than as a snapshot.
Lines taken back out
21,316
That is 33% of everything written. The interesting number on this page: most of what this site is, it is by subtraction.
Lines standing today
22,283
15,843 of interface, 5,588 of logic and data, 852 of styling.
Written, and unwritten
21,316 removed63,905 written
Commits
65
Milestones
13
Steps
96
Reversals
12
Source files
164
Components
54
Routes
17
Services priced
11
Palettes
10
Contrast pairs checked
122
Browser tests
26
Dependencies
25
Alongside 22,283 lines of code sit 7,808 lines of written record — the day logs, the operations manual and this archive. Close to one line of prose for every three of code, which is the whole reason this timeline could be written at all.
05Conceptual
2026-09-04
A UI teardown of gronn.studio against the 21st.dev component catalogue
Not built, and said out loud
Thirteen components, picked on one question: does this close a gap the site has today? Read against the codebase before it was published here — one of the three top findings did not survive that reading, and says so where it stands.
None of this is a commitment. It is a proposal with a date and a source on it, kept where the built things are because a list of intentions nobody can see is a list nobody is accountable to.
First — the ones that earn
Before and after, draggable
Project pages
Now
Each project has one atmospheric photograph and a written description of its phases.
Gap
No visual proof of transformation anywhere — the very thing somebody with a cloudy pond decides to call about.
Checked
This one is wrong as stated, and checking it was worth more than acting on it. The slider already exists: `before-after.tsx`, draggable, keyboard-operable, rendered on case-study pages. The real gap is content, not component — one project of six has a before/after pair filled in, because the rest are still placeholder photography. No package would have fixed that.
Vertical scroll drives a horizontal track with number, title and parallax image. Has a mobile fallback stack.
An enquiry as a conversation, not a button
Start a project
Now
One call to action leading to a form. All or nothing.
Gap
No qualification: you learn at the intake conversation whether this is a balcony pond or half a hectare.
Checked
Half built since. The short form on /contact is four steps and asks what kind of project first; the long design intake behind the dashboard was cut from twenty-four written questions to two, with sixty-seven things to click instead. What is still true is the middle: nothing qualifies a first-time visitor before they choose between the two.
Hover fades the other cards. A quiet effect that makes the grid read as a portfolio rather than a list.
Then — trust and findability
The FAQ that does not exist yet
New — under Services
Now
Nine sections, no FAQ. Every piece of knowledge sits inside running prose.
Gap
"Why is my pond cloudy", "what does a natural pond cost", "does it need a pump" — those are the searches, and question-and-answer is the format that ranks for them.
Checked
Checked and true: no FAQ anywhere in the codebase. Of everything on this page, this is the one that is purely additive — it breaks nothing and competes with nothing.
The pick. Marks the active step from scroll position. Six steps without modification, and the accent can be the brand green.
The working area, literally
New — footer or contact
Now
Projects are in Utrecht, Arnhem, Nijmegen, Zeist, Amersfoort and on the Veluwe. Nowhere does it say where the studio sits or how far it travels.
Gap
A local service with no sense of place. Somebody nearby cannot tell you are nearby; somebody far away books an intake that will not happen.
Checked
True, and sharper than the teardown knew: those six places are placeholder fiction awaiting real projects, while the studio is registered in Limburg. So the map would today be drawn from invented locations — which is the argument for real photography and real projects first, and the map after.
Counts up when it comes into view. Only with real figures — square metres reshaped, litres of rainwater held. Invented numbers here are worse than none.
Layered blur through gradient masks, so photographs dissolve into the ground instead of sitting on it as rectangles.
What not to take
Liquid glass, neon buttons, shaders, chat widgets. They score highly in the catalogue and run straight against "nature is infrastructure". This site is credible because it is restrained.
Watch the weight
There is already a lot of movement on the page. Every pick above adds more. At most one that draws the eye, per page.
Reduced motion
Community components often do not honour it, and scroll-driven timelines and sweeps are exactly what people are troubled by. It gets added during the retokening, not after.
Order
One at a time, and measure before the next. Nothing on this list is worth two of them going in together.