:root{
  /* --muted 는 라벨/설명 공통색 — 판독성 위해 패널 대비 7:1 이상 유지(#b39c7d 는 5:1 미달이었다) */
  --bg:#221a14; --panel:#2f2519; --panel2:#3a2d1d; --ink:#f3e6cf; --muted:#c9b491;
  --dirt:#6b4f2e; --dirt-lo:#4a3620; --gold:#f2c14e; --gold-lo:#b8862b;
  --com:#9aa0a6; --unc:#5fd38a; --rare:#5aa9e6; --epic:#b06ee6; --leg:#f2a13e;
  --line:#1a130d;
  /* 채굴장 창 높이 — 가로/내용물은 원래 크기 그대로, 이 값만 키우면 하늘(세로 여백)이 늘어난다(원래 100px). */
  --mine-h:130px;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  font-family:"Galmuri11","Galmuri9",monospace;
  background:var(--bg);
  color:var(--ink);
  image-rendering:pixelated;
  -webkit-font-smoothing:none;
  /* align-items:flex-start — #app 을 stretch 로 뷰포트 높이에 가두지 않고 내용만큼 자라게 한다.
     (stretch 면 내용이 길 때 #app 박스가 뷰포트에 갇혀 하단 패딩·패널 테두리가 잘려 보였다) */
  display:flex;justify-content:center;align-items:flex-start;
  background-image:linear-gradient(rgba(0,0,0,.25) 1px,transparent 1px),linear-gradient(90deg,rgba(0,0,0,.25) 1px,transparent 1px);
  background-size:16px 16px;
}
#app{width:100%;max-width:460px;min-height:100%;padding:12px;display:flex;flex-direction:column;gap:12px}

/* 스켈레톤 로딩 — 데이터 준비 전, 빈 틀 대신 뜨는 고정 오버레이(광고는 이 위 z-index 9998). */
.loading-screen{position:fixed;inset:0;z-index:50;display:flex;justify-content:center;align-items:flex-start;
  background:var(--bg);overflow:auto;
  background-image:linear-gradient(rgba(0,0,0,.25) 1px,transparent 1px),linear-gradient(90deg,rgba(0,0,0,.25) 1px,transparent 1px);
  background-size:16px 16px}
.loading-screen.hidden{display:none}
.loading-inner{width:100%;max-width:460px;min-height:100%;padding:12px;display:flex;flex-direction:column;gap:12px}
.skel{position:relative;overflow:hidden;background:var(--panel);border:3px solid var(--line);
  box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),inset 3px 3px 0 rgba(255,255,255,.06)}
.skel::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent 0,rgba(255,255,255,.10) 50%,transparent 100%);
  animation:skelShimmer 1.3s ease-in-out infinite}
@keyframes skelShimmer{100%{transform:translateX(100%)}}
@media (prefers-reduced-motion:reduce){.skel::after{animation:none}}
.skel-bar{height:46px}
.skel-hud{height:118px}
.skel-site{height:230px}
.skel-tabs{display:flex;gap:6px}
.skel-tab{flex:1;height:34px}
.skel-panel{height:200px}
.skel-balance{height:52px}
.skel-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}
.skel-card{height:150px}
.skel-row{height:44px}

/* 픽셀 박스 공통 */
.bar,.hud,.site,.panel,.claim-box,.pet-banner,.pet-slot,.pet-card,.shop-balance-bar{
  background:var(--panel);
  border:3px solid var(--line);
  box-shadow:inset -3px -3px 0 rgba(0,0,0,.35), inset 3px 3px 0 rgba(255,255,255,.06);
}

.bar{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 12px}
.who{font-size:11px;color:var(--muted);white-space:nowrap}
/* 헤더에는 페이지 이름이 없다 — 어느 화면인지는 하단 모드 내비가 이미 보여준다.
   남는 것은 계정 이름(왼쪽)과 소리·설정 아이콘(오른쪽)뿐이다. 슬롯은 bgm.js 가 .who
   **앞에** 꽂으므로 order 로 자리를 되돌린다. */
