bruno.exePROJECTScontact.exe
BR95

</br95>

BR95

This website: a Win95 desktop where every window is a real, crawlable URL.

1-bit

original icon suite · every glyph generated, zero colour

byte-level

SEO parity gate on every route

Bayer 4×4

ordered-dither asset pipeline

zero JS

needed to read any public case study on this site

SPECIFICATIONS

ROLESOLO BUILD
DATEJul 2026
TYPEWEBSITE / OS SHELL
STATUSLIVE
STACKnext.js 16 · react 19 · typescript · zustand 5 · tailwind 4 · three.js / r3f · canvas · webaudio +3 more
LINKS[live ↗]
AVAILABILITYbrunojaamaa.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.

== 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 first visit opens on a 3D room at night and dollies into the monitor to boot, the home window is BRpedia, a Wikipedia-style article about its author, and a headset on the desk leads out to a black three.js space where every project is a cube. Underneath: a zustand window manager, a terminal with a virtual file system, an original 1-bit icon suite, a Bayer-dithered asset pipeline, and a resident desktop cat.

br95 desktop: BRpedia open in the home window, taskbar, 1-bit icon suite
a project window: every window is a real crawlable url
terminal.exe: real command registry over a virtual file system
start menu: programs, documents, settings, shut down (it works)
the room after START: a baked 3D desk at night, seen from the seat
monitor view: the live desktop inside the tube, with the room still around it
act 2, outside the box: every project as a cube on a timeline, one selected

== </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.

== </the 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, visible, indexed by a CONTENTS rail. Guard the whole thing with scripts: a byte-level SEO parity gate, tsc, and a Playwright E2E pass on every release. Built solo, first through sprints D1 to D6 and then in versioned releases, with Claude Code doing the implementation and the diffs reviewed by hand.

role & context

Solo build · design, engineering, asset pipeline, and content. The site is its own case study.

== </the story> ==

BR95 is the website this page is part of: Bruno Jaamaa's portfolio, built as a Windows 95 style desktop. The desktop went live in July 2026, replacing an earlier design of the same site, and has been extended since.

The brief he set himself was that every portfolio looks the same, and that the usual fix, a heavy visual gimmick, destroys the two things a portfolio needs most: crawlability and accessibility. So instead of putting a gimmick on top of the content, he 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, three small 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.

Since late September 2026 there is an act on either side of the desktop. A first visit on a desktop browser opens on a 3D room at night with baked lighting: a lamp and a ceiling light that switch, black curtains that draw, a light bar that changes colour, a record player, a keyboard whose keys go down as you type, and a CRT you click to boot, at which point the camera dollies in until the desktop sits inside the monitor with the room still around it. Going the other way, a headset on the desk (or HEADSET.EXE on the desktop) closes two lenses over the view and opens on a black space where every project is a cube on a timeline and BUBBA is rebuilt out of voxels. The home window changed too: it is now BRpedia, a Wikipedia-style article about its author in Wikipedia's night palette. None of the three gates the content: reduced motion and deep links skip the desk, phones never load it, and every route still renders on the server.

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 drawn onto the screen of a 3D CRT monitor (react-three-fiber), which then hands off to the live desktop DOM projected into the screen rect. On a first desktop visit that CRT sits in a 3D room modelled and baked in Blender: one Draco-compressed GLB of about 460 KB, five pairs of lightmaps baked with the lamp on and off, a half-size light layer for the ceiling light, unlit materials that mix the bakes in the shader, and a fallback to the 2D boot if the assets are late. Nothing in the room is lit at runtime; what switches or changes colour (the light bar, the phone, the city outside) is a handful of unlit quads. The space outside the box is a second scene: under the headset's two-lens veil the room's canvas is unmounted before the other mounts, so there is only ever one live WebGL context, and the desktop underneath stays laid out exactly where it was. The older way out is still in the code for the screensaver: the desktop shrinks into the tube and is sampled as a 1-bit grid of roughly 96 by 60 cells. The home route renders BRpedia, an article styled with Wikipedia's own night-mode colour tokens and layout, server-rendered inside the same window frame as every other route. 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 in the shell is generated by repo scripts on a 1-bit budget: 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. The Windows-style chimes are original WebAudio synths; key presses, mouse clicks and the room's tone, CRT, lamp and disk-drive sounds are recorded CC0 samples; the smaller room sounds are synthesised by a script. 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.

The room, the BIOS boot and the headset

A first visit opens on a 3D room you can look around, with things to click. Clicking the CRT plays a BIOS POST on its screen while the camera dollies in, then hands off to the live desktop inside the monitor. Putting on the headset on the desk opens a black space where every project is a cube.

BRpedia

The home window is a Wikipedia-style biography in night mode, with an infobox, a contents list, figures and numbered references, server-rendered like every other route.

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 colour.

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. A case study is a help-viewer document with a CONTENTS rail of anchor links rather than a spawned client window, so the full text is in the DOM, crawled, and readable with JavaScript off · the rail is real <a href="#…"> anchors and the headings are real <h2> ids, so navigation needs no JavaScript either.

DECISION 03

The 1-bit law and the text diet are constraints that do design work: no accent colour in the desktop shell, ≤80-character one-liners, and a six-window cap that doubles as a period-correct out-of-memory gag when you open a seventh. The law has three deliberate exceptions, none of them in the shell's chrome: the orange shutdown screen, the BRpedia article, which keeps Wikipedia's night palette and its blue links, and the 3D desk, which is lit in colour. The space outside the TV goes back to strict black and white.

DECISION 04

The blog was killed rather than left to rot · its routes redirect permanently 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 was 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.

next:

Keep treating the site as a product: more desk toys, and whatever the next hardware generation of BR95 turns out to be.

== HOW IT WAS BUILT ==

Built solo in Claude Code against an implementation-grade sprint plan (D1 to D6), diffs reviewed by hand, 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 the 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 reviews it before it is committed.

== </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 ==

EDITORVS Code
AI TOOLSClaude Code (implementation) · Claude (reasoning + review) · Perplexity (research)
PROCESSTicketing + sprint planning · manual code review · on-device testing · clean commit history
GATEStsc · next build · SEO parity script · Playwright E2E
INFRAGitHub · Vercel, deployed from the CLI

== </full stack> ==

next.js 16 · react 19 · typescript · zustand 5 · tailwind 4 · three.js / r3f · canvas · webaudio · sharp · playwright · claude code