/* =============================================================================
 * 토룡 — 게임 스타일 (P4)
 *
 * 🔴 왜 ds/v1 을 링크하지 않고 토큰을 여기 복제하는가
 *    PLAN §18: 토룡은 임베디드 앱 전환 대상이라 **네트워크 요청 0개**여야 하고
 *    "`toryong/` 폴더를 통째로 복사하면 동작해야 한다"가 합격 기준이다.
 *    `https://crownyuja.co.kr/ds/v1/yuja.css` 절대 URL은 그 두 조건을 다 깬다.
 *    그래서 **값을 그대로 복제**한다. 포크가 아니라 사본이다 —
 *    ds/v1 의 토큰이 바뀌면 여기도 같이 고친다.
 *
 * 🔴 왜 .yj-shell 구조를 쓰지 않는가
 *    `.yj-shell__body` 는 데스크톱에서 `max-width:720px` 로 조이고 자체 padding 을
 *    갖는다. 이 화면은 **캔버스가 자기 크기를 소유**하는 유형이라(대문 home-scale 과
 *    같은 부류) 셸의 flex/padding 모델과 정면 충돌한다.
 *    디자인 시스템이 허용한 예외 경로대로 **셸의 "값"만 빌리고 "구조"는 안 씌운다.**
 *
 * 폰트도 웹폰트를 부르지 않는다(§18) — 설치돼 있으면 쓰고, 없으면 시스템 폰트다.
 * ========================================================================== */

