Skip to content

fix: 좁은 화면에서 영상 페이지·인증 모달 사용성 복구 - #19

Merged
gylee44 merged 3 commits into
developfrom
fix/mobile-header-a11y
Sep 15, 2026
Merged

gylee44 merged 3 commits into
developfrom
fix/mobile-header-a11y

Conversation

@gylee44

@gylee44 gylee44 commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

배경

영상 분석 페이지와 인증 모달이 폰 폭에서 깨져 있었다. 사이드바는 데스크톱 전용 고정 폭이라 393px 화면에서 본문을 덮었고, 우측 타임라인 컬럼은 340px 고정이라 가로 스크롤을 만들었다. 인증 모달은 바깥 여백과 폼 여백이 이중으로 잡혀 안쪽 폭이 216px까지 좁아졌다.

변경

영상 플레이어

  • 사이드바를 lg 미만에서 서랍으로 전환 (배경 클릭 / ESC / 닫기 버튼)
  • 데스크톱 '접기' 상태는 서랍에 적용하지 않고 항상 펼친 모양으로 그림
  • 좁은 화면 상단 바 추가 — 영상 제목이 사이드바에만 있어 서랍을 닫으면 무엇을 보고 있는지 알 수 없었다
  • 우측 컬럼을 lg 미만에서 폭 100%로 눕히고 좌/우를 세로로 쌓음
  • 스트로크 필터 칩 줄바꿈, TOP 3 하이라이트 1열 전환
  • 100vh100dvh — 모바일 주소창이 접혔다 펴져도 잘리지 않음

목록 / 대시보드

  • 액션 버튼을 좁은 화면에서 아래 줄로 내리고 44px 터치 목표 확보
  • 로딩 골격을 실제 행과 같은 모양으로 맞춤

인증 모달 / 폼

  • Tab 포커스를 모달 안에 가둠 (헤더·본문으로 새어나가고 있었다)
  • 열 때 카드로 포커스 이동, 닫을 때 호출 버튼으로 복귀
  • 이중 여백 제거, 닫기 버튼 44px, overscroll-contain, env(safe-area-inset-*)
  • 세 폼이 각자 들고 있던 클래스 문자열을 authFormStyles.ts로 통합
  • autocomplete 추가, label htmlFor 연결, 입력 16px 유지 (iOS 확대 방지)
  • fetch 실패와 비 JSON 응답(프록시 오작동)을 구분해 원인 있는 메시지로

접근성 후속 수정 (1161c61)

닫힌 서랍이 -translate-x-full로만 밀려나 내부 버튼 10여 개가 탭 순서에 남아 있었다. aria-hidden까지 걸려 있어 "aria-hidden 영역에 포커스 가능한 요소" 위반. invisible + lg:visible로 교체하고 visibility를 transition 목록에 넣어 닫힘 애니메이션을 유지했다.

검증

  • npm run build 통과. 생성된 CSS에 transition-property:transform,visibility 확인
  • Web Interface Guidelines 감사 실행 — 이 diff 범위의 차단 항목 없음
  • npm test는 실행 못 함 (설치된 Node가 --experimental-strip-types 미지원, 기존 환경 문제)
  • 실기기 확인은 안 됨 — 반응형 변경이라 머지 후 폰에서 한 번 봐야 함

후속 과제 (이 PR 범위 밖)

  • 서랍 열림 시 포커스 이동/트랩·body 스크롤 잠금 (모달은 구현, 서랍은 없음)
  • 썸네일 loading="lazy", width/height
  • VITE_GEMINI_API_KEY가 클라이언트 번들에 인라인됨 — 기존 문제이며 이 PR과 무관하지만 별도 처리 필요
  • 안 쓰는 의존성 react-router-dom, @google/genai 제거 시 Dependabot critical 1건 + high 2건 해소

🤖 Generated with Claude Code

온보딩 네비게이션은 로고를 left:50% 로 고정 배치해 레이아웃 폭 계산에
잡히지 않았다. 폰에서는 이 로고가 우측 버튼 위를 덮어 [로그인] 이
완전히 가려졌고, 모바일에서 로그인 진입 자체가 막혀 있었다.
로고 중앙 정렬을 768px 이상으로 한정하고 그 아래에서는 좌측에 고정한다.

nav
- 폰에서 로고 h-9, 좌우 여백을 --nav-gutter 하나로 통일
- 375px 미만에서는 [로그인] 숨김 (회원가입 모달 안에서 전환 가능)
- 탭 영역 48px / 46px 확보
- left 대신 transform 을 애니메이션, transition-all 제거
- prefers-reduced-motion 에서 이동만 정지하고 REC 점멸은 유지
- 타임코드를 state 대신 DOM 에 직접 기록 (nav 전체가 초당 21회
  리렌더되고 있었다). UTC 날짜 + 로컬 시각을 섞어 쓰던 것도 정정

