Skip to main content
Welcome. This site supports keyboard navigation and screen readers. Press ? at any time for keyboard shortcuts. Press [ to focus the sidebar, ] to focus the content. High-contrast themes are available via the toolbar.
serard@dev00:~/cv

The Journey: Building This Site with Claude

A PDF, a prompt, and a week of conversations. This is the full story of how this site came to exist — every decision, every iteration, every course correction.

Act 1 — The Spark (March 18, 3 AM)

It started with a PDF resume and a simple prompt: "Can you turn this into a website?"

Not a template. Not a WordPress site. Something that reflects how I think — terminals, modules, typed APIs, infrastructure-as-code. Claude took that context and generated an initial commit: 28 files, 5,620 lines, a complete SPA with markdown rendering, sidebar TOC, syntax highlighting, and a dark terminal aesthetic.

The architecture decision was immediate and deliberate: vanilla JavaScript, zero frameworks. The site loads markdown via fetch(), renders with marked.js, highlights code with highlight.js, draws diagrams with Mermaid. No React, no bundler, no build step beyond TOC generation.

Why? Because the problem doesn't need a framework. And because the simplest tool that solves the problem is always the right tool — the "anything-as-code" principle applied to itself.

What Landed on Day 1

  • Terminal window aesthetic — macOS / Windows / Linux title bar variants, persisted to localStorage
  • Four color themes — dark, light, dark high-contrast, light high-contrast — all via CSS custom properties
  • Markdown-driven content — YAML frontmatter, one file per experience entry, one file per blog post
  • Sidebar TOC — collapsible sections, scroll spy, resizable with drag handle
  • Mermaid diagrams — inline rendering with click-to-zoom fullscreen overlay
  • Deep linking#path/to/file.md::heading-slug with hierarchical slug generation

The collaboration pattern established itself immediately: I describe intent, Claude proposes an implementation, I review and redirect, we iterate. This pattern held for every session that followed.

Act 2 — Content Explosion (March 18–20)

The site was a shell. Now it needed content — and not just job listings. I was simultaneously building the FrenchExDev ecosystem with Claude: 20+ .NET projects, 7 CLI binary wrappers, DSL frameworks, a DDD code generation pipeline. Each project deserved its own article.

Over three days, the blog section grew from zero to 14 technical articles:

Article What It Documents
BinaryWrapper The flagship project — wrapping CLI binaries into typed C# APIs
Result Pattern Composable error handling with Result<T, TError>
Builder Pattern Source-generated async object construction
DDD & Code Generation Attribute-based domain modeling → generated repositories
QualityGate Roslyn-powered static analysis for CI/CD
Docker Compose Bundle Typed models from 32 Docker Compose schema versions
Modeling & Metamodeling The M0–M3 meta-metamodel theory
Feature Tracking Requirements as code, compile-time traceability
Infrastructure as Code The PowerShell module ecosystem
CMF Series 13-part deep dive into a Content Management Framework

The CMF series alone required Claude to design a parent-child navigation system — 13 markdown files with parent: cmf frontmatter, rendered as a collapsible sub-tree in the sidebar. This was the first architectural challenge that pushed the SPA beyond "simple markdown viewer."

Each article was written in tandem with the code. I'd implement a Roslyn source generator, then describe it. Claude would help refine both — sometimes the article revealed a design flaw, sometimes the code revealed a better way to explain the concept.

Act 3 — Static Generation (March 22)

The SPA worked beautifully — unless you were a search engine. View Source showed an empty <div>. Google's JavaScript rendering is slow and unreliable. A CV site that recruiters can't find defeats its purpose.

The constraint was non-negotiable: keep the SPA feel while making every page work without JavaScript.

In 5 hours, Claude built a Node.js static site generator (scripts/build-static.js) that:

  1. Pre-renders every markdown file into a standalone HTML page in public/
  2. Converts Mermaid diagrams into static SVGs using Mermaid's Node.js API
  3. Injects per-page <title>, meta descriptions, Open Graph tags, JSON-LD structured data
  4. Generates a sitemap.xml and robots.txt
  5. Adds <noscript> content blocks with full article text

