/* =============================================================================
 * style.css — 짐프러너 v2 (세로 9:16)
 *  · 브랜드: JIMFF Red #CB0E12 / Ink #1C1C1B / Cyan 2026 #01BEFF / Paper #FAF7F2
 *  · 캔버스는 항상 뒤에서 살아 있고 DOM 화면이 그 위에 겹쳐진다.
 * =========================================================================== */
:root {
  --red: #CB0E12;
  --ink: #1C1C1B;
  --cyan: #01BEFF;
  --cyan-deep: #0096D6;
  --cyan-pale: #8FE4FF;
  --paper: #FAF7F2;
  --sand: #E8DCC8;
  --gold: #FFC93C;
  --vermilion: #FF3B1F;
  --font: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont,
    'Apple SD Gothic Neo', 'Noto Sans KR', system-ui, sans-serif;
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-back: cubic-bezier(.34, 1.56, .64, 1);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: #07080E;
  font-family: var(--font);
  color: var(--paper);
  overscroll-behavior: none;
  touch-action: manipulation;
}

#device {
  position: fixed; inset: 0;
  display: grid; place-items: center;
  background: radial-gradient(120% 80% at 50% 0%, #16233F 0%, #0A0D18 55%, #07080E 100%);
}

#app {
  position: relative;
  width: min(100vw, calc(100vh * 9 / 16));
  height: min(100vh, calc(100vw * 16 / 9));
  overflow: hidden;
  border-radius: clamp(0px, 1.6vmin, 22px);
  box-shadow: 0 30px 90px rgba(0, 0, 0, .65);
  isolation: isolate;
}

#game-canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
  z-index: 0;
}

/* ══════════════════ 공통 ══════════════════ */
.screen {
  position: absolute; inset: 0;
  z-index: 20;
  display: none;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: linear-gradient(180deg, rgba(7, 8, 14, .82) 0%, rgba(7, 8, 14, .93) 60%, rgba(7, 8, 14, .97) 100%);
  backdrop-filter: blur(3px);
  animation: screenIn .32s var(--ease-out);
}
.screen.active { display: block; }
@keyframes screenIn { from { opacity: 0; transform: scale(1.015); } to { opacity: 1; transform: none; } }

.hidden { display: none !important; }

