RoadmapDesign Debt

Design Debt — 단일 부채 추적

기준: BE v0.102.0 / FE v0.132.0 / SPEC #134 시점. 이 페이지는 디자인 부채(전용 handoff 시안 없이 idiom 미러·atom 으로 임시 구현된 화면)의 단일 소스다. 정책: handoff 에 없는 시각 결정은 코드에서 임의 발명하지 않는다(memory feedback_design_only_from_handoff). 부채 화면은 atom/idiom 으로 영역·동작만 잡고, 정식 시안이 도착하면 정합 교체한다. 타이밍 전략: 도메인 안정 시 묶음 핸드오프(개별 슬라이스마다 시안을 요청하지 않고, 한 도메인이 굳으면 묶어서 claude design 에 넘긴다).

이전까지 부채 추적이 3곳(이 페이지 · docs/jira/_pending/_temp-layout-debt.md · design_handoff_linkmusic/briefs/requests/)으로 분산·드리프트했다. 이 페이지로 단일화한다.


0. 부채 강도 기준

강도정의처리
A순수 발명 — 화면 전체 근거 0, atom 임의 선택.0건. packages/ui atom 13종은 briefs/20-design-system-proposal.md 에 전부 근거. 발명 화면 없음.
Bidiom 미러 — 전용 시안 없이 기존 화면 관용구(목록·다이얼로그·테이블)를 미러해 합성. atom-grounded.정식 시안 요청서로 정합 교체.
B+시안에 stub/정적 mock 만 존재 — 골격은 미러하되 인터랙션을 FE 가 결정했고 시안 확인이 필요.요청서에 인터랙션 확인 요망 명시 + 시안 도착 시 교체.
C후속 리팩터가 명시된 임시 — 부채로 추적하되 별도 SPEC 후속(F)으로 닫음.후속 SPEC 에서 정식화.

모든 부채는 해당 코드 doc-comment 에 시안 출처(또는 “시안 부재 — atom-grounded”)가 박혀 있다. 임의 색/아이콘/미세 인터랙션은 추측하지 않았다.


1. 해소 완료 (부채에서 제외 — 기록)

