:root {
  --a11y-hit: 48px;
  --a11y-root-size: 16px;
  --a11y-secondary: rgba(244, 231, 202, 0.62);
}

html[data-text-scale="100"] { --a11y-root-size: 16px; --a11y-scale: 1; }
html[data-text-scale="130"] { --a11y-root-size: 20.8px; --a11y-scale: 1.3; }
html[data-text-scale="200"] { --a11y-root-size: 32px; --a11y-scale: 2; }

html { font-size: var(--a11y-root-size); }

body.artbg #home::before {
  left: 0;
  right: 0;
}

.scene.art-v2[data-adaptive-phase="choice"] .scene-msg:has(.adaptive-choice),
.scene.art-v2[data-adaptive-phase="route"] .scene-msg:has(.adaptive-choice) {
  left: 0;
  right: 0;
  transform: none;
}

html[data-text-scale="130"] .screen,
html[data-text-scale="200"] .screen {
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
}

[hidden] { display: none !important; }

[inert] {
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}

[inert] * {
  animation-play-state: paused !important;
}

.accessibility-btn,
.route-action,
#boardA11yGrid > button,
.accessibility-choice,
.save-recovery-action {
  min-width: var(--a11y-hit);
  min-height: var(--a11y-hit);
}

.accessibility-mark {
  display: inline-grid;
  width: 30px;
  height: 24px;
  place-items: center;
  border-top: 1px solid var(--electric-cyan);
  border-bottom: 1px solid var(--brass-42);
  color: var(--warm-ivory);
  font-size: 0.75rem;
  font-weight: 900;
  letter-spacing: -0.08em;
  line-height: 1;
}

.home-tools {
  min-width: 0;
  flex-wrap: wrap;
}

.boardwrap > canvas {
  max-width: 100%;
  max-height: 100%;
}

.boardwrap {
  overflow: hidden;
}

.tap-route-controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 6;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 6px;
  padding: 6px;
  border: 1px solid var(--ivory-16);
  border-radius: 2px;
  background: rgba(7, 10, 16, 0.96);
  box-shadow: 0 -8px 24px rgba(7, 10, 16, 0.62);
}

html[data-input-mode="tap"][data-board-mode="visual"] .tap-route-controls {
  display: grid !important;
}

html[data-input-mode="tap"][data-board-mode="visual"] .boardwrap {
  padding-bottom: 62px;
}

.tap-route-status {
  min-width: 0;
  color: var(--ivory-72);
  font-size: 0.75rem;
  font-weight: 750;
  line-height: 1.25;
  text-align: center;
  overflow-wrap: anywhere;
}

.route-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px 10px;
  border: 1px solid var(--ivory-16);
  border-radius: 2px;
  background: var(--surface-1);
  color: var(--warm-ivory);
  font: 850 0.78rem/1.2 "Noto Sans KR", system-ui, sans-serif;
  cursor: pointer;
}

.route-action.primary {
  border-color: var(--brass-42);
  background: var(--brushed-brass);
  color: var(--vault-black);
}

.route-action.secondary {
  border-color: var(--cyan-42);
  color: var(--electric-cyan);
}

.route-action:disabled {
  border-color: var(--ivory-09);
  background: var(--surface-0);
  color: var(--ivory-48);
  cursor: not-allowed;
}

.route-action:focus-visible,
#boardA11yGrid > button:focus-visible,
.accessibility-choice:focus-visible,
.save-recovery-action:focus-visible {
  outline: 3px solid var(--electric-cyan);
  outline-offset: 2px;
}

/* D6: 텍스트 보드는 시각 보드의 고정 슬롯을 쓰지 않는다. 내부 스크롤 대신
   자연 높이로 흐르고, 스크롤은 #game(화면)이 담당한다 */
.board-a11y {
  position: relative;
  z-index: 3;
  width: min(100%, 38rem);
  max-height: none;
  min-height: 0;
  margin: auto;
  padding: 12px;
  overflow: visible;
  border: 1px solid var(--ivory-16);
  border-radius: 2px;
  background: var(--surface-0);
  box-shadow: inset 0 0 0 1px rgba(99, 217, 242, 0.08);
  color: var(--warm-ivory);
  scrollbar-color: var(--cyan-42) transparent;
}

html[data-board-mode="text"] #board {
  display: none;
}

html[data-board-mode="text"] #boardA11y {
  display: grid !important;
  grid-template-rows: auto auto auto auto;
  gap: 10px;
}

html[data-board-mode="text"] .boardwrap {
  flex: 0 0 auto;
  align-items: stretch;
  padding-bottom: 0;
  overflow: visible;
}

/* 캔버스 연출용 스윕 레이어(±22% 돌출 절대배치)는 텍스트 모드에서 유령 가로
   오버플로만 만든다. overflow:visible 전환과 짝으로 반드시 끈다 */
html[data-board-mode="text"] .boardwrap::before,
html[data-board-mode="text"] .boardwrap::after {
  content: none;
}

html[data-board-mode="text"] #game {
  overflow-y: auto;
}

.board-a11y-head {
  display: grid;
  gap: 4px;
}

.board-a11y-head h2 {
  margin: 0;
  color: var(--warm-ivory);
  font-size: 1rem;
  font-weight: 900;
  line-height: 1.25;
}

.board-a11y-head p {
  margin: 0;
  color: var(--ivory-72);
  font-size: 0.75rem;
  line-height: 1.45;
  overflow-wrap: anywhere;
}

.board-a11y-grid {
  display: grid;
  grid-template-columns: repeat(var(--board-size, 3), minmax(var(--a11y-hit), 1fr));
  align-content: start;
  gap: 7px;
  min-height: 0;
}

#boardA11yGrid > button {
  position: relative;
  display: grid;
  grid-template-rows: auto auto;
  place-items: center;
  gap: 2px;
  /* aspect-ratio 강제 금지: 행 트랙보다 커진 셀이 다음 행을 덮었다(D6) */
  min-height: max(var(--a11y-hit), calc(var(--a11y-hit) * var(--a11y-scale, 1)));
  padding: 5px;
  overflow: hidden;
  border: 1px solid var(--ivory-16);
  border-radius: 2px;
  background: var(--surface-1);
  color: var(--warm-ivory);
  font: 850 0.76rem/1.1 "Noto Sans KR", system-ui, sans-serif;
}