/* ── ds/v1 토큰 사본 ─────────────────────────────────────────────────────── */
:root {
  /* 브랜드 3색 */
  --yj-amber:        #F5C800;
  --yj-amber-press:  #DDB400;
  --yj-amber-tint:   rgba(245, 200, 0, .16);
  --yj-amber-ink:    #8A6F00;
  --yj-orange:       #F08C1E;
  --yj-orange-press: #D97A0F;
  --yj-orange-tint:  rgba(240, 140, 30, .15);
  --yj-leaf:         #4CAA48;
  --yj-leaf-tint:    rgba(76, 170, 72, .14);
  --yj-leaf-ink:     #2F7A2C;
  --yj-forest:       #142814;

  /* 서피스 */
  --yj-canvas:          #FFFFFF;
  --yj-cream:           #FBFAF6;
  --yj-surface:         #F5F4F0;
  --yj-hairline:        #E8E7E4;

  /* 잉크 */
  --yj-ink-deep: #16181A;
  --yj-ink:      #37352F;
  --yj-slate:    #6F6E69;
  --yj-steel:    #9B9A97;
  --yj-on-dark:  #FFFFFF;

  /* 의미색 */
  --yj-error:      #C82014;
  --yj-error-tint: rgba(200, 32, 20, .10);

  /* radius 4종 */
  --yj-r-xs:   4px;
  --yj-r-sm:   8px;
  --yj-r-lg:   16px;
  --yj-r-full: 9999px;

  /* motion 3종 */
  --yj-m-fast: 120ms;
  --yj-m-mid:  200ms;
  --yj-m-slow: 320ms;
  --yj-ease:   cubic-bezier(.2, .8, .2, 1);

  /* 간격 8단계 */
  --yj-s1:  4px;  --yj-s2:  8px;  --yj-s3: 12px;  --yj-s4: 16px;
  --yj-s5: 24px;  --yj-s6: 32px;  --yj-s7: 48px;  --yj-s8: 64px;

  /* 타이포 */
  --yj-font-ui: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont,
                "Segoe UI", "Malgun Gothic", "Apple SD Gothic Neo", sans-serif;
  --yj-t-body:  17px;
  --yj-t-vocab: 20px;
  --yj-t-cap:   13px;
  --yj-t-label: 11px;

  /* 골격 */
  --yj-dock-h: 56px;
  --yj-tap:    44px;
  --yj-safe-t: env(safe-area-inset-top, 0px);
  --yj-safe-b: env(safe-area-inset-bottom, 0px);
  --yj-safe-l: env(safe-area-inset-left, 0px);
  --yj-safe-r: env(safe-area-inset-right, 0px);

  --yj-sh-card: 0 1px 2px rgba(20,24,16,.05), 0 4px 14px rgba(20,24,16,.05);

  /* ── 토룡 픽셀 팔레트 (PLAN §9-3 — 하드코딩 HEX 금지, 토큰에 추가한다) ──
     스프라이트는 이 토큰들만 참조한다. 캔버스가 getComputedStyle 로 읽어 쓰므로
     여기 값을 바꾸면 아트가 통째로 따라온다 — 색을 코드에 박지 않는 이유다.

     ⚠ 밝기 순서가 곧 명암이다. `-hi`(하이라이트) > 기본 > `-sh`(그늘) > `-edge`(윤곽).
        이 순서를 뒤집으면 픽셀 아트가 평평해 보인다. */

  /* 밭 — 유자 과수원 흙 */
  --yj-px-soil:      #6B4A2F;   /* 짙은 칸 */
  --yj-px-soil-2:    #7A563A;   /* 옅은 칸 */
  --yj-px-soil-dot:  #5A3D26;   /* 흙 알갱이(어두운 점) */
  --yj-px-soil-dot2: #8A6446;   /* 흙 알갱이(밝은 점) */
  --yj-px-grass:     #4CAA48;   /* 잔디 테두리 */
  --yj-px-grass-dk:  #3A8637;   /* 잔디 그늘 */
  --yj-px-fence:     #3E2C1C;   /* 울타리 */

  /* 유자볼 — 먹이·함정 공통(§9-4). 이 다섯 색 밖으로 나가지 않는다. */
  --yj-px-ball:      #F5C800;
  --yj-px-ball-hi:   #FFE873;   /* 왼쪽 위 광택 */
  --yj-px-ball-sh:   #D9A800;   /* 오른쪽 아래 그늘 */
  --yj-px-ball-edge: #A67C00;   /* 윤곽 */
  /* 🔴 꼭지는 **흙과 다른 색**이어야 한다. 갈색으로 두면 흙(--yj-px-soil #6B4A2F)과
     값이 같아져 배경에 그대로 묻힌다(P7 실측에서 꼭지가 아예 안 보였다).
     진한 초록이면 흙 위에서도 또렷하고 잎과도 이어져 "열매"로 읽힌다. */
  --yj-px-stem:      #2D6B2A;   /* 꼭지 */

  /* 토룡 */
  --yj-px-worm:      #E07B2C;   /* 몸통 */
  --yj-px-worm-hi:   #F7A863;   /* 몸통 광택 */
  --yj-px-worm-sh:   #B85F1C;   /* 몸통 그늘 */
  --yj-px-worm-edge: #8A4512;   /* 윤곽 */
  --yj-px-worm-head: #F5A44E;   /* 머리 */
  --yj-px-eye:       #2A1A0C;   /* 눈 */
  --yj-px-crown:     #F5C800;   /* 왕관 */
  --yj-px-crown-sh:  #C79E00;   /* 왕관 그늘 */
}

/* ── 골격 ────────────────────────────────────────────────────────────────── */
* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  /* 🔴 100vh 금지 — 모바일 하단바 겹침의 1차 원인 */
  min-height: 100dvh;
}

/* 🔴 게임 화면은 **절대 스크롤되지 않는다.** 그래서 상한도 못박는다.
   `min-height` 만 주면 하한만 정해질 뿐이라 내용이 그보다 커지면 body 가 따라 자란다.
   그러면 "남은 공간"이라는 개념이 사라져서 캔버스 높이 → 셸 높이 → 캔버스 높이로
   되먹임이 생기고, 잴 때마다 답이 달라진다.
   P4 에서 실제로 터졌다: 앱(도크바 60px)에서 행 수가 13이 아니라 16으로 잡혀
   격자가 도크바 아래로 48px 내려가고 페이지가 세로로 스크롤됐다.
   상한을 주는 순간 셸이 "남은 공간"을 받게 되고 되먹임이 끊긴다. */
