This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build locally
npm run preview
# Build and preview combined
npm run serve- Prefer existing tools over custom code - Use built-in features from installed packages (e.g., Tailwind prose modifiers like
prose-table:border) instead of writing custom CSS or helper functions. Check package documentation for available utilities before creating new code.
When the user says "JobDone", it indicates the current job has been perfectly completed. Follow these steps:
-
Summarize lessons learned from the job, including:
- New technologies discovered or used
- Challenges encountered and how they were solved
- Coding style insights
- Design principles applied
- Architecture changes made
-
Update CLAUDE.md with the lessons learned in the appropriate sections (e.g., add new technologies to "Key Technologies", add new principles to "Development Principles", etc.)
-
Git commit the changes of this job with CLAUDE.md
This is an Astro-based blog migrated from Jekyll. The site is built as a static site and deployed to GitHub Pages.
- Site URL:
https://luffbee.github.io(configured in astro.config.mjs) - Base path:
/(repository root deployment) - Output directory:
dist/ - Language:
zh-CN
- Astro 5 - Static site generator with content collections
- Tailwind CSS v4 - Utility-first CSS via
@tailwindcss/viteplugin - Shiki - Syntax highlighting for code blocks (github-light/github-dark themes)
- astro-pagefind - Pagefind integration for client-side search (indexes on build)
- @pagefind/component-ui - Modal search UI with keyboard shortcuts (Ctrl/Cmd+K)
- @astrojs/rss - RSS feed generation
- @astrojs/sitemap - Automatic sitemap.xml generation
- astro-icon - Icon component system using Iconify (e.g.,
<Icon name="lucide:sun" />with@iconify-json/lucide) - @tailwindcss/typography - Prose styling for markdown content
- remark-math + rehype-katex - LaTeX math rendering at build time
├── .github/
│ └── workflows/
│ └── deploy.yml # GitHub Pages deployment workflow
├── public/
│ └── favicon.svg # Site favicon
├── src/
│ ├── components/
│ │ ├── blog/
│ │ │ └── PostCard.astro # Blog post preview card
│ │ ├── layout/
│ │ │ ├── Header.astro # Navigation bar with search
│ │ │ └── Footer.astro # Page footer
│ │ └── ui/
│ │ └── ThemeToggle.astro # Dark mode toggle button
│ ├── content/
│ │ ├── config.ts # Content collection schemas (Zod)
│ │ └── blog/ # Markdown blog posts
│ ├── layouts/
│ │ └── Layout.astro # Base layout with meta tags, theme init
│ ├── pages/
│ │ ├── index.astro # Homepage (lists all posts)
│ │ ├── about.astro # About page
│ │ ├── blog/
│ │ │ └── [slug].astro # Dynamic blog post routes
│ │ └── rss.xml.js # RSS feed endpoint
│ └── styles/
│ └── global.css # Global styles with Tailwind v4
├── astro.config.mjs # Astro configuration
├── tsconfig.json # TypeScript configuration
└── package.json # Dependencies and scripts
Blog posts are managed through Astro's content collections with Zod schema validation. Each post requires frontmatter:
---
title: Post Title
description: Post description
header: Optional Header Title (defaults to title)
date: YYYY-MM-DD
typst: false # Reserved for future use
---The slug is auto-generated from the filename (e.g., 2024-01-15-post.md → 2024-01-15-post).
Layout.astro - Base page layout
- Renders Header and Footer components
- Initializes dark mode via inline script (prevents flash)
- Manages meta tags (title, description, OpenGraph, Twitter)
- Flexbox layout with sticky footer pattern
Header.astro - Navigation and search
- Site title linking to homepage
- Navigation links: Home, About
- Modal search trigger (
<pagefind-modal-trigger>) with keyboard shortcut support - Theme toggle button
- Sticky positioning with backdrop blur
Footer.astro - Page footer
- Dynamic copyright year
- Built with Astro attribution
PostCard.astro - Blog post preview
- Displays header/title, formatted date (zh-CN), description
- Hover effects with border and shadow transitions
- Description line clamping (2 lines)
ThemeToggle.astro - Dark mode switcher
- Uses astro-icon with Lucide icons (
lucide:sun,lucide:moon) - localStorage persistence
- Falls back to system preference
Dark mode uses a dark class on <html> with special handling:
- Prevents flash - Inline script in
Layout.astrohead applies theme class before render - Persists preference - Uses
localStorage.getItem('theme') - Falls back to system -
window.matchMedia('(prefers-color-scheme: dark)') - Shiki code blocks - CSS custom properties (
--shiki-dark-bg,--shiki-dark) forced via!importantwhen.darkis present
The toggle is in ThemeToggle.astro.
Tailwind CSS v4 Setup (global.css):
- Imports via
@import "tailwindcss" - Typography plugin:
@plugin "@tailwindcss/typography" - Custom CSS properties for theming:
--color-primary: #333333 (light), #e5e5e5 (dark)--color-background: #ffffff (light), #1a1a1a (dark)
Shiki Code Blocks:
- Dual themes: github-light and github-dark
- Dark mode override via
!importanton.dark preselectors - Styled in global.css
Prose Styling:
- Uses
@tailwindcss/typographyplugin - Applied in blog/[slug].astro with
prose-invertfor dark mode
Math equations are rendered at build time using KaTeX via remark-math and rehype-katex plugins configured in astro.config.mjs.
Syntax:
- Inline math:
$E = mc^2$renders as inline formula - Display math:
$$\int_0^\infty e^{-x^2} dx$$renders as centered block
Setup:
- KaTeX CSS loaded from CDN in Layout.astro
- Dark mode support via
.dark .katex { color: inherit; }in global.css
Migration Note: Jekyll used \\(...\\) delimiters which must be converted to $...$ for remark-math compatibility.
Search is powered by astro-pagefind with @pagefind/component-ui for the modal interface. The index is generated during build and written to dist/pagefind/.
Implementation (Header.astro):
<pagefind-modal-trigger></pagefind-modal-trigger>
<pagefind-modal></pagefind-modal>
<script>
import "@pagefind/component-ui";
import "@pagefind/component-ui/css/pagefind-component-ui.css";
</script>Features:
- Click trigger button or press Ctrl+K (Cmd+K on Mac) to open modal
- Press Escape or click backdrop to close
- Dark mode support via
data-pf-themeattribute synced with site theme
Note: The Component UI CSS must be imported via JavaScript, not as a static link (it's bundled from node_modules, not generated by Pagefind CLI).
Generated at /rss.xml via rss.xml.js using @astrojs/rss. Includes all blog posts with title, pubDate, description, and link.
Automatically generated at /sitemap.xml by @astrojs/sitemap integration.
Blog post dates are formatted in Chinese locale (zh-CN):
new Date(date).toLocaleDateString('zh-CN')GitHub Pages deployment via deploy.yml:
- Triggers on push to
masterbranch or manual dispatch - Uses Node.js v20
- Runs
npm cithennpm run build - Deploys
dist/to GitHub Pages