/* quiz by quiz — 디자인 층: «clean cozy pastel mobile game»

   파일 이름은 로딩·테스트 계약 때문에 voxel-theme.css 로 남겼다. 안은 체계적인
   모바일 게임 디자인 층이다. 기준 문서는 docs/design-system.md 다.

   원칙
     · 크롬(버튼·카드·HUD·폼)은 절제한다. 중립 바탕 + 깊은 보라 브랜드 + 민트·코랄·골드 의미색.
     · 픽셀/복셀 정체성은 캐릭터·아이콘·세계 장식(마을·무대·대기실)에만 쓴다.
     · 간격은 4px 미세 / 8px 기본 격자 토큰(--space-*)만 쓴다.
     · 표면 높이는 세 단계(--elevation-1·2·3)뿐이다. 카드마다 굵은 하단 그림자를 주지 않는다.
     · 테두리는 기본 1px(--border-1)과 상태가 바뀌는 게임 조각의 2px(--border-2) 두 종류다.
     · 상태는 색만이 아니라 모양·표식·테두리·높이로 함께 구분한다.
     · 움직임은 100–180ms 의 짧은 피드백이고, 움직임 줄이기 설정을 따른다.

   구조·배치·동작 계약은 css/style.css 가 갖는다. 여기서는 그 위에 «어떻게 보이는가»만 정한다. */

@font-face {
  font-family: 'NeoDunggeunmo';
  src: url('fonts/neodgm.woff2') format('woff2');
  font-display: swap;
  font-style: normal;
  font-weight: 400;
}

/* ── 1. 토큰 ─────────────────────────────────────────────────── */
:root {
  /* 색: 역할 스케일 (Radix Colors 방식). 단계 번호가 같으면 쓰임새가 같다.
     1–2 바탕·옅은 채움 / 3–4 선·트랙 / 9 채움 / 10 눌림·초점 / 11 옅은 바탕 위 글자 / 12 진한 글자 */
  --mist-0: #ffffff;
  --mist-1: #f4f5fb;
  --mist-2: #eef0f7;
  --mist-3: #e3e6f0;
  --mist-4: #d6d9e6;
  --mist-6: #8a90aa;
  --mist-10: #585d7b;
  --mist-12: #1d1f3a;

  --violet-1: #f4f1ff;
  --violet-2: #ebe6ff;
  --violet-3: #d9cffd;
  --violet-9: #5b3fd6;
  --violet-10: #4b30bd;
  --violet-11: #4a2fb8;
  --violet-12: #2b1a75;

  --mint-2: #e2f5eb;
  --mint-9: #1d7d55;
  --mint-11: #16613f;

  --coral-2: #ffe9ec;
  --coral-9: #c93a54;
  --coral-11: #9e2339;

  --gold-2: #fff3d1;
  --gold-4: #ffdf8a;
  --gold-9: #f0b429;
  --gold-11: #7f4c00;

  /* 역할 이름. 컴포넌트는 이 이름만 쓴다 */
  --bg: var(--mist-1);
  --surface: var(--mist-0);
  --surface-subtle: var(--mist-2);
  --surface-sunken: var(--mist-3);
  --border: var(--mist-4);
  /* 입력칸 테두리는 흰 바탕에서 3:1 을 넘겨 칸 자체가 보이게 한다 (WCAG 1.4.11) */
  --border-strong: var(--mist-6);
  --text: var(--mist-12);
  --text-muted: var(--mist-10);
  --text-disabled: var(--mist-6);
  --code-bg: var(--mist-12);
  --code-text: var(--mist-2);

  --accent: var(--violet-9);
  --accent-hover: var(--violet-10);
  --accent-soft: var(--violet-2);
  --accent-subtle: var(--violet-1);
  --accent-line: var(--violet-3);
  --accent-ink: var(--violet-11);
  --accent-strong: var(--violet-12);
  --on-accent: var(--mist-0);
  --on-accent-muted: var(--violet-1);

  /* 상태 색은 WCAG AA(4.5:1)를 제 배경과 흰 배경 양쪽에서 넘긴다.
     기호와 글자가 뜻을 지고 색은 거들 뿐이지만(FR-4.1, FR-4.2) 거드는 것도 보여야 거든다. */
  --correct: var(--mint-9);
  --correct-soft: var(--mint-2);
  --correct-ink: var(--mint-11);
  --wrong: var(--coral-9);
  --wrong-hover: var(--coral-11);
  --wrong-soft: var(--coral-2);
  --wrong-ink: var(--coral-11);
  --warning: var(--gold-11);
  --warning-soft: var(--gold-2);
  --gold: var(--gold-9);
  --gold-soft: var(--gold-4);
  --primary-action: var(--gold-4);
  --primary-action-hover: var(--gold-9);
  --primary-action-line: var(--gold-2);

  --focus: var(--violet-10);
  --overlay: rgb(29 31 58 / 0.48);
  --glass: rgb(255 255 255 / 0.88);

  /* 카테고리 식별 색. 아이콘 칸 같은 작은 자리에만 쓴다 — 카드를 통째로 칠하지 않는다 */
  --cat-history: #a8461f;
  --cat-history-soft: #ffe8dc;
  --cat-science: #0f7461;
  --cat-science-soft: #dcf4ec;
  --cat-geography: #2b63a8;
  --cat-geography-soft: #e0edff;
  --cat-general: #7f5300;
  --cat-general-soft: #fff0c9;
  --cat-art: #a33673;
  --cat-art-soft: #fce4f1;

  /* 순위 메달 (글자는 --text) */
  --medal-gold: var(--gold-4);
  --medal-silver: #e6e8f0;
  --medal-bronze: #f6d2bd;

  /* 세계 장식. 마을·무대·대기실만 쓴다 */
  --world-sky-1: #eef6ff;
  --world-sky-2: #dbecfb;
  --world-sky-edge: #c9dff3;
  --world-path: #efe3c8;
  --world-stone: #fffcf4;
  --world-stone-edge: #e2d4b6;
  --world-wall: #f7f1e3;
  --world-baseboard: #a58f74;
  --world-floor: #e5d6b8;
  --world-wood-edge: #dccdb1;
  --world-grass: #a8df91;
  --world-soil-left: #bd8b68;
  --world-soil-right: #9d6d58;

  /* 간격: 4px 미세 / 8px 기본 격자 */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  /* 크기 */
  --tap: 44px;
  --tap-lg: 52px;
  --icon-sm: 16px;
  --icon-md: 20px;
  --icon-lg: 24px;
  --icon-tile: 40px;
  --content-max: 680px;
  --page-pad: var(--space-4);
  /* 모든 화면이 같은 이동 UI 크기를 쓴다. 아래 media query가 세 토큰을 함께 바꾼다. */
  --walk-stick-size: 96px;
  --walk-knob-size: 48px;
  --walk-confirm-size: 72px;
  --walker-width: 34px;
  --walker-height: 42px;
  --screen-walker-width: 40px;
  --screen-walker-height: 48px;
  --lounge-floor: 176px;

  /* 모서리 */
  --radius-xs: 4px;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-xl: 24px;
  --radius-full: 999px;

  /* 테두리: 기본 1px, 상태가 바뀌는 게임 조각 2px — 두 종류뿐이다 */
  --border-1: 1px;
  --border-2: 2px;

  /* 표면 높이: 세 단계뿐이다
       1  쉬는 카드·패널·버튼
       2  떠 있는 조각 (마우스를 올린 보기, 손가락 조작부, 말풍선)
       3  덮는 것 (대화상자, 피드백 시트) */
  --elevation-1: 0 1px 2px rgb(29 31 58 / 0.06), 0 2px 8px rgb(29 31 58 / 0.05);
  --elevation-2: 0 6px 16px rgb(29 31 58 / 0.12);
  --elevation-3: 0 16px 40px rgb(29 31 58 / 0.2);
  /* 채운 버튼의 두께. 높이 단계가 아니라 «누를 수 있다»는 표식이고, 누르면 사라진다 */
  --press-edge: inset 0 -3px 0 rgb(29 31 58 / 0.2);
  /* 목록 줄 안의 «내 것» 표지: 왼쪽 4px 보라 띠. 높이가 아니라 표식이다 */
  --marker-mine: inset var(--space-1) 0 0 var(--accent);

  /* 글꼴: 본문은 읽기 좋은 한글 시스템 글꼴, 픽셀 글꼴은 브랜드·숫자·짧은 게임 표식에만 */
  --font-text: -apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo', 'Pretendard', 'Noto Sans KR',
    'Malgun Gothic', system-ui, sans-serif;
  --font-display: 'NeoDunggeunmo', -apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo',
    'Malgun Gothic', system-ui, sans-serif;
  --text-xs: 12px;
  --text-sm: 14px;
  --text-md: 16px;
  --text-lg: 18px;
  --text-xl: 20px;
  --text-2xl: 24px;
  --text-3xl: 32px;
  --text-4xl: 48px;
  --text-5xl: 64px;
  --leading-tight: 1.25;
  --leading-snug: 1.4;
  --leading-normal: 1.6;
  --weight-bold: 700;
  --weight-heavy: 800;

  /* 움직임: 100–180ms 의 짧은 피드백 */
  --duration-fast: 120ms;
  --duration-base: 160ms;
  --duration-slow: 180ms;
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);

  /* 초점 고리. 캐릭터가 올라선 버튼도 같은 모양을 쓴다 — 「지금 이걸 누르면 된다」는 뜻이 같다 */
  --focus-width: 3px;
  --focus-offset: 2px;

  /* 월드 우선 화면: 캐릭터와 같은 큰 픽셀 격자의 2D 배경 위에 올라가는 제한된 HUD 표면 */
  --world-art-mobile: url('assets/world-academy-pixel-mobile.webp');
  --world-art-desktop: url('assets/world-academy-pixel-desktop.webp');
  --world-clear: rgb(29 31 58 / 0.04);
  --world-veil: rgb(29 31 58 / 0.2);
  --world-veil-strong: rgb(29 31 58 / 0.3);
  --hud-bg: rgb(29 31 58 / 0.88);
  --hud-bg-soft: rgb(29 31 58 / 0.76);
  --hud-line: rgb(255 255 255 / 0.34);
  --hud-text: var(--mist-0);
  --hud-text-muted: #e6e8f8;
  --world-glass: rgb(255 255 255 / 0.9);
  --world-glass-soft: rgb(255 255 255 / 0.8);
  --world-floor-glass: rgb(255 255 255 / 0.22);
  --world-floor-line: rgb(255 255 255 / 0.78);
  --world-title-shadow:
    -1px -1px 0 rgb(29 31 58 / 0.82),
    1px -1px 0 rgb(29 31 58 / 0.82),
    -1px 1px 0 rgb(29 31 58 / 0.82),
    1px 1px 0 rgb(29 31 58 / 0.82),
    0 3px 10px rgb(29 31 58 / 0.46);
}

/* viewport별 크기도 화면 이름이 아니라 공용 토큰 한 벌로 정한다. */
@media (pointer: coarse) and (max-height: 700px) {
  :root {
    --walk-stick-size: 80px;
    --walk-knob-size: 40px;
    --walk-confirm-size: 64px;
  }
}

@media (pointer: coarse) and (max-height: 420px) {
  :root {
    --walk-stick-size: 64px;
    --walk-knob-size: 40px;
    --walk-confirm-size: 56px;
  }
}

@media (pointer: coarse) and (max-height: 360px) {
  :root {
    --walk-stick-size: 44px;
    --walk-knob-size: 24px;
    --walk-confirm-size: 44px;
  }
}

/* 좁은 화면은 바깥 여백만 한 단계 줄인다 */
@media (max-width: 420px) {
  :root {
    --page-pad: var(--space-3);
  }
}

/* ── 2. 아이콘 ────────────────────────────────────────────────────
   24×24 격자 위의 12×12 픽셀(한 점 = 2 단위)로 그린 자체 아이콘이다. 외부 에셋을 쓰지 않는다.
   번들 픽셀 글꼴에 없는 글리프(✓ ✗ ⏱ ⚠ ♛ ← ↻ ⚙)를 쓰지 않으려고 만들었다.
   mask 로 그리므로 색은 언제나 currentColor 다. 이름은 data-icon 으로 고른다. */