.btn {
  display: block; width: 100%;
  padding: 3.4% 4%;
  min-height: 46px;                 /* 작은 화면에서도 터치 타깃 44px 이상 확보 */
  font-family: inherit; font-size: clamp(14px, 3.9vmin, 21px); font-weight: 800;
  letter-spacing: -.01em;
  border: 0; border-radius: 999px;
  cursor: pointer;
  transition: transform .16s var(--ease-back), filter .16s, box-shadow .2s;
}
.btn:active { transform: scale(.965); }
.btn-primary {
  background: linear-gradient(180deg, var(--red) 0%, #A00B0E 100%);
  color: #fff;
  box-shadow: 0 6px 0 #6E0709, 0 12px 24px rgba(203, 14, 18, .35);
}
.btn-primary:active { box-shadow: 0 2px 0 #6E0709, 0 6px 14px rgba(203, 14, 18, .3); }
.btn-ghost {
  background: rgba(250, 247, 242, .07);
  color: var(--paper);
  border: 1.5px solid rgba(250, 247, 242, .22);
  font-weight: 700;
}
.start-row { display: flex; gap: 2.4%; margin-top: 2.6%; }
.start-row .btn { margin: 0; }

/* ══════════════════ 시작 화면 ══════════════════ */
#screen-start {
  /* 뒤에서 실제로 게임이 돌고 있다 — 위쪽은 비워 두고 아래만 눌러 가독성을 확보한다 */
  background: linear-gradient(180deg,
    rgba(7, 8, 14, .30) 0%, rgba(7, 8, 14, .18) 26%,
    rgba(7, 8, 14, .62) 58%, rgba(7, 8, 14, .93) 82%, rgba(7, 8, 14, .97) 100%);
  backdrop-filter: none;
}
.start-inner {
  min-height: 100%;
  padding: 6% 8% 4.5%;
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
}

.lang-toggle {
  position: absolute; top: 3.2%; right: 5%;
  display: flex; gap: 2px; padding: 3px;
  background: rgba(250, 247, 242, .09); border-radius: 999px;
}
.lang-toggle button {
  border: 0; background: transparent; color: rgba(250, 247, 242, .55);
  font-family: inherit; font-size: clamp(10px, 2.5vmin, 13px); font-weight: 800;
  padding: 5px 12px; border-radius: 999px; cursor: pointer;
}
.lang-toggle button.on { background: var(--cyan); color: #04121C; }

.brand-logo { width: 42%; max-width: 190px; margin: 0 0 4%; filter: brightness(0) invert(1); opacity: .88; }

/* 타이틀 뒤 컨페티 파편 프레임 (중앙이 비어 있는 아트)
 * ⚠ ui_title_plate.png 는 파편 대부분이 잉크색(#1C1C1B)이다. 이걸 그냥 opacity 로 깔면
 *   밝은 하늘 위에 시커먼 사각 얼룩이 생긴다(실제 피드백). mix-blend-mode:screen 을 쓰면
 *   검은 파편은 결과에 기여하지 않고 시안/레드 컨페티만 빛으로 남는다. */
.title-wrap { position: relative; display: flex; flex-direction: column; align-items: center; }
.title-wrap::before {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 124%; aspect-ratio: 3 / 2.1; transform: translate(-50%, -50%);
  background: url('../assets/images/ui/ui_title_plate.png') center/contain no-repeat;
  mix-blend-mode: screen; opacity: .85;
  pointer-events: none; z-index: -1;
}
.game-title {
  margin: 0; line-height: .86;
  font-size: clamp(46px, 16vmin, 108px); font-weight: 900; letter-spacing: -.045em;
  display: flex; flex-direction: column;
}
.game-title .t-line1 { color: var(--paper); text-shadow: 0 4px 22px rgba(0,0,0,.7); }
.game-title .t-line2 {
  color: transparent;
  background: linear-gradient(100deg, var(--cyan) 0%, var(--cyan-pale) 55%, #fff 100%);
  -webkit-background-clip: text; background-clip: text;
}
.game-title .t-line2 { filter: drop-shadow(0 4px 18px rgba(0,0,0,.55)); }
.game-sub {
  text-shadow: 0 2px 10px rgba(0,0,0,.8);
  margin: 3.5% 0 0; font-size: clamp(11px, 2.9vmin, 15px); font-weight: 600;
  color: rgba(250, 247, 242, .62); letter-spacing: -.01em;
}

/* ══════════════════ 캐릭터 선택 ══════════════════
 * 초상 3장을 나란히. 고른 것만 시안 링 + 살짝 확대되고, 나머지는 채도를 눌러 둔다.
 * 아직 안 고른 사람도 "고를 수 있다"가 한눈에 보여야 한다. */
.char-pick { width: 100%; margin: 2% 0 4%; }
.char-pick-label {
  margin: 0 0 8px; font-size: clamp(9px, 2.3vmin, 11px); font-weight: 800;
  letter-spacing: .16em; color: rgba(250, 247, 242, .45); text-transform: uppercase;
}
.char-list { display: flex; gap: 8px; justify-content: center; }
.char-card {
  flex: 1 1 0; max-width: 108px; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 8px 4px 7px; border-radius: 16px; cursor: pointer;
  background: rgba(250, 247, 242, .06);
  border: 2px solid transparent;
  transition: transform .22s var(--ease-back), background .18s, border-color .18s;
  -webkit-tap-highlight-color: transparent;
}
.char-card img {
  width: 100%; max-width: 62px; aspect-ratio: 1; object-fit: contain;
  filter: saturate(.35) brightness(.72);
  transition: filter .18s, transform .22s var(--ease-back);
}
.char-card .cc-name {
  font-size: clamp(10px, 2.6vmin, 13px); font-weight: 900; letter-spacing: -.01em;
  color: rgba(250, 247, 242, .55);
}
.char-card .cc-tag {
  font-size: clamp(8px, 2vmin, 10px); font-weight: 600;
  color: rgba(250, 247, 242, .34);
}
.char-card.on {
  background: rgba(1, 190, 255, .13);
  border-color: var(--cyan);
  transform: translateY(-3px);
}
.char-card.on img { filter: none; transform: scale(1.06); }
.char-card.on .cc-name { color: var(--paper); }
.char-card.on .cc-tag { color: rgba(250, 247, 242, .6); }

.stage-chips { display: flex; gap: 5px; margin: 5% 0 4%; flex-wrap: wrap; justify-content: center; }
.chip {
  backdrop-filter: blur(6px);
  font-size: clamp(9px, 2.4vmin, 12px); font-weight: 700;
  padding: 5px 11px; border-radius: 999px;
  background: rgba(1, 190, 255, .12); color: var(--cyan-pale);
  border: 1px solid rgba(1, 190, 255, .3);
}

.start-form { width: 100%; margin-top: auto; }
#name-input {
  width: 100%; padding: 3.6% 5%;
  font-family: inherit; font-size: clamp(14px, 4vmin, 20px); font-weight: 700;
  text-align: center; color: var(--paper);
  background: rgba(250, 247, 242, .07);
  border: 1.5px solid rgba(250, 247, 242, .2); border-radius: 999px;
  outline: none; margin-bottom: 3%;
  transition: border-color .2s, background .2s;
}
#name-input:focus { border-color: var(--cyan); background: rgba(1, 190, 255, .08); }
#name-input::placeholder { color: rgba(250, 247, 242, .35); font-weight: 500; }

.warn {
  margin: 0; height: 0; opacity: 0;
  font-size: clamp(10px, 2.7vmin, 13px); font-weight: 700; color: #FF6B5B;
  transition: opacity .2s;
}
.warn.on { height: auto; opacity: 1; margin-bottom: 2.5%; }

/* (조작 안내 .howto 블록은 제거됐다 — 아케이드는 실물 조이스틱이,
 *  폰은 게임 중 #controls 가 안내를 대신한다) */
.credit { margin: 6% 0 0; font-size: clamp(9px, 2.3vmin, 11px); color: rgba(250, 247, 242, .3); letter-spacing: .1em; font-weight: 700; }

/* ══════════════════ 방향키 / 조이스틱 포커스 링 ══════════════════
 * js/uinav.js 가 지금 선택된 항목에 .nav-on 을 건다.
 * 링 자체는 <html class="nav-keys"> 일 때만 보인다 — 키·패드를 처음 쓴 순간
 * 켜지고, 마우스·터치를 쓰면 다시 꺼진다(:focus-visible 과 같은 관례).
 * 그래야 폰 사용자에게 "이미 눌린 버튼"처럼 보이지 않는다. */
.nav-keys .nav-on {
  outline: 3px solid var(--cyan);
  outline-offset: 3px;
  animation: navPulse 1.15s ease-in-out infinite;
}
.nav-keys .btn.nav-on { filter: drop-shadow(0 0 12px rgba(1, 190, 255, .55)); }
.nav-keys .char-card.nav-on { outline-offset: 2px; }
/* 체크박스는 작아서 링만으로는 눈에 안 띈다 — 배경까지 얹는다 */
.nav-keys #chk-mute.nav-on { outline-offset: 4px; box-shadow: 0 0 14px rgba(1, 190, 255, .8); }
/* 언어 토글도 작다 */
.nav-keys .lang-toggle button.nav-on { box-shadow: 0 0 16px rgba(1, 190, 255, .7); }

/* 닉네임 칸 — 얇은 링만으로는 존재감이 없었다(실제 피드백: "어디 있는지 감이 안 온다").
 * 커서가 여기 오면 칸 **전체**가 시안으로 물들고 캐럿이 깜빡여서,
 * "지금부터 키보드로 치면 된다"가 눈으로 바로 읽히게 한다. */
.nav-keys #name-input.nav-on,
.nav-keys #name-input:focus {
  border-color: var(--cyan);
  background: rgba(1, 190, 255, .18);
  color: #fff;
  caret-color: var(--cyan);
  box-shadow: 0 0 0 6px rgba(1, 190, 255, .16), 0 0 28px rgba(1, 190, 255, .6);
}
.nav-keys #name-input.nav-on::placeholder { color: rgba(250, 247, 242, .8); }
@keyframes navPulse {
  0%, 100% { outline-color: var(--cyan); }
  50% { outline-color: var(--cyan-pale); }
}

/* ══════════════════ HUD ══════════════════ */
#hud {
  position: absolute; inset: 0; z-index: 10;
  pointer-events: none;
  padding: 3.4% 4.5%;
}
#hud.shake { animation: hudShake .3s; }
@keyframes hudShake {
  0%, 100% { transform: none; } 25% { transform: translate(-4px, 2px); }
  50% { transform: translate(4px, -2px); } 75% { transform: translate(-2px, -3px); }
}
.hud-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }

.hud-hearts { display: flex; gap: 5px; padding-top: 4px; }
/* 하트 회복 — 채워지는 순간 한 번 부풀며 빛난다(획득감).
 * 글로우는 하트색(붉은색)이 아니라 회복 민트그린이다 — 붉게 빛나면 피격으로 읽힌다. */
.hud-hearts.heal { animation: healPop .6s var(--ease-back); }
@keyframes healPop {
  0% { transform: scale(1); filter: none; }
  35% { transform: scale(1.28); filter: drop-shadow(0 0 12px rgba(75, 255, 165, .95)); }
  100% { transform: scale(1); filter: none; }
}
.heart {
  width: clamp(16px, 4.2vmin, 24px); height: clamp(16px, 4.2vmin, 24px);
  background: var(--red);
  clip-path: polygon(50% 100%, 6% 46%, 4% 30%, 12% 12%, 30% 6%, 50% 20%, 70% 6%, 88% 12%, 96% 30%, 94% 46%);
  transition: opacity .25s, transform .25s var(--ease-back);
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .5));
}
.heart.off { opacity: .18; transform: scale(.78); filter: grayscale(1); }

.hud-center { text-align: center; flex: 1; }
.hud-score {
  font-size: clamp(26px, 7.6vmin, 44px); font-weight: 900; letter-spacing: -.03em;
  line-height: 1; color: #fff;
  text-shadow: 0 2px 0 rgba(0, 0, 0, .45), 0 6px 18px rgba(0, 0, 0, .5);
  font-variant-numeric: tabular-nums;
}
.hud-dist {
  margin-top: 2px; font-size: clamp(10px, 2.7vmin, 14px); font-weight: 800;
  color: var(--cyan-pale); letter-spacing: .02em;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .6);
  font-variant-numeric: tabular-nums;
}

