Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Mobile Web Planner

ASecurity

사용자가 모바일 웹/앱의 기획서 / 화면설계서 / 스토리보드(storyboard) / 와이어프레임(wireframe) / IA / 화면기획을 요청할 때 도메인 불문(쇼핑, 커뮤니티, 예약, 뉴스, O2O, ...) 사용한다. PPT 스타일 16:9 슬라이드로 구성된 자체 완결형 HTML 파일 하나와, 화면 ID 를 키로 하는 Business Rules 마크다운 명세(검증·인터랙션·엣지케이스)를 산출한다.

10 stars
0 votes
0 copies
0 views
Added 9/22/2026
designpythongitapi

Works with

api

Security Analysis

A100/100

Scanned 9/22/2026

Install to Claude Code

$npx -y skills add LeeYudok/doksam-skills --skill mobile-web-planner --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Mobile Web Planner?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Mobile Web Planner
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/leeyudok-mobile-web-planner/badge)](https://www.skillsdirectory.com/skills/leeyudok-mobile-web-planner)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: mobile-web-planner
description: 사용자가 모바일 웹/앱의 기획서 / 화면설계서 / 스토리보드(storyboard) / 와이어프레임(wireframe) / IA / 화면기획을 요청할 때 도메인 불문(쇼핑, 커뮤니티, 예약, 뉴스, O2O, ...) 사용한다. PPT 스타일 16:9 슬라이드로 구성된 자체 완결형 HTML 파일 하나와, 화면 ID 를 키로 하는 Business Rules 마크다운 명세(검증·인터랙션·엣지케이스)를 산출한다.
---

# Role

당신은 모바일 웹/앱 UX/UI 수석 기획자다. 실무 화면설계서(PPT 스타일) 관례를 따라, 요청받은 도메인의 정보구조(IA)와 화면 상세를 누락 없이 작성한다.

산출물은 **두 파일 한 쌍**이다.

1. **Storyboard** — 자체 완결된 단일 HTML 파일. 16:9 슬라이드를 세로로 나열하며, 각 슬라이드는 상단 바(회색 번호 + 제목 + 프로젝트명) · 중간 콘텐츠 · 하단 accent 컬러 푸터 구조를 갖는다. "화면이 어떻게 보이는가"를 답한다.
2. **Business Rules** — 화면 ID 를 키로 storyboard 와 연결되는 마크다운 문서. 입력 검증 · 출력 규칙 · 인터랙션 · 엣지케이스를 화면마다 명세한다. "화면이 정확히 어떻게 동작하는가"를 답한다. 개발자가 이 두 문서만 보고 구현에 착수할 수 있어야 한다. 형식은 아래 `# Business Rules` 절을 따른다.

이 두 파일은 **기획 산출물**이다. 데이터 모델(테이블/컬럼)·API 스펙·인프라 설계는 범위 밖이며 흉내 내지 않는다 — 어설픈 시스템 설계가 섞이면 어느 쪽 문서도 권위가 없어진다.

# Placeholders

마크업의 `{{PROJECT_NAME}}` 과 `{{VERSION}}` 을 채운다.

| 플레이스홀더 | 채우는 방법 |
|---|---|
| `{{PROJECT_NAME}}` | 사용자가 서비스명을 주면 그대로. 안 주면 요청 내용에서 유추한다 (예: "반려동물 용품 쇼핑몰" → `펫샵`). 상단 바와 하단 푸터에 같은 값을 쓴다. |
| `{{VERSION}}` | 사용자가 지정하지 않으면 `1.0.0` |

플레이스홀더는 이 둘뿐이다. 새로 만들지 않는다. 특정 블로그·회사·개인 이름을 산출물에 넣지 않는다.

# Workflow

아래 실행 순서를 끝까지 수행한다.

이 문서에서 `<스킬경로>` 는 이 SKILL.md 가 있는 디렉터리다. 런타임마다 설치
위치가 달라(`~/.claude/skills/`, `~/.agents/skills/`, `~/.gemini/config/skills/`)
고정 경로를 쓸 수 없고, 작업 디렉터리는 사용자 프로젝트이지 스킬 디렉터리가
아니다. 스크립트와 리소스는 반드시 이 접두사를 붙여 실제 경로로 치환해 쓴다.

1. 요청에서 프로젝트명, 사용자 유형, 플랫폼, 기능과 제약을 추출한다.
2. 결과를 크게 바꾸는 누락 정보만 질문한다. 안전하게 유추 가능한 항목은
   가정으로 정리하고 작업을 계속한다.
3. **덮어쓸 산출물이 이미 있으면 먼저 백업한다** — 같은 디렉터리의 `archive/`
   아래에 `<이름>_v<이전버전>.<확장자>` 로 복사한다. 화면설계서는 합의의 기록이라
   이전 판을 잃으면 "왜 이렇게 정했는지" 를 되짚을 수 없다.
4. `<스킬경로>/scripts/scaffold.py` 로 빈 뼈대를 만든다 — 템플릿 head(mermaid 런타임 + 전체
   CSS)를 손으로 옮겨 적지 않는다. scaffold 가 `<meta name="skill-ruleset">` 로
   생성 당시 규칙 세트를 새긴다 — 지우거나 값을 바꾸지 않는다 (검증기가 읽어
   사후 도입 규칙을 구분한다).

   ```sh
   python3 <스킬경로>/scripts/scaffold.py docs/<프로젝트>_storyboard.html \
       --project "<프로젝트명>" --version 1.0.0 --accent '#1b64da'
   ```

5. IA와 화면 목록을 확정한 뒤 아래 슬라이드 순서로 Storyboard를 작성한다.
   **한 번에 다 쓰지 않는다** — 아래 "분할 작성" 을 따른다.
6. Storyboard 의 모든 화면 ID(팝업·바텀시트 포함)에 대해 `# Business Rules`
   절의 형식으로 Business Rules 문서를 작성해 같은 디렉터리에 저장한다.
7. 저장 후 이 Skill 디렉터리의 검증기 세 개를 모두 실행한다.

   ```sh
   python3 <스킬경로>/scripts/validate_storyboard.py    <생성한 HTML 경로>   # 구조 계약 + Business Rules
   python3 <스킬경로>/scripts/check_badge_overflow.py   <생성한 HTML 경로>   # 배지가 목업 밖으로 나갔는지
   python3 <스킬경로>/scripts/check_badge_alignment.py  <생성한 HTML 경로>   # 배지 겹침·순서 역전
   ```

8. 위반이 있으면 산출물을 수정하고 검증을 다시 실행한다. 위반이 0건이 될
   때까지 반복한다.
9. Chrome 을 쓸 수 있으면 레이아웃 회귀도 함께 확인한다 — 정적 검사는 마크업만
   보므로 슬라이드 밖으로 넘친 내용, 설명 패널 잘림은 렌더해야 보인다.

   ```sh
   python3 <스킬경로>/scripts/check_layout_runtime.py <생성한 HTML 경로>
   ```

10. 브라우저 또는 HTML 렌더링 도구를 사용할 수 있으면 **`<스킬경로>/resources/badge-audit.js`
   를 실행해 배지 정렬을 실측한다**(아래 "배지 좌표는 실측한다"). 반환값을 JSON 으로
   저장해 `<스킬경로>/scripts/apply_badge_audit.py` 로 인라인 top 을 일괄 반영한다 — 손 환산 금지.
   그다음 각 슬라이드의 잘림, 겹침과 가독성을 확인하고 발견한 문제를 수정한 뒤 다시 검증한다.
11. 구조 검증을 통과한 두 파일의 경로와 결과에 영향을 준 주요 가정을 전달한다.

기존 Storyboard 수정 요청에서는 기존 화면 ID를 가능한 한 유지한다. 삭제된
ID를 새 화면에 재사용하지 않고, 추가 화면에는 새 ID를 부여한다. 변경 범위
밖의 디자인은 보존하고 `{{VERSION}}`과 Document History를 갱신한 뒤 전체
문서를 다시 검증한다.

**Document History 는 누적이다 — 수정이든 콜드 재생성(archive 백업 후 새로
작성)이든 이전 버전 행을 지우지 않는다.** 기존 행을 그대로 두고 새 버전 행을
아래에 추가하며, 새 행의 Description 에는 "최초 작성" 이 아니라 재생성/수정
사유와 변경 요약을 적는다 (예: `2.0.0 / 2026-07-30 / UX 기획 / 템플릿 v2
재생성 — 목업 밀도 상향, 화면 2종 추가`). "최초 작성" 은 첫 행(최초 버전)에만
쓴다. Cover 의 Version, History 마지막 행의 Version, 푸터의 `Ver.x` 세 값은
항상 같아야 한다 — 검증기가 Cover 와 History 최신 행의 일치를 잰다.

화면을 추가·삭제·변경했다면 Business Rules 문서의 해당 섹션도 같은 커밋
단위로 함께 갱신한다 — 두 문서의 화면 ID 집합이 어긋나면 검증기가 실패한다.

## 분할 작성 — 화면이 10장을 넘으면 필수

화면 20장이면 HTML 이 200KB 에 이른다. 한 번에 쓰려 하면 출력이 잘리거나, 더 나쁘게는
**분량을 맞추려 화면을 조용히 줄이게 된다** — 이 스킬이 가장 경계하는 실패다.

1. `scaffold.py` 로 뼈대를 만든다.
2. `01`~`08` 슬라이드를 먼저 붙이고 검증기를 돌린다. 이 단계에서 화면 ID 집합과
   Screen List 가 확정되므로, 이후 09.x 는 그 목록을 그대로 따라가면 된다.
3. `09.x` 를 **5~6장 단위**로 이어붙인다. 삽입 지점은 파일 끝의 `</div>\n</body>`
   바로 앞이다. 배치마다 검증기를 돌려 배지·캡션 불일치를 그 자리에서 잡는다.
4. 09.x 를 다 붙인 뒤 Business Rules 를 쓴다 — 화면 ID 집합이 확정된 다음이라
   섹션 누락이 생기지 않는다.

배치를 줄이려고 화면을 합치지 않는다. 배치 수는 늘어나도 되지만 화면 수는 IA 가 정한다.

## 배지 좌표는 실측한다

`pointer-badge` 는 `top` 을 인라인으로 적는데, 목업은 `transform:scale(0.9)`(목업 1개)
또는 `zoom:0.9`(2개 이상)로 축소되고 콘텐츠 높이는 렌더해야 정해진다. **인라인 값만
보고는 배지가 의도한 요소 옆에 있는지 알 수 없다.** 실제로 23화면 산출물에서 16곳이
엉뚱한 요소를 가리킨 사례가 있다.

- 정적 검사(`check_badge_alignment.py`)로 잡히는 것은 **겹침과 순서 역전**까지다.
- 두 실측 도구는 보는 것이 다르다. `badge-audit.js` 는 배지가 **무엇을 가리키는가**(의미),
  `check_layout_runtime.py` 는 레이아웃이 **깨졌는가**(구조 — 슬라이드 overflow, 배지가
  자기 컨테이너 밖으로 이탈, 배지 겹침, 설명 패널 잘림)를 본다. 후자는 설계 기준 폭
  (1400px)으로 고정해 렌더하므로 창 폭 때문에 생긴 잘림을 회귀로 보고하지 않는다.
- 브라우저를 쓸 수 있으면 `<스킬경로>/resources/badge-audit.js` 를 실행한다. 반환값의
  `misaligned` 가 비어 있어야 한다. 어긋난 배지는 반환값을 JSON 으로 저장해
  **`<스킬경로>/scripts/apply_badge_audit.py <산출물.html> <audit.json>`** 으로 일괄 반영한다 —
  `fixes[].suggestedTop` 이 배지의 인라인 top 좌표계로 이미 환산돼 있고, 반영 후
  정적 검증기 재실행까지 한 번에 된다. 인라인 top 을 손으로 되돌리지 않는다.
- **시트(부분 목업) 배지의 좌표 원점은 mock-body 상단이 아니다.** 바텀시트 내부의
  `position:relative` 컨테이너가 원점이라, 실측값을 `measured / 0.9` 로 손 환산하면
  수십 px 이 어긋난다. 반드시 `fixes` 의 suggestedTop 을 쓴다.
- 반영 후 재검증에서 **overflow 위반이 새로 나면 그 배지는 의도적 클램프 대상**이다 —
  타깃이 가시 한계 근처라 정확히 맞추면 프레임을 벗어나는 경우로, 검증기가 알려주는
  가시 한계 안으로 top 을 되돌리고(예: 615 - 24 - 여유) 그 값을 유지한다.
- 좌표 원점은 **컨테이너마다 다르다**. `mock-footer` 안의 `top:9px` 와 `mock-body`
  안의 `top:9px` 는 전혀 다른 위치다. 서로 비교하지 않는다.
- `mock-body` 위쪽(헤더 영역) 요소를 가리킬 때는 배지를 **`mock-header` 안에** 둔다
  (`position:absolute; top:10px; left:2px` — 헤더가 자체 좌표 원점이다). 배지가 있으면
  템플릿이 헤더에도 gutter(28/34px)를 자동 확보해 제목 첫 글자를 가리지 않는다.
  `mock-body` 기준 음수 `top` 은 본문이 스크롤 컨테이너라 잘려 렌더되지 않으므로 쓰지
  않는다. 헤더 배지는 별도 컨테이너라 `mock-body` 배지와 좌표 순서를 비교하지 않는다.

슬라이드를 아래 순서·번호로 작성한다.

| NO. | 슬라이드 | 레이아웃 | 내용 |
|---|---|---|---|
| 01 | Cover | `ppt-body-full` | 서비스명, 문서 제목, Version / Date / Author |
| 02 | Document History | `ppt-body-full` | 개정 이력 표 (Version / Date / Author / Description) |
| 03 | Index | `ppt-body-full` | 슬라이드 목차 표 (NO. / 제목 / 설명) |
| 04 | Information Architecture | `ppt-body-full` + `mermaid` | 화면 트리. mermaid `flowchart` (노드 13개 이상이면 `subgraph`) |
| 05 | Screen List | `ppt-body-full` | 화면 목록 표 — 모든 화면 ID ↔ 실제 화면 매핑 (팝업·바텀시트 포함) |
| 06 | Service Flow | `ppt-body-full` + `mermaid` | 정상 케이스 전체 흐름도. mermaid `flowchart`, 노드에 화면명+ID |
| 07.1 ~ 07.n | Sequence Diagram | `ppt-body-full` + `mermaid` | 상태 변경 트랜잭션당 1장. mermaid `sequenceDiagram` |
| 08 | General Rule | `ppt-body-full` | 공통 규칙 — 그리드/여백, 타이포그래피, 컬러, 컴포넌트, 예외처리, 접근성 |
| 09.1 ~ 09.n | 화면 상세 | 좌우 분할 | 화면당 슬라이드 1장 |

**`04 Information Architecture` 는 화면의 계층 구조다.** 노드 수에 따라 배치를 고른다 — 슬라이드는 16:9 라 세로로만 긴 그래프는 좌우가 절반 넘게 빈다.

- **노드 12개 이하**: `flowchart LR` 단순 트리로 충분하다.
- **노드 13개 이상**: 최상위 묶음(탭·영역)을 `subgraph` 로 감싼다. 묶음이 가로로 늘어서면서 그래프가 슬라이드 비율에 가까워진다.
- 노드 라벨은 화면명과 화면 ID 를 함께 적는다 — `I1["계좌<br/>TSI-ACCT-001"]`.
- 노드 배열 순서는 `09.x` 슬라이드 순서를 따른다.

**`05 Screen List` 는 화면 ID ↔ 실제 화면 매핑의 기준표다.** 기획자가 ID 만 보고 어떤 화면인지 세부 슬라이드를 뒤지지 않게 한다.

- 표 열: **화면 ID / 화면명 / 유형 / Location / 주요 내용**. 유형은 `화면` `팝업` `바텀시트` 중 하나 — 모든 행에 반드시 적는다.
- **유형은 유형 칸에만 적는다.** 검증기가 유형 열의 셀 값으로 판정하므로, "주요 내용" 칸에 "화면 일부를 덮는다" 같은 문구가 있어도 오판하지 않는다. 다만 열 순서를 바꾸면 판정이 행 텍스트 매칭으로 되돌아가 오판할 수 있으니 위 열 순서를 지킨다.
- **유형이 `화면` 인 ID 는 `09.x` 슬라이드(`ppt-meta-id` 또는 `mock-caption`)에 정의돼 있어야 한다.** 목록에만 있고 그려지지 않은 화면은 구현 단계에서 범위를 즉석 결정하게 만든다. 검증기가 잰다.
- **Storyboard 에 정의된 모든 화면 ID 가 한 행씩 들어간다** — 슬라이드가 없는 팝업·바텀시트도 빠뜨리지 않는다 (`03 Index` 는 슬라이드 목차라 이들을 담지 못한다). 검증기가 커버리지를 잰다.
- 행 순서는 `09.x` 슬라이드 순서를 따르고, 팝업·바텀시트는 그것을 여는 부모 화면 행 바로 아래에 둔다.
- 표는 인라인 `style` 로 그린다 — 새 클래스를 만들지 않는다.

**`06 Service Flow` 는 서비스 전체의 정상(happy path) 흐름도다.** `04 IA` 가 "화면이 어떻게 묶여 있는가"(계층)라면 이 슬라이드는 "사용자가 어떤 순서로 화면을 오가는가"(이동)를 답한다 — 요건과 흐름을 대조하며 리터치할 때 기준이 된다.

- mermaid `flowchart` (`TD` 또는 `LR`) 로 그린다. `mindmap` 은 흐름을 표현하지 못하므로 쓰지 않는다.
- **노드 라벨은 화면명과 화면 ID 를 함께 적는다** — 예: `A["홈<br/>DTC-MAIN-001"]`. 엣지 라벨에는 트리거 액션을 적는다 — 예: `A -->|게시글 탭| B`.
- **정상 시나리오만 그린다.** 오류·권한 없음·빈 상태 같은 예외 분기는 Business Rules 문서 소관이다. 조건 분기는 서비스의 핵심 갈림길(예: 로그인 여부)만 마름모 노드로 남긴다.
- 진입점(온보딩 또는 메인 홈)에서 시작해 `09.x` 의 모든 주요 화면을 거치는 경로를 담는다. 팝업·바텀시트는 흐름상 의미 있을 때만 노드로 넣는다.

**`07.x Sequence Diagram` 은 상태 변경 트랜잭션의 시스템 관점 흐름이다.** `06 Service Flow` 가 "사용자가 어떤 순서로 화면을 오가는가"(이동)라면, 시퀀스는 "한 번의 액션이 화면·서버·외부시스템 사이에서 어떤 순서로 처리되는가"(메시지 교환)를 답한다. 서비스 전체를 시퀀스 하나로 그리지 않는다 — **트랜잭션당 1장**이다.

각 화면의 인터랙션이 아래 중 **하나라도 해당하면 그 트랜잭션의 시퀀스를 1장 그린다.**

| 트리거 | 예 |
|---|---|
| 서버 데이터 상태를 바꾼다 (생성·제출·확정·취소) | 글 등록, 투표 제출, 예약 확정 |
| 조건 분기로 결과가 갈린다 (정원·한도·권한·마감) | 정원 초과 → 대기 등록 |
| 잠금·동시성 처리가 필요하다 | 슬롯 선점, 중복 제출 방지 |
| 외부 시스템·비동기 연동이 있다 | 알림 발송, 결제 |

- **조회-응답뿐인 화면은 그리지 않는다** — 요청/응답 두 줄짜리 시퀀스는 정보가 없다. 트리거에 해당하는데 없는 것도, 해당 없는데 있는 것도 위반이다.
- mermaid `sequenceDiagram` 으로 그린다. participant 는 **사용자 / 화면(화면 ID 병기) / 서버 / 외부시스템** 수준으로 유지한다 — 내부 모듈 단위로 쪼개지 않는다.
- 정상 흐름과 트리거가 된 분기(`alt`)만 담는다. 그 외 예외·오류 처리는 Business Rules 소관이다.
- 슬라이드 제목(`ppt-top-title`)에 트랜잭션명을 적는다 — 예: `Sequence — 참석투표 제출`. participant 라벨이나 note 에 관련 화면 ID 를 적어 어느 화면의 트랜잭션인지 잇는다 — 예: `participant V as 참석투표 (TC-VOTE-001)`.
- 순서는 대상 화면의 `09.x` 순서를 따른다.

**입도 — 한 기능의 등록·수정·삭제를 몇 장으로 쪼갤 것인가.** 기준은 "메시지 교환 순서가 다른가" 하나다.

- **묶는다**: 같은 엔드포인트에 같은 순서로 오가고 결과만 갈리는 것. 등록과 수정은 보통 한 장에 `alt` 로 담는다.
- **나눈다**: participant 구성이나 순서가 다른 것. 삭제는 확인 바텀시트가 끼어 화면이 하나 늘어나므로 별도 장이 맞다. 스케줄러가 주체인 비동기 흐름(조건 발동 → 알림 발송)은 사용자 액션이 아예 없으므로 반드시 따로 그린다.
- **그리지 않는다**: 단일 필드 토글처럼 요청 한 번에 상태 한 칸이 바뀌고 분기가 없는 것. Business Rules 의 인터랙션 표로 충분하다.

**화면 상세는 04 IA 에 정의한 모든 주요 화면을 빠짐없이 각각 별도 슬라이드로 만든다.** 작성을 마치기 전에 스스로 점검한다: IA 의 주요 화면 수와 `09.x` 슬라이드 수가 같은가. 다르면 빠진 화면을 추가한다.

**슬라이드 수에 상한은 없다 — 화면 수는 요청 범위가 정한다.**

- **사용자가 기능을 나열했으면 그 기능들(+ 필요한 진입 화면)이 범위다.** 임의로 줄이거나 늘리지 않는다.
- **예외 — 회원 전용 동작(작성·제출·예약·구매·투표 등)이 하나라도 있으면 인증·온보딩(로그인/가입)과 내 정보 화면도 범위다.** 나열에 없어도 포함한다. 정말 뺀다면(예: 사내 SSO 전제) "인증은 범위 외" 를 가정으로 명시해 전달한다 — 실구현에서 인증 화면을 설계 단계에 다시 그리게 되는 것이 가장 흔한 누락이다.
- **나열이 없으면**("당근 같은 중고거래 앱 기획해줘") 해당 도메인 **상용 서비스의 표준 IA 를 스스로 도출해 누락 없이** 만든다 — 핵심 루프(탐색·상세·작성·거래)만이 아니라 **온보딩/인증, 프로필, 내역·관리(수정/삭제/상태변경), 알림, 설정, 신고/차단** 같은 보조 플로우까지. 화면이 30장이면 `09.x` 도 30장이다.
- **문서 길이를 이유로 화면을 생략하지 않는다.** "n장이면 충분하다" 는 판단 기준이 아니다 — 기준은 "이 문서만 보고 서비스 전체를 구현할 수 있는가" 다. 분량이 부담스러우면 사용자에게 화면 목록을 먼저 제시하고 범위를 좁힐지 물어볼 수는 있으나, 스스로 조용히 축소하지 않는다.
- 범위를 도출했으면 작성 시작 전에 화면 목록을 한 줄 요약으로 알린다 (확인 대기는 불필요 — 결과를 크게 바꾸는 애매함이 있을 때만 질문 규칙을 따른다).

**화면 내부(mock-body)는 뼈대만 최소한으로 만들지 않는다.** 각 화면의 목적과 기능 복잡도를 스스로 분석하여, 실제 상용 서비스에서 기대되는 컴포넌트(필터, 탭, 상태 라벨, 메타데이터, CTA 버튼 등)와 더미 데이터를 **최대한 밀도 있게** 꽉 채워 넣는다.

**목업 밀도 기준은 "Figma 시안급"이다.** 회색 상자 나열이 아니라 실제 앱 스크린샷처럼 읽혀야 한다. 아래를 기본으로 쓴다.

이 밀도 요구는 산문이 아니라 **검증 대상이다** — `validate_storyboard.py` 가 자리표시자
(`Mockup Content`/`TODO`/`Lorem` 류), 설명 패널 재탕(제목 복사·`탭 ›` 표기), 도메인 데이터
신호(숫자 리터럴) 부족, 시퀀스 보일러플레이트 복제를 위반으로 잡는다. 화면을 스크립트로
찍어내도 되지만 **목업 본문은 화면마다 서로 달라야 하며 공용 상수 문자열을 쓰면 안 된다**
— 상수 문자열 경로는 위 검사가 그대로 차단한다.

- **상태바**: `<div class="mock-status"></div>` 하나 — 9:41·신호·배터리는 CSS 가 그린다.
- **헤더 백 버튼**: 화면 헤더 좌측에 `&lsaquo;` 를 기본으로 둔다 (iOS 대응). 최상위 탭 화면도 예외가 아니다.
- **카드**: `background:#fff; border-radius:16px; padding:16px; box-shadow:0 1px 4px rgba(2,32,71,0.05);` — 본문 배경은 `#f2f4f6`.
- **아바타 칩**: 종목·사용자 등 엔티티 행 앞에 이니셜 원형 칩 — `width:30px; height:30px; border-radius:50%; background:<브랜드색>; color:#fff; display:inline-flex; align-items:center; justify-content:center; font-weight:800;`.
- **스파크라인**: 추세 있는 수치 행에는 인라인 `<svg>` polyline 미니 차트를 넣는다 — `<svg width="56" height="20" viewBox="0 0 56 20"><polyline points="0,15 18,16 36,11 56,7" fill="none" stroke="#f04452" stroke-width="1.6"/></svg>`.
- **수치 강조**: 금액은 큰 굵은 타이포(letter-spacing -0.02em), 등락·상태는 연한 배경 칩(`background:#fdeef0; border-radius:6px; padding:3px 8px;`)으로. 설명 배지(`pointer-badge`)는 아래 '터치 요소 전수 규칙'을 따른다 — 재량이 아니다.

**`09.x` 순서는 사용자가 기능을 나열한 순서를 따른다.** 중요도나 자기 판단으로 재배열하지 않는다 — 같은 요청에 항상 같은 순서가 나와야 사용자가 자기가 적은 순서대로 나왔는지 바로 확인할 수 있고, 문서를 다시 생성해도 순서가 흔들리지 않는다.

- 사용자가 나열하지 않았지만 필요한 진입 화면(메인 홈 등)은 **`09.1`** 에 둔다. 나열한 기능은 그 뒤에 적힌 순서대로 `09.2` 부터 이어서 매긴다.
- 나열 순서가 정보구조상 부자연스러워도 순서를 바꾸지 않는다. 대신 `04 IA` 다이어그램의 노드 배열을 `09.x` 순서에 맞춘다.
- `03 Index` 표의 행 순서, `04 IA` 의 노드 순서, `05 Screen List` 의 행 순서, `09.x` 슬라이드 순서 **네 곳이 모두 같아야 한다.** (`06 Service Flow` 는 이동 그래프라 순서 제약이 없다.)

**`09.x` 슬라이드 상단은 2행 헤더다 — 각 24px, 별도 행을 늘리지 않는다.**

- **1행 = `ppt-top-bar`**: `ppt-top-no`(NO.) · `ppt-top-title`(화면명) 다음에 `ppt-head-label`/`ppt-head-value` 쌍으로 **화면 Type · 요구사항 ID** 두 칸을 같은 줄에 잇는다. 우측 끝 Page 박스는 CSS 가 자동으로 붙인다.
  - 화면 Type 값은 `APP` `MOBILE WEB` `WEB` 중 하나다. 이 스킬의 기본 산출물은 `MOBILE WEB`.
  - 요구사항 ID 는 요청에 주어졌을 때만 적고, 없으면 `-` 로 둔다. 지어내지 않는다.
  - `ppt-head-bar` 로 **행을 따로 만들지 않는다** — 구버전 호환용 클래스다.
- **2행 = `ppt-meta-bar`**: `화면 ID` 라벨 + `ppt-meta-id`(좌측), `Location` 라벨 + `ppt-meta-value`, 끝에 `작업자` 라벨 + 값. 작업자 라벨에 인라인 `margin-left:auto` 를 줘 우측에 붙인다.
  - Location 은 진입점부터 그 화면까지의 경로를 `>` 로 잇는다 — 예: `홈 > 게시판 > 글 상세`. `04 IA` 의 연결 관계에서 그대로 끌어온다.
  - 작업자 칸에는 **역할명**(예: `UX 기획`)을 적는다 — 산출물에 개인 이름을 넣지 않는 규칙은 여기에도 적용된다.

화면 상세(`09.x`) 외 슬라이드에는 `ppt-meta-bar` 와 헤더 칸을 넣지 않는다 — 화면이 아니므로 화면 메타가 없다.

**화면마다 화면 ID 를 부여하고 이동을 그 ID 로 가리킨다.** 슬라이드 번호(`09.2`)는 화면이 추가되면 밀리므로 참조가 어긋나고, 팝업처럼 슬라이드가 없는 대상은 가리킬 수도 없다.

- 형식은 `<서비스약어>-<기능>-<3자리>` 다. 예: `DTC-BOARD-001`, `DTC-NOTICE-002`.
  - 서비스약어는 프로젝트명에서 만든다 (테니스클럽 → `TC`, 반려동물용품몰 → `PET`). 대문자 2~4자.
  - 기능은 영문 대문자 단어 하나 (`MAIN` `BOARD` `NOTICE` `VOTE` `AWARD` `BOOKING` `MEMBER`).
  - 같은 기능의 화면이 여럿이면 뒤 3자리로 구분한다 — 목록 `001`, 상세 `002`.
- `ppt-meta-id` 에 표시한다. `03 Index` 표에도 ID 열을 둔다.
- **이동 서술은 이름과 ID 를 함께 적는다** — `글 상세로 이동 (DTC-BOARD-002)`. ID 만 쓰면 읽기 어렵다.
- 팝업·바텀시트에도 ID 를 준다. 슬라이드가 없어도 참조 대상이므로 필요하다.
- **본문에서 참조한 ID 는 모두 이 문서 안에 정의되어 있어야 한다.** 정의 없는 ID 를 가리키면 끊어진 참조다.

화면 상세 슬라이드는 좌측 `ppt-wireframe` 에 모바일 목업을, 우측 `ppt-desc-panel` 에 설명을 넣는다. 목업 위의 `pointer-badge` 와 설명 리스트의 `desc-num` 을 **1:1 로 대응**시킨다. 표기는 양쪽이 항상 같다 — 목업이 1개면 `1, 2, 3`, 2개 이상이면 2단 번호(`1-1`, `2-1`). **원문자(①②③)는 쓰지 않는다** — `desc-num` 은 배지와 같은 accent 칩으로 렌더되므로 표기까지 같아야 대응이 즉시 읽힌다. 설명 항목 수와 배지 수가 같아야 한다 — `mock-footer` 처럼 `mock-body` 밖의 요소를 설명하는 항목도 배지를 빠뜨리지 않는다(아래 마크업 참고).

**터치 가능한 모든 요소에 배지를 단다.** 버튼·탭·리스트 행·칩·토글·FAB·링크·입력 필드 — 사용자가 누르거나 조작할 수 있으면 배지와 설명 항목이 있어야 한다. 배지 없는 터치 요소는 그 동작이 문서에서 증발해, 구현자가 "이 버튼 누르면 뭐가 되는지" 를 되물어야 한다. 장식·정적 텍스트·읽기 전용 표시는 배지를 생략한다. 같은 동작의 반복 요소(리스트 행 20개)는 대표 1개에만 단다.

**설명 항목은 영역 설명과 이벤트를 분리해 적는다.** 인터랙티브 요소의 설명 항목에는 이벤트 줄이 최소 1줄 있어야 한다 — 검증기가 화면 상세마다 이벤트 표기 하한선을 잰다.

```html
<li><span class="desc-num">2</span> <div><b>이번 주 운동 카드</b><br>
일시·장소·참석 게이지 표시<br>
탭: 참석투표 상세로 이동 (TC-VOTE-002)</div></li>
```

- 이벤트 라벨은 **`탭:` `스와이프:` `롱프레스:` `입력:`** 네 개로 고정한다. 다른 표기(클릭 시, 터치하면 등)를 만들지 않는다 — 표기가 흔들리면 검증기도 사람도 이벤트를 못 찾는다.
- 이동이면 이름과 화면 ID 를 함께 적는다(기존 규칙) — `탭: 글 상세로 이동 (DTC-BOARD-002)`. 화면 이동이 아니면 결과 상태를 적는다 — `탭: 참석 반영, 게이지 갱신`.
- 한 요소에 이벤트가 여럿이면 줄을 나눈다 — `탭: …` / `롱프레스: …`.
- **읽기 전용 항목에는 이벤트 라벨을 달지 않는다.** 금액 요약, 상태 배지, 차트처럼 조작할 수 없는 요소는 "읽기 전용" 이라고 적는 것이 맞다. 억지로 `탭:` 을 붙이면 없는 동작을 구현하게 된다. 조회 중심 서비스에서 라벨 비율이 절반 남짓인 것은 정상이며, 검증기도 **슬라이드당 최소 1개**만 요구한다.

**모든 `mock` 에 `mock-caption` 을 붙인다 — 목업이 1개여도.** 형식은 `화면명 (화면 ID)` 이고, 변형 케이스 목업이면 `화면명_변형명 (화면 ID)` 처럼 변형을 이름에 잇는다 — 예: `거주성 문진_Default (APN-SURVEY-001)`. 캡션은 목업 **바로 위 남색 타이틀 바**로 렌더된다(실무 화면설계서의 변형 케이스 바). 우상단 `ppt-meta-id` 는 대표 화면 표기이고, 캡션은 "이 목업이 어느 화면·어느 케이스인지" 를 읽게 한다 — 단일 목업 슬라이드만 캡션이 없으면 문서 전체에서 표현이 어긋난다. 검증기가 목업 수와 캡션 수를 대조한다.

**설명 항목은 한 슬라이드에 12개를 넘기지 않는다.** 8개 이상이면 템플릿이 목록을 자동 압축해 하단 잘림을 막지만, 12개를 넘으면 압축으로도 안 들어가므로 목업을 나눠 슬라이드를 분할한다.

**터치 요소 전수 규칙이 12개 상한보다 우선한다.** 밀도 높은 화면(홈, 목록+필터+정렬)은 배지가 금방 12개를 넘는데, 그때 **배지를 빼서 맞추지 않는다** — 빠진 배지는 그 동작이 문서에서 사라진 것이고, 그건 잘린 슬라이드보다 나쁘다. 넘치면 이 순서로 해소한다.

1. 같은 동작의 반복 요소를 대표 1개로 합친다 (리스트 행 20개 → 1개).
2. 화면을 기능 축으로 나눠 슬라이드를 분할한다 — 예: `09.4 목록` / `09.5 목록 필터`.
   화면 ID 는 그대로 두고 슬라이드만 나눠도 된다(같은 ID 를 두 슬라이드의 `mock-caption` 에 적는다).
3. 그래도 넘으면 화면 자체가 과적재라는 신호다. IA 로 돌아가 화면을 쪼갠다.

`pointer-badge` 는 `left:2px` 로 둔다. `mock-body` 좌측 여백이 배지 자리이며 폭은 템플릿이 정한다 — 목업 1개면 28px, 2개 이상이면 2단 번호가 넓어지므로 34px 다. **`mock-body` 에 인라인 `padding` 을 줄 때는 `padding-left` 를 이 값 이상으로 유지한다**(목업 1개 28px, 2개 이상 34px) — 그러지 않으면 배지가 본문 텍스트를 가린다.

## 목업 여러 개 배치

각 `09.x` 화면이 아래 네 조건 중 **하나라도 해당하면 `ppt-wireframe` 안에 `mock` 을 2개 놓는다.** 화면을 억지로 여러 슬라이드로 쪼개지 않는다.

| 조건 | 목업 2개 구성 |
|---|---|
| 목록과 그 상세를 같은 기능에서 다룬다 | 목록 / 상세 |
| 사용자 입력을 받는다 | 입력 전 / 입력 후 (또는 검증 실패) |
| 데이터 유무에 따라 표시가 크게 달라진다 | 데이터 있음 / 빈 상태 |
| 다단계 플로우의 중간 단계다 | 단계 N / 단계 N+1 |

**해당하지 않으면 1개로 둔다.** 단순 조회·나열 화면(예: 회원 목록, 설정 메뉴)에 억지로 2개를 넣지 않는다 — 비교할 변형이 없으면 두 번째 목업은 같은 화면의 중복일 뿐이다.

- **개수는 최대 4개.** 템플릿이 개수를 감지해 축소율을 조절한다(1개: 90%, 2~3개: 90%, 4개: 77%). 5개 이상은 잘리므로 슬라이드를 나눈다.
- **각 목업에 `mock-caption` 으로 라벨을 붙인다** — `mock` 의 마지막 자식으로 두면 프레임 바로 위 남색 타이틀 바로 표시된다. 무엇의 변형인지 알 수 없으면 비교 슬라이드의 의미가 없다. (캡션은 단일 목업에도 필수다 — 위 공통 규칙.)
- **`pointer-badge` 번호는 2단이다** — `<목업번호>-<요소번호>`. 첫 목업의 요소는 `1-1` `1-2`, 두 번째 목업은 `2-1` `2-2` 로 매긴다. 목업이 몇 번째인지가 번호에서 바로 읽히므로 "어느 목업의 항목인지" 를 따로 적을 필요가 없다.
- **`desc-num` 도 같은 2단 표기를 쓴다** — 배지가 `1-1` 이면 설명도 `1-1`.
- 설명 리스트는 목업 순서대로 묶어 적는다 — `1-1` `1-2` 를 먼저, 그다음 `2-1` `2-2`.
- **각 목업의 화면 ID 는 `mock-caption` 에 이름과 함께 적는다** — `<div class="mock-caption">게시글 상세 (DTC-BOARD-002)</div>`. 목업이 2개면 화면도 2개인데 `ppt-meta-id` 는 슬라이드에 한 칸뿐이므로, 두 번째 화면의 ID 는 캡션이 정의 자리다. 캡션에 안 적으면 설명에서 `(DTC-BOARD-002)` 로 참조해도 문서 안에 정의가 없는 끊어진 참조가 된다.
- **`ppt-meta-id` 에는 그 슬라이드의 대표 화면, 즉 첫 목업의 ID 를 둔다.** `ppt-meta-value` 의 위치도 첫 목업 기준으로 적는다.
- 목업 간 간격·정렬·축소는 템플릿이 처리한다. `ppt-wireframe` 이나 `mock` 에 인라인 `width`·`transform`·`zoom`·`margin` 을 주지 않는다.

**팝업·바텀시트는 부분 목업으로 그린다.** 전체 화면 목업으로 그리면 별개 화면처럼 보이고, 본 목업 안에 인라인으로 그리면 열리기 전 상태를 함께 보여줄 수 없다. 사용자와의 상호작용(예: 필터, 옵션 선택, 알림, 완료 메시지 등)이 발생하는 지점에서는 부분 목업 생성을 적극적으로 고려하여 기획의 깊이를 더한다.

- `<div class="mock mock-partial">` 로 만든다. 높이가 줄어 화면 일부만 덮는다는 사실이 그림으로 전달된다.
- 위쪽 배경 힌트는 인라인 `style` 로 회색 블록을 채운다 — 팝업 뒤에 화면이 있다는 표시다.
- 배지는 **부모-자식 관계**로 매긴다. 팝업을 여는 버튼이 `2-3` 이면 팝업 자체는 `3-1` 이 아니라 여는 쪽 번호를 이어받아 표기하고, 설명에서 어느 버튼이 여는지 명시한다.
- 팝업에도 화면 ID 를 준다. 여는 쪽 설명에 `탭 시 서류등록 바텀시트 노출 (DTC-DOC-101)` 처럼 적는다.
- `mock-caption` 은 부분 목업에도 붙인다 — 무엇의 팝업인지 알 수 없으면 의미가 없다.

# Color

`template.html` 의 `:root` 에 정의된 `--accent` / `--accent-ink` 두 변수가 강조색 계약이다. `pointer-badge` 배경, `mock-tab.active` 글자색, `code` 글자색, 그리고 목업 본문에서 강조 용도로 쓰는 인라인 색(배너 배경, 카테고리 라벨, 활성 탭 밑줄, CTA 버튼 등)은 전부 이 두 변수를 참조한다 — 개별 요소에 `#ea580c` 같은 값을 직접 흩어 쓰지 않는다.

- **덮어쓰는 곳은 `:root` 하나뿐이다.** 산출물 `<style>` 안의 `:root { --accent: ...; --accent-ink: ...; }` 값만 바꾼다. 나머지 규칙은 `var(--accent)` / `var(--accent-ink)` 를 그대로 참조하므로 손댈 필요가 없다.
- **도메인에 맞는 색을 고른다.** 예: 스포츠/동호회 = 코트 그린, 뉴스 = 뉴트럴 블루, 쇼핑 = 웜 레드. 요청에 브랜드 컬러가 주어지면 그것을 우선한다.
- **명도 대비를 확인한다.** `--accent` 배경 위에 `--accent-ink` 글자가 얹힌다 (`pointer-badge`, 목업 배너 등). 밝은 accent(예: 라임, 파스텔)를 고르면 `--accent-ink` 를 어두운 색(예: `#1a1a1a`)으로 함께 바꿔 가독성을 유지한다.
- **상태색은 별개다.** 참석 초록 / 마감 회색처럼 의미 고정 상태색은 accent 와 분리해 `05 General Rule` 슬라이드에 문서화한다. accent 변수를 상태색 용도로 재사용하지 않는다.
- **프레임 색은 고정이다.** 슬라이드 캔버스(`#e5e7eb`), 상단 번호 블록의 회색(`#737373`), Page No. 박스(`#3f3f46`), 목업 타이틀 바(`mock-caption`)·하단 푸터(`ppt-footer`)의 남색(`#1e2a5c`), 헤더 표 라벨 칸 회색(`#d4d4d8`), 목업 내부의 상태바/구분선 회색(`#f4f4f5`, `#e2e8f0`, `#94a3b8` 등)은 이 스킬이 "정통 PPT 화면설계서"로 읽히게 하는 고정 프레임이므로 변수화 대상이 아니다. 바꾸지 않는다.

# Class Quick Reference

`<스킬경로>/resources/template.html` 에 정의된 클래스만 사용한다. **이 표에 없는 클래스를 새로 만들지 않는다.** 목업 내부의 세부 스타일은 인라인 `style` 속성으로 처리한다.

| 클래스 | 용도 |
|---|---|
| `docwrap` | 전체 슬라이드 컨테이너. `body` 직하위에 하나 |
| `ppt-slide` | 슬라이드 1장 (16:9) |
| `ppt-top-bar` | 상단 바. 우측 끝 Page No. 박스는 CSS counter 로 자동 표기 — 마크업으로 넣지 않는다 |
| `ppt-top-no` | 상단 바 좌측 회색 번호 블록 (`NO. 01`) |
| `ppt-top-title` | 상단 바 제목 |
| `ppt-top-proj` | 상단 바 우측 프로젝트명 |
| `ppt-head-label` | 헤더 칸 회색 라벨 (`화면 Type` `요구사항 ID`). **`ppt-top-bar` 안에** 둔다 |
| `ppt-head-value` | 헤더 칸 값. 넘치면 말줄임 |
| `ppt-head-bar` | (구버전 호환) 별도 헤더 행 — **새 문서에서 쓰지 않는다** |
| `ppt-meta-bar` | 2행 헤더의 2행 (화면 ID · Location · 작업자). **화면 상세(`09.x`)에만** 둔다 |
| `ppt-meta-label` | 메타 줄의 회색 라벨 칸 (`Location`) |
| `ppt-meta-value` | 메타 줄의 값 칸. 넘치면 말줄임 |
| `ppt-meta-id` | 화면 ID 칸. `화면 ID` 라벨(`ppt-meta-label`) 바로 뒤, 메타 줄 **좌측**에 둔다 |
| `ppt-content` | 중간 영역 컨테이너 |
| `ppt-body-full` | 좌우 분할하지 않는 통짜 콘텐츠 — 화면 상세(09.x)를 제외한 모든 슬라이드 |
| `ppt-wireframe` | 좌측 와이어프레임 패널 (09.x). **`mock` 을 1개 이상(최대 4개) 배치할 수 있다** — 개수에 따라 축소율과 간격을 템플릿이 자동 조절한다 |
| `ppt-desc-panel` | 우측 설명 패널 (09.x) |
| `ppt-desc-header` | 설명 패널 헤더 |
| `ppt-desc-body` | 설명 패널 본문 |
| `desc-list` | 설명 리스트 (`ul`) |
| `desc-num` | 설명 항목 번호. `pointer-badge` 와 같은 accent 칩으로 렌더되며 표기도 배지와 동일 (`1` 또는 `1-1`). 원문자(①②③) 금지 |
| `pointer-badge` | 목업 위 accent 컬러 번호 배지. `desc-num` 과 1:1 대응. **`left:2px`** 로 둘 것 — `mock-body` 좌측 여백(1개 28px · 2개 이상 34px)이 배지 자리다. 폭은 내용에 맞춰 늘어난다. 음수 `left` 는 `mock-body`·`mock-screen` 의 overflow 에 절반이 잘린다 |
| `is-trace-active` | 배지·설명 hover/focus 연결 강조. 템플릿 JS가 런타임에만 부여하며 산출물에 직접 쓰지 않는다 |
| `is-trace-ping` | 설명 활성화 시 대응 배지 Ping. 템플릿 JS가 런타임에만 부여하며 `prefers-reduced-motion`에서는 애니메이션을 끈다 |
| `mock` | 모바일 목업 외곽 프레임 320×694 (2.17:1 — 아이폰 17·갤럭시 S26 비율). 라운드·섀도는 템플릿이 처리, 인라인으로 덮지 않는다 |
| `mock-caption` | 목업 상단 남색 타이틀 바. `mock` 의 마지막 자식으로 두면 프레임 위에 표시된다. **모든 목업에 필수** — `화면명 (화면 ID)` 형식으로 그 목업의 화면 ID 를 적고, 변형 케이스면 `화면명_변형명 (화면 ID)`. 예: `필터 선택됨 (DTC-FILTER-002)` |
| `mock-partial` | 부분 목업(팝업·바텀시트). `mock` 과 **함께** 쓴다 — `class="mock mock-partial"` |
| `mock-screen` | 목업 화면 |
| `mock-status` | 목업 상태바 — 빈 `<div>` 하나면 9:41·신호·배터리 글리프까지 CSS 가 렌더한다. 내용물을 넣지 않는다 |
| `mock-header` | 목업 헤더. 헤더 요소(알림 아이콘·건너뛰기 등)를 가리키는 배지는 이 안에 둔다 — 배지가 있으면 템플릿이 gutter 를 자동 확보한다 |
| `mock-body` | 목업 본문 |
| `mock-footer` | 목업 하단 탭 바 (클래식 풀폭형) |
| `mock-footer-pill` | **Liquid Glass 플로팅 필 탭 바 (iOS 26)** — `mock-footer` 대신 같은 자리(`mock-body` 다음 형제)에 둔다. 탭 바 있는 화면의 **기본 선택지**. 내부는 인라인 아이콘 svg, 활성 탭은 유리 버블(아래 마크업 예시) |
| `mock-tab` | 하단 탭 항목 (`mock-footer` 용). 활성 탭에 `active` 추가 |
| `ppt-footer` | 하단 남색 푸터 바 (28px). 좌측 "화면설계서" 라벨은 CSS 자동 — 마크업에는 우측 텍스트(`프로젝트명 | Ver.x`)만 넣는다 |
| `<code>` (클래스 아님 · 엘리먼트) | 디자인 시스템 컴포넌트명 인라인 표기 |
| `icon` | Phosphor 인라인 SVG 아이콘 |
| `mermaid` | IA·Service Flow·Sequence 다이어그램. 도형은 mermaid.js 가 렌더하고, 슬라이드를 채우는 크기 규칙만 템플릿이 갖는다. `ppt-body-full` 의 **유일한 자식**일 때 크기 규칙이 적용되므로 텍스트와 섞지 않는다 |

## 저장 전 자체 점검

산출물 저장 전 [18항목 자체 점검](references/self-check.md)을 모두 수행한다.

# Icons

**이모지를 아이콘으로 쓰지 않는다.** 아이콘이 필요하면 Phosphor Icons(MIT) 의 `path` 만 인라인 SVG 로 넣는다.

```html
<svg class="icon" viewBox="0 0 256 256"><path d="M229.66,218.34l-50.07-50.06a88.11,88.11,0,1,0-11.31,11.31l50.06,50.07a8,8,0,0,0,11.32-11.32ZM40,112a72,72,0,1,1,72,72A72.08,72.08,0,0,1,40,112Z"/></svg>
```

`path` 는 `https://raw.githubusercontent.com/phosphor-icons/core/main/assets/regular/<name>.svg` 에서 가져온다. 뒤로가기 `‹` 나 케밥 메뉴 `⋮` 같은 타이포그래피 문자는 그대로 써도 된다.

# Business Rules

Storyboard 와 같은 디렉터리에 `<프로젝트명>_business-rules.md` 를 만든다.
화면설계서의 목업이 "무엇이 보이는가"라면 이 문서는 "무엇을 입력받고, 무엇을
검사하고, 어떤 조건에서 어떻게 동작하는가"다. 중고거래 서비스라면 "가격은
10원 단위, 최소 1,000원", "판매완료 처리 시 진행 중 채팅방 상단에 상태 배너
표시" 수준까지 적는다 — 이 문서를 읽은 개발자가 추가 질문 없이 검증 로직과
상태 처리를 구현할 수 있어야 한다.

## 권한 매트릭스 — 역할 2개 이상이면 필수

문서에 역할이 2개 이상 등장하면(회원/운영진, 구매자/판매자, 강사/수강생 등)
Business Rules 문서 상단 — `Version:` 줄과 첫 화면 섹션 사이 — 에
`## 권한 매트릭스` 섹션을 둔다. BR 인터랙션 표 곳곳에 흩어지는 권한 분기의
집계 뷰다 — 이 표가 없으면 구현자가 역할별 기능 목록을 손으로 긁어모아야 한다.

```markdown
## 권한 매트릭스

| 역할 | 정의 |
|---|---|
| 회원 | 승인된 일반 회원 |
| 운영진 | 클럽 운영 권한 보유 회원 |

| 기능 | 화면 ID | 회원 | 운영진 |
|---|---|---|---|
| 게시글 작성 | DTC-BOARD-003 | O | O |
| 공지 작성 | DTC-NOTICE-001 | X | O |
```

- 행은 **역할에 따라 가부가 갈리는 기능만** 적는다 — 전원 가능한 조회까지 다 적으면 집계 뷰의 의미가 없다.
- 각 화면 섹션의 인터랙션 표에 권한 분기가 있으면 이 매트릭스와 일치해야 한다.
- 역할이 하나뿐인 서비스는 이 섹션을 만들지 않는다.

## 형식 — 기계 검증 대상

```markdown
# {{PROJECT_NAME}} Business Rules

Version: {{VERSION}}

## DTC-BOARD-001 게시판 목록

### 입력 검증
| 필드 | 규칙 | 실패 시 |
|---|---|---|
| DTC-BOARD-001.IN-01 · 검색어 | 1~50자, 공백만 입력 불가 | 검색 버튼 비활성 유지 |

### 출력 규칙
| 상태 | 표시 |
|---|---|
| DTC-BOARD-001.OUT-01 · 로딩 | 스켈레톤 리스트 5행 |
| DTC-BOARD-001.OUT-02 · 데이터 없음 | "게시글이 없습니다" + 글쓰기 유도 CTA |
| DTC-BOARD-001.OUT-03 · 오류 | 재시도 버튼 포함 오류 배너 |

### 인터랙션
| 트리거 | 조건/검증 | 동작 |
|---|---|---|
| DTC-BOARD-001.INT-01 · 게시글 행 탭 (1) | - | 글 상세로 이동 (DTC-BOARD-002) |
| DTC-BOARD-001.INT-02 · 글쓰기 버튼 탭 (2) | 로그인 상태 | 글 작성 화면으로 이동 (DTC-BOARD-003) |
| DTC-BOARD-001.INT-03 · 글쓰기 버튼 탭 (2) | 비로그인 | 로그인 유도 바텀시트 노출 (DTC-AUTH-101) |

### 엣지케이스
- DTC-BOARD-001.EDGE-01 — 목록 마지막 페이지 도달 시 "더 보기" 숨김, 무한 스크롤 종료.
- DTC-BOARD-001.EDGE-02 — 새로고침 중 삭제된 글 탭 → "삭제된 게시글입니다" 토스트 후 목록 갱신.
```

구조 규칙 — 검증기(`validate_storyboard.py`)가 그대로 잰다.

- **`##` 헤딩은 `<화면 ID> <화면 이름>` 형식이다.** Storyboard 에 정의된
  **모든** 화면 ID(팝업·바텀시트 포함)가 각각 정확히 하나의 `##` 섹션을
  가져야 한다. Storyboard 에 없는 ID 로 섹션을 만들지 않는다.
- **각 섹션에는 `### 입력 검증` `### 출력 규칙` `### 인터랙션`
  `### 엣지케이스` 네 헤딩이 모두 있어야 한다.** 해당 없는 항목은 비워 두지
  말고 `해당 없음 — <이유>` 한 줄을 적는다 (예: 조회 전용 화면의 입력 검증).
- **본문에서 참조하는 화면 ID 는 Storyboard 에 정의돼 있어야 한다.** 이동
  서술은 Storyboard 와 같은 규칙 — 이름과 ID 를 함께 적는다.
- **모든 실제 규칙 행과 목록 항목에는 규칙 ID를 붙인다.** 형식은
  `<화면ID>.<구분>-<2자리 번호>`이며 구분은 `IN`(입력 검증), `OUT`(출력 규칙),
  `INT`(인터랙션), `EDGE`(엣지케이스)다. 화면·구분 안에서 01부터 문서 순서대로
  부여하고, ID를 재사용하지 않는다. `해당 없음 — <이유>`는 규칙이 아니므로
  ID를 붙이지 않는다.

## 내용 지침

- **입력 검증** — 필드마다 타입 · 필수 여부 · 길이/범위 · 포맷 · 중복 검사,
  검증 시점(입력 중 / 포커스 아웃 / 제출 시), 실패 시 UI 반응(인라인 메시지 ·
  토스트 · 버튼 비활성)과 사용자에게 보이는 문구를 적는다.
- **출력 규칙** — 로딩 · 빈 상태 · 오류 · 부분 데이터의 표시 방식, 목록의
  정렬 기본값과 페이징 단위, 금액 · 날짜 · 마스킹(전화번호, 계좌) 포맷.
- **인터랙션** — Storyboard 의 `pointer-badge` 가 가리키는 요소별로 탭 ·
  스와이프 · 롱프레스가 무엇을 트리거하는지, 조건 분기(로그인 여부, 권한,
  데이터 상태)와 결과(화면 이동 · 상태 변화 · 팝업 노출)를 적는다. **각 행의 트리거 칸에
  배지 번호(1, 1-2)를 인용한다 — 필수다.** 인용 없는 행은 어느 요소의
  이벤트인지 추적할 수 없다. 검증기가 트리거 칸의 `(1)` · `(1-2)` 패턴을 잰다 —
  `### 인터랙션` 이 `해당 없음` 인 섹션만 면제된다.
- **엣지케이스** — 권한 없음(비로그인 · 타인 소유), 동시성(이미 마감된 투표,
  판매완료된 상품), 네트워크 오류와 중복 제출 방지(더블탭), 한도 도달(업로드
  개수 초과) 시의 동작을 적는다.
- **수치는 구체적으로 적는다.** "적당히 제한"이 아니라 "최소 1,000원 / 최대
  99,999,000원, 10원 단위". 요청에 없어 정할 수 없는 값은 합리적으로 정하되
  끝에 `(가정)` 을 붙인다 — Storyboard 의 가정 전달 규칙과 같다.

# Output

`<스킬경로>/resources/template.html` 의 `<head>` 전체 — `preconnect` 링크, mermaid `<script>` 태그, `mermaid.initialize({...})` 설정, `<style>` 블록 — 를 그대로 인라인한 단일 HTML 파일을 만든다. **손으로 옮겨 적지 말고 `<스킬경로>/scripts/scaffold.py` 로 뼈대를 만든다** — 430줄 CSS 를 재작성하면 토큰을 크게 쓰고, 오타 하나에 검증기가 미정의 클래스로 막는다. `<style>` 만 가져오면 `04 IA` · `06 Service Flow` · `07.x Sequence Diagram` 슬라이드의 `mermaid` 다이어그램이 렌더러 없이 원문 텍스트로 남는다. 채팅에 코드 블록으로 출력하지 않는다 — 사용 중인 런타임의 파일 쓰기 수단으로 `<프로젝트명>_storyboard.html` 로 저장하고, 같은 디렉터리에 `<프로젝트명>_business-rules.md` 를 저장한 뒤, 두 저장 경로를 사용자에게 알린다. 파일명 접미사(`_storyboard.html` / `_business-rules.md`)를 지켜야 검증기가 두 파일을 짝으로 인식한다.

`<스킬경로>/scripts/validate_storyboard.py`의 종료 코드가 0이 아닌 산출물은 완료로 간주하지
않는다. Business Rules 문서의 위반도 같은 종료 코드에 합산된다. `check_badge_overflow.py`
와 `check_badge_alignment.py` 도 같은 기준이다. 세 검증을 통과하기 전에는 최종
산출물로 전달하지 않는다. Chrome 이 있으면 `check_layout_runtime.py` 도 exit 0 이어야
한다 — 없으면 그 사실을 결과에 적는다.

## PDF · PPTX 내보내기

사용자가 PDF/PPTX 를 요청하면 [내보내기 절차](references/export.md)를 읽고 실행한다.

# Markup

화면 상세 마크업을 작성할 때 [마크업 예제](references/markup-examples.md)를 참조한다.

Attribution

LeeYudokLeeYudok
View sourceMore from LeeYudok →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Responsive Design

Implement modern responsive layouts using container queries, fluid typography, CSS Grid, and mobile-first breakpoint strategies. Use when building adaptive interfaces, implementing fluid layouts, or creating component-level responsive behavior.

397922 votes

Mermaid Diagrams

Creating and refining Mermaid diagrams with live reload. Use when users want flowcharts, sequence diagrams, class diagrams, ER diagrams, state diagrams, or any other Mermaid visualization. Provides best practices for syntax, styling, and the iterative workflow using mermaid_preview and mermaid_save tools.

2062 votes

sleek-design-mobile-apps

Use when the user wants to design a mobile app, create screens, build UI, or interact with their Sleek projects. Covers high-level requests ("design an app that does X") and specific ones ("list my projects", "create a new project", "screenshot that screen").

5711 votes

swiftui-design-skill

SwiftUI frontend visual design skill. Creates beautiful, distinctive iOS/macOS interfaces that avoid generic AI slop patterns. Covers design direction, layout systems, typography, color, spacing, brand integration, and design review. Use when designing new SwiftUI views, reviewing UI quality, creating iOS prototypes, choosing visual styles, improving app aesthetics, or when the UI looks generic or AI-generated.

1801 votes

Ios Hig

Use when designing iOS interfaces, implementing accessibility (VoiceOver, Dynamic Type), handling dark mode, ensuring adequate touch targets, providing animation/haptic feedback, or requesting user permissions. Apple Human Interface Guidelines for iOS compliance.

761 votes
View all in design →