Skip to content
Live · Free

NOVEN

Shipped solo, with AI

This site. A static Next.js build that presents the other products, teaches from them, and is the only one on this page you can inspect without leaving it — the screenshot below is a page you are two clicks from. Content is typed data files, so adding a build or a lesson is an edit, not a deploy script.

You’re looking at it

Start a conversation
The builds index of this site: a panel defining the four status labels — live paid, live free, pre-launch, unlisted — above the REON card showing its pre-launch badge and the figures 48,000+ markets, 1,200+ metros and 3,100+ counties, with the Reef Frags Select card beginning below it.

The builds index of this site, which is where the status vocabulary is defined before it is used. Captured 10 August 2026.

What’s in it

  • Design tokens in a single @theme block; every text color measured against the lightest surface it can appear on, not against the darkest
  • The builds showcase lights whichever product is nearest the middle of the screen, and hands that over to the cursor the moment you point at one
  • The lesson library groups itself into tracks when you have not asked for anything, and flattens to a plain grid the moment you filter
  • Reduced motion is a path, not a switch — the shaders never mount, the counters render their final value, and the layout is identical either way

The hard calls

Three sections that were one section

The constraint
Lessons, Tracks and Courses were three of six nav items, and all three listed the same eleven lessons. Two of the four tracks held exactly the same lessons as a course module. None of the eleven videos existed.
What I did
Folded all of it into one library page where the tracks are sections, and deleted the course data model entirely. Twenty routes went with it.
What it cost
The scaffolding for selling a course — isFree, priceLabel, checkoutUrl — went too. It is in git history and comes back in one commit, but it is not sitting there ready any more.

A screenshot is a document, not a texture

The constraint
Two different off-the-shelf gallery components were tried for the builds section. Both are built for portrait photography and crop to fit: measured against the REON shot, a collapsed accordion panel showed 24% of its width, and a scroll-expanding frame rendered the headline as “th for every / ket” halfway through its reveal.
What I did
Rejected both and built the frame here, which grows to full bleed with object-contain so nothing is ever cropped.
What it cost
A more compact and more conventional gallery was available, and this section is longer than one would have been.

Every dependency has to earn the download

The constraint
The component libraries that make this kind of site look good each drag in a WebGL runtime. three.js is 23 MB installed, ogl is 423 KB, and it is easy to end up with both.
What I did
three.js was deleted the day its globe was cut. ogl stayed only once a single component was using it. Everything else — the scroll lighting, the cursor spotlight, the entrance stagger, the glare on the screenshots — is CSS plus one requestAnimationFrame handler.
What it cost
The most obviously impressive effects on offer were the ones that cost the most, so the site is quieter than it could be.

Where AI helped, and where it didn’t

Where it saved me days

  • Every line of it was written with AI and then read back line by line — the reading is the job, and it is where the rest of this list comes from
  • Vendored components arrived the same way every time: hooks with no “use client”, no reduced-motion handling, an unclamped device pixel ratio. Learning that shape once turned each new one into a checklist
  • Measuring instead of guessing — panel geometry, glare opacity, contrast ratios, bundle weight — was consistently faster than arguing about how something looked

Where it was confidently wrong

  • A stylesheet rule that looked correct and never applied once: .prose-noven sat in @layer components, and the typography plugin registers .prose in utilities, which the cascade orders afterwards. It was invisible until a white background made white headings obvious
  • An animated counter that settled on 47,261 where the data said 48,000 — a spring approaches its target and never arrives. It read as a real number in every screenshot
  • A page-weight measurement that was confidently wrong in the reassuring direction, because Chromium shares its disk cache across browser contexts and the second run was reading empty response bodies as real ones

What’s still rough

  • Eleven lessons are written out and none are recorded — every youtubeId is a placeholder, and those pages are noindex until they are not
  • content/services.ts is still gated, so every “work with me” button opens a prefilled email rather than a page
  • garage-trades.png is a 943 KB PNG where every other screenshot on the site is WebP
Status
Live · Free

Public and published. Nothing to buy on it yet.

What changes it
A domain of its own, and the first lesson that points at a video instead of a placeholder.

NOVEN’s own figures.

Page routes
11
Runtime deps
9
Home page JS
593 KB

What’s on it

  • Builds
  • Lessons
  • Blog
  • About

What this proves I can build

The transferable part.

  • Design systems built from tokens, with contrast measured rather than judged by eye

  • Content models a non-developer can edit safely, where a typo fails the build instead of reaching the page

  • Sites that carry real motion and still ship under a megabyte, with every dependency argued for

  • Accessibility held across every route and breakpoint as a standing check, not a launch-day audit

If you need one of these built, that is the work I sell.

Newsletter

The email list opens soon

I'm still setting up the newsletter. Subscribe on YouTube in the meantime and I'll announce it there first.