MSN-004 · 2026 · react, typescript, vite, github-pages
This site. LCARS terminal aesthetic from Star Trek Picard, built with React 18 and Vite, deployed to GitHub Pages.
This site started as a design conversation with Claude, then became a Claude Code implementation, then became a codebase I've been maintaining and extending since. The aesthetic is LCARS from Star Trek: Picard — the angular chrome, cut corners, and panel borders. The stack is React 18, Vite, TypeScript, deployed to GitHub Pages.
Before any TypeScript existed, I described the constraints to Claude: monospaced secondary font, display font for headers, CSS custom properties for the entire colour system, two modes (Night Ops and Daylight), no icon libraries. Claude produced a token set and a CSS Grid layout. The cut-corner chrome and scan line animations came from iterating on values together. The output was a design document I could push back on before handing it to an implementation phase.
Early version of the site — the LCARS chrome and panel layout before the content system was built
The value was having something concrete to react to rather than starting from a blank Figma file. The colour system and layout were settled before Claude Code wrote a single line of component code.
All content started in a single TypeScript data file. At a few hundred lines it was manageable. Writing the first real blog post pushed it past the point where editing it felt safe: one post body was fifty lines of nested objects, and the diffs were unreadable.
The refactor split the data by concern and moved every blog post and project into Markdown, each one a file in its own folder alongside its images. A small custom parser maps standard Markdown to the typed blocks the page components render, so there is no heavyweight Markdown toolchain in the build.
Each Markdown file is loaded at build time and the co-located images are fingerprinted for caching automatically. Adding a post is one command and editing one file.
The site deploys to GitHub Pages with the base path set to the repository name. It started on hash-based routing, which needs no server configuration but keeps every route behind a `#`, so shared links and crawlers could not tell pages apart. I moved it to real path-based URLs with a static fallback so deep links still resolve on a static host.
A client-rendered site can look finished and still be invisible to anything that does not run JavaScript: crawlers saw an empty shell and pasted links showed no preview. A build step now writes a static HTML version of every project and post, with the text already in the markup, so crawlers and link-preview bots get real content without running JavaScript. Open Graph metadata gives shared links a title, description, and image. In a browser the app mounts over the static page and the experience stays the same.
Callout boxes, automatic video embedding when a linked file is a video, and promoting the first paragraph to a lede are all handled by the parser. Authors write standard Markdown and the right block type is inferred, with no extra authoring syntax to remember.
Every surface carries a Daylight override. Night Ops is the default, deep navy with amber accents. Daylight flips to a light-background palette, and the toggle lives in the top bar. Red Alert is a third mode from the Tweaks panel, which exists mostly to confirm that alert styling holds up on new surfaces.
Twelve projects and three posts, all in Markdown. The only file that needs editing to publish new content is the `.md` itself. No TypeScript, no imports, no registration steps.
- React 18, React Router 6, TypeScript, Vite - Custom Markdown parser, no unified or remark - `marked` for inline rendering (bold, italic, inline code, links) - `mermaid` and `jsdom` for build-time diagram rendering - GitHub Pages, path-based routing with build-time prerender and Open Graph metadata - Fonts: Antonio (display), JetBrains Mono (mono), Inter (body)