I’m not a frontend engineer, and I wanted to replace the minima theme on my Jekyll blog with a custom one – no frontend experience required. I used Claude Code to build the entire theme in a single session.

What Was Done

Built a Complete Local Theme

Claude Code read the existing repository structure, fetched the reference design, and produced a full theme from scratch:

  • 4 layouts: default.html, home.html, page.html, post.html
  • 4 includes: head.html (meta, fonts, dark mode flash prevention), header.html (sticky nav, theme toggle), footer.html (social links), scripts.html (theme/nav/mermaid JS)
  • 4 SCSS files: variables.scss (design tokens), base.scss (reset, CSS custom properties for light/dark themes), layout.scss (all components), syntax.scss (code highlighting for both themes)

Design: Inter font, JetBrains Mono for code, purple accent (#6041ed), CSS custom properties for theme switching, responsive down to mobile.

Removed All External Theme Dependencies

Dropped the minima gem from Gemfile, removed theme: minima from _config.yml, and traced every site.minima.* reference across all templates to replace them with direct config paths.

Made Mermaid Diagrams Built-in

Before: required mermaid: true in front matter and <div class="mermaid"> HTML blocks.

After: mermaid loads automatically on every page. Standard ` ```mermaid ` fenced code blocks work out of the box – same syntax as VS Code markdown preview. JavaScript converts Jekyll’s rendered <pre><code class="language-mermaid"> elements into mermaid divs at runtime. All existing posts were refactored to the new format.

Replaced an External Plugin with a Local One

The jekyll-remote-include gem (pulled from GitHub) was replaced with a 38-line local plugin in _plugins/remote_include.rb. The local version adds proper HTTP redirect handling and error reporting. One fewer external dependency.

Homepage with Author Info and Formatted Post Excerpts

Extracted author bio and project links from the about page into a hero section on the homepage. Post excerpts render full HTML content (headings, code blocks, lists) inside a CSS height-clamp with a fade-out gradient, preserving the original article formatting.

Applied 7 Code Review Suggestions from GitHub Copilot

Gave Claude Code the PR URL. It fetched all Copilot review comments and applied them:

  1. Fixed typo: giscuss to giscus
  2. Mermaid dark mode: initializes with matching theme based on site preference
  3. Giscus theme sync: sends postMessage to iframe on theme toggle
  4. Google Analytics: gated behind jekyll.environment == 'production', measurement ID moved to _config.yml
  5. Mobile nav accessibility: added aria-controls and aria-expanded state updates
  6. Social links consistency: unified all templates to use site.social_links
  7. Homepage excerpts: evaluated the suggestion, kept full content with CSS clamp (with rationale)

How the Session Worked

Each prompt built on the previous result:

  1. “Create a new theme like this” – got the base theme
  2. “Article briefs should be at least 10 lines” – adjusted excerpt length
  3. “Keep format/line separators in briefs” – switched to rendering full HTML with CSS height-clamp
  4. “Extract about page info to the homepage” – added hero section with author bio
  5. “Make mermaid support built-in” – refactored mermaid integration and all posts
  6. “Clean up all minima information” – found and removed every trace
  7. “Write a local plugin to replace jekyll-remote-include” – created the plugin
  8. “Apply suggestions from Copilot” – processed 7 review comments

Claude Code ran bundle exec jekyll build after every change and verified the output. When it switched SCSS from @import to @use, it confirmed deprecation warnings disappeared. When it created the local plugin, it verified the about page still rendered correctly.

The Result

The blog now runs on a fully local theme:

  • Dark/light mode with system preference detection and localStorage persistence
  • Sticky header with responsive mobile navigation and ARIA attributes
  • Built-in mermaid via standard fenced code blocks
  • Giscus comments synced with site theme
  • Production-only Google Analytics
  • Syntax highlighting for both light and dark themes
  • Zero external theme or plugin gem dependencies

All source lives in the repository. Deployable on GitHub Pages directly.

Later Iterations

Material 3 Expressive Redesign

In a follow-up session, the entire UI was re-themed with Material 3 Expressive design language – again using Claude Code:

  • Seed color: #6750A4 (M3 purple), generating a full tonal palette for light and dark schemes
  • Typography: switched from Inter to Outfit, mapped to the M3 type scale (Display / Headline / Title / Body / Label)
  • Shape system: pill-shaped tags and nav indicators (border-radius: 9999px), 12px rounded post cards, 16px rounded images
  • Motion: M3 standard and spring easings, hover elevation on post cards (translateY(-2px)), spring scale on social icons
  • Components: floating sticky header with backdrop blur, tonal pill chips for tags, circular icon buttons, surface-container card backgrounds

All changes were pure SCSS – no HTML markup changes required. The M3 token system (60+ CSS custom properties) makes future color scheme changes a single-variable edit.

Mermaid Interactive Zoom

Mermaid diagrams gained a click-to-zoom overlay:

  • Click any diagram to open a fullscreen modal
  • Scroll wheel to zoom (0.1x – 10x), drag to pan
  • Touch support: pinch-to-zoom, single-finger pan
  • Double-click to reset, Esc or close button to exit
  • requestAnimationFrame-based rendering for smooth transforms

Modular M3 Expressive Mermaid Theme

A standalone, reusable Mermaid theme was created at assets/js/mermaid-m3-expressive-theme.js:

  • UMD module – works with ES modules (import), CommonJS (require), or as a global (mermaidM3Expressive)
  • Provides light, dark, and getTheme(isDark) exports
  • Covers all diagram types: flowcharts, sequence, state, class, git graphs, pie charts
  • Colors derived from the same M3 tonal palette used by the site
  • Reusable in any project – just include the script and pass the theme to mermaid.initialize()
// Example usage in another project
mermaid.initialize({
  theme: 'base',
  themeVariables: mermaidM3Expressive.getTheme(isDark)
});

Thoughts

Claude Code’s performance was impressive, and the generated theme suits my needs. I no longer need to wait for someone with frontend experience to build it for me.