:root {
  --i-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18 4h4v2h-4zM16 6h6v2h-6zM14 8h6v2h-6zM2 10h4v2h-4zM12 10h6v2h-6zM2 12h6v2h-6zM10 12h6v2h-6zM4 14h10v2h-10zM6 16h6v2h-6zM8 18h2v2h-2z'/%3E%3C/svg%3E");
  --i-cross: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 4h4v2h-4zM16 4h4v2h-4zM4 6h6v2h-6zM14 6h6v2h-6zM6 8h12v2h-12zM8 10h8v2h-8zM8 12h8v2h-8zM6 14h12v2h-12zM4 16h6v2h-6zM14 16h6v2h-6zM4 18h4v2h-4zM16 18h4v2h-4z'/%3E%3C/svg%3E");
  --i-clock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 0h8v2h-8zM4 2h4v2h-4zM16 2h4v2h-4zM2 4h2v2h-2zM20 4h2v2h-2zM2 6h2v2h-2zM10 6h2v2h-2zM20 6h2v2h-2zM0 8h2v2h-2zM10 8h2v2h-2zM22 8h2v2h-2zM0 10h2v2h-2zM10 10h2v2h-2zM22 10h2v2h-2zM0 12h2v2h-2zM10 12h8v2h-8zM22 12h2v2h-2zM0 14h2v2h-2zM22 14h2v2h-2zM2 16h2v2h-2zM20 16h2v2h-2zM2 18h2v2h-2zM20 18h2v2h-2zM4 20h4v2h-4zM16 20h4v2h-4zM8 22h8v2h-8z'/%3E%3C/svg%3E");
  --i-alert: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 0h4v2h-4zM8 2h8v2h-8zM8 4h8v2h-8zM6 6h4v2h-4zM14 6h4v2h-4zM6 8h4v2h-4zM14 8h4v2h-4zM4 10h6v2h-6zM14 10h6v2h-6zM4 12h6v2h-6zM14 12h6v2h-6zM2 14h20v2h-20zM2 16h8v2h-8zM14 16h8v2h-8zM0 18h24v2h-24zM0 20h24v2h-24z'/%3E%3C/svg%3E");
  --i-question: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 2h12v2h-12zM4 4h4v2h-4zM16 4h4v2h-4zM4 6h4v2h-4zM16 6h4v2h-4zM16 8h4v2h-4zM14 10h4v2h-4zM10 12h6v2h-6zM10 14h4v2h-4zM10 18h4v2h-4zM10 20h4v2h-4z'/%3E%3C/svg%3E");
  --i-play: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 2h4v2h-4zM6 4h8v2h-8zM6 6h12v2h-12zM6 8h14v2h-14zM6 10h16v2h-16zM6 12h16v2h-16zM6 14h14v2h-14zM6 16h12v2h-12zM6 18h8v2h-8zM6 20h4v2h-4z'/%3E%3C/svg%3E");
  --i-arrow-left: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 4h4v2h-4zM6 6h4v2h-4zM4 8h4v2h-4zM2 10h20v2h-20zM2 12h20v2h-20zM4 14h4v2h-4zM6 16h4v2h-4zM8 18h4v2h-4z'/%3E%3C/svg%3E");
  --i-refresh: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 2h10v2h-10zM18 2h4v2h-4zM4 4h4v2h-4zM16 4h6v2h-6zM2 6h4v2h-4zM14 6h8v2h-8zM2 8h2v2h-2zM2 10h2v2h-2zM2 12h2v2h-2zM20 12h2v2h-2zM2 14h2v2h-2zM20 14h2v2h-2zM2 16h4v2h-4zM18 16h4v2h-4zM4 18h4v2h-4zM16 18h4v2h-4zM6 20h12v2h-12z'/%3E%3C/svg%3E");
  --i-filter: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 2h4v2h-4zM0 4h24v2h-24zM6 6h4v2h-4zM14 10h4v2h-4zM0 12h24v2h-24zM14 14h4v2h-4zM4 18h4v2h-4zM0 20h24v2h-24zM4 22h4v2h-4z'/%3E%3C/svg%3E");
  --i-sound-on: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 2h2v2h-2zM8 4h4v2h-4zM18 4h2v2h-2zM6 6h6v2h-6zM20 6h2v2h-2zM0 8h12v2h-12zM14 8h2v2h-2zM20 8h2v2h-2zM0 10h12v2h-12zM16 10h2v2h-2zM22 10h2v2h-2zM0 12h12v2h-12zM16 12h2v2h-2zM22 12h2v2h-2zM0 14h12v2h-12zM14 14h2v2h-2zM20 14h2v2h-2zM6 16h6v2h-6zM20 16h2v2h-2zM8 18h4v2h-4zM18 18h2v2h-2zM10 20h2v2h-2z'/%3E%3C/svg%3E");
  --i-sound-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 2h2v2h-2zM8 4h4v2h-4zM6 6h6v2h-6zM14 6h2v2h-2zM22 6h2v2h-2zM0 8h12v2h-12zM16 8h2v2h-2zM20 8h2v2h-2zM0 10h12v2h-12zM18 10h2v2h-2zM0 12h12v2h-12zM18 12h2v2h-2zM0 14h12v2h-12zM16 14h2v2h-2zM20 14h2v2h-2zM6 16h6v2h-6zM14 16h2v2h-2zM22 16h2v2h-2zM8 18h4v2h-4zM10 20h2v2h-2z'/%3E%3C/svg%3E");
  --i-palette: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 0h8v2h-8zM4 2h16v2h-16zM2 4h4v2h-4zM10 4h4v2h-4zM18 4h4v2h-4zM0 6h6v2h-6zM10 6h4v2h-4zM18 6h6v2h-6zM0 8h24v2h-24zM0 10h4v2h-4zM8 10h16v2h-16zM0 12h4v2h-4zM8 12h8v2h-8zM0 14h16v2h-16zM0 16h18v2h-18zM2 18h18v2h-18zM4 20h14v2h-14z'/%3E%3C/svg%3E");
  --i-trophy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 2h16v2h-16zM0 4h4v2h-4zM6 4h12v2h-12zM20 4h4v2h-4zM0 6h2v2h-2zM6 6h12v2h-12zM22 6h2v2h-2zM0 8h4v2h-4zM6 8h12v2h-12zM20 8h4v2h-4zM6 10h12v2h-12zM8 12h8v2h-8zM10 14h4v2h-4zM10 16h4v2h-4zM8 18h8v2h-8zM6 20h12v2h-12z'/%3E%3C/svg%3E");
  --i-users: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 2h4v2h-4zM16 2h4v2h-4zM4 4h8v2h-8zM14 4h8v2h-8zM4 6h8v2h-8zM14 6h8v2h-8zM6 8h4v2h-4zM16 8h4v2h-4zM2 12h12v2h-12zM16 12h6v2h-6zM0 14h16v2h-16zM18 14h6v2h-6zM0 16h16v2h-16zM18 16h6v2h-6zM0 18h16v2h-16zM18 18h6v2h-6z'/%3E%3C/svg%3E");
  --i-book: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M2 4h8v2h-8zM14 4h8v2h-8zM0 6h2v2h-2zM10 6h4v2h-4zM22 6h2v2h-2zM0 8h2v2h-2zM4 8h4v2h-4zM10 8h4v2h-4zM16 8h4v2h-4zM22 8h2v2h-2zM0 10h2v2h-2zM10 10h4v2h-4zM22 10h2v2h-2zM0 12h2v2h-2zM4 12h4v2h-4zM10 12h4v2h-4zM16 12h4v2h-4zM22 12h2v2h-2zM0 14h2v2h-2zM10 14h4v2h-4zM22 14h2v2h-2zM0 16h2v2h-2zM4 16h4v2h-4zM10 16h4v2h-4zM16 16h4v2h-4zM22 16h2v2h-2zM0 18h2v2h-2zM10 18h4v2h-4zM22 18h2v2h-2zM2 20h8v2h-8zM14 20h8v2h-8z'/%3E%3C/svg%3E");
  --i-flask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 2h12v2h-12zM8 4h2v2h-2zM14 4h2v2h-2zM8 6h2v2h-2zM14 6h2v2h-2zM8 8h2v2h-2zM14 8h2v2h-2zM6 10h2v2h-2zM16 10h2v2h-2zM4 12h2v2h-2zM18 12h2v2h-2zM4 14h16v2h-16zM2 16h20v2h-20zM2 18h20v2h-20zM4 20h16v2h-16z'/%3E%3C/svg%3E");
  --i-globe: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 0h8v2h-8zM4 2h4v2h-4zM16 2h4v2h-4zM2 4h2v2h-2zM10 4h4v2h-4zM20 4h2v2h-2zM2 6h2v2h-2zM8 6h2v2h-2zM14 6h2v2h-2zM20 6h2v2h-2zM0 8h2v2h-2zM8 8h2v2h-2zM14 8h2v2h-2zM22 8h2v2h-2zM0 10h24v2h-24zM0 12h2v2h-2zM8 12h2v2h-2zM14 12h2v2h-2zM22 12h2v2h-2zM0 14h2v2h-2zM8 14h2v2h-2zM14 14h2v2h-2zM22 14h2v2h-2zM2 16h2v2h-2zM8 16h2v2h-2zM14 16h2v2h-2zM20 16h2v2h-2zM2 18h2v2h-2zM10 18h4v2h-4zM20 18h2v2h-2zM4 20h4v2h-4zM16 20h4v2h-4zM8 22h8v2h-8z'/%3E%3C/svg%3E");
  --i-bulb: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 0h8v2h-8zM4 2h16v2h-16zM2 4h4v2h-4zM8 4h14v2h-14zM2 6h2v2h-2zM6 6h16v2h-16zM2 8h20v2h-20zM2 10h20v2h-20zM4 12h16v2h-16zM6 14h12v2h-12zM6 18h12v2h-12zM8 20h8v2h-8z'/%3E%3C/svg%3E");
  --i-music: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 2h12v2h-12zM10 4h12v2h-12zM10 6h2v2h-2zM20 6h2v2h-2zM10 8h2v2h-2zM20 8h2v2h-2zM10 10h2v2h-2zM20 10h2v2h-2zM10 12h2v2h-2zM20 12h2v2h-2zM4 14h8v2h-8zM16 14h6v2h-6zM2 16h10v2h-10zM14 16h8v2h-8zM2 18h10v2h-10zM14 18h8v2h-8zM4 20h6v2h-6zM16 20h4v2h-4z'/%3E%3C/svg%3E");
  --i-grid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M2 2h8v2h-8zM14 2h8v2h-8zM2 4h8v2h-8zM14 4h8v2h-8zM2 6h8v2h-8zM14 6h8v2h-8zM2 8h8v2h-8zM14 8h8v2h-8zM2 14h8v2h-8zM14 14h8v2h-8zM2 16h8v2h-8zM14 16h8v2h-8zM2 18h8v2h-8zM14 18h8v2h-8zM2 20h8v2h-8zM14 20h8v2h-8z'/%3E%3C/svg%3E");
  --i-crown: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M0 4h2v2h-2zM10 4h4v2h-4zM22 4h2v2h-2zM0 6h4v2h-4zM8 6h8v2h-8zM20 6h4v2h-4zM0 8h6v2h-6zM8 8h8v2h-8zM18 8h6v2h-6zM0 10h24v2h-24zM0 12h24v2h-24zM0 14h24v2h-24zM0 16h24v2h-24zM0 20h24v2h-24z'/%3E%3C/svg%3E");
  --i-lock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 2h8v2h-8zM6 4h2v2h-2zM16 4h2v2h-2zM6 6h2v2h-2zM16 6h2v2h-2zM6 8h2v2h-2zM16 8h2v2h-2zM4 10h16v2h-16zM4 12h16v2h-16zM4 14h8v2h-8zM14 14h6v2h-6zM4 16h8v2h-8zM14 16h6v2h-6zM4 18h16v2h-16zM4 20h16v2h-16z'/%3E%3C/svg%3E");
  --i-key: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M2 2h8v2h-8zM0 4h2v2h-2zM10 4h2v2h-2zM0 6h2v2h-2zM4 6h4v2h-4zM10 6h2v2h-2zM0 8h2v2h-2zM4 8h4v2h-4zM10 8h14v2h-14zM0 10h2v2h-2zM10 10h2v2h-2zM16 10h2v2h-2zM20 10h2v2h-2zM2 12h8v2h-8zM16 12h2v2h-2zM20 12h2v2h-2z'/%3E%3C/svg%3E");
  --i-plus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 4h4v2h-4zM10 6h4v2h-4zM10 8h4v2h-4zM4 10h16v2h-16zM4 12h16v2h-16zM10 14h4v2h-4zM10 16h4v2h-4zM10 18h4v2h-4z'/%3E%3C/svg%3E");
  --i-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 2h8v2h-8zM2 4h2v2h-2zM12 4h2v2h-2zM0 6h2v2h-2zM14 6h2v2h-2zM0 8h2v2h-2zM14 8h2v2h-2zM0 10h2v2h-2zM14 10h2v2h-2zM2 12h2v2h-2zM12 12h4v2h-4zM4 14h10v2h-10zM16 14h2v2h-2zM14 16h6v2h-6zM16 18h6v2h-6zM18 20h4v2h-4z'/%3E%3C/svg%3E");
  --i-user: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 2h8v2h-8zM6 4h12v2h-12zM6 6h12v2h-12zM6 8h12v2h-12zM8 10h8v2h-8zM4 14h16v2h-16zM2 16h20v2h-20zM2 18h20v2h-20zM2 20h20v2h-20z'/%3E%3C/svg%3E");
  --i-pencil: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18 2h4v2h-4zM16 4h8v2h-8zM14 6h8v2h-8zM12 8h2v2h-2zM16 8h4v2h-4zM10 10h2v2h-2zM14 10h2v2h-2zM8 12h2v2h-2zM12 12h2v2h-2zM6 14h2v2h-2zM10 14h2v2h-2zM4 16h2v2h-2zM8 16h2v2h-2zM4 18h4v2h-4zM2 20h6v2h-6z'/%3E%3C/svg%3E");
  --i-star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 0h4v2h-4zM10 2h4v2h-4zM8 4h8v2h-8zM0 6h24v2h-24zM2 8h20v2h-20zM4 10h16v2h-16zM6 12h12v2h-12zM4 14h16v2h-16zM4 16h6v2h-6zM14 16h6v2h-6zM2 18h4v2h-4zM18 18h4v2h-4zM2 20h2v2h-2zM20 20h2v2h-2z'/%3E%3C/svg%3E");
  --i-target: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 0h8v2h-8zM4 2h4v2h-4zM16 2h4v2h-4zM2 4h2v2h-2zM20 4h2v2h-2zM2 6h2v2h-2zM8 6h8v2h-8zM20 6h2v2h-2zM0 8h2v2h-2zM6 8h2v2h-2zM16 8h2v2h-2zM22 8h2v2h-2zM0 10h2v2h-2zM6 10h2v2h-2zM10 10h4v2h-4zM16 10h2v2h-2zM22 10h2v2h-2zM0 12h2v2h-2zM6 12h2v2h-2zM10 12h4v2h-4zM16 12h2v2h-2zM22 12h2v2h-2zM0 14h2v2h-2zM6 14h2v2h-2zM16 14h2v2h-2zM22 14h2v2h-2zM2 16h2v2h-2zM8 16h8v2h-8zM20 16h2v2h-2zM2 18h2v2h-2zM20 18h2v2h-2zM4 20h4v2h-4zM16 20h4v2h-4zM8 22h8v2h-8z'/%3E%3C/svg%3E");
  --i-hourglass: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M2 2h20v2h-20zM4 4h2v2h-2zM18 4h2v2h-2zM4 6h2v2h-2zM18 6h2v2h-2zM6 8h2v2h-2zM10 8h4v2h-4zM16 8h2v2h-2zM8 10h8v2h-8zM8 12h2v2h-2zM14 12h2v2h-2zM6 14h2v2h-2zM16 14h2v2h-2zM4 16h2v2h-2zM10 16h4v2h-4zM18 16h2v2h-2zM4 18h2v2h-2zM8 18h8v2h-8zM18 18h2v2h-2zM2 20h20v2h-20z'/%3E%3C/svg%3E");
  --i-info: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M8 0h8v2h-8zM4 2h16v2h-16zM2 4h8v2h-8zM14 4h8v2h-8zM2 6h20v2h-20zM0 8h10v2h-10zM14 8h10v2h-10zM0 10h10v2h-10zM14 10h10v2h-10zM0 12h10v2h-10zM14 12h10v2h-10zM0 14h10v2h-10zM14 14h10v2h-10zM2 16h8v2h-8zM14 16h8v2h-8zM2 18h20v2h-20zM4 20h16v2h-16zM8 22h8v2h-8z'/%3E%3C/svg%3E");
  --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23585d7b' d='M4 6h4v2h-4zM16 6h4v2h-4zM4 8h6v2h-6zM14 8h6v2h-6zM6 10h12v2h-12zM8 12h8v2h-8zM10 14h4v2h-4z'/%3E%3C/svg%3E");
  --i-check-inverse: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M18 4h4v2h-4zM16 6h6v2h-6zM14 8h6v2h-6zM2 10h4v2h-4zM12 10h6v2h-6zM2 12h6v2h-6zM10 12h6v2h-6zM4 14h10v2h-10zM6 16h6v2h-6zM8 18h2v2h-2z'/%3E%3C/svg%3E");
  --i-cross-inverse: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M4 4h4v2h-4zM16 4h4v2h-4zM4 6h6v2h-6zM14 6h6v2h-6zM6 8h12v2h-12zM8 10h8v2h-8zM8 12h8v2h-8zM6 14h12v2h-12zM4 16h6v2h-6zM14 16h6v2h-6zM4 18h4v2h-4zM16 18h4v2h-4z'/%3E%3C/svg%3E");
}

