# 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. 화면 목록과 상태 (구현 체크용) - 홈(로그인 전/후, 진행 중 게임 있음) - 닉네임 입력(게스트 시작 / 링크 입장) - 코드 입력 - 게임 상세 + 공개 방 목록 - 대기실(방장/참가자/관전자, 인원 부족/가득 참) - 게임 화면(내 차례/남의 차례/연결 끊김/자리 비움/일시 정지) - 결과 화면(승/패/무승부, 한 판 더 투표 중) - 계정(게스트/디스코드) - 오류(방 없음, 방 가득 참, 서버 업데이트, 오프라인)