Update .gitignore, CLAUDE.md, and Experience component

- Add AGENTS.md symlink to .gitignore for tracking documentation.
- Expand CLAUDE.md with core development commands, utilities, image conversion scripts, and detailed architecture sections.
- Modify src/components/sections/Experience.astro to reflect updated schema and presentation.
This commit is contained in:
Nicholai 2025-12-18 15:08:04 -07:00
parent b10690e123
commit d336705c5c
2 changed files with 80 additions and 62 deletions

3
.gitignore vendored
View File

@ -33,3 +33,6 @@ src/utils/.env
.specstory/**
.specstory/
.cursorindexingignore
# AGENTS.md symlink
AGENTS.md

139
CLAUDE.md
View File

@ -1,93 +1,108 @@
```
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Development Commands
### Build the project
### Core Development
```bash
npm run build
pnpm dev # Run development server
pnpm build # Build the project
pnpm preview # Build and preview with Wrangler
pnpm deploy # Build and deploy to Cloudflare Pages
```
### Run development server
### Utilities
```bash
npm run dev
```
pnpm commit # Auto-generate commit message for staged files
pnpm notepad # Quick note-taking utility
### Lint the codebase
```bash
npm run lint
```
### Run tests
```bash
npm run test
```
### Build and preview a specific page
```bash
npm run build:page <page-name>
```
### Preview the blog section
```bash
npm run preview:blog
# Image conversion to AVIF format
pnpm run convert:avif:all # Convert all images
pnpm run convert:avif:jpeg # Convert JPEG only
pnpm run convert:avif:png # Convert PNG only
```
## High-Level Architecture
The website follows a clean separation of concerns with three distinct layers:
This is an Astro-based portfolio and blog site deployed on Cloudflare Pages. The architecture follows a content-driven approach with three distinct layers:
1. **Content Layer** - Markdown/MDX files containing structured content located in `src/content/**`
2. **Component Layer** - Reusable UI components built with Astro, organized by purpose and functionality
3. **Layout & Structure Layer** - Page templates that orchestrate component composition across different sections
### 1. Content Layer (`src/content/**`)
Content is managed via Astro's Content Collections API with schema validation defined in `src/content.config.ts`:
### Content Structure
- All content is stored in Markdown/MDX format within the `src/content/**` directory
- Organized into logical groups:
- `sections/*` - About, Experience, Skills, Featured Project
- `pages/contact.mdx` - Contact form data
- `blog/*.mdx` - Blog posts with structured metadata and frontmatter
- **`blog/`** - Blog posts as MDX files
- Schema: title, description, pubDate, heroImage (optional), featured (boolean), category, tags
- Posts are sorted by pubDate (newest first)
### Component Structure
The component architecture follows a consistent pattern with different types of components:
- **`sections/`** - Homepage section content (hero, experience, skills, featured-project)
- Each section has a custom schema for its specific data needs
- Experience entries include systemId, status, dates, company, role, achievements, links
- Skills entries include domain, tools, proficiency
**Core Components**: Reusable elements like `BlogCard`, `FormattedDate`, and `Navigation`
- **`pages/`** - Page-specific content (contact form configuration)
- Includes form labels, social links, subject options
**Section Components**: Page-specific sections like `Experience`, `Skills`, and `FeaturedProject`
### 2. Component Layer
Components are organized by purpose:
**Layout Components**: Base templates that provide shared styling and structure (e.g., `BaseLayout`, `BlogPost`)
- **Core UI**: `BlogCard`, `FormattedDate`, `Navigation`, `Footer`, `GridOverlay`
- **Blog-specific**: `BlogFilters`, `ReadingProgress`, `TableOfContents`, `PostNavigation`, `RelatedPosts`
- **Section components**: `Hero`, `Experience`, `Skills`, `FeaturedProject`
### Component Relationships
### 3. Page & Layout Layer
- **Layouts**: `BaseLayout` (shared structure), `BlogPost` (blog template)
- **Routes**: Static routes in `src/pages/` with dynamic blog routes via `[...slug].astro`
**Blog Section Flow**: The blog page (`src/pages/blog/index.astro`) fetches all blog posts via `getCollection()` and organizes content into three distinct sections:
- Featured post (first with `featured: true`)
- Editor's picks (next 3 posts after featured)
- Latest posts (all posts for filtering)
## Data Flow Patterns
**Content Rendering Pattern**: All components use a consistent data model where properties are passed through props. For example, `BlogCard` receives title, description, pubDate, and heroImage as parameters.
### Blog Index (`src/pages/blog/index.astro`)
1. Fetches all posts via `getCollection('blog')`
2. Sorts by pubDate (newest first)
3. Identifies featured post (first with `featured: true` or fallback to latest)
4. Renders featured hero + filterable grid of all posts
5. Extracts unique categories for filter UI
### Data Flow Architecture
### Individual Blog Posts (`src/pages/blog/[...slug].astro`)
1. Uses `getStaticPaths()` to generate all blog post routes
2. For each post, calculates:
- Previous/next posts (by date)
- Related posts (matching category or shared tags, limited to 3)
- Reading time (based on word count, 200 wpm)
3. Passes everything to `BlogPost` layout which handles headings, navigation, related posts
### Content Collections
All content follows the schema validation pattern:
```
Content Files → Astro Content API → Page Components → UI Components → Final Render
MDX file → src/content.config.ts schema → getCollection() → Component props
```
- **Content Collection**: Configured in `src/content.config.ts` with schema validation for frontmatter
- **Data Fetching**: Uses Astro's content API to load and transform data from Markdown/MDX files
- **Component Composition**: Pages assemble components based on fetched data, creating dynamic and responsive layouts
## Key Technical Patterns
### Design System Elements
- **Styling System**: Consistent use of classes like `.animate-on-scroll`, `.stagger-*`, and `.border-white/[0.1]`
- **Navigation**: Responsive mobile menu with smooth transitions
- **Accessibility**: Proper ARIA attributes, keyboard navigation support
- **Performance**: Optimized image loading and lazy rendering (using AVIF/WebP formats)
### Image Handling
- Assets in `src/assets/` are processed by Astro (use relative paths in frontmatter)
- Static files in `public/media/` are served as-is (use absolute paths like `/media/file.mp4`)
- AVIF conversion utility available for optimization
### Technical Features
- **AI Integration**: Blog post highlights AI/ML usage in technical workflow
- **Interactive Elements**: Form dropdowns, modal responses for contact form
- **Animation System**: Scroll-triggered animations with staggered effects
- **Responsive Design**: Mobile-first approach with viewport-specific classes and media queries
### Styling
- Tailwind CSS v4 via Vite plugin
- Custom animation classes: `.animate-on-scroll`, `.slide-up`, `.stagger-*`, `.fade-in`
- Monospace font used for technical labels and metadata
The architecture is highly maintainable with clear separation of content from presentation. The use of Astro's data API and component system enables dynamic content generation while maintaining a consistent visual language throughout the site.
```
### Deployment
- Cloudflare Pages adapter configured in `astro.config.mjs`
- Image service set to "compile" mode
- Platform proxy enabled for development
## Blog Post Creation Workflow
1. Create `.mdx` file in `src/content/blog/` (filename becomes URL slug)
2. Add required frontmatter: title, description, pubDate
3. Optionally add: heroImage, featured, category, tags
4. Write content using Markdown/MDX with embedded JSX/HTML
5. Images can reference `src/assets/` (relative) or `public/media/` (absolute)
## Utility Scripts
- **`src/utils/convert-to-avif.js`** - Converts images to AVIF format with quality options
- **`src/utils/git-commit.js`** - Auto-generates commit messages from staged changes
- **`src/utils/notepad.js`** - Quick note-taking utility