.icon-btn {
  pointer-events: auto;
  width: clamp(32px, 8.4vmin, 44px); height: clamp(32px, 8.4vmin, 44px);
  display: grid; place-items: center; gap: 3px; grid-auto-flow: column;
  border-radius: 50%; cursor: pointer;
  background: rgba(7, 8, 14, .42); backdrop-filter: blur(6px);
  border: 1.5px solid rgba(250, 247, 242, .2);
}
.icon-btn span { width: 3px; height: 42%; background: var(--paper); border-radius: 2px; }

.hud-stage {
  position: absolute; left: 0; right: 0; top: 12.5%;
  text-align: center; font-size: clamp(10px, 2.6vmin, 13px); font-weight: 800;
  letter-spacing: .16em; color: rgba(250, 247, 242, .5);
  text-shadow: 0 1px 6px rgba(0, 0, 0, .7);
}

/* 활성 파워업 — 왼쪽 세로 스택. 남은 시간이 게이지로 줄어든다.
 * 게임 중 시선은 화면 아래 3레인에 있으므로, 여기는 흘깃 봐도 읽히게 아이콘 위주로 둔다. */
.hud-powers {
  position: absolute; left: 3.5%; top: 15%;
  display: flex; flex-direction: column; gap: 6px;
  pointer-events: none;
}
.pw {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 8px 4px 5px; border-radius: 999px;
  background: rgba(7, 8, 14, .52);
  border: 1.5px solid currentColor;
  animation: pw-in .26s var(--ease-back) both;
}
.pw-ico { width: 18px; height: 18px; flex: 0 0 auto; display: block; }
.pw-ico-fallback {
  width: 12px; height: 12px; border-radius: 50%;
  background: currentColor; box-shadow: 0 0 8px currentColor;
}
.pw-bar {
  width: 34px; height: 4px; border-radius: 999px;
  background: rgba(250, 247, 242, .22); overflow: hidden;
}
.pw-bar > i { display: block; height: 100%; background: currentColor; border-radius: 999px; }
/* 1.5초 남으면 깜빡여 알린다 — 광과민성 규칙상 2Hz(3Hz 미만) */
.pw.ending { animation: pw-blink .5s steps(2, end) infinite; }
@keyframes pw-in { from { opacity: 0; transform: translateX(-14px) scale(.8); } to { opacity: 1; transform: none; } }
@keyframes pw-blink { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

/* 콤보 배율 — 아이템을 이어 먹는 맛의 핵심 피드백이라 크게 읽혀야 한다.
 * 기존 clamp(20/6.2vmin/34) 는 화면 중앙 상단에서 존재감이 없었다 → 전 구간 2배. */
.hud-combo {
  position: absolute; left: 0; right: 0; top: 20%;
  text-align: center;
  font-size: clamp(40px, 12.4vmin, 68px); font-weight: 900; font-style: italic;
  color: var(--gold); letter-spacing: -.02em;
  text-shadow: 0 3px 0 rgba(0, 0, 0, .5), 0 0 40px rgba(255, 201, 60, .6);
  opacity: 0; transform: scale(.7);
  transition: opacity .18s, transform .28s var(--ease-back);
}
.hud-combo.on { opacity: 1; transform: none; }

/* ══════════════════ 온스크린 조작 ══════════════════ */
#controls {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 12;
  display: flex; align-items: flex-end; gap: 2.6%;
  padding: 0 4.5% 4.5%;
  pointer-events: none;
}
.ctrl {
  pointer-events: auto;
  border: 1.6px solid rgba(250, 247, 242, .22);
  background: rgba(7, 8, 14, .34);
  backdrop-filter: blur(8px);
  color: var(--paper);
  border-radius: 22px; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  transition: transform .1s, background .12s, border-color .12s;
  user-select: none;
}
.ctrl:active { transform: scale(.94); background: rgba(1, 190, 255, .2); border-color: var(--cyan); }
.ctrl-side { flex: 1; height: clamp(52px, 13.5vmin, 78px); }
.ctrl-jump {
  flex: 1.25; height: clamp(64px, 16.5vmin, 96px);
  background: rgba(1, 190, 255, .16); border-color: rgba(1, 190, 255, .45);
}
.ctrl .arw { font-size: clamp(26px, 7.6vmin, 42px); line-height: .8; font-weight: 300; }
.ctrl em { font-style: normal; font-size: clamp(9px, 2.3vmin, 12px); font-weight: 800; letter-spacing: .1em; margin-top: 3px; opacity: .8; }

