# preflight — 단일 납품 체크리스트 5단계에서 읽는다. **자기 결과물을 남의 것처럼 본다.** 통과 못 한 항목은 4단계로 돌아가 고친다. **이 문서가 5단계의 유일한 납품 체크리스트다.** 다른 references 문서에 있는 체크리스트(motion §5, typography §8 등)는 구현 중 자기 점검이다. 납품 판정은 이 문서의 행 ID로만 한다. 같은 점검이 두 곳에 있으면 이 문서의 문구가 납품 기준이고, 세부 방법은 각 행이 가리키는 정본 문서를 따른다. 슬롭 지문 grep 목록과 맥락 질문은 [antipatterns.md](antipatterns.md), 시각 품질의 축별 판정은 [critique.md](critique.md) §2-1 루브릭, 게이트 설치와 측정 계약은 [audit-gate.md](audit-gate.md)에 있다. --- ## 이 문서를 읽는 법 | 절 | 행 ID | 언제 | |---|---|---| | §0 기계 검사 | M-A~M-E | 전체·연장은 항상. 국소는 아래 "경로별로 돌 범위" | | §1 접근성 | A1~A25 | 항상(하드 게이트) | | §2 성능 | P1~P8 | 항상. 국소 경로는 손댄 자산·코드가 예산에 닿을 때 | | §3 반응형 | W1~W16 | 전체·연장은 항상. 국소는 손댄 요소가 놓인 뷰만 | | §4 콘텐츠 | C1~C8 | 카피·데이터를 바꿨을 때 | | §4-1 상태 완결성 | S1~S11 | 입력·파괴·열림이 있는 화면 | | §4-2 진실 완결성 | T1~T11 | 가상·예시·AI·규제 화면 | | §4-3 썸네일·OG | O1~O4 | 썸네일·OG 이미지를 만들 때 | | §4-4 조건부 모듈 | X1~X19 | 해당 기술·표면을 썼을 때 | | §5 시각 판정 | V1~V7 | 전체·연장 경로, 국소는 손댄 축만 | | §6 최종 게이트 | G-1~G-12 | 완료 선언 직전 | `G-n`은 이 문서의 최종 게이트 행이고, 하이픈 없는 `Gn`(G20, G32 등)은 [audit-gate-rules.md](audit-gate-rules.md)의 게이트 규칙 번호다. ### 경로별로 돌 범위 | 경로 | 돌 행 | |---|---| | 전체·연장 | §0~§6 전부. §4-2·§4-3·§4-4는 조건이 맞는 행만 | | 국소 | 하드 게이트 행은 전부 돈다. 그 밖의 행은 손댄 영역이 걸친 것만 돈다. §5 루브릭은 손댄 영역이 걸친 축만 채점한다 | | 리뷰(5′) | 리뷰는 읽기 전용이다([change-review.md](change-review.md) §1-1). 사용자 프로젝트를 바꾸지 않고 잴 수 있는 행만 돈다. 패키지 설치·설정 파일 생성이 필요한 행은 미검증으로 남긴다. 범위 밖으로 뺀 행은 미점검이다([critique.md](critique.md) §7·§8) | **하드 게이트의 "전부"는 행을 뜻한다. 표면은 이번 작업이 정한다.** - 전체 경로: 만든 화면 전부. - 연장·국소: 손댄 요소, 그 요소가 놓인 뷰, 그 변경이 닿는 상태(hover·focus·열림·오류)와 폭. 토큰을 바꿨으면 그 토큰을 쓰는 곳까지다. - 범위 밖에서 발견한 위반은 **기존 결함**으로 분리한다. 고치지 않고, 완료 보고의 "기존 결함" 목록에 위치·기준·제안을 적는다. 하드 게이트 집계(충족/미검증/차단)에 넣지 않는다. 사용자가 고쳐 달라고 하면 그때 경로를 다시 판정한다. 분류 기준은 change-review의 Introduced·Regression·Pre-existing과 같다. 이렇게 나누는 이유: 표면을 페이지 전체로 읽으면 hover를 고치러 들어간 작업이 푸터의 기존 대비 위반 때문에 끝나지 않거나, 요청받지 않은 곳을 고치다 경로까지 올라간다. ### 행의 상태와 위계 - 상태는 넷이다: **충족 / 미검증 / 실패 / 해당 없음**. 도구·기기가 없어 확인하지 못한 행은 미검증이다. 미검증은 충족이 아니다. - 위계 표시: `[하드 게이트]`, `[계약]`(프로젝트 계약), `[휴리스틱]`(관찰 후보), `[방향]`(critique §4 Direction). §1의 표시 없는 행은 하드 게이트, 그 밖의 표시 없는 행은 계약이다. - 실패 행은 [critique.md](critique.md) §3 형식으로 finding을 만들고 §4 심각도를 매긴다. - 같은 결함의 수정 시도는 3회까지다. 넘으면 멈추고 사용자에게 보고한다([audit-gate.md](audit-gate.md) "루프와 재작업 상한"). --- ## 0. 먼저 기계로 검사한다 **무엇에 돌리는가부터 정해라.** - 정적 HTML/CSS 프로젝트 → 소스 그대로 - **React·Vue·Astro 등 프레임워크 프로젝트 → 프로덕션 빌드 결과에 돌린다.** 소스만 보면 렌더된 DOM 이 없어 대비·가로 스크롤·LCP 를 잴 수 없다. `pnpm build && pnpm preview` 로 띄우고 그 URL 을 검사해라 - **소스만 보고 "측정 불가"로 남기지 마라.** 렌더할 수단이 정말 없을 때만 미검증이고, 미검증은 통과가 아니다 grep 검사는 **주석과 문자열을 제외**해라. "100vh 금지"라고 쓴 주석이 하드 게이트 검사에 걸리는 오탐이 실제로 나왔다. 전체·연장은 M-A~M-E를 모두 돌린다. 국소는 손댄 것에 닿는 것만 돌린다(hover 수정이면 M-A와 M-D). ### M-A. 이펙트 전부 끄기 ```css /* 임시로 주입해서 확인한다 */ *, *::before, *::after { filter: none !important; backdrop-filter: none !important; animation: none !important; transition: none !important; transform: none !important; } canvas { display: none !important; } ``` 이 상태에서 **페이지가 여전히 읽히고 구조가 살아 있어야 한다.** 무너지면 이펙트가 구조를 대신하고 있는 것이다. 4단계로 돌아가 구조부터 고친다. 필터·3D·캔버스·패럴랙스를 쓴 경우의 추가 확인은 §4-4다. ### M-B. 스타일 후보 grep `[휴리스틱]` [antipatterns.md](antipatterns.md)의 grep 목록을 소스에 돌려 보라 CTA, 전체 대문자 헤드라인, 번호 매긴 단계 같은 반복 후보를 찾는다. 검출은 실패가 아니다. 프로젝트 계약·브리프·실제 렌더를 대조해 유지·수정·제거를 기록한다. ### M-C. 카피 경쟁사 치환 브랜드가 특별하다고 주장하는 문구에만 제품·회사 이름을 경쟁사 이름으로 바꿔 읽는 **진단 질문**을 쓴다. 다른 업체에도 그대로 성립하면 근거와 구체성을 재검토한다. 헤드라인·히어로 본문이 그대로 성립하면 루브릭 R7 0점이다(§5). 수업·가격·대상·위치·FAQ·CTA 같은 안내는 치환만으로 실패시키지 않는다. 독자의 실제 질문에 대한 구체적 답, 검증 가능한 사실, 자연스러운 업종 표현을 먼저 확인한다. 낯선 업종이나 추상 표현의 용법이 불확실하면 공식 실제 사례를 소규모로 조사해 용어를 참고한다. 그 사례의 주장·실적·후기를 가져오지 않으며, 현재 프로젝트의 사실로 바꾸어 말하지 않는다. ### M-D. 죽은 코드·토큰 위생 (design-gate 내장 검사) - CSS 클래스가 HTML·JS 어디에도 등장하지 않으면 죽은 것이다. 컴포넌트를 없앨 때 HTML·CSS·JS 를 **삼위일체로** 지웠는지 대조한다(동적 클래스 `is-${type}`·`seg-${n}` 처럼 조립되는 접두사는 게이트 설정의 `deadCssIgnore` 로 제외한다) - 토큰 파일이 있는데 다른 CSS 파일에 색 리터럴(hex·rgb)이 남아 있으면 실패다. 반지름 리터럴은 게이트가 `thresholds.radiusLiterals`(기본 3종) 이상일 때 실패로 본다 — 그보다 적으면 토큰으로 옮길지 직접 판정한다. 눈 검사로는 전부 못 잡는다 - `theme-color` 메타가 실제 배경색과 다르면 **낡은 토큰**이다. 브랜드 표면(theme-color·파비콘·og:image)이 함께 갱신됐는지 본다 ### M-E. 왼쪽 인셋 리듬 (모바일) 오버플로 검사는 오른쪽만 본다. **왼쪽이 붙어 깨지는 결함은 통과한다.** 게이트의 `leftInset` 검사가 재는 폭과 항목은 [audit-gate.md](audit-gate.md)의 검사별 측정 폭을 본다 — 게이트가 재지 않는 폭과 "같은 축" 판정은 직접 잰다. 모바일 폭(320·390)에서: - 화면의 모든 보이는 텍스트 시작점 ≥ 12px - 헤더 텍스트·화면 제목·카드 텍스트가 **같은 축**(±10px) - 측정은 전폭 컨테이너의 보더박스가 아니라 **텍스트 시작점**으로 하고, `display:none` 요소(rect=0)는 제외한다 --- ## 1. 접근성 — 타협 없음 판정 원칙과 구현 세부의 정본은 [accessibility.md](accessibility.md)다. 이 표는 납품 판정 행만 둔다. | ID | 항목 | 확인 방법 | 기준 | |---|---|---|---| | A1 | 키보드 도달 | Tab 만으로 순회 | 모든 인터랙티브 요소에 도달, 순서가 시각 순서와 일치 | | A2 | 포커스 표시 | Tab 하며 눈으로 | 항상 보인다. `outline: none` 만 있고 대체가 없으면 실패 | | A3 | 대비 | 측정 도구 | 본문 4.5:1, 큰 글자·UI 3:1. 라이트·다크 등 지원하는 외형마다 잰다. 반투명 배경은 합성해서 잰다([audit-gate-rules.md](audit-gate-rules.md) §3) | | A4 | 이미지 대체텍스트 | 소스 확인 | 의미 있는 이미지에 alt, 장식은 `alt=""` | | A5 | 폼 레이블 | 소스 확인 | 모든 입력에 연결된 `