Files
web-page-backend/docs/superpowers/specs/2026-04-23-responsive-web-design.md
gahusb bd7875b36a 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>
2026-04-23 14:17:07 +09:00

14 KiB
Raw Blame History

반응형 웹 UI/UX 전면 개선 설계

모바일에서 UI 짤림 현상 해결 + 풀 모바일 경험 적용 작성일: 2026-04-23 리뷰 반영: 2026-04-23 (라우트 경로 수정, breakpoint 예외 명시, 구현 복잡도 보완)


1. 목표

  • 전체 15개 뷰(12개 라우트 + 3개 서브라우트)에서 모바일 UI 짤림 현상 해결
  • 현재 다크 네온 사이버펑크 디자인 톤 유지
  • 모바일 전용 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. 접근 방식

글로벌 모바일 시스템 구축 → 주요 페이지 적용 → 전체 페이지 확장

  1. 공통 모바일 인프라(컴포넌트, breakpoint, 앱 셸) 구축
  2. 주요 4개 페이지 (홈, 로또, 주식, 여행) 우선 적용
  3. 나머지 페이지 확장 적용

3. 글로벌 모바일 인프라

3-1. Breakpoint 시스템 통일

현재 53개 미디어 쿼리에서 다양한 값이 혼재. 4단계로 통일:

이름 용도
sm 480px 소형 폰
md 768px 태블릿/대형 폰 (주요 분기점)
lg 1024px 소형 데스크톱
xl 1280px 대형 데스크톱

기존 미디어 쿼리의 비표준 값(640px, 900px, 960px, 1100px 등)은 기능 손실 없이 가장 가까운 표준 breakpoint로 정리한다.

허용 예외 (이동 시 시각적 회귀 발생):

기존 값 파일 사유
420px Stock.css (4곳) 소형 폰 전용 패딩/라벨 축소, 480px로 이동 시 중간 기기에서 불필요한 축소
520px Stock.css (1곳) 지표 카드 특수 레이아웃
700px Stock.css (1곳) AI 코치 설정 그리드, 768px로 이동 시 태블릿에서 조기 축소

위 값들은 해당 페이지 CSS에서 기존 값을 유지한다.

3-2. 바텀 네비게이션 바 (BottomNav)

  • 768px 이하에서 사이드바 대신 표시
  • 주요 5개 메뉴 아이콘 + "더보기" 메뉴 (나머지 페이지)
  • 현재 페이지 활성 표시 — 네온 시안 글로우 유지
  • 사이드바는 모바일에서 완전히 숨김 (기존 햄버거→슬라이드 방식 제거)
  • 높이: 56~64px
  • env(safe-area-inset-bottom) 대응 (노치/홈 인디케이터 기기)
  • index.htmlviewport-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개 메뉴 구성:

순서 아이콘 라벨 경로
1 /
2 클로버 로또 /lotto
3 차트 주식 /stock
4 카메라 여행 /travel
5 더보기 메뉴 오버레이

3-3. 공통 모바일 컴포넌트

컴포넌트 파일 역할
BottomNav src/components/BottomNav.jsx 하단 고정 네비게이션
PullToRefresh src/components/PullToRefresh.jsx 터치 풀다운 새로고침 래퍼
SwipeableView src/components/SwipeableView.jsx 좌우 스와이프 탭/뷰 전환
FAB src/components/FAB.jsx 플로팅 액션 버튼 (바텀 네비 위 배치)
MobileSheet src/components/MobileSheet.jsx 바텀시트 모달 (드래그 핸들, 스냅 포인트)

공통 훅 (신규 src/hooks/ 디렉토리 생성):

기존 훅은 페이지별 디렉토리에 colocate (src/pages/lotto/hooks/ 등). 모바일 인프라 훅은 여러 페이지에서 공유하므로 src/hooks/에 배치한다.

파일 역할
useIsMobile src/hooks/useIsMobile.js 768px 이하 감지 (matchMedia)
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. 앱 셸 레이아웃 변경

데스크톱:  [사이드바 240px] [콘텐츠]
모바일:    [탑바 56px]
           [콘텐츠 (padding-bottom: 바텀네비 높이)]
           [바텀 네비 56-64px]
  • 콘텐츠 영역에 padding-bottom 추가 (바텀 네비 겹침 방지)
  • 탑바: 현재 구조 유지, 페이지 타이틀 + 액션 버튼 영역
  • body overflow: 모바일에서 auto (현재와 동일)

