이 저장소는 두 개의 정적 페이지가 하나의 데이터 파일(data/profile.json)을 공유하는 구조입니다.
index.html(루트, 기본 페이지) — 포트폴리오.portfolio.js가data/profile.json을 읽어 렌더링합니다. 화면에서는 일반적인 스크롤형 포트폴리오 사이트로 보이고(이력서와 같은 hero/quick-nav 디자인 언어를 공유), 인쇄할 때만 16:9 와이드스크린(PPT와 동일 비율) 가로형 PDF로 섹션 단위 페이지 나눔이 적용됩니다.resume.html— 세로형 이력서.resume.js가 같은data/profile.json을 읽어 렌더링하며, 인쇄 시 A4 세로 PDF로 출력됩니다.
두 페이지는 서로 링크로 연결되어 있지 않은 독립된 페이지입니다. 연락처·경력·프로젝트 등 실제 정보는 data/profile.json 한 곳에만 적으면 되고, 두 페이지가 필요한 필드만 골라서 다른 방식으로 보여줍니다.
포트폴리오에만 필요한 UI 문구는 개인 정보가 아니라 화면 표현이므로 데이터 파일이 아닌
portfolio.js/portfolio.css에서 관리합니다.
resume.html: A4 세로, 일반 이력서처럼 페이지가 자연스럽게 이어집니다.index.html: 인쇄 버튼을 누르면portfolio.css의@page { size: 13.333in 7.5in; }규칙이 적용되어 가로형(16:9, PPT 위젯스크린 비율) PDF로 출력됩니다. About(사진+소개+철학 전체) / Skills / Experience·Project 각 항목별 블록 / Activity가 각각 새 페이지에서 시작하도록.print-page클래스로 표시되어 있습니다(portfolio.js가 Experience·Project 항목마다 자동으로 이 클래스를 붙입니다).- 화면에서는 이 클래스가 아무 스타일도 주지 않아 평범한 스크롤 섹션처럼 보이고,
@media print에서만break-before: page가 적용됩니다. - 내용이 한 페이지보다 길어지는 경우(예: 프로젝트 설명이 아주 길 때) 잘리지 않고 다음 페이지로 자연스럽게 이어집니다 — 고정 높이나
overflow: hidden을 쓰지 않기 때문입니다. - Experience / Project: 화면·인쇄 모두 같은 디자인입니다 — 제목·역할·기간이 한 행에, GitHub/Live 링크는 그 행의 오른쪽 끝에 표시됩니다. Project는 텍스트(설명/My Contribution/관련 링크)와 미디어(사진·영상, 최대 2개까지)가 나란히(병렬로) 배치되고, Experience는 미디어 없이 텍스트만 전체 폭으로 표시됩니다. 인쇄에서는
.project-list/.project-block을 블록 레이아웃으로 고정해 항목마다 독립된 가로 페이지에 출력됩니다(CSS Grid는 인쇄 시 페이지 경계에서 예측 불가하게 잘릴 수 있어 사용하지 않습니다).
- 화면에서는 이 클래스가 아무 스타일도 주지 않아 평범한 스크롤 섹션처럼 보이고,
hero: 이름/역할/태그라인/사진/철학/연락처 — 이력서 헤더 + 포트폴리오 About 섹션에 공용으로 쓰입니다.intro: 소개 문단 — 이력서 Introduce 섹션 전용입니다. (포트폴리오는 이 필드를 사용하지 않습니다 —hero.philosophy가 그 역할을 대신합니다.)experience: 경력 타임라인 — 이력서 Experience 섹션 + 포트폴리오 Experience 섹션(단독)에 공용으로 쓰입니다.project: 프로젝트 목록 — 이력서 카드 + 포트폴리오 프로젝트 쇼케이스(사진/동영상 포함)에 공용으로 쓰이되, 포트폴리오 전용 필드(stack/contribution[].detail/media/links)가 추가로 있습니다.skills: 기술 목록(기술 하나당 항목 하나) — 이력서에는 표시되지 않고 포트폴리오 Skills 섹션 전용으로 쓰입니다.deepDive(포트폴리오 전용): 기술적으로 깊게 파고든 주제 + 관련 링크 목록. 이력서는 이 필드를 사용하지 않습니다.presentation: 발표/세미나 리스트 (이력서 전용 — 현재 포트폴리오에는 대응 섹션 없음)article: 아티클 리스트 (이력서 전용)openSource: 오픈소스 활동 — 이력서 섹션 + 포트폴리오 Activity 섹션에 공용으로 쓰입니다.education: 학력/자격 (이력서 전용)etc: 기타 활동 — 이력서 섹션 + 포트폴리오 Activity 섹션에 공용으로 쓰입니다.footerName: 푸터에 표시되는 이름
아래 project[]의 필드들은 실제 스토리텔링 내용이 없어 대괄호([ ])로 감싼 안내 문구가 들어있습니다. 포트폴리오 화면/인쇄 시 이탤릭체로 눈에 띄게 표시되니, 실제 내용으로 교체해주세요. (이력서에서는 사용하지 않는 필드라 이력서 화면에는 영향이 없습니다.)
contribution[].detail: 해당 기여 항목의 구체적인 과정 (불릿 목록)contribution[].result: 해당 기여 항목의 정량적/정성적 결과 (배열, ★ 표시와 함께 시그니처 컬러로 굵게 강조 표시)media: 빈 배열[]이면 점선 박스(자리표시자)가 표시됩니다. 사진/동영상 경로를 넣으면 실제 미디어로 대체됩니다.
{
"hero": {
"role": "직무/타이틀",
"name": "이름",
"tagline": "한 줄 소개",
"photo": null,
"greetingLead": "기록과 도전을 좋아하는",
"greetingKeywords": ["기록", "도전"],
"philosophy": [
{ "label": "좋아하는 것", "text": "..." },
{ "label": "중요하게 생각하는 것", "text": "..." },
{ "label": "엔지니어로서의 태도", "text": "..." }
],
"contacts": [
{ "label": "Email", "value": "메일주소", "url": "mailto:..." },
{ "label": "GitHub", "value": "github.com/...", "url": "https://..." }
]
}
}role: 이력서 상단 작은 라벨. 포트폴리오는 이 필드를 표시하지 않습니다 (관심사는greetingLead, 지향점은philosophy첫 항목으로 표현).name: 메인 이름 (이력서 H1 / 포트폴리오 About의 인사말 문장 "안녕하세요,{greetingLead}{name}입니다."에 사용 — 이름 부분은 글자 색이 강조색(파란색)으로 바뀌어 다른 텍스트와 구분됩니다)tagline: 한 줄 설명. 이력서 부제로 쓰이고, 포트폴리오에서는 화면에 직접 표시되지 않는 대신philosophy첫 항목의text로 재사용하는 것을 추천합니다 (아래 예시 참고).photo: 현재 포트폴리오에서는 사용하지 않는 필드입니다(프로필 사진을 렌더링하지 않도록 되어 있습니다). 이력서도 이 필드를 사용하지 않습니다.greetingLead(포트폴리오 전용): About 표지 인사말에서 이름 앞에 붙는 문구(예: "기록과 도전을 좋아하는"). 실제 활동에서 뽑아낸 2개 정도의 키워드를 추천합니다. 비워두면 "안녕하세요,{name}입니다."만 표시됩니다. 이력서는 이 필드를 사용하지 않습니다.greetingKeywords[](포트폴리오 전용):greetingLead문구 안에서 강조할 단어 목록(예:["기록", "도전"]). 여기 적은 단어와greetingLead안의 문자열이 일치하면 굵게 + 연한 하이라이터 색이 글자 아래쪽과 겹치도록 자동 강조됩니다(글자색 자체는 그대로). 문구를 바꿔도 같은 단어가 포함돼 있으면 강조가 유지됩니다.philosophy[](포트폴리오 전용): About 화면에서 사진/소개/연락처 바로 아래 이어서 표시되는{ label, text }목록.label은 강조 표시되는 한 줄(제목처럼 크게 표시),text는 그 근거가 되는 활동/경험 설명입니다. 첫 항목을 "OO 엔지니어를 희망하고 있습니다." 같은 지향점 +tagline내용으로 채우면 표지의 역할/한줄소개를 자연스럽게 대신할 수 있습니다. 이력서는 이 필드를 사용하지 않습니다.label이나text를 빈 문자열""로 두면 해당 항목은 렌더링되지 않고 자동으로 건너뜁니다 — 아직 안 쓴 항목은 그냥 비워두면 됩니다.
contacts[]: 연락처 목록 (이력서는 헤더에, 포트폴리오는 About 섹션에 표시)label: 아이콘 자동 선택에 사용(Email/GitHub/LinkedIn은 전용 아이콘)value: 화면에 보이는 텍스트url: 클릭 시 이동할 링크- 이메일은
mailto:someone@example.com - 웹/깃허브/링크드인은
https://...
- 이메일은
{
"intro": {
"text": "소개 문단(긴 텍스트 가능)"
}
}text: 이력서 Introduce 문단 전용입니다. 포트폴리오는 이 필드를 사용하지 않습니다(Hero의philosophy가 이 역할을 대신합니다).
{
"experience": [
{
"period": "2023.01 ~ 현재",
"title": "회사 · 부서",
"role": "직함(예: 인턴)",
"description": "담당 업무를 한 줄로 요약",
"items": [
{ "summary": "업무/성과 1 (한 줄)" },
{ "summary": "업무/성과 2 (한 줄)", "detail": ["구체적인 과정·결과 2-1", "구체적인 과정·결과 2-2"] }
]
}
]
}period: 근무 기간title: 기업-부서 (예: "카카오엔터프라이즈 - 클라우드 솔루션팀")role: 직함/포지션 (뱃지로 표시, 없으면 생략 가능)description: 근무 내용을 한 줄로 요약 (없으면 생략 가능)items[]: 담당 업무 목록. 항목마다summary(한 줄 요약, 이력서에도 그대로 쓰입니다)와detail[](포트폴리오 전용, 구체적인 과정·결과를 담는 서브 리스트, 없으면 생략 가능)로 구성됩니다. 모든 항목에detail을 채울 필요는 없고, 기술적으로 자세히 보여줄 만한 항목에만 선택적으로 추가하면 됩니다.
포트폴리오에서는 Project와 같은 디자인(제목·역할·기간이 한 행, "상세 내용" 라벨 아래 summary+detail[] 목록)으로 표시되어 더 구체적인 내용을 자유롭게 적을 수 있고, 항목마다 독립된 인쇄 페이지를 갖습니다. 이력서에서는 각 items[].summary만 날짜-내용 두 칸 목록으로 표시됩니다(detail은 이력서에 표시되지 않습니다).
{
"project": [
{
"title": "프로젝트명",
"period": "2025.09 – 2025.12",
"role": "인프라 / 배포 담당",
"description": "무엇을/왜 했는지 1~2문장",
"github": "https://github.com/...",
"url": "",
"stack": ["Terraform", "Kubernetes"],
"contribution": [
{ "summary": "기여한 부분 1 (핵심 한 줄)", "detail": ["구체적인 과정 1-1", "구체적인 과정 1-2"], "result": ["정량적/정성적 결과 1-1", "정량적/정성적 결과 1-2"] },
{ "summary": "기여한 부분 2 (핵심 한 줄)", "detail": ["구체적인 과정 2-1"], "result": ["정량적/정성적 결과 2"] }
],
"media": [
{ "src": "./assets/projects/vibot-architecture.png", "alt": "Vibot 아키텍처 다이어그램" },
{ "src": "./assets/projects/vibot-demo.mp4" }
],
"links": [
{ "label": "블로그", "url": "https://blog.llokr.kr/..." }
]
}
]
}title: 프로젝트명period: 기간role: 담당 역할 (파란색 뱃지로 표시). 포트폴리오에서는period와 함께 제목 옆에 표시됩니다.description: 한 줄 설명github: GitHub 링크 (없으면 빈 문자열). 포트폴리오에서는url과 함께 제목과 같은 행 오른쪽에 표시됩니다.url: 라이브 서비스 링크 (없으면 빈 문자열)stack[](포트폴리오 전용): 기술 태그 칩으로 표시contribution[]: 프로젝트에서 기여한 부분을 (요약 + 구체적인 과정 + 결과) 묶음의 목록으로 작성합니다(따로 나뉜 Solution/Result 섹션은 없고, 포트폴리오에서 "My Contribution" 블록 하나에 항목마다 이어서 표시됩니다).summary: 기여한 부분을 한 줄로 (이력서 "주요 성과" 목록에도 이 값이 그대로 쓰입니다)detail[](포트폴리오 전용): 그 항목의 구체적인 과정을 짧은 불릿 목록으로 작성 (문단 대신 서브 리스트로 표시됩니다)result[](포트폴리오 전용, 선택): 정량적/정성적 결과 목록. 각 항목이 ★ 표시와 함께 시그니처 컬러로 굵게 강조된 줄로 표시됩니다
media[](포트폴리오 전용): 프로젝트 하나당 사진·동영상을 최대 2개까지 나란히 넣을 수 있습니다(3개 이상은 앞의 2개만 표시됩니다).- 배열의 각 항목은
{ "src": "경로", "alt": "설명(선택)" }형태이거나, 그냥 문자열 경로만 적어도 됩니다("media": ["./assets/projects/foo.png"]). src의 확장자가.mp4/.webm/.mov/.ogg/.ogv면 자동으로<video controls>로, 그 외에는 이미지로 렌더링됩니다. 파일 확장자로 자동 판별하므로 별도 타입 지정은 필요 없습니다.- 동영상에는 선택적으로
"poster": "썸네일-이미지-경로"를 추가할 수 있습니다. - 인쇄(PDF)에는 동영상을 표시할 수 없어서, 인쇄본에서는 동영상 대신 "웹 버전에서 재생 가능" 링크 텍스트로 대체됩니다. 사진은 그대로 인쇄됩니다.
- 이미지/동영상 파일은
assets/projects/폴더 같은 곳에 넣고 상대 경로로 연결하는 것을 추천합니다. media가 빈 배열[]이면 "사진/동영상을 1~2개 추가해주세요" 문구가 담긴 점선 자리표시자 박스가 대신 표시됩니다.
- 배열의 각 항목은
links[](포트폴리오 전용): GitHub/Live 외에 덧붙이고 싶은 관련 링크(블로그 글, 문서, PR 리뷰 등) — "관련 링크" 블록에 표시됩니다.{ "label": "표시할 텍스트", "url": "링크" }형태이며, 비어 있으면 블록 자체가 표시되지 않습니다.
{
"skills": [
{ "name": "Kubernetes", "context": ["실제로 어디서/어떻게 썼는지 1", "필요하면 2번째 줄도 추가 가능"] }
]
}기술 하나당 항목 하나씩 작성합니다(그룹으로 묶지 않습니다). 화면에서는 name이 왼쪽, context가 오른쪽에 나란히 표시됩니다.
name: 기술명 (왼쪽 컬럼에 표시)context[]: 숙련도 바 대신, 실제 사용 경험을 설명하는 문장들 — 리스트(불릿) 형식으로 여러 줄 작성 가능합니다. 이력서에는 표시되지 않습니다.
{
"deepDive": [
{
"title": "Kubernetes 파드 스케줄링이 실패하는 원인 파헤치기",
"summary": "왜 이 주제를 팠는지, 무엇을 알아냈는지 2~3문장 요약",
"links": [
{ "label": "블로그", "url": "https://blog.llokr.kr/..." },
{ "label": "스터디 노트", "url": "https://..." }
]
}
]
}title: 파고든 주제 제목summary: 간단한 소개(왜 파고들게 됐는지, 무엇을 알아냈는지)links[]: 블로그 글/스터디 노트 등 관련 링크 (label+url, 없으면 생략 가능)- 배열이 비어 있으면 Deep Dive 섹션 전체가 (nav 링크까지) 숨겨집니다. 이력서는 이 필드를 사용하지 않습니다.
{
"presentation": [
{
"year": "2025",
"title": "발표 제목",
"items": ["세부 내용 1", "세부 내용 2"]
}
]
}year: 연도 또는 날짜title: 발표 제목items[]: 세부 내용 불릿 (없으면 생략 가능)- 이력서 전용 필드입니다. (포트폴리오 슬라이드에는 아직 대응 슬라이드가 없습니다.)
type 필드로 기여(contribution) 와 직접 제작(project) 두 가지를 구분합니다.
기여한 오픈소스 (type: "contribution")
{
"type": "contribution",
"project": "org/repo-name",
"title": "PR 제목 또는 기여 내용",
"url": "https://PR-또는-커밋-링크",
"status": "Merged"
}project: 기여 대상 레포 (왼쪽 컬럼에 표시)title: PR 제목 또는 기여 내용url: PR / 리뷰 / 커밋 링크 (없으면 빈 문자열)status:Merged/Open/Closed등
직접 만든 오픈소스 (type: "project")
{
"type": "project",
"name": "my-project",
"description": "프로젝트 한 줄 설명",
"github": "https://github.com/llokr1/my-project",
"url": "",
"status": "Active"
}name: 프로젝트명 (왼쪽 컬럼에 표시)description: 무엇을 하는 프로젝트인지 한 줄 설명github: GitHub 레포 링크url: 라이브 데모/배포 링크 (없으면 빈 문자열)status:Active/Archived등
{
"education": [
{
"date": "2021.03 - ",
"title": "가천대학교 컴퓨터공학과",
"subtitle": "재학 중"
}
]
}date: 입학/취득 연도 (왼쪽 컬럼에 표시)title: 학교명 또는 자격증명subtitle: 재학 중 / 졸업 / 취득 등 상태 (없으면 생략 가능)- 이력서 전용 필드입니다.
{
"article": ["글 제목 1", "글 제목 2"]
}문자열 배열로 작성합니다. 이력서 전용 필드입니다.
etc는 아래 두 형태를 모두 지원합니다.
- 문자열 배열(기존 방식):
{
"etc": ["기타 1", "기타 2"]
}- 객체 배열(추천: 날짜 포함):
{
"etc": [
{ "date": "2026", "text": "사내 기술 세미나 분기별 운영" },
{ "date": "2025.11", "text": "클라우드 아키텍처 리뷰 멘토링" }
]
}date: 화면에서 굵게 표시되는 날짜/기간(예:2026,2025.11,2024.03~2024.06)text: 활동 내용(문장/불릿 1개)
{ "footerName": "홍길동" }별도의 Hero 헤더 없이 **About이 곧 첫 화면(표지)**입니다. About → Experience → Project[] → Skills → Deep Dive → Activity(openSource+etc) 순서로 고정되어 있으며, 각 섹션이 data/profile.json의 어떤 필드를 쓰는지는 위 표를 참고하세요. 섹션 순서를 바꾸려면 index.html의 <main> 안 섹션 순서와 portfolio.js의 renderPortfolio 함수를 함께 수정하면 됩니다.
- Experience:
data.experience를 단독 섹션으로 표시합니다 (이력서와 같은 데이터, 포트폴리오에서는 더 이상 Activity 안에 묶여있지 않습니다). - Deep Dive (포트폴리오 전용):
data.deepDive[]— 기술적으로 깊게 파고든 주제 + 블로그/스터디 노트 링크. 아래 필드 가이드 참고. - Activity:
openSource와etc를 "오픈소스 기여" / "활동" 두 그룹으로 나눠서 보여줍니다 — 오픈소스 기여가 동아리·커뮤니티 활동과 섞여 구분이 안 되는 문제를 해결하기 위함입니다.
Experience, Project, Skills, Deep Dive, Activity(그리고 Activity 안의 "오픈소스 기여"/"활동" 그룹)는 뒷받침하는 데이터가 비어 있으면 섹션 자체가 렌더링되지 않고, 우측 nav 링크도 함께 숨겨집니다 (예: 지금은 deepDive가 비어 있어 Deep Dive 섹션과 nav의 "DEEP DIVE"가 보이지 않습니다). 내용을 채우면 자동으로 다시 나타나므로, 아직 준비되지 않은 섹션은 그냥 빈 배열로 두면 됩니다.
#about 섹션 하나에 다음이 모두 이어서 표시됩니다 (강제로 화면을 나누지 않고 자연스럽게 스크롤됩니다):
.about__top: "안녕하세요,{hero.greetingLead}{hero.name}입니다." 인사말(h1, 한 줄로 표시, 이름만 크게 강조) +hero.contacts(이메일/GitHub/LinkedIn/블로그). 프로필 사진은 렌더링하지 않습니다..hero__philosophy:hero.philosophy목록 (바로 아래 이어서 표시) — 첫 항목에 지향점(예: "OO 엔지니어를 희망하고 있습니다.")을 넣어 표지에서 뺀 역할/한줄소개를 대신합니다.
이력서(resume.html)는 기존처럼 헤더에 역할·이름·소개·연락처를 한 번에 표시합니다 (철학 목록은 포트폴리오만의 연출입니다).
- 프로필 이미지:
assets/profile/MyProfile.png- 교체 시 파일명/경로를 유지하면 코드 수정 없이 반영됩니다.
- 다운로드(인쇄) 버튼 아이콘:
assets/icons/LightModeDownloadButton.svg