.icon {
  display: inline-block;
  flex: none;
  width: var(--icon-md);
  height: var(--icon-md);
  background-color: currentColor;
  -webkit-mask: var(--icon, var(--i-question)) center / contain no-repeat;
  mask: var(--icon, var(--i-question)) center / contain no-repeat;
}

[data-icon='check'] { --icon: var(--i-check); }
[data-icon='cross'] { --icon: var(--i-cross); }
[data-icon='clock'] { --icon: var(--i-clock); }
[data-icon='alert'] { --icon: var(--i-alert); }
[data-icon='question'] { --icon: var(--i-question); }
[data-icon='play'] { --icon: var(--i-play); }
[data-icon='arrow-left'] { --icon: var(--i-arrow-left); }
[data-icon='refresh'] { --icon: var(--i-refresh); }
[data-icon='filter'] { --icon: var(--i-filter); }
[data-icon='sound-on'] { --icon: var(--i-sound-on); }
[data-icon='sound-off'] { --icon: var(--i-sound-off); }
[data-icon='palette'] { --icon: var(--i-palette); }
[data-icon='trophy'] { --icon: var(--i-trophy); }
[data-icon='users'] { --icon: var(--i-users); }
[data-icon='book'] { --icon: var(--i-book); }
[data-icon='flask'] { --icon: var(--i-flask); }
[data-icon='globe'] { --icon: var(--i-globe); }
[data-icon='bulb'] { --icon: var(--i-bulb); }
[data-icon='music'] { --icon: var(--i-music); }
[data-icon='grid'] { --icon: var(--i-grid); }
[data-icon='crown'] { --icon: var(--i-crown); }
[data-icon='lock'] { --icon: var(--i-lock); }
[data-icon='key'] { --icon: var(--i-key); }
[data-icon='plus'] { --icon: var(--i-plus); }
[data-icon='search'] { --icon: var(--i-search); }
[data-icon='user'] { --icon: var(--i-user); }
[data-icon='pencil'] { --icon: var(--i-pencil); }
[data-icon='star'] { --icon: var(--i-star); }
[data-icon='target'] { --icon: var(--i-target); }
[data-icon='hourglass'] { --icon: var(--i-hourglass); }
[data-icon='info'] { --icon: var(--i-info); }

/* 아이콘 칸: 옅은 바탕 위에 아이콘 하나. 칸 요소에 data-icon 을 달면 ::before 가 그린다 */
.menu-card__figure::before,
.category-card__icon::before,
.challenge-card__icon::before,
.online-action-card__icon::before,
.online-panel-heading__icon::before,
.room-item__icon::before,
.room-empty__icon::before,
.result-stats__item::before {
  content: '';
  width: var(--icon-lg);
  height: var(--icon-lg);
  background-color: currentColor;
  -webkit-mask: var(--icon, var(--i-question)) center / contain no-repeat;
  mask: var(--icon, var(--i-question)) center / contain no-repeat;
}

/* ── 3. 바탕·글자 ──────────────────────────────────────────────── */
body {
  background-color: var(--bg);
  /* 위쪽만 하늘빛으로 아주 옅게 물들인다. 격자 무늬는 두지 않는다 */
  background-image: linear-gradient(180deg, var(--world-sky-1) 0, var(--bg) 360px);
  background-repeat: no-repeat;
  color: var(--text);
  font-family: var(--font-text);
  font-size: var(--text-md);
  line-height: var(--leading-normal);
}

h1,
h2,
h3 {
  line-height: var(--leading-tight);
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

/* 키보드로 이동할 때만 고리를 보여준다. 마우스 클릭에는 뜨지 않는다.
   모서리는 요소의 border-radius 를 따른다 — 고리 때문에 모양을 바꾸지 않는다 */
:focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
}

.boot__loading,
.boot__body {
  color: var(--text-muted);
  font-size: var(--text-sm);
}

.boot__error {
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--elevation-1);
}

.boot__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-heavy);
}

.boot__code {
  border-radius: var(--radius-sm);
  background: var(--code-bg);
  color: var(--code-text);
  font-size: var(--text-sm);
}

.boot code {
  border-radius: var(--radius-xs);
  background: var(--surface-subtle);
  font-size: var(--text-sm);
}

/* ── 4. 표면 ───────────────────────────────────────────────────
   기본 패널: 흰 바탕 · 1px 선 · 큰 모서리 · 높이 1. 한 화면에 같은 무게의 카드를 늘어놓지
   않으려고, 목록은 패널 하나 안에 줄로 넣고 줄 사이는 1px 선으로만 나눈다. */
.quiz-hud,
.question,
.home-player .menu-card--wide,
.home-menu,
.home-quests,
.result-block,
.result-stats__item,
.ranking-list,
.ranking-tabs,
.online-actions,
.online-block,
.online-final-ranking,
.online-reveal,
.setting-card,
.character-card {
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--elevation-1);
}

.home-quests,
.online-block,
.result-header {
  border-radius: var(--radius-xl);
}

/* ── 5. 버튼 ───────────────────────────────────────────────────
   주 행동(채움) · 보조(흰 바탕 선) · 위험(코랄 채움) 세 가지.
   쉬는 / 올림(hover) / 눌림 / 꺼짐 상태가 색뿐 아니라 높이와 두께로도 달라진다. */
.button {
  border: var(--border-1) solid transparent;
  border-radius: var(--radius-md);
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out),
    box-shadow var(--duration-fast) var(--ease-out),
    translate var(--duration-fast) var(--ease-out);
}

.button--small {
  font-size: var(--text-sm);
}

.button--primary {
  background: var(--accent);
  box-shadow: var(--elevation-1), var(--press-edge);
  color: var(--on-accent);
}

.button--ghost {
  border-color: var(--border);
  background: var(--surface);
  color: var(--text);
}

.button--danger {
  background: var(--wrong);
  box-shadow: var(--elevation-1), var(--press-edge);
  color: var(--on-accent);
}

@media (hover: hover) {
  .button--primary:hover:not(:disabled) {
    background: var(--accent-hover);
  }

  .button--ghost:hover:not(:disabled) {
    border-color: var(--accent-line);
    background: var(--accent-subtle);
    color: var(--accent-ink);
  }

  .button--danger:hover:not(:disabled) {
    background: var(--wrong-hover);
  }
}

/* 눌림: 두께가 사라지고 한 칸 내려앉는다 */
.button:active:not(:disabled) {
  translate: 0 2px;
  box-shadow: none;
}

.button--primary:active:not(:disabled) {
  background: var(--accent-hover);
}

/* 꺼짐: 채움을 거두고 흐린 글자로. 모양은 그대로라 무엇이 꺼졌는지는 보인다 */
.button:disabled {
  border-color: var(--border);
  background: var(--surface-subtle);
  box-shadow: none;
  color: var(--text-disabled);
}

/* 위험한 행동을 보조 버튼 자리에서 부를 때 (랭킹 초기화) */
.ranking-footer .button--ghost {
  color: var(--wrong-ink);
}

@media (hover: hover) {
  .ranking-footer .button--ghost:hover:not(:disabled) {
    border-color: var(--wrong);
    background: var(--wrong-soft);
    color: var(--wrong-ink);
  }
}

/* ── 6. 상단 바 · 소리 ───────────────────────────────────────── */
.icon-button {
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-full);
  background: var(--surface);
  box-shadow: var(--elevation-1);
  color: var(--accent-ink);
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    translate var(--duration-fast) var(--ease-out);
}

.icon-button__icon {
  width: var(--icon-lg);
  height: var(--icon-lg);
}

/* 꺼진 소리는 아이콘 모양(× 표)과 흐린 색으로 함께 알린다. 상태 자체는 aria-pressed 가 낭독한다 */
.icon-button[aria-pressed='false'] {
  background: var(--surface-subtle);
  color: var(--text-muted);
}

@media (hover: hover) {
  .icon-button:hover {
    border-color: var(--accent-line);
    background: var(--accent-subtle);
  }
}

.icon-button:active {
  translate: 0 1px;
}

/* ── 7. 홈 ─────────────────────────────────────────────────────── */

/* 플레이어 줄: 맨 위의 내 이름. 왼쪽 아바타 칸 · 이름 · 연필 표식 */
.menu-card {
  border: var(--border-1) solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text);
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    translate var(--duration-fast) var(--ease-out);
}

.menu-card__figure {
  color: var(--accent-ink);
}

.menu-card__figure::before {
  width: var(--icon-lg);
  height: var(--icon-lg);
}

.menu-card--wide .menu-card__figure {
  border-radius: var(--radius-md);
  background: var(--accent-soft);
}

.menu-card__name {
  font-size: var(--text-md);
  font-weight: var(--weight-heavy);
  line-height: var(--leading-tight);
}

.menu-card--wide .menu-card__name {
  font-size: var(--text-lg);
}

.menu-card__label {
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  line-height: 1;
}

.menu-card__desc {
  color: var(--text-muted);
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
}

.menu-card__edit {
  color: var(--text-muted);
  background-color: currentColor;
  -webkit-mask: var(--i-pencil) center / contain no-repeat;
  mask: var(--i-pencil) center / contain no-repeat;
}

/* dock 안의 칸은 따로 놀지 않는다 — 바탕 없이 아이콘과 이름만, 올리면 옅게 채운다 */
.home-menu .menu-card__name {
  font-size: var(--text-sm);
}

@media (hover: hover) {
  .menu-card:hover:not(:disabled) {
    background: var(--surface-subtle);
  }

  .home-player .menu-card--wide:hover:not(:disabled),
  .home-menu .menu-card:hover:not(:disabled) {
    border-color: var(--accent-line);
    background: var(--hud-bg);
  }
}

.menu-card:active:not(:disabled) {
  translate: 0 1px;
}

.menu-card:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

/* 마을 패널: 하늘 바탕에 브랜드와 복셀 마을. 테두리 장식·창문 점은 두지 않는다 */
.home-header {
  border: var(--border-1) solid var(--world-sky-edge);
  border-radius: var(--radius-xl);
  background: linear-gradient(170deg, var(--world-sky-1) 0%, var(--world-sky-2) 100%);
  box-shadow: var(--elevation-1);
}

.home-title {
  color: var(--accent-strong);
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0;
}

.home-title span {
  display: inline-block;
  padding: var(--space-1) var(--space-1);
  border-radius: var(--radius-xs);
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--text-md);
  line-height: 1;
  vertical-align: 0.4em;
}