The result: two versions of the same site sharing the same CSS and content.

  • index.html — the SPA, for humans who want the interactive experience
  • public/*.html — static pages, for crawlers and no-JS users

Both served from the same deployment. Vercel's routing sends crawlers to static pages, humans get the SPA.

Act 4 — Polish & Production (March 22–23)

With the foundation solid, we entered the refinement phase. This is where the site went from "working prototype" to "professional product." Every issue was discovered through actual use — testing on mobile, switching themes, sharing links.

Mobile Responsive Overhaul

The sidebar wasn't just "not great" on mobile — it was broken. Clicking the hamburger opened the sidebar but there was no backdrop, no way to close it by tapping outside. The OS selector (macOS/Windows/Linux buttons) took up precious space on small screens.

Fixes:

  • Semi-transparent backdrop behind the mobile sidebar, closes on tap
  • OS selector hidden on viewports under 768px (still accessible on desktop)
  • Touch-friendly tap targets throughout

High-Contrast Theme Bug

A subtle but critical bug: the "Available for Hire" CTA button was invisible in dark high-contrast mode. The CSS variable --accent-green was set to #ffffff in the high-contrast dark theme, and the button text was also white. White on white.

I noticed it while testing themes and said: "regarde en dark/dark, To Hire n'est plus visible."

Claude diagnosed it by reading computed styles via Chrome DevTools, then added a targeted CSS override:

[data-color-theme="highcontrast"] .cta-hire-me {
  background: #3fb950;
  color: #000000;
  border: 2px solid currentColor;
}

A one-line color assumption made the primary CTA disappear for accessibility-conscious users — exactly the audience most likely to use high-contrast mode. Ironic.

The sidebar footer evolved from a bare email link to a full identity section:

  • Three GitHub profile links (personal, FrenchExDev org, Diem project)
  • Open Graph and Twitter Card meta tags for link previews
  • Contact email with one-click copy button
  • Keyboard shortcuts modal (? key)

Search (Ctrl+K)

A client-side full-text search over all markdown content, triggered by Ctrl+K or ⌘K. Searches titles, headings, and body text from toc.json. Results are navigable with arrow keys — the entire interaction works without touching the mouse.

Act 5 — The PDF CV (March 22–23)

Here's where the site's journey loops back to its origin.

The site started from a PDF resume. Now it needed to generate a PDF from the site content — a proper CV that recruiters can download, print, and circulate.

Claude built generate_cv_pdf.py using ReportLab, reading the actual markdown content files to construct a 5-page professional CV:

Page 1    Header + Professional Experience (Schneider, BIM&CO, Qwant, CrossKnowledge)
Page 2    Experience continued (AUSY, Freelance, Diem, Tequila Rapido, AB Croisière)
Page 23  Technical Skills (.NET, Design Patterns, SOLID, Testing, Design-Time Engineering)
Page 3    Requirements Engineering, DevOps, Education, Soft Skills
Page 4    FrenchExDev Ecosystem (.NET libraries, CLI Wrappers, Infrastructure, Applications)
Page 45  PowerShell Modules (40 modules, curated into 3 categories)
Page 5    C# Professional Home Lab

The Iteration Cycle

The PDF didn't arrive in one shot. It was built through conversation:

  1. First pass — basic layout, pulled data from markdown files → "la partie technique, je pense qu'il y a des choses à faire"
  2. Enriched technical section — I pointed Claude to the skills page on localhost; Claude browsed it via Chrome and added Design-Time Engineering, SOLID principles, Requirements Engineering
  3. Reordered sections — I specified: "header + expériences pro + Technical skills + Educ + Soft skills + FrenchExDev + HomeLab C#"
  4. Print-friendly URL"after CV Website, write down the http link, because when printed it is useful" → added (stephane-erard-cv.vercel.app) in gray after the link
  5. Case sensitivity fix — the download button pointed to Stephane_Erard_Cv.pdf but the file was Stephane_Erard_CV.pdf. Vercel is case-sensitive. Invisible on localhost, broken in production.
  6. PowerShell modules"dans le CV tu peux ajouter un subset des projets PoSh sur FrenchExDev sur github" → Claude browsed the GitHub org, found 40 PowerShell repos, organized them into Developer Environment / Infrastructure & Containers / Services & Networking

Each iteration made the PDF more accurate. The final version reflects the actual content of the site, not a hand-crafted summary. The data flows from markdown → website → PDF, keeping everything in sync.

The Technical Stack

At the end of the journey, the site consists of:

Source Files
├── index.html                     15 KB   SPA shell
├── css/style.css                  35 KB   1,800+ lines, 4 themes × 3 OS styles
├── js/
│   ├── app.js                     42 KB   SPA: routing, TOC, scroll spy, preloading
│   ├── app-static.js              30 KB   Static site progressive enhancement
│   ├── markdown-renderer.js       18 KB   Marked.js + Mermaid + code blocks
│   ├── search.js                   6 KB   Ctrl+K full-text search
│   └── theme-switcher.js           8 KB   Color mode + OS style persistence
├── content/                               12,500+ lines of markdown
│   ├── 5 top-level pages                  About, Skills, FrenchExDev, Home Lab, Roadmap
│   ├── 9 experience entries               One per role
│   └── 14 blog articles                   Including 13-part CMF series
├── scripts/
│   ├── build-toc.js                       Scans content/ → toc.json
│   ├── build-static.js                    Pre-renders public/*.html + Mermaid SVGs
│   └── workflow.js                        Interactive dev CLI
├── generate_cv_pdf.py             685 lines  ReportLab PDF generation
└── Stephane_Erard_CV.pdf          5 pages    Generated from content

Zero framework dependencies. Three rendering libraries (marked.js, highlight.js, mermaid.js). One CSS file. Deployed on Vercel with automatic static/SPA routing.

The Collaboration Model

Looking back, the pattern was remarkably consistent across every session:

I bring the intent, Claude brings the implementation. I bring the taste, Claude brings the speed.

Some concrete examples:

I Said Claude Did
"Turn my CV into a website" Generated 28 files, chose terminal aesthetic from my profile
"Add a blog section" Designed markdown pipeline with Mermaid, cross-refs, code highlighting
"The CMF needs 13 parts" Built parent-child TOC system with collapsible trees
"regarde en dark/dark, To Hire n'est plus visible" Diagnosed white-on-white via computed styles, fixed with targeted CSS
"créer un pdf CV à partir de mon site" Built 685-line ReportLab script reading from actual markdown files
"regarde pourquoi le téléchargement ne fonctionne pas" Found case-sensitivity bug in Vercel deployment
"ajouter un subset des projets PoSh" Browsed GitHub org, catalogued 40 repos, organized into 3 categories

The tools mattered. Claude Code (the CLI tool) gave Claude direct file access, so edits were immediate. Claude in Chrome let Claude browse localhost and GitHub to verify visual changes and gather data. The combination meant I could describe a problem in French, and Claude could diagnose it by actually looking at the running site.

What This Journey Demonstrates

This site is not the product of a single prompt. It's the product of dozens of conversations across multiple sessions, each building on the last. The architecture evolved through use:

  • The SPA was built first because I needed to see the content
  • The static generator was added when SEO became a requirement
  • The accessibility audit happened when I ran Lighthouse on a whim
  • The PDF CV was born from a practical need — recruiters want PDFs
  • The PowerShell section grew because I realized the GitHub repos told a story the CV was missing

Every feature was added because a real problem surfaced. Nothing was planned upfront. The roadmap emerged from the work, not the other way around.

That's how I build software. Iteratively, with clear feedback loops, using the simplest tools that solve the problem. This site is both the demonstration and the proof.


Total elapsed time: ~1 week of iterative sessions. Total custom code: ~4,800 lines (JS + CSS + HTML + Python). Total content: 12,500+ lines of markdown. Framework dependencies: zero. The whole thing started with a PDF and a prompt.