---
name: html-prototype
description: >
결정을 검증할 목업이나 실제로 동작하는 프로토타입을 자체 완결 HTML 하나로 만들 때
로드한다. 시나리오 하나를 골라 상태 모델을 먼저 세우고 키보드까지 동작하게 만든다.
"눌러볼 수 있게 만들어 줘", "목업 하나 뽑아 줘", "이 흐름 태워 보자"가 트리거다.
구조가 아직 안 정해졌으면 html-wireframe이, 제품에 들어갈 UI 코드는 frontend-design이,
읽는 리포트는 html-report가, 개념을 큰 그림으로 설명하는 지면은 html-explainer가 맡는다.
compatibility: >
SaveFile 빌트인이 제시된 런에서는 HTML 파일로 남기고, 없으면 코드 블록으로 낸다.
브라우저가 없어 렌더링과 상호작용을 직접 확인하지 못하므로 확인하지 못한 항목을 밝힌다.
---
# HTML 프로토타입
제품 결정 하나를 검증할 수 있는 모형을 만든다. 목표는 가능한 화면을 다 만드는 것이 아니라
**중요한 질문 하나를 눌러볼 수 있게** 만드는 것이다. 넓고 가짜인 제품보다 좁고 진짜인
흐름 하나가 낫다.
## 충실도 모드를 고른다
| 열린 질문 | 모드 |
|---|---|
| 시각 위계, 레이아웃, 활자, 색, 제품 적합성 | **목업** — 다듬어진 반응형 정적 화면 |
| 내비게이션, 입력, 상태 변화, 피드백, 복구, 전환 | **프로토타입** — 동작하는 흐름 |
목업을 완성돼 보이게 하려고 동작을 덧붙이지 않는다. 두 모드를 다 요청받으면 콘텐츠와
구조를 같게 유지해 충실도 차이만 비교되게 한다.
목업 모드에서도 시맨틱 구조와 보이는 focus 스타일은 유지하고, **어디까지가 정적인지**를
화면이나 핸드오프에 밝힌다.
## 방향을 어디서 가져오는가
충돌하면 위가 이긴다.
1. 사용자가 명시한 시각·기능 지시
2. 프로젝트의 디자인 시스템, 토큰, 상호작용 관례
3. 제품, 대상 사용자, 콘텐츠, 시나리오
4. 모델 자신의 디자인 판단
디자인 시스템이 없으면 주제와 사용 맥락에서 방향을 만든다. 그라데이션, 어두운 대시보드,
서로 바꿔도 되는 카드, 장식용 지표를 기본값으로 쓰지 않는다. **현장 작업 도구와 편집
워크플로와 재무 승인 화면이 같은 제품처럼 보이면 방향을 안 고른 것이다.** 시각 클리셰의
목록은 같은 플러그인의 `frontend-design` 스킬 안에 있다 — **그 스킬을 열면 그 디렉터리의**
`references/ai-visual-tells.md`다. 이 스킬이 정한 것과 겹치면 이 스킬이 이긴다.
만들기 전에 정한다.
- 사용자와 그가 끝내야 하는 결정적인 일
- 경계가 분명한 시나리오 하나
- 목업인가 프로토타입인가
- 시각 방향의 출처
- 상태 모델
- 실제 제품이 이어받는 지점
## 흐름 하나를 제대로 만든다
리뷰 질문에 답할 수 있는 가장 작은 흐름을 고른다. 이름·날짜·상태·수량·문구를 현실적이고
서로 앞뒤가 맞게 채운다.
- 모델링한 범위 안에서는 내비게이션이 실제로 동작하게 한다.
- form 은 label, 검증, 제출 피드백, 합리적인 기본값까지 구현한다.
- dialog 는 중단이나 확인이 시나리오의 일부일 때만 쓴다.
- 전환은 연속성과 상태 변화를 설명할 때만 쓴다.
- **죽은 버튼을 남기지 않는다.** 실제 시스템이 담당하는 행동이면 완료된 척하지 말고
경계를 화면에 밝힌다.
## 상태 모델을 먼저 나열한다
화면을 짜기 전에 `references/states.md`의 표로 상태를 적는다. 표를 먼저 쓰면 만들다
상태를 잊지 않고, 무엇을 빼기로 했는지가 남는다.
체크리스트를 채우려고 시나리오에 없는 상태를 억지로 끼워 넣지 않는다. 대신 **뺀 상태를
핸드오프에 적는다.**
## 상호작용을 끝까지 만든다
- 의미가 맞으면 네이티브 요소를 쓴다.
- 모델링한 흐름 전체를 키보드만으로 통과할 수 있게 한다.
- focus 를 보이게 두고, 의미 있는 전환 뒤에는 focus 를 의도한 자리로 옮긴다.
- dialog 에는 접근 가능한 이름을 주고, focus 를 가두고, `Escape`로 닫고, 닫힌 뒤 트리거로
focus 를 되돌린다.
- form 오류를 해당 컨트롤에 연결하고 중요한 상태 변화를 알린다.
- 필수 동작을 hover 뒤에 숨기지 않는다.
- `prefers-reduced-motion`에서 모션을 끄되 상태 피드백은 남긴다.
- 터치 대상을 충분히 키우고 page body 에 가로 스크롤이 생기지 않게 한다.
- 상태를 색만으로 구분하지 않는다.
## 빌드 계약
자체 완결 HTML 하나로 낸다. CSS 와 JavaScript 를 전부 인라인하고 빌드 도구, 인증, 실시간
API, 외부 서비스를 요구하지 않는다.
- **바깥으로 요청하지 않는다.** 웹폰트, CDN, 원격 이미지, `fetch` 전부. 이미지는 data URI
로 넣거나 SVG 로 그린다.
- **저장소와 부모 창을 건드리지 않는다.** `localStorage`·`sessionStorage`·쿠키·`window.parent`
는 격리된 자리에서 예외를 던진다. 상태는 DOM 과 메모리 안에서만 다룬다.
- **링크는 문서 안(`#id`)이나 절대 주소로.** 상대 경로는 파일이 놓이는 위치에 따라 깨진다.
- 데스크톱 화면을 줄이는 대신 반응형으로 다시 구성한다.
- 토큰은 작게 유지하고 이 방향에만 쓰이는 값으로 둔다.
- 사용자가 입력한 문자열을 화면에 다시 그릴 때 `innerHTML` 로 붙이지 않는다.
## 산출
**이번 런에 `SaveFile`이 있으면 그것으로 낸다.** `mime_type`은 `text/html`, `content`는 완성된
HTML 전문, `name`은 내용을 알아볼 수 있는 이름이다. 파일은 따로 전달되므로 답변에 본문을 다시 붙이지 않는다.
`SaveFile`이 없으면 완성된 HTML 전문을 `html` 코드 블록 하나로 주고, `.html`로 저장해서
열면 된다고 알린다. 이때 파일을 만들었다고 말하지 않는다.
## 핸드오프
- 충실도 모드와 모델링한 시나리오
- 구현한 상태와 **일부러 뺀 상태**
- 실제 제품이 이어받는 지점 — 인증, 영속화, 권한, 롤백처럼 프로토타입 밖의 동작
- 확인하지 못한 렌더링·상호작용 조건. 브라우저가 없으므로 실제로 눌러 봤다고 말하지 않고,
소스를 읽은 것을 검증으로 대체하지 않는다