.ready-panel #play-button{opacity:1}
.trail-selector{display:flex;gap:8px;overflow-x:auto;padding:5px 3px 12px}.course-leaderboard li{min-height:44px}
/* 2026-08-13: 캐릭터 이름 검색창을 없애면서 랭킹 박스 아래가 허전해졌다 —
   .leaderboard-panel의 상단 여백(20px)과 맞춰 하단에도 같은 여백을 준다.
   #id로 명시해 뒤에 나오는 .leaderboard-panel{margin:20px auto 0} 축약 선언이
   bottom을 다시 0으로 덮어쓰지 않게 한다. */
#course-leaderboard{margin-bottom:20px}.trail-chip{flex:1;min-width:165px;background:var(--panel);color:var(--ink);border:2px solid transparent;text-align:left}.trail-chip span{display:block;font-size:.76rem;color:var(--muted);margin-top:2px}.trail-chip[aria-selected=true]{border-color:var(--accent)}.ready-panel,.game-over-panel{text-align:center;padding:20px 0}
.ready-panel p,.game-over-panel p{color:var(--muted)}
.event-status{height:24px;margin:5px 0;text-align:center;color:var(--accent);font-weight:900}
.canvas-wrap{position:relative}.pause-overlay{position:absolute;inset:0;display:grid;place-content:center;gap:6px;background:rgba(9,20,12,.76);color:var(--ink);text-align:center}.pause-overlay strong{font-size:clamp(1.4rem,6vw,2.4rem);color:var(--accent)}.pause-overlay span{font-weight:700}
.final-score{display:block;font-size:clamp(2.8rem,12vw,5rem);color:var(--accent)}
.game-actions,.future-actions{display:flex;justify-content:center;flex-wrap:wrap;gap:10px;margin-top:14px}
.secondary{background:#d7e6c7}
.future-actions button{background:var(--panel);color:var(--muted)}
.future-actions #share-button{background:var(--accent);color:#172015}
.celebration-overlay{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;pointer-events:none;opacity:0;transition:opacity .2s}
.celebration-overlay.active{opacity:1;pointer-events:auto}
.celebration-hint{position:absolute;left:0;right:0;bottom:28px;z-index:2;text-align:center;color:#fff;font-weight:700;font-size:.85rem;text-shadow:0 1px 4px rgba(0,0,0,.6);opacity:.85}
.celebration-overlay[hidden]{display:none}
.celebration-overlay::before{content:'';position:absolute;inset:0;background:linear-gradient(180deg,#e4002b,#ff8c00,#ffed00,#008026,#004dff,#750787);opacity:.22;animation:celebration-bg-pulse 1.1s ease-in-out infinite}
@keyframes celebration-bg-pulse{0%,100%{opacity:.14}50%{opacity:.32}}
.celebration-text{position:relative;z-index:2;margin:0;padding:16px 24px;max-width:88vw;text-align:center;font-size:clamp(1.3rem,6vw,2.1rem);font-weight:900;color:#fff;text-shadow:0 2px 6px rgba(0,0,0,.45);background:linear-gradient(90deg,#e4002b,#ff8c00,#ffed00,#008026,#004dff,#750787);background-size:300% 100%;border-radius:18px;box-shadow:0 0 0 4px #fff,0 10px 30px rgba(0,0,0,.4);animation:celebration-pop .5s cubic-bezier(.34,1.56,.64,1),celebration-rainbow-sweep 1.8s linear infinite}
@keyframes celebration-pop{0%{transform:scale(.4) rotate(-8deg);opacity:0}60%{transform:scale(1.12) rotate(3deg);opacity:1}100%{transform:scale(1) rotate(0)}}
@keyframes celebration-rainbow-sweep{0%{background-position:0% 0}100%{background-position:100% 0}}
.celebration-confetti{position:absolute;inset:0;overflow:hidden}
.confetti-piece{position:absolute;width:36px;height:auto;image-rendering:pixelated;will-change:transform,opacity;animation-name:confetti-fly;animation-timing-function:ease-in;animation-fill-mode:forwards;transform:translate(-50%,-50%) scale(var(--scale,1)) rotate(0deg);opacity:0}
@keyframes confetti-fly{0%{transform:translate(-50%,-50%) scale(var(--scale,1)) rotate(0deg);opacity:0}10%{opacity:1}100%{transform:translate(calc(-50% + var(--dx)),calc(-50% + var(--dy))) scale(var(--scale,1)) rotate(var(--rot));opacity:0}}
/* 2026-08-12: 부스트(좌하단)/점프(우하단) 전용 대형 터치 버튼. canvas-wrap 안에
   position:absolute로 겹쳐 그려서 게임 화면 하단 모서리에 항상 고정된다. */
.control-button{position:absolute;bottom:max(16px,env(safe-area-inset-bottom));width:min(84px,18vw,18vh);height:min(84px,18vw,18vh);border-radius:50%;border:3px solid rgba(255,255,255,.5);font-size:1.8rem;line-height:1;display:flex;align-items:center;justify-content:center;touch-action:none;user-select:none;-webkit-user-select:none;color:#172015;transition:transform .08s}
.control-button:active,.control-button.pressed{transform:scale(.9)}
/* 2026-08-12 버그 수정: pointer-events:none을 주면 브라우저가 히트테스트에서 이
   버튼을 아예 없는 셈 치고 "뒤에 있는" canvas-wrap이 탭을 받아버려서, 비활성화된
   부스트 버튼을 눌러도 점프가 발동했다. disabled 속성만으로 충분히 무반응 처리되고
   (자기 자신의 이벤트만 안 쏘고 뒤로 새지 않음) pointer-events는 그대로 auto로 둔다. */
.control-button.disabled{opacity:.35;filter:grayscale(.65)}
.control-button.ready-flash{animation:control-ready-flash .6s ease-out}
@keyframes control-ready-flash{0%{box-shadow:0 0 0 0 rgba(255,255,255,.9);transform:scale(1.18)}100%{box-shadow:0 0 0 22px rgba(255,255,255,0);transform:scale(1)}}
.boost-button{left:16px;background:radial-gradient(circle at 35% 30%,#8fe6ff,#2ab6e6);color:#0b2a33}
.jump-button{right:16px;background:radial-gradient(circle at 35% 30%,#ffe27a,#ffc23a)}
/* 2026-08-12: HUD(거리/게이지)를 캔버스 안 드로잉에서 DOM으로 이동 — 캔버스 상단을
   가려서 점프한 캐릭터가 그 뒤에 숨는다는 피드백 반영. game-heading과 canvas-wrap
   사이에 항상 고정된 자리를 차지해서 게임 화면 자체는 안 가린다. */
/* 2026-08-12: canvas-wrap "안쪽" 상단에 오버레이 — 세로로 긴 화면에서 캔버스 위쪽에
   생기는 레터박스 여백(실제 게임 콘텐츠가 없는 빈 공간) 자리에 앉는다. canvas-wrap
   바깥에 별도 블록으로 두면 "눈에 안 들어온다"는 피드백이 있었고, 캔버스 안에
   그대로 그리면 점프하는 캐릭터를 가렸다 — 이 둘 다 아닌 절충: canvas-wrap의 자식
   으로 두되 실제 게임이 렌더링되는 letterbox 안쪽 콘텐츠 영역과는 안 겹치는
   상단 여백에만 절대위치로 얹는다. */
/* 2026-08-12: 폭은 원래 캔버스 드로잉 버전(로직 220/960 ≈ 23%)과 맞추고 좌측 정렬
   유지, 세로 위치는 top을 JS(main.js updateHud)가 매 프레임 renderer의 실제
   letterbox 오프셋을 읽어 "게임 영역 바로 위"에 정확히 붙도록 인라인으로 덮어쓴다
   (여기 top 값은 JS가 아직 안 돌았을 때의 안전한 기본값일 뿐). */
.game-hud{position:absolute;top:14px;left:14px;width:23%;min-width:150px;max-width:230px;z-index:2;background:rgba(12,25,18,.82);border-radius:12px;padding:8px 12px;color:#fff6d0;font-weight:700;font-size:.85rem;pointer-events:none}
.game-hud-row{display:flex;justify-content:space-between;align-items:center;gap:8px}
.game-hud-bar{height:6px;border-radius:3px;background:rgba(255,255,255,.22);margin:4px 0;overflow:hidden}
.game-hud-fill{height:100%;width:0%;border-radius:3px;transition:width .12s linear}
.game-hud-fill.progress{background:#ffd85a}
.game-hud-fill.stamina{background:#7bd67b}
.game-hud-fill.stamina.boosting{background:#5cd6ff}
.game-hud-fill.stamina.ready-flash{animation:hud-stamina-flash .6s ease-out}
@keyframes hud-stamina-flash{0%{background:#ffffff;box-shadow:0 0 8px 2px #fff}100%{background:#7bd67b;box-shadow:none}}
/* 2026-08-13: 체크포인트 출발 후 5초 부스트 무한 모드 — 게이지가 꽉 찬 채로
   반짝인다. 일반 boosting(파랑, 위 규칙)과는 확실히 구분되는 금색 셔머로. */
.game-hud-fill.stamina.cp-boost{background:linear-gradient(90deg,#ffd85a,#fff8dc,#ffd85a);background-size:200% 100%;animation:cp-boost-shimmer .8s linear infinite;box-shadow:0 0 6px 1px rgba(255,216,90,.8)}
@keyframes cp-boost-shimmer{0%{background-position:0% 0}100%{background-position:200% 0}}
.leaderboard-result{font-weight:800}.leaderboard-panel{margin:20px auto 0;max-width:620px;padding:14px;border:1px solid var(--line);border-radius:14px;background:#17291d;text-align:left}.leaderboard-heading{display:flex;align-items:center;justify-content:space-between;gap:12px}.leaderboard-heading h2{margin:0;color:var(--ink)}.leaderboard-heading button{min-height:36px;padding:6px 12px}.leaderboard-panel>p{text-align:center}.leaderboard-panel ol{list-style:none;margin:10px 0 0;padding:0}.leaderboard-panel li{display:grid;grid-template-columns:44px 42px minmax(0,1fr) auto;align-items:center;gap:8px;min-height:50px;padding:5px 7px;border-top:1px solid var(--line)}.leaderboard-panel li img{width:40px;height:40px;object-fit:contain;image-rendering:pixelated}.leaderboard-panel li span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.leaderboard-panel li strong{color:var(--accent)}
.lb-metric{display:flex;flex-direction:column;align-items:flex-end;line-height:1.3;min-width:0}
.lb-metric strong{white-space:nowrap}
.lb-metric .lb-pace{font-size:.68rem;color:var(--muted);font-weight:600;white-space:nowrap}
.share-toast{position:fixed;z-index:20;left:50%;bottom:calc(18px + env(safe-area-inset-bottom));transform:translateX(-50%);width:min(calc(100% - 32px),560px);padding:13px 16px;border-radius:12px;background:#fff3c0;color:#172015;font-weight:800;text-align:center;box-shadow:0 8px 30px rgba(0,0,0,.35)}
.share-dialog{width:min(calc(100% - 32px),520px);border:1px solid var(--line);border-radius:16px;padding:0;background:var(--panel);color:var(--ink)}
.share-dialog::backdrop{background:rgba(5,12,8,.72)}
.share-dialog form{display:grid;gap:12px;padding:20px}.share-dialog h2,.share-dialog p{margin:0}.share-dialog textarea{width:100%;resize:none;border:1px solid var(--line);border-radius:10px;padding:12px;background:#101b14;color:var(--ink);font:inherit;line-height:1.5;user-select:text}
@media(max-width:600px){.game-screen{padding-bottom:var(--safe-bottom)}}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
/* 2026-08-12: 리포트/도감 페이지와 공통 헤더(header.top) 도입. cast.html의
   header.top 스타일을 그대로 이식 — 사이트 전체에서 헤더가 동일하게 보여야 한다는
   요청이라 게임 페이지의 다크 톤(--ink 등)으로 바꾸지 않고 원본 올리브/아이보리
   배색을 유지한다. app-shell은 기존에 자체적으로 100dvh를 차지했는데, 헤더가
   추가되면서 그대로 두면 뷰포트 아래로 밀려 넘친다 — page-shell을 세로 flex로
   만들고 app-shell은 남는 공간(flex:1)만 차지하도록 재정의한다. */
.page-shell{display:flex;flex-direction:column;height:100vh;height:100dvh}
header.top{flex:0 0 auto;background:#6f8b3d;color:#fffff0;padding:13px 0}
header.top .wrap{max-width:1180px;margin:0 auto;padding:0 20px;display:flex;align-items:center;gap:14px;flex-wrap:wrap}
header.top .brand{font-weight:800;font-size:16px}
header.top nav{margin-left:auto;display:flex;gap:14px;font-size:13.5px}
header.top nav a{color:rgba(255,255,255,.9);text-decoration:none}
header.top nav a:hover{color:#fff;text-decoration:underline}
header.top nav a[aria-current=page]{color:#fff;font-weight:700;text-decoration:underline}
.page-shell .app-shell{height:auto;flex:1 1 auto;min-height:0}
@media(max-width:600px){header.top nav{width:100%;margin-left:0}}
