# D 트랙 — P0/P1/P2 Review Follow-up Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** P0/P1/P2 review feedback에서 defer된 5 follow-up cleanup 일괄 처리 — KAKAO URL SSOT, KakaoFloatButton 추출, mypage 잔여 정돈, 모바일 7-tab 가로 스크롤, "Try now" 로그인 시 노출.
**Architecture:** 각 task 독립적 cleanup. 기존 review에서 명세된 fix들이라 design 결정 없음. 5 task × ~5-30 LOC = 총 약 100 LOC 미만. brainstorm 생략.
**Tech Stack:** Next.js 16 App Router + TS + Tailwind v4
**Source Reviews:**
- P1 Task 2 review (TopNav auth): M-3 "Try now" disappears on login
- P1 Task 3 review (PublicShell kakao button): I-1 component extraction, I-2 URL SSOT
- P2 Task 4 review (mypage packs): M-2 disabled button conditional (already addressed in implementation), M-5 mobile tab wrap
---
## File Structure
| 파일 | 종류 | 책임 |
|---|---|---|
| `lib/contact.ts` | Create | `KAKAO_OPENCHAT_URL` 상수 single source of truth |
| `app/components/KakaoFloatButton.tsx` | Create | 카카오 1:1 상담 플로팅 버튼 컴포넌트 (PublicShell 인라인 JSX + style 추출) |
| `app/components/PublicShell.tsx` | Modify | 인라인 카카오 버튼 → `` 컴포넌트 사용 |
| `app/mypage/page.tsx` | Modify | (a) kakao URL → 상수 import (b) EmptyState linkHref `/services/music` → `/music/packs` (c) 탭 바 `flex-wrap` → `overflow-x-auto flex-nowrap` |
| `app/components/TopNav.tsx` | Modify | 로그인 상태에서도 "Try now" 노출 (마이페이지/로그아웃 옆) |
---
## Task 순서
각 task는 독립적이라 어느 순서든 가능. 다음 순서로 진행:
1. **D1**: `lib/contact.ts` 신규 + KAKAO_OPENCHAT_URL — 다른 task의 import source
2. **D2**: `KakaoFloatButton.tsx` 신규 + PublicShell 인라인 추출 (D1의 상수 활용)
3. **D3**: mypage 잔여 정돈 (kakao URL 상수 import + linkHref + 탭 가로 스크롤)
4. **D4**: TopNav "Try now" 로그인 시 노출
총 4 task. (당초 5개 중 "mypage 다운로드 버튼 조건부 렌더"는 Phase 2 implementation에서 이미 처리됨 — D3에 정돈 한 줄로 흡수.)
---
## Task D1: lib/contact.ts — KAKAO_OPENCHAT_URL SSOT
**Files:**
- Create: `C:\Users\jaeoh\Desktop\workspace\jaengseung-made\lib\contact.ts`
- [ ] **Step 1: 파일 작성**
```ts
/**
* 외부 연락 채널 상수 SSOT.
* - KAKAO_OPENCHAT_URL: 1:1 카카오 오픈채팅. PublicShell 플로팅 버튼 + mypage 안내 등에서 공유.
* URL 변경 시 이 파일만 수정.
*/
export const KAKAO_OPENCHAT_URL = 'https://open.kakao.com/o/s9stoNvb';
```
- [ ] **Step 2: 린트**
```bash
npx eslint lib/contact.ts
```
Expected: exit 0.
- [ ] **Step 3: 커밋**
```bash
git add lib/contact.ts
git commit -m "$(cat <<'EOF'
feat(lib): contact.ts — KAKAO_OPENCHAT_URL SSOT 상수
D 트랙 1/4. 현재 카카오 오픈채팅 URL이 3곳에 하드코딩(PublicShell, mypage,
historical DashboardShell) — single source of truth로 정돈. 향후 URL 변경 시
이 파일만 수정.
Co-Authored-By: Claude Opus 4.7 (1M context)
EOF
)"
```
- [ ] **Step 4: ⚠️ git log -3 직접 확인**
```bash
git log --oneline -3
```
기대: HEAD = 본인 commit, 직전 = `972bfd8` (P1 D1 완료) 또는 그 이후 push 후 영향 없음 (push는 origin/main 동기화만).
---
## Task D2: KakaoFloatButton 컴포넌트 추출
**Files:**
- Create: `C:\Users\jaeoh\Desktop\workspace\jaengseung-made\app\components\KakaoFloatButton.tsx`
- Modify: `C:\Users\jaeoh\Desktop\workspace\jaengseung-made\app\components\PublicShell.tsx`
- [ ] **Step 1: KakaoFloatButton.tsx 신규 작성**
기존 PublicShell.tsx 의 인라인 카카오 버튼 JSX + `
>
);
}
```
추가 사항:
- SVG에 `aria-hidden` 추가 (parent anchor의 aria-label이 announce 대체)
- KAKAO_OPENCHAT_URL import (D1에서 신규)
- [ ] **Step 2: PublicShell.tsx 수정**
현재 (119-169행 부근):
```tsx
{/* 카카오 오픈채팅 플로팅 버튼 */}
...
```
위 두 element(`` + `