#boardA11yGrid > button .node-index {
  color: inherit;
  font-size: 1em;
  font-variant-numeric: tabular-nums;
}

#boardA11yGrid > button .node-flags {
  max-width: 100%;
  color: var(--ivory-72);
  font-size: 0.75rem;
  font-weight: 750;
  line-height: 1.15;
  text-align: center;
  overflow-wrap: anywhere;
}

#boardA11yGrid > button[data-node-state~="required"] {
  border-color: var(--brass-42);
  box-shadow: inset 0 0 0 1px rgba(216, 166, 74, 0.14);
}

#boardA11yGrid > button[data-node-state~="sensor"] {
  border-color: var(--coral-42);
  border-style: dashed;
}

#boardA11yGrid > button[aria-pressed="true"] {
  border-color: var(--electric-cyan);
  background: var(--surface-2);
  box-shadow: inset 0 -4px var(--electric-cyan);
}

#boardA11yGrid > button[aria-disabled="true"],
#boardA11yGrid > button:disabled {
  opacity: 0.52;
}

.route-actions {
  position: static;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 7px;
  padding-top: 6px;
}

.board-a11y-status {
  min-height: 1.5em;
  margin: 0;
  color: var(--ivory-72);
  font-size: 0.75rem;
  font-weight: 750;
  line-height: 1.4;
  text-align: center;
  overflow-wrap: anywhere;
}

html[data-board-mode="text"] .scene {
  min-height: 48px !important;
  padding: 6px 8px !important;
}

html[data-board-mode="text"] .scene-bg,
html[data-board-mode="text"] .scene-open-bg,
html[data-board-mode="text"] .scene-guard-bg,
html[data-board-mode="text"] .scene-cinema,
html[data-board-mode="text"] .door-slot,
html[data-board-mode="text"] .bag {
  display: none !important;
}

html[data-board-mode="text"] .scene .scene-msg {
  position: static !important;
  width: 100%;
  max-width: none;
  padding: 5px 7px;
  transform: none !important;
  border-left-color: var(--electric-cyan);
  background: transparent;
  font-size: 0.75rem;
  line-height: 1.35;
}

.accessibility-settings,
.save-recovery-settings {
  display: grid;
  gap: 14px;
  font-size: 1rem;
}

.accessibility-setting-group,
.save-recovery-setting-group {
  display: grid;
  gap: 7px;
  margin: 0;
  padding: 0;
  border: 0;
}

.accessibility-setting-group legend,
.save-recovery-setting-group h3 {
  margin: 0;
  color: var(--warm-ivory);
  font-size: 0.82rem;
  font-weight: 900;
  line-height: 1.3;
}

.accessibility-setting-group p,
.save-recovery-setting-group p {
  margin: 0;
  color: var(--ivory-72);
  font-size: 0.75rem;
  line-height: 1.45;
}

.accessibility-choices,
.save-recovery-actions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  gap: 7px;
}

.accessibility-choice,
.save-recovery-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 9px 10px;
  border: 1px solid var(--ivory-16);
  border-radius: 2px;
  background: var(--surface-1);
  color: var(--ivory-72);
  font-size: 0.75rem;
  font-weight: 850;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
}

.accessibility-choice[aria-pressed="true"],
.accessibility-choice[aria-checked="true"] {
  border-color: var(--electric-cyan);
  background: var(--surface-2);
  box-shadow: inset 0 -3px var(--electric-cyan);
  color: var(--warm-ivory);
}

.save-recovery-action.primary {
  border-color: var(--brass-42);
  color: var(--brushed-brass);
}

.save-code-label {
  color: var(--warm-ivory);
  font-size: 0.75rem;
  font-weight: 850;
  line-height: 1.3;
}

.save-code-input {
  width: 100%;
  min-height: 5.5rem;
  resize: vertical;
  padding: 9px 10px;
  overflow-wrap: anywhere;
  border: 1px solid var(--ivory-16);
  border-radius: 2px;
  background: var(--surface-1);
  color: var(--warm-ivory);
  font: 650 0.75rem/1.4 ui-monospace, "Cascadia Mono", Consolas, monospace;
}

.save-code-input:focus-visible {
  outline: 3px solid var(--electric-cyan);
  outline-offset: 2px;
}

.save-recovery-status,
.save-import-warning {
  min-height: 1.5em;
  margin: 0;
  color: var(--ivory-72);
  font-size: 0.75rem;
  line-height: 1.45;
  overflow-wrap: anywhere;
}

.save-recovery-status.bad,
.save-import-warning {
  color: var(--alarm-coral);
}

.overlay:not(.hidden) {
  display: flex;
}

.panel {
  scroll-padding-bottom: calc(var(--a11y-hit) + 24px);
}

.panel .p-btns,
.panel .modal-actions {
  position: sticky;
  bottom: -1px;
  z-index: 5;
  padding-top: 10px;
  padding-bottom: 2px;
  background: linear-gradient(180deg, transparent, var(--surface-0) 14px);
}

/* 접근성 설정 패널: 200% 배율에서 sticky 완료 버튼이 옵션을 덮는다 → 정적 footer */
.panel[data-panel-kind="accessibility"] .p-btns {
  position: static;
  z-index: auto;
  background: none;
}

.panel :where(button, [role="button"]) {
  min-height: var(--a11y-hit);
}