.bar.has-bgm-control{display:flex;align-items:center;justify-content:space-between;gap:8px}
.bar.has-bgm-control>.who{order:0;min-width:0;overflow:hidden;text-overflow:ellipsis}
.bar.has-bgm-control>.bgm-header-slot{order:1;flex:none;display:flex}
.bgm-control{display:inline-flex;align-items:stretch;gap:2px;min-width:0;max-width:100%}
.bgm-toggle{display:inline-flex;align-items:center;gap:5px;min-width:0;min-height:28px;padding:4px 6px;border:2px solid var(--line);background:#34291f;color:#d9d4c9;font:inherit;font-size:10px;line-height:1;white-space:nowrap;cursor:pointer;box-shadow:inset -2px -2px 0 rgba(0,0,0,.3),inset 2px 2px 0 rgba(255,255,255,.06)}
.bgm-toggle:hover{background:#453528;color:var(--gold)}
.bgm-toggle:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.bgm-toggle.is-off{color:var(--muted);background:#28231e}
.bgm-label{flex:none}
.bgm-track-title{min-width:0;max-width:128px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#f7d99b}
.bgm-toggle.is-off .bgm-track-title{color:var(--muted)}
.bgm-next{flex:none;min-width:28px;padding:3px 5px;border:2px solid var(--line);background:#34291f;color:#d9d4c9;font:inherit;font-size:11px;line-height:1;cursor:pointer;box-shadow:inset -2px -2px 0 rgba(0,0,0,.3),inset 2px 2px 0 rgba(255,255,255,.06)}
.bgm-next:hover:not(:disabled){background:#453528;color:var(--gold)}
.bgm-next:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.bgm-next:disabled{cursor:not-allowed;opacity:.42}
.bgm-equalizer{display:flex;align-items:flex-end;gap:1px;width:13px;height:12px}
.bgm-equalizer i{display:block;width:2px;height:3px;background:#fbbf24;transform-origin:bottom;image-rendering:pixelated;box-shadow:0 0 3px currentColor}
.bgm-equalizer i:nth-child(2){background:#fb7185}.bgm-equalizer i:nth-child(3){background:#22d3ee}.bgm-equalizer i:nth-child(4){background:#a3e635}
.bgm-equalizer i:nth-child(2){height:8px}.bgm-equalizer i:nth-child(3){height:5px}.bgm-equalizer i:nth-child(4){height:10px}
.bgm-toggle.playing .bgm-equalizer i{animation:bgmEq .72s steps(3,end) infinite alternate,bgmEqColor 1.8s steps(4,end) infinite}
.bgm-toggle.playing .bgm-equalizer i:nth-child(2){animation-delay:-.28s,-.42s}.bgm-toggle.playing .bgm-equalizer i:nth-child(3){animation-delay:-.51s,-.86s}.bgm-toggle.playing .bgm-equalizer i:nth-child(4){animation-delay:-.16s,-1.28s}
@keyframes bgmEq{to{transform:scaleY(.35)}}
@keyframes bgmEqColor{0%,100%{background:#fbbf24}25%{background:#fb7185}50%{background:#22d3ee}75%{background:#a3e635}}
@media (prefers-reduced-motion:reduce){.bgm-toggle.playing .bgm-equalizer i{animation:none}}
@media(max-width:360px){.bar.has-bgm-control{gap:4px;padding-left:8px;padding-right:8px}}

.hud{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;padding:12px}
.stat{display:flex;flex-direction:column;align-items:center;gap:2px;text-align:center}
.stat .label{font-size:10px;color:var(--muted)}
.stat .val{font-size:14px;color:var(--ink)}
.stat.big{grid-column:1/-1;border-bottom:2px dashed var(--dirt-lo);padding-bottom:10px;position:relative}
.stat.big .label{font-size:11px}
.stat.big .val{font-size:30px;color:var(--gold);text-shadow:2px 2px 0 var(--line)}
.unit{font-size:10px;color:var(--muted)}

.site{padding:18px;display:flex;flex-direction:column;align-items:center;gap:10px}
.dig-btn{
  font-family:inherit;cursor:pointer;color:var(--ink);
  background:var(--dirt);border:3px solid var(--line);
  box-shadow:inset -4px -4px 0 var(--dirt-lo), inset 4px 4px 0 rgba(255,255,255,.08);
  width:160px;height:160px;border-radius:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  transition:transform .03s;
}
.dig-btn:active{transform:translateY(3px);box-shadow:inset -4px -4px 0 var(--dirt-lo)}
.dig-emoji{font-size:54px;line-height:1}
.dig-text{font-size:16px;color:var(--gold)}
.hint{font-size:10px;color:var(--muted);text-align:center;line-height:1.6}

/* 자동 채굴 버튼 — 1시간 서버 타이머 부스트(무료·재시작). 진행 중엔 카운트다운 + 펄스. */
.auto-mine-btn{font-family:inherit;cursor:pointer;font-size:12px;color:#2a1d0c;background:var(--gold);
  border:3px solid var(--line);box-shadow:inset -3px -3px 0 var(--gold-lo);padding:9px 14px;width:100%;
  display:flex;align-items:center;justify-content:center;gap:6px}
.auto-mine-btn:active{transform:translateY(2px)}
.auto-mine-btn .am-sub{font-size:10px;color:#5a4326}
.auto-mine-btn.active{background:var(--panel2);color:var(--gold);cursor:pointer;
  box-shadow:inset -3px -3px 0 rgba(0,0,0,.3);animation:autoMinePulse 1.4s ease-in-out infinite}
.auto-mine-btn.active .am-sub{color:var(--gold);font-variant-numeric:tabular-nums}
@keyframes autoMinePulse{
  0%,100%{box-shadow:inset -3px -3px 0 rgba(0,0,0,.3),0 0 6px rgba(242,193,78,.4)}
  50%{box-shadow:inset -3px -3px 0 rgba(0,0,0,.3),0 0 13px rgba(242,193,78,.85)}}
@media (prefers-reduced-motion:reduce){.auto-mine-btn.active{animation:none}}

/* ── 채굴장 — 펫이 우측 광산 ↔ 좌측 수레 왕복 운반 (Kenney 배경 타일맵 하늘 + 흙 바닥 + GHUB 펫 SVG) ── */
.mine{position:relative;width:100%;height:var(--mine-h);overflow:hidden;cursor:pointer;
  user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent;
  border:3px solid var(--line);
  /* Kenney tilemap-backgrounds(파랑 테마) 하늘 — 구름·나무 띠는 .mine::before, 흙 바닥은 .mine-floor */
  background:linear-gradient(180deg,#eafbfa 0%,#dff6f5 48%,#d4f1f2 100%);
  box-shadow:inset -3px -3px 0 rgba(0,0,0,.28),inset 3px 3px 0 rgba(255,255,255,.18)}
.mine:active{box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),inset 3px 3px 0 rgba(0,0,0,.12)}
/* 원경 구름+나무 실루엣 띠 — Kenney 배경 타일셋 파랑 row1 [8,9,10,11]을 가로로 무한 타일.
   하단을 바닥 타일(.mine-floor 32px) 뒤로 8px 끼워(bottom 24px + 높이 40px) 단색 밑단을 가리고,
   z-index:0 이라 바닥·펫·광산입구(z≥1)보다 뒤·하늘 그라데이션보다 앞에 그려진다. 아주 느리게 흐른다. */
.mine::before{content:"";position:absolute;left:0;width:calc(100% + 160px);bottom:24px;height:40px;z-index:0;
  pointer-events:none;image-rendering:pixelated;will-change:transform;
  background:url(/assets/bg/cloudband.png) repeat-x left center / auto 40px;
  animation:cloudDrift 90s linear infinite}
/* 한 타일(160px)만큼 transform 이동=1바퀴. background-position(매 프레임 재페인트) 대신 transform(GPU 합성).
   요소를 컨테이너보다 160px 넓혀(.mine overflow:hidden 이 클립) 이동 내내 빈틈 없이 덮는다. */
@keyframes cloudDrift{from{transform:translateX(0)}to{transform:translateX(-160px)}}
@media (prefers-reduced-motion:reduce){.mine::before{animation:none}}
.mine-tap-hint{position:absolute;top:4px;left:4px;z-index:7;font-size:9px;
  color:#4a3620;background:rgba(255,255,255,.55);padding:2px 5px;border-radius:2px;pointer-events:none}
.mine-floor{position:absolute;left:0;right:0;bottom:0;height:32px;image-rendering:pixelated;
  background:url(/assets/mine/tile_0002.png) left bottom / 32px 32px repeat-x;
  border-top:2px solid rgba(0,0,0,.3)}
/* 우측 광산 입구(굴) */
.mine-entrance{position:absolute;right:0;bottom:24px;width:80px;height:76px;
  background:url(/assets/mine/entrance.svg) right bottom / 80px 76px no-repeat}
.mine-entrance.back{z-index:1;clip-path:inset(0 50% 0 0)}    /* 왼쪽 절반 — 펫 뒤(나올 때 펫이 앞) */
.mine-entrance.front{z-index:5;clip-path:inset(0 0 0 50%)}   /* 오른쪽 절반 — 펫 앞(들어가면 가려짐) */
.mine-entrance-label{position:absolute;right:18px;bottom:74px;width:44px;text-align:center;
  z-index:6;font-size:9px;color:#4a3620;text-shadow:0 1px 0 rgba(255,255,255,.6)}
/* 좌측 수레 */
.mine-cart{position:absolute;left:4px;bottom:28px;width:32px;height:28px;z-index:3;
  background:url(/assets/mine/cart.svg) center bottom / 32px 28px no-repeat;image-rendering:pixelated}
/* 펫 왕복 컨테이너 */
.mine-crew{position:absolute;inset:0;z-index:2}
.mine-empty{position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);
  text-align:center;font-size:10px;color:var(--muted)}
.miner{position:absolute;bottom:24px;left:0;width:32px;height:32px;will-change:transform}  /* 위치는 mineTick(JS)가 transform 으로 매 프레임 설정(GPU 합성 레이어) */
.miner-pet{display:block;width:32px;height:32px}
.miner-pet .pet-img{display:block;image-rendering:auto;filter:drop-shadow(0 1px 0 rgba(0,0,0,.45))}
.miner-rock{position:absolute;top:-13px;left:50%;transform:translateX(-50%);opacity:0;
  width:15px;height:15px;background-size:contain;background-repeat:no-repeat;background-position:center;
  image-rendering:pixelated}
/* 크리티컬 — 들고 나오는 광물이 다이아(tile_0067)로, 반짝 */
.miner-rock.crit{background-image:url(/assets/mine/tile_0067.png)!important;
  filter:drop-shadow(0 0 4px var(--gold)) drop-shadow(0 0 2px #fff)}
/* 카트 담기 연출 — 펫이 카트에 도착하면 광물이 머리에서 카트로 톡 떨어진다(JS가 .ore-toss 1회 생성) */
.ore-toss{position:absolute;left:50px;bottom:50px;width:14px;height:14px;
  background-size:contain;background-repeat:no-repeat;image-rendering:pixelated;
  z-index:4;pointer-events:none;animation:oreToCart .55s cubic-bezier(.45,0,.7,1) forwards}
.ore-toss.crit{filter:drop-shadow(0 0 3px #6fd6ff)}
@keyframes oreToCart{
  0%   {transform:translate(0,0) scale(1);            opacity:1}
  35%  {transform:translate(-10px,-12px) scale(1.05); opacity:1}   /* 살짝 떠오름(포물선 정점) */
  100% {transform:translate(-34px,20px) scale(.4);    opacity:0}   /* 카트(좌하)로 쏙 */
}

.tabs{display:flex;gap:6px}
/* 탭은 완전한 테두리(4면) — 과거 border-bottom:none 은 패널과 붙는 폴더탭 의도였으나
   #app gap(12px)이 연결을 끊어 '바닥 잘린 상자'로 보였다. 4면 테두리로 완성형 탭 버튼이 된다. */
.tab{flex:1;font-family:inherit;cursor:pointer;font-size:12px;padding:10px 4px;color:var(--muted);
  background:var(--panel2);border:3px solid var(--line)}
.tab.active{color:var(--gold);background:var(--panel);transform:translateY(0);box-shadow:inset 0 3px 0 var(--gold)}

.panel{padding:12px;display:flex;flex-direction:column;gap:10px}
.panel.hidden{display:none}
.panel h2{font-size:14px;color:var(--gold)}
.panel h3{font-size:12px;color:var(--muted);margin-top:6px}

.big-action{font-family:inherit;cursor:pointer;font-size:14px;color:#2a1d0c;background:var(--gold);
  border:3px solid var(--line);box-shadow:inset -4px -4px 0 var(--gold-lo);padding:14px;width:100%}
.big-action:active{transform:translateY(2px)}
.big-action.gold{background:var(--gold)}
.big-action:disabled{opacity:.45;cursor:not-allowed}

.ghub-desc,.ghub-state{font-size:11px;color:var(--muted);line-height:1.6}
.claim-box{padding:14px;display:flex;flex-direction:column;gap:10px;align-items:center}
.claimable{font-size:13px}
.claimable strong{font-size:22px;color:var(--gold)}

.toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);
  background:var(--panel2);border:3px solid var(--line);color:var(--ink);
  padding:12px 16px;font-size:12px;max-width:90%;text-align:center;z-index:50;
  box-shadow:inset -3px -3px 0 rgba(0,0,0,.4)}
.toast.hidden{display:none}
.toast.legendary{border-color:var(--leg);box-shadow:0 0 14px var(--leg)}
.toast.epic{border-color:var(--epic)}
.toast.rare{border-color:var(--rare)}

@keyframes pop{0%{transform:translate(-50%,8px) scale(.9);opacity:0}100%{transform:translate(-50%,0) scale(1);opacity:1}}
.toast:not(.hidden){animation:pop .15s ease-out}

/* ── 로그인 게이트 (미인증 401) ────────────────────────── */
.login-gate{
  position:fixed;inset:0;z-index:40;
  display:flex;align-items:center;justify-content:center;padding:24px;
  background:var(--bg);
  background-image:linear-gradient(rgba(0,0,0,.25) 1px,transparent 1px),linear-gradient(90deg,rgba(0,0,0,.25) 1px,transparent 1px);
  background-size:16px 16px;
}
.login-gate.hidden{display:none}
.gate-card{
  /* 🔴 width 를 반드시 명시한다. 없으면 카드 너비가 "내용이 밀어낸 만큼"으로 정해지는데,
     제목 자리에 width:100% 인 그림(로고)을 넣으면 퍼센트는 너비 계산에 기여하지 않아
     카드가 통째로 쪼그라든다(실제로 313px → 131px 로 무너졌다). */
  width:100%;max-width:340px;text-align:center;
  background:var(--panel);border:3px solid var(--line);
  box-shadow:inset -4px -4px 0 rgba(0,0,0,.3),6px 6px 0 var(--line);
  padding:28px 22px;
}
.gate-emoji{font-size:44px;line-height:1;margin-bottom:6px}
.gate-title{font-size:16px;color:var(--gold);text-shadow:2px 2px 0 var(--line);margin-bottom:4px}
/* 부제 — 제목과 한 덩어리(로고 락업)로 읽히도록 간격을 좁게 붙인다.
   이름을 한 줄에 다 넣으면 340px 카드에서 어중간하게 줄바꿈된다. */
/* 로그인 카드 제목 자리에 로고 그림을 넣는다. 그림 안에 게임 이름이 이미 있어
   텍스트를 겹쳐 쓰지 않는다(h1 은 남기고 alt 가 이름을 대신한다).
   ⚠️ .gate-title 은 가입·카카오·복구 카드도 함께 쓰므로 **전용 클래스에만** 건다 —
      전역으로 line-height 를 0 으로 만들면 나머지 세 카드의 제목이 겹쳐 버린다. */
.gate-title-logo{line-height:0;margin-bottom:2px}
.gate-logo{display:block;width:100%;max-width:200px;height:auto;margin:0 auto}
.gate-tagline{font-size:10px;color:var(--muted);letter-spacing:.05em;margin-bottom:16px}
.gate-msg{font-size:11px;color:var(--ink);line-height:1.8;margin-bottom:18px}
.gate-msg b{color:var(--gold)}
.gate-input{
  display:block;width:100%;box-sizing:border-box;margin:8px 0;
  font-family:inherit;font-size:12px;color:var(--ink);
  background:var(--panel2);border:3px solid var(--line);padding:11px 12px;
}
.gate-input::placeholder{color:var(--muted)}
.gate-input:focus{outline:none;border-color:var(--gold)}
.gate-btn{
  display:block;width:100%;box-sizing:border-box;margin-top:6px;
  font-family:inherit;font-size:13px;color:#2a1d0c;background:var(--gold);
  border:3px solid var(--line);box-shadow:inset -3px -3px 0 var(--gold-lo);
  padding:11px 22px;text-decoration:none;cursor:pointer;
}
.gate-btn:active{transform:translateY(2px)}
.gate-btn:disabled{opacity:.55;cursor:not-allowed}
.gate-err{font-size:11px;color:#f0907e;line-height:1.5;margin-top:10px}
.gate-err.hidden{display:none}
.gate-sub{font-size:10px;color:var(--muted);line-height:1.6;margin-top:16px}

/* ── 초대 계정 (가입 · 비밀번호 찾기) ─────────────────────────
   같은 .login-gate 안에서 카드만 갈아 끼운다(별도 화면을 만들면 배경·중앙정렬을
   두 벌로 관리하게 된다). 접두사 extgate- 는 전역 클래스 충돌을 피하려는 것. */
.gate-card.hidden{display:none}
.extgate-links{display:flex;align-items:center;justify-content:center;gap:8px;margin-top:12px}
.extgate-sep{color:var(--line)}
.extgate-link{
  font-family:inherit;font-size:10px;color:var(--gold);line-height:1.6;
  background:none;border:none;padding:2px 0;cursor:pointer;text-decoration:underline;
}
.extgate-link:active{transform:translateY(1px)}
.extgate-note{text-align:left;margin-top:12px;color:var(--ink);opacity:.85}
.extgate-note b{color:var(--gold)}
.extgate-ok{color:var(--gold)}
.extgate-ok.hidden{display:none}
/* ── 카카오 로그인 ────────────────────────────────────────
   브랜드 색(#FEE500·글자 85% 검정)은 카카오 가이드가 정한 값이라 테마 변수로
   빼지 않는다 — 다크·라이트 어느 쪽에서도 같아야 하는 남의 브랜드다.
   대신 테두리·그림자는 게임의 픽셀 톤(.gate-btn)과 맞춰 이질감을 줄인다. */
.kakao-block{margin-bottom:4px}
.kakao-block.hidden{display:none}
.kakao-btn{
  display:flex;align-items:center;justify-content:center;gap:8px;
  width:100%;box-sizing:border-box;
  font-family:inherit;font-size:13px;color:rgba(0,0,0,.85);background:#FEE500;
  border:3px solid var(--line);box-shadow:inset -3px -3px 0 #d9c400;
  padding:11px 18px;cursor:pointer;
}
.kakao-btn:active{transform:translateY(2px)}
.kakao-btn:disabled{opacity:.55;cursor:not-allowed}
.kakao-symbol{width:18px;height:18px;flex:0 0 auto}

/* 구분선 — "또는 아이디로". 선 사이에 글자를 앉힌다. */
.gate-divider{
  display:flex;align-items:center;gap:10px;
  margin:16px 0 4px;color:var(--muted);font-size:10px;
}
.gate-divider::before,.gate-divider::after{
  content:"";flex:1;height:3px;background:var(--line);
}

/* 이어받기를 켜면 닉네임 칸이 잠긴다 — 그 이유를 바로 아래에 적는다. */
.claim-locked-note{text-align:left;margin-top:6px;color:var(--gold)}
.claim-locked-note.hidden{display:none}
.gate-input:disabled{opacity:.55;cursor:not-allowed}

/* ── 헤더 닉네임 편집 ──────────────────────────────────────
   헤더는 좁아서 별도 화면을 띄우지 않고 그 자리에서 바꾼다.
   편집 중에는 이름 표시를 감춰 폭이 두 배로 벌어지지 않게 한다. */
.who-edit{
  font-family:inherit;font-size:10px;line-height:1;
  background:none;border:none;padding:2px 4px;cursor:pointer;opacity:.7;
}
.who-edit:hover{opacity:1}
.who-edit.hidden,#who.hidden,.who-edit-box.hidden{display:none}
.who-edit-box{display:inline-flex;align-items:center;gap:4px}
.who-input{
  font-family:inherit;font-size:11px;color:var(--ink);width:110px;
  background:var(--panel2);border:2px solid var(--line);padding:3px 6px;
}
.who-input:focus{outline:none;border-color:var(--gold)}
.who-btn{
  font-family:inherit;font-size:10px;color:#2a1d0c;background:var(--gold);
  border:2px solid var(--line);padding:3px 7px;cursor:pointer;
}
.who-btn.ghost{background:var(--panel2);color:var(--muted)}
.who-btn:disabled{opacity:.55;cursor:not-allowed}
/* 1회성 경고 — 편집칸 옆에 붙어 "지금 쓰면 끝"임을 알린다. */
.who-once{font-size:9px;color:var(--gold);white-space:nowrap}
/* 이미 써 버린 뒤의 연필 — 지우지 않고 흐리게 둔다. 사라지면 "어디 갔지"가 되고,
   눌렀을 때 이유를 알려 주므로 '눌러도 아무 일 없는 버튼'도 아니다. */
.who-edit.is-used{opacity:.3}


/* ── 이용 동의 게이트 ──────────────────────────────────────
   로그인 뒤 게임 진입 전 관문. 본문이 길어 카드 안쪽만 스크롤한다
   (카드 전체를 스크롤시키면 동의 버튼이 화면 밖으로 밀린다). */
/* z-index 는 하단 모드 내비(.game-mode-nav = 70)보다 위여야 한다.
   게이트가 아래에 깔리면 동의 전에 게임 내비가 노출되고 안내 문구까지 가린다. */
.consent-gate{
  position:fixed;inset:0;z-index:80;
  display:flex;align-items:center;justify-content:center;padding:16px;
  background:var(--bg);
  background-image:linear-gradient(rgba(0,0,0,.25) 1px,transparent 1px),linear-gradient(90deg,rgba(0,0,0,.25) 1px,transparent 1px);
  background-size:16px 16px;
}
.consent-gate.hidden{display:none}
/* 게이트가 떠 있는 동안은 게임 UI(하단 모드 내비)를 완전히 치운다 —
   z-index 만으로는 내비가 게이트 카드 아래 여백에 그대로 보인다. */
body.consent-open .game-mode-nav{display:none!important}
.consent-card{
  width:100%;max-width:520px;max-height:calc(100vh - 32px);
  display:flex;flex-direction:column;text-align:center;
  background:var(--panel);border:3px solid var(--line);
  box-shadow:inset -4px -4px 0 rgba(0,0,0,.3),6px 6px 0 var(--line);
  padding:20px 18px;box-sizing:border-box;
}
.consent-emoji{font-size:36px;line-height:1;margin-bottom:4px}
.consent-title{font-size:15px;color:var(--gold);text-shadow:2px 2px 0 var(--line);margin-bottom:10px}
.consent-intro{font-size:10px;color:var(--ink);line-height:1.8;margin-bottom:14px;text-align:left}
.consent-items{
  flex:1;min-height:0;overflow-y:auto;text-align:left;
  border:3px solid var(--line);background:var(--panel2);padding:10px;
}
.consent-item{padding:9px 0;border-bottom:2px dashed var(--dirt-lo)}
.consent-item:last-child{border-bottom:none}
.consent-item-head{display:flex;align-items:flex-start;gap:7px;cursor:pointer}
.consent-item-head input{margin-top:2px;flex-shrink:0;width:14px;height:14px;accent-color:var(--gold)}
.consent-item-title{font-size:11px;color:var(--gold);line-height:1.5}
.consent-item-req{font-size:9px;color:#f0907e;margin-left:4px}
.consent-item-body{
  font-size:10px;color:var(--ink);line-height:1.9;margin-top:6px;padding-left:21px;
  white-space:pre-line;   /* 본문 개행(\n)을 그대로 보여준다 */
}
.consent-all{
  display:flex;align-items:center;gap:8px;justify-content:center;
  font-size:11px;color:var(--ink);margin-top:12px;cursor:pointer;
}
.consent-all input{width:16px;height:16px;accent-color:var(--gold)}
.consent-err{font-size:10px;color:#f0907e;line-height:1.5;margin-top:8px}
.consent-err.hidden{display:none}
.consent-actions{display:flex;gap:8px;margin-top:12px}
.consent-btn{
  flex:1;font-family:inherit;font-size:12px;
  border:3px solid var(--line);padding:11px 10px;cursor:pointer;
}
.consent-btn.primary{color:#2a1d0c;background:var(--gold);box-shadow:inset -3px -3px 0 var(--gold-lo)}
.consent-btn.ghost{color:var(--muted);background:var(--panel2);box-shadow:inset -3px -3px 0 rgba(0,0,0,.25)}
.consent-btn:active{transform:translateY(2px)}
.consent-btn:disabled{opacity:.5;cursor:not-allowed;transform:none}
.consent-sub{font-size:9px;color:var(--muted);line-height:1.7;margin-top:10px}
.consent-sub b{color:var(--ink)}
.consent-version{display:block;margin-top:3px;opacity:.7}

/* ── 펫 도우미 ──────────────────────────────────────────── */
.pet-desc{font-size:11px;color:var(--muted);line-height:1.6}
.pet-desc b{color:var(--gold)}
.pet-banner{display:flex;align-items:center;gap:10px;padding:12px;position:relative}
.pet-banner-label{font-size:11px;color:var(--muted)}
.pet-banner strong{font-size:22px;color:var(--gold);text-shadow:2px 2px 0 var(--line)}
.pet-count{font-size:11px;color:var(--muted);margin-left:auto}

.pet-slots{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.pet-slot{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  padding:10px 4px;min-height:104px;text-align:center;position:relative}
.pet-slot.empty{background:var(--panel2);box-shadow:none;border-style:dashed;border-color:var(--dirt-lo);opacity:.85}
.pet-slot.filled{cursor:pointer}
.pet-slot-plus{font-size:24px;color:var(--dirt-lo)}
.pet-slot-hint{font-size:10px;color:var(--muted)}
.pet-slot-name{font-size:10px;color:var(--ink);line-height:1.2;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pet-slot-bonus{font-size:11px;color:var(--gold)}
.pet-slot-x{position:absolute;top:2px;right:4px;font-size:10px;color:var(--muted)}
.pet-slot.filled:hover .pet-slot-x{color:#f0907e}

.pet-list{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
/* 가상 스크롤 스페이서 — 화면 밖 행 자리를 대신 차지해 스크롤 길이를 보존한다(game.js renderPetWindow).
   한 줄을 통째로 먹어야 아래 카드가 그 옆에 끼어들지 않는다. */
.pet-vpad{grid-column:1/-1}
.pet-card{display:flex;flex-direction:column;align-items:center;gap:3px;padding:8px 4px;text-align:center}
.pet-card-art{height:54px;display:flex;align-items:center;justify-content:center}
.pet-card-name{font-size:10px;color:var(--ink);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 높이 3줄 고정 — 가상 스크롤(game.js renderPetWindow)이 '행 높이는 일정하다'를 전제로 스페이서를
   계산하는데, 이 줄이 2줄↔3줄로 접히면 행마다 어긋난다(실측 카드 높이 190.28 / 205.28 = 15px 차).
   그대로 두면 스크롤할 때마다 평균 행 피치가 흔들려 스크롤 위치가 튄다.
   이름(.pet-card-name)이 이미 말줄임을 쓰는 것과 같은 방침으로, 넘치는 줄은 감춘다. */
.pet-card-meta{font-size:9px;color:var(--muted);line-height:1.35;height:calc(1.35em * 3);overflow:hidden}
.pet-card-bonus{font-size:10px;color:var(--gold)}
.pet-card.is-deployed{box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),0 0 6px var(--gold)}
.pet-btn{margin-top:4px;font-family:inherit;cursor:pointer;font-size:11px;width:100%;
  color:#2a1d0c;background:var(--gold);border:2px solid var(--line);box-shadow:inset -2px -2px 0 var(--gold-lo);padding:6px}
.pet-btn.off{background:var(--panel2);color:var(--muted);box-shadow:inset -2px -2px 0 rgba(0,0,0,.3)}
.pet-btn:active{transform:translateY(1px)}
.pet-img{image-rendering:auto}   /* 펫은 벡터 SVG — 픽셀화 끔 */
/* 등급 오라 — GHUB(pet_auras.py)가 오라 SVG(애니 포함)를 내려주면 펫 뒤(z-0)에 펫보다 크게 깐다.
   래퍼는 펫 크기, 오라는 150%로 넘쳐 그려지고(overflow:visible) 펫 본체는 그 위(z-1). */
.pet-aura-wrap{position:relative;display:inline-flex;align-items:center;justify-content:center;vertical-align:bottom;line-height:0}
.pet-aura{position:absolute;left:50%;top:50%;width:150%;height:150%;transform:translate(-50%,-50%);pointer-events:none;z-index:0}
.pet-aura,.pet-aura svg{display:block;overflow:visible}
.pet-aura svg{width:100%;height:100%}
.pet-aura-wrap>.pet-img{position:relative;z-index:1}
.pet-empty{font-size:11px;color:var(--muted);text-align:center;line-height:1.7;padding:8px}
/* 첫 펫이 없을 때의 길 안내 — 뽑기 입구가 컬렉션 안에 숨어 있어 처음 오는 사람은 못 찾는다. */
.pet-empty-go{display:block;margin:12px auto 4px;font-family:inherit;font-size:11px;
  color:#2a1d0c;background:var(--gold);border:3px solid var(--line);
  box-shadow:inset -3px -3px 0 var(--gold-lo);padding:10px 18px;cursor:pointer}
.pet-empty-go:active{transform:translateY(2px)}

/* 희귀도별 배치 슬롯 (등급당 N칸) */
.pet-h3-sub{font-size:10px;color:var(--muted)}
.pet-slots-rarity{display:flex;flex-direction:column;gap:6px}
.pet-rarity-row{display:flex;align-items:stretch;gap:6px}
.pet-rarity-tag{flex:0 0 34px;display:flex;align-items:center;justify-content:center;text-align:center;
  font-size:10px;line-height:1.2;padding:2px;border:2px solid var(--line);background:var(--panel2)}
.pet-rarity-cells{flex:1;display:grid;grid-template-columns:1fr 1fr;gap:6px}
.pet-rarity-cells .pet-slot{min-height:72px;padding:6px 3px;gap:2px}
.pet-rarity-cells .pet-slot .pet-slot-name{font-size:9px}
.pet-rarity-cells .pet-slot .pet-slot-bonus{font-size:10px}
.pet-rarity-tag.common{color:var(--com)}
.pet-rarity-tag.uncommon{color:var(--unc)}
.pet-rarity-tag.rare{color:var(--rare)}
.pet-rarity-tag.epic{color:var(--epic)}
.pet-rarity-tag.legendary{color:var(--leg)}
.pet-btn.full{background:var(--panel2);color:var(--muted);box-shadow:inset -2px -2px 0 rgba(0,0,0,.3);cursor:not-allowed;opacity:.7}

/* ── 유물 조각 오도미터(자릿수 0~9 롤링) + 크리티컬 ───────────── */
#shards.odo{display:inline-flex;justify-content:center;line-height:1}
.odo-digit{display:inline-block;height:1em;line-height:1em;overflow:hidden;width:.62em;vertical-align:bottom}
.odo-strip{display:flex;flex-direction:column;will-change:transform}
.odo-strip>span{height:1em;line-height:1em;text-align:center}
.crit-flash{animation:critFlash .9s}
@keyframes critFlash{0%,100%{filter:none}30%,60%{filter:brightness(1.7) drop-shadow(0 0 6px var(--gold))}}
.crit-pop{position:absolute;top:4px;right:6px;z-index:10;
  font-size:10px;color:#fff;background:var(--leg);border:2px solid var(--line);
  padding:3px 7px;box-shadow:2px 2px 0 var(--line);white-space:nowrap;animation:critPop .9s ease-out}
.crit-pop.hidden{display:none}
@keyframes critPop{
  0%{transform:translateY(8px) scale(.8);opacity:0}
  25%{transform:translateY(0) scale(1.12);opacity:1}
  70%{transform:translateY(-2px) scale(1);opacity:1}
  100%{transform:translateY(-12px);opacity:0}}

/* ── 오프라인 복귀 보상 모달 ───────────────────────────── */
.offline-modal{
  position:fixed;inset:0;z-index:60;
  display:flex;align-items:center;justify-content:center;padding:24px;
  background:rgba(0,0,0,.55);
}
.offline-modal.hidden{display:none}
.offline-card{
  max-width:320px;text-align:center;
  background:var(--panel);border:3px solid var(--line);
  box-shadow:inset -4px -4px 0 rgba(0,0,0,.3),6px 6px 0 var(--line);
  padding:26px 22px;
  animation:offlinePop .22s ease-out;
}
@keyframes offlinePop{0%{transform:scale(.85);opacity:0}100%{transform:scale(1);opacity:1}}
.offline-emoji{font-size:46px;line-height:1;margin-bottom:8px}
.offline-title{font-size:16px;color:var(--gold);text-shadow:2px 2px 0 var(--line);margin-bottom:14px}
.offline-msg{font-size:12px;color:var(--ink);line-height:1.9}
.offline-gain{font-size:22px;color:var(--gold);text-shadow:2px 2px 0 var(--line)}
.offline-capped{font-size:10px;color:var(--muted);margin-top:10px}
.offline-capped.hidden{display:none}
.offline-btn{
  margin-top:18px;font-family:inherit;font-size:13px;cursor:pointer;
  color:#2a1d0c;background:var(--gold);
  border:3px solid var(--line);box-shadow:inset -3px -3px 0 var(--gold-lo);
  padding:11px 28px;
}
.offline-btn:active{transform:translateY(2px)}
/* 전환 확인 모달 (offline-modal 재사용 + 버튼 2개) */
.claim-actions{display:flex;gap:10px;justify-content:center}
.offline-btn.ghost{color:var(--ink);background:var(--panel);box-shadow:inset -3px -3px 0 rgba(0,0,0,.25)}
.claim-sub{font-size:11px;color:var(--muted)}
.claim-cap-note{font-size:11px;color:var(--muted);margin-top:12px}

/* 등급 테두리 (펫) — --pet-bc 는 GHUB 펫 마스터의 종별 지정색(인라인 주입). 없으면 등급 기본색. */
.pet-slot.common,.pet-card.common,.craft-cell.common,.craft-slot.common,.gacha-item.common,.fx-cell.common{border-color:var(--pet-bc,var(--com))}
.pet-slot.uncommon,.pet-card.uncommon,.craft-cell.uncommon,.craft-slot.uncommon,.gacha-item.uncommon,.fx-cell.uncommon{border-color:var(--pet-bc,var(--unc))}
.pet-slot.rare,.pet-card.rare,.craft-cell.rare,.craft-slot.rare,.gacha-item.rare,.fx-cell.rare{border-color:var(--pet-bc,var(--rare))}
.pet-slot.epic,.pet-card.epic,.craft-cell.epic,.craft-slot.epic,.gacha-item.epic,.fx-cell.epic{border-color:var(--pet-bc,var(--epic))}
.pet-slot.legendary,.pet-card.legendary,.craft-cell.legendary,.craft-slot.legendary,.gacha-item.legendary,.fx-cell.legendary{border-color:var(--pet-bc,var(--leg));
  box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),0 0 8px var(--pet-bc,var(--leg))}

/* 종별 지정색(.bc) — 등급색 5종만으로는 히든/이벤트 종이 같은 레전드 노랑에 묻힌다.
   3px 기본 테두리 + 안쪽 3px 링 = 실질 6px, 배경도 그 색 틴트로 깔고 바깥 글로우까지 준다.
   ⚠ 두께는 반드시 box-shadow(inset 링)로 낸다 — border-width 를 키우면 카드 높이가 종마다
   달라져 펫 목록 가상 스크롤(game.js renderPetWindow)의 '행 높이 일정' 전제가 깨진다. */
.pet-card.bc,.pet-slot.filled.bc{
  border-color:var(--pet-bc);
  background-image:linear-gradient(165deg,var(--pet-bc-soft) 0%,rgba(0,0,0,0) 72%);
  box-shadow:
    inset 0 0 0 3px var(--pet-bc),
    inset -3px -3px 0 rgba(0,0,0,.35),
    inset 3px 3px 0 rgba(255,255,255,.06),
    0 0 11px var(--pet-bc-glow);
}
/* 배치 완료 카드는 금색 글로우가 지정색 글로우를 덮지 않게 둘 다 남긴다. */
.pet-card.bc.is-deployed{
  box-shadow:
    inset 0 0 0 3px var(--pet-bc),
    inset -3px -3px 0 rgba(0,0,0,.35),
    0 0 6px var(--gold),
    0 0 12px var(--pet-bc-glow);
}

/* ── 아이템 가방 ─────────────────────────────────────────── */
.item-desc{font-size:11px;color:var(--muted);line-height:1.6}
.item-desc b{color:var(--gold)}

/* 상자 섹션 */
.box-section{display:flex;flex-direction:column;gap:8px}
.box-card{display:flex;align-items:center;gap:12px;padding:12px;
  background:var(--panel);border:3px solid var(--line);
  box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),inset 3px 3px 0 rgba(255,255,255,.06)}
.box-card.legend{border-color:var(--leg);box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),0 0 10px var(--leg)}
.box-card.hidden{display:none}
.box-img{width:44px;height:44px;image-rendering:pixelated;animation:boxBob 2.4s ease-in-out infinite}
@keyframes boxBob{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}
@media (prefers-reduced-motion:reduce){.box-img{animation:none}}
.box-info{flex:1;display:flex;align-items:center;justify-content:space-between;gap:10px}
.box-count{font-size:12px;color:var(--ink)}
.box-count strong{font-size:18px;color:var(--gold);text-shadow:2px 2px 0 var(--line)}
.box-open-btn{font-family:inherit;cursor:pointer;font-size:12px;color:#2a1d0c;background:var(--gold);
  border:3px solid var(--line);box-shadow:inset -3px -3px 0 var(--gold-lo);padding:10px 14px;white-space:nowrap}
.box-open-btn:active:not(:disabled){transform:translateY(2px)}
.box-open-btn:disabled{opacity:.4;cursor:not-allowed}
.box-open-btn.legend{background:var(--leg)}
/* 상자 분해 — 되돌릴 수 없는 소모라 '열기'와 색으로 구분한다(라임=분해 계열). */
.box-open-btn.decompose{background:#b6d97a}
.box-open-btn.decompose.hidden{display:none}

/* 활성 부스트 바 */
.active-boosts{display:flex;flex-wrap:wrap;align-items:center;gap:6px;padding:8px 10px;
  background:var(--panel2);border:3px solid var(--line)}
.active-boosts.hidden{display:none}
.ab-title{font-size:10px;color:var(--muted)}
.ab-chip{display:inline-flex;align-items:center;gap:4px;font-size:11px;
  background:var(--panel);border:2px solid var(--line);padding:3px 6px}
.ab-chip img{width:16px;height:16px;image-rendering:pixelated}
.ab-chip.rate{border-color:var(--unc)}
.ab-chip.crit{border-color:var(--leg)}
.ab-label{color:var(--ink)}
.ab-time{color:var(--gold);font-variant-numeric:tabular-nums}

/* 장착(전시) */
.equipped-row{display:flex;flex-wrap:wrap;align-items:center;gap:6px;padding:8px 10px;
  background:var(--panel2);border:3px solid var(--line)}
.equipped-row.hidden{display:none}
.eq-title{font-size:10px;color:var(--muted)}
.eq-chip{display:inline-flex;align-items:center;gap:4px;font-size:10px;cursor:pointer;
  background:var(--panel);border:2px solid var(--gold);padding:3px 6px}
.eq-chip img{width:18px;height:18px;image-rendering:pixelated}

/* 카테고리 필터 칩 */
.item-filters{display:flex;flex-wrap:wrap;gap:5px}
.chip{font-family:inherit;cursor:pointer;font-size:11px;color:var(--muted);
  background:var(--panel2);border:2px solid var(--line);padding:6px 9px}
.chip.active{color:var(--gold);border-color:var(--gold)}

/* 가방 그리드 */
.item-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
/* 상점 */
/* 상점 = 독립 화면(모드). 방치/던전 셸과 같은 폭 + 하단 모드나브 여백. */
.shop-shell{padding:12px 12px calc(var(--mode-nav-height,54px) + 24px);color:var(--ink);min-height:100vh;min-height:100dvh}
.shop-shell>.bar{margin-bottom:12px}
.shop-balance-bar{display:flex;align-items:stretch;gap:12px;margin:0 0 12px;padding:12px 14px}
.sbb-item{flex:1;display:flex;flex-direction:column;gap:3px;min-width:0}
.sbb-item.points{border-left:2px solid var(--dirt-lo);padding-left:12px}
.shop-balance-bar .label{font-size:11px;color:var(--muted)}
.shop-balance-label{display:flex;align-items:center;gap:5px}
.shop-balance-label img{width:15px;height:15px;display:block}
.shop-balance-bar .val{font-size:20px;color:var(--gold);font-variant-numeric:tabular-nums;overflow:hidden;text-overflow:ellipsis}
.sbb-item.points .val{color:var(--unc)}
.shop-desc{font-size:12px;color:var(--muted,#9aa);margin:0 0 8px}
.shop-balance{margin:0 0 10px;font-size:13px}
.shop-balance strong{color:var(--gold,#ffd76a)}
.shop-catalog{display:flex;flex-direction:column;gap:14px}
.shop-section{padding:10px;background:rgba(0,0,0,.12);border:2px solid var(--dirt-lo)}
.shop-section-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:9px;padding-bottom:7px;border-bottom:2px solid var(--dirt-lo)}
.shop-section-head>div{display:flex;flex-direction:column;gap:2px;min-width:0}
.shop-section-head strong{font-size:13px;color:var(--gold)}
.shop-section-head span{font-size:9px;color:var(--muted)}
.shop-section-head em{flex:0 0 auto;font-style:normal;font-size:10px;color:var(--muted);padding:2px 6px;border:1px solid var(--dirt-lo);border-radius:999px}
.shop-section-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}
.shop-section-empty{grid-column:1/-1;margin:0;padding:16px 4px;text-align:center;font-size:11px;color:var(--muted)}
.shop-item{display:flex;flex-direction:column;align-items:center;gap:5px;padding:10px 8px;text-align:center;
  background:var(--panel);border:3px solid var(--line);
  box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),inset 3px 3px 0 rgba(255,255,255,.06)}
.shop-item.sold-out{opacity:.55}
.shop-item-art{position:relative;display:grid;place-items:center;width:48px;height:48px;flex:0 0 auto}
.shop-img{position:absolute;inset:0;display:block;width:48px;height:48px;object-fit:contain;image-rendering:pixelated}
.shop-img[hidden]{display:none}
.shop-img-ph{display:grid;place-items:center;width:46px;height:46px;background:rgba(0,0,0,.10);color:var(--muted)}
.shop-img-ph::before{content:"";width:10px;height:10px;border:2px solid var(--dirt);border-top-color:var(--gold);border-radius:50%;animation:shopIconLoading .7s steps(8,end) infinite}
.shop-item-art.image-ready .shop-img-ph{visibility:hidden}
.shop-item-art.image-fallback .shop-img-ph{color:var(--gold)}
.shop-item-art.image-fallback .shop-img-ph::before{content:"?";width:auto;height:auto;border:0;border-radius:0;animation:none;font:700 16px/1 "Galmuri11","Galmuri9",sans-serif}
@keyframes shopIconLoading{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.shop-img-ph::before{animation:none}}
.shop-item-name{font-size:12px;font-weight:bold;line-height:1.2}
.shop-item-desc{font-size:10px;color:var(--muted,#9aa);line-height:1.25}
.shop-item-stock{display:flex;flex-wrap:wrap;gap:4px;justify-content:center;font-size:10px;color:var(--muted,#9aa);line-height:1.35;min-height:18px}
/* 재고/구매 현황 칩 — ① 글로벌 재고(전체·오늘) ② 내가 살 수 있는 수량 */
.ss{display:inline-flex;align-items:baseline;gap:1px;padding:2px 6px;background:var(--panel2);border:2px solid var(--line);color:var(--muted);white-space:nowrap}
.ss b{color:var(--ink);font-size:11px;font-weight:bold}
.ss i{font-style:normal;color:var(--muted);font-size:9px}
.ss-mine{border-color:var(--gold-lo);color:var(--gold)}
.ss-mine b{color:var(--gold)}
.ss-out{border-color:#8a3b32;color:#e8907f;background:#3a201c}
.ss-out b{color:#f2b3a6}
.ss-muted{opacity:.7}
.shop-buy-btn{margin-top:2px;width:100%;padding:6px 4px;font:inherit;font-size:11px;cursor:pointer;color:#fff;
  background:var(--accent,#4a7a55);border:none;
  box-shadow:inset -2px -2px 0 rgba(0,0,0,.35),inset 2px 2px 0 rgba(255,255,255,.12)}
.shop-buy-btn:disabled{opacity:.5;cursor:not-allowed}
.shop-price{display:inline-flex;align-items:center;justify-content:center;gap:4px;padding:0;border:0;background:transparent;box-shadow:none;color:var(--gold);font-size:12px;font-weight:bold;line-height:1}
.shop-currency-icon{display:block;width:16px;height:16px;flex:0 0 auto}
.shop-empty{font-size:12px;color:var(--muted,#9aa);text-align:center;padding:20px 0}
.shop-empty.hidden{display:none}
.item-card{position:relative;display:flex;flex-direction:column;align-items:center;gap:3px;
  padding:8px 4px;text-align:center;
  background:var(--panel);border:3px solid var(--line);
  box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),inset 3px 3px 0 rgba(255,255,255,.06)}
.item-art{height:40px;display:flex;align-items:center;justify-content:center}
.item-art img{width:32px;height:32px;image-rendering:pixelated}
.item-count{position:absolute;top:2px;right:4px;font-size:11px;color:var(--gold)}
.item-name{font-size:10px;color:var(--ink);line-height:1.2;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.item-rarity{font-size:9px}
.item-btn{margin-top:4px;font-family:inherit;cursor:pointer;font-size:11px;width:100%;
  color:#2a1d0c;background:var(--gold);border:2px solid var(--line);box-shadow:inset -2px -2px 0 var(--gold-lo);padding:5px}
.item-btn.on{background:var(--unc)}
.item-btn.off{background:var(--panel2);color:var(--muted);box-shadow:inset -2px -2px 0 rgba(0,0,0,.3)}
.item-btn:active{transform:translateY(1px)}
.item-card.equipped{box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),0 0 6px var(--gold)}
.item-empty,.item-empty-cat{font-size:11px;color:var(--muted);text-align:center;line-height:1.7;padding:8px;grid-column:1/-1}
.item-empty.hidden{display:none}

/* 등급 테두리/색 (아이템) */
.item-card.common{border-color:var(--com)} .item-rarity.common{color:var(--com)}
.item-card.uncommon{border-color:var(--unc)} .item-rarity.uncommon{color:var(--unc)}
.item-card.rare{border-color:var(--rare)} .item-rarity.rare{color:var(--rare)}
.item-card.epic{border-color:var(--epic)} .item-rarity.epic{color:var(--epic)}
.item-card.legendary{border-color:var(--leg);box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),0 0 8px var(--leg)}
.item-rarity.legendary{color:var(--leg)}

/* ── 전설 장비(legend) — 형광 테두리 + 영구 효과 표시 ───────────────────────── */
.item-effect{font-size:10px;color:#7CFFB2;text-shadow:0 0 4px #39ff14}
.item-card.lg .item-art{height:54px}
.item-card.lg .item-art img{width:auto;height:54px;max-width:100%}
.item-card.lg{border-color:#39ff14;animation:legendNeon 2s linear infinite}
@keyframes legendNeon{
  0%,100%{border-color:#39ff14;box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),0 0 7px #39ff14,0 0 14px #39ff14}
  33%{border-color:#00e5ff;box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),0 0 9px #00e5ff,0 0 18px #00e5ff}
  66%{border-color:#ff3df0;box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),0 0 9px #ff3df0,0 0 18px #ff3df0}
}
/* 장착된 전설 장비 효과 행(형광) */
.legend-row{display:flex;flex-wrap:wrap;align-items:center;gap:6px;padding:8px 10px;
  background:var(--panel2);border:3px solid #39ff14;box-shadow:0 0 8px rgba(57,255,20,.4)}
.legend-row.hidden{display:none}
.lr-title{font-size:9px;color:#7CFFB2}
.lr-chip{display:inline-flex;align-items:center;gap:4px;font-size:10px;cursor:pointer;
  background:var(--panel);border:2px solid #39ff14;padding:3px 7px;box-shadow:0 0 5px rgba(57,255,20,.5)}
.lr-chip img{width:auto;height:20px;image-rendering:pixelated}
.lr-chip span{color:var(--ink)}
/* 전설 장비 리빌 — 형광 + 큰 메달 */
.box-reveal.lg{border-color:#39ff14!important;animation:legendNeon 2s linear infinite}
.box-reveal.lg .reveal-rarity{color:#39ff14;border-color:#39ff14}
.box-reveal.lg .reveal-art{height:104px}
.box-reveal.lg .reveal-art img{width:auto;height:96px}
@media (prefers-reduced-motion:reduce){.item-card.lg,.box-reveal.lg{animation:none}}

.offline-boxes{font-size:11px;color:var(--gold);margin-top:8px}
.offline-boxes.hidden{display:none}

/* 상자 리빌 모달 */
.box-reveal{position:relative;overflow:hidden}
.reveal-burst{position:absolute;left:50%;top:46%;width:160px;height:160px;transform:translate(-50%,-50%);
  background:radial-gradient(circle,rgba(242,193,78,.45) 0%,transparent 60%);animation:revealBurst 1s ease-out;pointer-events:none}
@keyframes revealBurst{0%{transform:translate(-50%,-50%) scale(.2);opacity:0}40%{opacity:1}100%{transform:translate(-50%,-50%) scale(1.6);opacity:0}}
.reveal-emoji{font-size:34px;line-height:1}
.reveal-art{height:72px;display:flex;align-items:center;justify-content:center;margin:6px 0}
.reveal-art img{width:60px;height:60px;image-rendering:pixelated;animation:revealPop .4s cubic-bezier(.2,1.4,.5,1)}
@keyframes revealPop{0%{transform:scale(.2) rotate(-20deg);opacity:0}100%{transform:scale(1) rotate(0);opacity:1}}
.reveal-rarity{display:inline-block;font-size:10px;padding:2px 8px;border:2px solid var(--line);margin-bottom:6px}
.box-reveal.common .reveal-rarity{color:var(--com);border-color:var(--com)}
.box-reveal.uncommon .reveal-rarity{color:var(--unc);border-color:var(--unc)}
.box-reveal.rare .reveal-rarity{color:var(--rare);border-color:var(--rare)}
.box-reveal.epic .reveal-rarity{color:var(--epic);border-color:var(--epic)}
.box-reveal.legendary .reveal-rarity{color:var(--leg);border-color:var(--leg)}
.box-reveal.epic{box-shadow:inset -4px -4px 0 rgba(0,0,0,.3),0 0 14px var(--epic)}
.box-reveal.legendary{box-shadow:inset -4px -4px 0 rgba(0,0,0,.3),0 0 18px var(--leg)}

/* 럭키 오버레이 (상자 드롭 — 크리티컬처럼 잠깐) */
.lucky-overlay{position:fixed;inset:0;z-index:55;display:flex;align-items:center;justify-content:center;pointer-events:none}
.lucky-overlay.hidden{display:none}
.lucky-inner{display:flex;flex-direction:column;align-items:center;gap:8px}
.lucky-box{width:72px;height:72px;image-rendering:pixelated}
.lucky-text{font-size:22px;color:var(--gold);text-shadow:2px 2px 0 var(--line),0 0 12px var(--gold);text-align:center;line-height:1.4}
.lucky-text span{display:block;font-size:12px;color:var(--ink)}
.lucky-overlay.show .lucky-inner{animation:luckyPop 1.5s ease-out}
@keyframes luckyPop{0%{transform:scale(.4);opacity:0}15%{transform:scale(1.15);opacity:1}30%{transform:scale(1)}80%{transform:scale(1);opacity:1}100%{transform:scale(1.05) translateY(-10px);opacity:0}}
@media (prefers-reduced-motion:reduce){.lucky-overlay.show .lucky-inner{animation:none}.reveal-art img{animation:none}}
/* 럭키 상자 토스(카트로) — ore-toss 변형, 더 크고 금빛 */
.ore-toss.box{width:22px;height:22px;filter:drop-shadow(0 0 5px var(--gold));z-index:6}

/* ── 샤이니 잭팟 오오라 — 카드 틀을 넘쳐 눈부시게 빛난다(보유/배치/채굴 공통) ── */
.pet-card.shiny,.pet-slot.shiny.filled{position:relative;z-index:1;border-color:#fff6b0!important;
  animation:shinyPulse 1.6s ease-in-out infinite}
@keyframes shinyPulse{
  0%,100%{box-shadow:0 0 10px #ffe27a,0 0 22px rgba(255,226,122,.6),0 0 34px rgba(174,244,255,.3)}
  50%{box-shadow:0 0 20px #fff,0 0 40px #ffe27a,0 0 64px rgba(174,244,255,.55)}}
/* 사선 광택 스윕(유리 반짝임) — 보유 카드 */
.pet-card.shiny::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:3;
  background:linear-gradient(115deg,transparent 40%,rgba(255,255,255,.9) 49%,transparent 58%);
  background-size:280% 100%;background-repeat:no-repeat;animation:shinySweep 2.6s ease-in-out infinite}
@keyframes shinySweep{0%{background-position:200% 0}60%,100%{background-position:-120% 0}}
/* 채굴 중 펫 — 미너 SVG 에 금빛 광휘(mine 은 overflow:hidden 이라 글로우로) */
.miner.shiny .miner-pet{animation:minerShiny 1.5s ease-in-out infinite}
@keyframes minerShiny{
  0%,100%{filter:drop-shadow(0 0 4px #fff) drop-shadow(0 0 8px #ffe27a)}
  50%{filter:drop-shadow(0 0 9px #fff) drop-shadow(0 0 16px #ffd24d)}}
@media (prefers-reduced-motion:reduce){
  .pet-card.shiny,.pet-slot.shiny.filled,.pet-card.shiny::after,.miner.shiny .miner-pet{animation:none}
  .pet-card.shiny,.pet-slot.shiny.filled{box-shadow:0 0 16px #ffe27a}}

/* ── 장착 꾸미기 (모든 모드 헤더 배지 + 스티커 색 액센트) ─────────── */
.cosmetic-badges{display:inline-flex;align-items:center;gap:4px;margin-right:6px;vertical-align:middle}
.cb{display:inline-flex;width:22px;height:22px;align-items:center;justify-content:center;
  border:2px solid var(--line);background:var(--panel2);image-rendering:pixelated}
.cb img{width:16px;height:16px;image-rendering:pixelated}
.cb-medal{border-color:var(--gold)}
.cb-painting{border-color:var(--epic)}
.cb-sticker{border-color:var(--sticker,var(--gold))}
/* 스티커 장착 시에도 기본(베이스) 픽셀 테두리는 그대로 유지 — 테두리 색을 스티커색으로 덮어쓰지 않고,
   스티커 색은 은은한 외곽 글로우로만 입힌다(치장). 타이틀 글로우·헤더 코너 핀은 아래에서 별도 유지. */
body.has-sticker .bar,
body.has-sticker .hud,
body.has-sticker .site,
body.has-sticker .panel,
body.has-sticker .pet-banner,
body.has-sticker .shop-balance-bar,
body.has-sticker .shop-item,
body.has-sticker .shop-cat-heading{box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),inset 3px 3px 0 rgba(255,255,255,.06),0 0 9px var(--sticker)}
/* 방치 탭 바 전체에는 아주 옅은 빛을 두르고, 선택된 탭은 한 단계 더 또렷하게 표시한다. */
body.has-sticker .tabs{filter:drop-shadow(0 0 3px var(--sticker))}
body.has-sticker .tab.active{box-shadow:inset 0 3px 0 var(--sticker),0 0 6px var(--sticker);text-shadow:0 0 7px var(--sticker)}
body.has-sticker .shop-section-head{border-bottom-color:var(--sticker)}
/* 헤더 코너에 스티커 장식 핀 — 액자에 꽂은 스티커처럼 살짝 흔들린다 */
body.has-sticker .bar{position:relative}
body.has-sticker .bar::after{content:"";position:absolute;top:-9px;right:9px;width:20px;height:20px;
  background:var(--sticker-img,none) center/contain no-repeat;image-rendering:pixelated;
  filter:drop-shadow(0 0 4px var(--sticker));animation:stickerPin 2.6s ease-in-out infinite;pointer-events:none}
@keyframes stickerPin{0%,100%{transform:translateY(0) rotate(-7deg)}50%{transform:translateY(-2px) rotate(7deg)}}
body.has-sticker .cb-sticker{box-shadow:0 0 6px var(--sticker);animation:stickerPulse 2.2s ease-in-out infinite}
@keyframes stickerPulse{0%,100%{box-shadow:0 0 4px var(--sticker)}50%{box-shadow:0 0 11px var(--sticker)}}
@media (prefers-reduced-motion:reduce){body.has-sticker .cb-sticker,body.has-sticker .bar::after{animation:none}}

/* ── 피버 상태 (부스트 2개+ 겹침) — 화면 반짝임 + 🔥FEVER 배지 ──────────────── */
.fever-overlay{position:fixed;inset:0;z-index:45;pointer-events:none;display:none}
body.fever .fever-overlay{display:block}
.fever-ring{position:absolute;inset:0;animation:feverRing 1.1s ease-in-out infinite}
@keyframes feverRing{
  0%,100%{box-shadow:inset 0 0 14px rgba(242,193,78,.30), inset 0 0 38px rgba(242,161,62,.12)}
  50%{box-shadow:inset 0 0 calc(16px + var(--fever-n,2)*7px) rgba(242,193,78,.65),
              inset 0 0 calc(46px + var(--fever-n,2)*9px) rgba(242,161,62,.32)}
}
.fever-sparkles span{position:absolute;font-size:16px;opacity:0;
  filter:drop-shadow(0 0 4px var(--gold));animation:feverTwinkle 1.6s ease-in-out infinite}
.fever-sparkles span:nth-child(1){left:8%;top:18%;animation-delay:0s}
.fever-sparkles span:nth-child(2){left:87%;top:23%;animation-delay:.2s}
.fever-sparkles span:nth-child(3){left:15%;top:63%;animation-delay:.5s}
.fever-sparkles span:nth-child(4){left:81%;top:69%;animation-delay:.8s}
.fever-sparkles span:nth-child(5){left:49%;top:11%;animation-delay:.35s}
.fever-sparkles span:nth-child(6){left:6%;top:43%;animation-delay:.95s}
.fever-sparkles span:nth-child(7){left:92%;top:49%;animation-delay:.6s;font-size:21px}
.fever-sparkles span:nth-child(8){left:58%;top:83%;animation-delay:1.15s}
@keyframes feverTwinkle{0%,100%{opacity:0;transform:scale(.4) rotate(0)}50%{opacity:1;transform:scale(1.15) rotate(15deg)}}

.fever-badge{position:absolute;top:6px;left:50%;transform:translateX(-50%);z-index:8;
  font-size:12px;color:#2a1d0c;background:linear-gradient(90deg,var(--gold),var(--leg));
  border:2px solid var(--line);padding:3px 11px;white-space:nowrap;
  box-shadow:0 0 10px var(--gold);animation:feverBadge .8s ease-in-out infinite}
.fever-badge.hidden{display:none}
@keyframes feverBadge{
  0%,100%{transform:translateX(-50%) scale(1);box-shadow:0 0 8px var(--gold)}
  50%{transform:translateX(-50%) scale(1.07);box-shadow:0 0 17px var(--leg)}
}
/* 피버 중엔 '초당 채굴' 수치가 주황빛으로 — 부스트가 강하게 걸렸음을 직접 체감 */
body.fever #rate{color:var(--leg);text-shadow:0 0 9px var(--gold)}
@media (prefers-reduced-motion:reduce){
  .fever-ring,.fever-sparkles span,.fever-badge{animation:none}
  body.fever .fever-ring{box-shadow:inset 0 0 24px rgba(242,193,78,.5)}
  .fever-sparkles span{opacity:.7}
}

/* ── 생명의가루(재료) + 적립 한도 증가권(제작) ─────────────────────────────── */
.dust-card{display:flex;align-items:center;gap:10px;margin:4px 0 10px;padding:9px 11px;
  background:var(--panel2);border:3px solid var(--line);box-shadow:inset -3px -3px 0 rgba(0,0,0,.28)}
.dust-emoji{font-size:20px;line-height:1;filter:drop-shadow(0 0 4px var(--gold))}
.dust-info{display:flex;flex-direction:column;gap:2px;min-width:0}
.dust-count{font-size:12px;color:var(--ink)}
.dust-count strong{font-size:18px;color:var(--gold);text-shadow:2px 2px 0 var(--line)}
.dust-hint{font-size:10px;color:var(--muted);line-height:1.6}
.dust-hint b{color:var(--gold)}
/* 분해 가능 재고의 결과별 내역 — 총합만 보면 전부 가루로 읽히는 걸 막는 한 줄. */
.dust-breakdown{display:block;margin-top:4px;font-size:10px;color:var(--muted);line-height:1.5}
.dust-breakdown[hidden]{display:none}
.item-btn.decompose{background:var(--panel2);color:var(--gold);box-shadow:inset -2px -2px 0 rgba(0,0,0,.32)}

.cap-boost-card{margin-top:14px;padding:11px;background:var(--panel2);
  border:3px solid var(--line);box-shadow:inset -3px -3px 0 rgba(0,0,0,.28)}
.cap-boost-head{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--ink);
  padding-bottom:9px;margin-bottom:9px;border-bottom:2px solid var(--line)}
.cap-boost-head strong{font-size:16px;color:var(--gold);text-shadow:2px 2px 0 var(--line)}
.cap-boost-body{display:flex;align-items:center;gap:10px}
.cap-boost-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.cap-boost-name{font-size:12px;color:var(--gold)}
.cap-boost-desc{font-size:10px;color:var(--muted);line-height:1.6}
.cap-boost-desc b{color:var(--ink)}
.cap-boost-state{font-size:10px;color:var(--muted);line-height:1.5}
.cap-boost-body .big-action{width:auto;flex:0 0 auto;padding:11px 16px;font-size:12px}
.cap-boost-body .big-action:disabled{opacity:.5;cursor:not-allowed;filter:grayscale(.4)}
.cap-bonus-inline{color:var(--gold)}

/* ── 버닝타임 연출 (전역 오버레이 + 채굴장 하늘 + 자동채굴 ×2) ──────────────────── */
/* 전역 오버레이: body.burning 이면 노출(방치/상점/던전 공통). */
/* style = server burning.style(sunset/aurora/meteor/festival) → body[data-burn-style]. */
/* 버닝 배너 색상 토큰 — style.css/dungeon.css 공유(스타일별 그라디언트 단일 소스, 두 파일 동기화 방지). */
:root{
  --burn-grad:linear-gradient(90deg,#ff2d95,#ff7a18);
  --burn-grad-aurora:linear-gradient(90deg,#1f9e8a,#38c46a);
  --burn-grad-meteor:linear-gradient(90deg,#6a4bff,#28a0d0);
  --burn-grad-festival:linear-gradient(90deg,#ff2d95,#f4c430,#28c8e0);
}
.burning-overlay{position:fixed;inset:0;z-index:46;pointer-events:none;display:none}
body.burning .burning-overlay{display:block}
.burn-fx{position:absolute;inset:0;width:100%;height:100%}

/* 무지개 프레임 — 정지한 테두리 창(마스크) 안에서 무지개 conic 이 회전(색만 돈다) */
.burn-frame{position:absolute;inset:0;padding:3px;overflow:hidden;opacity:.85;
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude}
.burn-frame::before{content:"";position:absolute;inset:-50%;
  background:conic-gradient(from 0deg,#ff004c,#ff7a18,#f4e400,#38e04a,#28c8e0,#7a5cff,#ff2d95,#ff004c);
  animation:burnFrameSpin 7s linear infinite}
@keyframes burnFrameSpin{to{transform:rotate(360deg)}}
body[data-burn-style="sunset"] .burn-frame::before{filter:hue-rotate(-14deg) saturate(1.15)}
body[data-burn-style="aurora"] .burn-frame::before{filter:hue-rotate(55deg) saturate(1.05)}
body[data-burn-style="meteor"] .burn-frame::before{filter:hue-rotate(200deg) saturate(1.1)}
/* 모바일: 회전하는 거대 레이어 대신 **테두리 자체를 흐르게** 한다.
   `::before` 는 `inset:-50%` 라 뷰포트의 4배 면적이고, 거기에 부모의 mask-composite 와 자신의
   hue-rotate 필터가 겹친다 — 아이폰 390×844·DPR3 이면 약 11.9M 디바이스 픽셀이 7초마다 한 바퀴
   돈다(파티클보다 한 자릿수 크다). 아래 규칙은 레이어를 뷰포트 크기로 줄이고 회전·필터를 없애며,
   마스크가 실제로 칠하는 3px 링만 남긴다. 무지개가 흐르는 인상은 그대로다.
   ⚠️ 계열별 색조(hue-rotate)는 모바일에서 포기한다 — 배너 색이 그 역할을 대신한다. */
@media (pointer: coarse) {
  .burn-frame::before{display:none}
  .burn-frame{background:linear-gradient(90deg,#ff004c,#ff7a18,#f4e400,#38e04a,#28c8e0,#7a5cff,#ff2d95,#ff004c);
    background-size:300% 100%;animation:burnFrameFlow 7s linear infinite}
  @keyframes burnFrameFlow{to{background-position:300% 0}}
}

/* 상단 배너 — 지배 축·배율 표시(슬라이드 다운) */
.burn-banner{position:absolute;top:7px;left:50%;transform:translate(-50%,0);
  display:inline-flex;align-items:center;gap:6px;font-family:inherit;font-size:11px;color:#fff;
  padding:5px 13px;border-radius:999px;white-space:nowrap;
  background:var(--burn-grad);border:2px solid var(--line);
  box-shadow:0 4px 16px -4px #ff7a18,inset 0 0 0 1px rgba(255,255,255,.18);opacity:0}
/* 등장(슬라이드다운) 1회 → 구름처럼 둥둥 떠다니는 플로트 무한반복(translate 의 -50% 중앙정렬 유지) */
body.burning .burn-banner{opacity:1;animation:bannerEnter .55s cubic-bezier(.2,1.35,.4,1),bannerFloat 5.5s ease-in-out .55s infinite}
.burn-banner .bb-flame{animation:burnFlame 1.1s ease-in-out infinite}
@keyframes burnFlame{50%{transform:translateY(-2px) rotate(-7deg)}}
@keyframes bannerEnter{from{opacity:0;transform:translate(-50%,-46px)}to{opacity:1;transform:translate(-50%,0)}}
@keyframes bannerFloat{0%,100%{transform:translate(-50%,0)}30%{transform:translate(calc(-50% - 5px),-4px)}62%{transform:translate(calc(-50% + 4px),-6px)}}
body[data-burn-style="aurora"] .burn-banner{background:var(--burn-grad-aurora)}
body[data-burn-style="meteor"] .burn-banner{background:var(--burn-grad-meteor)}
body[data-burn-style="festival"] .burn-banner{background:var(--burn-grad-festival);
  background-size:220% 100%;animation:burnFestival 3.2s linear infinite}
@keyframes burnFestival{to{background-position:220% 0}}

/* 버닝 중 채굴장 하늘 교체/글로우는 제거(요청) — 하늘은 항상 기본(.mine background)을 유지한다. */

/* 자동채굴 ×2 익사이팅 연출 — .mine.boosting(자동채굴 활성) 게이트 */
.mine-boost-fx{position:absolute;inset:0;z-index:6;pointer-events:none;display:none}
.mine.boosting .mine-boost-fx{display:block}
.mbf-badge{position:absolute;top:4px;right:7px;font-size:19px;color:#fff;letter-spacing:-.02em;
  text-shadow:0 0 8px #ff7a18,0 2px 0 #7a1420,0 0 15px #ff2d95;-webkit-text-stroke:2px #7a1420;
  animation:mbfPulse .7s ease-in-out infinite}
@keyframes mbfPulse{0%,100%{transform:scale(1) rotate(-4deg)}50%{transform:scale(1.2) rotate(4deg)}}
/* 좌우 세로 스피드라인(.mine-boost-fx::before)은 제거(요청) — 뱃지·버스트 링만 남긴다. */
.mine.boost-burst .mine-boost-fx::after{content:"";position:absolute;top:13px;right:15px;width:16px;height:16px;
  border-radius:50%;border:3px solid var(--gold);transform:translate(50%,-50%) scale(.2);opacity:0;animation:mbfBurst .6s ease-out}
@keyframes mbfBurst{0%{opacity:.9;transform:translate(50%,-50%) scale(.2)}100%{opacity:0;transform:translate(50%,-50%) scale(6)}}

@media (prefers-reduced-motion:reduce){
  .burn-fx{display:none}
  .burn-frame,.burn-frame::before,.burn-banner,.burn-banner .bb-flame,.mbf-badge,
  .mine.boost-burst .mine-boost-fx::after{animation:none}
  .burn-banner{transition:none}
}

/* 서버 드레인·연결 끊김 안내 — 읽기 화면은 유지하고 경제 작업만 요청 계층에서 차단한다. */
.service-status-banner{position:fixed;top:max(8px,env(safe-area-inset-top));left:50%;z-index:10020;
  width:min(92vw,520px);transform:translateX(-50%);padding:10px 14px;border:1px solid #f2b84b;
  border-radius:12px;background:#fff4cc;color:#6d4700;font-size:13px;font-weight:800;text-align:center;
  box-shadow:0 8px 24px rgba(76,51,0,.2)}
.service-status-banner[hidden]{display:none}
body.service-unavailable .big-action,body.service-unavailable .item-btn,
body.service-unavailable .dbag-use,body.service-unavailable .fb-go,
body.service-unavailable #claimConfirm,body.service-unavailable [data-shop-buy]{
  filter:grayscale(.7);opacity:.58;cursor:not-allowed
}

/* ── 모바일 절전(무입력 60초) ────────────────────────────────────────────────
   방치 게임은 '화면 켜둔 채 안 보는' 시간이 대부분인데, 그 동안에도 브라우저는 페이지를
   '보이는 중'으로 취급해 장식 애니메이션을 전부 60fps 로 돌린다(발열·방전). 적립은 서버
   권위(accrue)라 연출을 멈춰도 획득량 손해가 0 이므로, 무입력이 이어지면 장식만 정지한다.
   game.js 가 body.power-save 를 토글하고 터치 즉시 해제한다. 레이아웃에 영향 주는 속성은
   건드리지 않는다(animation 만 정지 → 위치·크기·색 그대로). */
body.power-save .mine::before,
body.power-save .box-img,
body.power-save .item-card.lg,
body.power-save .miner.shiny .miner-pet,
body.power-save .pet-card.shiny,
body.power-save .pet-slot.shiny.filled,
body.power-save .pet-card.shiny::after,
body.power-save .auto-mine-btn.active,
body.power-save .fever-ring,
body.power-save .fever-badge,
body.power-save .mbf-badge,
body.power-save .fever-sparkles span,
body.power-save .cb-sticker,
body.power-save .bar::after,
body.power-save .burn-banner,
body.power-save .burn-banner .bb-flame,
body.power-save .burn-frame,
body.power-save .burn-frame::before{
  animation:none!important
}

/* ===== 2026-08-03 일괄 개봉 · 일괄 분해 =====
   상자·에그가 1개씩만 처리돼 아무도 끝까지 못 했다(실측 미개봉 1,519개, 최다 보유자 885번 클릭).
   확률·수율은 그대로 두고 조작만 없앤 경로라 포인트 발행량은 변하지 않는다. */
.box-btns{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px}
.box-open-btn.bulk{background:#3c5a4a;color:#c9f5e0}
.box-open-btn.bulk:disabled{opacity:.45;cursor:not-allowed}
/* 전역 .hidden 규칙이 없는 프로젝트라 여기서 선언해야 숨기기가 먹는다(구 백엔드 대비 게이트). */
.box-open-btn.hidden{display:none}
.dust-info .box-open-btn.bulk{margin-top:7px;align-self:flex-start}
.bulk-result{max-width:340px}
/* 200개를 열면 종류가 많아진다 — 목록만 스크롤시키고 제목·확인 버튼은 고정. */
.bulk-result .unlock-reveal-rows{max-height:min(44vh,290px);overflow-y:auto;scrollbar-width:thin}

/* ===== 2026-08-03 치장 추출(제한 해제) =====
   쌓이기만 하던 스티커·메달·명화를 태워 적립 한도의 '상한'을 넓히는 가챠.
   ⚠ 생명의가루 카드(.cap-boost-card = 한도 자체를 올림)와 축이 다르다. 강조색을 시안 계열로
   따로 잡아 두 카드를 색으로도 구분한다 — 문구만으로는 계속 헷갈린다는 게 이 기능의 출발점이다. */
.unlock-card{margin-top:10px;padding:10px;background:var(--panel2);border:3px solid var(--line);
  box-shadow:inset -3px -3px 0 rgba(0,0,0,.3)}
/* 이 프로젝트엔 전역 .hidden 규칙이 없다(클래스마다 따로 선언). 빠뜨리면 숨기기가 안 먹는다. */
.unlock-card.hidden,.unlock-gauge.hidden{display:none}
.unlock-head{display:flex;align-items:center;gap:8px}
.unlock-emoji{flex:none;font-size:20px;line-height:1}
.unlock-title{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.unlock-title strong{font-size:12px;color:var(--ink)}
.unlock-sub{font-size:9px;line-height:1.5;color:var(--muted)}
.unlock-sub b{color:#7cf5ff}
.unlock-avail{flex:none;padding:4px 7px;background:var(--panel);border:2px solid var(--line);
  font-size:9px;color:var(--muted)}
.unlock-avail b{color:#7cf5ff;font-size:12px}
.unlock-stock{display:flex;flex-wrap:wrap;gap:5px;margin-top:9px}
.unlock-chip{display:flex;align-items:center;gap:5px;min-height:32px;padding:4px 7px;
  background:var(--panel);border:2px solid var(--line);color:var(--ink);
  font:700 9px "Galmuri11","Galmuri9",sans-serif;cursor:pointer;touch-action:manipulation}
.unlock-chip:hover{background:#453520}
.unlock-chip img{width:18px;height:18px;image-rendering:pixelated}
.unlock-chip .uc-count{color:var(--muted)}
.unlock-chip .uc-reward{color:#7cf5ff}
.unlock-chip.rare{border-color:var(--rare)}
.unlock-chip.epic{border-color:var(--epic)}
.unlock-empty{font-size:9px;line-height:1.6;color:var(--muted)}
.unlock-actions{margin-top:9px}
.unlock-note{margin-top:7px;font-size:9px;line-height:1.7;color:var(--muted)}
.unlock-note b{color:#7cf5ff}

/* 결과 연출 — 추출한 장 수만큼 칸이 순차로 켜지고(성공만 발광) 총 해제 P가 카운트업된다. */
.unlock-reveal-grid{display:flex;flex-wrap:wrap;justify-content:center;gap:3px;
  max-width:264px;margin:10px auto 4px}
.ur-cell{width:12px;height:12px;background:#3a2d1d;border:1px solid var(--line);
  animation:urPop .34s ease-out backwards;animation-delay:var(--d,0ms)}
.ur-cell.ok{background:var(--gold);box-shadow:0 0 6px var(--gold)}
.ur-cell.rare.ok{background:var(--rare);box-shadow:0 0 6px var(--rare)}
.ur-cell.epic.ok{background:var(--epic);box-shadow:0 0 7px var(--epic)}
.ur-more{align-self:center;font-size:9px;color:var(--muted)}
@keyframes urPop{from{opacity:0;transform:scale(.2) rotate(-25deg)}to{opacity:1;transform:none}}
.unlock-reveal-rows{display:grid;gap:3px;width:100%;margin-top:9px}
.ur-row{display:grid;grid-template-columns:1fr auto auto;align-items:center;gap:7px;padding:4px 7px;
  background:#2a2018;border:1px solid var(--line);font-size:9px;color:var(--muted)}
.ur-row b{color:var(--ink)}
.ur-row em{font-style:normal;color:#7cf5ff}
.ur-row.rare b{color:var(--rare)}
.ur-row.epic b{color:var(--epic)}
.unlock-reveal-foot{margin-top:8px;font-size:9px;line-height:1.6;color:var(--muted)}

/* 감속 모드에서도 **끄지 않는다**. 이 사내 PC 들은 Windows '애니메이션 표시' OFF 라 일반 크롬도
   prefers-reduced-motion:reduce 를 보고한다 — animation:none 으로 처리하면 실사용자에게는
   연출이 통째로 사라진 정지 화면만 남는다(전광판·시즌 쇼케이스·3D 단상에서 같은 원인으로 3건 제보).
   그래서 재생은 유지하고 회전·확대 폭만 줄인다. */
@media (prefers-reduced-motion:reduce){
  .ur-cell{animation-name:urPopSoft}
  .us-wheel{animation-name:usSpinSoft}
}
@keyframes urPopSoft{from{opacity:0;transform:scale(.8)}to{opacity:1;transform:none}}
@keyframes usSpinSoft{from{transform:rotate(0)}to{transform:rotate(720deg)}}

/* ── 추출 전 확인 — 되돌릴 수 없는 소모라 '최대'와 '기대'를 함께 보여준다.
   최대치만 내걸면 25% 가챠에서 기대를 부풀리게 된다. ── */
.unlock-confirm{max-width:330px}
/* 최소·기대·최대 3칸 — 가운데(기대)만 강조하면 평균을 준다고 읽히므로 최대를 금색으로 세운다. */
.unlock-confirm-sum{display:grid;grid-template-columns:repeat(3,1fr);gap:5px;width:100%;margin-top:9px}
.unlock-confirm-sum>div{padding:6px 3px;background:#2a2018;border:2px solid var(--line);text-align:center}
.unlock-confirm-sum span{display:block;font-size:9px;color:var(--muted)}
.unlock-confirm-sum b{display:block;margin-top:3px;font-size:12px;color:var(--muted)}
.unlock-confirm-sum>div.exp b{color:#7cf5ff}
.unlock-confirm-sum>div:last-child b{color:var(--gold)}
.unlock-confirm-roll{margin-top:8px;font-size:9px;line-height:1.65;color:var(--ink)}
.unlock-confirm-roll b{color:var(--gold)}
.unlock-confirm-warn{margin-top:6px;font-size:9px;line-height:1.65;color:var(--muted)}
.unlock-confirm-actions{display:grid;grid-template-columns:1fr 1.35fr;gap:6px;width:100%;margin-top:10px}
.unlock-confirm-actions .hidden{display:none}
.offline-btn.ghost{background:#3a2d1d;color:var(--muted)}
.offline-btn.wide{width:100%;margin-top:6px}

/* 결과 게이지 — 0 ~ 최대(전부 성공) 중 이번 결과의 위치 */
.unlock-gauge{width:100%;height:9px;margin:2px 0 5px;background:#2a2018;border:2px solid var(--line);overflow:hidden}
.unlock-gauge>i{display:block;height:100%;width:0;background:linear-gradient(90deg,#7cf5ff,var(--gold));
  transition:width .5s ease-out}
.unlock-gauge-label{font-size:9px;color:var(--muted);margin-bottom:6px}

/* ── 가챠 돌림판(3초) → 결과. 한 모달 안에서 data-phase 로 단계만 바꾼다. ── */
#unlockModal[data-phase="spin"] .unlock-reveal-grid,
#unlockModal[data-phase="spin"] .reveal-rarity,
#unlockModal[data-phase="spin"] .offline-title,
#unlockModal[data-phase="spin"] .offline-msg,
#unlockModal[data-phase="spin"] .unlock-reveal-rows,
#unlockModal[data-phase="spin"] .unlock-reveal-foot,
#unlockModal[data-phase="spin"] .unlock-gauge,
#unlockModal[data-phase="spin"] .unlock-gauge-label,
#unlockModal[data-phase="spin"] .offline-btn{display:none}
#unlockModal[data-phase="result"] .unlock-spin,
#unlockModal[data-phase="result"] .unlock-spin-msg{display:none}
.unlock-spin{position:relative;width:136px;height:136px;margin:10px auto 4px}
.us-wheel{width:100%;height:100%;border-radius:50%;border:3px solid var(--line);
  background:conic-gradient(var(--gold) 0 12.5%,#3a2d1d 0 25%,var(--rare) 0 37.5%,#3a2d1d 0 50%,
    var(--epic) 0 62.5%,#3a2d1d 0 75%,#7cf5ff 0 87.5%,#3a2d1d 0);
  box-shadow:inset 0 0 12px rgba(0,0,0,.6),0 0 14px rgba(242,193,78,.35);
  animation:usSpin 3s cubic-bezier(.16,.86,.28,1) forwards}
.us-hub{position:absolute;top:50%;left:50%;width:26px;height:26px;margin:-13px 0 0 -13px;
  border-radius:50%;background:var(--panel2);border:3px solid var(--line)}
.us-pointer{position:absolute;top:-13px;left:50%;transform:translateX(-50%);
  color:var(--gold);font-size:17px;line-height:1;text-shadow:0 2px 0 var(--line)}
/* 5.5바퀴 — 가속 후 천천히 멈춘다. 실제 결과와 각도를 맞추지는 않는다(여러 장을 한 번에 굴리므로). */
@keyframes usSpin{from{transform:rotate(0)}to{transform:rotate(1980deg)}}
.unlock-spin-msg{margin-top:6px;font-size:10px;color:var(--muted);animation:usPulse 1.1s ease-in-out infinite}
@keyframes usPulse{0%,100%{opacity:.55}50%{opacity:1}}

/* ── 복권(스크래치) — 은박 캔버스를 문지르면 아래의 당첨 포인트가 드러난다 ──
   단계는 data-phase 하나로만 가른다(추출 돌림판과 같은 규율). 긁는 중에는 '확인'을 감춰
   결과를 못 본 채 닫는 사고를 막고, 결과에서는 카드 어디를 눌러도 닫힌다. */
.lottery-card{max-width:320px}
#lotteryModal[data-phase="scratch"] .offline-btn,
#lotteryModal[data-phase="scratch"] .reveal-burst,
#lotteryModal[data-phase="scratch"] .unlock-reveal-foot{display:none}
#lotteryModal[data-phase="result"] .lt-scratch{pointer-events:none}
.lottery-ticket{
  position:relative;width:100%;max-width:264px;height:120px;margin:8px auto 10px;
  border:3px solid var(--line);background:linear-gradient(155deg,#3b2c15,#241a0e 60%,#3b2c15);
  box-shadow:inset 0 0 14px rgba(0,0,0,.55);overflow:hidden;
}
/* 티켓 좌우의 절취선 자국 — 장식이라 클릭을 먹지 않게 pointer-events 를 끈다. */
.lottery-ticket::before,.lottery-ticket::after{
  content:"";position:absolute;top:0;bottom:0;width:6px;pointer-events:none;
  background:repeating-linear-gradient(180deg,var(--line) 0 5px,transparent 5px 11px);
}
.lottery-ticket::before{left:6px}
.lottery-ticket::after{right:6px}
.lt-prize{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px}
.lt-prize-label{font-size:9px;letter-spacing:1px;color:var(--muted)}
.lt-prize-amount{font-size:26px;line-height:1;color:var(--gold);text-shadow:2px 2px 0 var(--line)}
#lotteryModal[data-phase="result"] .lt-prize-amount{animation:ltPop .32s ease-out}
@keyframes ltPop{0%{transform:scale(.72)}70%{transform:scale(1.12)}100%{transform:scale(1)}}
/* 은박 코팅 — 캔버스가 실제 스크래치 면이다. 열리면 투명도로 사라진다(캔버스를 지우면
   되감기가 불가능해져 재시도 표시가 어렵다). touch-action:none 이 없으면 모바일에서
   문지르기가 페이지 스크롤로 먹힌다. */
.lt-scratch{position:absolute;inset:0;width:100%;height:100%;
  touch-action:none;cursor:crosshair;transition:opacity .45s ease-out}

/* ── 부화캡슐(펫 선택) — 그 등급의 종을 격자로 깔고 하나를 고른다 ────────── */
.capsule-card{width:min(100%,360px);max-width:360px}
.capsule-search{width:100%;margin:6px 0 8px;padding:7px 9px;font:inherit;font-size:11px;
  color:var(--ink);background:#2a2018;border:2px solid var(--line)}
.capsule-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(72px,1fr));gap:5px;
  width:100%;max-height:min(46vh,300px);overflow-y:auto;scrollbar-width:thin;
  padding:4px;background:#2a2018;border:2px solid var(--line)}
.capsule-cell{display:flex;flex-direction:column;align-items:center;gap:3px;padding:5px 3px;
  background:#3a2d1d;border:2px solid var(--line);color:var(--ink);font:inherit;font-size:9px;
  cursor:pointer;touch-action:manipulation}
.capsule-cell:hover{background:#453520}
.capsule-cell.picked{border-color:var(--gold);box-shadow:inset 0 0 0 1px var(--gold)}
.capsule-cell-art{width:40px;height:40px;display:grid;place-items:center}
.capsule-cell-name{width:100%;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.capsule-empty{grid-column:1/-1;padding:12px;text-align:center;font-size:10px;color:var(--muted)}
/* 선택 표시 — 한 줄 고정(넘치면 말줄임)이라 이름이 길어도 카드가 안 밀린다. */
.capsule-picked{margin-top:6px;min-height:14px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-size:10px;color:var(--gold)}
#capsuleModal[data-phase="result"] .capsule-picked{display:none}
.capsule-result{grid-column:1/-1;display:grid;place-items:center;padding:10px}
.capsule-actions{display:grid;grid-template-columns:1fr 1fr;gap:6px;width:100%;margin-top:10px}
/* 결과 단계에서는 검색·닫기를 감춘다 — 획득 카드에 필요 없고 오조작만 만든다. */
#capsuleModal[data-phase="result"] .capsule-search,
#capsuleModal[data-phase="result"] #capsuleCancel{display:none}
#capsuleModal[data-phase="result"] .capsule-actions{grid-template-columns:1fr}
#capsuleModal[data-phase="pick"] .reveal-burst{display:none}

/* ── 펫 상점(랜덤 출몰) 패널 — #shopMode 최상단, 창이 닫히면 통째로 사라진다 ──
   무지개 연출 규율은 dungeon.css 의 모드 내비 규칙과 같다: 색은 정적 background,
   @keyframes 는 움직임만. 이 PC 는 항상 reduced-motion 이라 정지 상태가 기본 외형이다. */
.pet-shop-panel{
  margin:0 0 12px;padding:12px;border:3px solid #0e0a12;
  background-color:#221a2b;
  background-image:linear-gradient(135deg,rgba(255,77,109,.22),rgba(255,159,28,.18),rgba(61,220,132,.18),rgba(76,201,240,.2),rgba(177,92,255,.24));
  box-shadow:inset 0 3px 0 rgba(255,255,255,.18),4px 4px 0 #0d0911;
}
.pet-shop-panel[hidden]{display:none!important}
.pet-shop-panel[data-mood="golden"],.pet-shop-panel[data-mood="mythic"]{
  background-image:linear-gradient(135deg,rgba(255,214,10,.3),rgba(255,159,28,.24),rgba(255,243,176,.28),rgba(255,107,53,.24));
  border-color:#6b4d05;
}
.ps-head{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.ps-title{font:700 15px "Galmuri11","Galmuri9",sans-serif;color:#fff7df}
.ps-mood{margin-left:7px;padding:2px 6px;background:#12101a;border:2px solid #0d0911;color:#ffe14d;font-size:10px}
.ps-clock{font:700 11px "Galmuri11","Galmuri9",sans-serif;color:#ffd9a8}
.ps-clock b{color:#fff;font-size:13px}
.ps-desc{margin:8px 0 10px;font-size:11px;line-height:1.6;color:#e6dcef}
.ps-desc b{color:#ffe14d}
.ps-cap{display:block;margin-top:4px;color:#ffb0a0}
.ps-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:8px}
.ps-card{
  padding:8px 6px;text-align:center;border:2px solid #0d0911;background:#1a151f;
  display:flex;flex-direction:column;align-items:center;gap:4px;
}
.ps-card.sold{opacity:.45;filter:grayscale(.85)}
.ps-card.mine{border-color:#63a38c;box-shadow:inset 0 0 0 2px rgba(99,163,140,.45)}
/* position:relative 는 좌상단 '미보유' 배지(.dex-badge-lock, absolute)의 기준점이다 — 빼면 배지가
   카드 밖 조상으로 올라가 엉뚱한 자리에 뜬다. */
.ps-art{width:72px;height:72px;display:grid;place-items:center;position:relative}
.ps-tier{font:700 9px "Galmuri11","Galmuri9",sans-serif;letter-spacing:.5px;color:#a99dad}
.ps-card.t-hidden .ps-tier{color:#ff8ae2}
.ps-card.t-legendary .ps-tier{color:#ffd60a}
.ps-card.t-epic .ps-tier{color:#c792ea}
.ps-card.t-rare .ps-tier{color:#79c0ff}
.ps-card.t-uncommon .ps-tier{color:#7ee787}
.ps-name{font:700 11px "Galmuri11","Galmuri9",sans-serif;color:#f2e9f8;line-height:1.3}
.ps-price{display:flex;align-items:center;justify-content:center;gap:3px;font-size:10px;color:#ffe14d}
.ps-buy{
  width:100%;margin-top:2px;padding:6px 4px;border:2px solid #0d0911;background:#40344c;
  color:#fff7df;font:700 10px "Galmuri11","Galmuri9",sans-serif;cursor:pointer;touch-action:manipulation;
}
.ps-buy:disabled{opacity:.5;cursor:not-allowed;filter:grayscale(.6)}
/* 히든 카드는 정지 상태에서도 홀로그램으로 보여야 한다(색은 정적) */
.ps-card.t-hidden{
  border-color:#8a3fbf;
  background-image:linear-gradient(135deg,rgba(255,138,226,.28),rgba(124,77,255,.24),rgba(76,201,240,.24));
}
@keyframes petShopCardShine{to{background-position:200% 50%}}
@media (prefers-reduced-motion: no-preference){
  .ps-card.t-hidden{background-size:200% 100%;animation:petShopCardShine 4s linear infinite}
}

/* ── 컬렉션(도감·확률·뱃지·통계) ────────────────────────────
   GHUB 게이미피케이션 화면을 옮겨온 읽기 전용 뷰. 값은 전부 서버(GHUB) 권위라
   여기 스타일은 표시에만 관여한다. */
.col-desc{font-size:11px;color:var(--muted);line-height:1.7}
.col-desc b{color:var(--gold)}
.col-note{font-size:10px;color:var(--muted);line-height:1.7}
.col-note b{color:var(--ink)}
/* 세그먼트가 5개를 넘으면 한 줄로는 글자가 뭉개진다 — 3열 격자로 접는다(5개면 3+2, 6개면 3+3).
   flex 로 두면 마지막 줄만 늘어나 칸 폭이 줄마다 달라지므로 grid 를 쓴다. */
.col-seg{display:grid;grid-template-columns:repeat(3,1fr);gap:4px}
.col-seg-btn{flex:1;font-family:inherit;cursor:pointer;font-size:11px;padding:9px 2px;
  color:var(--muted);background:var(--panel2);border:2px solid var(--line)}
.col-seg-btn.active{color:var(--gold);border-color:var(--gold);background:var(--panel)}
.col-view{display:flex;flex-direction:column;gap:9px}
.col-view.hidden{display:none}
.col-summary{font-size:11px;color:var(--ink);line-height:1.7;
  background:var(--panel2);border:2px solid var(--line);padding:9px 10px}
.col-summary b{color:var(--gold)}
.col-filters{display:flex;flex-wrap:wrap;gap:4px}
.col-loading{font-size:11px;color:var(--muted);text-align:center;padding:18px 0}
.col-error{font-size:11px;color:#f0907e;text-align:center;padding:14px 0;line-height:1.7}

/* 도감 — GHUB DexTab 구성(진행도 → 필터/정렬 → 그리드 → 상세 모달) */
.dex-progress{background:var(--panel2);border:2px solid var(--line);padding:9px 10px;display:flex;flex-direction:column;gap:6px}
.dex-progress-head{display:flex;align-items:baseline;justify-content:space-between;font-size:11px;color:var(--ink)}
.dex-progress-head strong{color:var(--gold);font-size:13px}
.dex-bar{height:8px;background:var(--bg);border:2px solid var(--line);overflow:hidden}
.dex-bar-fill{height:100%;width:0;background:linear-gradient(90deg,var(--gold-lo),var(--gold));transition:width .5s}
.dex-progress-note{font-size:9px;color:var(--muted)}
.dex-chips{display:flex;flex-wrap:wrap;gap:4px}
.dex-chip{display:inline-flex;align-items:center;gap:4px;font-size:9px;color:var(--ink);
  border:2px solid var(--line);padding:2px 6px;background:var(--bg)}
.dex-chip i{width:6px;height:6px;display:inline-block;font-style:normal}
.dex-chip b{color:var(--ink)}
.dex-chip.done b{color:#7ee081}
.dex-controls{display:flex;flex-direction:column;gap:6px}
.dex-ctl-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.dex-ctl-label{font-size:9px;color:var(--muted);width:26px;flex-shrink:0}
.dex-select{font-family:inherit;font-size:10px;color:var(--ink);background:var(--panel2);
  border:2px solid var(--line);padding:5px 6px}
.dex-sort-hint{font-size:9px;color:var(--muted)}
.dex-sort-hint.hidden{display:none}

/* 카드 = 정사각 버튼(스프라이트) + 아래 이름. 미보유는 흐리게 + '미보유' 배지(도감 전체 공개). */
.dex-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px}
.dex-cell{display:flex;flex-direction:column;align-items:center;gap:3px;min-width:0}
.dex-card{position:relative;width:100%;aspect-ratio:1/1;display:flex;align-items:center;justify-content:center;
  background:var(--panel2);border:2px solid var(--line);cursor:pointer;padding:0;overflow:visible}
.dex-card.locked{opacity:.6}
.dex-card:active{transform:translateY(1px)}
.dex-badge-lock{position:absolute;top:1px;left:1px;font-size:7px;color:var(--muted);
  background:rgba(0,0,0,.55);padding:0 3px;line-height:1.5}
.dex-badge-stat{position:absolute;bottom:1px;left:1px;font-size:8px;color:#2a1d0c;background:var(--gold);
  padding:0 3px;line-height:1.5}
/* 역할 라벨은 우하단을 쓰므로, 등급 도트는 우상단으로 분리한다. */
.dex-dot{position:absolute;top:3px;right:3px;bottom:auto;width:6px;height:6px;border-radius:50%}
.dex-name{font-size:9px;line-height:1.25;text-align:center;width:100%;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;color:var(--muted)}
.dex-name.owned{font-weight:700}

/* 상세 모달 — 카드 안쪽만 스크롤(닫기 버튼이 화면 밖으로 밀리지 않게) */
.dex-modal{position:fixed;inset:0;z-index:85;display:flex;align-items:center;justify-content:center;padding:12px;
  background:rgba(0,0,0,.62)}
.dex-modal.hidden{display:none}
.dex-modal-card{width:100%;max-width:360px;max-height:calc(100vh - 24px);display:flex;flex-direction:column;
  background:var(--panel);border:3px solid var(--line);box-shadow:6px 6px 0 var(--line);box-sizing:border-box}
.dex-modal-glow{height:3px;flex-shrink:0}
.dex-modal-body{flex:1;min-height:0;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:9px}
.dex-modal-head{display:flex;align-items:center;gap:10px}
.dex-modal-sprite{width:72px;height:72px;flex-shrink:0;display:flex;align-items:center;justify-content:center;
  border:2px solid var(--line)}
.dex-modal-title{font-size:14px;color:var(--ink);line-height:1.3}
.dex-modal-tags{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}
.dex-tag{font-size:9px;padding:1px 6px;border:2px solid var(--line);background:var(--panel2);color:var(--muted)}
.dex-tag.rarity{border-color:currentColor}
.dex-unlocked{font-size:9px;color:#7ee081;margin-top:4px}
.dex-sec{background:var(--panel2);border:2px solid var(--line);padding:8px 9px}
.dex-sec-head{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:5px}
.dex-sec-head span{font-size:9px;color:var(--muted);letter-spacing:.3px}
.dex-sec-head strong{font-size:10px}
.dex-desc{font-size:10px;color:var(--ink);line-height:1.8;font-style:italic}
.dex-stat-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:4px}
.dex-stat{display:flex;flex-direction:column;align-items:center;gap:1px;background:var(--bg);padding:4px 1px}
.dex-stat-l{font-size:8px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.dex-stat-v{font-size:11px;color:var(--ink)}
.dex-note{font-size:8px;color:var(--muted);margin-top:5px;line-height:1.6}
.dex-own-bar{height:7px;background:var(--bg);border:2px solid var(--line);overflow:hidden}
.dex-own-fill{height:100%;transition:width .6s}
.dex-own-meta{display:flex;justify-content:space-between;font-size:8px;color:var(--muted);margin-top:4px}
.dex-owned-line{display:flex;align-items:center;justify-content:center;gap:6px;font-size:10px;padding:7px}
.dex-modal-foot{flex-shrink:0;border-top:2px solid var(--line);padding:9px 12px calc(9px + env(safe-area-inset-bottom))}
.dex-close{width:100%;font-family:inherit;font-size:12px;color:var(--muted);background:var(--panel2);
  border:3px solid var(--line);padding:10px;cursor:pointer}
.dex-close:active{transform:translateY(2px)}

/* 스킬 카드 — GHUB SkillCard 와 같은 정보 배치(속성·역할·궁극기·배수·쿨다운·요약·설명).
   탭하면 카드 안에 skill-preview.html iframe 이 펼쳐져 실제 배틀 이펙트를 재생한다. */
.skill-card{background:var(--bg);border:2px solid var(--line);padding:7px 8px;margin-bottom:5px;cursor:pointer}
.skill-card:last-of-type{margin-bottom:0}
.skill-card.ult{border-color:var(--gold)}
.skill-head{display:flex;align-items:flex-start;gap:7px}
.skill-el{flex-shrink:0;width:22px;height:22px;display:flex;align-items:center;justify-content:center;font-size:12px}
.skill-main{flex:1;min-width:0}
.skill-title{display:flex;flex-wrap:wrap;align-items:center;gap:4px}
.skill-slot{font-size:8px;color:var(--muted)}
.skill-name{font-size:11px;color:var(--ink)}
.skill-ult{font-size:8px;color:#2a1d0c;background:var(--gold);padding:0 4px}
.skill-role{font-size:8px;color:var(--muted);border:1px solid var(--dirt-lo);padding:0 4px}
.skill-behavior{font-size:9px;color:var(--muted);line-height:1.5;margin-top:2px}
.skill-num{flex-shrink:0;text-align:right}
.skill-mult{font-size:11px}
.skill-cd{font-size:8px;color:var(--muted)}
.skill-chips{display:flex;flex-wrap:wrap;gap:3px;margin-top:5px}
.skill-chips span{font-size:8px;color:var(--muted);background:var(--panel2);border:1px solid var(--dirt-lo);padding:1px 4px}
.skill-desc{font-size:9px;color:var(--ink);line-height:1.7;margin-top:5px;opacity:.85}
.skill-fx-hint{font-size:8px;color:var(--muted);margin-top:5px;opacity:.7}
.skill-fx{margin-top:6px}
.skill-fx iframe{display:block;width:100%;height:170px;border:2px solid var(--line);background:#05040a}

/* 확률 */
.prob-body{display:flex;flex-direction:column;gap:9px}
.prob-sec{background:var(--panel2);border:2px solid var(--line);padding:9px 10px}
.prob-sec h3{font-size:11px;color:var(--gold);margin-bottom:6px}
.prob-row{display:flex;justify-content:space-between;align-items:baseline;gap:10px;
  font-size:10px;color:var(--ink);padding:4px 0;border-bottom:1px dashed var(--dirt-lo);line-height:1.5}
.prob-row:last-child{border-bottom:none}
.prob-row .pv{color:var(--gold);white-space:nowrap;flex-shrink:0}
.prob-group{font-size:9px;color:var(--gold);opacity:.85;padding:7px 0 2px;letter-spacing:.3px}
.prob-group:first-child{padding-top:0}
.prob-sub{font-size:9px;color:var(--muted);line-height:1.6;margin-top:5px}


/* 통계 — 능력치 랭킹(표) + 반짝 쇼케이스(순위·닉네임·펫 리스트).
   표는 열이 많아 좁은 화면에서 가로 스크롤한다(칸을 줄이면 숫자가 뭉개진다). */
.stats-body{display:flex;flex-direction:column;gap:10px}
.stats-sec{background:var(--panel2);border:2px solid var(--line);padding:9px 10px}
.stats-sec h3{font-size:11px;color:var(--gold);margin-bottom:6px}
/* 능력치 랭킹 등급 탭 — 전체+5등급 6개가 좁은 화면에서도 한두 줄에 들어가게 도감 칩보다 촘촘히.
   활성 칩의 색은 인라인(등급색)으로 덮으므로 여기서는 크기만 정한다. */
.rk-tabs{margin-bottom:2px}
.rk-tabs .chip{font-size:10px;padding:4px 7px}
.rk-wrap{overflow-x:auto;margin-top:6px}
.rk-table{width:100%;border-collapse:collapse;font-size:9px;white-space:nowrap}
.rk-table th{padding:4px 3px;text-align:center;font-weight:normal;color:var(--muted);
  border-bottom:2px solid var(--line)}
.rk-table th.rk-sort{cursor:pointer}
.rk-table th.rk-sort.on{color:var(--gold)}
.rk-table th.rk-th-pet{text-align:left}
.rk-table td{padding:7px 3px;text-align:center;color:var(--ink);border-bottom:1px dashed var(--dirt-lo)}
.rk-table tr:last-child td{border-bottom:none}
.rk-table tr.shiny{background:rgba(251,191,36,.10)}
.rk-no{color:var(--muted)}
.rk-pet{text-align:left!important}
.rk-sprite{display:inline-block;vertical-align:middle;width:22px;height:22px}
.rk-pname{display:inline-block;vertical-align:middle;max-width:92px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.rk-shiny{color:var(--gold)}
.rk-rarity{display:inline-block;font-size:8px;padding:1px 4px}
.rk-num i{font-style:normal;font-size:7px;color:var(--muted);margin-left:1px}
.rk-num.on{color:var(--gold)}
.rk-total{color:#7ee081}
.rk-star{color:var(--gold)}

/* 반짝 쇼케이스 — 순위 / 닉네임 / ✨보유수 / 작은 펫들. 닉네임 미설정자는 '익명 #N'. */
.sh-row{display:flex;flex-wrap:wrap;align-items:center;gap:6px;background:var(--bg);
  border:2px solid var(--line);padding:6px;margin-bottom:5px}
.sh-row:last-child{margin-bottom:0}
.sh-no{flex-shrink:0;width:16px;text-align:center;font-size:10px;color:var(--gold)}
.sh-name{flex:1 1 auto;min-width:0;font-size:10px;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sh-count{flex-shrink:0;font-size:8px;color:#2a1d0c;background:var(--gold);padding:1px 5px}
/* 펫 줄은 **다음 줄로** 내린다 — 한 줄에 몰면 닉네임이 긴 사람의 이름과 ✨배지를 펫이 덮는다
   (실측: '부엉이가부엉부엉' 행에서 이름이 가려짐). overflow 를 숨기지 않는 이유는 오라(몸통의
   150%)가 잘리기 때문. */
.sh-pets{flex-basis:100%;display:flex;align-items:center;justify-content:flex-start;
  gap:6px;margin-top:5px;overflow:visible}
.sh-pet{flex-shrink:0;width:26px;height:26px;display:flex;align-items:center;justify-content:center;
  border:2px solid var(--line);background:var(--panel2)}
.sh-more{flex-shrink:0;font-size:8px;color:var(--muted)}

/* 컬렉션 셸 — 하단 모드 내비에 가리지 않도록 아래 여백을 둔다(상점 셸과 같은 규칙). */
.collection-shell{padding:12px 12px calc(var(--mode-nav-height,54px) + 24px);min-height:100vh;min-height:100dvh}
.collection-shell .col-view{gap:9px}

/* 퀘스트 — 진행도는 GHUB 활동으로 오르고 여기서는 수령만 한다. */
.quest-body{display:flex;flex-direction:column;gap:6px}
.quest-row{background:var(--panel2);border:2px solid var(--line);padding:8px 9px;
  display:flex;flex-direction:column;gap:5px}
.quest-row.ready{border-color:var(--gold)}
.quest-row.claimed{opacity:.55}
.quest-head{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.quest-type{font-size:8px;color:var(--muted);border:1px solid var(--dirt-lo);padding:1px 4px;flex-shrink:0}
.quest-title{font-size:11px;color:var(--ink);flex:1;min-width:0}
.quest-reward{font-size:9px;color:var(--gold);flex-shrink:0}
.quest-desc{font-size:9px;color:var(--muted);line-height:1.6}
.quest-foot{display:flex;align-items:center;gap:7px}
.quest-bar{flex:1;height:6px;background:var(--bg);border:2px solid var(--line);overflow:hidden}
.quest-bar i{display:block;height:100%;background:var(--gold);transition:width .4s}
.quest-count{font-size:9px;color:var(--muted);flex-shrink:0}
.quest-claim{font-family:inherit;font-size:10px;color:#2a1d0c;background:var(--gold);
  border:2px solid var(--line);padding:4px 9px;cursor:pointer;flex-shrink:0}
.quest-claim:active{transform:translateY(1px)}
.quest-claim:disabled{opacity:.6;cursor:not-allowed}
.quest-done{font-size:9px;color:#7ee081;flex-shrink:0}
.quest-wait{font-size:9px;color:var(--muted);flex-shrink:0}

/* 펫 꾸미기 — 카드 그림이 진입점이라 연필 힌트를 작게 얹는다. */
.pet-card-art{position:relative}
.pet-dress-hint{position:absolute;right:0;bottom:0;font-size:9px;opacity:.55;pointer-events:none}
.dress-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px}
.dress-opt{display:flex;flex-direction:column;align-items:center;gap:2px;font-family:inherit;
  background:var(--bg);border:2px solid var(--line);padding:6px 3px;cursor:pointer}
.dress-opt.on{border-color:var(--gold);background:var(--panel)}
.dress-opt.out{opacity:.4;cursor:not-allowed}
.dress-opt-name{font-size:9px;color:var(--ink);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;max-width:100%}
.dress-opt-qty{font-size:8px;color:var(--muted)}

/* 전투 역할 — 도감 카드는 아이콘만(자리가 없다), 모달·편성은 라벨까지. */
/* 역할 라벨 — 카드 왼쪽은 '미보유'(좌상)와 능력치(좌하)가 이미 쓰고 있어 **우하단**에 둔다.
   색은 던전 화면과 같은 `.role-*`(아래) 를 얹는다. */
.dex-badge-role{position:absolute;right:4px;bottom:4px;padding:1px 3px;border:1px solid #51435d;
  background:#292130;color:#c8bbce;font-size:7px;line-height:1.4;pointer-events:none}
.dex-tag.role{background:#292130}
/* 던전 `.role-*` 와 같은 값 — 도감에서도 탱커는 파랑, 근접은 빨강이어야 한다. */
.role-tank{border-color:#6f9ec7;color:#a9d8ff}
.role-ranged{border-color:#62a77f;color:#a7e7bd}
.role-aoe{border-color:#a06dc2;color:#dcb4f5}
.role-support{border-color:#c1a35e;color:#ffe09a}
.role-melee{border-color:#b46868;color:#f2aaaa}

/* 사내 접속 안내 — 게임을 **통째로 덮는다**. 배경을 반투명으로 두면 뒤가 비쳐 "가렸다"는
   뜻이 흐려지므로 불투명하게 칠한다. */
.return-overlay{position:fixed;z-index:300;inset:0;display:grid;place-items:center;
  padding:24px;background:var(--bg)}
.return-card{width:min(100%,320px);padding:26px 20px;background:var(--panel);
  border:3px solid var(--gold);box-shadow:0 10px 34px rgba(0,0,0,.55);text-align:center}
.return-icon{font-size:34px;line-height:1}
.return-card h2{margin:14px 0 0;color:var(--gold);font-size:13px;line-height:1.6}
.return-card p{margin:12px 0 0;color:var(--muted);font-size:10px;line-height:1.9}
.return-card button{width:100%;margin-top:20px;padding:11px;border:2px solid var(--gold);
  background:var(--gold);color:#2a1d0c;font-family:inherit;font-size:11px;font-weight:700;
  cursor:pointer;touch-action:manipulation}
.return-card button:hover{background:transparent;color:var(--gold)}
/* 뒤 화면이 스크롤되면 덮개 아래에서 게임이 움직이는 게 느껴진다 — 잠근다. */
body.has-return-overlay{overflow:hidden}

/* 홈 화면 추가 안내 — 헤더 바로 아래 **흐름 안에** 둔다.
   fixed 로 띄우면 하단 내비(--mode-nav-height)·서브내비·safe-area 를 전부 계산해야 하고,
   모드마다 높이가 달라 규칙이 네 벌로 불어난다. 페이지 최상단이라 어차피 처음 눈에 들어온다. */
.install-chip{display:flex;align-items:center;gap:10px;margin:0 12px 10px;padding:9px 10px;
  background:var(--panel2);border:2px solid var(--gold)}
.install-chip img{flex:none;width:38px;height:38px;display:block}
.install-chip .ic-text{flex:1;min-width:0}
.install-chip strong{display:block;color:var(--gold);font-size:10px;line-height:1.5}
.install-chip span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--muted);font-size:9px;line-height:1.5}
.install-chip button{flex:none;font-family:inherit;cursor:pointer;touch-action:manipulation}
.install-chip .ic-go{padding:8px 10px;border:2px solid var(--gold);background:var(--gold);
  color:#2a1d0c;font-size:10px;font-weight:700}
.install-chip .ic-no{width:26px;padding:6px 0;border:2px solid var(--line);
  background:transparent;color:var(--muted);font-size:11px;line-height:1}

/* 알림 설정 카드 (적립 탭) */
.push-card{margin-top:14px;padding:12px;background:var(--panel2);border:2px solid var(--line)}
.push-head{display:flex;align-items:center;gap:10px}
.push-emoji{flex:none;font-size:22px;line-height:1}
.push-title{flex:1;min-width:0}
.push-title strong{display:block;color:var(--gold);font-size:11px;line-height:1.6}
.push-title span{display:block;color:var(--muted);font-size:9px;line-height:1.7}
.push-card .big-action{margin-top:11px}
.push-prefs{display:flex;flex-direction:column;gap:1px;margin-top:11px}
/* 종류별 토글 — 라벨 전체가 누를 자리다(체크박스만 노리면 손가락으로 못 맞춘다). */
.push-prefs label{display:flex;align-items:center;gap:9px;padding:9px 8px;
  background:var(--panel);color:var(--ink);font-size:10px;line-height:1.5;cursor:pointer}
.push-prefs input{flex:none;width:17px;height:17px;accent-color:var(--gold);margin:0}
.push-actions{display:flex;gap:6px;margin-top:11px}

.push-actions button{flex:1}
.push-note{margin:10px 0 0;padding:9px;background:var(--panel);
  color:var(--muted);font-size:9px;line-height:1.8}

/* 설치 직후 알림 안내 — 켜는 쪽이 기본이고 거절은 직접 누르게 한다.
   '나중에' 같은 미루기 버튼을 일부러 안 뒀다. 미루기가 있으면 매번 미루다 영영 안 켜고,
   그 사이 같은 창이 실행할 때마다 떠서 오히려 더 성가시다. */
.notify-gate{position:fixed;z-index:320;inset:0;display:grid;place-items:center;padding:22px;
  background:rgba(10,7,5,.86)}
/* 목록이 6줄이라 작은 화면에서 넘칠 수 있다 — 카드 안에서 스크롤시킨다(화면이 밀리면 안 된다). */
.ng-card{width:min(100%,320px);max-height:100%;overflow-y:auto;padding:26px 20px;
  background:var(--panel);border:3px solid var(--gold);
  box-shadow:0 10px 34px rgba(0,0,0,.55);text-align:center}
.ng-icon{font-size:34px;line-height:1}
.ng-card h2{margin:14px 0 0;color:var(--gold);font-size:13px;line-height:1.6}
.ng-card p{margin:12px 0 0;color:var(--muted);font-size:10px;line-height:1.9}
.ng-lead{margin:10px 0 0}
/* 종류 목록 — 문구는 서버(push.KINDS)가 준다. 아이콘 열을 고정폭으로 잡아 글머리가 맞는다. */
.ng-list{display:flex;flex-direction:column;gap:1px;margin:12px 0 0;padding:0;list-style:none;
  text-align:left}
.ng-list li{display:flex;align-items:center;gap:9px;padding:8px 10px;background:var(--panel2)}
.ng-list i{flex:none;width:18px;font-style:normal;font-size:13px;text-align:center}
.ng-list span{min-width:0;color:var(--ink);font-size:10px;line-height:1.5}
.ng-hint{font-size:9px}
.ng-ok{margin-top:18px;padding:12px;border:2px solid var(--gold);background:var(--gold);
  color:#2a1d0c;font-size:11px;font-weight:700}
.ng-card button{width:100%;font-family:inherit;cursor:pointer;touch-action:manipulation}
.ng-yes{margin-top:20px;padding:12px;border:2px solid var(--gold);background:var(--gold);
  color:#2a1d0c;font-size:11px;font-weight:700}
.ng-yes:disabled{opacity:.6}
/* 거절은 있되 눈에 덜 띄게 — 기본값이 '켜기'라는 걸 형태로도 말한다.
   다만 **누르기 어려울 만큼 작게 만들지는 않는다**(약 41px). 거절을 방해하는 건 다크 패턴이고,
   빗나간 탭은 결국 원치 않는 허용으로 이어진다. 차이는 색·테두리·글자 크기로만 준다. */
.ng-no{margin-top:8px;padding:11px;border:2px solid var(--line);background:transparent;
  color:var(--muted);font-size:10px}

/* iOS 전용 3단계 안내 — 사파리는 설치를 코드로 못 부르니 손으로 할 일을 그 자리에 띄운다. */
.ios-steps{position:fixed;z-index:310;inset:0;display:grid;place-items:center;padding:20px;
  background:rgba(10,7,5,.82)}
.is-card{width:min(100%,320px);max-height:100%;overflow-y:auto;padding:20px;
  background:var(--panel);border:3px solid var(--gold);box-shadow:0 10px 34px rgba(0,0,0,.55)}
.is-card h2{margin:0;color:var(--gold);font-size:12px;line-height:1.6}
.is-card ol{margin:14px 0 0;padding-left:18px;color:var(--ink);font-size:10px;line-height:2}
.is-card li+li{margin-top:9px}
.is-card li b{color:var(--gold)}
.is-card small{color:var(--muted);font-size:9px}
.is-note{margin:14px 0 0;padding:9px;background:var(--panel2);
  color:var(--muted);font-size:9px;line-height:1.8}
.is-card button{width:100%;margin-top:16px;padding:11px;border:2px solid var(--gold);
  background:var(--gold);color:#2a1d0c;font-family:inherit;font-size:11px;font-weight:700;
  cursor:pointer;touch-action:manipulation}

/* ── 조합 탭 ────────────────────────────────────────────────────────────────
   재료는 **되돌릴 수 없이** 사라진다. 그래서 화면 위쪽에 고른 재료를 항상 띄워 두고
   (스크롤로 사라지지 않게), 실행 버튼은 미리보기를 받은 뒤에만 살린다. */
.craft-guide{margin-top:12px;padding:10px;background:var(--panel2);border:2px solid var(--line)}
.craft-guide-head{display:flex;align-items:flex-start;gap:8px}
.craft-guide-head>div{min-width:0;flex:1}
.craft-guide h3{margin:0;color:var(--gold);font-size:11px;line-height:1.5}
.craft-guide-count{margin:3px 0 0;color:var(--muted);font-size:8px;line-height:1.55}
.craft-guide-count b{color:var(--ink)}
.craft-guide-toggle,.craft-guide-available{flex:none;padding:7px 8px;border:1px solid var(--line);background:var(--panel);
  color:var(--muted);font-family:inherit;font-size:8px;cursor:pointer;touch-action:manipulation}
.craft-guide-toggle{color:var(--gold)}
.craft-guide-toggle span{display:inline-block;font-size:10px}
.craft-guide-toggle[aria-expanded="true"] span{transform:translateY(-1px)}
.craft-guide-available.active{border-color:var(--gold);background:rgba(242,193,78,.15);color:var(--gold)}
.craft-guide-tools{display:flex;gap:5px;margin-top:9px}
.craft-guide-tools input,.craft-guide-tools select{min-width:0;padding:7px;border:1px solid var(--line);
  background:var(--panel);color:var(--ink);font-family:inherit;font-size:8px}
.craft-guide-tools input{flex:1}
.craft-guide-tools select{max-width:94px}
.craft-guide-tools .craft-guide-available{padding:7px 6px;white-space:nowrap}
/* 스크롤 색·두께·픽셀 트랙은 dungeon.css 공통 .dq-scroll이 담당한다. */
.craft-guide-list{display:flex;flex-direction:column;gap:5px;max-height:260px;margin-top:8px;overflow-y:auto;
  overscroll-behavior:contain;padding-right:2px}
.craft-guide-row{padding:7px;background:var(--panel);border:1px solid var(--line)}
.craft-guide-row.can-craft{border-color:var(--gold);box-shadow:inset 0 0 0 1px rgba(242,193,78,.24)}
.craft-guide-row.is-hidden{border-style:dashed}
.craft-guide-recipe{display:flex;flex-wrap:wrap;align-items:center;gap:3px;color:var(--muted);font-size:8px;line-height:1.5}
.craft-guide-chip{display:inline-flex;align-items:center;gap:2px;min-height:23px;padding:1px 4px;
  border:1px solid color-mix(in srgb,var(--guide-border,var(--guide-color)) 60%,transparent);
  background:color-mix(in srgb,var(--guide-color) 14%,transparent);color:var(--guide-color);white-space:nowrap}
.craft-guide-chip .pet-img{display:block;filter:drop-shadow(0 1px 1px rgba(0,0,0,.45))}
.craft-guide-chip.mystery{justify-content:center;min-width:23px;border-color:color-mix(in srgb,var(--guide-color) 60%,transparent);
  font-size:12px;font-weight:700}
.craft-guide-chip.mystery span{font-size:8px;font-weight:400}
.craft-guide-chip b{font-size:8px}
.craft-guide-plus,.craft-guide-arrow{color:var(--muted);font-size:10px}
.craft-guide-arrow{margin:0 1px;color:var(--gold)}
.craft-guide-badge{padding:2px 4px;background:var(--line);color:var(--muted);font-size:7px;white-space:nowrap}
.craft-guide-badge.found{background:#1e4a39;color:#bff3d6}
.craft-guide-fill{width:100%;margin-top:6px;padding:7px;border:1px solid var(--gold);background:rgba(242,193,78,.12);
  color:var(--gold);font-family:inherit;font-size:9px;font-weight:700;cursor:pointer;touch-action:manipulation}
.craft-guide-fill:active{transform:scale(.99)}
.craft-guide-reason{margin:5px 0 0;color:var(--muted);font-size:8px;line-height:1.5}
.craft-guide-empty{padding:13px 8px;color:var(--muted);font-size:9px;line-height:1.6;text-align:center}
.craft-guide-empty button{display:block;margin:7px auto 0;padding:6px 8px;border:1px solid var(--gold);
  background:transparent;color:var(--gold);font-family:inherit;font-size:8px;cursor:pointer}

.craft-slots{display:grid;grid-template-columns:repeat(4,1fr);gap:5px;margin-top:10px}
.craft-slot{position:relative;display:grid;place-items:center;gap:2px;min-height:74px;
  padding:5px 3px;background:var(--panel2);border:2px solid var(--line)}
.craft-slot.filled{border-color:var(--gold);cursor:pointer}
.craft-slot.empty{border-style:dashed;color:var(--muted);font-size:16px}
.craft-slot .cs-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;
  color:var(--ink);font-size:8px;line-height:1.4}
.craft-slot .cs-lv{color:var(--muted);font-size:7px;line-height:1.3}
.craft-slot .cs-x{position:absolute;top:1px;right:3px;color:var(--gold);font-size:9px}

.craft-preview{margin-top:11px;padding:10px;background:var(--panel2);border:2px solid var(--line)}
.craft-preview h4{margin:0 0 7px;color:var(--gold);font-size:10px}
.craft-odds{display:flex;flex-direction:column;gap:4px}
.craft-odd{display:flex;align-items:center;gap:6px;font-size:9px;line-height:1.5}
.craft-odd i{flex:none;width:9px;height:9px;font-style:normal}
.craft-odd b{flex:none;min-width:44px;color:var(--ink);text-align:right;
  font-variant-numeric:tabular-nums}
.craft-odd span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--muted)}
.craft-xp{margin-top:8px;padding-top:8px;border-top:1px solid var(--line);
  color:var(--muted);font-size:9px;line-height:1.8}
.craft-xp b{color:var(--ink)}
.craft-warn{margin-top:8px;padding:7px;background:#3a2418;border:1px solid var(--gold);
  color:#ffe6bd;font-size:9px;line-height:1.7}

.craft-actions{margin-top:11px}
.craft-xfer{display:flex;align-items:center;gap:7px;margin-bottom:8px;
  color:var(--muted);font-size:9px;line-height:1.6;cursor:pointer}
.craft-xfer input{flex:none;width:15px;height:15px;accent-color:var(--gold)}
.craft-go{width:100%;padding:12px;border:2px solid var(--gold);background:var(--gold);
  color:#2a1d0c;font-family:inherit;font-size:11px;font-weight:700;cursor:pointer;
  touch-action:manipulation}
.craft-go:disabled{background:transparent;border-color:var(--line);color:var(--muted);
  cursor:not-allowed}

.craft-h3{margin:16px 0 7px;color:var(--gold);font-size:11px}
.craft-h3-sub{color:var(--muted);font-size:9px;font-weight:400}
.craft-pool{display:grid;grid-template-columns:repeat(auto-fill,minmax(64px,1fr));gap:5px}
.craft-cell{display:grid;place-items:center;gap:2px;padding:6px 3px;background:var(--panel2);
  border:2px solid var(--line);cursor:pointer;touch-action:manipulation}
.craft-cell.picked{border-color:var(--gold);background:var(--panel)}
.craft-cell.disabled{opacity:.4;cursor:not-allowed}
.craft-cell .cc-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;
  color:var(--ink);font-size:8px;line-height:1.4}
.craft-cell .cc-meta{color:var(--muted);font-size:7px;line-height:1.3}

/* ── 뽑기 탭 ────────────────────────────────────────────────────────────────
   쓰는 화폐가 상점(유물 조각)과 다르다 — 잔액을 맨 위에 크게 둬서 "무엇을 쓰는지"를
   버튼보다 먼저 읽게 한다. */
.gacha-head{display:flex;align-items:baseline;gap:7px;margin-top:10px;padding:11px 12px;
  background:var(--panel2);border:2px solid var(--gold)}
.gacha-p-label{flex:1;color:var(--muted);font-size:9px}
.gacha-p{color:var(--gold);font-size:17px;line-height:1;font-variant-numeric:tabular-nums}
.gacha-p-unit{color:var(--gold);font-size:10px}

.gacha-btns{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-top:11px}
.gacha-btn{display:grid;gap:3px;padding:13px 6px;border:2px solid var(--gold);
  background:transparent;color:var(--gold);font-family:inherit;font-size:11px;font-weight:700;
  cursor:pointer;touch-action:manipulation}
.gacha-btn span{color:var(--muted);font-size:9px;font-weight:400}
.gacha-btn.ten{background:var(--gold);color:#2a1d0c}
.gacha-btn.ten span{color:#5c4415}
/* 100연차는 2열 그리드에서 한 줄을 통째로 쓴다 — 3열로 쪼개면 세로 화면에서 글자가 깨진다. */
.gacha-btn.hundred{grid-column:1/-1;border-color:var(--epic);background:var(--epic);color:#1b1030}
.gacha-btn.hundred span{color:#3d2560}
.gacha-btn:disabled{border-color:var(--line);background:transparent;color:var(--muted);
  cursor:not-allowed}
.gacha-btn:disabled span{color:var(--muted)}

.gacha-result{margin-top:12px;padding:11px;background:var(--panel2);border:2px solid var(--gold)}
.gacha-result h4{margin:0 0 8px;color:var(--gold);font-size:10px}
.gacha-items{display:grid;grid-template-columns:repeat(auto-fill,minmax(62px,1fr));gap:5px}
.gacha-item{display:grid;place-items:center;gap:2px;padding:6px 3px;background:var(--panel);
  border:2px solid var(--line)}
.gacha-item .gi-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;
  color:var(--ink);font-size:8px;line-height:1.4}
.gacha-item .gi-tag{font-size:7px;line-height:1.3}
.gacha-emoji{font-size:22px;line-height:1.1}

.gacha-rates{display:flex;flex-direction:column;gap:4px}
.gacha-rate{display:flex;align-items:center;gap:6px;font-size:9px;line-height:1.5}
.gacha-rate i{flex:none;width:9px;height:9px;font-style:normal}
.gacha-rate b{flex:none;min-width:42px;color:var(--ink);text-align:right;
  font-variant-numeric:tabular-nums}
.gacha-rate span{flex:1;min-width:0;color:var(--muted)}

/* ── 뽑기·조합 연출 ─────────────────────────────────────────────────────────
   치장 추출(unlock-reveal)과 **같은 시각 언어**를 쓴다. 게임 안에서 "뽑는다"는 행위가
   화면마다 다르게 생기면 같은 기능인지 알아보지 못한다. 그래서 새 모달 골격을 만들지 않고
   offline-modal / reveal-burst / us-wheel 을 그대로 재사용하고 여기서는 차이만 얹는다. */
/* ⚠️ **display 를 지정한 요소는 `hidden` 속성이 안 먹는다.** 작성자 스타일(display:grid)이
   브라우저 기본 `[hidden]{display:none}` 을 이기기 때문이다. JS 가 `el.hidden = true` 로
   숨겼다고 믿는 사이 화면에는 그대로 남는다 — 실제로 가챠 10연차 그리드가 **조합 결과 화면
   아래에 계속 붙어 있었다**. `el.hidden` 만 찍어 보면 true 라 검사에서도 안 걸린다.
   display 를 주는 요소에는 반드시 [hidden] 규칙을 같이 둔다. */
.fx-sprite[hidden],.fx-grid[hidden],.fx-rarity[hidden],.reveal-rarity[hidden]{display:none}
.fx-sprite{display:grid;place-items:center;min-height:78px;margin:4px 0 2px}
.fx-sprite .pet-img{filter:drop-shadow(0 3px 6px rgba(0,0,0,.55))}
.fx-name{color:var(--gold);font-size:15px;line-height:1.5;text-shadow:2px 2px 0 var(--line)}
.fx-sub{margin-top:5px;color:var(--muted);font-size:10px;line-height:1.7}

/* 10연차·조합 결과 그리드 — 한 화면에 다 보이게 작게, 등급 테두리는 유지 */
/* ⚠️ 100연차는 20행이라 카드가 화면 밖으로 자라 **'확인' 버튼이 사라진다**(모달에 max-height
   가 없다). 그리드 자체를 스크롤 영역으로 만든다 — 10연차(2행)는 이 높이에 닿지 않는다. */
.fx-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:4px;margin-top:10px;
  max-height:46vh;overflow-y:auto;overscroll-behavior:contain}
.fx-cell{display:grid;place-items:center;gap:1px;padding:5px 2px;background:var(--panel2);
  border:2px solid var(--line)}
.fx-cell .fc-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;
  color:var(--ink);font-size:7px;line-height:1.3}

/* 조합 융합 — 재료가 가운데로 빨려들어가 하나가 된다. 확률 화면이 아니라 '합쳐진다'를 보여야
   재료가 사라진 이유가 납득된다. */
.fuse-stage{position:relative;display:grid;place-items:center;height:112px;margin:6px 0 2px}
.fuse-mat{position:absolute;animation:fuseIn .9s cubic-bezier(.5,0,.75,0) forwards}
@keyframes fuseIn{
  0%{transform:translate(var(--fx),var(--fy)) scale(1);opacity:1}
  70%{opacity:1}
  100%{transform:translate(0,0) scale(.25);opacity:0}
}
.fuse-core{width:26px;height:26px;border-radius:50%;background:var(--gold);
  box-shadow:0 0 18px 6px var(--gold);animation:fuseCore 1.5s ease-in-out infinite}
@keyframes fuseCore{0%,100%{transform:scale(.8)}50%{transform:scale(1.25)}}
@keyframes fuseCoreSoft{0%,100%{opacity:.72}50%{opacity:1}}
@media (prefers-reduced-motion:reduce){
  /* 움직임만 줄인다 — 완전히 없애면 '진행 중'이라는 유일한 신호가 사라진다. */
  .fuse-mat{animation-duration:.1s}
  /* 끄지 않고 완만하게 — 이 PC 들은 항상 reduce 를 보고하므로 끄면 '진행 중' 신호가 사라진다. */
  .fuse-core{animation-name:fuseCoreSoft;animation-duration:2.4s}
}

/* 재료 정렬 · 편성 안내 */
.craft-tools{display:flex;align-items:center;gap:6px;margin:14px 0 7px}
.craft-tools label{flex:none;color:var(--muted);font-size:9px}
.craft-sort{flex:1;min-width:0;padding:7px;background:var(--panel2);border:2px solid var(--line);
  color:var(--ink);font-family:inherit;font-size:10px}
.craft-locked-note{margin-top:6px;color:var(--muted);font-size:9px;line-height:1.7}
.craft-locked-note b{color:var(--gold)}

/* ── 펫 등장 강조 연출 ──────────────────────────────────────────────────────
   GHUB GachaRevealOverlay 와 같은 3단계(charge → burst → reveal)·같은 수치를 쓴다.
   등급이 높을수록 오래 모으고, 광선·입자가 늘고, 전설만 색종이가 떨어진다.
   ⚠️ 펫에만 쓴다 — 먹이·치장까지 이 연출을 주면 "펫이 나왔다"는 신호가 죽는다. */
.pr-overlay{position:fixed;z-index:400;inset:0;display:grid;place-items:center;overflow:hidden;
  background:radial-gradient(circle at 50% 46%,rgba(0,0,0,.72),rgba(0,0,0,.94))}
.pr-overlay.hidden{display:none}

/* 모으기 — 가운데 빛덩이가 커지며 밝아진다 */
.pr-core{width:44px;height:44px;border-radius:50%;background:var(--pr-color,#f2c14e);
  box-shadow:0 0 30px 12px var(--pr-color,#f2c14e);
  animation:prCharge var(--pr-charge,900ms) cubic-bezier(.5,0,.9,.4) forwards}
@keyframes prCharge{
  0%{transform:scale(.2);opacity:.5}
  70%{transform:scale(1.1);opacity:1}
  100%{transform:scale(2.6);opacity:1}
}
/* 폭발 — 화면 전체 섬광 */
.pr-flash{position:absolute;inset:0;background:var(--pr-color,#fff);
  animation:prFlash 450ms ease-out forwards;pointer-events:none}
@keyframes prFlash{0%{opacity:.92}100%{opacity:0}}

/* 광선 — 뒤에서 회전. 등급이 높을수록 개수가 는다(개수는 JS 가 정한다). */
.pr-rays{position:absolute;width:340px;height:340px;pointer-events:none;
  animation:prSpin 9s linear infinite}
.pr-ray{position:absolute;left:50%;top:50%;width:3px;height:170px;
  background:linear-gradient(to top,transparent,var(--pr-color,#f2c14e));
  transform-origin:50% 100%;opacity:.55}
@keyframes prSpin{to{transform:rotate(360deg)}}

.pr-particles{position:absolute;inset:0;pointer-events:none}
.pr-particle{position:absolute;left:50%;top:50%;width:6px;height:6px;border-radius:50%;
  background:var(--pr-color,#f2c14e);
  animation:prBurst 1.1s cubic-bezier(.2,.7,.4,1) forwards}
@keyframes prBurst{
  0%{transform:translate(-50%,-50%) scale(.4);opacity:1}
  100%{transform:translate(calc(-50% + var(--px)),calc(-50% + var(--py))) scale(0);opacity:0}
}
/* 색종이 — 전설 전용. "이건 특별하다"를 딱 한 등급에만 준다. */
.pr-confetti{position:absolute;top:-14px;width:6px;height:11px;
  animation:prFall linear forwards}
@keyframes prFall{to{transform:translateY(102vh) rotate(540deg);opacity:.2}}

.pr-card{position:relative;display:grid;justify-items:center;gap:8px;padding:22px 26px;
  animation:prPop .42s cubic-bezier(.2,1.5,.4,1) both}
@keyframes prPop{0%{transform:scale(.5);opacity:0}100%{transform:scale(1);opacity:1}}
.pr-badge{padding:3px 10px;border:2px solid var(--pr-color,#f2c14e);color:var(--pr-color,#f2c14e);
  font-size:10px}
.pr-art{filter:drop-shadow(0 0 14px var(--pr-color,#f2c14e))}
.pr-name{color:#fff;font-size:19px;line-height:1.4;text-shadow:2px 2px 0 rgba(0,0,0,.6)}
.pr-sub{color:var(--muted);font-size:10px;line-height:1.7;text-align:center}
.pr-shiny{color:#ffe08a;font-size:11px}
.pr-tap{margin-top:6px;color:var(--muted);font-size:9px;opacity:.8}
@media (prefers-reduced-motion:reduce){
  /* 화면 전체 섬광·낙하는 자극이 커서 없앤다. 등장 자체(pop)는 상태 신호라 남긴다. */
  .pr-rays,.pr-confetti,.pr-flash{animation:none;opacity:.3}
  .pr-particle{animation-duration:.1s}
  .pr-core{animation-duration:.2s}
}

/* 설정 화면 --------------------------------------------------------------
   헤더 톱니로 여는 전역 모달. 전투 패널(z-index:90) 위에 떠야 원정 중에도 소리를 맞출 수 있다.
   클래스 접두사 gs- 는 전역 클래스명 충돌을 피하려는 것(CLAUDE.md 13). 열림 표시는
   body.gs-modal-open 이라 버튼 클래스(.gs-open-btn)와 이름이 겹치지 않는다 - 겹치면 상태
   클래스가 컴포넌트 스타일을 먹는다. */
.gs-open-btn{flex:none;min-width:30px;padding:3px 5px;border:2px solid var(--line);background:#34291f;color:#d9d4c9;font:inherit;font-size:12px;line-height:1;cursor:pointer;box-shadow:inset -2px -2px 0 rgba(0,0,0,.3),inset 2px 2px 0 rgba(255,255,255,.06)}
.gs-open-btn:hover{background:#453528;color:var(--gold)}
.gs-open-btn:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
/* 아이콘만 남아 터치 타깃이 좁아지지 않게 최소 폭을 준다. */
.bgm-control .bgm-toggle{min-width:34px;justify-content:center}

body.gs-modal-open{overflow:hidden}
.gs-modal{position:fixed;inset:0;z-index:350;display:flex;align-items:center;justify-content:center;padding:12px;background:rgba(10,7,4,.78)}
.gs-modal[hidden]{display:none}
.gs-dialog{width:100%;max-width:380px;max-height:calc(100dvh - 24px);display:flex;flex-direction:column;background:var(--panel);border:3px solid var(--line);box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),inset 3px 3px 0 rgba(255,255,255,.06),6px 6px 0 rgba(0,0,0,.5)}
.gs-dialog:focus{outline:none}
.gs-head{flex:none;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 12px;border-bottom:2px solid var(--line)}
.gs-head strong{font-size:14px;color:var(--gold);text-shadow:2px 2px 0 var(--line)}
.gs-close{min-width:30px;min-height:26px;padding:0 6px;border:2px solid var(--line);background:#34291f;color:#d9d4c9;font:inherit;font-size:11px;line-height:1;cursor:pointer}
.gs-close:hover{background:#453528;color:var(--gold)}
.gs-close:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.gs-body{flex:1;min-height:0;overflow-y:auto;padding:12px 12px calc(12px + env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:10px}
.gs-card{padding:10px;border:2px solid var(--line);background:var(--panel2);display:flex;flex-direction:column;gap:8px}
.gs-card-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
.gs-card-title{min-width:0;font-size:12px;color:var(--ink)}
.gs-switch{flex:none;min-width:46px;padding:6px 8px;border:2px solid var(--line);background:#3c6b4a;color:#eaf7ee;font:inherit;font-size:10px;line-height:1;cursor:pointer;box-shadow:inset -2px -2px 0 rgba(0,0,0,.3),inset 2px 2px 0 rgba(255,255,255,.08)}
.gs-switch.is-off{background:#4a3a2a;color:var(--muted)}
.gs-switch:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.gs-slider-row{display:flex;align-items:center;gap:9px}
.gs-value{flex:none;min-width:40px;text-align:right;font-size:11px;color:var(--gold)}
.gs-slider{flex:1;min-width:0;height:18px;-webkit-appearance:none;appearance:none;background:transparent;cursor:pointer}
.gs-slider:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.gs-slider::-webkit-slider-runnable-track{height:8px;background:#241c12;border:2px solid var(--line)}
.gs-slider::-moz-range-track{height:8px;background:#241c12;border:2px solid var(--line)}
.gs-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:14px;height:16px;margin-top:-6px;background:var(--gold);border:2px solid var(--line);box-shadow:inset -2px -2px 0 rgba(0,0,0,.3)}
.gs-slider::-moz-range-thumb{width:14px;height:16px;background:var(--gold);border:2px solid var(--line);border-radius:0}
.gs-track{display:flex;align-items:center;gap:6px;min-width:0}
.gs-track .bgm-label{flex:none;font-size:10px;color:var(--muted)}
/* 헤더에서는 곡 제목을 좁게 잘랐지만, 설정 화면에서는 카드 폭만큼 다 쓴다. */
.gs-track .bgm-track-title{flex:1;min-width:0;max-width:none}
.gs-hint{font-size:10px;line-height:1.6;color:var(--muted)}
.gs-body .push-card{margin:0}

/* ── 회원가입 · 이어받기 코드 (Phase 2) ───────────────────────────────────
   기본은 접혀 있다 — 대다수는 신규 가입이고, 코드 칸이 늘 보이면 "코드가 있어야
   가입되나?" 하고 멈칫하게 된다.
   ⚠️ 클래스 이름에 `signup-` 접두사를 붙였다 — `.claim-box` 는 시즌 보상 수령 영역이
      이미 쓰고 있어 그대로 쓰면 그쪽 레이아웃이 딸려 온다. */
.signup-claim{margin:10px 0 4px;padding:10px 12px;border:1px solid rgba(255,255,255,.12);border-radius:10px;background:rgba(255,255,255,.03)}
.signup-claim .claim-toggle{display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer;user-select:none}
.signup-claim .claim-toggle input{width:16px;height:16px;cursor:pointer}
.signup-claim .claim-fields{margin-top:8px}
.signup-claim .claim-hint{margin:6px 2px 0;font-size:12px;line-height:1.5}
.signup-claim .claim-hint-ok{color:#7ddba0}
.signup-claim .claim-hint-bad{color:#ff9d9d}
