Building the Site
The meta-thread — designing, building, and shipping andrewvoirol.com. Micro-interactions, finding a voice, and the content pipeline that makes it all work.

Editorial portfolio layout — typography-first design with interactive background canvas.

Building a portfolio site is its own project. This thread captures the decisions, experiments, and infrastructure that turned a blank Next.js app into a living workshop — from jelly-physics dark mode toggles to the three-tier atomic content model that generates this very page.
Timeline
Added a theme toggle to the site today. It's got a spring animation on the knob, twinkling stars in the dark mode track, and sun rays that rotate in. The real engineering was underneath — ThemeProvider with localStorage persistence, anti-FOUC inline script, and a custom event system so the globe canvas can pick up theme changes without re-mounting. The animation is fun but the architecture is the part I'm proud of.
Built the entire site in a single evening — 12 commits between 5pm and midnight. Started with create-next-app, ended with a live portfolio on Vercel with Cloudflare DNS, dynamic OG images for social sharing, an ambient dot-matrix globe in the hero section, and the first Gemma 4 benchmark showcase self-hosted with interactive charts. The OG images went through three iterations — dynamic edge-rendered, then static PNGs, then back to dynamic with proper caching — because X kept showing blank cards. Added Cloudflare Web Analytics in the same session because I wanted real traffic data from day one, not retroactive instrumentation. Twelve commits, zero planning docs, one git push to production. The site existed in my head at 5pm and on the internet by midnight.
Threw out the default Next.js styling and rebuilt the entire visual identity in one pass — editorial typography, warm color palette, and intentional spacing. The site had been functional but generic. The overhaul gave it a personality: large serif headings, tight tracking, generous whitespace, and a palette that leans warm instead of the cold blue-gray that every developer portfolio defaults to. Also pushed the quantization data — the inverted ladder where Q4 beats Q8 beats F16 — into the benchmark charts, which gave the Gemma 4 page its first genuinely surprising visual. The design system commit was the moment the site stopped looking like a template and started looking like mine.
Rewrote my own site copy because my AI told me I sound like LinkedIn. Replaced every 'intersection of' with something a human would actually say. Added 'vibe coder' to my identity line. Replaced emoji placeholders with animated SVGs. Introduced workshop-style borders that are intentionally imperfect — dashes that fall short, grids that aren't quite grids. The whole point is that the site should feel like a builder's workshop, not a corporate portfolio. Turns out the hardest part of building in public is sounding like yourself. The second hardest part is accepting that 'imperfect on purpose' is a real design decision and not laziness.
Rebuilt the content architecture from the ground up — log entries are now the only thing I write, and everything else composes from them. Thread pages render entries in expandable accordions. Project pages show a "How This Got Built" provenance section. The same MDX renders identically whether you're reading a standalone log entry, expanding it inside a thread timeline, or seeing it in a project's build history.
Along the way, fixed three production bugs that had been hiding: tables and headings had zero CSS styling site-wide, the ScoreBadge component showed "NaN%" on the Gemma 4 page because MDX doesn't pass numeric JSX props correctly, and the Edge Lab log entry was parented to the wrong thread. Cleaned up the content relationships, documented the atomic model, and built the publishing skill that generated this very entry.
Tested the publish-content skill on this project and immediately realized: the agent writes like an agent, not like a person. The skill could read transcripts, identify inflection points, and produce structurally correct MDX — but the voice was wrong. "In this session, we implemented the core pipeline" is how a bot talks. "55 AI Studio apps and no idea what to do with them" is how I talk. The fix wasn't a prompt tweak — it was a rule: read 3-5 existing log entries in content/log/*.mdx before drafting new ones. Match the voice. Bold declarative lead sentences. First person. Specific data. No "phase," no "implementation," no "session," no "execute."
The /learn session after this conversation codified it: the batch-project-pipeline skill now requires voice calibration from existing entries before any drafting begins. The skill also got the cascading provenance format — conversations feed log entries, log entries build threads, threads compose projects. Every claim traced to a specific conversation ID and step range. The meta-lesson: automating content production is easy; automating content quality requires teaching the agent what good looks like by example, not by instruction.
Spent an entire day stress-testing the batch pipeline across multiple projects — verifying provenance claims, auditing conversation transcripts, and building the skill that would let me run batch-project-pipeline on any Antigravity project folder and get draft content out the other end. The conversation hit 844 steps and 39 user turns, the longest single session in this project's history. The pipeline reads the conversation index, separates user conversations from subagent noise, deep-reads transcripts for inflection points, and drafts log entries in the site's voice. When the first dry-run produced 376 lines of speculative recommendations based on conversation counts instead of conversation content, I killed it and rewrote the skill to require evidence-backed provenance chains. Every log entry now cites specific conversation IDs and step ranges. Every thread traces back to its source entries. The skill went from 0 to 662 lines across 5 working days — a codified version of everything I learned about turning build history into portfolio content.
Three skills now compose the full pipeline: ai-studio-export-rescue (342 lines) for cleaning raw exports, batch-project-pipeline (662 lines) for autonomous content production, and publish-content for the interactive human-in-the-loop workflow. The 55 apps aren't just sorted anymore — they're feedstock for a content machine that reads its own build transcripts and writes about what happened.
Pushed 135 log entries and 35 threads to the site in a single session — the batch pipeline's first real production run. The site went from a handful of manually written entries to a living archive overnight. Each entry was mined from git history and Antigravity conversations, backdated to real build timestamps, and tagged with the canonical vocabulary. Then 18 more gap-fill entries and a QC review pass. The thread count jumped from 13 to 48. The log page went from something you'd scroll through in 10 seconds to something with actual depth. The build still passed with zero errors, which meant the content validation script was doing its job — every thread: reference resolved, every tag was canonical, every MDX file parsed clean. Five months of build history, compressed into one evening of pipeline output.
Ran a portfolio-wide media capture across all 48 threads and 8 projects, then redesigned the homepage featured section from scratch. The old featured layout was a flat list. The new one uses a 1+2 hero grid — one large card with the primary project image, two smaller cards flanking it, then the rest below. Added a 5th featured item (Personal Pomodoro) and swapped MUJŌ's hero image for one that actually shows the ink physics. Promoted Building the Site itself from a thread to a project, which felt appropriately meta. By end of day: every thread had at least one image, every project had a hero capture, and the homepage looked like it was designed instead of generated. Twenty-two commits in 18 hours.