@media (max-width: 359px) {
  .screen {
    padding-inline: 10px;
    overflow-x: hidden;
    overflow-y: auto;
  }

  .brand-title { font-size: 36px; }
  .home-tools { gap: 6px; }

  .tap-route-controls {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .tap-route-status {
    grid-column: 1 / -1;
    grid-row: 1;
  }

  html[data-input-mode="tap"][data-board-mode="visual"] .boardwrap {
    padding-bottom: 108px;
  }

  .board-a11y { padding: 9px; }
  .board-a11y-grid { gap: 5px; }
  .route-actions { gap: 5px; }

  .panel {
    width: calc(100vw - 20px);
    padding-inline: 14px;
    --panel-px: 14px;
  }

  .result-lead {
    grid-template-columns: 1fr;
  }
}

@media (max-height: 620px) {
  .scene.art-v2[data-adaptive-phase="choice"] .scene-msg:has(.adaptive-choice),
  .scene.art-v2[data-adaptive-phase="route"] .scene-msg:has(.adaptive-choice) {
    left: 0;
    right: 0;
  }

  #accessibilityBtn,
  .route-action,
  #boardA11yGrid > button,
  .panel :where(button, [role="button"]) {
    min-height: var(--a11y-hit);
  }

  .board-a11y {
    padding-top: 9px;
    padding-bottom: 9px;
  }

  .board-a11y-head p { line-height: 1.3; }
}

@media (orientation: landscape) and (min-width: 568px) {
  .screen {
    width: 100%;
    max-width: 1000px;
    padding:
      max(calc(env(safe-area-inset-top, 0px) + 6px), 8px)
      max(calc(env(safe-area-inset-right, 0px) + 8px), 12px)
      max(calc(env(safe-area-inset-bottom, 0px) + 6px), 8px)
      max(calc(env(safe-area-inset-left, 0px) + 8px), 12px);
  }

  #game {
    display: grid;
    grid-template-columns: minmax(210px, 0.82fr) minmax(260px, 1.18fr);
    grid-template-rows: auto auto minmax(0, 1fr) auto;
    gap: 6px 10px;
    overflow: hidden;
  }

  /* D6: 텍스트 보드는 가로에서도 자연 흐름 + 단일 스크롤 소유자(#game).
     2열 고정 그리드와 overflow:hidden을 그대로 두면 자연 높이 보드가 잘린다 */
  html[data-board-mode="text"] #game {
    display: flex;
    flex-direction: column;
    overflow-y: auto;
  }

  #game > .gtop {
    grid-column: 1;
    grid-row: 1;
    min-width: 0;
  }

  #game > .chips {
    grid-column: 1;
    grid-row: 2;
    min-width: 0;
  }

  #game > .scene {
    grid-column: 1;
    grid-row: 3 / 5;
    min-width: 0;
    min-height: 0;
    height: 100%;
  }

  #game > .boardwrap {
    grid-column: 2;
    grid-row: 1 / 4;
    min-width: 0;
    min-height: 0;
  }

  #game > .gfoot {
    grid-column: 2;
    grid-row: 4;
    min-width: 0;
  }

  /* 진행 세이브 홈은 침입 CTA와 훈련 재도전이 동시에 뜬다. 두 요소를 같은 셀(1열
     2행)에 겹쳐 놓던 4행 그리드를 행별 분리로 바꿨다(2026-08-23 실측 결함).
     행은 max-content로 내용을 온전히 담고 start 정렬로 둔다 — center 정렬은 트랙보다
     커진 항목(568×320 실측: 2행 CTA 72px vs 트랙 56px)을 이웃 행으로 넘치게 한다. */
  #home {
    display: grid;
    grid-template-columns: minmax(190px, 0.72fr) minmax(320px, 1.28fr);
    grid-template-rows: none;
    grid-auto-rows: max-content;
    gap: 7px 12px;
    align-items: start;
    overflow-x: hidden;
    overflow-y: auto;
  }

  #home > .brand {
    grid-column: 1;
    grid-row: 1;
    min-width: 0;
    margin: 0;
  }

  #home > .cta {
    grid-column: 1;
    grid-row: 2;
    min-width: 0;
  }

  #home > .training-replay {
    grid-column: 1;
    grid-row: 3;
    min-width: 0;
  }

  #home > .vault-card {
    grid-column: 1;
    grid-row: 4;
    min-width: 0;
    align-self: start;
  }

  #home > .home-foot {
    grid-column: 1;
    grid-row: 5;
    min-width: 0;
  }

  #home > .mode-grid {
    grid-column: 2;
    grid-row: 1 / 4;
    min-width: 0;
  }

  #home > .buildings {
    grid-column: 2;
    grid-row: 4 / 6;
    min-width: 0;
    align-self: stretch;
  }

  /* 좌열은 최소 190px까지 좁아진다. EN 최장 단어 PHANTOM이 잘리지 않는 상한(42px,
     844px 기준 실측 205px 열)으로 묶는다 */
  .brand-title { font-size: clamp(26px, 4.9vw, 42px); }
  .brand-sub { font-size: 12px; }
  .brand::after { margin-top: 5px; }
  .home-foot { width: 100%; }

  .board-a11y {
    width: min(100%, 42rem);
  }
}

@media (min-width: 673px) and (orientation: portrait) {
  .screen { max-width: 680px; }
  #home { max-width: 600px; }
  .board-a11y { max-width: 600px; }
}

@media (min-width: 800px) and (orientation: portrait) {
  .screen { max-width: 720px; }
}

@media (prefers-reduced-motion: reduce) {
  .route-action,
  #boardA11yGrid > button,
  .accessibility-choice,
  .save-recovery-action {
    transition: none;
  }
}

@media (forced-colors: active) {
  .accessibility-mark,
  .board-a11y,
  #boardA11yGrid > button,
  .route-action,
  .accessibility-choice,
  .save-recovery-action {
    border-color: ButtonText;
    box-shadow: none;
    forced-color-adjust: auto;
  }

  #boardA11yGrid > button[aria-pressed="true"],
  .accessibility-choice[aria-pressed="true"],
  .accessibility-choice[aria-checked="true"] {
    outline: 3px solid Highlight;
    outline-offset: -4px;
  }
}

/* User-selected text scaling applies to the shipped pixel-based skin as well as
   the rem-based accessibility controls. */
html[data-text-scale] .brand-title {
  font-size: calc(clamp(36px, 11vw, 52px) * var(--a11y-scale)) !important;
}

/* 확대 배율에서 1.2 줄높이는 24px급 아이브로의 글리프 잉크(어센더·디센더)보다 낮아
   2px 세로 클립을 만든다(200% 실측 31/29). 배율에서만 여유를 준다. */