.home-subtitle {
  max-width: 200px;
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
}

/* 분야 고르기 패널 안의 칸은 카드가 아니라 «칸»이다. 선 없이 옅은 바탕만 깐다.
   분야 색은 아이콘 칸에만 쓴다 — 칸 전체는 모두 같은 중립 바탕이다.
   분야 색 묶음(--cat-ink·--cat-soft)은 로비의 방 줄도 함께 쓴다. 없는 분야는 브랜드 보라다 */
.category-card {
  --cat-ink: var(--accent-ink);
  --cat-soft: var(--accent-soft);
  border: var(--border-2) solid transparent;
  border-radius: var(--radius-lg);
  background: var(--surface-subtle);
  color: var(--text);
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    translate var(--duration-fast) var(--ease-out);
}

.category-card[data-category='history'],
.room-item[data-category='history'] {
  --cat-ink: var(--cat-history);
  --cat-soft: var(--cat-history-soft);
}

.category-card[data-category='science'],
.room-item[data-category='science'] {
  --cat-ink: var(--cat-science);
  --cat-soft: var(--cat-science-soft);
}

.category-card[data-category='geography'],
.room-item[data-category='geography'] {
  --cat-ink: var(--cat-geography);
  --cat-soft: var(--cat-geography-soft);
}

.category-card[data-category='general'],
.room-item[data-category='general'] {
  --cat-ink: var(--cat-general);
  --cat-soft: var(--cat-general-soft);
}

.category-card[data-category='art'],
.room-item[data-category='art'] {
  --cat-ink: var(--cat-art);
  --cat-soft: var(--cat-art-soft);
}

.category-card__icon {
  border-radius: var(--radius-md);
  background: var(--cat-soft);
  color: var(--cat-ink);
}

.category-card__name {
  font-size: var(--text-md);
  font-weight: var(--weight-heavy);
  line-height: var(--leading-snug);
}

.category-card__desc {
  color: var(--text-muted);
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
}

.category-card__best {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  background: var(--surface);
  color: var(--accent-ink);
  font-size: var(--text-xs);
  font-weight: var(--weight-heavy);
  line-height: var(--leading-snug);
}

@media (hover: hover) {
  .category-card:hover:not(:disabled) {
    border-color: var(--accent-line);
    background: var(--surface);
  }
}

.category-card:active:not(:disabled) {
  translate: 0 2px;
}

.category-card:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

/* 온라인과 전체 도전: 같은 크기와 눌림 깊이를 가진 주요 게임 진입점 */
.challenge-card {
  border: var(--border-1) solid transparent;
  border-radius: var(--radius-lg);
  background: var(--accent);
  box-shadow: var(--elevation-1), var(--press-edge);
  color: var(--on-accent);
  transition:
    background-color var(--duration-fast) var(--ease-out),
    box-shadow var(--duration-fast) var(--ease-out),
    translate var(--duration-fast) var(--ease-out);
}

.challenge-card__icon {
  border-radius: var(--radius-full);
  background: var(--on-accent);
  color: var(--accent);
}

.challenge-card__name {
  font-size: var(--text-lg);
  font-weight: var(--weight-heavy);
  line-height: var(--leading-tight);
  white-space: nowrap;
}

.challenge-card__desc {
  color: var(--on-accent-muted);
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
}

.challenge-card__meta {
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  background: var(--accent-hover);
  color: var(--on-accent);
  font-size: var(--text-xs);
  font-weight: var(--weight-heavy);
  line-height: 24px;
}

@media (hover: hover) {
  .challenge-card:hover:not(:disabled) {
    background: var(--accent-hover);
  }
}

.challenge-card:active:not(:disabled) {
  translate: 0 2px;
  box-shadow: none;
}

.challenge-card:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

.home-hint,
.arena__hint {
  color: var(--text-muted);
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
}

/* ── 8. 알림 줄 (오류·안내) ─────────────────────────────────────
   앞의 아이콘 칸은 글 첫 줄과 같은 높이(1lh)라 몇 줄이 되어도 첫 줄 가운데에 선다 */
.home-note,
.online-message {
  border: var(--border-1) solid var(--wrong);
  border-radius: var(--radius-md);
  background: var(--wrong-soft);
  color: var(--wrong-ink);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

.ranking-scope,
.online-note {
  border-radius: var(--radius-md);
  background: var(--accent-subtle);
  color: var(--accent-ink);
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
}

.home-note::before,
.online-message::before,
.ranking-scope::before,
.online-note::before {
  content: '';
  flex: none;
  width: var(--icon-sm);
  height: var(--icon-sm);
  height: 1lh;
  background-color: currentColor;
  -webkit-mask: var(--icon) center / var(--icon-sm) no-repeat;
  mask: var(--icon) center / var(--icon-sm) no-repeat;
}

.home-note,
.online-message {
  --icon: var(--i-alert);
}

.ranking-scope,
.online-note {
  --icon: var(--i-info);
}

/* ── 9. 화면 머리 ──────────────────────────────────────────────── */
.screen-title,
.ranking-title {
  color: var(--text);
  font-size: var(--text-2xl);
  font-weight: var(--weight-heavy);
  letter-spacing: -0.01em;
}

.screen-lead {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

/* ── 10. 퀴즈 HUD ────────────────────────────────────────────────
   한 블록 안에서 무엇이 무엇인지 읽히게 한다. 분야는 칩, 위치는 픽셀 숫자,
   진행률은 얇은 옅은 보라, 타이머는 굵은 진한 보라. */
.quiz-category {
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-size: var(--text-xs);
  font-weight: var(--weight-heavy);
  line-height: 24px;
}

.quiz-position {
  color: var(--text);
  font-family: var(--font-display);
  font-size: var(--text-md);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.progress,
.timer__track {
  border-radius: var(--radius-full);
  background: var(--surface-sunken);
}

.progress__fill {
  border-radius: var(--radius-full);
  background: var(--accent-line);
  transition: width var(--duration-base) var(--ease-out);
}

.timer__fill {
  border-radius: var(--radius-full);
  background: var(--accent);
}

.timer__label {
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
}

/* 남은 시간 표식. 시계 → 경고 삼각형으로 모양이 바뀐다 (FR-3.9: 색만이 아니라 아이콘·글자도) */
.timer__icon {
  background-color: currentColor;
  -webkit-mask: var(--i-clock) center / contain no-repeat;
  mask: var(--i-clock) center / contain no-repeat;
}

.timer--warning .timer__icon {
  -webkit-mask-image: var(--i-alert);
  mask-image: var(--i-alert);
}

.timer--warning .timer__label {
  color: var(--wrong-ink);
}

.timer--warning .timer__fill {
  background: var(--wrong);
}

.quiz-hud:has(.timer--warning) {
  border-color: var(--wrong);
}

.arena__help {
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-full);
  background: var(--surface);
  color: var(--accent-ink);
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out);
}

.arena__help .icon {
  width: var(--icon-lg);
  height: var(--icon-lg);
}

@media (hover: hover) {
  .arena__help:hover {
    border-color: var(--accent-line);
    background: var(--accent-subtle);
  }
}

/* ── 11. 문제와 보기 ─────────────────────────────────────────────
   질문은 가장 먼저 읽히는 하나의 표면이다. 보기는 차분한 같은 조각 넷이다. */
.question {
  color: var(--text);
  font-size: var(--text-xl);
  font-weight: var(--weight-heavy);
  line-height: var(--leading-snug);
  letter-spacing: -0.01em;
}

/* 보기는 상태가 바뀌는 게임 조각이라 2px 테두리를 늘 갖는다. 두께가 그대로라
   상태가 바뀌어도 글자가 밀리지 않는다 */
.choice {
  border: var(--border-2) solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text);
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    box-shadow var(--duration-fast) var(--ease-out),
    translate var(--duration-fast) var(--ease-out);
}

.choice__key {
  border-radius: var(--radius-sm);
  background: var(--surface-subtle);
  color: var(--accent-ink);
  font-family: var(--font-display);
  font-size: var(--text-md);
  line-height: 1;
}

.choice__text {
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
}

/* 판정 알약: 아이콘 + 짧은 글. 색만이 아니라 ✓ ✗ ⧗ 모양이 뜻을 진다 (FR-4.1, FR-4.2) */
.choice__mark {
  padding: 0 var(--space-2) 0 var(--space-1);
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: var(--weight-heavy);
  line-height: 24px;
}

.choice--correct .choice__mark::before,
.choice--wrong .choice__mark::before,
.choice--submitted .choice__mark::before {
  content: '';
  flex: none;
  width: var(--icon-sm);
  height: var(--icon-sm);
  background-color: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat;
  mask: var(--icon) center / contain no-repeat;
}

/* ── 보기의 상태 ──
   한 보기가 가질 수 있는 상태를 서로 다른 모양으로 나눈다. 세기 순서가 곧 뜻의 순서다.
     hover        눌릴 수 있다는 반응. 옅은 선과 한 칸 들림 — 채우지 않는다
     눌림         한 칸 내려앉고 그림자가 사라진다
     focus        키보드 위치. 공통 초점 고리
     캐릭터 위치   «불 켜짐». 보라로 채우고 번호 칸도 채운다. 아직 확정은 아니다
     제출됨        온라인 채점 전. 골드 점선 테두리와 모래시계
     정답 공개     민트·코랄로 채우고 ✓ ✗ 알약을 단다. 가장 강하다
   hover 를 캐릭터 위치처럼 채우면 마우스만 올려도 고른 것처럼 보인다.
   터치 기기에서는 스크롤하다 스친 보기에 hover 가 남으므로 (hover: hover) 에서만 반응한다. */
@media (hover: hover) {
  .choice:hover:not(:disabled) {
    translate: 0 -1px;
    border-color: var(--accent-line);
    background: var(--surface);
    box-shadow: var(--elevation-2);
  }

  .choice:active:not(:disabled) {
    translate: 0 1px;
    box-shadow: none;
  }
}

/* 캐릭터가 선 보기. 바닥 칸과 같은 뜻이라 같은 «불»로 칠한다.
   [data-arena-target] 은 캐릭터가 바닥 칸에 섰을 때 arena 가 같은 번호의 보기에 다는
   표시다. 칸에는 번호뿐이라 무슨 답 위인지는 여기서 읽힌다.
   hover 규칙 뒤에 둔다 — 둘이 겹치면 캐릭터 위치가 이긴다. */
.choice.is-standing:not(:disabled),
.choice[data-arena-target]:not(:disabled) {
  translate: 0 0;
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: none;
}

.choice.is-standing:not(:disabled) .choice__key,
.choice[data-arena-target]:not(:disabled) .choice__key {
  background: var(--accent);
  color: var(--on-accent);
}

/* 정답 공개. 명시도를 한 단계 올려 hover·캐릭터 위치 표시가 결과 색을 덮지 못하게 한다 */
.choice.choice--correct {
  border-color: var(--correct);
  background: var(--correct-soft);
  box-shadow: none;
}

.choice.choice--wrong {
  border-color: var(--wrong);
  background: var(--wrong-soft);
  box-shadow: none;
}

.choice--correct .choice__key {
  background: var(--correct);
  color: var(--on-accent);
}

.choice--wrong .choice__key {
  background: var(--wrong);
  color: var(--on-accent);
}

.choice--correct .choice__mark {
  --icon: var(--i-check);
  background: var(--correct);
  color: var(--on-accent);
}

.choice--wrong .choice__mark {
  --icon: var(--i-cross);
  background: var(--wrong);
  color: var(--on-accent);
}

/* 온라인에서 답을 냈지만 아직 채점 전. 캐릭터 위치(보라)나 정답(민트)과 겹치지 않는
   «기다림»이다 — 골드 바탕에 점선 테두리, 모래시계 알약 */
.choice.choice--submitted {
  border-color: var(--gold);
  border-style: dashed;
  background: var(--warning-soft);
  box-shadow: none;
}

.choice--submitted .choice__key {
  background: var(--gold-soft);
  color: var(--text);
}

.choice--submitted .choice__mark {
  --icon: var(--i-hourglass);
  background: var(--gold-soft);
  color: var(--text);
}

/* 고르지 않은 나머지 보기 */
.choice.choice--muted {
  opacity: 0.55;
  box-shadow: none;
}

/* ── 12. 캐릭터 퀴즈 무대 ────────────────────────────────────────
   무대는 화면의 «세계»다. 모래 길이 십자로 지나가고(=아무 칸도 아닌 자리) 네 칸은
   돌판이다. 칸 색은 정답 민트와 헷갈리지 않게 크림색으로 둔다. */
.arena__grid {
  border: var(--border-1) solid var(--world-stone-edge);
  border-radius: var(--radius-xl);
  background: var(--world-path);
  box-shadow: var(--elevation-1);
}

.arena-tile {
  border: var(--border-2) solid var(--world-stone-edge);
  border-radius: var(--radius-lg);
  background: var(--world-stone);
  transition:
    background-color var(--duration-base) var(--ease-out),
    border-color var(--duration-base) var(--ease-out);
}

.arena-tile__number {
  color: var(--text-muted);
  font-family: var(--font-display);
  font-size: var(--text-md);
}

/* 캐릭터가 서 있는 칸. 불이 들어온 것처럼 보이게 한다.
   클래스 이름은 워커가 붙이는 is-standing 하나로 통일했다 —
   홈이든 무대든 «발밑»을 나타내는 것은 같은 개념이다. */
