designpaca/packages/skill/references/preflight.md
Yun Chan eb3ca69b5d 타이포그래피 스킬 신설 + 폴백 메트릭 보정
'폰트 관련된 것도 스킬이 좀 잘 해줘야 하는데 그렇지 못한 것 같다'는 지적.
점검해보니 size-adjust, ascent-override, unicode-range, OpenType 기능,
FOUT/FOIT, 폰트 라이선스가 스킬 어디에도 없었다. font-display 와 서브셋은
tokens.md 에 한 줄씩뿐이었다.

references/typography.md 신설
- 고르는 절차: 개수를 먼저 정하고, 성격을 브리프에서 끌어내고,
  x-height·대비·웨이트 범위·숫자 형태를 실제로 재서 검증한다
- 가변 폰트: 축, 표준 속성 우선, 가변 축 애니메이션이 왜 게이트 8 위반인지
- 로딩: font-display 값별 선택 기준, preload 조건, unicode-range
- 폴백 메트릭: size-adjust 와 override 3종. 재는 코드 포함
- OpenType: tabular-nums 등. font-variant-* 를 font-feature-settings 보다 먼저
- 한글: 동적 서브셋 원리, 웨이트가 라틴과 다르게 보이는 이유, 스택 순서
- 라이선스: 웹 임베딩 허용 여부가 상업 이용 허용과 다르다는 것

그리고 이 페이지가 그 규칙을 어기고 있었다
- 실측: 맑은 고딕이 Pretendard 보다 13.0% 넓다. 교체 순간 줄바꿈이 다시 잡힌다
- fonts.css 신설. OS 별로 폴백을 따로 정의하고 size-adjust 로 맞췄다
- 실측 차이 13.0% -> 0.0%

preflight.md 에 폰트 검사 6개를 추가했다. 지금까지 하나도 없었다.
2026-08-20 12:42:59 +09:00