html[data-text-scale="130"] .brand-eyebrow,
html[data-text-scale="200"] .brand-eyebrow {
  line-height: 1.4;
}

/* 작전 파일 허브 텍스트도 배율 계약을 따른다(기본 크기 보존형 개별 규칙) */
html[data-text-scale] :where(.ops-hub-copy b) { font-size: calc(14px * var(--a11y-scale)) !important; }
html[data-text-scale] :where(.hub-row-copy b) { font-size: calc(13.5px * var(--a11y-scale)) !important; }
html[data-text-scale] :where(.ops-hub-copy small, .hub-row-copy small, .hub-row-act, .hub-targets-title) { font-size: calc(12px * var(--a11y-scale)) !important; }
html[data-text-scale] :where(.hub-row-go, .ops-hub-go) { font-size: calc(18px * var(--a11y-scale)) !important; }
html[data-text-scale="130"] .hub-row,
html[data-text-scale="200"] .hub-row,
html[data-text-scale="130"] .ops-hub-btn,
html[data-text-scale="200"] .ops-hub-btn { min-height: calc(52px * var(--a11y-scale)); }

/* 배율에서 우측 보상 라벨이 제목 열을 압사시킨다(320@200 실측 제목 0px) →
   보상 라벨을 둘째 행으로 내린다 */
html[data-text-scale="130"] .hub-row,
html[data-text-scale="200"] .hub-row { grid-template-columns: minmax(0, 1fr) auto; }

html[data-text-scale="130"] .hub-row-act,
html[data-text-scale="200"] .hub-row-act {
  grid-column: 1 / -1;
  justify-self: start;
  white-space: normal;
  overflow-wrap: anywhere;
}

html[data-text-scale] :where(
  .brand-eyebrow,
  .daily-title,
  .daily-streak,
  .daily-status,
  .daily-btn,
  .weekly-case-eyebrow,
  .weekly-case-meta,
  .weekly-case-reward,
  .adaptive-eyebrow,
  .adaptive-meta,
  .vault-card .v-title,
  .vault-card .v-sub,
  .vault-card .v-go,
  .bld .nm,
  .bld .pg,
  .ver,
  .lv-label .pos,
  .chip,
  .chip b,
  .bag,
  .quip,
  .adaptive-choice-title,
  .adaptive-choice b,
  .adaptive-choice .route-vibe,
  .adaptive-choice small,
  .adaptive-choice small em,
  .challenge-kicker,
  .grade-cap,
  .feedback-setting-copy small,
  .feedback-note,
  .challenge-protocol-preview,
  .challenge-target,
  .challenge-route span,
  .challenge-route b,
  .challenge-facts span,
  .challenge-proof,
  .challenge-recap i,
  .challenge-recap b,
  .challenge-score span,
  .challenge-score em,
  .challenge-result-row,
  .challenge-choice,
  .challenge-compare,
  .challenge-compare span,
  .challenge-compare b,
  .challenge-compare.reset,
  .challenge-pb,
  .challenge-delta,
  .challenge-seed,
  .challenge-details > summary,
  .chapter-dossier-copy > span,
  .chapter-dossier-copy > small,
  .next-target-dossier small,
  .next-target-dossier b,
  .next-target-dossier em,
  .lvbtn .no,
  .lvbtn .gim,
  .lvbtn .lock-name,
  .v-bld,
  .v-bld > span
) {
  font-size: calc(12px * var(--a11y-scale)) !important;
}

html[data-text-scale] :where(
  .brand-sub,
  .training-replay,
  .adaptive-title,
  .weekly-case-title,
  .lv-label,
  .scene-msg,
  .hint-label
) {
  font-size: calc(13px * var(--a11y-scale)) !important;
}

html[data-text-scale] :where(
  .p-desc,
  .p-btn,
  .feedback-setting-copy strong
) {
  font-size: calc(14px * var(--a11y-scale)) !important;
}

html[data-text-scale] .result-copy .p-desc {
  font-size: calc(12px * var(--a11y-scale)) !important;
}

html[data-text-scale] .cta {
  font-size: calc(20px * var(--a11y-scale)) !important;
}

html[data-text-scale="130"] .cta,
html[data-text-scale="200"] .cta {
  height: auto !important;
  min-height: calc(3em + (28px * var(--a11y-scale))) !important;
  padding-block: calc(14px * var(--a11y-scale)) !important;
  /* 200% 가로 568px에서 EN 'training' 한 단어(약 160px)가 콘텐츠 폭(약 130px)을 넘어
     키홀 예약 영역을 36px 침범했다(R19 실측). 배율에서는 단어 내 분절을 허용한다. */
  overflow-wrap: anywhere;
}

html[data-text-scale] .challenge-score b {
  font-size: calc(38px * var(--a11y-scale)) !important;
}

/* 확대 배율에서 점수 격자(1fr auto)는 접히지 않아 폰트 계측이 큰 플랫폼에서 가로로
   넘친다(우분투 200% 실측 344>318). 세로 적층이면 폭과 무관하게 수납되고, 폰트는
   그대로라 배율 비율 계약(×1.3/×2.0)도 유지된다. */
html[data-text-scale="130"] .challenge-score,
html[data-text-scale="200"] .challenge-score {
  grid-template-columns: 1fr;
  /* 적층 행 사이 간격: 기본 행 간격 1px에 숫자의 압축 줄높이가 더해지면 글리프
     상자가 위 행의 텍스트 렉트를 침범한다(우분투 130 실측). */
  row-gap: 8px;
}
html[data-text-scale="130"] .challenge-score b,
html[data-text-scale="200"] .challenge-score b {
  grid-row: auto;
  grid-column: 1;
  justify-self: start;
  min-width: 0;
  /* 압축 줄높이(0.9)는 한 줄 장식용이다. 적층에서는 글리프 상자(약 1.16em)를
     온전히 담아 형제 텍스트 렉트와 교차하지 않게 한다. */
  line-height: 1.2;
}

/* 대배율 HUD 라벨: nowrap+ellipsis가 의미 텍스트를 자른다 → 줄바꿈 허용.
   .lock-title 스팬은 인라인이라 ellipsis가 안 먹고 그대로 넘치므로 함께 푼다 */
