spec-flow · skill guide

ui-order

모호한 UI 요청을 바로 구현하지 않고, 질문과 화면 주문서 초안으로 먼저 되묻는 스킬.

파일 쓰기는 --setup --apply 만 --check 는 읽기 전용 질문 최대 5개 차단형 프롬프트 없음 “기본값으로 진행”

빠른 시작

  1. /spec-flow:ui-order --setup — 미리보기. 스택을 감지하고, 프로젝트 CLAUDE.md 에 넣을 블록을 출력만 한다. 아무것도 쓰지 않는다.
  2. /spec-flow:ui-order --setup --apply — 그 블록을 CLAUDE.md 끝에 넣는다 (<!-- ui-order:begin --> ~ <!-- ui-order:end --> 표식 안).
  3. CLAUDE.md 에서 [화면] 자리표시(<이 프로젝트의 화면 종류: ...>)를 이 프로젝트의 화면 종류로 고친다.
  4. 이제 그냥 “버튼 만들어줘”라고 하면, 슬래시 명령 없이도 질문과 주문서 초안으로 되묻는다.
  5. 기존 코드 점검 — /spec-flow:ui-order --check 로 이미 있는 프런트엔드를 읽기 전용으로 점검하고, 코드가 실제로 쓰는 값으로 주문서 블록을 고칠 제안을 받는다.

한 줄 요약

“버튼 만들어줘”, “좀 예쁘게”, “폰에서도 되게” 같은 모호한 UI 요청을 받으면 바로 구현하지 않는다. 요청을 UI/UX 용어의 칸에 대 보고 빠진 결정을 찾아, 질문 최대 5개 + 기본값을 채운 화면 주문서 초안으로 먼저 답한 뒤 턴을 끝낸다.

AI 는 모호한 말을 임의로 해석하고 해피 패스만 만든다. 문제는 실력이 아니라 이름과 숫자가 빠진 주문이다.

무엇을 만드는가

채팅 출력 하나가 산출물이다. 파일은 쓰지 않는다 — 예외는 --setup --apply 하나로, 프로젝트 CLAUDE.md 의 ui-order 표식 블록 안에만 쓴다. --check 의 산출물은 점검 보고서(채팅 출력)이며 역시 아무것도 쓰지 않는다.

부분내용
질문영향 큰 순서로 최대 5개. 각 질문에 구체적인 기본값이 붙는다
주문서 초안[화면] [레이아웃] [내용] [부품] [상태] [토큰] [글자] [반응형] [접근성] 중 관련 칸만. 사용자가 주지 않은 값은 (기본값) 표시
마무리 한 줄“기본값으로 진행”이라고 답하면 초안대로 구현한다는 안내

언제 쓰고 언제 안 쓰는가

쓴다 — UI 요청에 부품 이름·숫자·상태가 빠져 있을 때. 예: “버튼 만들어줘”, “대시보드 만들어줘”, “알림 띄워줘”, “폰에서도 되게 해줘”.

안 쓴다:

  • 요청이 이미 이름과 숫자를 다 담고 있을 때 → 스킬은 묻지 않고 바로 구현한다. 잘 쓴 요청을 귀찮게 하지 않는다.
  • UI 가 아닌 기능 설계 → prd-to-trd.

호출 형식

/spec-flow:ui-order "<UI request>"
/spec-flow:ui-order --setup [--apply] [--force] [--project <dir>]
/spec-flow:ui-order --check [--project <dir>]
인자필수설명
"<UI request>"예사용자가 쓴 그대로의 UI 요청
--setup—프로젝트 CLAUDE.md 에 넣을 블록 미리보기 (쓰지 않음)
--apply—--setup 과 함께: 블록을 실제로 쓴다
--force—--setup --apply 와 함께: 이미 있는 표식 안의 내용을 교체
--check—기존 프런트엔드 코드의 UI 기준 점검 보고서 (읽기 전용)
--project <dir>—대상 프로젝트 (기본: 현재 디렉터리의 git 최상위)
help / -h / --help—도움말만 출력

동작 단계

  1. 대상 식별 — 화면 종류와 부품을 찾고, 감각어는 용어집의 번역표로 정확한 말에 대응시킨다.
  2. 칸 점검 — 화면 칸 9개와 부품 계열별 칸(버튼이면 위계·크기·radius·상태·아이콘)에서 이름이나 숫자가 없는 칸을 표시한다.
  3. 판단 — 관련 칸이 전부 채워져 있으면 바로 구현. 아니면 4단계.
  4. 주문서 초안 출력 후 턴 종료 — 질문, 초안, 마무리 한 줄.
  5. 다음 턴 — 답을 초안에 합쳐 구현한다. “기본값으로 진행”이면 기본값을 적용하고 적용한 기본값 목록을 밝힌다.