body {
  max-height: 100dvh;
  overflow: hidden;
}
@supports not (min-height: 100dvh) {   /* 구형 WebView 폴백 */
  html, body { min-height: 100vh; }
  body { max-height: 100vh; }
}

body {
  background: var(--yj-forest);
  color: var(--yj-on-dark);
  font-family: var(--yj-font-ui);
  font-size: var(--yj-t-body);
  letter-spacing: -0.01em;
  display: flex;
  justify-content: center;
  align-items: stretch;
  /* 게임 중 스크롤·당겨서 새로고침·핀치줌을 전부 죽인다(§8-6).
     안 막으면 위로 꺾다가 새로고침돼 판이 통째로 날아간다. */
  overscroll-behavior: none;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  padding-top: var(--yj-safe-t);
  padding-left: var(--yj-safe-l);
  padding-right: var(--yj-safe-r);
}

/* 🔴 §8-6 — 앱 WebView 는 하단 60px 을 도크바가 먹는다.
   `yj-env-app` 일 때만 그만큼 비운다. `@media (display-mode: standalone)` 을
   새로 쓰지 않는다 — 판정 축이 둘로 갈라지면 조용히 어긋난다(tier.js 주석). */
.yj-env-app body {
  padding-bottom: calc(60px + var(--yj-safe-b));
}

/* ── 좌우 장식 패널 ───────────────────────────────────────────────────────
   격자 폭은 셀 상한(44px) 때문에 ~440px 에서 멈춘다(G4). 화면이 그보다 넓으면
   남는 좌우를 빈 배경으로 두지 않는다. 실제 유자밭 픽셀 아트는 P7. */