html[data-text-scale="130"] .lv-label,
html[data-text-scale="200"] .lv-label,
html[data-text-scale="130"] .lv-label .lock-title,
html[data-text-scale="200"] .lv-label .lock-title {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}

/* 200%의 좁은 랜드스케이프 열(92px)에서는 nowrap 'LOCK n/n'(약 110px)이 유일한
   수평 넘침원이다. 200%만 단위 접힘을 푼다(130%는 71px로 수납). */
html[data-text-scale="200"] .lv-label .pos {
  white-space: normal;
}

html[data-text-scale="130"] .lv-label,
html[data-text-scale="200"] .lv-label {
  height: auto;
  min-height: 48px;
}

html[data-text-scale] .p-title,
html[data-text-scale] .result-copy .p-title {
  font-size: calc(28px * var(--a11y-scale)) !important;
}

html[data-text-scale="130"] :where(#home, #game),
html[data-text-scale="200"] :where(#home, #game) {
  overflow-x: hidden !important;
  overflow-y: auto !important;
}

html[data-text-scale="130"] #home,
html[data-text-scale="200"] #home {
  justify-content: flex-start;
}

html[data-text-scale="130"] #home > *,
html[data-text-scale="200"] #home > * {
  flex-shrink: 0;
}

html[data-text-scale="200"] .brand {
  padding-right: 14px;
}

html[data-text-scale="200"] .brand::before {
  display: none;
}

html[data-text-scale="130"] .mode-grid,
html[data-text-scale="200"] .mode-grid {
  grid-template-columns: minmax(0, 1fr);
}

html[data-text-scale="200"] :where(
  .daily-title,
  .daily-streak,
  .daily-status,
  .adaptive-meta,
  #weeklyCaseTitle,
  #weeklyCaseMeta,
  #weeklyCaseReward
) {
  white-space: normal;
  overflow-wrap: anywhere;
}

html[data-text-scale="130"] :where(.daily-title, .daily-streak, .daily-status, .adaptive-meta),
html[data-text-scale="130"] #weeklyCaseTitle,
html[data-text-scale="130"] #weeklyCaseMeta,
html[data-text-scale="130"] #weeklyCaseReward,
html[data-text-scale="200"] #weeklyCaseTitle,
html[data-text-scale="200"] #weeklyCaseMeta,
html[data-text-scale="200"] #weeklyCaseReward {
  white-space: normal;
  overflow-wrap: anywhere;
}

/* 대배율에서만 타이틀 말줄임을 푼다. 배율 무관(data-text-scale 존재만 보는) 선택자는
   기본 100 배율까지 nowrap을 풀어 430px 2열에서 글자 세로 쌓임을 만들었다(실측) */
html[data-text-scale="130"] #weeklyCaseTitle,
html[data-text-scale="200"] #weeklyCaseTitle {
  overflow: visible;
  text-overflow: clip;
}

html[data-text-scale] .adaptive-meta {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  overflow-wrap: anywhere;
}

html[data-text-scale] .adaptive-copy,
html[data-text-scale] .vault-card .v-mid {
  gap: calc(3px * var(--a11y-scale));
}

html[data-text-scale] .adaptive-copy > *,
html[data-text-scale] .vault-card :where(.v-title, .v-sub) {
  line-height: 1.4;
}

html[data-text-scale="130"] :where(.adaptive-cta, .vault-card),
html[data-text-scale="200"] :where(.adaptive-cta, .vault-card) {
  height: auto;
  min-height: calc(50px * var(--a11y-scale));
}

html[data-text-scale] :where(.daily-title, .daily-status, .vault-card .v-sub, .bld .nm, .bld .pg) {
  overflow: visible !important;
  text-overflow: clip !important;
  white-space: normal !important;
  overflow-wrap: anywhere;
}

html[data-text-scale="130"] .daily-head,
html[data-text-scale="200"] .daily-head {
  flex-wrap: wrap;
  align-items: flex-start;
}

html[data-text-scale="130"] .buildings {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

html[data-text-scale="200"] .buildings {
  grid-template-columns: minmax(0, 1fr);
}

html[data-text-scale="130"] .bld,
html[data-text-scale="200"] .bld {
  min-height: 76px;
  height: auto;
  padding-block: 6px;
}

html[data-text-scale] .bld :where(.nm, .pg) {
  display: block;
  width: 100%;
  max-width: 100%;
  line-height: 1.4;
}

html[data-text-scale] .bld .pg {
  margin-top: calc(3px * var(--a11y-scale));
}

html[data-text-scale="130"] #weeklyCaseCard .weekly-case-copy,
html[data-text-scale="200"] #weeklyCaseCard .weekly-case-copy {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "head" "meta" "stamps" "reward";
}

html[data-text-scale="200"] .challenge-route {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  row-gap: 12px;
}

html[data-text-scale="200"] .challenge-route::before {
  display: none;
}

html[data-text-scale="200"] .challenge-route span,
html[data-text-scale="200"] .challenge-facts span {
  min-width: 0;
  overflow-wrap: anywhere;
}

html[data-text-scale="200"] .result-lead {
  grid-template-columns: minmax(0, 1fr);
}

html[data-text-scale="200"] .result-copy :where(.p-title, .p-desc),
html[data-text-scale="200"] .challenge-details,
html[data-text-scale="200"] .challenge-recap :where(i, b),
html[data-text-scale="200"] :where(.challenge-choice, .challenge-pb, .challenge-delta, .challenge-proof) {
  min-width: 0;
  overflow-wrap: anywhere;
}

html[data-text-scale="200"] .challenge-recap,
html[data-text-scale="200"] .challenge-compare {
  grid-template-columns: minmax(0, 1fr);
}

html[data-text-scale="200"] .challenge-result-row {
  flex-direction: column;
  align-items: flex-start;
}

html[data-text-scale="200"] .brand-title {
  max-width: 100%;
  white-space: normal;
  overflow-wrap: anywhere;
}

html[data-text-scale="130"] .next-target-dossier,
html[data-text-scale="200"] .next-target-dossier {
  height: auto;
  min-height: 48px;
}