.arena-tile.is-standing {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.arena-tile.is-standing .arena-tile__number {
  color: var(--accent-ink);
}

/* 채점 뒤. 색만이 아니라 ✓ ✗ 표시로도 구분한다 (FR-4.1, FR-4.2).
   캐릭터 위치(보라 불)보다 뒤에 두어, 둘이 겹쳐도 결과가 이긴다 */
.arena-tile.arena-tile--correct {
  border-color: var(--correct);
  background: var(--correct-soft);
}

.arena-tile.arena-tile--wrong {
  border-color: var(--wrong);
  background: var(--wrong-soft);
}

.arena-tile--correct .arena-tile__number {
  color: var(--correct-ink);
}

.arena-tile--wrong .arena-tile__number {
  color: var(--wrong-ink);
}

.arena-tile--correct .arena-tile__mark,
.arena-tile--wrong .arena-tile__mark {
  -webkit-mask: var(--icon) center / contain no-repeat;
  mask: var(--icon) center / contain no-repeat;
}

.arena-tile--correct .arena-tile__mark {
  --icon: var(--i-check);
  background-color: var(--correct);
}

.arena-tile--wrong .arena-tile__mark {
  --icon: var(--i-cross);
  background-color: var(--wrong);
}

.arena-tile--muted {
  opacity: 0.55;
}

/* ── 13. 피드백 시트 ─────────────────────────────────────────────
   엄지가 닿는 자리에 붙는 시트. 판정은 글자색만이 아니라 시트 테두리와
   ✓ ✗ 배지로도 읽힌다. 시간 초과도 오답이라 ✗ 를 쓴다 — 무엇 때문인지는 판정 글이 말한다 */
.feedback {
  border: var(--border-2) solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--surface);
  box-shadow: var(--elevation-3);
}

.feedback.feedback--correct {
  border-color: var(--correct);
}

.feedback.feedback--wrong {
  border-color: var(--wrong);
}

.feedback__verdict {
  font-size: var(--text-lg);
  font-weight: var(--weight-heavy);
  line-height: var(--leading-tight);
}

.feedback--correct .feedback__verdict {
  color: var(--correct-ink);
}

.feedback--wrong .feedback__verdict {
  color: var(--wrong-ink);
}

/* 판정 배지: 상태 색으로 채운 둥근 칸 위에 흰 ✓ ✗. 판정 글이 라이브 리전 안에 있으므로
   배지는 글자가 아니라 그림이고, 다시 낭독할 것이 없도록 content 를 비운다 */
.feedback--correct .feedback__verdict::before,
.feedback--wrong .feedback__verdict::before,
.online-reveal--correct .online-reveal__verdict::before,
.online-reveal--wrong .online-reveal__verdict::before {
  content: '';
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
  background: var(--badge-icon) center / var(--icon-md) no-repeat, var(--badge-color);
}

.feedback--correct .feedback__verdict::before,
.online-reveal--correct .online-reveal__verdict::before {
  --badge-icon: var(--i-check-inverse);
  --badge-color: var(--correct);
}

.feedback--wrong .feedback__verdict::before,
.online-reveal--wrong .online-reveal__verdict::before {
  --badge-icon: var(--i-cross-inverse);
  --badge-color: var(--wrong);
}

.feedback__explanation {
  color: var(--text-muted);
  font-size: var(--text-md);
  line-height: var(--leading-normal);
}

.feedback .button {
  min-height: var(--tap-lg);
}

/* 「다음 문제」의 Space/Enter 표시. 보라 바탕에서 작은 글자 대비(4.5:1)를 넘기도록
   흐리게 하지 않고 옅은 보라 글자로 둔다 */
.key-hint {
  color: var(--on-accent-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

.key-hint__key {
  border-radius: var(--radius-xs);
  background: var(--accent-hover);
  font: inherit;
}

/* ── 14. 대화상자 ────────────────────────────────────────────── */
.dialog-backdrop {
  background: var(--overlay);
}

.dialog {
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--surface);
  box-shadow: var(--elevation-3);
}

.dialog__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-heavy);
}

.dialog__body {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
}

.help-list {
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

.help-list dt {
  font-weight: var(--weight-heavy);
}

.help-list dd {
  color: var(--text-muted);
}

/* 키 모양: 1px 선과 아래 2px 두께. 실제 자판처럼 읽히면 된다 */
.help-list kbd,
.chat__hint kbd {
  border: var(--border-1) solid var(--border);
  border-bottom-width: var(--border-2);
  border-radius: var(--radius-xs);
  background: var(--surface-subtle);
  color: var(--text);
  font: inherit;
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

/* ── 15. 폼 ──────────────────────────────────────────────────── */
.room-form__input,
.register__input,
.chat__input {
  border: var(--border-1) solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text);
  /* 16px 아래로 내리면 iOS 가 입력칸에 들어갈 때 화면을 확대한다 */
  font-size: var(--text-md);
  transition: border-color var(--duration-fast) var(--ease-out);
}

.room-form__input::placeholder,
.register__input::placeholder,
.chat__input::placeholder {
  color: var(--text-disabled);
}

@media (hover: hover) {
  .room-form__input:hover:not(:disabled),
  .register__input:hover:not(:disabled),
  .chat__input:hover:not(:disabled) {
    border-color: var(--text-muted);
  }
}

.room-form__input:focus-visible,
.register__input:focus-visible,
.chat__input:focus-visible {
  border-color: var(--accent);
}

.room-form__input:disabled,
.register__input:disabled,
.chat__input:disabled {
  border-color: var(--border);
  background: var(--surface-subtle);
  color: var(--text-muted);
}

/* select 는 의사 요소가 없어 아이콘 묶음의 화살표를 배경 그림으로 단다 */
select.room-form__input {
  -webkit-appearance: none;
  appearance: none;
  padding-right: var(--space-8);
  background-image: var(--select-chevron);
  background-position: right var(--space-2) center;
  background-repeat: no-repeat;
  background-size: var(--icon-md);
}

.room-form__label,
.register__label {
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
}

.room-filter {
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

.room-form__row--check {
  border-radius: var(--radius-md);
  background: var(--surface-subtle);
  color: var(--text);
  font-size: var(--text-sm);
}

.room-form__row--check input {
  accent-color: var(--accent);
}

.room-message,
.register__message {
  color: var(--correct-ink);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

.room-message--bad,
.register__message--error {
  color: var(--wrong-ink);
}

.register__message:not(.register__message--error):not(.register__message--done) {
  color: var(--text-muted);
}

.register__message--done {
  font-weight: var(--weight-bold);
}

/* ── 16. 결과 ─────────────────────────────────────────────────────
   점수와 등급이 먼저 읽히는 축하 장면 → 세 개의 요약 칩 → 다시 하기(주 행동) →
   보조 행동 → 랭킹 등록 → 오답 복습. 카드 안에 카드를 넣지 않는다. */
.result-header {
  border: var(--border-1) solid var(--accent-line);
  background:
    radial-gradient(circle at 50% 0%, var(--accent-soft) 0, transparent 70%),
    var(--surface);
  box-shadow: var(--elevation-1);
}

/* 축하 장식: 오른쪽 위에 골드 별 두 개. 캐릭터가 시작하는 왼쪽 위는 비워 둔다 */
.result-header::before,
.result-header::after {
  content: '';
  position: absolute;
  background-color: var(--gold);
  -webkit-mask: var(--i-star) center / contain no-repeat;
  mask: var(--i-star) center / contain no-repeat;
}

.result-header::before {
  top: var(--space-4);
  right: var(--space-5);
  width: var(--icon-lg);
  height: var(--icon-lg);
}

.result-header::after {
  top: var(--space-10);
  right: var(--space-12);
  width: var(--icon-sm);
  height: var(--icon-sm);
  opacity: 0.7;
}

.result-mode {
  border-radius: var(--radius-full);
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-size: var(--text-xs);
  font-weight: var(--weight-heavy);
}

.result-score {
  color: var(--text-muted);
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
  line-height: 1;
}

.result-score strong {
  color: var(--accent-strong);
  font-family: var(--font-display);
  font-size: var(--text-4xl);
  font-weight: 400;
  line-height: 1;
}

.result-grade {
  color: var(--accent-ink);
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 400;
  line-height: var(--leading-tight);
}

.result-grade-message {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

.result-best {
  border-radius: var(--radius-full);
  background: var(--surface-subtle);
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
}

/* 신기록·첫 기록: 골드 바탕에 별. 색이 없어도 별 모양과 글이 남는다 */
.result-best--new {
  background: var(--warning-soft);
  color: var(--warning);
}

.result-best--new::before {
  content: '';
  flex: none;
  width: var(--icon-sm);
  height: var(--icon-sm);
  background-color: currentColor;
  -webkit-mask: var(--i-star) center / contain no-repeat;
  mask: var(--i-star) center / contain no-repeat;
}

/* 요약 칩 세 개: 아이콘 · 이름 · 값 */
.result-stats__item::before {
  grid-area: icon;
  width: var(--icon-md);
  height: var(--icon-md);
  color: var(--accent-ink);
}

.result-stats dt {
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

.result-stats dd {
  color: var(--text);
  font-size: var(--text-md);
  font-weight: var(--weight-heavy);
  line-height: var(--leading-tight);
}

.result-block__title {
  font-size: var(--text-md);
  font-weight: var(--weight-heavy);
}

.category-score__item + .category-score__item {
  border-top: var(--border-1) solid var(--border);
}

.category-score__name {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
}

.category-score__count {
  border-radius: var(--radius-full);
  background: var(--surface-subtle);
  font-size: var(--text-sm);
  font-weight: var(--weight-heavy);
  line-height: 24px;
}

.review__item + .review__item {
  border-top: var(--border-1) solid var(--border);
}

.review__question {
  font-size: var(--text-md);
  font-weight: var(--weight-heavy);
  line-height: var(--leading-snug);
}

.review__row {
  font-size: var(--text-sm);
  line-height: 24px;
}

.review__tag {
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: var(--weight-heavy);
}

.review__tag::before {
  content: '';
  flex: none;
  width: var(--icon-sm);
  height: var(--icon-sm);
  background-color: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat;
  mask: var(--icon) center / contain no-repeat;
}

.review__row--mine .review__tag {
  --icon: var(--i-cross);
  background: var(--wrong-soft);
  color: var(--wrong-ink);
}

.review__row--answer .review__tag {
  --icon: var(--i-check);
  background: var(--correct-soft);
  color: var(--correct-ink);
}

.review__explanation {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
}

/* ── 17. 랭킹 ──────────────────────────────────────────────────── */
/* 탭은 한 묶음의 분절 버튼이다. 고른 탭은 흰 표면으로 «들려» 있다 — 색만이 아니라 높이로 */
.ranking-tabs {
  border-color: transparent;
  background: var(--surface-sunken);
  box-shadow: none;
}

.ranking-tab {
  border: var(--border-1) solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  transition:
    background-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out);
}

@media (hover: hover) {
  .ranking-tab:hover {
    color: var(--text);
  }
}

.ranking-tab--active {
  border-color: var(--border);
  background: var(--surface);
  box-shadow: var(--elevation-1);
  color: var(--accent-ink);
  font-weight: var(--weight-heavy);
}

.ranking-list {
  overflow: hidden;
}

.ranking-item + .ranking-item {
  border-top: var(--border-1) solid var(--border);
}

/* 방금 등록한 기록 (FR-6.5). 바탕과 왼쪽 띠, 「방금 등록」 배지가 함께 짚는다 */
.ranking-item.ranking-item--mine {
  background: var(--accent-soft);
  box-shadow: var(--marker-mine);
}

/* 순위는 칸 안의 픽셀 숫자다. 1·2·3위는 금·은·동 칸이다. 순위를 말하는 것은 숫자이고
   색은 거들 뿐이다 */
.ranking-item__rank {
  border-radius: var(--radius-sm);
  background: var(--surface-subtle);
  color: var(--text-muted);
  font-family: var(--font-display);
  font-size: var(--text-md);
  line-height: 1;
}

.ranking-item:nth-child(1) .ranking-item__rank {
  background: var(--medal-gold);
  color: var(--text);
}

.ranking-item:nth-child(2) .ranking-item__rank {
  background: var(--medal-silver);
  color: var(--text);
}

.ranking-item:nth-child(3) .ranking-item__rank {
  background: var(--medal-bronze);
  color: var(--text);
}

.ranking-item--mine .ranking-item__rank {
  outline: var(--border-2) solid var(--accent);
  outline-offset: -2px;
}

.ranking-item__nickname {
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
}

.ranking-item__badge {
  border-radius: var(--radius-full);
  background: var(--accent);
  color: var(--on-accent);
  font-size: var(--text-xs);
  font-weight: var(--weight-heavy);
  line-height: 20px;
}

.ranking-item__score {
  font-size: var(--text-md);
  font-weight: var(--weight-heavy);
}

/* 몇 문제 중 몇 개인지. 점수보다 작게 붙여 순위는 점수로 읽히게 둔다 */
.ranking-item__hits,
.ranking-item__date {
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

.ranking-empty {
  border: var(--border-2) dashed var(--border);
  border-radius: var(--radius-xl);
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

.ranking-empty::before {
  content: '';
  width: var(--icon-tile);
  height: var(--icon-tile);
  background-color: var(--accent-line);
  -webkit-mask: var(--i-trophy) center / contain no-repeat;
  mask: var(--i-trophy) center / contain no-repeat;
}

/* ── 18. 내 캐릭터 ─────────────────────────────────────────────── */
.character-card {
  border-width: var(--border-2);
  color: var(--text);
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    translate var(--duration-fast) var(--ease-out);
}

/* 그림 아래 받침 그림자. 정지 그림이 바닥에 서 있게 한다 */
.character-card__figure::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -6px;
  width: 30px;
  height: 6px;
  translate: -50% 0;
  border-radius: 50%;
  background: var(--surface-sunken);
}

@media (hover: hover) {
  .character-card:hover {
    border-color: var(--accent-line);
  }
}

.character-card:active {
  translate: 0 1px;
}

/* 지금 쓰는 캐릭터. 보라 테두리·바탕에 더해 ✓ 배지를 달아 색에만 기대지 않는다.
   낭독은 aria-pressed 가 맡는다 */
.character-card.character-card--on {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.character-card--on::after {
  content: '';
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  width: var(--icon-lg);
  height: var(--icon-lg);
  border-radius: var(--radius-full);
  background: var(--i-check-inverse) center / var(--icon-sm) no-repeat, var(--accent);
}

/* ── 19. 온라인 로비 ─────────────────────────────────────────── */
.online-hero {
  border: var(--border-1) solid var(--world-sky-edge);
  border-radius: var(--radius-xl);
  background: linear-gradient(170deg, var(--world-sky-1) 0%, var(--world-sky-2) 100%);
  box-shadow: var(--elevation-1);
}

.online-hero__eyebrow,
.online-block__eyebrow {
  color: var(--accent-ink);
  font-size: var(--text-xs);
  font-weight: var(--weight-heavy);
}

/* 「친구와 함께」 앞의 점: 연결 상태를 뜻하지 않는 장식이라 글리프 대신 작은 원으로 */
.online-hero__dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--correct);
}

.online-hero__title {
  color: var(--accent-strong);
}

.online-hero__lead {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

.online-note {
  background: var(--glass);
}

.online-home .icon {
  width: var(--icon-sm);
  height: var(--icon-sm);
}

/* 세 동작: dock 과 같은 분절 묶음. 고른 칸은 보라로 채우고 아이콘 칸도 채운다 */
.online-action-card {
  border: var(--border-1) solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text);
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out);
}

.online-action-card__icon {
  border-radius: var(--radius-md);
  background: var(--surface-subtle);
  color: var(--accent-ink);
}

.online-action-card__icon::before {
  width: var(--icon-md);
  height: var(--icon-md);
}

.online-action-card__body strong {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-heavy);
  line-height: var(--leading-snug);
}

/* style.css의 짧은 로비 배치를 theme 뒤에서도 지킨다. 같은 specificity의 기본
   아이콘·글자 규칙이 compact 값을 되돌리면 320px에서 동작 이름이 잘린다. */
@media (max-width: 420px), (max-height: 480px) {
  .online-action-card__icon::before {
    width: var(--icon-sm);
    height: var(--icon-sm);
  }

  .online-action-card__body strong {
    font-size: var(--text-xs);
  }
}

.online-action-card__copy {
  color: var(--text-muted);
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
}

@media (hover: hover) {
  .online-action-card:hover {
    background: var(--surface-subtle);
  }
}

.online-action-card[aria-pressed='true'] {
  border-color: var(--accent-line);
  background: var(--accent-soft);
  color: var(--accent-ink);
}

.online-action-card[aria-pressed='true'] .online-action-card__icon {
  background: var(--accent);
  color: var(--on-accent);
}

.online-block__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-heavy);
}