.tr-side {
  display: none;
  flex: 1 1 0;
  min-width: 0;
  max-width: 280px;
  background:
    repeating-linear-gradient(90deg, transparent 0 38px, rgba(255,255,255,.03) 38px 40px),
    linear-gradient(180deg, #1B331B, var(--yj-forest));
}
@media (min-width: 700px) { .tr-side { display: block; } }

.tr-shell {
  width: 100%;
  max-width: 430px;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* ── HUD ─────────────────────────────────────────────────────────────────── */
.tr-hud {
  height: var(--yj-dock-h);
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--yj-s3);
  padding: 0 var(--yj-s3);
}
.tr-hud__lives { display: flex; gap: 2px; flex: 0 0 auto; }
.tr-hud__lives svg { width: 18px; height: 18px; display: block; }
.tr-hud__heart      { color: var(--yj-error); }
.tr-hud__heart--off { color: rgba(255,255,255,.22); }

/* 스테이지 이름(훈음)은 이 화면의 주인공이다 — 목표를 잊으면 게임이 무의미해진다(§9-7) */
.tr-hud__stage {
  font-size: var(--yj-t-vocab);
  font-weight: 800;
  letter-spacing: -0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tr-hud__right {
  margin-left: auto;
  display: flex;
  align-items: baseline;
  gap: var(--yj-s2);
  font-size: var(--yj-t-cap);
  color: rgba(255,255,255,.72);
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
}
.tr-hud__score { color: var(--yj-amber); font-weight: 700; }
.tr-hud__combo { color: var(--yj-orange); font-weight: 700; }
.tr-hud__combo[hidden] { display: none; }

/* ── 힌트 잔류 슬롯 (H4 — 머리 위 플로팅을 놓쳤으면 여기서 3초 더 읽는다) ── */
.tr-hintslot {
  height: 28px;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--yj-s2);
  padding: 0 var(--yj-s3);
  font-size: var(--yj-t-cap);
  color: rgba(255,255,255,.62);
  white-space: nowrap;
  overflow: hidden;
}
.tr-hintslot__word { color: var(--yj-on-dark); font-weight: 700; }
.tr-mark { width: 14px; height: 14px; flex: 0 0 auto; display: block; }
.tr-mark--feed { color: var(--yj-leaf); }
.tr-mark--trap { color: var(--yj-error); }

/* ── 밭 ──────────────────────────────────────────────────────────────────── */
/* 🔴 `flex: 1 1 0` — basis 를 `auto` 로 두면 안 된다.
   `auto` 는 flex 기준 크기를 **내용(캔버스) 높이**로 잡는데, 그 캔버스 높이는
   이 컨테이너를 재서 정해진다. 서로가 서로를 정하는 되먹임이 생겨서
   측정할 때마다 다른 답이 나온다 — P4 에서 실제로 터졌다:
   앱(도크바 60px) 환경에서 행 수가 14가 아니라 16으로 잡혀 격자가 도크바 아래로
   48px 내려가고 페이지가 세로로 스크롤됐다.
   basis 를 0 으로 두면 높이가 **남은 공간만으로** 정해져 캔버스와 무관해진다.

   `overflow:hidden` 은 마지막 방어선이다. 계산이 어긋나도 페이지를 스크롤시키지 않는다. */
.tr-field {
  flex: 1 1 0;
  position: relative;
  min-height: 0;
  overflow: hidden;
  padding: 0 var(--yj-s2) var(--yj-s2);
}
/* 🔴 G4-1 — 캔버스에 width:100% 를 주지 않는다. CSS 폭이 격자 논리폭과 어긋나면
   가로로만 늘어나고(P2 실측 1.0118배) 정수 배율 스케일링이 깨진다.
   크기는 layout.js 가 px 로 못박는다. */
.tr-field__canvas {
  display: block;
  margin: 0 auto;
  image-rendering: pixelated;
  image-rendering: -webkit-optimize-contrast;   /* 구형 WebView */
  border-radius: var(--yj-r-sm);
}
/* 라벨 레이어는 캔버스와 정확히 같은 사각형에 얹는다(위치는 layout.js 가 px 로 준다) */
.tr-field__labels { position: absolute; pointer-events: none; }

.tr-label {
  position: absolute;
  transform: translate(-50%, 0);
  background: rgba(10, 16, 8, .88);
  border: 1px solid rgba(255,255,255,.18);
  border-radius: var(--yj-r-xs);
  padding: 2px 6px;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  white-space: nowrap;
  color: var(--yj-on-dark);
}

/* 힌트 — 토룡 머리 위에 뜬다(H1). 시선이 이미 거기 있으므로 옮기지 않아도 읽힌다. */
.tr-hint {
  position: absolute;
  transform: translate(-50%, -100%);
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: var(--yj-t-cap);
  font-weight: 800;
  white-space: nowrap;
  text-shadow: 0 1px 3px rgba(0,0,0,.9);
}
.tr-hint--feed { color: var(--yj-leaf); }
.tr-hint--trap { color: var(--yj-error); }

/* ── D패드 (I9 — 격자 "위" 반투명 오버레이) ──────────────────────────────
   🔴 위치는 layout.js 가 격자에 맞춰 px 로 준다. 컨테이너 바닥에 붙이면
   세로로 긴 화면에서 격자 밖으로 떨어진다(P2 실측 768×1024). */
.tr-dpad {
  position: absolute;
  width: 168px;
  height: 168px;
  opacity: .45;
  display: grid;
  grid-template-columns: repeat(3, 56px);
  grid-template-rows: repeat(3, 56px);
  touch-action: none;
}
.tr-dpad[hidden] { display: none; }

/* 🔴 버튼 실치수 = 트랙 그대로 56px. `margin` 을 주면 트랙을 갉아 52px 이 된다
   (P2 실측). 십자 배치라 상하좌우가 변을 공유하지 않아 gap 없이도 오입력이 없다. */
.tr-dpad__btn {
  background: rgba(255,255,255,.22);
  border: 1px solid rgba(255,255,255,.32);
  border-radius: var(--yj-r-sm);
  color: var(--yj-on-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--yj-m-fast) var(--yj-ease),
              transform var(--yj-m-fast) var(--yj-ease);
}
.tr-dpad__btn svg { width: 24px; height: 24px; }
.tr-dpad__btn:active { background: rgba(255,255,255,.5); transform: scale(.97); }
.tr-dpad__spacer { background: none; border: none; }

/* ── 덮개 (밭 훑기 · 일시정지 · 결과) ────────────────────────────────────── */
.tr-veil {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--yj-s4);
  padding: var(--yj-s5);
  text-align: center;
  background: rgba(10, 16, 8, .88);
}
.tr-veil[hidden] { display: none; }
.tr-veil__title { font-size: 22px; font-weight: 800; letter-spacing: -0.02em; }
.tr-veil__body  { font-size: var(--yj-t-cap); line-height: 1.7; color: rgba(255,255,255,.72); }
.tr-veil__body b { color: var(--yj-on-dark); }
.tr-veil__row { display: flex; gap: var(--yj-s2); flex-wrap: wrap; justify-content: center; }