html[data-text-scale] .next-target-dossier b {
  min-width: 0;
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  overflow-wrap: anywhere;
}

html[data-text-scale="130"] .v-bld,
html[data-text-scale="200"] .v-bld {
  min-height: 48px;
  height: auto;
  white-space: normal;
  overflow-wrap: anywhere;
}

html[data-text-scale="130"] .challenge-details > summary,
html[data-text-scale="200"] .challenge-details > summary {
  min-height: 48px;
  white-space: normal;
  overflow-wrap: anywhere;
}

#panelBox[data-panel-kind="level-select"] .lv-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  row-gap: 3px;
  min-width: 0;
}

/* Give three-column dossiers enough measure for intact localized labels and
   compact rule metadata without reducing type. */
#panelBox[data-panel-kind="level-select"] {
  padding: 16px 14px 14px;
}

html[data-text-scale] #panelBox[data-panel-kind="level-select"] .lvbtn {
  min-width: 0;
  max-width: 100%;
  min-height: calc(58px * var(--a11y-scale));
  height: auto;
  font-size: calc(12px * var(--a11y-scale));
  line-height: 1.4;
  text-align: center;
  padding-block: calc(5px * var(--a11y-scale));
}

html[data-text-scale] .lvbtn :where(.no, .gim, .lock-name) {
  line-height: 1.4;
}

html[data-text-scale="100"] #panelBox[data-panel-kind="level-select"] .lvbtn {
  display: block;
}

html[data-text-scale] #panelBox[data-panel-kind="level-select"] .lv-main {
  display: flex;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  align-items: baseline;
  justify-content: center;
  gap: calc(4px * var(--a11y-scale));
  line-height: 1.4;
}

html[data-text-scale] #panelBox[data-panel-kind="level-select"] .lv-main > .no {
  flex: 0 0 auto;
}

html[data-text-scale] #panelBox[data-panel-kind="level-select"] .lv-main > .lock-name {
  min-width: 0;
}

html[data-text-scale="130"] #panelBox[data-panel-kind="level-select"] .lvbtn,
html[data-text-scale="200"] #panelBox[data-panel-kind="level-select"] .lvbtn {
  display: flex;
  gap: calc(3px * var(--a11y-scale));
}

#panelBox[data-panel-kind="level-select"] .lvbtn .gim {
  display: block;
  min-width: 0;
  max-width: 100%;
  margin-top: 3px;
  letter-spacing: 0;
  overflow-wrap: anywhere;
}

#panelBox[data-panel-kind="level-select"] .lvbtn .gim:empty {
  display: none;
}

/* The catalogue footer remains in flow below the full dossier. */
#panelBox[data-panel-kind="level-select"] > .p-btns {
  position: static;
}

html[data-text-scale] .lvbtn .lock-name {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  overflow-wrap: anywhere;
}

html[lang="ko"][data-text-scale] #panelBox[data-panel-kind="level-select"] .lv-main > .lock-name {
  overflow-wrap: normal;
  word-break: keep-all;
  hyphens: none;
}

/* Float the index without splitting English lock names. */
html[lang="en"][data-text-scale] #panelBox[data-panel-kind="level-select"] .lv-main {
  display: block;
}

html[lang="en"][data-text-scale] #panelBox[data-panel-kind="level-select"] .lv-main > .no {
  position: static;
  float: left;
  margin-right: calc(6px * var(--a11y-scale));
  margin-bottom: calc(2px * var(--a11y-scale));
}

html[lang="en"][data-text-scale] #panelBox[data-panel-kind="level-select"] .lv-main > .lock-name {
  display: block;
  width: 100%;
  overflow-wrap: normal;
  word-break: normal;
  hyphens: none;
}

html[data-text-scale="130"] #panelBox[data-panel-kind="level-select"] .lv-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

html[data-text-scale="200"] #panelBox[data-panel-kind="level-select"] .lv-grid {
  grid-template-columns: minmax(0, 1fr);
}

@media (max-width: 340px) {
  html[data-text-scale="100"] #panelBox[data-panel-kind="level-select"] .lv-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 390px) {
  html[data-text-scale] #weeklyCaseCard .weekly-case-copy {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "head" "meta" "stamps" "reward";
  }
}

/* Secondary copy remains normal text, so reserve low-contrast ivory for
   disabled controls and decorative marks only. */
html[data-text-scale] :where(
  .daily-streak,
  .daily-status,
  .adaptive-meta,
  .bld:not(.locked) .nm,
  .vault-card .v-sub,
  .lv-label .pos,
  #weeklyCaseMeta,
  #weeklyCaseReward,
  .chapter-dossier-copy > span,
  .chapter-dossier-copy > small,
  .next-target-dossier small,
  .next-target-dossier em,
  .lvbtn:not(.locked):not(.paused) .lock-name,
  .challenge-protocol-preview,
  .challenge-target,
  .challenge-route span,
  .challenge-facts span,
  .challenge-proof,
  .challenge-score span,
  .challenge-result-row,
  .challenge-choice,
  .challenge-compare span,
  .challenge-compare.reset,
  .challenge-pb,
  .challenge-delta
) {
  color: var(--a11y-secondary);
}

html[data-text-scale] :where(
  .chip:not(.over):not(.gold):not(.ready):not(.red),
  .adaptive-choice small em,
  .quip,
  .grade-cap
) {
  color: var(--a11y-secondary);
}

html[data-text-scale] .vault-card .v-sub,
html[data-text-scale] .bld:not(.locked) .nm,
html[data-text-scale] .lv-label .pos,
html[data-text-scale] #weeklyCaseMeta,
html[data-text-scale] #weeklyCaseReward,
html[data-text-scale] .adaptive-choice small em,
html[data-text-scale] .chapter-dossier-copy > span,
html[data-text-scale] .chapter-dossier-copy > small,
html[data-text-scale] .next-target-dossier small,
html[data-text-scale] .next-target-dossier em,
html[data-text-scale] .lvbtn:not(.locked):not(.paused) .lock-name {
  color: var(--a11y-secondary);
}

html[data-text-scale="130"] #game,
html[data-text-scale="200"] #game {
  min-height: 100%;
  height: auto;
}

