프론트엔드 개발자라면 누구나 한 번쯤 이런 경험이 있을 겁니다. Figma에서 볼 때는 완벽했던 시안이, 브라우저에 올리는 순간 미묘하게 어긋나기 시작하는 그 순간. 컬러가 살짝 다르고, 여백이 4px쯤 벌어져 있고, 폰트 웨이트가 한 단계 달라 보이는 — 디자이너는 "이거 시안이랑 다른데요"라고 말하고, 개발자는 "제 화면에선 똑같은데요"라고 답하는 그 영원한 갭. 최근 velog에 올라온 판다마켓 랜딩페이지 마크업 회고는 이 갭을 체계적으로 줄여나간 과정을 담고 있어서, 예민한 프론트엔드 개발자 입장에서 꼼꼼히 뜯어볼 가치가 있었습니다.
디자인 토큰을 CSS 변수로: 시안의 '의도'를 코드에 심는 법
이 회고에서 가장 먼저 눈에 들어온 건 Figma 시안의 디자인 토큰을 :root CSS 커스텀 프로퍼티로 1:1 변수화한 부분입니다. --primary-100: #3692FF부터 --secondary-900: #111827까지, 컬러 팔레트를 통째로 변수로 옮겼고, 시안 팔레트에는 없지만 랜딩페이지에서 반복되는 --bg-hero, --bg-feature 같은 컬러도 별도 상수로 정의했습니다. 사용자 입장에서는 보이지 않는 작업이지만, 이게 왜 중요하냐면 — 디자이너가 "primary 컬러 톤 한 단계 올려주세요"라고 했을 때 변수 하나만 바꾸면 끝나기 때문입니다. Figma의 Design Token 플러그인이나 Dev Mode에서 토큰을 내보내는 워크플로우와 정확히 맞물리는 구조죠.
타이포그래피도 .text-2xl-medium, .text-xl-semibold 같은 유틸리티 클래스로 정의했는데, 사실 이건 Tailwind CSS의 유틸리티 퍼스트 철학과 닮아 있습니다. 다만 Tailwind를 도입하지 않고 순수 CSS 클래스로 직접 만든 건, 디자인 시스템의 토큰 체계를 손으로 한 번 만져봐야 "아, 이 font-weight 600이 시안에서 semibold구나"하는 감각이 생기기 때문이라고 봅니다. Figma에서 Inspect 패널로 확인한 값을 rem 단위로 변환하는 과정 자체가 학습이 되는 거죠.
시멘틱 태그와 접근성: '보이는 것' 너머의 마크업
이 회고가 단순 코딩 연습과 다른 지점은, 시멘틱 태그 선택에 대한 고민이 녹아 있다는 겁니다. <section> vs <article> 선택 기준을 "독립적으로 배포할 수 있는가"로 판단한 것, <h1>을 로고에 한 번만 쓰고 섹션 제목은 <h2>, <h3>으로 계층을 지킨 것, 장식용 이미지에 alt=""와 aria-hidden="true"를 동시에 적용한 것 — 이런 디테일이 스크린리더 사용자 경험을 결정합니다. WCAG 관점에서 보면 heading 계층이 깨지는 순간 페이지 구조 파악이 불가능해지거든요. 1px 어긋나는 것도 못 참는 저로서는, heading 레벨이 점프하는 건 그보다 더 심각한 문제라고 봅니다.
position: sticky와 min-width: 0 — 실전에서 겪어야 아는 1px의 함정
헤더에 position: fixed 대신 sticky를 선택한 판단이 인상적입니다. fixed를 쓰면 본문에 padding-top을 헤더 높이만큼 줘야 하고, 헤더 높이가 바뀔 때마다 같이 수정해야 하는 유지보수 지옥이 열리죠. sticky는 문서 흐름을 유지하면서 스크롤 시 고정되니까 이 문제가 깔끔하게 해결됩니다. "Figma에서 볼 때는 괜찮았는데 실제로 구현하면 본문이 헤더 뒤로 들어가더라" — 이 갭을 경험해본 사람만 sticky의 가치를 압니다.
히어로 이미지에 min-width: 0을 적용한 것도 실전 감각입니다. Flexbox 자식은 기본적으로 min-width: auto라서 콘텐츠 크기 이하로 줄어들지 않거든요. 1024×600 해상도에서 가로 스크롤이 발생하는 걸 잡아낸 건, 실기기 테스트 없이는 절대 발견할 수 없는 버그입니다. 여기서 Claude Code를 활용한 React 웹개발 사례(velog, mole101)가 시사하는 점이 있는데 — AI 코딩 에이전트가 코드를 생성해주더라도 "데스크톱에서 잘 되던 레이아웃이 모바일에서 어김없이 깨졌다"는 고백처럼, 미세한 터치 영역 문제나 브레이크포인트별 레이아웃 깨짐은 결국 사람이 실기기에서 확인해야 합니다.
AI 코딩 시대에도 변하지 않는 것: 디자인-개발 갭의 '라스트 마일'
WXT+React+TypeScript로 브라우저 확장을 만든 dev.to 사례에서도 비슷한 패턴이 보입니다. Shadow DOM으로 사이드바를 격리하고, type-safe 메시지 패싱으로 컨텍스트 간 통신을 설계하는 — 결국 "구조를 먼저 잡고, 디테일을 쌓아올리는" 방식은 랜딩페이지 마크업이든 브라우저 확장이든 동일합니다. 피그마 기본 개념을 다룬 부캠 학습 노트가 프레임, 레이어 패널, 속성 패널의 계층 구조를 강조한 것도 같은 맥락이죠. Figma의 레이어 계층이 곧 HTML의 DOM 트리이고, 속성 패널의 값이 곧 CSS 프로퍼티입니다.
시사점: 워크플로우가 품질을 결정한다
이 회고가 보여주는 워크플로우를 정리하면 이렇습니다 — ① Figma 토큰을 CSS 변수로 매핑 → ② 시멘틱 태그로 문서 구조 설계 → ③ rem 기반 반응형 → ④ flexbox 레이아웃 → ⑤ 실기기 테스트로 엣지 케이스 검증. AI 코딩 에이전트가 ①~④를 빠르게 생성해줄 수 있는 시대지만, ⑤의 "1024×600에서 가로 스크롤이 생기네"를 잡아내는 건 여전히 브라우저 앞에 앉은 사람의 몫입니다.
앞으로 Container Queries, @layer, :has() 같은 새 CSS 기능이 안정화되면 이 워크플로우는 더 정교해질 겁니다. 특히 Container Queries는 컴포넌트 단위로 반응형을 제어할 수 있어서, max-width: 69.375rem 같은 매직 넘버를 줄이는 데 결정적일 거예요. 그때까지, 그리고 그 이후에도 — 디자인 시안을 열어놓고 브라우저를 옆에 띄워서 1px씩 비교하는 이 집요한 습관은 프론트엔드 장인의 기본기로 남을 겁니다. Lighthouse 점수 100점보다 중요한 건, 디자이너가 시안을 보고 "이거 그대로네요"라고 말해주는 그 한 마디니까요.