design_7 핸드오프 흡수(FE v0.63.0)로 닫힌 항목. 더 이상 부채 아님.

  • 운영사 Phase3/4 전부ops-hq-detail·ops-store-manager(발급+관리)·ops-settings·ops-audit-actions·ops-tickets·ops-policies-history·ops-dashboard-stats·ops-reagree 시안 정합 교체 완료(SPEC #031 AE·#033·#035·#038·#040). _temp-layout-debt.md #1#7·#9·#10·#13.
  • idiom 미러 4건ops-libraries·ops-playlist-detail·hq-announcements·onboarding-supplement 요청서분 흡수.
  • 점장 즉시방송 녹음 탭·템플릿 탭 (묶음1) — 시안 정합 완료: design_8 핸드오프(store-broadcast-recording.jsx·store-broadcast-templates.jsx, §8E-②·③) 흡수. recording-tab.tsx·templates-tab.tsx 가 그 시안 출처를 명시하고, stub/정적 mock 임시 → 정식 시각으로 교체했다(대형 타이머·80px 버튼·상태별 카드 / 행 레이아웃·인라인 폼·인라인 2-step 삭제·빈상태 CTA). 인터랙션은 §8E-① 확정(시작/정지 = 탭 토글, 행 탭 = 로드, 삭제 = 인라인 2-step)대로. 동작·API·검증·에러매핑은 100% 보존(시각만 교체). 더 이상 B+ 부채 아님.
  • 본사 CS·CM송·설정 (묶음3) — 시안 정합 완료: design_8 핸드오프(hq-cs-support.jsx·hq-commercials.jsx·hq-settings.jsx, §8E-⑥⑦⑧) 흡수. atom-grounded 임시 → 정식 시각으로 교체했다.
    • CS /admin/support — 상세를 2-컬럼(좌측 본문+채팅 스레드+하단 작성폼 / 우측 처리 사이드)으로 재설계. 댓글 = 좌우 말풍선(HQ_MANAGER 우측 primary-soft·“내 본사” / OPERATOR 좌측 surface-2·“운영사”). 목록 배지 dot(우선순위는 URGENT 만), 작성 폼 중앙 카드.
    • CM송 /admin/commercials — 목록/상세 활성 배지 dot, 등록 폼 아래 dashed “후속 업로드 영역” placeholder, 미리듣기는 네이티브 <audio controls> 유지(브랜드 player X).
    • 설정 /admin/settings — 880 중앙 컨테이너 + 4 섹션(SectionHeader 제목+부제). CM 사이클에 예시 박스 + 레거시 warn 배지(미설정 fallback 5), 비번 안내 박스.
    • CS 상태 전이(HQ 허용만)·우선순위(URGENT 제외)·CM CRUD·audioUrl·설정 4섹션·비번 reseal·에러 매핑·testid·접근성은 100% 보존(시각만 교체). 더 이상 B 부채 아님.
  • 본사 송출이력 다이얼로그·감사 (묶음3 잔여) — 시안 정합 완료: design_8 핸드오프(dispatch-history-dialog.jsx·hq-audit-page.jsx, §8E-④⑤) 흡수. atom-grounded 임시 → 정식 시각으로 교체했다. 이로써 묶음3 본사 5건 전부 해소 → 1차 핸드오프 패키지(본사 5 + 점장 방송 2) 7건 전부 완료.
    • 송출이력 다이얼로그 /admin/announcements — 집계 헤더를 surface-2 박스 패널(“전체” uppercase + dot prefix chip + 세로 구분선 + “페이지 이동·필터와 무관” 힌트)로, 테이블 헤더 surface-2, 같은 매장 연속 row 는 info bar+“(중복 송출)” 라벨, empty state 는 라운드 아이콘 타일+보조 설명, 로딩은 column-centered spinner.
    • 감사 /admin/audit — ★ impersonation 행 = 좌측 brand vertical bar + 옅은 primary tint, ↩ impersonatedBy 보조줄을 actorEmail 에 배치(“운영자 위장” primary 배지). 헤더 부제 “(시간 역순)”, “발생 시각” 컬럼 “(서버 정렬)” 보조라벨, 하단 액션 톤 가이드 strip.
    • 송출이력 그룹핑(#089)·매장명 검색(#098)·일괄 액션(#096)·재송출/취소(#076·#077)·집계 chip·감사 필터(actor select #069)·CSV 내보내기(#070)·empty 분기·ACTION_TONES 실제 매핑(삭제=warn)·에러 매핑·testid·접근성은 100% 보존(시각만 교체). 더 이상 B 부채 아님.
  • 운영사 잔여 2건 — 드리프트 정정(해소됨): _temp-layout-debt.md #8·#11·#12 는 “남은 대기”로 남아 있었으나, 실제 코드는 이미 시안 정합 완료다.
    • 운영자 계정관리 /usersops-users.jsx 시안 도착, operator-list-client.tsx 가 그 시안 출처를 명시(SPEC #032·#043). 더 이상 ops-store-manager 미러 임시 아님.
    • 매장상세 /stores/:id + 상태전이/폐점 다이얼로그 — ops-store-detail.jsx 시안 도착, store-detail-client.tsx·store-status-transition-dialog.tsx 가 시안 정합 완료 명시(SPEC #036·#037·#039).
    • 묶음2(운영사 잔여) 핸드오프는 불필요. _temp-layout-debt.md 의 해당 행은 stale 이며 이 페이지가 정정한다.
  • 본사 매장 CSV 일괄등록·점장 랜딩 (묶음4 부분) — 시안 정합 완료: design_9 핸드오프(hq-stores-bulk-csv.jsx·store-landing.jsx) 흡수. atom-grounded 임시 → 정식 시각으로 교체했다.
    • CSV 일괄등록 /admin/stores/bulk — CSV 형식 안내 블록(5컬럼 번호·필수표식 칩, 헤더 단일 소스), 점선 드롭존(파일 선택 시 success 톤·파일명·KB·행수 추정), 업로드 단계표시(파일 업로드→서버 처리 StepDot), 결과 요약 도넛(성공/실패 arc + 큰 카운트, allSuccess=success/부분실패=warn 톤 분기), 실패 행 그룹핑 토글(행번호순 테이블 ↔ 사유별 묶음), 재업로드 루프 안내 카드로 재설계. 빈 파일 가드·multipart 업로드·부분 실패 파싱·노출 필드(rowNumber/storeName/errorMessage)·에러 매핑(C9 파일오류 배너 vs 행오류 테이블·C10 SUSPENDED 403)·disabled 규칙·testid·접근성은 100% 보존(시각만 교체). 드래그앤드롭 실제 동작·실패행 CSV 다운로드는 후속(시각 힌트만). 더 이상 B 부채 아님.
    • 점장 랜딩 /landing — 헤더(L 마크 gradient 배지)·히어로(라이브 도트 배지+gradient 강조 h1+큰 CTA)·6 기능 카드(긴급 안내방송 warn 톤 차등+caution)·3 운영 스텝(번호 원형 배지)·4 FAQ 아코디언(첫 항목 defaultOpen)·하단 CTA·푸터로 완성형 마케팅 랜딩 재설계. 공개·비인증 접근(C1)·유일 CTA=[점장 로그인]→/login(C2 가입/결제 폼 없음)·본사 문의 안내(C3)·인증자 server-side redirect(C4 HQ→/admin·STORE→/store·기타→/login)·외부 의존 0(C6)·testid·a11y는 100% 보존(시각만 교체). 더 이상 C 부채 아님.
  • 점장 온보딩 intro/start (묶음4) — 시안 정합 완료: design_10 핸드오프(store-onboarding-intro-start.jsx) 흡수. atom-grounded 임시 → 정식 시각으로 교체했다.
    • 간단 소개 /store/onboarding/intro — 4슬라이드 캐러셀(PRD Page 9 문구 그대로, emoji 6480px·제목 2630px·본문 18px)·길쭉 dot 인디케이터+N/4·[이전](첫 슬라이드 disabled)/[다음](마지막=“시작 준비 완료”)·헤더 우측 저강조 [건너뛰기](항상 노출)·슬라이드 3(긴급)=warn 톤 차등(warn 카드 보더 + “긴급 상황 한정” StatusPill + danger 경고 박스 “마케팅·이벤트엔 사용할 수 없습니다.”)로 재설계.
    • 음악 시작 /store/onboarding/start — 120px success 원+glow 박동+🎉 + 체크리스트 3줄(원형 success 체크 배지) + 80px 대형 [음악 시작하기] CTA로 재설계.
    • 슬라이드 인덱스 clamp·[건너뛰기]→start·완료 플래그(done) localStorage 저장·router.push('/store') 자동재생 진입·공유 Stepper 4단계·testid·접근성(aria-live)은 100% 보존(시각만 교체). 완료 BE 연동(FR-9.5)은 후속. 더 이상 C 부채 아님. 이로써 묶음4 핸드오프 가능분(매장 CSV·랜딩·온보딩 3건) 전부 완료 — 잔여는 점장 CS(미구현)뿐.
  • 점장 모드 전체 (묶음5) — 시안 정합 완료: design_14 핸드오프(Phase 8 §8G-①~⑤ — store-player.jsx·store-support.jsx·store-scheduled-broadcasts.jsx·store-profile.jsx·store-active-playlist.jsx) 흡수. atom-grounded 임시 → 정식 시각으로 교체. 신규 공용 atom StoreSubHeader(점장 서브페이지 헤더 — /support·/profile·/playlist·/scheduled 공용) 추가. 이로써 3차 핸드오프 패키지(묶음5) 5건 전부 완료.
    • player 홈 /store — 4상태 즉시구분(음악 무배지 / 안내 info pill+트랙배지 / CM muted pill / 긴급 danger pill+상단 danger Banner+커버·진행바 danger), 상태별 brand 그라데이션 커버 placeholder(앨범아트 없음·data drift), 큐 source 3종 시각(DEFAULT 본사 기본 안내), dead-end CTA, CS 새 답변 dot.
    • 고객지원 /store/support — category 큰 칩 5종(필수·?category= 사전선택), 댓글 좌우 말풍선(STORE_MANAGER 우측 primary-soft / OPERATOR 좌측 surface-2), 확인 종료(/close) 1종만·우선순위 미노출.
    • 예약 목록/취소 /store/broadcast/scheduled — max-w-760 카드 리스트, inline [취소]→warn confirm strip 2-step, native <audio> 단일 펼침, 긴급 배지 병기.
    • 프로필 /store/profile — read-only 8행 + “조회 전용” 배지, 매장 상태 배지(ACTIVE success·INACTIVE warn·SUSPENDED danger·dot pulse), 매니저 이름 편집·비번 변경·고객지원 진입 카드.
    • 활성 PL 선택 /store/playlist — 카드 리스트, active 행 “재생 중” 강조, 파생 상태 4종(ACTIVE success·FALLBACK info·EMPTY warn·UNUSED muted) 라벨 병기, [본사 기본으로]=활성 해제.
    • 동작·API·hook·라우팅·에러 매핑·검증·testid 100% 보존(시각만 교체). 596 store 테스트 회귀 0. 더 이상 부채 아님.

2. 미해소 부채 인벤토리

강도·상태는 코드 doc-comment 실측 기준. 추정은 “(추정)“으로 표기.

화면페르소나SPEC현재 상태강도요청서
unread/actionable 배지 (운영자 사이드바 CS pill · 본사 ack 카드/CS dot · 점장 player CS dot)운영자·본사·점장#119구현 완료 · atom-grounded — 전용 배지 시안 부재라 기존 atom 재사용: 운영자 /tickets 카운트 pill·본사 /admin/support dot 은 sidebar-star 도트 패턴과 동형(primary 톤·tabular-nums), 점장 player [고객지원] dot 은 버튼 우상단 primary 도트, 본사 대시보드 “오늘 송출 미도달 매장” 카드는 기존 대시보드 카드 idiom(min-h-[120px] + StatusPill dot) 미러. 색/배치/크기 임의 발명 없음(전부 토큰·기존 패턴).B후속(전용 시안 도착 시 — 알림 배지/badge atom 정식화)
본사 bootstrap 체크리스트 · 계정 전달 안내문 복사 (대시보드 진척 체크리스트 · 점장/운영자 발급 안내문 복사)본사·운영자#120구현 완료 · atom-grounded — 전용 시안 부재라 기존 atom 재사용: 대시보드 bootstrap 체크리스트(bootstrap-checklist.tsx)는 대시보드 카드 idiom(surface 카드) + Check 아이콘 success 배지/단계 번호 ring + primary/secondary Link 버튼, 계정 발급 안내문 복사 섹션(account-share-section.tsx)은 Banner success + mono surface-2 미리보기 블록(임시 비번 input idiom) + Copy/Check 아이콘 secondary Button. 색/배치 임의 발명 없음(전부 토큰·기존 패턴).B후속(전용 시안 도착 시 — 온보딩 진척/공유 UI 정식화)
운영사 본사명 인라인 편집 /hq/[id] 개요운영자#123구현 완료 · atom-grounded — 본사명 편집 전용 시안 부재라 운영사 매장 정보 인라인 편집(#105 hq-store-edit-form.tsx) 패턴을 정확 미러: 개요 탭 상단 “본사명” 섹션 헤더 우측 [편집] 토글 → Field+Input 1필드 + [저장]/[취소] 인라인 폼(hq-name-edit-form.tsx). 성공 시 router.refresh()(server-fetch prop 갱신) + read 복귀 + success Banner. 색/배치 임의 발명 없음(전부 토큰·기존 #105 idiom).B후속(묶음6 — HQ 상세 편집 UI 정식화)
운영사 협약 동의 조회 /contracts운영자#127구현 완료 · atom-grounded — ComingSoon → 본사 드롭다운 선택 → 약관 동의 이력·현재 동의 상태 조회(legal 재사용·read-only). 전용 시안 부재 — 운영자 목록/DescCard idiom 미러.B후속(묶음6)
운영자 설정 7서브 /settings/* (프로필 #130 · 알림(TTS smoke-test) #134 · 장르/무드 옵션 #132 · 스캐폴딩 #128)운영자#128·#130·#132·#134부분 내실 · atom-grounded — 7서브 탭 셸 + 18-1 내 프로필(프로필 read + 비번변경)·18-2 알림(TTS [연결 확인] smoke-test)·18-3 장르/무드 옵션 CRUD 내실, 나머지 4서브 ComingSoon. 전용 시안 부재 — settings form·목록 idiom 미러.B후속(묶음6 — 설정 UI 정식화)

곧 쌓일 부채: 없음 — 점장 도메인(player·CS·예약·프로필·활성 PL)은 묶음5 요청서 5종 작성 완료(시안 대기). 운영자/본사 신규 atom-grounded(협약 조회·설정 7서브·배지·bootstrap·본사명·통계 CSV)는 묶음6 후보로 등재. TTS 활성화(#134)는 운영자 설정 18-2 smoke-test 로 묶음6 설정 묶음에 포함.


3. 핸드오프 묶음 계획 (도메인 안정 게이트)

개별 슬라이스마다 시안을 요청하지 않는다. 도메인이 굳으면(후속 F 가 더 안 쌓이면) 묶어서 claude design 에 넘긴다.

묶음구성게이트상태
묶음1 — 점장 방송녹음 탭(B+) · 템플릿 탭(B+) · (+player CM/긴급/예약 시각 정합은 묶음3)#090~#104 안정녹음 탭·템플릿 탭 시안 정합 완료(design_8 §8E-②·③ 흡수, §1). player 시각 정합은 묶음3로 이관
묶음2 — 운영사 잔여ops-users(#032) · ops-store-detail(#036·37·39)이미 해소ops-users.jsx·ops-store-detail.jsx 시안 정합 완료(§1). 핸드오프 불필요
묶음3 — 본사송출이력 다이얼로그(#065) · 감사(#067) · CS(#086·108) · CM송(#093) · 설정(#085)완료 — 본사 5건 전부 design_8 §8E-④⑤⑥⑦⑧ 흡수로 시안 정합 완료(§1). 묶음3 잔여 0
묶음4 — 온보딩·CS·랜딩·CSV매장 CSV 일괄(#111) · 점장 랜딩(#079) · 온보딩 intro/start(#110) · 점장 CS(#112 → 묶음5로 이관)화면이 생긴 뒤🟢 시안 정합 가능분 완료 — 매장 CSV 일괄·점장 랜딩(design_9)·온보딩 intro/start(design_10) 3건 시안 정합 완료(§1). 점장 CS(#112)는 묶음5(점장 모드 전체)로 이관.
묶음5 — 점장 모드 전체player 홈+인터럽트(#064·#090·#094·#095·#103·#104) · 고객지원(#112·#121) · 예약 목록/취소(#091·#092·#102·#131) · 프로필(#087·#100) · 활성 PL 선택(#129)✅ 점장 도메인 안정(PRD 9페이지 전부 구현)완료 — design_14(Phase 8 §8G-①~⑤) 흡수로 5건 전부 시안 정합 완료(§1). StoreSubHeader atom 추가. 596 store 테스트 회귀 0.
묶음6 — 운영자/본사 신규협약 동의 조회(#127) · 운영자 설정 7서브(#128·#130·#132·#134) · unread 배지(#119) · bootstrap 체크리스트/계정 안내문(#120) · 본사명 인라인 편집(#123) · 통계 CSV(#133)운영자/본사 신규 화면 안정요청서 미작성 — 묶음5 다음 후보. atom-grounded 구현 완료분, 도메인 굳으면 묶어서 요청.

입력 분석이 가정했던 “묶음2 운영사 잔여 = 지금 넘김”은 코드 실측 결과 이미 해소되어 무효다(§1 드리프트 정정). 묶음1(점장 방송 녹음·템플릿 탭)은 design_8 §8E-②·③ 흡수로 해소 완료(§1). 묶음3 본사 5건(CS·CM송·설정 + 송출이력 다이얼로그(#065)·감사(#067))은 design_8 §8E-④⑤⑥⑦⑧ 흡수로 전부 시안 정합 완료(§1) — 묶음3 잔여 0. 이로써 1차 핸드오프 패키지(본사 5 + 점장 방송 2) 7건 전부 완료. 2차 핸드오프 패키지(묶음4)는 design_9(매장 CSV 일괄·점장 랜딩) + design_10(온보딩 intro/start) 으로 3건 전부 시안 정합 완료(§1). 묶음4 잔여 = 점장 CS(#112)는 묶음5로 이관. 3차 핸드오프 패키지(묶음5 — 점장 모드 전체) 5건은 design_14(Phase 8 §8G-①~⑤) 흡수로 전부 시안 정합 완료(§1) — StoreSubHeader atom 추가·596 store 테스트 회귀 0. 이로써 점장 모드 디자인 부채 0. 묶음6(운영자/본사 신규 — 협약·설정 7서브·배지·bootstrap·본사명·통계 CSV)은 요청서 미작성 후보 = 현재 남은 유일한 atom-grounded 부채(§2, 전부 강도 B·구현 완료·전용 시안 도착 시 정합). 미구현 대기 화면은 0.


4. 시안 없이도 시안 atom 인 것 (교체 불필요)

  • 목록·다이얼로그 셸·툴바·페이지네이션·StatusPill·DescCard·OrgAvatar 등 @linkmusic/ui atom 13종 — briefs/20-design-system-proposal.md 근거.
  • 임퍼소네이션 감사 /audit/impersonation = ops-audit.jsx 시안 그대로(#025).
  • 매장 목록 /stores·HQ 목록 /hq = ops-hq-list.jsx 관용구(#019·#013).
  • HQ 상세 탭 바 = Tabs/Tab(ops-shared.jsx §OpsTab).

5. 시안 정합이나 데이터 모델 drift (시각 OK · 데이터 미제공으로 일부 생략)

시안 시각은 정합됐으나, 시안이 가정한 일부 데이터가 BE v1 미제공이라 컬럼/필드를 생략하거나 placeholder 로 둔 화면. 시각 부채(§2)와 구분 — 시각은 맞고, 데이터가 따라오면 자연 채워진다(디자인 재요청 불필요).

  • 임퍼소네이션 감사 /audit/impersonation (#025) — ops-audit.jsx 시안 정합이나, 시안의 ticket·reason·액션 타임라인 데이터는 BE v1 미제공 → 해당 컬럼/타임라인 생략·“준비 중” placeholder.
  • 점장 player(Classic, #064) — home-classic.jsx 시안의 “다음 방송(예약/대기) 큐”는 재생 큐(items)로 매핑(시안 더미 CM 빈도·예약 ETA 는 데이터 부재로 미노출). data-model drift.

6. 미구현 스텁 (부채 아님 — 화면 자체가 후속)

placeholder/ComingSoon 으로 자리만 잡은 라우트. 디자인 부채(임시 시각)가 아니라 기능 미구현이다. 구현 슬라이스 진입 시 §2 부채로 편입될 수 있다.

  • 점장: /store/broadcast/templates · /store/broadcast/schedule · /store/playliststore-stub-page placeholder(#064 §D6 후속).
  • 운영사: /billing · /contracts — ComingSoon(#030 — 정산·협약 도메인 후속).
  • 본사: /admin/dashboard 일부 카드 — “준비 중” placeholder(#051 §F1 — 송출·정산 데이터 미도착).

정책 (memory feedback_design_only_from_handoff)

  • handoff 에 없는 시각 요소(로고 자리·사이드바 아이콘·정확한 색조/그라데이션·일러스트 등)는 코드에서 임의 결정하지 않는다.
  • 시각이 필요해지는 순간 → 사용자가 claude design 에 받아온 시안을 입력으로(묶음 단위).
  • placeholder/atom-grounded 구현은 “디자인 미정·정합 교체 예정”임이 doc-comment 에 명시된다.

Storybook (도입됨)

packages/ui atom 카탈로그가 Storybook 으로 도입됐다(@linkmusic/ui devDependencies — 앱 빌드와 분리).

  • 빌더: Storybook 9 (react-vite). config 는 packages/ui/.storybook/{main.ts,preview.tsx}.
  • 토큰 cascade(storybook.css → Pretendard + Tailwind v4 + src/styles/all.css)를 preview 에 주입해 atoms 가 실제 색으로 렌더된다. light/dark 테마 토글은 toolbar(globalTypes.theme) + decorator 가 <html data-theme> 속성을 갱신한다.
  • 대표 atom stories: Button · StatusPill · Banner · Card · Field · Input · Dialog · Tabs · OrgAvatar · ListToolbar(+ListPagination/ListNoResults).
pnpm --filter @linkmusic/ui storybook        # dev (http://localhost:6006)
pnpm --filter @linkmusic/ui build-storybook  # 정적 빌드 (storybook-static/)

stories 는 vitest·tsc·eslint 에 정상 포함되며 프로덕션 pnpm -r build 와는 무관하다.

References

  • 핸드오프 요청서: design_handoff_linkmusic/briefs/requests/ (+ README.md 묶음 구성)
  • memory feedback_design_only_from_handoff · feedback_no_domain_boundary_checkin
  • .claude/rules/frontend.md Copilot 패턴 7
  • handoff 00-design-brief.md §6 (Phase 1~3 워크플로우) · 20-design-system-proposal.md