html[data-text-scale="130"] #game.adaptive-vault > .scene.art-v2 {
  min-height: 250px;
}

html[data-text-scale="200"] #game.adaptive-vault > .scene.art-v2 {
  min-height: 465px;
}

html[data-text-scale="200"] .adaptive-choice {
  grid-template-columns: minmax(0, 1fr);
}

html[data-text-scale="130"] .scene[data-adaptive-phase="choice"] .scene-msg:has(.adaptive-choice),
html[data-text-scale="130"] .scene[data-adaptive-phase="route"] .scene-msg:has(.adaptive-choice),
html[data-text-scale="200"] .scene[data-adaptive-phase="choice"] .scene-msg:has(.adaptive-choice),
html[data-text-scale="200"] .scene[data-adaptive-phase="route"] .scene-msg:has(.adaptive-choice) {
  flex: 0 0 auto;
  align-self: stretch;
}

html[data-text-scale="130"]:not([data-board-mode="text"]) #game > .boardwrap,
html[data-text-scale="200"]:not([data-board-mode="text"]) #game > .boardwrap {
  flex: 0 0 max(252px, min(74vw, 430px));
  min-height: 252px;
}

html[data-text-scale="130"] .tap-route-controls,
html[data-text-scale="200"] .tap-route-controls {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

html[data-text-scale="130"] .tap-route-status,
html[data-text-scale="200"] .tap-route-status {
  grid-column: 1 / -1;
  grid-row: 1;
  line-height: 1.4;
}

html[data-text-scale="130"][data-input-mode="tap"][data-board-mode="visual"] .boardwrap {
  padding-bottom: 140px;
}

html[data-text-scale="200"][data-input-mode="tap"][data-board-mode="visual"] .boardwrap {
  padding-bottom: 190px;
}

/* The tap route panel occupies reserved space inside the wrapper. Daily mode
   has no scene, so grow that wrapper by the reservation instead of shrinking
   the playable square to the canvas fallback size. Large-text screens already
   scroll vertically and keep every control reachable. */
html[data-text-scale="130"][data-input-mode="tap"][data-board-mode="visual"] #game.daily-live > .boardwrap {
  min-height: calc(max(252px, min(74vw, 430px)) + 140px);
}

html[data-text-scale="200"][data-input-mode="tap"][data-board-mode="visual"] #game.daily-live > .boardwrap {
  min-height: calc(max(252px, min(74vw, 430px)) + 190px);
}

#boardA11yGrid > .dial-text-action {
  aspect-ratio: auto;
  min-height: 64px;
  padding: 12px;
}

.lvbtn.unlocked,
.lvbtn.skipped {
  border-style: dashed;
  border-color: var(--cyan-42);
}

.lvbtn.skipped .gim {
  color: var(--electric-cyan);
}

@media (orientation: landscape) and (min-width: 568px) {
  /* 좌열 최소 190px에서 EN 최장 단어가 잘리지 않는 상한. 비배율 규칙과 짝.
     배율 곱을 열 폭으로 캡하면 배율 계약(실배율 비율 게이트)을 어긴다 — 대신 아래에서
     배율 가로 홈의 브랜드를 전폭 행으로 승격해 스케일 공간을 준다. */
  html[data-text-scale] .brand-title {
    font-size: calc(clamp(26px, 4.9vw, 42px) * var(--a11y-scale)) !important;
  }

  /* 568~699px 가로 좌열(192px대)에서 시계 장식 예약(padding-right 70px)이 타이틀
     콘텐츠를 106px로 줄여 EN 최장 단어(134px)가 클립됐다(실측). 이 구간은 장식을 접는다. */
  @media (max-width: 699px) {
    .brand { padding-right: 14px; }
    .brand::before { display: none; }

    /* 배율 금고 카드는 고정 요소(패딩 26+갭 22+아이콘 20+진입 라벨 135)만 203px라
       좌열 190px에 안 든다(실측 194/190 클립). 진입 라벨을 둘째 행으로 내린다. */
    html[data-text-scale="130"] .vault-card,
    html[data-text-scale="200"] .vault-card {
      grid-template-columns: auto minmax(0, 1fr);
    }

    html[data-text-scale="130"] .vault-card .v-go,
    html[data-text-scale="200"] .vault-card .v-go {
      grid-column: 1 / -1;
      justify-self: start;
    }
  }

  html[data-text-scale="130"] #game,
  html[data-text-scale="200"] #game {
    align-content: start;
    grid-template-rows: auto auto minmax(240px, 1fr) auto;
  }

  html[data-text-scale="130"] #game > .boardwrap,
  html[data-text-scale="200"] #game > .boardwrap {
    min-height: 280px;
  }

  /* 확대 배율에서 트랙보다 커진 항목(CTA 218px vs 트랙 176px 실측)이 center 정렬로
     이웃 행을 침범한다. 배율 가로 홈은 start 정렬 + 각 항목이 자기 행을 온전히 갖게 한다. */
  html[data-text-scale="130"] #home,
  html[data-text-scale="200"] #home {
    grid-template-rows: none;
    grid-auto-rows: max-content;
    align-items: start;
  }

  /* 배율 곱(최대 84px)의 PHANTOM 한 단어는 좌열(190~205px)에 물리적으로 안 들어간다.
     배율 가로에서는 브랜드를 전폭 1행으로 승격하고 나머지를 한 행씩 내린다. */
  html[data-text-scale="130"] #home > .brand,
  html[data-text-scale="200"] #home > .brand {
    grid-column: 1 / -1;
    grid-row: 1;
  }

  html[data-text-scale="130"] #home > .cta,
  html[data-text-scale="200"] #home > .cta { grid-row: 2; }

  html[data-text-scale="130"] #home > .training-replay,
  html[data-text-scale="200"] #home > .training-replay { grid-row: 3; }

  html[data-text-scale="130"] #home > .vault-card,
  html[data-text-scale="200"] #home > .vault-card { grid-row: 4; }

  html[data-text-scale="130"] #home > .home-foot,
  html[data-text-scale="200"] #home > .home-foot { grid-row: 5; }

  html[data-text-scale="130"] #home > .mode-grid,
  html[data-text-scale="200"] #home > .mode-grid { grid-row: 2 / 5; }

  html[data-text-scale="130"] #home > .buildings,
  html[data-text-scale="200"] #home > .buildings { grid-row: 5 / 7; }
}