데이터를 보여주는 화면이면 로딩 = 스켈레톤, 빈 상태 = 엠프티 스테이트 + 다음 행동 버튼, 에러 = 재시도 버튼 세 가지를 묻든 기본값으로 넣든 반드시 주문서에 싣는다.

예시

입력: 버튼 만들어줘

질문 (영향 큰 순)
1. 어떤 행동의 버튼인가요? 위계: primary / secondary / ghost / destructive
   — 기본값: primary 1개, 레이블 "저장"
2. 취소 같은 두 번째 버튼이 필요한가요? — 기본값: 없음
3. 누른 뒤 서버 처리가 있나요? — 기본값: 있음, 처리 중 disabled + 스피너
4. 크기와 모양 — 기본값: 높이 40px, padding 12px 20px, radius 12px
5. 아이콘을 넣을까요? — 기본값: 없음

주문서 초안
[부품] primary 버튼 1개, 레이블 "저장" (기본값)
[상태] hover / focus-visible / disabled / loading (기본값)
[토큰] 높이 40px, padding 12px 20px, radius 12px (기본값); Tailwind + shadcn/ui (기본값)
[접근성] 포커스 링 유지, 명암비 4.5:1, 터치 영역 44px 이상 (기본값)

"기본값으로 진행"이라고 답하면 위 초안대로 구현합니다.

주요 기본값: 간격 8의 배수, radius 12px, 그림자 약하게, 타입 스케일 4단계, 본문 행간 1.6, 브레이크포인트 640/1024 모바일 퍼스트, 사이드바 240px → 1024 미만 드로어, 명암비 4.5:1, 터치 타깃 44px, Lucide outline 20px, 스택 미지정 시 Tailwind + shadcn/ui. 프로젝트에 이미 스택·토큰이 있으면 그쪽이 우선한다.

기존 코드 점검 (--check)

이미 만들어진 프런트엔드에서 흐릿하거나 제각각인 UI 기준을 찾는다. 읽기 전용이다 — CLAUDE.md 도 쓰지 않는다. 두 단계로 동작한다.

  1. 결정적 스캐너 (lib/check_frontend.py) — *.tsx *.jsx *.ts *.js *.vue *.svelte *.css *.scss *.html 을 훑는다 (node_modules, .git, dist, build, .next, out, coverage, *.min.*, 테스트 파일 제외).
  2. AI 판단 — 스캐너가 가리킨 파일을 읽고 기계가 못 보는 것을 판단한다.
점검무엇을 찾는가
icon-set (high)Lucide 가 아닌 아이콘 세트 import (react-icons, Heroicons, MUI Icons, Font Awesome ...). 아이콘은 Lucide 단일 세트가 기본
icon-emoji (med)아이콘 자리에 쓴 이모지
a11y-icon-button (high)아이콘만 있고 aria-label 이 없는 버튼
a11y-focus / a11y-img-alt (med)focus-visible 없는 outline-none, alt 없는 <img>
token-spacing / token-radius (med/low)4·8 배수가 아닌 간격, 4종 이상 섞인 radius
color-hardcode (med)테마·토큰 파일 밖의 #hex / rgb() / hsl() (파일별 개수)
breakpoints (med)주문서 [반응형] 밖의 브레이크포인트 3개 이상
exception-states (high, AI)데이터를 불러오는 화면에 로딩·빈 상태·에러 처리가 빠짐
overlay-mix (med, AI)같은 목적(확인, 완료 알림)에 모달·window.confirm·토스트를 섞어 씀
order-unconfirmed (med)주문서 블록 없음, [화면] 자리표시 그대로, (기본값) 과 코드가 다름

보고서는 영향 큰 순서로 묶이고, 항목마다 file:line 근거와 고칠 때 쓸 정확한 용어가 붙는다. 끝에는 주문서 반영 제안 — 코드가 실제로 굳힌 값을 CLAUDE.md 블록에 적는 제안 — 이 온다. 적용은 사용자가 직접 편집하거나 --setup --apply --force 로 한다.

UI 기준 점검 — web/ (파일 42개, high 3 · med 6 · low 1)

### 아이콘 (high)
- src/Toolbar.tsx:12 — react-icons/fa import. Lucide 단일 세트로 교체 (lucide-react, outline 20px).
- src/Header.tsx:31 — 아이콘만 있는 버튼에 이름 없음. 아이콘 버튼 aria-label="닫기" 추가.

### 예외 상태 (high)
- src/pages/Orders.tsx:8 — useQuery 결과를 바로 map. 0건이면 빈 화면.
  엠프티 스테이트 + 다음 행동 버튼("주문 만들기"), 에러 상태 + 재시도 버튼 추가.

### 토큰 (med)
- radius 5종 (rounded-lg x24, rounded-md x6, 6px x2 ...). radius 토큰 8px 하나로 통일.