146 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# preflight — 출시 전 감사
5단계에서 읽는다. **자기 결과물을 남의 것처럼 본다.** 통과 못 한 항목은 4단계로 돌아가 고친다.
슬롭 지문 검출과 자가 채점표는 `references/antipatterns.md` 에 있다. 이 문서는 **그 외 전부**를 다룬다.
---
## 0. 먼저 기계로 검사한다
**무엇에 돌리는가부터 정해라.**
- 정적 HTML/CSS 프로젝트 → 소스 그대로
- **React·Vue·Astro 등 프레임워크 프로젝트 → 프로덕션 빌드 결과에 돌린다.** 소스만 보면 렌더된 DOM 이 없어 대비·가로 스크롤·LCP 를 잴 수 없다. `pnpm build && pnpm preview` 로 띄우고 그 URL 을 검사해라
- **소스만 보고 "측정 불가"로 남기지 마라.** 미측정은 통과가 아니다
grep 검사는 **주석과 문자열을 제외**해라. "100vh 금지"라고 쓴 주석이 게이트 #9 에 걸리는 오탐이 실제로 나왔다.
사람 눈보다 정확하고 빠르다. 셋 다 돌려라.
### 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-1로 돌아가라.
### B. 슬롭 지문 grep
`references/antipatterns.md` 의 grep 목록을 소스에 돌린다. 검출률 상위 항목(보라 CTA, 전체 대문자 헤드라인, 번호 매긴 1·2·3 단계)부터.
### C. 카피 경쟁사 치환
제품명을 경쟁사 이름으로 바꿔 읽는다. **문장이 그대로 성립하면 그 카피는 아무것도 말하지 않았다.** 히어로 문구부터 검사한다.
---
## 1. 접근성 — 타협 없음
| 항목 | 확인 방법 | 기준 |
|---|---|---|
| 키보드 도달 | Tab 만으로 순회 | 모든 인터랙티브 요소에 도달, 순서가 시각 순서와 일치 |
| 포커스 표시 | Tab 하며 눈으로 | 항상 보인다. `outline: none` 만 있고 대체가 없으면 실패 |
| 대비 | 측정 도구 | 본문 4.5:1, 큰 글자·UI 3:1 |
| 이미지 대체텍스트 | 소스 확인 | 의미 있는 이미지에 alt, 장식은 `alt=""` |
| 폼 레이블 | 소스 확인 | 모든 입력에 연결된 `<label>`. placeholder 는 레이블이 아니다 |
| 제목 구조 | 개요 확인 | h1 하나, 건너뛰지 않음 |
| 모션 감소 | `prefers-reduced-motion` 켜고 확인 | **전부 끄는 게 정답이 아니다** — 위치 이동·시차·자동재생을 죽이고, 페이드·상태 변화는 남긴다 |
| 자동재생 | 확인 | 5초 이상 반복되는 애니메이션에는 정지 수단이 있다 |
| 캔버스/WebGL 실패 | JS 끄고 확인 | 콘텐츠가 여전히 보인다 |
**스크린리더를 실제로 켜볼 수 없다면** 최소한 소스의 읽기 순서를 확인해라. `order`·`position: absolute` 로 시각 순서를 바꿨다면 읽기 순서가 어긋난다.
---
## 2. 성능 — 3단계에서 정한 예산과 대조
**예산 값은 `tokens.md` §5 를 보라. 여기서 다시 적지 않는다** — 두 곳에 적으면 갈라진다.
이 문서가 하는 일은 **실측을 채우는 것**이다.
| 항목 | 실측 | 판정 |
|---|---|---|
| 히어로까지 JS (gzip) | | |
| WebGL/3D 추가분 | | |
| 총 전송량 (첫 화면) | | |
| 첫 인터랙션 (모바일 4G) | | |
| LCP | | |
| CLS | | |
| 폰트 파일 수 | | |
**측정하지 않았으면 통과가 아니다.** 예산을 넘겼다면 둘 중 하나다: 이펙트를 빼거나, 예산을 올린 이유를 명시하거나.
### 폰트 (`typography.md` §8 이 전체 목록)
- [ ] **폴백 메트릭을 보정했거나 `font-display: optional` 을 골랐다.** 둘 다 안 했으면 폰트가 교체되는 순간 레이아웃이 튄다
- [ ] preload 한 파일이 첫 화면에 실제로 쓰인다. `crossorigin` 이 있다
- [ ] 수치를 나열하는 곳에 `tabular-nums` 가 있다
- [ ] 한글 폰트를 명시했고 서브셋을 쓴다
- [ ] 웹폰트 임베딩 라이선스를 확인해 `design.md` 에 적었다
- [ ] **폰트를 못 받은 상태로 열어봤다.** 그 상태로도 읽힌다
### 자주 걸리는 것
- 폰트 서브셋 안 함 (한글 전체 폰트는 수 MB)
- 첫 화면 밖 이미지에 `loading="lazy"` 누락
- 3D/WebGL을 초기 번들에 포함 (뷰포트 진입 시 동적 import 해야 한다)
- 애니메이션이 `top`/`left`/`width` 를 건드림 → `transform` 으로 바꿔라
- `will-change` 남발 → 레이어가 늘어 오히려 느려진다
---
## 3. 반응형
- [ ] **320px** 폭에서 가로 스크롤 없음 (하드 게이트 #5 는 320~1920px 전 구간을 요구한다. 375px 만 보면 그 아래가 뚫린다)
- [ ] 1920px 이상에서 콘텐츠가 늘어지지 않음(최대 폭 제한)
- [ ] 중간 뷰포트(768~1024px)에서 레이아웃이 깨지지 않음 — **가장 자주 빠뜨리는 구간**
- [ ] 터치 타깃: **버튼·아이콘·카드 등 독립 컨트롤은 44×44px 이상**(Apple/Google 권고)
- [ ] 터치 타깃: **본문 안 인라인 텍스트 링크는 24×24px 이상**(WCAG 2.5.8 AA). 여기에 44 를 요구하면 정상적인 내비 링크가 오탐된다
- [ ] 호버로만 접근되는 기능 없음
- [ ] 긴 단어/URL이 넘치지 않음 (`overflow-wrap: anywhere`)
- [ ] 가로 모드에서 첫 화면이 잠기지 않음
---
## 4. 콘텐츠
- [ ] 히어로가 **무엇인지** 말한다. 형용사만 있고 명사가 없으면 실패
- [ ] 로렘입숨이 남아 있지 않다
- [ ] 실제 콘텐츠 길이로 테스트했다 (짧은 제목만으로 맞춘 레이아웃은 긴 제목에서 깨진다)
- [ ] 빈 상태·오류 상태·로딩 상태가 있다
- [ ] 링크가 어디로 가는지 텍스트만 보고 알 수 있다 ("여기를 클릭" 금지)
- [ ] 이미지가 없거나 실패했을 때 레이아웃이 무너지지 않는다(`aspect-ratio` 지정)
---
## 5. 디자인 자체
기계로 못 잡는 부분이다. **정직하게 답해라.**
1. **이 사이트를 다른 회사의 것으로 바꿔도 그대로 쓸 수 있는가?** → 그렇다면 브리프에 맞춘 것이 없다
2. **2단계에서 정한 한 문장 컨셉이 화면에서 보이는가?** → 안 보이면 컨셉이 문서에만 있는 것이다
3. **감수하기로 한 리스크가 실제로 들어갔는가?** → 구현 중에 안전한 쪽으로 후퇴하지 않았는지
4. **1단계 레퍼런스 R2(다른 업종의 톤)의 흔적이 있는가?** → 없으면 결국 R1을 베낀 것이다
5. **강조색이 하나인가?**
6. **여백이 의도적인가, 남은 것인가?**
---
## 6. 최종 게이트
전부 통과해야 끝난다.
- [ ] 0장 기계 검사 3종 통과
- [ ] 접근성 표 전 항목 통과
- [ ] 성능 예산 내 (또는 초과 이유 명시)
- [ ] 반응형 체크리스트 통과
- [ ] 콘텐츠 체크리스트 통과
- [ ] 5장 여섯 질문에 정직하게 답했고, 실패 항목을 고쳤다
- [ ] `antipatterns.md` 자가 채점표 통과
**하나라도 실패하면 출시가 아니라 4단계 복귀다.**
> 근거: research/references/04-ai-slop-signatures.md, research/motion/01-principles.md, research/three/04-performance.md (조사일 2026-08-20)