.online-block__caption {
  color: var(--text-muted);
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
}

.online-panel-heading__icon {
  border-radius: var(--radius-md);
  background: var(--accent-soft);
  color: var(--accent-ink);
}

/* 필터·새로고침 버튼의 아이콘. 필터 글자는 JS 가 통째로 다시 쓰므로 ::before 로 단다 */
#room-filter-toggle::before {
  content: '';
  flex: none;
  width: var(--icon-sm);
  height: var(--icon-sm);
  background-color: currentColor;
  -webkit-mask: var(--i-filter) center / contain no-repeat;
  mask: var(--i-filter) center / contain no-repeat;
}

.online-block__tools .icon {
  width: var(--icon-sm);
  height: var(--icon-sm);
}

.room-filters {
  border-radius: var(--radius-lg);
  background: var(--surface-subtle);
}

.room-list-summary {
  border-radius: var(--radius-full);
  background: var(--surface-subtle);
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
}

/* 방 목록은 블록 안의 줄이다. 줄마다 카드를 씌우지 않고 1px 선으로만 나눈다 */
.room-item + .room-item {
  border-top: var(--border-1) solid var(--border);
}

.room-item {
  --cat-ink: var(--accent-ink);
  --cat-soft: var(--accent-soft);
}

.room-item__icon {
  border-radius: var(--radius-md);
  background: var(--cat-soft);
  color: var(--cat-ink);
}

.room-item__name {
  font-size: var(--text-md);
  font-weight: var(--weight-heavy);
  line-height: var(--leading-snug);
}

.room-item__meta {
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}

.room-item__visibility {
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: var(--weight-heavy);
  line-height: 20px;
}

.room-item__visibility--public {
  background: var(--correct-soft);
  color: var(--correct-ink);
}

/* 비공개는 자물쇠 모양을 함께 단다 */
.room-item__visibility--private {
  background: var(--accent-soft);
  color: var(--accent-ink);
}

.room-item__visibility--private::before {
  content: '';
  width: 12px;
  height: 12px;
  background-color: currentColor;
  -webkit-mask: var(--i-lock) center / contain no-repeat;
  mask: var(--i-lock) center / contain no-repeat;
}

.room-item--full .room-item__icon {
  background: var(--surface-subtle);
  color: var(--text-muted);
}

.room-empty {
  border: var(--border-2) dashed var(--border);
  border-radius: var(--radius-lg);
}

.room-empty__icon {
  border-radius: var(--radius-lg);
  background: var(--warning-soft);
  color: var(--warning);
}

.room-empty__title {
  font-size: var(--text-md);
  font-weight: var(--weight-heavy);
}