/* 버튼 5종 밖으로 나가지 않는다. 화면당 primary 는 1개.
   앰버 위 글자는 항상 잉크다 — 흰 글자는 대비 1.6:1 로 읽을 수 없다. */
.yj-btn {
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  min-height: var(--yj-tap);
  padding: 0 20px;
  border: none;
  border-radius: var(--yj-r-sm);
  cursor: pointer;
  transition: filter var(--yj-m-fast) var(--yj-ease),
              transform var(--yj-m-fast) var(--yj-ease);
}
.yj-btn:hover  { filter: brightness(.96); }
.yj-btn:active { transform: scale(.97); }
.yj-btn:focus-visible { outline: 2px solid var(--yj-on-dark); outline-offset: 2px; }

.yj-btn--primary {
  background: var(--yj-amber);
  color: var(--yj-ink-deep);
  border-radius: var(--yj-r-full);
  min-height: 52px;
  padding: 0 24px;
}
.yj-btn--secondary { background: var(--yj-amber-tint); color: var(--yj-amber); }
.yj-btn--ghost     { background: none; color: rgba(255,255,255,.66); }

/* 밭 훑기 카운트다운 (R2) */
.tr-preview { pointer-events: none; background: rgba(10, 16, 8, .35); }
.tr-preview__count {
  font-size: 56px;
  font-weight: 900;
  color: var(--yj-amber);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

/* 🔴 I8 — 일시정지 중에는 밭을 가린다. 멈춰놓고 어휘를 다 읽으면 밭 훑기(R2)와
   난이도가 통째로 무의미해진다. 쉬는 것은 되고, 읽는 것은 안 된다.
   backdrop-filter 는 쓰지 않는다(교실 저사양 기기에서 프레임이 무너진다) —
   불투명 덮개로 가린다. 가릴 수 없으면 투명하지 않는 것이 답이다. */
.tr-veil--pause { background: rgba(10, 16, 8, .97); }

.tr-diag {
  flex: 0 0 auto;
  padding: var(--yj-s1) var(--yj-s3) var(--yj-s2);
  font-size: var(--yj-t-label);
  color: rgba(255,255,255,.38);
  line-height: 1.5;
}
.tr-diag[hidden] { display: none; }

.tr-sr {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * 로비 (P5)
 *
 * 게임 화면과 성격이 정반대다 — 저기는 스크롤이 없는 캔버스, 여기는 스크롤되는
 * 목록이다. 그래서 body 규칙을 되돌린다(아래 .tr-lobbypage).
 * ═══════════════════════════════════════════════════════════════════════════ */
body.tr-lobbypage {
  display: block;
  background: var(--yj-cream);
  color: var(--yj-ink);
  /* 게임 화면의 스크롤 차단을 로비에서는 풀어 준다 */
  max-height: none;
  overflow: visible;
  touch-action: auto;
  user-select: auto;
  -webkit-user-select: auto;
}
.tr-lobbypage .tr-lobby { max-width: 560px; margin: 0 auto; }

/* 🔴 `.yj-btn--ghost` 는 게임 화면(어두운 배경)을 기준으로 `rgba(255,255,255,.66)` 로
   정의돼 있다. 로비는 밝은 카드 배경이라 그대로 쓰면 흰 글자가 흰 카드 위에서 거의
   안 보인다(실측: "새로 시작" 버튼, 대비 사실상 0). 버튼 5종 표의 ghost 정의
   ("배경 없음 · 회색 글자")대로 밝은 컨텍스트에서는 회색으로 되돌린다. */
.tr-lobbypage .yj-btn--ghost { color: var(--yj-slate); }

/* 🔴 상단바 — 유자볼·유자스핀 로비(yujaball/index.html·yuzaball2/index.html)의
   header 와 같은 처리로 맞춘다(2026-08-18). 색은 **주황**을 쓴다 — 디자인 시스템의
   토큰 역할표가 `--yj-orange` 를 "놀이/게임" 용도로 명시했고, 유자볼(노랑 계열)·
   유자스핀(보라 계열)과 겹치지 않아 "놀이탭 안에서 이 게임"임을 색으로도 구분한다.
   앰버·주황 위 글자는 항상 잉크다(대비 규칙) — 흰 글자는 1.6:1로 안 읽힌다. */
.tr-topbar {
  height: var(--yj-dock-h);
  background: var(--yj-orange);
  color: var(--yj-ink-deep);
  display: flex;
  align-items: center;
  gap: var(--yj-s2);
  padding: 0 var(--yj-s3);
}
.tr-topbar__title {
  font-size: var(--yj-t-vocab);
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--yj-ink-deep);
}
/* 버튼 5종 중 icon — 원형 44×44, aria-label 필수 */
.yj-btn--icon {
  width: var(--yj-tap);
  height: var(--yj-tap);
  min-height: var(--yj-tap);
  padding: 0;
  border-radius: var(--yj-r-full);
  background: none;
  color: var(--yj-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  transition: background var(--yj-m-fast) var(--yj-ease);
}
.yj-btn--icon svg { width: 24px; height: 24px; }
/* 상단바 안에서는 배경색 위 아이콘이라 살짝 눌린 느낌의 원형 배경을 준다
   (유자볼 #infoBtn 과 같은 처리 — rgba 흰색 14%). */
.tr-topbar .yj-btn--icon {
  background: rgba(255, 255, 255, .16);
  color: var(--yj-ink-deep);
}
.tr-topbar .yj-btn--icon:hover  { background: rgba(255, 255, 255, .3); }
.tr-topbar .yj-btn--icon:active { transform: scale(.94); }

.tr-lobby__body {
  padding: 0 var(--yj-s4) calc(var(--yj-s8) + var(--yj-safe-b));
  display: flex;
  flex-direction: column;
  gap: var(--yj-s4);
}
.tr-lobby__lede {
  font-size: var(--yj-t-cap);
  line-height: 1.7;
  color: var(--yj-slate);
}
.tr-lobby__lede b { color: var(--yj-ink-deep); }

/* 카드 — 넓은 면은 틴트로, 원색은 점으로 */
.tr-card {
  background: var(--yj-canvas);
  border: 1px solid var(--yj-hairline);
  border-radius: var(--yj-r-lg);
  padding: var(--yj-s4);
  display: flex;
  flex-direction: column;
  gap: var(--yj-s3);
}
.tr-card__title {
  font-size: var(--yj-t-vocab);
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--yj-ink-deep);
}
.tr-card__note { font-size: var(--yj-t-cap); color: var(--yj-slate); line-height: 1.6; }

/* 세그먼트 — 새 버튼 종류를 만들지 않는다.
   🔴 유자볼·유자스핀의 `.seg` 와 같은 조형으로 맞춘다: 흰 필 컨테이너 하나 안에
   버튼들이 들어가고, 선택된 것만 **원색으로 꽉 채운다**(틴트가 아니라 solid).
   이건 "화면당 primary 1개" 규칙과 충돌하지 않는다 — primary 는 CTA 버튼을 가리키고,
   세그먼트의 선택 표시는 유자볼·유자스핀에서 이미 쓰던 별도 관용구다. */
.tr-seg {
  display: flex;
  gap: 3px;
  background: var(--yj-canvas);
  padding: 3px;
  border-radius: var(--yj-r-lg);
  border: 1px solid var(--yj-hairline);
}
.tr-seg--wrap { flex-wrap: wrap; }
.tr-seg[hidden] { display: none; }
.tr-seg__btn {
  flex: 1 1 auto;
  min-height: var(--yj-tap);
  padding: var(--yj-s2) var(--yj-s3);
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  color: var(--yj-slate);
  background: transparent;
  border: none;
  border-radius: var(--yj-r-sm);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  transition: background var(--yj-m-fast) var(--yj-ease),
              color var(--yj-m-fast) var(--yj-ease);
}
.tr-seg__btn.is-on {
  background: var(--yj-orange);
  color: var(--yj-ink-deep);
}
.tr-seg__btn:active { transform: scale(.97); }
.tr-seg__btn:focus-visible { outline: 2px solid var(--yj-ink-deep); outline-offset: 2px; }
.tr-seg__label { font-size: 15px; }
.tr-hearts { display: inline-flex; gap: 1px; color: var(--yj-error); }
.tr-hearts svg { width: 11px; height: 11px; display: block; }

/* 연번 칩 — 화면에는 훈음만 나간다(O1)
   🔴 유자볼의 `.lv` 레벨 버튼과 같은 조형: 기본은 흰 배경 + 옅은 테두리이고,
   원색(주황 틴트)은 "이미 완료" 같은 상태 표시에만 쓴다 — 원색은 점으로,
   틴트는 면으로(§2-2)가 아니라 여기서는 그 반대로 "튀지 않는 기본값"이 필요해서
   흰 바탕을 쓴다. hover 시 살짝 떠오르는 것도 `.lv:hover`와 같다. */
.tr-stages {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: var(--yj-s2);
}
.tr-stage {
  min-height: var(--yj-tap);
  padding: var(--yj-s2) var(--yj-s3);
  border-radius: var(--yj-r-sm);
  background: var(--yj-canvas);
  border: 1px solid var(--yj-hairline);
  color: var(--yj-ink-deep);
  text-decoration: none;
  font-weight: 700;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  text-align: center;
  transition: border-color var(--yj-m-fast) var(--yj-ease),
              transform var(--yj-m-fast) var(--yj-ease);
}
.tr-stage:hover  { border-color: var(--yj-orange); transform: translateY(-1px); }
.tr-stage:active { transform: scale(.97); }
.tr-stage:focus-visible { outline: 2px solid var(--yj-ink-deep); outline-offset: 2px; }
.tr-stage__huneum { font-size: 16px; letter-spacing: -0.02em; }

/* R6 — 플레이 불가 연번. 숨기지 않고 사유를 적는다.
   자물쇠 아이콘은 쓰지 않는다 — 잠긴 게 아니라 원래 안 나오는 것이다. */
.tr-stage--off {
  background: var(--yj-surface);
  color: var(--yj-steel);
  cursor: not-allowed;
}
.tr-stage__why { font-size: var(--yj-t-label); font-weight: 500; }

@media (prefers-reduced-motion: reduce) {
  .tr-seg__btn, .tr-stage { transition: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * 순위표 · 게스트 (P6, GAME_RULES §15 V)
 * ═══════════════════════════════════════════════════════════════════════════ */
.tr-best__row { display: flex; align-items: center; justify-content: space-between; gap: var(--yj-s3); }
.tr-best__score { display: flex; flex-direction: column; gap: 2px; }
.tr-best__label { font-size: var(--yj-t-cap); color: var(--yj-slate); font-weight: 700; }
.tr-best__value { font-size: 22px; font-weight: 800; color: var(--yj-ink-deep); letter-spacing: -0.02em; }

.tr-guestname { margin-top: var(--yj-s1); }
.tr-guestname__input {
  width: 100%;
  min-height: var(--yj-tap);
  padding: 0 var(--yj-s3);
  font: inherit;
  font-size: 15px;
  border: 1px solid var(--yj-hairline);
  border-radius: var(--yj-r-sm);
  background: var(--yj-surface);
  color: var(--yj-ink-deep);
}
.tr-guestname__input:focus-visible { outline: 2px solid var(--yj-ink-deep); outline-offset: 1px; }

/* 모달 — 순위표. backdrop-filter 는 안 쓴다(§6 저사양 기기 프레임 드랍) */
.tr-modal {
  position: fixed; inset: 0; z-index: 10;
  display: flex; align-items: flex-end; justify-content: center;
  background: rgba(20, 24, 16, .55);
  padding: 0;
}
.tr-modal[hidden] { display: none; }
.tr-modal__sheet {
  width: 100%; max-width: 560px;
  max-height: 82dvh;
  overflow-y: auto;
  background: var(--yj-canvas);
  border-radius: var(--yj-r-lg) var(--yj-r-lg) 0 0;
  padding: var(--yj-s4);
  padding-bottom: calc(var(--yj-s4) + var(--yj-safe-b));
  display: flex; flex-direction: column; gap: var(--yj-s3);
}
.tr-modal__head { display: flex; align-items: center; justify-content: space-between; }
.tr-modal__title { font-size: var(--yj-t-vocab); font-weight: 800; color: var(--yj-ink-deep); }

.tr-board { list-style: none; display: flex; flex-direction: column; gap: var(--yj-s1); }
.tr-board__row {
  display: flex; align-items: center; gap: var(--yj-s2);
  padding: var(--yj-s2) var(--yj-s3);
  border-radius: var(--yj-r-sm);
  background: var(--yj-surface);
}
.tr-board__row--self { background: var(--yj-amber-tint); }
.tr-board__rank { width: 22px; flex: 0 0 auto; font-weight: 800; color: var(--yj-slate); text-align: center; }
.tr-board__name { flex: 1 1 auto; font-weight: 700; color: var(--yj-ink-deep); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tr-board__meta { flex: 0 0 auto; display: flex; align-items: center; gap: var(--yj-s2); font-size: var(--yj-t-cap); color: var(--yj-slate); }
.tr-board__score { font-weight: 800; color: var(--yj-ink-deep); font-variant-numeric: tabular-nums; }
.tr-board__badge { font-size: 10px; font-weight: 800; padding: 1px 6px; border-radius: var(--yj-r-full); }
.tr-board__badge--easy { background: var(--yj-leaf-tint); color: var(--yj-leaf-ink); }
.tr-board__badge--mid  { background: var(--yj-orange-tint); color: var(--yj-orange-ink); }
.tr-board__badge--hard { background: var(--yj-error-tint); color: var(--yj-error); }
.tr-board__del {
  flex: 0 0 auto;
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; border-radius: var(--yj-r-full);
  color: var(--yj-steel); cursor: pointer;
}
.tr-board__del svg { width: 16px; height: 16px; }
.tr-board__del:hover { color: var(--yj-error); background: var(--yj-error-tint); }
.tr-board__empty { padding: var(--yj-s4); text-align: center; color: var(--yj-slate); font-size: var(--yj-t-cap); }

/* 접근성 — 움직임을 줄이라고 한 사용자에게는 전환을 끈다.
   게임 자체는 실시간이라 멈출 수 없지만, UI 전환은 줄일 수 있다. */
@media (prefers-reduced-motion: reduce) {
  .yj-btn, .tr-dpad__btn { transition: none; }
}
