포트폴리오 사이트 — 유지보수 스킬
이것은 Mitchell Palmer의 개인 포트폴리오 사이트입니다: Next.js 16(App Router)으로 재구축된 이전 Webflow 사이트입니다. 콘텐츠는 CMS 대신 src/content/ 아래에 일반 TypeScript/JSON/MDX 파일로 저장됩니다. 변경하기 전에 이 문서를 읽어 새로운 패턴을 도입하지 않고 기존 규칙을 따르도록 하세요.
멘탈 모델
src/content/ → 데이터 (무엇을 말할지 — 거의 모든 것은 이것을 수정)
src/app/ → 페이지 (라우팅 — 하나의 폴더 = 하나의 URL, App Router 규칙)
src/components/ → UI 조각 (재사용 가능 — Header, Footer, ProjectCard, PhotoGallery, MDX 임베드)
public/images/ → 정적 에셋, 섹션별로 정리 (site/, projects/, projects/hero/, photography/, icons/)
작업이 "콘텐츠 추가/수정"(프로젝트, 직업, 소개 문구, 사진)이라면 거의 항상 src/content/만 수정합니다. 순수한 콘텐츠 변경의 경우 src/app/ 또는 src/components/는 건드리지 마세요.
콘텐츠 파일 참조
| 파일 | 제어 대상 |
|---|---|
src/content/site.ts | 이름, 태그라인, 이메일, 네비게이션 링크, 소셜 링크 |
src/content/about.ts | 소개 문단, "여정" 스토리, 미션 선언문, 상태 |
src/content/experience.ts | 업무 이력(experience[]), 교육, 기술 목록, 서비스 카드 |
src/content/photography.json | { src, season, location, type } 배열 — /photography의 필터 버튼은 여기에 나타난 값에서 자동 생성됨 |
src/content/projects.ts | 로직만 포함 (projects/의 .mdx 파일을 읽음) — 프로젝트 로드/정렬 방식을 변경하지 않는 한 수정하지 마세요 |
src/content/projects/*.mdx | 프로젝트당 하나의 파일. 프론트매터 + Markdown/MDX 본문. 파일명 = URL 슬러그 |
프로젝트 MDX 프론트매터 형식
---
title: "프로젝트 제목"
description: "1-2문장, 카드 및 상세 페이지 상단에 표시됨."
image: "/images/projects/thumbnail.jpg"
heroImage: "/images/projects/hero/banner.jpg" # 선택 사항, 없으면 `image`로 대체
featured: true # 홈페이지에 표시됨
link: { label: "GitHub 저장소", href: "https://..." }
skills: ["스킬 One", "스킬 Two"]
tools: ["Python", "PostgreSQL"]
# 또는 기술이 많은 프로젝트의 경우 skills/tools 대신 techGroups 사용:
techGroups:
언어 및 라이브러리: ["Python", "pandas"]
통계 방법: ["CUSUM", "Z-Score 분석"]
---
참고: ProjectCard.tsx는 project.tools ?? project.skills를 표시합니다(둘 다 있으면 tools 우선). techGroups는 표시에서 skills/tools와 상호 배타적입니다 — 상세 페이지 사이드바는 둘 중 하나만 표시합니다.
프로젝트 본문 내에서 사용 가능한 두 가지 맞춤 MDX 컴포넌트:
<DashboardEmbed src="https://your-app.streamlit.app/" title="내 대시보드" />
<PdfEmbed src="/path/to/summary.pdf" />
스타일링 규칙
- Tailwind v4, CSS 변수는
src/app/globals.css의:root아래에 정의됨 (예:--color-brand: #486161). 컴포넌트에서 하드코딩된 16진수 값 대신 거기에서 팔레트를 변경하세요. - 두 가지 폰트:
--font-serif(Merriweather, 제목) 및--font-sans(Inter Tight, 본문) — 둘 다layout.tsx에서next/font/google을 통해 로드됨. 빌드 시 인터넷 접근 필요 — 오프라인/샌드박스 환경에서는 실패합니다. .container-page유틸리티 클래스는 모든 페이지에서 일관된 최대 너비 + 패딩을 처리합니다.
건드리지 마세요
node_modules/— git에서 무시됨,npm install로 재생성됨. 절대 git에 다시 추가하지 마세요.- 저장소 루트의
AGENTS.md—next dev에 의해 자동 재생성되며, AI 에이전트에게 이 Next.js 버전의 특정 규칙을 안내합니다. 직접 수정하지 마세요. 덮어쓰여집니다. - 저장소 루트의
CLAUDE.md— 현재는@AGENTS.md(임포트)만 포함합니다. 영구적인 사용자 지정 지침을 추가하려면 새 파일에 작성하고 별도로 참조하세요. AGENTS.md 임포트를 덮어쓰지 마세요. next-env.d.ts— 자동 생성됨, git에서 무시됨.
일반적인 작업, 빠른 참조
새 프로젝트 → public/images/projects/에 썸네일 (+ 선택적 히어로 배너) → src/content/projects/에 새 .mdx 파일 → 완료, 라우팅 코드 불필요.
새 사진 → public/images/photography/에 파일 → photography.json에 일치하는 항목 추가.
소개/미션 수정 → src/content/about.ts, 일반 문자열 편집.
새 직업 항목 → src/content/experience.ts, experience[] 배열 앞에 추가 (배열 순서대로 렌더링되므로 최신순).
네비게이션/소셜 링크 변경 → src/content/site.ts.
빌드 및 확인
npm install # package.json을 변경하는 풀 후 실행
npm run dev # 로컬 개발 서버, 핫 리로드
npm run build # 프로덕션 빌드 — 구조 변경을 푸시하기 전에 실행
npm run lint # eslint 확인
npm run build는 인터넷 접근 없이는 실패합니다(Google Fonts 가져오기) — 완전히 오프라인 환경에서는 예상된 동작이며 코드 버그가 아닙니다.