주문서 반영 제안
- [화면] 자리표시 -> "대시보드 + 목록-상세 + 설정"
- [토큰] 라운드 12px (기본값) -> 라운드 8px (코드 기준)

주의사항 / 제약

  • 질문이 최종 출력이다. 실행 중간에 차단형 프롬프트를 쓰지 않는다. 질문과 초안을 출력하고 턴을 끝내며, 사용자는 평범한 다음 턴에 답한다.
  • 파일을 쓰지 않는다. 프로젝트는 기존 스택·토큰을 확인하려고 읽기만 한다 (--check 도 읽기 전용). 예외는 --setup --apply 뿐이며, 프로젝트 CLAUDE.md 의 ui-order 표식 사이만 쓴다. 표식 밖의 바이트는 건드리지 않고, CLAUDE.md 가 AGENTS.md 심링크면 링크를 유지한 채 대상 파일에 쓴다. 표식이 이미 있으면 건너뛰고(--force 면 안쪽만 교체), 표식이 깨져 있으면 아무것도 쓰지 않고 실패한다.
  • 질문은 최대 5개. 사용자가 신경 쓰지 않을 세부는 묻지 않고 (기본값) 으로 초안에 넣는다.

CLAUDE.md 에 붙일 문구

프로젝트의 CLAUDE.md 에 아래를 넣어 두면, 슬래시 명령 없이도 모호한 UI 요청마다 이 절차가 돈다. /spec-flow:ui-order --setup --apply 가 이 블록과 아래 “프로젝트 기본 주문서” 블록을 한 번에 생성한다 — 블록 문구의 원본은 헬퍼 skills/ui-order/lib/setup_claude_md.py 이고, 아래 사본은 손으로 붙이려는 사용자를 위한 참고용이다. 둘이 다르면 헬퍼가 맞다.

## UI 요청 규칙
UI 요청이 모호하면 바로 구현하지 말고 `/spec-flow:ui-order` 절차로 먼저 되묻는다.
모호한 요청 = 부품 이름·숫자·상태가 빠진 요청 (예: "버튼 만들어줘", "예쁘게", "폰에서도 되게").
되물을 항목: 위계(primary/secondary/ghost/destructive) · 크기·여백(padding, radius) ·
상태(hover/focus-visible/disabled/loading) · 예외 화면(로딩/빈/에러) · 반응형(브레이크포인트).
"기본값으로 진행"이라고 답하면 ui-order 기본값으로 구현하고, 적용한 기본값을 밝힌다.

프로젝트 기본 주문서 (선택)

위 규칙 아래에 프로젝트 성격에 맞게 한 번 고친 화면 주문서를 붙여 두면, ui-order 는 checklist.md 기본값 대신 이 값을 (프로젝트 기본값) 으로 초안에 채운다. 매 요청마다 같은 스택·토큰을 다시 설명할 필요가 없어진다. 출발점은 skills/ui-order/references/order-template.md 의 one-shot example 이다. --setup 은 감지한 스택은 그대로, 감지 못 한 값은 (기본값) 표시를 붙여 채우고, [화면] 은 직접 고칠 자리표시로 남긴다. 아래는 그 자리를 다 채운 모습이다.

## 화면 주문서 (프로젝트 기본값)
[화면]     대시보드 + 목록-상세 + 설정, 로그인은 SSO 버튼 하나, 없는 주소는 404.
[레이아웃] 상단 56px 앱 바 + 좌측 240px 고정 사이드바 + 본문. 컨테이너 max-width 1200px.
[내용]     본문은 카드 그리드(데스크톱 3열 / 태블릿 2열 / 모바일 1열, gap 16px).
[부품]     검색 입력, 필터는 칩, 행 클릭 시 상세는 팝오버가 아니라 모달로.
[상태]     로딩은 스켈레톤, 0건은 엠프티 스테이트(생성 버튼 포함), 실패는 재시도 버튼이 있는 에러 상태.
[토큰]     간격 8의 배수, 라운드 12px, 그림자 약하게, 글자 크기 4단계(Display/Heading/Body/Caption).
[글자]     본문 16px · 행간 1.6, 카드 제목은 2줄 line-clamp, 숫자 열은 tabular-nums.
[반응형]   모바일 퍼스트, 브레이크포인트 640/1024. 1024px 미만에서 사이드바는 드로어로.
[접근성]   포커스 링 유지, 명암비 4.5:1 이상, 아이콘 버튼에 aria-label.
스택: Tailwind + shadcn/ui, 미니멀 스타일, 라이트/다크 모드 둘 다.
화면 단위 작업은 와이어프레임 먼저 → 스크린샷 확인 → 스타일 입히기.

출처: 용어와 기본값은 바이브 코더를 위한 UI/UX 용어 사전(geniuskey)을 바탕으로 요약·재구성했다.