Files
joke-app/docs/07-ui-ux.md

158 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 07. UI/UX 설계
## 1. 디자인 원칙
1. **한 화면에 할 일 하나.** 지금 눌러야 하는 버튼이 가장 크고 진하다.
2. **글자 + 아이콘.** 아이콘만 있는 버튼 금지(닫기 ✕ 제외).
3. **지금 상황을 문장으로.** 화면 맨 위에 "내 차례예요. 돌을 놓을 곳을 눌러 주세요."
4. **할 수 있는 것만 누를 수 있게.** 둘 수 있는 곳·낼 수 있는 카드만 밝게, 나머지는 흐리게. 잘못 누르면 짧게 흔들리고 이유를 한 줄로("같은 색 카드만 낼 수 있어요").
5. **실수 방지.** 큰 결정(기권, 나가기, 올인, 다이)은 확인. 단, 매 턴 확인창은 금지(느려짐) — 대신 "두 번 눌러 확정" 옵션(바둑·오목 오착 방지, 기본 켜짐: 첫 탭은 미리보기 돌, 같은 곳을 다시 탭하면 착수).
6. **기다림을 보여 준다.** 남은 시간 링, "OO님이 생각 중…", 연결 상태.
7. **가볍게.** 장식 이미지 최소, 애니메이션은 짧게(150~250ms), `prefers-reduced-motion` 존중.
## 2. 디자인 토큰
### 2.1 색 (밝은 테마 / 어두운 테마)
| 토큰 | 밝게 | 어둡게 | 용도 |
|---|---|---|---|
| `--bg` | #F7F5F0 | #16181D | 배경(따뜻한 미색) |
| `--surface` | #FFFFFF | #20232A | 카드, 패널 |
| `--text` | #1C1E21 | #F2F3F5 | 본문(명암비 15:1 이상) |
| `--text-sub` | #4A4F57 | #B8BCC4 | 보조 글(4.5:1 이상) |
| `--primary` | #2563EB | #5B8DEF | 주요 버튼(파랑) |
| `--primary-text` | #FFFFFF | #0B1020 | 주요 버튼 글자 |
| `--success` | #15803D | #4ADE80 | 준비, 성공 |
| `--warning` | #B45309 | #FBBF24 | 시간 부족, 연결 불안정 |
| `--danger` | #B91C1C | #F87171 | 기권, 나가기 |
| `--felt` | #1F6B4A | #17513A | 카드 게임 테이블 |
| `--wood` | #E3B76B | #B98C45 | 바둑판·오목판·장기판 |
| `--focus` | #F59E0B | #F59E0B | 키보드 포커스 테두리 3px |
- 색만으로 정보를 전달하지 않는다(내 차례 = 색 + 글자 + 테두리). 색약 모드: 카드 무늬에 모양 추가(♦에 빗금 등), 팀 색을 파랑/주황 조합으로.
### 2.2 글자
- 글꼴: Pretendard Variable(자체 호스팅, KS X 1001 서브셋 + 필요한 문자).
- 크기 단계(기본 "보통"): 본문 17px, 작은 글 15px(최소), 버튼 18px, 제목 22/28px. 줄 간격 1.5.
- 글자 크기 설정: 보통(100%) / 크게(120%) / 아주 크게(140%). 루트 `font-size`만 바꾸고 모든 크기는 `rem`으로.
- 굵기: 본문 500, 버튼·제목 700. 300 이하 금지.
### 2.3 크기·간격
- 터치 영역 최소 48×48px, 주요 버튼 높이 56px, 버튼 사이 간격 최소 8px.
- 간격 단위 4px(4/8/12/16/24/32).
- 모서리 둥글기 12px(버튼), 16px(카드).
- 바둑판처럼 칸이 작은 보드: 칸 크기가 32px 미만이면 "확대 보기" 버튼 + 두 손가락 확대 지원, "두 번 눌러 확정" 기본 켜짐.
## 3. 화면 틀 — PC 중심 (2026-10-04 결정)
사용자 요청으로 **PC 화면을 기준으로 설계**한다. 휴대폰·태블릿은 같은 화면을 세로로 접어서 지원한다.
### 3.1 화면 폭 구간
| 구간 | 폭 | 배치 |
|---|---|---|
| PC (기준) | 1100px 이상 (설계 기준 1280~1920) | 상단 메뉴 + 여러 칸 배치, 채팅·기보 항상 보임 |
| 태블릿 | 720~1099px | 두 칸 → 한 칸으로 접힘, 오른쪽 패널은 판 아래로 |
| 휴대폰 | 720px 미만 | 한 칸, 채팅은 버튼으로 여는 시트, 주요 버튼은 아래 고정 |
### 3.2 공통 상단 메뉴 (PC)
```
┌──────────────────────────────────────────────────────────────────────────┐
│ ● 같이 놀자 보드게임 홈 게임 목록 [코드 6자리 입력칸][참여] 👤 닉네임 ▾ │ 64px
└──────────────────────────────────────────────────────────────────────────┘
```
- 어느 화면에서든 코드를 바로 넣어 참여할 수 있게 상단에 코드 입력칸을 둔다.
- 내용 폭은 최대 1280px, 가운데 정렬. 게임 화면만 화면 전체 폭을 쓴다.
### 3.3 홈 (PC)
```
┌ 상단 메뉴 ───────────────────────────────────────────────────────────────┐
│ [+ 방 만들기 (큰 버튼)] [코드로 참여: □□□ □□□ ] [▶ 하던 게임으로] │
├──────────────────────────────────────────────────────┬───────────────────┤
│ 게임 카드 격자 (4~5열, 카드에 인원·시간·난이도) │ 지금 열린 공개 방 │
│ │ (게임·인원·참여) │
└──────────────────────────────────────────────────────┴───────────────────┘
```
### 3.4 대기실 (PC)
```
┌──────────────────────────────┬────────────────────────────────┐
│ 초대 카드(코드 크게, 복사·QR) │ 자리 목록(2~10칸 격자) │
│ 게임 설정(펼쳐서 바로 수정 — 방장) │ 채팅(항상 보임) │
│ 규칙 요약 │ [게임 시작] / [준비하기] │
└──────────────────────────────┴────────────────────────────────┘
```
### 3.5 게임 화면 (PC)
```
┌ 상단 메뉴(얇게 48px: 게임명·코드·메뉴) ─────────────────────────────────────┐
│ │ 상태: 내 차례예요 ◔ 23초 │
│ │ 상대 정보 · 시계 │
│ 게임 판 (화면 높이에 맞춤) │ 내 정보 · 시계 │
│ │ [무르기][무승부][기권] │
│ │ 기보(수 목록) │
│ │ 채팅 + 반응 버튼 │
└──────────────────────────────────────────────┴──────────────────────────────┘
```
- 오른쪽 패널 폭 360px, 판은 남은 공간에서 가장 큰 정사각형.
- 카드 게임: 판 자리에 원형 테이블, 나는 항상 아래, 내 패는 판 아래쪽 넓게.
- PC 조작: 마우스를 올리면 미리 보기 돌(반투명), 클릭 한 번에 착수(기본값). "두 번 눌러 확정"은 터치 기기의 기본값이고 설정에서 바꿀 수 있다.
- 단축키: `Enter` 채팅 입력, `Esc` 창 닫기, 방향키+`Enter` 판 조작.
### 3.6 관리자 (PC)
왼쪽 사이드바(220px)에 메뉴, 오른쪽에 내용. 표는 PC에서 표 형태, 좁은 화면에서는 카드 목록.
## 4. 공통 컴포넌트
| 컴포넌트 | 동작 |
|---|---|
| `BigButton` | 56px, 종류 primary/secondary/danger, 로딩 표시, 두 번 눌림 방지 |
| `CodeDisplay` | `123 456` 큰 글씨 + 복사 |
| `CopyButton` | 복사 후 1.5초 "복사했어요 ✓", 실패하면 텍스트 선택 상태로 보여 줌 |
| `ShareButton` | `navigator.share` 있으면 공유 시트, 없으면 링크 복사 |
| `QrModal` | QR 크게 + 코드 |
| `CodeInput` | 6칸, 숫자 키패드, 붙여넣기 감지, 다 채우면 자동 제출 |
| `Seat` | 프로필, 이름, 방장/준비/연결 상태 |
| `TurnTimer` | 원형 링, 10초 남으면 주황 + 똑딱 소리(설정), 5초 남으면 빨강 + 진동 |
| `Toast` | 위에서 내려오는 짧은 알림(3초), 스크린리더 `aria-live` |
| `ConfirmSheet` | 아래에서 올라오는 확인창(큰 버튼 두 개) |
| `Card` | 트럼프/화투/게임 카드 공용 SVG, 크기 3단계 |
| `RulesSheet` | 게임 중 규칙 요약(그림), 현재 상황 도움말 |
| `ConnectionBanner` | "다시 연결하는 중…" 띠 |
## 5. 초보자 도움
- 처음 하는 게임이면(기기 기준) 시작할 때 "30초 규칙 요약" 카드 3장(그림 위주), [건너뛰기].
- 게임 중 [?] → 지금 상황에서 할 수 있는 것 설명("지금은 낼 카드를 고르는 차례예요. 밝게 보이는 카드만 낼 수 있어요").
- 족보·점수가 복잡한 게임(섯다, 포커, 고스톱, 마작)은 내 패 옆에 현재 족보 이름 표시("지금: 7끗", "투페어"), 족보표 버튼.
- 힌트 옵션(방 설정): 끄면 하이라이트만, 켜면 추천 수 표시(초보 방).
## 6. 소리·진동
- 짧은 효과음만(돌 놓기, 카드 넘기기, 내 차례 알림, 시간 경고, 승리). 합쳐서 100KB 이하, 처음 사용자 조작 후에만 재생(브라우저 정책).
- 내 차례가 되었는데 탭이 백그라운드면: 탭 제목 깜빡임("● 내 차례예요") + 소리(설정).
- 진동(`navigator.vibrate`): 내 차례, 시간 5초 남음.
## 7. 접근성
- 키보드만으로 모든 조작 가능(보드는 방향키로 칸 이동 + Enter). 포커스 테두리 항상 보이게.
- 스크린리더: 보드 칸에 `aria-label`("가로 8, 세로 8, 빈칸"), 상대의 수를 `aria-live`로 읽어 줌("상대가 H8에 두었어요").
- 명암비 기준 WCAG 2.2 AA 이상, 큰 글자 모드에서 화면이 깨지지 않는지 테스트.
- 시스템 글자 크기·확대 존중(`user-scalable` 막지 않음).
## 8. 성능 예산
| 항목 | 예산 |
|---|---|
| 첫 화면 JS | 150KB gzip 이하 (React + 라우터 + 홈) |
| 게임 화면 하나 | 추가 80KB gzip 이하(lazy) |
| 글꼴 | 서브셋 woff2 2개(500/700) 합 400KB 이하, `font-display: swap` |
| 이미지 | 게임 카드 썸네일은 SVG 또는 WebP 10KB 이하 |
| 외부 요청 | 0개(디스코드 아바타 제외) |
## 9. 문구 규칙
- 존댓말 해요체, 짧게. "~하시겠습니까?" 대신 "~할까요?".
- 어려운 말 금지: "테이블" → "방", "세션" → 쓰지 않음, "로비" → "홈".
- 오류 문구는 원인 + 할 일: "방을 찾을 수 없어요. 코드를 다시 확인해 주세요."
## 10. 화면 목록과 상태 (구현 체크용)
- 홈(로그인 전/후, 진행 중 게임 있음)
- 닉네임 입력(게스트 시작 / 링크 입장)
- 코드 입력
- 게임 상세 + 공개 방 목록
- 대기실(방장/참가자/관전자, 인원 부족/가득 참)
- 게임 화면(내 차례/남의 차례/연결 끊김/자리 비움/일시 정지)
- 결과 화면(승/패/무승부, 한 판 더 투표 중)
- 계정(게스트/디스코드)
- 오류(방 없음, 방 가득 참, 서버 업데이트, 오프라인)