@media (max-height: 620px) {
  html[data-text-scale] .challenge-score b {
    font-size: calc(32px * var(--a11y-scale)) !important;
  }
}

/* The progressed home carries campaign, replay, daily, weekly and meta entry
   points at once. Keep the complete information hierarchy on short phones
   without letting the bottom-anchored stack push the brand above the safe
   viewport. Larger text modes retain their scrollable reflow. */
@media (max-height: 760px) and (max-width: 480px) {
  html[data-text-scale="100"] #home {
    gap: 4px;
  }

  html[data-text-scale="100"] .brand {
    padding: 0 14px;
  }

  html[data-text-scale="100"] .brand::before,
  html[data-text-scale="100"] .brand::after {
    display: none;
  }

  html[data-text-scale="100"] .brand-eyebrow {
    margin-bottom: 3px;
  }

  html[data-text-scale] .brand-title {
    font-size: calc(32px * var(--a11y-scale)) !important;
  }

  html[data-text-scale="100"] .brand-title {
    white-space: nowrap;
  }

  html[data-text-scale="100"] .brand-sub {
    margin-top: 2px;
  }

  html[data-text-scale="100"] #weeklyCaseCard {
    padding: 6px 8px;
  }

  html[data-text-scale="100"] #weeklyCaseCard .weekly-case-copy {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: none;
    gap: 3px 8px;
  }

  html[data-text-scale="100"] #weeklyCaseCard .weekly-case-head {
    grid-column: 1 / 3;
    grid-row: 1;
  }

  html[data-text-scale="100"] #weeklyCaseMeta {
    grid-column: 1;
    grid-row: 2;
  }

  html[data-text-scale="100"] #weeklyCaseStamps {
    grid-column: 2;
    grid-row: 2;
    gap: 3px;
  }

  html[data-text-scale="100"] #weeklyCaseStamps .weekly-stamp {
    width: 10px;
  }

  html[data-text-scale="100"] #weeklyCaseReward {
    grid-column: 1 / 3;
    grid-row: 3;
  }

  html[data-text-scale="100"] .vault-card {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 8px;
  }

  html[data-text-scale="100"] .vault-card .v-ico {
    display: none;
  }

  html[data-text-scale="100"] .vault-card .v-sub {
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    white-space: nowrap !important;
  }
}

@media (max-height: 620px) and (max-width: 480px) {
  html[data-text-scale="100"] #home {
    gap: 3px;
  }
}

/* Preserve full-size controls on the smallest supported portrait instead of
   letting the bottom-anchored flex stack clip its first rows. */
@media (max-height: 620px) and (max-width: 359px) {
  html[data-text-scale="100"] #home {
    justify-content: flex-start;
    overflow-x: hidden;
    overflow-y: auto;
  }

  html[data-text-scale="100"] #home > * {
    flex-shrink: 0;
  }
}


/* P1.3 × 접근성 배율: 씬 높이는 배율별로도 '라운드 진입 전에 결정되는 고정값'이다.
   100% 고정(116/76px)을 그대로 두면 130·200% 확대 문구가 overflow:hidden에 잘린다.
   보드 위치 불변 계약은 유지된다 — 높이는 배율이 정하고 라운드 중엔 변하지 않는다. */
html[data-text-scale="130"]:not([data-board-mode="text"]) #game:not(.adaptive-vault) > .scene {
  height: 156px;
  flex: 0 0 auto;
}

html[data-text-scale="200"]:not([data-board-mode="text"]) #game:not(.adaptive-vault) > .scene {
  height: 236px;
  flex: 0 0 auto;
}

/* 확대 배율에서 씬이 안 줄어들면 압착이 칩·HUD로 옮겨간다(칩 10px 실측).
   배율에서는 게임 컬럼 전원이 고정이고, 넘침은 .screen 스크롤이 받는다 */
html[data-text-scale="130"] #game:not(.adaptive-vault) > *,
html[data-text-scale="200"] #game:not(.adaptive-vault) > * {
  flex-shrink: 0;
}

/* 주간 카드 머리행: 확대 배율에서 CASE FILE 어포던스가 제목을 밀어내면 줄을 바꾼다 */
html[data-text-scale="130"] .weekly-case-head,
html[data-text-scale="200"] .weekly-case-head {
  flex-wrap: wrap;
}

/* 확대 배율에서는 아트 점유보다 문구 판독이 우선 — 메시지 열을 넓힌다 */
html[data-text-scale="130"] .scene.art-v2 .scene-msg,
html[data-text-scale="200"] .scene.art-v2 .scene-msg {
  left: 8%;
  right: 8%;
}

/* 넓힌 박스가 중앙 정렬로 위로 자라면 좌상단 전리품 카운터(#bag, 정보)를 덮는다
   (568x320/200 실측 8.6px). 중심을 내려 배지 줄을 비킨다. 배율 씬 높이(156/236)
   기준 최장 문구 수납 예산 안이다. ★적응형 제외: 그 상태의 메시지는 절대배치가
   아니라 플렉스 아이템이라 마진이 보드를 민다(130% 실측 16.8px 이동).
   2026-08-26: 세로 760px 이상은 메시지가 하단 고정(scene-art.css)이라 이 마진이 작용하지 않고,
   116px 씬과 가로는 여전히 중앙 정렬이라 이 보정이 필요하다(568x320/200에서 6px 겹침 실측). */
html[data-text-scale="130"] #game:not(.adaptive-vault) .scene.art-v2 .scene-msg {
  margin-top: 20px;
}

/* EN 200%는 줄 수가 많아 20px로도 5.5px 남았다(실측). 200%만 28px — 수납 예산
   236-56=180px, 최장 문구 약 160px. */
html[data-text-scale="200"] #game:not(.adaptive-vault) .scene.art-v2 .scene-msg {
  margin-top: 28px;
}