4. 주요 페이지별 모바일 설계

4-1. 홈 (Home) — /

영역 데스크톱 모바일 (≤768px)
히어로 2컬럼 그리드 1컬럼 스택, 타이틀 축소
네비 카드 그리드 auto-fill minmax(180px) 2컬럼 고정, 카드 높이 축소
TODO 보드 3컬럼 칸반 스와이프 탭 (Todo/진행중/완료)
블로그 포스트 카드 그리드 1컬럼 리스트
프로필 섹션 사이드 카드 하단 접이식 패널
  • 풀다운 리프레시: 블로그 포스트 갱신
  • FAB: 없음 (네비게이션 허브)

4-2. 로또 (Lotto) — /lotto

영역 데스크톱 모바일
3탭 구조 상단 탭바 스와이프 탭 전환
브리핑 탭 카드 레이아웃 1컬럼, 볼 크기 36→32px
분석 탭 그리드 카드 1컬럼 스택
구매 이력 테이블 6컬럼 그리드 가로 스크롤 테이블 + 행 터치 바텀시트
번호 추천 카드 다중 그리드 1컬럼, 볼 간격 조정
전략 차트 넓은 차트 가로스크롤 또는 축소
  • FAB: "추천받기" (빠른 번호 추천)
  • 풀다운 리프레시: 브리핑/분석 데이터 갱신

4-3. 주식 (Stock / StockTrade) — /stock, /stock/trade

Stock (뉴스/지표)

영역 데스크톱 모바일
헤더 2컬럼 1컬럼 스택
뉴스 그리드 auto-fit minmax(260px) 1컬럼 카드 리스트
필터 가로 나열 가로 스크롤 칩 바
지표 카드 그리드 가로 스크롤 카드 캐러셀

StockTrade (매매)

영역 데스크톱 모바일
포트폴리오 테이블 넓은 테이블 카드형 리스트 (종목별 카드)
매도 이력 테이블 가로 스크롤 + 행 터치 바텀시트
자산 차트 넓은 recharts 풀 너비, 축 라벨 축소
예수금 섹션 인라인 접이식 카드
  • FAB: "종목 추가" (Stock), "매도 기록" (StockTrade)
  • 풀다운 리프레시: 뉴스/포트폴리오 갱신

4-4. 여행 (Travel) — /travel

영역 데스크톱 모바일
지역 선택 Leaflet 지도 높이 50vh→35vh, 핀치 줌
사진 그리드 다중 컬럼 2컬럼 → 1컬럼 (≤480px)
사진 상세 모달 풀스크린 뷰어 + 스와이프 넘기기
지역 필터 드롭다운 바텀시트 지역 선택
  • 풀다운 리프레시: 사진 목록 갱신
  • FAB: 없음

5. 나머지 페이지 모바일 설계

5-1. 블로그 (Blog) — /blog

영역 모바일 변경
글 목록 1컬럼 리스트형
글 상세 풀 너비, 폰트 크기 조정
태그 필터 가로 스크롤 칩 바
작성/수정 폼 풀 너비, 툴바 축소
  • FAB: "글 쓰기"
  • 풀다운 리프레시: 글 목록 갱신

5-2. 블로그 마케팅 (BlogMarketing) — /blog-lab

영역 모바일 변경
대시보드 지표 2컬럼 → 1컬럼 (≤480px)
파이프라인 테이블 카드형 리스트 (상태 배지)
키워드 분석 접이식 아코디언
수익 내역 가로 스크롤 테이블
  • FAB: "키워드 분석"
  • 풀다운 리프레시: 대시보드 갱신

5-3. 부동산 청약 (Subscription) — /realestate

영역 모바일 변경
공고 목록 1컬럼 카드 리스트
필터 바텀시트 필터 패널
공고 상세 바텀시트 상세보기
매칭 결과 1컬럼, 점수 강조
대시보드 2컬럼 그리드
  • FAB: "공고 등록"
  • 풀다운 리프레시: 공고/매칭 갱신

