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/**
.specstory/ .specstory/
.cursorindexingignore .cursorindexingignore
# AGENTS.md symlink
AGENTS.md

139
CLAUDE.md
View File

@ -1,93 +1,108 @@
```
# CLAUDE.md # CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Development Commands ## Development Commands
### Build the project ### Core Development
```bash ```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 ```bash
npm run dev pnpm commit # Auto-generate commit message for staged files
``` pnpm notepad # Quick note-taking utility
### Lint the codebase # Image conversion to AVIF format
```bash pnpm run convert:avif:all # Convert all images
npm run lint pnpm run convert:avif:jpeg # Convert JPEG only
``` pnpm run convert:avif:png # Convert PNG only
### 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
``` ```
## High-Level Architecture ## 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/**` ### 1. Content Layer (`src/content/**`)
2. **Component Layer** - Reusable UI components built with Astro, organized by purpose and functionality Content is managed via Astro's Content Collections API with schema validation defined in `src/content.config.ts`:
3. **Layout & Structure Layer** - Page templates that orchestrate component composition across different sections
### Content Structure - **`blog/`** - Blog posts as MDX files
- All content is stored in Markdown/MDX format within the `src/content/**` directory - Schema: title, description, pubDate, heroImage (optional), featured (boolean), category, tags
- Organized into logical groups: - Posts are sorted by pubDate (newest first)
- `sections/*` - About, Experience, Skills, Featured Project
- `pages/contact.mdx` - Contact form data
- `blog/*.mdx` - Blog posts with structured metadata and frontmatter
### Component Structure - **`sections/`** - Homepage section content (hero, experience, skills, featured-project)
The component architecture follows a consistent pattern with different types of components: - 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: ## Data Flow Patterns
- Featured post (first with `featured: true`)
- Editor's picks (next 3 posts after featured)
- Latest posts (all posts for filtering)
**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 ## Key Technical Patterns
- **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
### Design System Elements ### Image Handling
- **Styling System**: Consistent use of classes like `.animate-on-scroll`, `.stagger-*`, and `.border-white/[0.1]` - Assets in `src/assets/` are processed by Astro (use relative paths in frontmatter)
- **Navigation**: Responsive mobile menu with smooth transitions - Static files in `public/media/` are served as-is (use absolute paths like `/media/file.mp4`)
- **Accessibility**: Proper ARIA attributes, keyboard navigation support - AVIF conversion utility available for optimization
- **Performance**: Optimized image loading and lazy rendering (using AVIF/WebP formats)
### Technical Features ### Styling
- **AI Integration**: Blog post highlights AI/ML usage in technical workflow - Tailwind CSS v4 via Vite plugin
- **Interactive Elements**: Form dropdowns, modal responses for contact form - Custom animation classes: `.animate-on-scroll`, `.slide-up`, `.stagger-*`, `.fade-in`
- **Animation System**: Scroll-triggered animations with staggered effects - Monospace font used for technical labels and metadata
- **Responsive Design**: Mobile-first approach with viewport-specific classes and media queries
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