Colophon
Every decision has a reason. Most of them are documented here. This is the page for the curious.
01 \u00b7 Stack
Framework
Next.js 15 · App Router · TypeScript · Vercel deployment
Styling
Tailwind CSS v4 · @theme syntax · CSS custom properties · No tailwind.config.ts
Animation
Framer Motion · all transitions named · AnimatePresence · useSpring · whileInView
Fonts
Fraunces (display/headings) · DM Sans (hero name) · Plus Jakarta Sans (body/UI) · All via next/font/google
Database
Supabase · PostgreSQL · Row Level Security · 7 tables · Real-time · SSR client
Auth
Cookie-based admin auth · No third-party · ADMIN_PASSWORD env var · 7-day session
CMS
Custom-built · lives at /admin · Fragments · Projects · Shelf · Now · About · Guestbook · Posts
Images
Cloudinary · signed upload · auto WebP/AVIF · admin-only · next/image optimization
Resend · guestbook notifications · publish alerts · signer confirm · hello@ojasmutreja.com
Sound
Howler.js · 6 sounds · ambient room tone (4% volume) · toggleable · off by default
OG Images
next/og · edge runtime · per-page + per-article dynamic · 1200×630 · Fraunces loaded inline
Playground
Font Pairing Explorer · Contrast Checker (WCAG 2.1) · Reading Time + Flesch score
02 \u00b7 Animations
Page transition curtain · #1C1C1A wipe · 500ms cover · 500ms reveal · GPU composited
SVG feTurbulence grain · 4% opacity · mix-blend overlay · fixed position · baseFreq 0.65
Custom cursor · 8px dot + 32px ring · useSpring 80ms lag · pointer:fine devices only
Rotating hero ring · SVG textPath · 18s spin · speeds on hover · "Thinker · Developer · Designer · Maker · Reader"
Canvas stars + constellations · mulberry32 seeded PRNG · 80 stars · gradient mask fade · pauses when tab hidden
Horizontal scroll cards · scroll-snap-type: x mandatory · overflow-x scroll
Card hover · translateY -6px · filter drop-shadow · 400ms · GPU layer · never clipped
Scroll-triggered reveals · whileInView · opacity + y · once · staggered
Cursor idle 1200ms → text appears · no bubble · caption size · pointer:fine only
Howler.js · ambient loop · transition whoosh · hover ticks · click sounds · nav toggle
03 \u00b7 Design
Type
Typography scale rooted at 128px, divided by φ (1.618) recursively: 128 → 79 → 49 → 30 → 18.5 → 11.5px. The same ratio governs all spacing tokens. Nothing is arbitrary.
Ojas
display · 128px
Mutreja
title · 79px
Builder
heading · 49px
Designer
sub · 30px
Software and design, built for humans.
body · 18.5px
The Texture · SVG feTurbulence · 4% opacity
caption · 11.5px
DM Sans: weight 300, letter-spacing 0. Exception: footer “ojasmutreja.com” uses weight 400.
Fraunces: weight 400, letter-spacing -0.02em. Exception: hero intro uses weight 300.
Plus Jakarta Sans: weight 400. Body, UI, captions.
Color
Background
#EFEFED · Warm gray · not pure white
Ink
#0A0A0A · Near black
Surface
#E8E8E6 · Slightly darker warm gray
Drape
#1C1C1A · Transition curtain
Muted
#9A9A98 · Secondary text
Ghost
#C4C4C2 · Borders · dividers
04 \u00b7 Philosophy
The content management system is custom-built and lives at /admin — a password-gated interface for writing fragments, articles, and posts; managing projects, shelf items, and guestbook entries; and editing every part of this site that changes. No third-party CMS. No Notion integration. No markdown files committed to git. Everything lives in a Supabase database and updates instantly without a redeploy.
The /now page changes in under a second. The guestbook sends an email when someone signs. Articles get their own reading page with a full-bleed banner. Posts show a 1:1 image carousel. The whole system was built in one session, prompt by prompt, with obsessive attention to what each piece should feel like to use.
The /colophon itself is the only page that never needs a CMS. It updates when the code does. That feels right.
05 \u00b7 /now movement
The /now page follows the format proposed by Derek Sivers — a single page that answers the question “what are you focused on right now?” Updated whenever the answer changes, not on a schedule. More at nownownow.com.
06 \u00b7 Credits
Fraunces by Undercase Type and Octavia Saul. Plus Jakarta Sans by Tokotype. Next.js by Vercel. Framer Motion by Matt Perry.