login form
- label 과 input 을 htmlFor 로 연결 (연결이 없어 라벨 클릭·스크린리더
  모두 동작하지 않았다)
- autocomplete 추가로 비밀번호 관리자 동작
- 포커스 링 추가

theme
- 명시도 0 인 :focus-visible 기본 규칙. 자체 포커스 스타일이 있는
  컴포넌트는 그대로 두고, 아무것도 없던 요소만 채운다

html
- lang=en → ko, 로고 preload, 이미지 CDN preconnect, theme-color

onboarding
- fetchPriority 는 React 19 전용이라 매 렌더마다 경고가 찍히고 있었다
영상 분석 페이지와 인증 모달이 폰 폭에서 깨져 있었다. 사이드바는
데스크톱 전용 고정 폭이라 393px 화면에서 본문을 덮었고, 우측 타임라인
컬럼은 340px 고정이라 가로 스크롤을 만들었다. 인증 모달은 바깥
여백과 폼 여백이 이중으로 잡혀 안쪽 폭이 216px까지 좁아졌다.

video player
- 사이드바를 lg 미만에서 서랍으로 전환 (배경 클릭 / ESC / 닫기 버튼)
  데스크톱 '접기' 상태는 서랍에 적용하지 않고 항상 펼친 모양으로 그린다
- 좁은 화면 상단 바 추가. 영상 제목이 사이드바에만 있어 서랍을 닫으면
  무엇을 보고 있는지 알 수 없었다
- 우측 컬럼을 lg 미만에서 폭 100% 로 눕히고 좌/우를 세로로 쌓음
- 스트로크 필터 칩을 좁은 화면에서 줄바꿈 (가로 스크롤은 lg 이상만)
- TOP 3 하이라이트 1열 전환, hover 안내 문구는 sm 이상에서만
- 100vh → 100dvh: 모바일 주소창이 접혔다 펴져도 잘리지 않는다

video item / dashboard
- 액션 버튼을 좁은 화면에서 아래 줄로 내리고 44px 터치 목표 확보
- 로딩 골격도 같은 모양으로 맞춤 (골격과 실제 행의 높이가 달랐다)
- 썸네일 h-14 w-24 → sm 이상 72x112

auth modal
- Tab 포커스를 모달 안에 가둠 (헤더·본문으로 새어나가고 있었다)
- 열 때 카드로 포커스 이동, 닫을 때 호출 버튼으로 복귀
- 이중 여백 제거: 카드 껍데기는 모달이, 내용만 폼이 갖는다
- 닫기 버튼 44px, aria-label 한글화, aria-modal / aria-label 추가
- overscroll-contain 으로 카드 끝에서 뒤 페이지가 따라 움직이지 않게
- fetch 실패와 비 JSON 응답(프록시 오작동 시 index.html)을 구분해
  원인을 알 수 있는 메시지로

auth forms
- 세 폼이 각자 들고 있던 클래스 문자열을 authFormStyles.ts 로 통합.
  입력 높이·글자 크기가 폼마다 미묘하게 달랐다
- input 16px 유지 (iOS 사파리가 그 미만에서 포커스 시 확대한다)
- autocomplete 추가로 비밀번호 관리자 동작
- label htmlFor 연결, id 는 useId 로 생성해 재마운트 시 충돌 방지
- break-keep 으로 한글이 어절 중간에서 잘리지 않게
- OTP 입력 시 비어 있는 첫 칸으로 커서 이동
- onLogin await 누락 수정

misc
- useMediaQuery 훅 추가 (CSS 로 표현 못 하는 분기용)
- scrollbar-none 유틸리티 정의. Tailwind v4 에는 없어서 클래스만
  붙어 있고 동작하지 않았다
- App.tsx 의 미사용 LoginForm import 제거
서랍을 -translate-x-full 로만 밀어내서, 닫혀 있어도 내부 버튼 10여 개가
탭 순서와 접근성 트리에 남아 있었다. aria-hidden 까지 같이 걸려 있어
"aria-hidden 영역에 포커스 가능한 요소" 위반이기도 했다. 폰에서 키보드나
스위치 컨트롤로 탭하면 화면 밖 버튼으로 포커스가 사라졌다.

- 닫힌 상태에 invisible 추가, lg 이상은 lg:visible 로 복구.
  visibility 는 CSS 브레이크포인트로만 갈리므로 JS 첫 렌더 깜빡임이 없다
- visibility 를 transition 목록에 넣어 닫힘 애니메이션 유지
- 이제 필요 없어진 aria-hidden 제거 (visibility 가 같은 일을 정확히 한다)
- 서랍에 overscroll-contain 추가 — 끝까지 스크롤해도 뒤 페이지가 안 따라온다
- transition-all 두 곳을 실제 애니메이션 속성으로 명시
@gylee44
gylee44 merged commit ecd76d9 into develop Sep 15, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant