학생들 90%가
핸드폰으로 쓴다.
그래서 모바일이 본체.
데스크톱은 강사 전용 + 학생 가끔 쓰는 채널.
학생 일상은 모바일 — 사진 찍어 묻고, 노트에 써 묻고, 통학 길에 복습.
이 문서는 5개 모바일 화면(mobile-home / chat / photo / write / drill)을
시스템으로 묶어 PWA 구현까지 연결한다.
System · 01
화면 맵 — 5개로 끝
데스크톱은 7화면(채팅·사진·강사 큐·디자인 시스템 등)이지만 모바일은 학생만 5화면. 강사 큐는 모바일에서 안 함.
묻기 홈 mobile-home.html
진입점. Hero CTA 2개(사진/글) + 오늘 복습 카드 + 이어할 대화 + 강사 코멘트 알림.
글로 묻기 mobile-write.html
노트 종이톤 textarea + 수식 toolbar. 보내기 → 대화로.
사진 채점 mobile-photo.html
가로 스크롤 사진 + OCR 게이트 + 풀-블리드 빨간펜 채점.
대화 mobile-chat.html
스텝 collapse + 인용 sheet + sticky composer. 모든 입력의 결과 화면.
오늘 복습 mobile-drill.html
4가지 신호(AskAI fail / 시험 오답 / 숙제 감점 / 단원지 X)에서 자동 카드. SM-2 + "모름" → 대화 재진입.
Foundations · 01
모바일-only 토큰
desktop과 공유하는 토큰은 _shared.css. 모바일만의 추가는 7개.
--safe-bottom
env(safe-area-inset-*) wrapping. 노치/홈 인디케이터 침범 방지. viewport-fit=cover 필수.
0 24px 60px rgba(0,0,0,0.10)
--margin-line
--paper-textbook paper textarea / 사진 SVG 도메인 톤 — desktop과 공유 (이미 _shared.css에 추출됨)
Foundations · 02
뷰포트 규약
모든 모바일 화면이 따라야 할 head 메타.
width=device-width, initial-scale=1, viewport-fit=cover — cover 없으면 노치 영역 비어 보임
#fafbfc (canvas) 또는 #f7f5ee (paper, write 화면만)
yes
max-width: 430px; margin: 0 auto; @media (min-width:480px) { border-radius: 36px; box-shadow: var(--shadow-frame); }
Foundations · 03
터치타겟
모바일은 데스크톱과 다르게 모든 인터랙션 ≥ 44×44px 디폴트. _shared.css의 @media (pointer: coarse)가 자동 적용.
min-height: 44px
::after { inset: -12px }로 hit 44px
Atoms
모바일-only 아톰 7종
desktop에 없는 모바일 전용 컴포넌트. desktop과 공유하는 Button·Chip·Badge 등은 design-system.html 참조.
Molecules
모바일-only 몰리큘 5종
인용된 자료 3개
한 줄로도 좋고,
풀이 과정 풀어 적어도
좋아.
Patterns
5 화면 와이어프레임
9:16 폰 비율. 클릭하면 실제 mockup으로.
Implementation · 01
PWA 전략 — 별도 앱 X, 기존 student 앱 확장
이미 apps/student가 React + Vite로 모바일 친화적. 추가만 하면 됨.
왜 PWA 추천
장점: 기존 코드 베이스 재사용 (학생 인증·라우팅·KaTeX·Layout 다 있음). 앱스토어 심사 없음. URL 공유 가능. 학원 도메인 한 곳에서 관리.
모바일 추가:
manifest.json— 이름·아이콘·테마컬러·시작URL·standalone 디스플레이sw.js또는 Vite PWA 플러그인 — 정적 자산 캐싱 + 오프라인 fallback<meta>추가 — viewport-fit=cover, theme-color, apple-mobile-web-app-capable- 홈화면 추가 프롬프트 (a2hs) — 학생에게 한 번만 안내
왜 React Native 아님 대안
앱스토어 심사·iOS 인증서·CodePush·React Native 학습 곡선·디자인 시스템 재구현 — 모두 비용. 학원 학생 100명 단위 사용량에선 ROI 약함. 나중에 사용자 1000+ 가 되거나 카메라 ML 같은 native 강한 기능이 필요해지면 그때 Capacitor wrapper로 점진 이전.
Capacitor 옵션 필요 시
PWA로 시작 → 나중에 카메라·푸시 등 native API가 정말 필요하면 Capacitor로 같은 React 코드를 네이티브 wrapper에 넣음. 코드 재작성 X. 현 단계에선 대부분 PWA Web API로 충분.
Implementation · 02
필요한 Native API 4개
전부 Web API로 가능. 해상도·권한 처리만 잘 하면 PWA로 충분.
<input type="file" accept="image/*" capture="environment"> 가 더 단순 (네이티브 카메라 앱 호출).Implementation · 03
오프라인 · 캐싱 전략
학생 통학길 = 오프라인 ↔ 약신호 반복. 핵심 기능 살아있어야.
화면별 오프라인 동작
- mobile-home: 마지막 fetch한 데이터 캐시 → 오프라인서도 보임 ("연결 안 됨" 배너만)
- mobile-drill: 오늘 카드 8장 + 정답 + AI cite 미리 prefetch. 자가평가는 IndexedDB 큐에 → 온라인 시 동기. 오프라인 핵심 기능
- mobile-chat: 새 질문은 큐에 저장 → 온라인 시 send. 기존 대화는 캐시에서
- mobile-photo: 사진 업로드는 reliable connection 필요 → 오프라인 시 "연결되면 보냄" 큐
- mobile-write: textarea 내용 localStorage 자동저장. 오프라인 send 큐
Implementation · 04
열린 질문
구현 들어가기 전 답이 필요한 것.
설치 프롬프트 시점
3번 사용 후? 첫 강사 코멘트 받으면? 학생이 짜증 안 날 시점.
기존 BottomTabBar.tsx 와 어떻게 통합
이미 있는 컴포넌트에 "묻기" 탭 추가만 할지, 별도 layout으로 갈지.
강사 코멘트 푸시 정책
모든 코멘트? OK 처리만? 빈도 제한? 학생이 끄는 옵션?
drill 카드 prefetch 시점
아침 wifi 잡혔을 때 자동? 명시적 다운로드 버튼? 매일 0시 백그라운드 sync?
업로드 압축 정책
학생 폰 카메라 = 4MB+. AI 입력엔 1MB도 충분. 클라이언트 압축 강제.
input file vs getUserMedia
input file = 단순 + iOS 호환. getUserMedia = UI 통제 가능. MVP는 input file 권장.
iOS 키보드 올라올 때 sticky composer 처리
visualViewport.height 감지 + composer 위치 조정. 또는 Visual Viewport API.
iOS bounce 스크롤 처리
bottom sheet open 시 background scroll 막기. overscroll-behavior: contain + body scroll lock.