🔗 https://yjh-dev.github.io/portfolio/
검색 엔진 색인은 막아 두었습니다(
noindex+robots.txt). 링크를 아는 사람만 실질적으로 접근합니다 — 다만 접근 제한은 아닙니다.
프레임워크·빌드 도구·외부 요청 없이 HTML · CSS로 만든 단일 페이지입니다. 다크 단일 테마로 고정했습니다.
index.html 마크업 + 스타일 + 스크립트 + 글꼴 (외부 요청 0)
img/ 스크린샷·다이어그램·도서표지 22장 (WebP, 합계 약 525KB)
font/ OFL.txt (라이선스 전문) + 심어 넣은 글꼴의 원본 파일
og.png 링크 공유용 미리보기 이미지 (1200×630)
이 페이지는 Pretendard 를 파일 안에 담고 있습니다. 앞선 판에서는 글꼴 이름만 적어 두었는데, 그 글꼴이 깔려 있지 않은 컴퓨터(대부분의 윈도우)에서는 맑은 고딕으로 대체되면서
- 굵기 단계가 무너지고 (맑은 고딕은 400·700 두 단계뿐, 이 페이지는 560·620·640·650·660을 씁니다)
- 큰 제목의 자간을 좁혀 놓은 부분에서 글자가 서로 붙어 뭉개지고
- 글자 폭이 달라져 한 화면에 맞춰 둔 계산이 어긋났습니다
그래서 이 페이지에 실제로 쓰인 글자 474자만 남긴 가변 폰트(87KB) 를 만들어 CSS 안에 직접 넣었습니다. 파일을 그냥 더블클릭해 열어도, 어느 컴퓨터에서 열어도 같은 글자로 보입니다.
- Pretendard 1.3.9 · SIL Open Font License 1.1 ·
font/OFL.txt - 가변 축(
wght45–930)을 그대로 남겨 굵기 단계가 전부 살아 있습니다 - 페이지 글자 436자를 폰트 cmap과 대조해 빠진 글자 0 확인
같은 마크업이 화면 폭에 따라 두 가지로 읽힙니다.
| 폭 | 읽는 방향 | 구조 |
|---|---|---|
| 1024px 이상 | 왼쪽 → 오른쪽 | 한 장이 정확히 100vw × 100svh. scroll-snap-type: x mandatory 로 화면 단위로 멈춥니다 |
| 1024px 미만 | 위 → 아래 | 같은 27장이 그대로 세로로 쌓입니다. 스냅 없이 평범하게 읽힙니다 |
전환 지점은 64rem 한 곳뿐입니다. .deck 의 flex-direction 이 column → row 로 바뀌면
슬라이드가 필름스트립이 되고, 애니메이션 축도 세로에서 가로로 함께 넘어갑니다.
| 입력 | 동작 |
|---|---|
| 마우스 휠 (세로) | 한 장씩 옆으로 — 세로 델타를 가로 이동으로 바꿉니다 |
| 트랙패드 좌우 제스처 | 브라우저 기본 동작 그대로. 가로 델타가 더 크면 손대지 않습니다 |
| ← → · PageUp/Down | 한 장씩 |
| Home / End | 처음 / 마지막 |
| 화면 좌우 원형 단추 | 한 장씩. 양 끝에서는 사라집니다 |
| 상단 내비게이션 | 해당 장으로 바로 |
| 터치 스와이프 | 스냅 스크롤 기본 동작 |
JavaScript는 넘기기 · 현재 위치 표시 · 확대 보기 세 가지에만 씁니다. 레이아웃과 애니메이션은 전부 CSS입니다.
| 장면 | 세로 모드 | 가로 모드 |
|---|---|---|
| 첫 화면 제목 | 줄 단위로 아래에서 밀려 올라옴 — overflow:hidden 마스크 + translate 108% |
동일 |
| 본문 등장 | 아래에서 올라오며 선명해짐 (view()) |
오른쪽에서 밀려 들어오며 선명해짐 (view(inline)) |
| 스크린샷 등장 | 아래에서 위로 닦임 — clip-path: inset(0 0 100% 0) |
왼쪽에서 오른쪽으로 닦임 — clip-path: inset(0 100% 0 0) |
| 숫자 | CSS만으로 0부터 카운트업 — @property --v(정수) + counter() |
동일, 축만 inline |
| 표지 배경 숫자 | — | 화면보다 느리게 따라오는 시차 (entry → exit 전 구간) |
| 진행 바 | scroll(root block) |
.deck 의 이름 붙은 타임라인 scroll-timeline: --page inline 을 timeline-scope 로 끌어올려 연결 |
| 화면 교체 | — | 지나간 화면이 뒤로 물러남 — opacity .14 · scale .94, animation-range: exit 0% exit 100% |
| 계단식 등장 | 순서대로 조금씩 늦게 | 순서대로 조금씩 늦게 |
| 기술 스택 | 두 벌을 이어 붙여 이음매 없이 순환 | 동일 |
| 확대 보기 | <dialog> + View Transitions로 썸네일이 원본으로 이어짐 |
동일 |
한 화면 안의 요소가 한꺼번에 나타나면 밋밋합니다. 사용자 지정 속성이 상속된다는 점을 이용해,
자리 순서를 --d(세로 순번) · --d2(가로 순번)로 매기고 .rise 가 그 합을 물려받게 했습니다.
.slide > .inner > *:nth-child(2){--d:1}
.hrow > *:nth-child(3){--d2:2}
.rise{--dd:calc(var(--d,0) + var(--d2,0))}
.rise{animation-range-start:entry calc(6% + var(--dd) * 4%);
animation-range-end: entry calc(62% + var(--dd) * 4%)}가장 늦은 요소도 entry 94% 에 끝나므로, 화면이 멈추는 순간(entry 100%)에는 전부 제자리입니다.
27장 × 모든 .rise 요소의 정지 상태 opacity 와 filter 를 실측해 확인했습니다.
모든 모션은 @supports로 감쌌고, 감싸지 않은 기본 상태에서 콘텐츠가 그대로 보입니다.
- 스크롤 애니메이션 미지원 → 요소가 처음부터 제자리에 보임 (사라지지 않음)
- 카운트업 미지원 → 최종 숫자가 그대로 표시됨 (
--v기본값이 목표치) scroll-snap미지원 → 스냅 없이 자유롭게 가로 스크롤- JavaScript 꺼짐 → 27장이 가로로 나열된 채 스크롤바·트랙패드·터치로 그대로 읽힘
prefers-reduced-motion→ 모션 정지, 화면 이동은behavior:'auto'
가로 모드에서는 한 장이 화면을 넘칠 수 없습니다. 넘치면 잘립니다. 그래서 글자 크기를 폭뿐 아니라 높이도 함께 보고 정합니다.
--t-display: clamp(2.8rem, min(10.6vw, 15.5svh), 9.5rem);
--t-h2: clamp(1.95rem, min(5.2vw, 8.4svh), 4.8rem);세로 화면(휴대폰 스크린샷) 줄도 같은 방식으로, 폭과 높이 중 먼저 걸리는 쪽에 맞춥니다.
--ph: min(52svh, 32rem,
calc((var(--avail) - (var(--n) - 1) * var(--rgap)) / var(--n) * 2.166));--n 은 그 줄에 놓인 장수입니다. 5장짜리 줄과 2장짜리 줄이 같은 규칙으로 정해집니다.
프로젝트마다 01~04 를 배경에 크게 깝니다. 제목을 방해하지 않으면서도 읽히도록:
| 값 | |
|---|---|
| 색 | #ffffff26 (검정 위) · #ffffff2b (어두운 회색 위) — 배경과 밝기 차 36단계 |
| 크기 | min(44vw, 32rem) |
| 자리 | 넓은 화면은 오른쪽에서 4vw 안쪽, 세로 가운데 |
| 움직임 | 화면이 들어오는 동안에만 오른쪽에서 밀려 들어오고, 멈추면 정확히 제자리 (animation-range: entry 0% entry 100%) |
| 좁은 화면 | 제목과 겹치지 않도록 오른쪽 아래 구석으로, 크기와 밝기를 낮춤 |
스크린샷은 눌러서 확대할 수 있는데, 그걸 알 방법이 없었습니다. 마우스를 올리면 오른쪽 아래에
돋보기 표시가 뜨고 커서가 zoom-in 으로 바뀝니다. 터치 기기에는 hover 가 없으므로 항상 옅게 띄웁니다.
아이콘은 글꼴에 의존하지 않도록 인라인 SVG로 그렸습니다.
- 주소 동기화 — 화면을 넘길 때마다 주소가
#dolkong처럼 바뀝니다. 중간을 복사해 보내면 받는 사람도 그 자리에서 열립니다. (세로 모드에서는 브라우저의 앵커 스크롤을 방해하지 않도록 건드리지 않습니다) - 탭 키 — 화면 밖 요소에 초점이 가면 그 화면으로 맞춰 세웁니다.
- 인쇄 —
Ctrl+P하면 가로 필름스트립이 세로 A4 27쪽으로 펴집니다. 흰 배경 · 검은 글씨로 바뀌고 머리띠·이동 단추·흐르는 띠는 빠집니다. 실제로 PDF로 뽑아 쪽수와 본문 추출까지 확인했습니다. - 공유 미리보기 —
og.png(1200×630). 배포 후<meta property="og:image">를https://…/og.png처럼 절대 주소로 바꿔야 카카오톡·슬랙에서 뜹니다.
숫자 화면 한 장만 배경을 흰색으로 뒤집었습니다. 그 위에서는 머리띠·이동 단추·진행 바가
검정으로 바뀝니다. 현재 장이 바뀔 때 body 에 .on-light 를 붙였다 떼는 방식입니다.
공개 링크에 올라가는 화면이라 아래를 이미지 자체에서 지웠습니다. 원본은 포함하지 않습니다.
| 화면 | 지운 것 |
|---|---|
| AppBox 빌드 내역 | 고객사(앱) 이름 · 앱 코드 · 요청자 이름 · 요청자 이메일 · 관리자 계정 |
| AppBox 고객사 상세 | 고객사명 · 앱 코드 · 소유자 · 이메일 · 관리자 계정 |
| AppBox 푸시 발송 상세 | 고객사명 · 앱 이름 · 프로젝트 코드 · 관리자 계정 |
| 돌콩 백오피스 | 닉네임 · 이메일 · Provider ID · 프로필 사진 |
| 돌콩 신고·차단 | 상대 사용자 닉네임 |
서버 IP · 포트 · 자격증명은 문서·화면 어디에도 넣지 않았습니다.
브라우저를 띄워 27장을 한 장씩 재면서 잡은 것들입니다.
| 증상 | 원인 | 조치 |
|---|---|---|
| 백오피스 화면이 최대 54% 잘려 나감 | 비율이 제각각인 세 장(1.78 · 1.31 · 0.92)을 같은 크기 상자에 넣고 object-fit: cover 로 채움 |
폭을 비율에 비례해 나눠 주는 방식으로 교체 — 높이는 같고 잘림 0 |
| 모든 스크린샷이 가로로 6px씩 눌림 | button 의 기본 안쪽 여백(1px 6px)을 지우지 않아 이미지가 그만큼 좁아짐 |
button { padding: 0 } |
| 윤사무실 화면 4% 잘림 | .shot.desk 에 aspect-ratio: 16/9 를 강제 (원본은 1100×643 = 1.71) |
원본 비율 그대로 |
| 좌우 이동 단추가 본문 글자를 덮음 | 단추는 화면 끝에서 22px, 본문은 64px — 단추 폭 48px과 겹침 | 넓은 화면의 좌우 여백을 max(--gut, 5.6rem) 로. 상단 머리띠도 같은 여백을 써서 세로선이 맞습니다 |
| 휴대폰에서 가장 작은 글자 14.5px | --t-small 최솟값이 0.9rem |
0.95rem (15.2px) 이상으로 |
| 이동 단추가 기술 스택 띠 위에서 뭉개짐 | 반투명 배경이라 뒤 글자가 비침 | 불투명 배경 + 실선 테두리 |
| 표지의 큰 숫자가 거의 안 보임 | 흰색 3.5%(#ffffff09) — 배경과 밝기 차가 256단계 중 8단계뿐. 게다가 시차 애니메이션이 멈추는 위치를 밀어내 01 의 1 이 화면 밖으로 잘려 나감 |
15%(#ffffff26, 밝기 차 36단계)로 올리고, 시차를 들어오는 동안만 돌게 바꿔 멈추는 자리를 고정 |
Chromium 실측 — 2560 · 1920 · 1600 · 1536 · 1512 · 1440 · 1366 · 1280 · 1152 · 1100 · 1024 · 820 · 430 · 390 · 360px, 높이는 650 / 720 / 768 / 800 / 900 / 1080 / 1200 으로 나눠서.
- 27장 전부 세로·가로 넘침 0 (한 장씩
.inner의 실제 높이를 슬라이드 안쪽 높이와 대조) - 이미지 21장의 렌더 비율을 원본 비율과 대조 — 잘림 0
- 형제 요소 겹침 0 · 15px 미만 글자 0 ·
overflow:hidden안에서 잘리는 글자 0 - 콘솔 에러 0 · 요청 실패 0 · 실제 가로 스크롤 발생 0
- 로컬 서버로도 띄워 21장 전부 응답 확인 (404 0)
file://로 그냥 열었을 때 글꼴이 적용되는지 별도 확인 (대체 글꼴과 글자 폭이 다른지 실측)- 휠 · ← → · Home/End · 좌우 단추 · 내비게이션 앵커를 실제로 입력해 이동 결과 확인
- 확대 보기 열림/닫힘, 상단 위치 표시(
03 / 26)와 내비게이션 강조 동기화 확인 - 이미지 23장 전부
alt·loading="lazy"· 크기 지정
저장소 이름을 yjh-dev.github.io 로 만들면 주소가 https://yjh-dev.github.io 가 됩니다.
git init && git add . && git commit -m "portfolio"
git branch -M main
git remote add origin https://github.com/yjh-dev/yjh-dev.github.io.git
git push -u origin main저장소 → Settings → Pages → Source: Deploy from a branch → main / (root)
@layer · @property · counter() · scroll-snap · 스크롤 구동 애니메이션(view(inline) · scroll()) ·
scroll-timeline + timeline-scope · View Transitions · :has() · clip-path ·
word-break: keep-all · text-wrap: balance / pretty · clamp() + min() · svh ·
aspect-ratio + object-fit · <dialog> · 논리 속성
이력서·경력기술서의 실측 수정에 맞춰 페이지 내용을 고쳤습니다.
| 항목 | 전 | 후 |
|---|---|---|
| 총 경력 | 4년 3개월 | 4년 1개월 (meta · 표지 · 카운트업) |
| 모바일파트너스 | 2024.05 · 2년 2개월 | 2024.09 · 1년 10개월 |
| Go · Node.js 기간 | 2년 2개월 | 1년 10개월 |
| 기여 표현 | "전담했습니다" | 레거시는 팀 / 신규 스택은 단독 — 저장소 커밋 99% 근거 |
| 경력 카드 | 3장 | 4장 — 프리랜스(인슈플러스 · ISMS-P) 추가, 종료일 역순 정렬 |
| 돌콩 | 기간 없음 | 2026.03 – 2026.07 |
| 투인원 | "Google Play에 올렸습니다" | App Store와 Google Play 양대 스토어 (제목은 2줄 유지, 스토어명은 본문으로) |
| 기술 스택 | Flutter · NestJS · Electron 누락 | 추가, 백엔드 행 신설, 인프라 → 인프라 · 보안 |
| 확대 닫기 | .vh 1×1px (보이지 않음) |
44×44 원형 버튼, close() 연결로 역방향 View Transition 유지 |
| 랜드마크 | nav · main |
header 추가 |
| 확대 버튼 | 접근명이 이미지 설명뿐 | aria-label="확대해서 보기" |
| og | og:url 없음 |
추가 (배포 시 절대 주소 입력 필요) |
.roles 그리드는 3열 고정에서 2열(≥60rem) / 4열(≥82rem) 로 바꿨습니다.
1024 · 1180 · 1280 · 1440 · 1920px에서 세로 넘침 0, 가로 오버플로 0을 헤드리스 Chrome 151로 실측했습니다.
og:image·og:url을 배포 도메인이 붙은 절대 주소로 교체- 페이지 하단
footer랜드마크는 넣지 않았습니다. 저작권 표시가section안에 있어 그 자리에<footer>를 두면 페이지 수준 랜드마크로 인식되지 않습니다(sectioning content 안에 중첩). 제대로 하려면 덱 바깥으로 빼야 하는데100svh레이아웃이 깨져서 두었습니다.
26장 → 27장. 채움률 최소 14% → 25%, 50% 미만 슬라이드 4장 → 1장.
| 슬라이드 | 바뀐 것 |
|---|---|
| 02 숫자 | 99% 기여 지표 추가 (신규 스택 커밋 1,755 / 1,772) |
| 04 AppBox 표지 | 제목 3줄 → 2줄 |
| 05~08 기능 | 기능 설명에 판단 문장 추가 (큐 분리 / Redis Streams / PG·Mongo 분리 / 디바이스 단위 여정) |
| 09 백오피스 | 화면 3장 → 2장 (판독 가능한 크기로) |
| 10 이관 판단 | 요약 3줄 → 저장소 분리 · 접수/발송 분리 · 포기한 것 (근거 포함) |
| 11 이관 결과 | 보안 회귀 2건의 실제 내용 추가 |
| 17 ISMS-P | 신설 — 프리랜스 여행보험 B2C, 노출·저장반출·접근 통제 |
| 20 투인원 문제 | 제목 추가 + 세 사례 전부 근거까지 서술 |
| 23·24 윤사무실 | 유사한 화면 2장 → 검사 실행 결과 · 스냅샷 되돌리기 |
| 25 윤사무실 결과 | "스스로 지운 것"(사용량 게이지 제거) 추가 |
| 26 기술 스택 | 도서 표지 이미지 2장 |
| 27 연락처 | 이력서 PDF · App Store · Google Play · 학력 · 경력 |
-
내비 원거리 이동이 6초 걸렸습니다 — 2560px에서 16장을 넘으면 기본 부드러운 스크롤로는 약 41,000px를 이동합니다. 3장을 넘는 점프는 즉시 이동으로 바꿔 1초로 줄였습니다.
-
확대 다이얼로그가 좌상단에 붙어 있었습니다 —
@layer reset의*{margin:0}이 브라우저 기본margin:auto를 덮어써 중앙 정렬이 풀려 있었습니다.inset:0;margin:auto로 복원. -
.cols3에 상단 hairline 을 넣어.roles와 규칙을 맞췄습니다. -
확대 보기를 빠르게 여닫으면 콘솔에 예외가 쌓였습니다 —
ViewTransition의ready·updateCallbackDone·finished세 프로미스 중 하나라도 받지 않으면 중단된 전환이 처리되지 않은 거부로 남습니다. 셋 다 삼키고, 전환 중 재실행을 막는 가드와 "전환이 깨져도 반드시 닫는" 보정을 넣었습니다.
| 항목 | 결과 |
|---|---|
| 세로 넘침 · 가로 오버플로 | 1024 · 1280 · 1440 · 1920 · 2560 · 390px 전부 0 |
| 콘솔 오류 | 0 (확대 여닫기 연타 후에도) |
viewTransitionName 잔류 |
0 |
| 자산 응답 | 이미지 22장 · 폰트 · 이력서 PDF · og.png 전부 200 |
| 내비 원거리 이동 | 5,968ms → 1,009ms |
| 태그 균형 · 중복 id · 깨진 앵커 · 미사용 이미지 | 전부 0 |
헤드리스 Chrome 151(CDP) + 실제 Chrome(확장, 로컬 서버) 양쪽에서 확인했습니다.
문제. 상단 내비가 (1) 작은 텍스트 링크를 나열한 것뿐이라 밋밋했고, (2) 7개가 늘어서 산만했고,
(3) 활성 표시가 색 변화뿐이라 지금 어느 섹션의 몇 번째 장인지 알 수 없었고
(AppBox 하나에만 8장이 묶여 있다), (4) 좁은 화면에서 2줄(81px)로 감기고 가로 스크롤되는데
스크롤된다는 단서가 없었습니다. 01 / 27 은 aria-hidden="true" 라 스크린리더에는 위치 정보가
아예 없었습니다.
바꾼 것 — 한 줄 안에 섹션과 위치를 같이 담는다.
윤정현 경력 [AppBox] 돌콩 ISMS-P 투인원 윤사무실 기술 │ ← ●●●▬●●●● → 09 / 27
^^^^^^ 활성 섹션만 알약 그 섹션 8장 중 6번째 · 눌러서 이동
| 불만 | 해결 |
|---|---|
| 밋밋함 | 활성 섹션에 알약 배경(10% 흰색) + 굵기 520 → 640, 호버에 배경 전환 |
| 항목이 많음 | 이름은 그대로 두되 활성만 도드라지게 — 나머지는 뒤로 물러남 |
| 현재 위치 | 활성 섹션의 장 수만큼 점, 현재 장은 파란 알약. 지나온 점은 밝기로 구분 |
| 모바일 | 81 → 76px, 칩 줄은 가로 스크롤 + 남은 쪽만 페이드, 활성 칩 자동 스크롤 |
- 점은 활성 섹션 것만 그립니다. 섹션이 바뀔 때만 다시 그리고, 같은 섹션 안에서는 상태만 갱신합니다.
- 앞머리 2장(표지 · 한눈에 보기)은 어느 섹션에도 없어 따로 한 묶음으로 잡았습니다.
- 장 이름은 별도 목록 없이 문서에서 뽑습니다(
h1/h2→.eyebrow→h3→figcaption). 본문을 고치면 툴팁·스크린리더 안내도 같이 바뀝니다.<br>은 공백으로 바꿉니다. - 화살표는 상단 오른쪽으로 옮겼습니다. 전에는 화면 세로 중앙에 떠 있어 본문과 겹쳤습니다.
01 / 27의aria-hidden을 걷고, 장이 바뀌면aria-live로 "9 / 27 AppBox · …" 를 알립니다.
- 내비 안이 세로로 어긋나 있었습니다. 바 중심이 26.00px인데 화살표는 19.59, 점은 21.77에
있었습니다. 원인은 두 가지 —
#dots li가display:list-item으로 남아 점 버튼이 줄 상자 기준선(baseline)에 걸렸고, 화살표에 붙인.step이 본문의 "01 / 04" 표시가 쓰던 클래스와 겹쳐 거기 달린margin-block-end:.8rem을 그대로 받고 있었습니다..here안을 전부 flex 중앙 정렬(block-size:1.75rem통일)로 바꾸고 화살표는.arrow로 갈랐습니다. 지금은 12개 요소의 중심이 전부 26.00px 로 일치합니다. - 클래스 이름 충돌 — 기술 스택 마퀴가 이미
.track을 쓰고 있었습니다. 마퀴는.marquee로 갈랐습니다. - 세로 모드에서 이동이 먹지 않음 —
goTo()가deck.scrollLeft만 다뤄 가로 전용이었습니다.at()을 만들어 가로·세로를 한 경로로 합쳤습니다. - 양 끝이 항상 흐림 — 칩 줄 페이드가 정적이라 스크롤할 곳이 없는 쪽도 죽어 보였습니다.
data-edge로 남은 쪽만 흐리게 바꿨습니다. - 고아가 된
@keyframes rail, 최상단 2px 레일 제거(상단바 경계선에 묻혀 보이지 않았습니다).
1024 · 1280 · 1440 · 1920 · 2560 · 390px(기기 에뮬레이션)에서 세로 넘침 0 · 가로 오버플로 0 · 콘솔 오류 0. 7개 섹션 전부 활성 칩·점 개수·현재 위치 대조 (경력1 · AppBox8 · 돌콩5 · ISMS-P1 · 투인원3 · 윤사무실5 · 기술2), 점 클릭으로 섹션 안 이동, 화살표, 밝은 슬라이드 반전, 모바일 상단바 접힘·활성 칩 자동 스크롤 확인.
측정 메모 — 백그라운드 탭에서는
requestAnimationFrame과 부드러운 스크롤이 멈춥니다. 자동 측정만 보면 "이동이 안 된다"로 보이니 프레임을 한 번 그린 뒤 읽어야 합니다.
기술 스택의 흐르는 글줄은 같은 문장을 두 벌 담고 있는데 정작 애니메이션이 없어 멈춰 있었습니다. 두 벌은 이음매 없이 이으려고 둔 것이므로 애니메이션을 붙였습니다.
@keyframes flow{to{translate:calc(-50% - .8rem) 0}}한 벌 폭 + 간격만큼만 밀면 두 번째 벌이 첫 번째 자리에 정확히 들어옵니다
(-50% 는 두 벌 합의 절반, .8rem 은 간격 1.6rem 의 절반). 실측으로 대조했습니다 —
한 벌 1,758px + 간격 = 이동량 일치. 46초 주기(약 39px/s)이고,
prefers-reduced-motion 에서는 아예 돌지 않으며 마우스를 올리면 멈춥니다.
슬로건("운영을 멈추지 않고 / 구조를 바꿉니다")과 설명 문장을 걷어내고 이름 · 직무 · 사실 다섯 줄만 남겼습니다.
윤정현
백엔드 · 풀스택 개발자
경력 4년 1개월 · 2022.04 – 2026.07
주력 Java · Spring Boot / Go · Node.js · Next.js
학력 호원대학교 컴퓨터게임학부 (중퇴)
이메일 yjhzzzzdev@gmail.com ← mailto 링크
GitHub github.com/yjh-dev ← 새 탭
- 이름은
clamp(3.2rem, min(9vw,13svh), 7.5rem)— 본문--t-display보다 한 단계 작게 잡았습니다. 세 글자를 원래 크기로 두면 화면을 다 먹습니다. - 정보는 기존
.spec격자(라벨 9rem + 값)를 그대로 씁니다. 좁은 화면에서는 자동으로 쌓입니다. - 전화번호는 넣지 않았습니다. 공개 페이지라 스팸 수집 대상이 되고, 같이 올린 이력서 PDF에도 없습니다. 연락은 이메일로 받습니다.
- 하단 "옆으로 넘기기 →"(세로 모드에서는 "아래로 스크롤 ↓") 안내는 유지했습니다.
검증 — 1024·1440·1920·2560·390px 세로 넘침 0 · 가로 오버플로 0 · 콘솔 오류 0.
학력(호원대학교 컴퓨터게임학부 중퇴)을 빼고 교육 이수로 대체했습니다.
교육 DBMS기반 빅데이터 응용 SW개발자 전문과정
중앙정보처리학원 · 2018.08 – 2019.03 · 22주
첫 화면과 연락처 두 곳에 들어갑니다. 과정 상세(Java 6주 / DB 2주 / 웹표준 4주 / JSP·Servlet 4주 / Spring 전자정부 2주 / 실무 프로젝트 4주)는 경력기술서에만 두었습니다.
글로 시키는 대신 방향만 보여 줍니다.
넓은 화면 ▬▬▬▭▭▭▭▭▭ ● 58×2px 레일 위를 19px 막대가 좌 → 우로
좁은 화면 세로 2×54px 레일, 막대가 위 → 아래로
- 축이 스크롤 방향을 따라갑니다 — 가로 덱이면 가로, 세로 스택이면 세로.
- 한 번이라도 움직이면 영구히 사라집니다(
deck.scrollLeft > 24 || scrollY > 24). 안내는 한 번이면 충분하고, 계속 떠 있으면 잔소리가 됩니다. 첫 화면으로 돌아와도 다시 나타나지 않습니다. prefers-reduced-motion에서는 막대가 멈춘 채 레일 왼쪽에 놓입니다.- 장식이므로
aria-hidden— 실제 이동 수단은 상단 내비와 키보드입니다.
inset-block:0뒤에inset-block-start:auto를 쓰면 앞의 축약이 풀립니다. start=auto / end=0 이 되어block-size:auto인 요소의 높이가 0 이 됐습니다. 막대가 분명 움직이는데(계산값은 바뀜) 화면에 아무것도 안 보였습니다.- 세로용
inset-inline:0이 가로 모드에 남아 막대가 레일 전체로 늘어나 있었습니다.inset-inline-end:auto로 풀어야 합니다.
헤드리스 스크린샷은 CSS 애니메이션을 진행시키지 않습니다. 프레임을 보려면
el.getAnimations()[0].pause(); a.currentTime = t로 시각을 직접 지정해야 합니다.
숫자 아래 구분선이 항목마다 다른 높이에 있었습니다.
전 구분선 top 470 · 446 · 470 · 470 · 446 ← 2번·5번이 24px 위
후 구분선 top 455 · 455 · 455 · 455 · 455
원인은 두 겹이었습니다.
margin-block-start:auto로 라벨을 바닥 정렬하고 있었습니다. 라벨이 한 줄인 항목과 두 줄인 항목("Java · Spring Boot 기반 웹 서비스", "신규 스택 저장소 커밋 기여 · 1,755 / 1,772")이 섞이면 위쪽 구분선 높이가 그만큼 달라집니다. 바닥은 맞는데 선이 어긋납니다.- 넓은 화면에서
.figures b{min-block-size:0}이라 숫자 블록이 두 줄("4년 1개월")과 한 줄("0건")로 제각각이었습니다.
고친 방법 — 숫자 블록을 min-block-size:2lh(정확히 두 줄) 로 통일하고, 라벨의 바닥 정렬을
없애 숫자 블록 바로 아래 고정 간격에 두었습니다. 이제 줄 수와 무관하게 구분선이 한 줄에 옵니다.
lh 를 못 읽는 브라우저를 위해 2.05em 을 앞에 두어 대비했습니다.
1280 · 1440 · 1920 · 2560px 에서 구분선 top 완전 일치.
1024px 이하는 그리드가 줄바꿈되어 4+1 · 2+2+1 로 배치되는데, 행 안에서는 모두 일치합니다
(auto-fit 의 정상 동작).
문제. 데이터 모델 자료가 763줄(앱박스 319 · 투인원 181 · 윤사무실 263) 있는데 웹에는 11번의 텍스트 상자 하나뿐이었습니다. 그것도 인프라 배치도지 데이터 모델이 아니었습니다. 백엔드 지원자가 가장 많이 질문받는 영역인데 근거가 화면에 없었습니다.
손으로 그린 인라인 SVG 3종. 라이브러리 없이 rect·path·text 로만 그렸고,
선과 글자는 currentColor, 판단이 걸린 요소 하나만 강조색을 씁니다.
| 다이어그램 | 어디 | 무엇을 보여주나 |
|---|---|---|
| 발송 파이프라인 | 11번 (텍스트 구조 대체) | 접수(web)와 발송(push)이 서버까지 갈라져 있다. 큐가 강조색 — 여기가 분리점 |
| 스냅샷 빌링 | 12번 (신설) | 제공량은 참조가 아니라 복사. 점선 + ✗ 로 "이후 수정이 닿지 않는다"를 그림 |
| TOCTOU 차단 | 22번 (신설) | 앱 검사는 둘 다 통과하고, DB가 두 번째를 거절한다 |
각 그림은 <figure> + <figcaption> 에 한 문장짜리 주장을 달았고, role="img" 와
aria-label 로 같은 주장을 텍스트로도 전달합니다.
곁들인 것 — 원자적 차감 SQL(WHERE remaining >= :qty), 두 지갑 차감 순서,
journey_instances 의 정리 못 한 부채(PG에 정의만 남고 실제는 Mongo — 먼저 밝히는 편이 낫다),
투인원 제약 4종 표.
27 → 29장.
지금까지 쓰던 넘침 검사가 틀렸습니다.
inn.scrollHeight > s.clientHeight // clientHeight 는 패딩을 포함한다 → 거짓 음성슬라이드는 위아래 72px 패딩 안에서 내용을 세로 가운데 정렬합니다. 내용이 콘텐츠 상자보다
크면 위아래로 삐져나가는데, 위쪽은 position:fixed 상단바(53px) 아래로 숨습니다.
clientHeight 기준으로는 이게 안 잡혀서 "넘침 없음"으로 보고돼 왔습니다.
고친 검사 — 각 슬라이드로 이동한 뒤(.rise 진입 애니메이션이 화면 밖에서 위치를 바꿉니다)
첫 요소의 화면상 top 이 상단바보다 위인지, inner 의 bottom 이 뷰포트를 넘는지 봅니다.
이 기준으로 12번(위 34px)·22번(위 9px)이 잡혀서 여백과 문장을 줄였습니다.
.spec-tight가 뒤에 오는.spec규칙에 밀려 열 폭이 9rem으로 되돌아가 제약 코드가 3줄로 깨져 있었습니다..spec.spec-tight로 특정도를 올리고white-space:nowrap을 걸었습니다. (이 파일에서 클래스 충돌·특정도 문제는.track·.step에 이어 세 번째입니다.)
1440 · 1920 · 2560px 에서 가려짐·잘림 0 · 콘솔 오류 0 (1440 / 390).
네 프로젝트 전부에 데이터 모델 슬라이드를 넣었습니다. 수치는 전부 저장소 실측입니다.
| 슬라이드 | 다이어그램 | 실측 근거 |
|---|---|---|
| 13 AppBox 스키마 지도 | 스키마별 테이블 분포 막대 | 마이그레이션 SQL 의 CREATE TABLE 을 스키마별로 집계 — cms 16 · core 15 · billing 15 · messaging 12 · support 6 · backoffice 6 · mailing 4 · build 4 · audit 2 = 81 |
| 19 돌콩 데이터 모델 | 6 컬렉션 관계 + 인덱스 | src/models/*.ts 의 .index() 실측 — 2dsphere · TTL · {room,createdAt:-1} · Report 3키 복합 · fcmToken sparse |
| 25 투인원 데이터 모델 | ownerScope 이중 테넌트 |
schema.prisma — 22 모델, enum OwnerScope { user, couple }, 6개 모델이 ownerScope 사용 |
| 31 윤사무실 프로토콜 | 훅 ↔ 파일 ↔ 앱 | .claude/ 파일 6종 · 이벤트 9종 |
AppBox 슬라이드에는 서비스 구성(저장소 6개 ↔ 서버 3대, dev·prod 분리)도 같이 넣었습니다.
29 → 33장, 다이어그램 3 → 7개.
- 문서에 “9개 스키마”라고 되어 있었는데 마이그레이션에는 스키마가 10개입니다.
10번째는 Drizzle 이 쓰는
migration한 테이블이라, 업무 스키마 9개가 맞습니다. - 돌콩 다이어그램에 처음
Message → Block화살표를 그렸는데 관계가 틀렸습니다.Block은blocker·blocked둘 다User를 참조하고,Message를 참조하는 건Report입니다. 모델 파일의ref:를 다시 읽고 고쳤습니다 — 스키마 그림의 틀린 화살표는 리뷰어가 가장 먼저 잡습니다.
태그 균형 검사가 rect 를 불균형으로 보고했는데, SVG 의 <rect …/> 는 자체 닫힘이라
</rect> 가 없는 게 정상입니다(44개 전부 자체 닫힘 확인). 검사 대상에서 빼야 합니다.
1440 · 1920 · 2560px 가려짐·잘림 0 · 콘솔 오류 0 (1440 / 390).