.room-empty__copy {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

/* ── 20. 대기실 ─────────────────────────────────────────────────
   방 그림(벽·바닥·가구·액자)은 세계 장식이라 css/style.css 에 구조와 함께 있다.
   여기서는 둘레의 조작(설정·준비·시작·채팅)을 시스템과 같은 말로 맞춘다. */
.setting-card {
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    translate var(--duration-fast) var(--ease-out);
}

.setting-card__label {
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

.setting-card__value {
  color: var(--text);
  font-size: var(--text-md);
  font-weight: var(--weight-heavy);
  line-height: var(--leading-snug);
}

/* «누르면 다음 값으로 돈다»는 표식. 방장이 아니면 돌 수 없으므로 표식을 거둔다 */
.setting-card::after {
  content: '';
  position: absolute;
  top: 50%;
  right: var(--space-3);
  width: var(--icon-md);
  height: var(--icon-md);
  translate: 0 -50%;
  background-color: var(--accent-ink);
  -webkit-mask: var(--i-refresh) center / contain no-repeat;
  mask: var(--i-refresh) center / contain no-repeat;
}

@media (hover: hover) {
  .setting-card:hover:not(:disabled) {
    border-color: var(--accent-line);
  }
}

.setting-card:active:not(:disabled) {
  translate: 0 1px;
}

.setting-card:disabled {
  background: var(--surface-subtle);
  box-shadow: none;
}

.setting-card:disabled::after {
  display: none;
}

/* 준비 토글. 켜지면 민트 바탕에 ✓ — 「준비 완료 / 준비 취소」 글자와 aria-pressed 가 함께 간다 */
.waiting-ready[aria-pressed='true'] {
  border-color: var(--correct);
  background: var(--correct-soft);
  color: var(--correct-ink);
}

.waiting-ready[aria-pressed='true']::before {
  content: '';
  flex: none;
  width: var(--icon-md);
  height: var(--icon-md);
  background-color: currentColor;
  -webkit-mask: var(--i-check) center / contain no-repeat;
  mask: var(--i-check) center / contain no-repeat;
}

.chat__hint {
  color: var(--text-muted);
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
}

.chat-log__line {
  color: var(--text);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

.chat-log__who {
  color: var(--accent-ink);
  font-weight: var(--weight-heavy);
}

.chat-log__line--notice {
  color: var(--warning);
  font-size: var(--text-xs);
}

/* ── 21. 온라인 퀴즈 · 최종 순위 ─────────────────────────────── */
.online-match-status {
  color: var(--text-muted);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

.online-match-status::before {
  content: '';
  flex: none;
  width: var(--icon-sm);
  height: var(--icon-sm);
  background-color: var(--accent-ink);
  -webkit-mask: var(--i-info) center / contain no-repeat;
  mask: var(--i-info) center / contain no-repeat;
}

.online-reveal {
  border-width: var(--border-2);
}

.online-reveal--correct {
  border-color: var(--correct);
}

.online-reveal--wrong {
  border-color: var(--wrong);
}

.online-reveal__verdict {
  font-size: var(--text-lg);
  font-weight: var(--weight-heavy);
}

.online-reveal--correct .online-reveal__verdict {
  color: var(--correct-ink);
}

.online-reveal--wrong .online-reveal__verdict {
  color: var(--wrong-ink);
}

.online-reveal__explanation {
  color: var(--text-muted);
  font-size: var(--text-md);
  line-height: var(--leading-normal);
}

.online-quiz-chat {
  border-top: var(--border-1) solid var(--border);
}

.online-final__summary {
  border-radius: var(--radius-lg);
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-size: var(--text-md);
  font-weight: var(--weight-heavy);
  line-height: var(--leading-snug);
}

.online-final-ranking {
  overflow: hidden;
}

.online-final-ranking__item + .online-final-ranking__item {
  border-top: var(--border-1) solid var(--border);
}

.online-final-ranking__place {
  border-radius: var(--radius-sm);
  background: var(--surface-subtle);
  color: var(--text);
  font-family: var(--font-display);
  font-size: var(--text-md);
  line-height: 1;
}

.online-final-ranking__item:nth-child(1) .online-final-ranking__place {
  background: var(--medal-gold);
}

.online-final-ranking__name {
  font-weight: var(--weight-heavy);
}

.online-final-ranking__score {
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
}

.online-final-ranking__item.online-final-ranking__item--mine {
  background: var(--accent-soft);
  box-shadow: var(--marker-mine);
}

/* ── 22. 걷는 캐릭터 · 말풍선 (세계 장식) ─────────────────────────── */
.walker__body {
  border-radius: 46% 46% 38% 38%;
  box-shadow: inset 0 -6px 0 rgba(29, 31, 58, 0.16), 0 2px 6px rgba(29, 31, 58, 0.22);
}

/* 도트 몬스터는 덩어리가 아니라 스프라이트다. 배경과 그림자를 지운다 */
.walker__body--pixel {
  background: none;
  border-radius: 0;
  box-shadow: none;
}

.walker__face,
.walker__face::after {
  border-radius: 50%;
  background: #ffffff;
}

.walker__shadow {
  border-radius: 50%;
  background: rgba(29, 31, 58, 0.2);
}

/* 틀렸을 때. 색을 뺀다 — 슬라임 색은 sprite.ts 가 인라인 style 로 칠해 배경 규칙으로는 덮을 수 없어
   슬라임과 도트 모두 회색 필터로 뺀다 */
.walker--sad .walker__body {
  filter: grayscale(1) brightness(1.05);
}

.walker--seated .walker__shadow {
  opacity: 0.5;
}

.walker__name {
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-full);
  background: var(--glass);
  box-shadow: var(--elevation-1);
  color: var(--text-muted);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  line-height: 20px;
}

.walker__bubble {
  border: var(--border-1) solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--elevation-2);
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
}

/* 꼬리는 말풍선 바탕을 이어받은 회전 네모다. 아래쪽 두 변에만 선을 그어 몸통과 붙는다 */
.walker__bubble::after {
  border-right: var(--border-1) solid var(--border);
  border-bottom: var(--border-1) solid var(--border);
  background: var(--surface);
}

.walker__bubble--below::after {
  border: 0;
  border-top: var(--border-1) solid var(--border);
  border-left: var(--border-1) solid var(--border);
}

/* ── 23. 손가락 조작부 ───────────────────────────────────────────
   스틱은 반투명 원판, 손잡이와 확정 버튼은 보라로 채운다. 원이라 두 엄지가 닿는
   자리가 분명하다. z-index 는 주지 않는다. */
.walk-stick {
  border: var(--border-1) solid var(--border);
  border-radius: 50%;
  background:
    linear-gradient(90deg, transparent 49%, var(--border) 49% 51%, transparent 51%),
    linear-gradient(transparent 49%, var(--border) 49% 51%, transparent 51%),
    var(--glass);
  box-shadow: var(--elevation-2);
}

.walk-stick__knob {
  border-radius: 50%;
  background: var(--accent);
  box-shadow: var(--elevation-1), var(--press-edge);
}

.walk-confirm {
  border: 0;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: var(--elevation-2), var(--press-edge);
  color: var(--on-accent);
  font-family: var(--font-text);
  font-size: var(--text-md);
  font-weight: var(--weight-heavy);
}

/* 최소 44px 원에서도 세 글자 「나가기」가 넘치지 않는다. */
@media (pointer: coarse) and (max-height: 360px) {
  .walk-confirm {
    font-size: var(--text-xs);
  }
}

.walk-confirm:active {
  translate: 0 2px;
  box-shadow: var(--elevation-1);
  background: var(--accent-hover);
}

/* ── 24. 걸어서 올라선 표시 (is-standing) ─────────────────────────
   카드처럼 제 표시가 따로 없는 버튼들. 걸어 올라서면 눌릴 수 있다고 알린다.
   초점 고리와 같은 모양을 쓴다 — 「지금 이걸 누르면 된다」는 뜻이 같다.
   글자를 적는 칸도 같은 표시를 쓴다. 밟으면 «누르는» 대신 커서가 들어가지만,
   보는 쪽에서는 둘 다 「지금 여기서 Enter」라 표시를 나눌 이유가 없다. */
.button.is-standing,
.icon-button.is-standing,
.ranking-tab.is-standing,
.character-card.is-standing,
.arena__help.is-standing,
.setting-card.is-standing,
.online-action-card.is-standing,
.menu-card.is-standing,
input.is-standing,
textarea.is-standing,
select.is-standing {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
}

/* 분야 칸·전체 도전·dock 칸은 고리에 더해 옅게 채워 «올라섰다»가 더 잘 보이게 한다 */
.category-card.is-standing,
.menu-card.is-standing {
  background: var(--accent-subtle);
}

.challenge-card.is-standing {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
  background: var(--accent-hover);
}

/* ── 25. 세계 장식: 복셀 마을 ────────────────────────────────────
   기능과 분리된 장식용 CSS 아이소메트릭 마을. 스크린리더와 조작 순서에는 들어가지 않는다. */
.voxel-scene {
  position: relative;
  width: 100%;
  min-width: 0;
  height: 136px;
}

.voxel-cloud {
  position: absolute;
  display: block;
  width: 18px;
  height: 8px;
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 10px -8px 0 rgba(255, 255, 255, 0.92), 20px 0 0 rgba(255, 255, 255, 0.92),
    30px 0 0 rgba(255, 255, 255, 0.92);
}

.voxel-cloud--one {
  top: 12px;
  left: 8%;
}

.voxel-cloud--two {
  top: 24px;
  right: 6%;
  scale: 0.72;
  opacity: 0.72;
}

.voxel-island,
.voxel-island > span {
  position: absolute;
  display: block;
}

.voxel-island {
  top: 22px;
  left: 50%;
  width: 224px;
  height: 112px;
  translate: -50% 0;
}

.voxel-island__top,
.voxel-island__left,
.voxel-island__right {
  inset: 0;
}

.voxel-island__top {
  clip-path: polygon(50% 0%, 100% 30%, 50% 60%, 0% 30%);
  background:
    linear-gradient(30deg, transparent 47%, rgba(255, 255, 255, 0.16) 48% 52%, transparent 53%),
    var(--world-grass);
  background-size: 28px 16px;
}

.voxel-island__left {
  clip-path: polygon(0% 30%, 50% 60%, 50% 89%, 0% 59%);
  background: var(--world-soil-left);
}

.voxel-island__right {
  clip-path: polygon(100% 30%, 50% 60%, 50% 89%, 100% 59%);
  background: var(--world-soil-right);
}

.voxel-path {
  position: absolute;
  display: block;
  width: 24px;
  height: 12px;
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  background: #fff3c8;
  box-shadow: inset 0 -3px 0 #dfc986;
}

.voxel-path--one {
  top: 92px;
  left: calc(50% - 12px);
}

.voxel-path--two {
  top: 101px;
  left: calc(50% + 4px);
}

.voxel-path--three {
  top: 110px;
  left: calc(50% + 20px);
}

.iso-cube,
.iso-cube > span {
  position: absolute;
  display: block;
}

.iso-cube {
  width: var(--cube-w, 44px);
  height: var(--cube-h, 58px);
}

.iso-cube > span {
  inset: 0;
}

.iso-cube__top {
  clip-path: polygon(50% 0%, 100% 25%, 50% 50%, 0% 25%);
  background: var(--cube-top, #fff0c8);
}

.iso-cube__left {
  clip-path: polygon(0% 25%, 50% 50%, 50% 100%, 0% 75%);
  background: var(--cube-left, #e7b785);
}

.iso-cube__right {
  clip-path: polygon(100% 25%, 50% 50%, 50% 100%, 100% 75%);
  background: var(--cube-right, #ca8c6c);
}

.voxel-building,
.voxel-tree {
  position: absolute;
  display: block;
}

.voxel-building__door,
.voxel-building__window,
.voxel-building__clock {
  position: absolute;
  display: block;
}

.voxel-building--school {
  top: 22px;
  left: calc(50% - 64px);
  width: 82px;
  height: 90px;
  scale: 0.84;
  transform-origin: 50% 100%;
}

.voxel-building--school .voxel-building__base {
  top: 19px;
  left: 5px;
  --cube-w: 70px;
  --cube-h: 70px;
  --cube-top: #fff0c7;
  --cube-left: #f6c996;
  --cube-right: #e7a77d;
}

.voxel-building--school .voxel-building__roof {
  top: 0;
  left: 0;
  --cube-w: 80px;
  --cube-h: 43px;
  --cube-top: #ffb7b0;
  --cube-left: #ea7d83;
  --cube-right: #c95f72;
}

.voxel-building--school .voxel-building__door {
  right: 12px;
  bottom: 10px;
  width: 12px;
  height: 22px;
  transform: skewY(-27deg);
  border: 2px solid #4b30bd;
  background: #7d66e4;
}

.voxel-building--school .voxel-building__window {
  bottom: 26px;
  left: 13px;
  width: 11px;
  height: 11px;
  transform: skewY(27deg);
  border: 2px solid #4d7394;
  background: #c8efff;
  box-shadow: 15px 8px 0 -2px #c8efff, 15px 8px 0 0 #4d7394;
}

.voxel-building--tower {
  top: 12px;
  left: calc(50% + 14px);
  width: 54px;
  height: 97px;
  scale: 0.84;
  transform-origin: 50% 100%;
}

.voxel-building--tower .voxel-building__base {
  top: 22px;
  left: 7px;
  --cube-w: 44px;
  --cube-h: 74px;
  --cube-top: #d5edff;
  --cube-left: #a4d3ee;
  --cube-right: #72aecf;
}

.voxel-building--tower .voxel-building__roof {
  top: 8px;
  left: 2px;
  --cube-w: 54px;
  --cube-h: 32px;
  --cube-top: #d9cffd;
  --cube-left: #8e7bdc;
  --cube-right: #6755b6;
}

.voxel-building--tower .voxel-building__clock {
  top: 50px;
  left: 12px;
  width: 14px;
  height: 14px;
  transform: skewY(27deg);
  border: 2px solid #47536e;
  background: var(--gold-soft);
  color: var(--accent-strong);
  font-family: var(--font-display);
  font-size: 11px;
  line-height: 10px;
  text-align: center;
}

.voxel-tree {
  width: 42px;
  height: 64px;
  scale: 0.8;
  transform-origin: 50% 100%;
}

.voxel-tree__trunk {
  top: 28px;
  left: 13px;
  --cube-w: 18px;
  --cube-h: 35px;
  --cube-top: #d49a62;
  --cube-left: #a86b45;
  --cube-right: #7f503c;
}

.voxel-tree__crown {
  top: 0;
  left: 0;
  --cube-w: 42px;
  --cube-h: 47px;
  --cube-top: #d5f39a;
  --cube-left: #86cf78;
  --cube-right: #55a76a;
}

.voxel-tree--one {
  top: 48px;
  left: calc(50% - 100px);
}

.voxel-tree--two {
  top: 56px;
  left: calc(50% + 62px);
  scale: 0.68;
}

.voxel-tree--three {
  top: 70px;
  left: calc(50% - 58px);
  scale: 0.56;
}

.voxel-spark {
  position: absolute;
  display: block;
  width: 8px;
  height: 8px;
  background: var(--accent);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
  opacity: 0.7;
}

.voxel-spark--one {
  top: 16px;
  left: calc(50% + 8px);
}

.voxel-spark--two {
  top: 52px;
  right: 4%;
  background: var(--gold);
}

/* ── 26. 반응형 ────────────────────────────────────────────────── */

/* 넓은 화면의 홈: 마을이 브랜드 곁으로 넉넉히 펼쳐진다 */
@media (min-width: 600px) {
  .home-header {
    min-height: 176px;
    padding-left: var(--space-6);
  }

  .voxel-scene {
    height: 152px;
    scale: 1.1;
  }

  .home-quests {
    padding: var(--space-4);
  }
}

@media (max-width: 420px) {
  .home-header {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    min-height: 136px;
    padding: var(--space-3) 0 var(--space-3) var(--space-4);
  }

  .home-title {
    font-size: var(--text-2xl);
  }

  .home-title span {
    font-size: var(--text-xs);
  }

  .home-subtitle {
    font-size: var(--text-xs);
  }

  .voxel-scene {
    height: 112px;
    scale: 0.78;
  }

  .question {
    font-size: var(--text-lg);
  }
}

/* 좁은 분야 칸은 아이콘 칸을 줄이고(css/style.css) 아이콘도 한 단계 작게 그린다 */
@media (max-width: 360px) {
  .category-card__icon {
    border-radius: var(--radius-sm);
  }

  .category-card__icon::before {
    width: var(--icon-md);
    height: var(--icon-md);
  }

  /* dock 칸은 이름을 한 단계 줄여 캐릭터가 서는 오른쪽과 겹치지 않게 한다 */
  .home-menu .menu-card__name {
    font-size: var(--text-xs);
  }

  .result-stats dd {
    font-size: var(--text-sm);
  }

  .result-stats__item::before {
    width: var(--icon-sm);
    height: var(--icon-sm);
  }

  .voxel-scene {
    scale: 0.7;
  }
}

/* ── 27. 움직임 ─────────────────────────────────────────────────
   정답·오답을 눈으로도 짚어 준다. 색상 대신이 아니라 색상에 더하는 것이다.
   모든 피드백은 180ms 안에 끝난다. 끝없이 깜빡이는 경고는 두지 않는다 — 남은 5초는
   아이콘·글자·색이 함께 바뀌어 알린다 (FR-3.9). */
@keyframes choice-pop {
  50% {
    scale: 1.02;
  }
}

@keyframes choice-shake {
  25% {
    translate: -3px 0;
  }
  75% {
    translate: 3px 0;
  }
}

@keyframes panel-fade {
  from {
    opacity: 0.72;
  }
}

.choice.choice--correct {
  animation: choice-pop var(--duration-base) var(--ease-out);
}

.choice.choice--wrong {
  animation: choice-shake var(--duration-base) var(--ease-in-out);
}

.feedback:not([hidden]) {
  animation: panel-fade var(--duration-slow) var(--ease-out);
}

/* ── 28. 고대비(강제 색) 모드 ─────────────────────────────────────
   아이콘은 mask 를 씌운 배경색으로 그린다. 강제 색 모드는 배경색을 지우므로 그대로 두면
   아이콘만 보이는 소리 토글과 ✓ ✗ 표식이 사라진다. 시스템 글자색으로 다시 칠한다. */
@media (forced-colors: active) {
  .icon,
  .menu-card__figure::before,
  .category-card__icon::before,
  .challenge-card__icon::before,
  .online-action-card__icon::before,
  .online-panel-heading__icon::before,
  .room-item__icon::before,
  .room-empty__icon::before,
  .result-stats__item::before,
  .menu-card__edit,
  .home-note::before,
  .online-message::before,
  .ranking-scope::before,
  .online-note::before,
  .timer__icon,
  .choice--correct .choice__mark::before,
  .choice--wrong .choice__mark::before,
  .choice--submitted .choice__mark::before,
  .arena-tile--correct .arena-tile__mark,
  .arena-tile--wrong .arena-tile__mark,
  .result-best--new::before,
  .review__tag::before,
  .ranking-empty::before,
  #room-filter-toggle::before,
  .room-item__visibility--private::before,
  .setting-card::after,
  .waiting-ready::before,
  .online-match-status::before,
  .lounge__host,
  .lounge__ready--on::before {
    forced-color-adjust: none;
    background-color: CanvasText;
  }

  /* 캐릭터·마을·가구·액자는 그림이다. 강제 색이 바탕을 지우면 캐릭터가 사라져 걷기를 볼 수 없다 */
  .walker,
  .voxel-scene,
  .lounge__furniture,
  .lounge__portrait,
  .character-card__figure {
    forced-color-adjust: none;
  }

  /* 손가락 조작부는 채움이 지워져도 모양이 남게 시스템 색 테두리를 두른다 */
  .walk-confirm,
  .walk-stick__knob {
    border: var(--border-2) solid ButtonText;
  }

  /* 배지의 흰 data-image는 밝은 강제 색상 배경에서 사라질 수 있다.
     같은 mask를 시스템 글자색으로 다시 그려 판정 글과 함께 남긴다. */
  .feedback--correct .feedback__verdict::before,
  .feedback--wrong .feedback__verdict::before,
  .online-reveal--correct .online-reveal__verdict::before,
  .online-reveal--wrong .online-reveal__verdict::before {
    forced-color-adjust: none;
    background: CanvasText;
    -webkit-mask: var(--badge-icon) center / var(--icon-md) no-repeat;
    mask: var(--badge-icon) center / var(--icon-md) no-repeat;
  }
}

/* 움직임에 민감한 사용자를 위해 OS 설정을 따른다. 캐릭터의 제자리 뛰기도 멈춘다 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── 30. 월드 우선 시각 언어 ─────────────────────────────────────
   배경은 장식 패널이 아니라 모든 화면이 공유하는 실제 게임 공간이다. 흰 표면은 읽거나
   입력해야 하는 순간에만 쓰고, 상시 조작은 어두운 가장자리 HUD 한 벌로 통일한다. */
body {
  background-color: var(--world-sky-2);
  background-image:
    linear-gradient(var(--world-veil), var(--world-veil)),
    var(--world-art-mobile);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
}

body:has([data-screen='home']:not([hidden])) {
  background-image:
    linear-gradient(var(--world-clear), var(--world-clear)),
    var(--world-art-mobile);
}

@media (min-width: 600px), (orientation: landscape) {
  body {
    background-image:
      linear-gradient(var(--world-veil), var(--world-veil)),
      var(--world-art-desktop);
    background-attachment: fixed;
  }

  body:has([data-screen='home']:not([hidden])) {
    background-image:
      linear-gradient(var(--world-clear), var(--world-clear)),
      var(--world-art-desktop);
  }
}

.screen {
  color: var(--text);
}

.app-bar .icon-button {
  border-color: var(--hud-line);
  background: var(--hud-bg);
  color: var(--hud-text);
  box-shadow: var(--elevation-2);
  backdrop-filter: blur(8px);
}

/* 홈 HUD */
.home-player .menu-card--wide,
.home-menu .menu-card {
  border-color: var(--hud-line);
  background: var(--hud-bg);
  color: var(--hud-text);
  box-shadow: var(--elevation-2);
  backdrop-filter: blur(8px);
}

.home-player .menu-card__figure,
.home-menu .menu-card__figure,
.home-player .menu-card__name,
.home-menu .menu-card__name,
.home-player .menu-card__desc,
.home-player .menu-card__edit {
  color: var(--hud-text);
}

.home-player .menu-card__label {
  color: var(--hud-text-muted);
}

.home-player .menu-card__figure {
  background: var(--correct-soft);
  color: var(--correct-ink);
}

.home-menu .menu-card__figure {
  color: var(--gold-soft);
}

.home-menu .menu-card:focus-visible,
.home-menu .menu-card.is-standing,
.home-player .menu-card--wide:focus-visible,
.home-player .menu-card--wide.is-standing {
  border-color: var(--gold-soft);
  background: var(--hud-bg);
  color: var(--hud-text);
}

.home-title,
.home-subtitle {
  color: var(--hud-text);
  text-shadow: var(--world-title-shadow);
}

.home-title {
  font-size: var(--text-4xl);
}

.home-title span {
  color: var(--gold-soft);
}

.home-subtitle {
  font-weight: var(--weight-bold);
}

.home-header {
  border: 0;
  background: transparent;
  box-shadow: none;
}

.home-quests {
  border-color: var(--hud-line);
  border-radius: var(--radius-lg);
  background: var(--hud-bg);
  box-shadow: var(--elevation-2);
  backdrop-filter: blur(8px);
}

.category-card {
  border-color: var(--hud-line);
  border-radius: var(--radius-sm);
  background: var(--world-glass);
  box-shadow: none;
}

.category-card__icon {
  border-radius: var(--radius-xs);
}

.category-card__name {
  color: var(--text);
  font-size: var(--text-xs);
  line-height: var(--leading-tight);
}

.category-card__best {
  gap: 0;
  padding: 0 var(--space-1);
  background: var(--gold-soft);
  color: var(--warning);
  line-height: 16px;
  white-space: nowrap;
}

.category-card__best::before {
  content: '';
  width: 12px;
  height: 12px;
  flex: none;
  background: currentColor;
  -webkit-mask: var(--i-star) center / contain no-repeat;
  mask: var(--i-star) center / contain no-repeat;
}

@media (hover: hover) {
  .category-card:hover:not(:disabled) {
    border-color: var(--gold-soft);
    background: var(--surface);
    box-shadow: none;
  }
}

.category-card.is-standing,
.category-card:focus-visible {
  border-color: var(--gold-soft);
  background: var(--accent-soft);
  box-shadow: none;
}

.challenge-card {
  border-color: var(--primary-action-line);
  border-radius: var(--radius-md);
  background: var(--primary-action);
  color: var(--text);
  box-shadow: var(--press-edge);
}

.challenge-card__icon {
  color: var(--text);
}

.challenge-card__name {
  font-size: var(--text-lg);
}

@media (hover: hover) {
  .challenge-card:hover:not(:disabled) {
    border-color: var(--primary-action-line);
    background: var(--primary-action-hover);
  }
}

/* 온라인은 브랜드 보라, 전체 도전은 골드로 구분하되 크기와 높이는 같다. */
.challenge-card--online {
  border-color: var(--accent-line);
  background: var(--accent);
  color: var(--on-accent);
}

.challenge-card--online .challenge-card__icon {
  color: var(--accent);
}

/* 어두운 dock 밖에서도 키보드 초점과 캐릭터 위치를 색 변화에 기대지 않고 읽는다. */
.home-primary-actions .challenge-card:focus-visible,
.home-primary-actions .challenge-card.is-standing {
  outline-color: var(--hud-text);
}

.home-primary-actions .challenge-card.is-standing {
  background: var(--accent-hover);
  color: var(--on-accent);
}

@media (hover: hover) {
  .challenge-card--online:hover:not(:disabled) {
    border-color: var(--accent-line);
    background: var(--accent-hover);
  }
}

/* 퀴즈 HUD·질문·보기 */
.quiz--character .quiz-hud {
  border-color: var(--hud-line);
  border-radius: var(--radius-lg);
  background: var(--hud-bg);
  color: var(--hud-text);
  box-shadow: var(--elevation-2);
  backdrop-filter: blur(8px);
}

.quiz--character .quiz-category {
  background: var(--gold-soft);
  color: var(--text);
}

.quiz--character .quiz-position,
.quiz--character .timer__label {
  color: var(--hud-text);
}

.quiz--character .progress,
.quiz--character .timer__track {
  background: var(--hud-line);
}

.quiz--character .progress__fill {
  background: var(--correct-soft);
}

.quiz--character .timer__fill {
  background: var(--gold-soft);
}

.quiz--character .arena__help,
.quiz--character .button--ghost {
  border-color: var(--hud-line);
  background: transparent;
  color: var(--hud-text);
}

.quiz--character .question {
  border-color: var(--world-floor-line);
  border-radius: var(--radius-xl);
  background: var(--world-glass);
  color: var(--text);
  box-shadow: var(--elevation-2);
  backdrop-filter: blur(8px);
}

.quiz--character .choice {
  border-color: var(--world-floor-line);
  background: var(--world-glass);
  box-shadow: var(--elevation-1);
  backdrop-filter: blur(8px);
}

.quiz--character .arena__grid {
  border-color: var(--world-floor-line);
  background: var(--world-floor-glass);
  box-shadow: var(--elevation-2);
  backdrop-filter: blur(2px);
}

.quiz--character .arena-tile {
  border-color: var(--world-floor-line);
  background: var(--world-floor-glass);
}

/* 월드 유리 표면보다 채점·제출 상태가 항상 우선한다. 색과 함께 선·표식을 유지한다. */
.quiz--character .choice.choice--correct,
.quiz--character .arena-tile.arena-tile--correct {
  border-color: var(--correct);
  background: var(--correct-soft);
  box-shadow: none;
}

.quiz--character .choice.choice--wrong,
.quiz--character .arena-tile.arena-tile--wrong {
  border-color: var(--wrong);
  background: var(--wrong-soft);
  box-shadow: none;
}

.quiz--character .choice.choice--submitted {
  border-color: var(--gold);
  border-style: dashed;
  background: var(--warning-soft);
  box-shadow: none;
}

.quiz--character .arena-tile__number,
.quiz--character .arena__hint {
  color: var(--hud-text);
  text-shadow: var(--world-title-shadow);
}

/* 결과: 점수는 세계 위에 직접 뜨고 상세 기록부터 표면을 쓴다. */
[data-screen='result'] .result-header {
  border: 0;
  background: transparent;
  box-shadow: none;
  color: var(--hud-text);
  text-shadow: var(--world-title-shadow);
}

[data-screen='result'] .result-header::before,
[data-screen='result'] .result-header::after {
  display: none;
}

[data-screen='result'] .result-mode {
  background: var(--hud-bg-soft);
  color: var(--hud-text);
}

[data-screen='result'] .result-score strong,
[data-screen='result'] .result-score__max,
[data-screen='result'] .result-grade,
[data-screen='result'] .result-grade-message {
  color: var(--hud-text);
}

[data-screen='result'] .result-score strong {
  font-size: var(--text-5xl);
}

[data-screen='result'] .result-best {
  border: var(--border-1) solid var(--hud-line);
  background: var(--hud-bg-soft);
  color: var(--hud-text);
}

.result-stats__item,
.result-block,
.online-final__summary,
.online-final-ranking {
  border-color: var(--world-floor-line);
  background: var(--world-glass);
  backdrop-filter: blur(8px);
}

[data-screen='result'] .result-actions .button--ghost,
[data-screen='online-result'] .result-actions .button--ghost {
  border-color: var(--hud-line);
  background: var(--hud-bg);
  color: var(--hud-text);
}

[data-screen='result'] .result-actions .button--primary,
[data-screen='online-result'] .result-actions .button--primary {
  border-color: var(--primary-action-line);
  background: var(--primary-action);
  color: var(--text);
}

/* 랭킹·캐릭터·온라인·대기실은 같은 월드 위의 상황별 표면이다. */
.ranking-header,
[data-screen='characters'] .quiz-header,
[data-screen='waiting'] > .quiz-header,
.online-hero__header {
  border: var(--border-1) solid var(--hud-line);
  border-radius: var(--radius-lg);
  background: var(--hud-bg);
  color: var(--hud-text);
  box-shadow: var(--elevation-2);
  backdrop-filter: blur(8px);
}

.ranking-header .ranking-title,
[data-screen='characters'] .screen-title,
[data-screen='waiting'] .screen-title,
.online-hero__title,
.online-hero__eyebrow,
.online-hero__lead {
  color: var(--hud-text);
}

.ranking-header .button--ghost,
[data-screen='characters'] .button--ghost,
[data-screen='waiting'] > .quiz-header .button--ghost,
.online-home {
  border-color: var(--hud-line);
  background: transparent;
  color: var(--hud-text);
}

.ranking-scope,
[data-screen='characters'] .screen-lead,
[data-screen='waiting'] > .screen-lead,
.online-note {
  border-color: var(--world-floor-line);
  background: var(--world-glass);
  color: var(--text);
  backdrop-filter: blur(8px);
}

.ranking-tabs,
.ranking-list,
.character-stage,
.online-actions,
.online-block,
.setting-card,
.lounge {
  border-color: var(--world-floor-line);
  background: var(--world-glass-soft);
  backdrop-filter: blur(8px);
}

.ranking-empty {
  border: var(--border-1) solid var(--world-floor-line);
  border-radius: var(--radius-lg);
  background: var(--world-glass);
  color: var(--text);
  box-shadow: var(--elevation-1);
  backdrop-filter: blur(8px);
}

.character-stage {
  border: 0;
  background: transparent;
  box-shadow: none;
  backdrop-filter: none;
}

.character-card {
  border-color: var(--world-floor-line);
  background: var(--world-floor-glass);
  box-shadow: none;
  backdrop-filter: blur(2px);
}

.character-card[aria-pressed='true'],
.character-card.is-standing {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.online-actions {
  border-radius: var(--radius-lg);
  background: var(--hud-bg);
  box-shadow: var(--elevation-2);
}

.online-action-card {
  border-color: var(--hud-line);
  background: transparent;
  color: var(--hud-text);
}

.online-action-card strong,
.online-action-card__copy,
.online-action-card__icon {
  color: var(--hud-text);
}

.online-action-card[aria-pressed='true'] {
  border-color: var(--gold-soft);
  background: var(--hud-bg-soft);
}

.online-block,
.lounge {
  box-shadow: var(--elevation-2);
}

/* 대기실의 라운지는 overlay 카드가 아니라 실제로 걷는 월드 바닥이다. */
[data-screen='waiting'] .lounge {
  background: var(--world-floor-glass);
  box-shadow: var(--elevation-1);
  backdrop-filter: none;
}

.waiting-settings .setting-card {
  background: var(--world-glass);
}

.feedback {
  border-color: var(--world-floor-line);
  background: var(--world-glass);
  backdrop-filter: blur(12px);
}

/* 그림이 지워지는 강제 색상에서는 시스템 표면만 남기고 상태 표식 계약을 유지한다. */
@media (forced-colors: active) {
  body,
  body:has([data-screen='home']:not([hidden])) {
    background: Canvas;
  }

  .home-title,
  .home-subtitle,
  .quiz--character .arena-tile__number,
  .quiz--character .arena__hint,
  [data-screen='result'] .result-header {
    color: CanvasText;
    text-shadow: none;
  }

  .home-player .menu-card--wide,
  .home-menu .menu-card,
  .home-quests,
  .quiz--character .quiz-hud,
  .ranking-header,
  [data-screen='characters'] .quiz-header,
  [data-screen='waiting'] > .quiz-header,
  .online-hero__header,
  .online-actions {
    border-color: CanvasText;
    background: Canvas;
    color: CanvasText;
  }
}

@media (max-width: 420px) {
  .home-title {
    font-size: var(--text-xl);
  }
}

@media (max-height: 500px) {
  .category-card__best {
    position: absolute;
    top: 2px;
    right: 2px;
  }
}