5-4. 뮤직 스튜디오 (MusicStudio) — /music

영역 모바일 변경
헤더 1컬럼, 타이틀 클램프 축소
생성 폼 풀 너비 스택
라이브러리 1컬럼 리스트 (앨범아트 + 제목)
플레이어 미니 플레이어 바텀 고정 (높이 56px, 바텀 네비 위 = bottom: 64px)
가사 에디터 풀 너비
레이더 위젯 중앙 정렬
  • FAB: "음악 생성"
  • 풀다운 리프레시: 라이브러리 갱신
  • 미니 플레이어 표시 시 콘텐츠 padding-bottom: 바텀네비(64px) + 미니플레이어(56px) = 120px

5-5. TODO — /todo

영역 모바일 변경
칸반 보드 스와이프 탭 (Todo/진행중/완료)
할일 카드 스와이프로 상태 변경
입력 폼 FAB → 바텀시트 입력 폼
  • FAB: "할일 추가"

5-6. 에이전트 오피스 (AgentOffice) — /agent-office

영역 모바일 변경
캔버스 오피스 풀스크린 캔버스, 핀치 줌/패닝
에이전트 패널 바텀시트 에이전트 상세
작업 로그 바텀시트 로그 뷰
명령 입력 하단 입력 바 (채팅 UX)
WebSocket 상태 탑바에 연결 상태 아이콘

5-7. 이펙트 랩 — /lab, /lab/day-calc, /lab/sword-stream

페이지 모바일 변경
EffectLab 허브 카드 그리드 → 1컬럼 리스트
DayCalc 풀 너비 스택, 네이티브 날짜 피커
SwordStream 풀스크린 캔버스, 터치 인터랙션 유지, 오버레이 축소

6. 터치 타겟 가이드라인

  • 모든 터치 타겟: 최소 44×44px (Apple HIG 기준)
  • 버튼 간 간격: 최소 8px
  • FAB 크기: 56×56px
  • 바텀 네비 아이템: 최소 48×48px 터치 영역

7. 성능 고려사항

  • 모바일에서 글로우/그라디언트 효과: box-shadow 개수 줄이기 (3중→1중)
  • background-attachment: fixed → 모바일에서 scroll (현재 적용됨, 유지)
  • 이미지: loading="lazy" 속성 확인
  • 스와이프/터치 이벤트: passive listener 사용
  • 바텀시트 애니메이션: transform + will-change 사용 (layout thrashing 방지)
  • 신규 애니메이션(스와이프, 바텀시트, 풀다운)은 prefers-reduced-motion: reduce 쿼리 존중 — Travel.css, MusicStudio.css 기존 패턴과 통일

주의: Stock.css / StockTrade.jsx 커플링

StockTrade.jsxStock.css의 스타일을 공유한다. Stock.css의 반응형 수정은 StockTrade에도 영향을 미치므로, 반드시 두 페이지를 함께 검증해야 한다.


8. 구현 순서

Phase 1: 글로벌 인프라

Phase 1a: Breakpoint 정리 (기존 CSS만 수정, 신규 코드 없음)

  1. Breakpoint 시스템 통일 — 각 CSS 파일의 비표준 미디어 쿼리를 표준 값으로 정리
  2. index.htmlviewport-fit=cover 추가
  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: 주요 페이지 적용

  1. 홈 페이지 반응형 개선
  2. 로또 페이지 반응형 개선
  3. 주식 페이지 (Stock + StockTrade 함께 검증) 반응형 개선
  4. 여행 페이지 반응형 개선

Phase 3: 나머지 페이지 확장

  1. 블로그 (/blog) + 블로그 마케팅 (/blog-lab)
  2. 부동산 청약 (/realestate)
  3. 뮤직 스튜디오 (/music)
  4. TODO (/todo)
  5. 에이전트 오피스 (/agent-office)
  6. 이펙트 랩 (/lab + /lab/day-calc + /lab/sword-stream)

Phase 4: 검증

  1. 전체 뷰 모바일 UI 검증 — 대상 뷰포트: 360px (Galaxy S), 390px (iPhone 14), 768px (iPad), 1024px (데스크톱)
  2. prefers-reduced-motion 동작 확인
  3. 터치 타겟 크기 검증 (44×44px 최소)