</br95>
This website: a Win95 desktop where every window is a real, crawlable URL.

1-bit
original icon suite · ~30 generated glyphs, zero color
byte-level
SEO parity gate on every route
Bayer 4×4
ordered-dither asset pipeline
6
window cap · the 7th triggers out-of-memory
SPECIFICATIONS
| ROLE | SOLO BUILD |
|---|---|
| YEAR | 2026 |
| TYPE | WEBSITE / OS SHELL |
| STATUS | LIVE |
| STACK | next.js 16 · react 19 · typescript · zustand 5 · tailwind 4 · three.js / r3f · canvas · webaudio +3 more |
| LINKS | [live ↗] |
| AVAILABILITY | brunojaamaa.dev |
“Every developer portfolio looks the same, and the usual fix is a heavy visual gimmick that destroys crawlability and accessibility · exactly the things a portfolio exists for.”
This portfolio itself: a Windows-95-style desktop operating system that is simultaneously a fully server-rendered website.Every window is a real URL, all case-study text lives in the HTML, and a byte-level SEO parity gate guards every release.
== WHAT IS THIS ==
This portfolio itself: a Windows-95-style desktop operating system that is simultaneously a fully server-rendered website. Every window is a real URL, all case-study text lives in the HTML, and a byte-level SEO parity gate guards every release. A zustand window manager, a canvas BIOS boot sequence, a terminal with a virtual file system, an original 1-bit icon suite, a Bayer-dithered asset pipeline, and a resident desktop cat · built solo with Claude Code as the primary dev environment.
== </the problem> ==
Every developer portfolio looks the same, and the usual fix is a heavy visual gimmick that destroys crawlability and accessibility · exactly the things a portfolio exists for. The challenge: build something a visitor screenshots and remembers, that is simultaneously a fast, fully server-rendered, parity-gated website a search engine reads as plain HTML.
role & context
Solo build · design, engineering, asset pipeline, and content. The site is its own case study.
== </my approach> ==
Make the gimmick the shell and the content the OS. The desktop mounts once; every meaningful surface is a real URL rendered into a window frame; all long-form text lives in server HTML behind <details> expanders. Guard the whole thing with scripts: a byte-level SEO parity gate, tsc, and a Playwright E2E pass on every release. Built solo through sprints D1–D6 with Claude Code doing the implementation and every diff manually reviewed.
== </the story> ==
BR95 is the website you are reading this on. The brief I gave myself: every portfolio looks the same, and the usual fix · a heavy visual gimmick · destroys the two things a portfolio actually needs, crawlability and accessibility. So instead of putting a gimmick on top of the content, I made the gimmick the shell and the content the operating system's real file system.
The site boots like a machine, runs a desktop with draggable windows, a taskbar, a Start menu, a terminal, two arcade games, and a resident cat named BUBBA. But underneath, it is a boring-on-purpose Next.js site: the desktop shell mounts once and never remounts, and the App Router renders each route's fully server-rendered content into a window frame. Opening a project window IS navigating to its URL. Closing it navigates back. View source on any project page and the entire case study is sitting there in the HTML.
The whole thing was built solo with Claude Code as the primary dev environment, against an implementation-grade sprint plan (D1 through D6) that ran to well over a thousand lines before the first line of code. It replaced an earlier amber-on-black "SIGNAL" design in a single pivot · the plan for that one is still in the repo too.
== </architecture> ==
The shell reads the route. DesktopShell mounts once in the root layout and holds the wallpaper, taskbar, Start menu, and desktop icons; a registry maps every pathname to window metadata, and the App Router's children render inside the matched window. Routed windows (real URLs) and client-only app windows (terminal, games, dialogs) share one zustand window manager · selector-based re-renders for components, getState() for the imperative modules that run outline-drag and the wireframe minimize/restore animations, no provider.
Boot is a canvas-rendered BIOS POST inside a 3D CRT monitor (react-three-fiber, one GLB), which then hands off to the live desktop DOM projected into the screen rect. The same machinery runs in reverse as "Exit the TV" · a void mode that pulls the camera back out of the screen. The terminal is a pure-logic command registry over a virtual file system built from the same grouping module that drives the desktop folders, so C:\PROJECTS always mirrors what the folder windows show.
Every visual asset is generated by repo scripts on a 1-bit budget: ~30 icon glyphs rasterized on an integer pixel grid and serialized to rect-only SVGs, window thumbnails run through an ordered Bayer 4×4 dither (chosen over Floyd–Steinberg to match the wallpaper's dither signature), custom cursors, and BUBBA's sprite sheet. Sounds are original WebAudio synths · no samples. A phone mode swaps the window manager for a full-screen sheet UI under 768px.
== </key features> ==
Shell-reads-route window manager
A zustand store drives draggable, resizable, minimizable windows · and the routed ones are real URLs with full server-rendered content. Closing a window is navigation.
Byte-level SEO parity gate
A script compares every route against committed baselines: head fields byte-identical, visible text containment-checked, links superset, one h1. Releases fail on unwaived diffs.
Canvas BIOS boot + Exit the TV
Boot renders a BIOS POST on a canvas inside a 3D CRT, then hands off to the live desktop projected into the screen. Void mode runs the same shot in reverse.
Terminal over a virtual file system
A pure-logic command registry (ls, cd, open, cat, hire, and some gags) over a virtual C:\ built from the same grouping module as the desktop folders.
1-bit generated asset pipeline
Icons, dithered thumbnails, cursors, and the BUBBA sprite sheet are all generated by repo scripts · rect-only SVGs on an integer grid, ordered Bayer 4×4 dithers, zero color.
BUBBA.EXE
A resident desktop cat with a state machine: guided tour, contextual one-liners, cursor chase, poke reactions, and strong opinions about being dismissed.
== </key decisions> ==
DECISION 01
Shell-reads-route over SPA-with-fake-URLs was the foundational call. The parity is enforced, not aspirational: a gate script compares every route against committed baselines · title, meta description, canonical, Open Graph, and JSON-LD must be byte-identical; visible text is containment-checked; internal links must be a superset; exactly one h1 per route. The build fails on any unwaived diff.
DECISION 02
Long prose stays in the server HTML. Case studies collapse into a <details> README.TXT expander instead of spawning client windows, so the full text is in the DOM, crawled, and readable with JavaScript off · <summary> gives keyboard and screen-reader semantics for free.
DECISION 03
The 1-bit law and the text diet are constraints that do design work: no color anywhere in the shell, ≤80-character one-liners before the expander, and a six-window cap that doubles as a period-correct out-of-memory gag when you open a seventh.
DECISION 04
The blog was killed rather than left to rot · its routes 301 to /about instead of 404ing indexed URLs. And accessibility rules are hard laws, not nice-to-haves: nothing flashes more than 3×/s, prefers-reduced-motion gets a static everything, and body text is always real DOM.
== </what i learned> ==
A parity gate changes how you build: when every release must produce byte-identical head fields, you structure components so chrome and content never mix.
Constraints are a design system. The 1-bit law and the text diet made a thousand small decisions automatic and gave the whole shell one voice.
The gimmick and the fundamentals are not in tension if the gimmick is the architecture. The Win95 shell is why the SEO is good, not what the SEO survives.
An implementation-grade plan before code · sprints, file-level tasks, locked amendments · is what lets an AI-augmented workflow ship a project this size solo without drift.
Keep treating the site as a product: a guestbook, a live GitHub feed, more desk toys, and whatever the next hardware generation of BR95 turns out to be.
next.js 16 · react 19 · typescript · zustand 5 · tailwind 4 · three.js / r3f · canvas · webaudio · sharp · playwright · claude code
== HOW IT WAS BUILT ==
Built solo in Claude Code against an implementation-grade sprint plan (D1–D6), every diff manually reviewed, byte-level SEO parity gated on every release.
== </the plan> ==
Nothing here was improvised. The repo carries a masterplan with sprint sections that specify the work down to file-level tasks · window store interfaces, drag algorithms, boot state machines · plus "final locked amendments" from hardening rounds that override anything they conflict with. The BR95 desktop replaced a completed amber-on-black design ("SIGNAL") in one planned pivot; both plans are still in the tree.
Each sprint ends the same way: tsc clean, next build clean, and the SEO parity gate green before the sprint is marked done.
== </the loop> ==
Every task runs the same five steps: scope it in the ticket system with acceptance criteria; hand it to Claude Code to architect and implement in the terminal; manually review every diff · read the logic, check the edge cases; test on a real device or browser against the spec; commit with a clean message and move on.
The manual review step is the contract. AI writes most of the code here; a human who understands the system has read every line of it.
== </ai workflow> ==
Claude Code is the primary dev environment for implementation. Claude handles reasoning and design review before code exists · the sprint plans themselves are drafted, argued with, and hardened in conversation. Perplexity covers research. The division of labor is deliberate: the machine does volume, the human does judgment, and the gates catch what both miss.
== </guardrails> ==
Four gates run before anything ships: TypeScript strict compilation, a production build, a byte-level SEO parity script that diffs every route against committed baselines, and a Playwright end-to-end pass over the desktop's critical flows. Content has its own law: never invent facts · anything unverified ships as an explicit placeholder or not at all.
== toolchain ==
| EDITOR | VS Code · Xcode (iOS) |
| AI TOOLS | Claude Code (implementation) · Claude (reasoning + review) · Perplexity (research) |
| PROCESS | Ticketing + sprint planning · manual code review · on-device testing · clean commit history |
| GATES | tsc · next build · SEO parity script · Playwright E2E |
| INFRA | GitHub · Vercel · CI/CD from day one |
LIVE · brunojaamaa.dev