docs: 반응형 설계 리뷰 피드백 반영

- 라우트 경로 수정 (/lab/music→/music, /blog-marketing→/blog-lab 등)
- /realestate/property 미등록 라우트 제외, 실제 14개 뷰로 정정
- breakpoint 예외 목록 명시 (420/520/700px)
- 사이드바→바텀네비 마이그레이션 상세 계획 추가
- react-swipeable 경량 라이브러리 활용 명시
- 미니플레이어+바텀네비 스태킹 사양 추가
- viewport-fit=cover, prefers-reduced-motion, 테스트 뷰포트 명시
- Phase 1을 1a(breakpoint 정리) + 1b(컴포넌트)로 세분화

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-23 14:17:07 +09:00
parent 5ac5cce0fe
commit bd7875b36a

View File

@@ -2,16 +2,38 @@
> 모바일에서 UI 짤림 현상 해결 + 풀 모바일 경험 적용 > 모바일에서 UI 짤림 현상 해결 + 풀 모바일 경험 적용
> 작성일: 2026-04-23 > 작성일: 2026-04-23
> 리뷰 반영: 2026-04-23 (라우트 경로 수정, breakpoint 예외 명시, 구현 복잡도 보완)
--- ---
## 1. 목표 ## 1. 목표
- 모든 페이지(13개)에서 모바일 UI 짤림 현상 해결 - 전체 15개 뷰(12개 라우트 + 3개 서브라우트)에서 모바일 UI 짤림 현상 해결
- 현재 다크 네온 사이버펑크 디자인 톤 유지 - 현재 다크 네온 사이버펑크 디자인 톤 유지
- 모바일 전용 UX 패턴 추가 (바텀 네비게이션, 스와이프, 풀다운 리프레시, FAB, 바텀시트) - 모바일 전용 UX 패턴 추가 (바텀 네비게이션, 스와이프, 풀다운 리프레시, FAB, 바텀시트)
- 기능적 손실 없이 반응형 적용 - 기능적 손실 없이 반응형 적용
**대상 뷰 목록 (routes.jsx 기준):**
| # | 라우트 | 컴포넌트 | 비고 |
|---|--------|---------|------|
| 1 | `/` | Home | |
| 2 | `/lotto` | Lotto | 3탭 (Briefing/Analysis/Purchase) |
| 3 | `/stock` | Stock | |
| 4 | `/stock/trade` | StockTrade | 서브라우트 |
| 5 | `/travel` | Travel | |
| 6 | `/blog` | Blog | |
| 7 | `/blog-lab` | BlogMarketing | |
| 8 | `/realestate` | Subscription | |
| 9 | `/music` | MusicStudio | |
| 10 | `/todo` | Todo | |
| 11 | `/agent-office` | AgentOffice | |
| 12 | `/lab` | EffectLab | |
| 13 | `/lab/sword-stream` | SwordStream | 서브라우트 |
| 14 | `/lab/day-calc` | DayCalc | 서브라우트 |
> Note: `RealEstate.jsx` (`/realestate/property`)는 routes.jsx에 미등록 상태. 반응형 스코프에서 제외.
--- ---
## 2. 접근 방식 ## 2. 접근 방식
@@ -20,7 +42,7 @@
1. 공통 모바일 인프라(컴포넌트, breakpoint, 앱 셸) 구축 1. 공통 모바일 인프라(컴포넌트, breakpoint, 앱 셸) 구축
2. 주요 4개 페이지 (홈, 로또, 주식, 여행) 우선 적용 2. 주요 4개 페이지 (홈, 로또, 주식, 여행) 우선 적용
3. 나머지 9개 페이지 확장 적용 3. 나머지 페이지 확장 적용
--- ---
@@ -37,7 +59,17 @@
| lg | 1024px | 소형 데스크톱 | | lg | 1024px | 소형 데스크톱 |
| xl | 1280px | 대형 데스크톱 | | xl | 1280px | 대형 데스크톱 |
기존 미디어 쿼리의 비표준 값(640px, 900px, 960px, 1100px 등)은 기능 손실 없이 가장 가까운 표준 breakpoint로 정리한다. 단, 특정 페이지에서 세밀한 조정이 반드시 필요한 경우 예외를 허용한다. 기존 미디어 쿼리의 비표준 값(640px, 900px, 960px, 1100px 등)은 기능 손실 없이 가장 가까운 표준 breakpoint로 정리한다.
**허용 예외 (이동 시 시각적 회귀 발생):**
| 기존 값 | 파일 | 사유 |
|---------|------|------|
| 420px | Stock.css (4곳) | 소형 폰 전용 패딩/라벨 축소, 480px로 이동 시 중간 기기에서 불필요한 축소 |
| 520px | Stock.css (1곳) | 지표 카드 특수 레이아웃 |
| 700px | Stock.css (1곳) | AI 코치 설정 그리드, 768px로 이동 시 태블릿에서 조기 축소 |
위 값들은 해당 페이지 CSS에서 기존 값을 유지한다.
### 3-2. 바텀 네비게이션 바 (`BottomNav`) ### 3-2. 바텀 네비게이션 바 (`BottomNav`)
@@ -47,8 +79,27 @@
- 사이드바는 모바일에서 완전히 숨김 (기존 햄버거→슬라이드 방식 제거) - 사이드바는 모바일에서 완전히 숨김 (기존 햄버거→슬라이드 방식 제거)
- 높이: 56~64px - 높이: 56~64px
- `env(safe-area-inset-bottom)` 대응 (노치/홈 인디케이터 기기) - `env(safe-area-inset-bottom)` 대응 (노치/홈 인디케이터 기기)
- `index.html``viewport-fit=cover` 추가 필요: `<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">`
- 더보기 메뉴: 탭 시 위로 펼쳐지는 오버레이 패널 - 더보기 메뉴: 탭 시 위로 펼쳐지는 오버레이 패널
**사이드바→바텀네비 마이그레이션 상세:**
- `Navbar.jsx`: 768px 이하에서 사이드바 렌더링 제거, `sidebar-toggle` 버튼 제거
- `Navbar.css`: `.sidebar` transform/transition 미디어 쿼리 제거, `.sidebar__overlay` 제거
- `Navbar.jsx` useEffect: `body.overflow = 'hidden'` 토글 로직 정리
- `App.jsx`에서 `BottomNav` 컴포넌트 조건부 렌더링 (`useIsMobile()` 기반)
**더보기 메뉴 내용 (나머지 네비게이션 항목):**
| 순서 | 아이콘 | 라벨 | 경로 |
|------|--------|------|------|
| 1 | 음악 | 뮤직 | `/music` |
| 2 | 로봇 | 에이전트 | `/agent-office` |
| 3 | 블로그 | 블로그 | `/blog` |
| 4 | 마케팅 | 블로그랩 | `/blog-lab` |
| 5 | 건물 | 청약 | `/realestate` |
| 6 | 체크 | TODO | `/todo` |
| 7 | 실험 | 이펙트랩 | `/lab` |
**기본 5개 메뉴 구성:** **기본 5개 메뉴 구성:**
| 순서 | 아이콘 | 라벨 | 경로 | | 순서 | 아이콘 | 라벨 | 경로 |
@@ -69,13 +120,21 @@
| `FAB` | `src/components/FAB.jsx` | 플로팅 액션 버튼 (바텀 네비 위 배치) | | `FAB` | `src/components/FAB.jsx` | 플로팅 액션 버튼 (바텀 네비 위 배치) |
| `MobileSheet` | `src/components/MobileSheet.jsx` | 바텀시트 모달 (드래그 핸들, 스냅 포인트) | | `MobileSheet` | `src/components/MobileSheet.jsx` | 바텀시트 모달 (드래그 핸들, 스냅 포인트) |
**공통 훅:** **공통 훅 (신규 `src/hooks/` 디렉토리 생성):**
> 기존 훅은 페이지별 디렉토리에 colocate (`src/pages/lotto/hooks/` 등).
> 모바일 인프라 훅은 여러 페이지에서 공유하므로 `src/hooks/`에 배치한다.
| 훅 | 파일 | 역할 | | 훅 | 파일 | 역할 |
|----|------|------| |----|------|------|
| `useIsMobile` | `src/hooks/useIsMobile.js` | 768px 이하 감지 (matchMedia) | | `useIsMobile` | `src/hooks/useIsMobile.js` | 768px 이하 감지 (matchMedia) |
| `useSwipe` | `src/hooks/useSwipe.js` | 터치 스와이프 방향·거리 감지 | | `useSwipe` | `src/hooks/useSwipe.js` | 터치 스와이프 방향·거리 감지 |
**경량 라이브러리 활용:**
- `react-swipeable` (~3KB gzipped): SwipeableView/useSwipe 기반으로 활용 — 터치 velocity, threshold snap, 방향 판별을 직접 구현하지 않음
- PullToRefresh: 터치 이벤트 직접 구현하되, iOS Safari rubber-banding 및 `overscroll-behavior: contain` 대응 필수
- MobileSheet: CSS `transform` + `touch-action: none`으로 구현, 스냅 포인트 2단계 (50%, 90%)
### 3-4. 앱 셸 레이아웃 변경 ### 3-4. 앱 셸 레이아웃 변경
``` ```
@@ -171,7 +230,7 @@
- FAB: "글 쓰기" - FAB: "글 쓰기"
- 풀다운 리프레시: 글 목록 갱신 - 풀다운 리프레시: 글 목록 갱신
### 5-2. 블로그 마케팅 (BlogMarketing) — `/blog-marketing` ### 5-2. 블로그 마케팅 (BlogMarketing) — `/blog-lab`
| 영역 | 모바일 변경 | | 영역 | 모바일 변경 |
|------|------------| |------|------------|
@@ -196,28 +255,22 @@
- FAB: "공고 등록" - FAB: "공고 등록"
- 풀다운 리프레시: 공고/매칭 갱신 - 풀다운 리프레시: 공고/매칭 갱신
### 5-4. 관심 매물 (RealEstate) — `/realestate/property` ### 5-4. 뮤직 스튜디오 (MusicStudio) — `/music`
| 영역 | 모바일 변경 |
|------|------------|
| 매물 목록 | 카드형 리스트 |
| 지도 뷰 | 높이 35vh, 핀치 줌 |
### 5-5. 뮤직 스튜디오 (MusicStudio) — `/lab/music`
| 영역 | 모바일 변경 | | 영역 | 모바일 변경 |
|------|------------| |------|------------|
| 헤더 | 1컬럼, 타이틀 클램프 축소 | | 헤더 | 1컬럼, 타이틀 클램프 축소 |
| 생성 폼 | 풀 너비 스택 | | 생성 폼 | 풀 너비 스택 |
| 라이브러리 | 1컬럼 리스트 (앨범아트 + 제목) | | 라이브러리 | 1컬럼 리스트 (앨범아트 + 제목) |
| 플레이어 | 미니 플레이어 바텀 고정 (바텀 네비 위) | | 플레이어 | 미니 플레이어 바텀 고정 (높이 56px, 바텀 네비 위 = bottom: 64px) |
| 가사 에디터 | 풀 너비 | | 가사 에디터 | 풀 너비 |
| 레이더 위젯 | 중앙 정렬 | | 레이더 위젯 | 중앙 정렬 |
- FAB: "음악 생성" - FAB: "음악 생성"
- 풀다운 리프레시: 라이브러리 갱신 - 풀다운 리프레시: 라이브러리 갱신
- 미니 플레이어 표시 시 콘텐츠 padding-bottom: 바텀네비(64px) + 미니플레이어(56px) = 120px
### 5-6. TODO — `/todo` ### 5-5. TODO — `/todo`
| 영역 | 모바일 변경 | | 영역 | 모바일 변경 |
|------|------------| |------|------------|
@@ -227,7 +280,7 @@
- FAB: "할일 추가" - FAB: "할일 추가"
### 5-7. 에이전트 오피스 (AgentOffice) — `/lab/agent-office` ### 5-6. 에이전트 오피스 (AgentOffice) — `/agent-office`
| 영역 | 모바일 변경 | | 영역 | 모바일 변경 |
|------|------------| |------|------------|
@@ -237,7 +290,7 @@
| 명령 입력 | 하단 입력 바 (채팅 UX) | | 명령 입력 | 하단 입력 바 (채팅 UX) |
| WebSocket 상태 | 탑바에 연결 상태 아이콘 | | WebSocket 상태 | 탑바에 연결 상태 아이콘 |
### 5-8. 이펙트 랩 — `/lab`, `/lab/day-calc`, `/lab/sword-stream` ### 5-7. 이펙트 랩 — `/lab`, `/lab/day-calc`, `/lab/sword-stream`
| 페이지 | 모바일 변경 | | 페이지 | 모바일 변경 |
|--------|------------| |--------|------------|
@@ -263,31 +316,45 @@
- 이미지: `loading="lazy"` 속성 확인 - 이미지: `loading="lazy"` 속성 확인
- 스와이프/터치 이벤트: passive listener 사용 - 스와이프/터치 이벤트: passive listener 사용
- 바텀시트 애니메이션: `transform` + `will-change` 사용 (layout thrashing 방지) - 바텀시트 애니메이션: `transform` + `will-change` 사용 (layout thrashing 방지)
- 신규 애니메이션(스와이프, 바텀시트, 풀다운)은 `prefers-reduced-motion: reduce` 쿼리 존중 — Travel.css, MusicStudio.css 기존 패턴과 통일
### 주의: Stock.css / StockTrade.jsx 커플링
`StockTrade.jsx``Stock.css`의 스타일을 공유한다. Stock.css의 반응형 수정은 StockTrade에도 영향을 미치므로, 반드시 두 페이지를 함께 검증해야 한다.
--- ---
## 8. 구현 순서 ## 8. 구현 순서
### Phase 1: 글로벌 인프라 ### Phase 1: 글로벌 인프라
1. Breakpoint 시스템 통일 (index.css)
2. `useIsMobile`, `useSwipe` 훅 생성 **Phase 1a: Breakpoint 정리 (기존 CSS만 수정, 신규 코드 없음)**
3. `BottomNav` 컴포넌트 구현 1. Breakpoint 시스템 통일 — 각 CSS 파일의 비표준 미디어 쿼리를 표준 값으로 정리
4. `PullToRefresh`, `SwipeableView`, `FAB`, `MobileSheet` 컴포넌트 구현 2. `index.html` `viewport-fit=cover` 추가
5. 앱 셸 레이아웃 수정 (App.jsx, App.css) 3. 회귀 테스트: 정리 후 각 페이지 데스크톱/모바일 확인
**Phase 1b: 공통 컴포넌트 & 앱 셸**
4. `react-swipeable` 패키지 설치
5. `src/hooks/` 디렉토리 생성 + `useIsMobile`, `useSwipe` 훅 구현
6. `BottomNav` 컴포넌트 구현 + 사이드바 모바일 제거 마이그레이션 (Navbar.jsx/css 수정)
7. `PullToRefresh`, `SwipeableView`, `FAB`, `MobileSheet` 컴포넌트 구현
8. 앱 셸 레이아웃 수정 (App.jsx, App.css)
### Phase 2: 주요 페이지 적용 ### Phase 2: 주요 페이지 적용
6. 홈 페이지 반응형 개선 9. 홈 페이지 반응형 개선
7. 로또 페이지 반응형 개선 10. 로또 페이지 반응형 개선
8. 주식 페이지 (Stock + StockTrade) 반응형 개선 11. 주식 페이지 (Stock + StockTrade 함께 검증) 반응형 개선
9. 여행 페이지 반응형 개선 12. 여행 페이지 반응형 개선
### Phase 3: 나머지 페이지 확장 ### Phase 3: 나머지 페이지 확장
10. 블로그 + 블로그 마케팅 13. 블로그 (`/blog`) + 블로그 마케팅 (`/blog-lab`)
11. 부동산 (Subscription + RealEstate) 14. 부동산 청약 (`/realestate`)
12. 뮤직 스튜디오 15. 뮤직 스튜디오 (`/music`)
13. TODO 16. TODO (`/todo`)
14. 에이전트 오피스 17. 에이전트 오피스 (`/agent-office`)
15. 이펙트 랩 (EffectLab + DayCalc + SwordStream) 18. 이펙트 랩 (`/lab` + `/lab/day-calc` + `/lab/sword-stream`)
### Phase 4: 검증 ### Phase 4: 검증
16. 전체 페이지 모바일 UI 검증 및 수정 19. 전체 모바일 UI 검증 — 대상 뷰포트: 360px (Galaxy S), 390px (iPhone 14), 768px (iPad), 1024px (데스크톱)
20. `prefers-reduced-motion` 동작 확인
21. 터치 타겟 크기 검증 (44×44px 최소)