JU.

Meta

Colophon

Everything used to build this site — tools, typefaces, tradeoffs, and the reasoning behind them. Updated when things change.

Framework

App Router, RSC, server actions. The full thing.

Server components let the data layer live where it belongs.

Styling

Vanilla CSS

No Tailwind. Raw CSS custom properties for everything. Total control.

Display typeface. Editorial and warm without being precious.

Mono accent. Labels, captions, code. Distinctive without shouting.

Body text. Clean and legible across sizes.

Data

Hosted on Supabase. Reliable, powerful, mature.

ORM. Schema-first, great DX, doesn't get in the way.

Writing and garden notes. Local files, no CMS needed.

Frontmatter parsing for MDX files.

Animation

For complex spring physics. Used sparingly.

CSS animations

Fade-ups, scroll reveals, keyframes. Most motion is CSS-only.

requestAnimationFrame

Custom tilt cards, cursor glow, canvas background. All hand-rolled.

Infrastructure

Deployment. Zero config, instant previews, edge network.

Image and video storage for the gallery.

Nodemailer

Contact form emails. Simple, direct, no third-party service.

Dev tools

Neovim

Primary editor. LazyVim config.

VS Code

For large projects and pair programming.

Fish shell

Autosuggestions out of the box.

TablePlus

Database GUI. Fast and clean.

Design decisions

No Tailwind

Tailwind trades CSS knowledge for speed. For a personal site where every pixel matters, raw CSS variables give better control and a more cohesive result. The design system lives in one file.

No CMS

MDX files in the repo. Writing is code — version controlled, portable, no vendor lock-in. Frontmatter handles metadata. Works until the content volume makes it painful.

No analytics service

Simple page view counts in Postgres. No third-party scripts, no data leaving the server, no cookie banners. The numbers I care about are already in the DB.

Custom cursor

A small thing that signals intentionality. Auto-disabled on touch devices so it never interferes. The amber ring expanding on links is a subtle interaction affordance.

Server components first

Data fetching happens on the server. Client components are opt-in ('use client'). This keeps bundle size small and database calls close to the source.

No comment system

Reply by email. Slower, but the conversations are better. Email creates a real context, not a reaction.

Source not public yet — but ask if you're curious about something specific. okparajamesuchechi@gmail.com