/* ══════════════════ 스테이지 카드 ══════════════════ */
.stage-card {
  position: absolute; left: 0; right: 0; top: 29%; z-index: 15;
  text-align: center; pointer-events: none;
  padding: 7% 0 6%;
  background-repeat: no-repeat; background-position: center; background-size: auto 118%;
  opacity: 0; transform: translateY(14px) scale(.96);
  transition: opacity .4s var(--ease-out), transform .55s var(--ease-out);
}
.stage-card.on { opacity: 1; transform: none; }
/* 글자 뒤에 **단색 판**을 깐다. 그림자만으로는 밝은 카드 아트 위에서 안 읽힌다
 * (실제 피드백: "스테이지 카드 글씨가 잘 안 보여"). */
.stage-card .sc-no, .stage-card .sc-name, .stage-card .sc-sub {
  position: relative; z-index: 1;
  display: inline-block;
  padding: 2px 14px; border-radius: 999px;
  background: rgba(7, 8, 14, .74);
  text-shadow: 0 2px 8px rgba(0,0,0,.95);
}
.stage-card .sc-name {
  font-size: clamp(23px, 7vmin, 38px); font-weight: 900; letter-spacing: -.03em;
  padding: 4px 20px; border-radius: 18px; margin: 4px 0;
  background: rgba(7, 8, 14, .82);
  border: 1.5px solid rgba(1, 190, 255, .45);
}
.stage-card .sc-no { color: var(--cyan); letter-spacing: .2em; }
/* 카드 아트는 ::before 로 — 반투명·라운드·비네트를 걸어 게임 화면을 다 가리지 않게 */
.stage-card::before {
  content: ''; position: absolute; inset: 0 14%;
  background: inherit;
  background-repeat: no-repeat; background-position: center; background-size: cover;
  border-radius: 18px;
  /* 맵이 바뀌는 순간이 잘 안 보인다는 피드백 — 카드 자체를 진하게 올리고
   * 뒤쪽을 어둡게 깔아 글씨가 배경에 묻히지 않게 한다. 완전 불투명은 아니라
   * 뒤에서 달리는 화면은 여전히 비친다. */
  opacity: 1;
  z-index: -1;
  /* ★ 카드 아트가 밝아(휘도 87~97) 흰 글씨가 묻혔다. 아트 **자체**를 눌러야 한다 —
   * 어둠을 아트 뒤에 깔아 봐야 소용이 없다(실측 확인). */
  filter: brightness(.5) saturate(1.15);
  box-shadow: 0 18px 60px rgba(0,0,0,.62), 0 0 0 2px rgba(250,247,242,.34) inset;
  -webkit-mask-image: radial-gradient(ellipse 100% 100% at 50% 50%, #000 76%, transparent 100%);
          mask-image: radial-gradient(ellipse 100% 100% at 50% 50%, #000 76%, transparent 100%);
}
/* 카드 뒤 어둠 — 아트가 밝은 스테이지에서도 흰 글씨가 읽힌다.
 * 글자에는 이미 단색 판이 깔려 있으므로 과하게 어둡힐 필요가 없다 —
 * .86 은 전환 순간 맵을 가렸다(실제 피드백). 무적 처리와 함께 완화. */
.stage-card::after {
  content: ''; position: absolute; inset: 0 10%;
  border-radius: 22px; z-index: -2;
  background: radial-gradient(ellipse 82% 74% at 50% 50%, rgba(7,8,14,.58) 0%, rgba(7,8,14,.34) 62%, rgba(7,8,14,0) 100%);
}
/* v3: 스테이지 5개 — 순서는 영화관 → 예술의전당 → 엽연초 → 여름광장 → 의림지 */
.stage-card[data-stage="0"] { background-image: url('../assets/images/ui/ui_card_s0.png'); }
.stage-card[data-stage="1"] { background-image: url('../assets/images/ui/ui_card_s1.png'); }
.stage-card[data-stage="2"] { background-image: url('../assets/images/ui/ui_card_s2.png'); }
.stage-card[data-stage="3"] { background-image: url('../assets/images/ui/ui_card_s4.png'); }
.stage-card[data-stage="4"] { background-image: url('../assets/images/ui/ui_card_s3.png'); }
.sc-name { text-shadow: 0 3px 0 rgba(0,0,0,.55), 0 10px 34px rgba(0,0,0,.75); }
.sc-sub { text-shadow: 0 2px 8px rgba(0,0,0,.8); }
.sc-no { font-size: clamp(10px, 2.6vmin, 13px); font-weight: 800; letter-spacing: .3em; color: var(--cyan); }
.sc-no b { color: #fff; }
.sc-name {
  font-size: clamp(30px, 9.4vmin, 54px); font-weight: 900; letter-spacing: -.035em;
  color: #fff; margin: 1.5% 0 .5%;
  text-shadow: 0 3px 0 rgba(0, 0, 0, .4), 0 10px 34px rgba(0, 0, 0, .6);
}
.sc-sub { font-size: clamp(12px, 3.2vmin, 17px); font-weight: 700; color: rgba(250, 247, 242, .66); }

/* ══════════════════ 오버레이 ══════════════════ */
.overlay {
  position: absolute; inset: 0; z-index: 30;
  display: none; place-items: center;
  background: rgba(7, 8, 14, .72); backdrop-filter: blur(7px);
  padding: 8%;
}
.overlay.on { display: grid; animation: screenIn .24s var(--ease-out); }
.panel {
  width: 100%; text-align: center;
  background: rgba(20, 24, 36, .92);
  border: 1.5px solid rgba(250, 247, 242, .14);
  border-radius: 26px; padding: 9% 7%;
}
.panel h2 { margin: 0 0 7%; font-size: clamp(20px, 5.6vmin, 30px); font-weight: 900; letter-spacing: -.03em; }
.panel .btn { margin-bottom: 3%; }
.mute-row { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 6%; font-size: clamp(11px, 2.9vmin, 14px); color: rgba(250, 247, 242, .6); font-weight: 700; }

/* ── 홍보 카드 ── */
.overlay.promo { background: rgba(7, 8, 14, .55); }
/* 홍보 오버레이 — 들어올 때만 애니메이션이 있고 나갈 때는 display:none 으로 툭 끊겼다.
 * (실제 피드백: "홍보 나올 때 문단 바뀌는 게 이상하다")
 * display 토글 대신 opacity/visibility 로 바꿔 **양방향** 전환을 만든다.
 * 캔버스 쪽 시간배속·레터박스도 같은 리듬(js/game.js promoK)으로 함께 움직인다. */
.overlay.promo {
  display: grid;                /* 항상 grid — 보이고 안 보이고는 opacity 가 정한다 */
  opacity: 0; visibility: hidden; pointer-events: none;
  animation: none;
  background: rgba(7, 8, 14, 0); backdrop-filter: blur(0px);
  transition: opacity .34s var(--ease-out),
              background .34s var(--ease-out),
              backdrop-filter .34s var(--ease-out),
              visibility 0s .34s;
}
.overlay.promo.on {
  opacity: 1; visibility: visible;
  /* 카드 뒤로 게임 화면이 계속 보여야 한다 — .78+blur8 은 맵을 통째로 지웠다
   * (실제 피드백: "홍보 안내 때 맵이 잘 안 보인다"). 카드가 떠 있는 동안은
   * 게임 쪽에서 무적 처리되므로 어둡게 가릴 이유도 없다. */
  background: rgba(7, 8, 14, .30); backdrop-filter: blur(1.5px);
  transition: opacity .26s var(--ease-out),
              background .26s var(--ease-out),
              backdrop-filter .26s var(--ease-out),
              visibility 0s;
}

.promo-card {
  width: 100%; position: relative; overflow: hidden;
  background: linear-gradient(155deg, #0E7FAE 0%, #01BEFF 60%, #4FD5FF 100%);
  color: #04121C;
  border-radius: 24px; padding: 9% 7% 7%;
  box-shadow: 0 26px 70px rgba(0, 0, 0, .55), 0 0 46px rgba(1, 190, 255, .45),
              0 0 0 2px rgba(255, 255, 255, .35) inset;
  /* 등장/퇴장을 keyframes 가 아니라 transition 으로 — 그래야 나갈 때도 움직인다 */
  opacity: 0; transform: translateY(26px) scale(.94);
  transition: opacity .30s var(--ease-out), transform .38s var(--ease-out);
}
.overlay.promo.on .promo-card {
  opacity: 1; transform: none;
  transition: opacity .28s var(--ease-out), transform .46s var(--ease-back);
}
/* 필름 퍼포레이션 — 영화제 정체성 */
.promo-strip {
  position: absolute; left: 0; right: 0; top: 0; height: 13px;
  background: repeating-linear-gradient(90deg, rgba(28, 28, 27, .85) 0 9px, transparent 9px 22px);
  opacity: .5;
}
.promo-tag {
  display: inline-block; font-size: clamp(10px, 2.6vmin, 13px); font-weight: 900;
  letter-spacing: .12em; padding: 5px 13px; border-radius: 999px;
  background: var(--ink); color: #fff; margin-bottom: 4%;
}
/* keep-all — 한글은 기본값(normal)에서 글자 아무 데서나 줄이 바뀐다.
 * 'JIMFF 오아시스 with 제주삼다수' 가 "…제주삼다 / 수" 로 끊겨 마지막 한 글자만
 * 아래로 떨어졌다. 어절 단위(공백)로만 끊게 해 제목이 항상 말이 되게 한다. */
.promo-title { margin: 0 0 3%; font-size: clamp(20px, 6vmin, 32px); font-weight: 900; letter-spacing: -.035em; line-height: 1.15; word-break: keep-all; }
.promo-date { font-size: clamp(13px, 3.5vmin, 18px); font-weight: 900; }
.promo-place { font-size: clamp(11px, 3vmin, 15px); font-weight: 700; opacity: .78; margin-top: 2px; }
.promo-desc { margin: 4% 0 6%; font-size: clamp(11px, 3vmin, 15px); font-weight: 600; line-height: 1.5; opacity: .88; }
.promo-bar { height: 4px; border-radius: 999px; background: rgba(4, 18, 28, .2); overflow: hidden; }
.promo-bar i { display: block; height: 100%; width: 0; background: var(--ink); border-radius: 999px; }

/* ══════════════════ 결과 ══════════════════ */
.result-wrap { min-height: 100%; padding: 9% 8% 6%; display: flex; flex-direction: column; align-items: center; text-align: center; }
.newrecord {
  opacity: 0; height: 0;
  font-size: clamp(11px, 3vmin, 15px); font-weight: 900; letter-spacing: .22em;
  color: var(--gold);
  transition: opacity .3s;
}
.newrecord.on { opacity: 1; height: auto; margin-bottom: 2%; animation: pop .6s var(--ease-back); }
@keyframes pop { from { transform: scale(.5); } to { transform: none; } }
.result-title { margin: 0; font-size: clamp(15px, 4.2vmin, 22px); font-weight: 800; letter-spacing: .16em; color: rgba(250, 247, 242, .55); }
.result-score { display: flex; align-items: baseline; justify-content: center; gap: 6px; margin: 3% 0 6%; }
.result-score span {
  font-size: clamp(52px, 17vmin, 104px); font-weight: 900; letter-spacing: -.05em; line-height: 1;
  color: transparent;
  background: linear-gradient(100deg, #fff 0%, var(--cyan-pale) 60%, var(--cyan) 100%);
  -webkit-background-clip: text; background-clip: text;
  font-variant-numeric: tabular-nums;
}
.result-score em { font-style: normal; font-size: clamp(13px, 3.6vmin, 18px); font-weight: 800; color: rgba(250, 247, 242, .5); }

.result-meta { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2%; width: 100%; margin-bottom: 5%; }
.result-meta div { background: rgba(250, 247, 242, .06); border-radius: 14px; padding: 5% 2%; }
.result-meta b { display: block; font-size: clamp(14px, 4vmin, 21px); font-weight: 900; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.result-meta span { display: block; margin-top: 3px; font-size: clamp(8px, 2.2vmin, 11px); font-weight: 700; color: rgba(250, 247, 242, .45); }

.rankline { min-height: 1.2em; margin-bottom: 4%; font-size: clamp(11px, 3vmin, 14px); font-weight: 800; color: var(--cyan); }
.rankline.warn { color: #FF6B5B; }
.result-actions { width: 100%; padding-top: 4%; }
.result-extra {
  display: flex; gap: 4%; justify-content: center; flex-wrap: wrap;
  margin-bottom: 4%; font-size: clamp(10px, 2.7vmin, 13px); font-weight: 700;
  color: rgba(250,247,242,.5);
}
/* "최고 콤보"·"아슬아슬" 이 좁은 화면에서 한 글자만 아래로 떨어지던 문제.
 * 라벨과 숫자를 한 덩어리로 묶고 그 안에서는 절대 줄바꿈하지 않는다. */
.result-extra > span, .result-extra > b { white-space: nowrap; }
.result-extra b { color: var(--gold); }

/* 자동 복귀 안내 — 부스 단말이 결과 화면에 갇히지 않게 남은 초를 보여 준다.
 * 자리를 항상 차지하게(min-height) 둔다 — 카운트다운이 뜰 때 버튼이 밀리면
 * 누르려던 손가락이 빗나간다. */
.autohome {
  min-height: 1.4em; margin: 3% 0 0; text-align: center;
  font-size: clamp(9px, 2.4vmin, 12px); font-weight: 700; letter-spacing: .02em;
  color: rgba(250, 247, 242, .38);
}

/* ══════════════════ 랭킹 / 축제 안내 ══════════════════ */
.rank-wrap, .promo-wrap { min-height: 100%; padding: 9% 8% 6%; display: flex; flex-direction: column; }
.rank-head { margin: 0 0 1%; font-size: clamp(20px, 6vmin, 32px); font-weight: 900; letter-spacing: .1em; text-align: center; }
.rank-live { text-align: center; font-size: clamp(10px, 2.6vmin, 13px); font-weight: 800; color: var(--cyan); margin-bottom: 6%; letter-spacing: .06em; }
.promo-period { text-align: center; font-size: clamp(10px, 2.7vmin, 13px); font-weight: 700; color: rgba(250, 247, 242, .5); margin: 0 0 6%; }

.rank-list { flex: 1; display: flex; flex-direction: column; gap: 5px; margin-bottom: 5%; }
.rank-list.mini { flex: 1 1 auto; width: 100%; margin-bottom: 4%; align-content: start; }
.rank-row {
  display: grid; grid-template-columns: 12% 1fr auto; align-items: center; gap: 3%;
  padding: 3.2% 4.5%; border-radius: 14px;
  background: rgba(250, 247, 242, .055);
  font-size: clamp(12px, 3.3vmin, 16px);
}
.rank-row.me { background: rgba(1, 190, 255, .16); box-shadow: 0 0 0 1.5px var(--cyan) inset; }
.rank-row .rk { font-weight: 900; color: rgba(250, 247, 242, .4); text-align: center; font-variant-numeric: tabular-nums; }
/* 상위 3위는 숫자 대신 메달 아트를 얹는다 */
.rank-row .rk.m1, .rank-row .rk.m2, .rank-row .rk.m3 {
  color: transparent;
  background-repeat: no-repeat; background-position: center; background-size: contain;
  min-height: clamp(24px, 6.4vmin, 34px);
}
.rank-row .rk.m1 { background-image: url('../assets/images/ui/ui_medal_gold.png'); }
.rank-row .rk.m2 { background-image: url('../assets/images/ui/ui_medal_silver.png'); }
.rank-row .rk.m3 { background-image: url('../assets/images/ui/ui_medal_bronze.png'); }
.rank-row .nm { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }
.rank-row .sc { font-weight: 900; font-variant-numeric: tabular-nums; color: var(--cyan-pale); }
.empty { text-align: center; color: rgba(250, 247, 242, .4); font-size: clamp(11px, 3vmin, 14px); padding: 12% 0; font-weight: 600; }

.promo-gallery { flex: 1; display: flex; flex-direction: column; gap: 8px; margin-bottom: 5%; }
.pg-card {
  background: rgba(250, 247, 242, .06); border-radius: 16px; padding: 4.5% 5%;
  border-left: 3px solid var(--cyan);
}
.pg-tag { display: inline-block; font-size: clamp(9px, 2.3vmin, 11px); font-weight: 900; letter-spacing: .1em; color: var(--cyan); margin-bottom: 4px; }
.pg-card h3 { margin: 0 0 4px; font-size: clamp(13px, 3.6vmin, 18px); font-weight: 900; letter-spacing: -.02em; word-break: keep-all; }
.pg-meta { font-size: clamp(9px, 2.5vmin, 12px); font-weight: 700; color: rgba(250, 247, 242, .5); }
.pg-card p { margin: 6px 0 0; font-size: clamp(10px, 2.8vmin, 13px); font-weight: 500; line-height: 1.45; color: rgba(250, 247, 242, .72); }

/* ══════════════════ 토스트 ══════════════════ */
.toast {
  position: absolute; left: 50%; bottom: 12%; z-index: 60;
  transform: translate(-50%, 16px);
  padding: 3% 6%; border-radius: 999px;
  background: rgba(20, 24, 36, .95); border: 1.5px solid rgba(250, 247, 242, .16);
  font-size: clamp(11px, 3vmin, 14px); font-weight: 700;
  opacity: 0; pointer-events: none;
  transition: opacity .25s, transform .35s var(--ease-out);
  max-width: 84%; text-align: center;
}
.toast.on { opacity: 1; transform: translate(-50%, 0); }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
