기능이 정상이어도 디자인은 끝나지 않았다
실제 백엔드 데이터와 Server Component, ISR과 MDX를 유지한 재설계는 경로와 빌드, 운영 점검을 통과했다. 하지만 Open Design v38과 나란히 보면 Home 패널 전환과 hero 위계가 달랐다. 모바일 메뉴의 실제 터치 영역은 44px보다 작았고 상세는 320px의 긴 URL과 1079px 분기점에서 무너졌다.
API 테스트와 경로 점검이 찾을 수 없는 차이였다. 기능 검수와 원본 충실도 검수를 분리했다.
기능: 무엇을 보여 주고 route와 interaction이 동작하는가
Fidelity: hierarchy와 layout, transition이 visual source의 의도와 맞는가시각적 판단은 v38, 데이터와 경로, 포커스와 캐시는 운영 계약을 기준으로 삼았다.
모든 차이를 결함으로 보지는 않았다
| 종류 | 대응 |
|---|---|
| 원본 충실도 결함 | 근거 없이 바꾼 위계와 상호작용을 원본 의도로 복원 |
| 의도적인 조정 | 실제 데이터와 접근성, 실행 환경에 필요한 차이를 이유와 함께 유지 |
| 근거 부족 | 추측하지 않고 원본이나 측정값 확보 |
화면이 더 정돈돼 보인다는 개인 판단은 근거가 아니었다. 반대로 프로토타입과 다르다는 이유로 실제 데이터나 44px 터치 영역을 버리지 않았다. 충돌하면 운영 계약을 지키면서 시각적 의도에 가장 가까운 구현을 찾았다.
Home은 같은 내용을 다르게 움직이고 있었다
첫 Home은 세 구역과 실제 데이터, 휠·키보드·터치·동작 줄이기 설정을 지원했다. 하지만 긴 track 전체를 위로 이동시켰고 v38은 고정 stage에서 이전 패널이 나가고 새 패널이 들어오는 구성에 가까웠다. Hero 문구와 글꼴, 24시간 타임라인, 구역 번호와 진행률도 단순화돼 있었다.
Commit 25f16b8에서는 패널을 같은 stage에 두고 active, incoming, outgoing 상태로 전환했다. Hero와
서울 현재 시각 표시선, 진행률과 행 위계를 복원했다. 실제 백엔드 글과 프로젝트 데이터, Server children,
캐시 계약은 바꾸지 않았다.
같은 정보 구조와 정상 동작만으로 같은 디자인이 되지는 않았다.
스크린샷과 브라우저 상태를 함께 봤다
스크린샷은 글꼴과 간격, 구성을 비교하는 데 유용하지만 터치 영역과 스크롤 경계, 접근성 상태는 보여 주지 않는다.
Screenshot -> 시각적 hierarchy
Bounding box와 computed style -> 크기와 layout
scrollHeight·scrollTop -> scroll 경계
scrollWidth·clientWidth -> overflow
inert·aria-hidden·focus -> 접근 가능 상태
실제 wheel·keyboard·touch -> input state machine화면 크기도 모바일과 데스크톱 둘로 줄이지 않았다. 1080px과 1079px처럼 구조가 바뀌는 경계 양쪽과 같은 너비의 작은 높이도 직접 확인했다.
24.5px이 Footer 접근을 막았다
320x720 Home 마지막 패널에서 브라우저는 수학적 최대 스크롤까지 가지 않았다.
최대 거리 약 382px
실제 정지 357.5px
남은 거리 24.5px
Footer edge 24pxFooter 표시 여부는 정규화한 값을 사용했지만 휠 소비 경로는 원시 값을 보고 더 스크롤할 수 있다고
판단했다. 이벤트는 소비됐고 실제 scrollTop은 그대로라 새 스크롤 이벤트도 없었다. Footer는 투명할 뿐 아니라
inert, aria-hidden=true라 반복 휠에도 링크에 도달할 수 없었다.
Commit 34c71a4에서는 경계 안에서 새 아래 방향 제스처가 들어오면 Footer를 열었다. 같은 제스처의 잔여
휠에는 열리지 않고 시간 간격 뒤 새 제스처에서만 열리도록 테스트했다. 위 방향 30px에서는 다시 숨기는
히스테리시스와 inert, aria-hidden 전환도 고정했다.
실제 콘텐츠와 분기점에서 상세가 깨졌다
긴 URL은 320px에서 전체 문서를 밀었다. Grid 자식에 min-width: 0, 링크에
overflow-wrap: anywhere를 적용하고 scrollWidth === clientWidth를 완료 조건으로 삼았다.
1079px에서 왼쪽 정보 영역 전체를 숨기자 돌아가기 링크와 grid 의미까지 사라지고 빈 공간이 남았다. 이 영역은 단일 열 행으로 유지하고 글 정보와 TOC만 숨겼다. 1080px의 압축된 세 열 구조와 바로 붙여 검증했다.
글 이동 영역과 Footer 사이에는 1280px에서 약 192px, 320px에서 약 144px의 빈 공간도 있었다. 페이지 여백과 상위 main 안쪽 여백을 제거해 Footer의 1px 테두리가 글 종료선이 되게 했다.
의도적인 차이는 남겼다
운영 검색은 v38의 단순 페이지 입력 대신 전역 Radix Dialog와 300ms debounce, 요청 취소, 로딩·빈 결과·오류 구분, 제한된 결과와 포커스 복귀 계약을 가졌다. 표현은 v38에 맞추되 기능은 유지했다.
프로젝트 category도 화면에는 짧은 label을 쓰면서 기준값은 데이터에 남겼다. 모바일 메뉴는 보이는 문구와 간격을 유지하고 버튼의 최소 터치 영역만 44px로 넓혔다.
차이를 유지하려면 실제 데이터나 실행 상태를 표현하는지, 키보드와 포커스, 터치, 동작 줄이기 설정에 필요한지, 시각적 의도를 나머지 구조와 문구에서 지키는지와 테스트로 확인 가능한지를 설명할 수 있어야 했다.
긴급 수정 뒤에는 전체 사용 흐름을 다시 확인했다
국소 수정은 이웃 화면 크기와 입력을 깨뜨릴 수 있다. 따라서 정확한 결함을 재현하고 테스트를 추가한 뒤 인접 경계와 test·lint·build, backend-unreachable build, 고유 URL의 운영 배포본, 실제 사용 흐름을 다시 확인했다.
Home은 320x720과 390x844, 데스크톱, 키보드와 터치, 동작 줄이기 설정을 봤다. Detail은 1280, 1080, 1079, 760, 390, 320px에서 rail과 본문, Footer를 확인했다. Search는 포커스 복귀와 오래된 요청, 오류와 빈 상태까지 다시 봤다.
최종 범위에는 Home과 Projects, Blog 분류·페이지 나누기, 대표 MDX 상세와 이웃 글, Search와 shell, 테마와
overflow, 키보드와 ARIA, 터치 영역, ISR과 MDX 캐시, icn1, checkout 없는 build가 포함됐다.
프런트엔드 기준선은 테스트 파일 32개, 테스트 266개였다. 테스트와 lint, 일반·backend-unreachable build를 통과했다. 백엔드 테스트의 정확한 수와 원시 출력은 확인 자료에 남아 있지 않아 새 숫자를 만들지 않았다.
완료 검수 기록에는 경로 7개 × 화면 크기 7개 = 조합 49개가 있었지만 원본 표와 스크린샷 묶음은
저장소에 없다. 재현 가능한 시각 자료로 과장하지 않고 수정 commit과 회귀 테스트,
b23233f의 완료 검수 기록을 보존 가능한 근거로 사용했다.
완료 조건을 먼저 정하고 멈췄다
시각적 다듬기에는 끝이 없으므로 더 고칠 것이 떠오르지 않는 상태를 완료로 삼지 않았다.
기능 contract 통과
Visual 차이 분류 완료
Blocking fidelity defect 수정
Intentional adaptation의 이유 존재
Responsive·접근성·theme regression 통과
Cache·runtime·build contract 유지
운영 SHA와 승인 revision 일치
대표 journey의 blocking defect 0이는 픽셀 단위로 같다는 선언이 아니다. 실제 제목과 프로젝트 데이터, 포커스와 동작 줄이기 설정, 가변적인 MDX는 프로토타입과 다른 결과를 만든다. 그 차이가 의도와 근거가 분명한 조정인지, 근거 없는 재해석인지 설명할 수 있게 된 시점을 재설계 완료로 정했다.