:root{--dq-ink:#fff7df;--dq-dark:#1f1711;--dq-panel:#34271e;--dq-line:#120d0a;--dq-gold:#f3c65b;--dq-mint:#70dbb0;--dq-red:#ef765f;--dq-blue:#78bce8;--game-shell-max:460px;--mode-nav-height:60px;--subnav-height:56px}
html{overflow-x:hidden}
/* 페이지 스크롤 막대 숨김 — 스크롤 동작(휠·드래그·키보드)은 그대로 두고 막대만 감춘다.
   실제 스크롤 컨테이너는 html 이 아니라 body 다: 바로 아래 body{overflow-x:hidden} 때문에
   overflow-y 가 visible → auto 로 계산되면서 body 가 스크롤포트가 된다(그래서 둘 다 지정).
   모달·상세 패널의 자체 스크롤(scrollbar-width:thin)은 의도된 것이므로 건드리지 않는다. */
html,body{scrollbar-width:none}
html::-webkit-scrollbar,body::-webkit-scrollbar{width:0;height:0;display:none}
/* 하단 내비(1~2층)에 가리지 않게 비워 둘 높이 = --page-pad. 방치 게임 화면은 이 여백을 body 가 아니라 #app 이 진다(style.css #app 절).
   body 가 스크롤 상자라 **body 의 아래 여백을 스크롤 범위에 넣지 않는 모바일 엔진**이 있다 — 그러면 적립 탭 맨 아래 「제작」이 내비 밑에 깔려
   끝까지 안 올라온다(2026-09-28 「모바일에서 생명의가루로 한도 제작이 안 됩니다」). 내용 안의 여백은 어느 엔진이든 스크롤된다. */
body{--page-pad:8px;padding-bottom:var(--page-pad);overflow-x:hidden}body.game-mode-authorized{--page-pad:calc(var(--mode-nav-height) + env(safe-area-inset-bottom) + 8px)}body.game-ready.idle-open:not(.game-mode-authorized){--page-pad:calc(var(--subnav-height) + env(safe-area-inset-bottom) + 8px)}body.game-mode-authorized.dungeon-open,body.game-mode-authorized.idle-open{--page-pad:calc(var(--mode-nav-height) + var(--subnav-height) + env(safe-area-inset-bottom) + 8px)}
.game-shell{width:100%;max-width:var(--game-shell-max);margin-left:auto;margin-right:auto}
.mode-hidden{display:none!important}
/* 공유 월드(별도 서비스 8703) iframe 임베드 — **화면 전체**(2026-09-24 개편). 헤더 도구 묶음(소리·알림·설정)과 하단 모드 메뉴는
   월드 위에서 사라진다 — 겹쳐서 스틱·점프·레일을 덮었다. 나가기·소리·알림·설정은 월드 안의 메뉴가 청한다(dungeon.js `world:*`).
   월드 메뉴를 못 누르는 동안(부팅·로그인·접속 종료)만 게임 창이 「나가기」를 대신 띄운다(.world-exit-fallback). */
body.world-open{overflow:hidden}
body.world-open .game-mode-nav{display:none!important}
/* 버닝타임 배너(모든 모드 공통 · 위 가운데)는 월드 메뉴 자리를 덮는다 — 월드에서는 무지개 테두리만 남긴다 */
body.world-open .burn-banner{display:none!important}
#worldMode iframe{position:fixed;inset:0;width:100%;height:100dvh;border:0;z-index:30;background:#0d1520}
#worldFramePlaceholder{position:fixed;inset:0;z-index:29;display:grid;place-items:center;background:#0d1520;color:#cfe0ee;font:700 12px "Galmuri11","Galmuri9",sans-serif}
.world-exit-fallback{position:fixed;z-index:31;top:calc(env(safe-area-inset-top) + 10px);left:calc(env(safe-area-inset-left) + 10px);display:inline-flex;align-items:center;gap:6px;padding:7px 14px 7px 9px;border-radius:999px;border:1px solid rgba(236,95,82,.65);background:rgba(13,19,29,.9);color:#ffe3de;font:800 13px "Segoe UI","Apple SD Gothic Neo","Malgun Gothic",sans-serif;box-shadow:0 6px 18px rgba(0,0,0,.42);cursor:pointer;touch-action:manipulation}
.world-exit-fallback img{width:22px;height:22px}
.world-exit-fallback[hidden]{display:none}
.game-mode-nav{position:fixed;z-index:70;left:50%;bottom:0;transform:translateX(-50%);width:min(100%,var(--game-shell-max));padding-bottom:env(safe-area-inset-bottom);display:none;grid-template-columns:repeat(auto-fit,minmax(68px,1fr));border-bottom:0;}body.game-mode-authorized .game-mode-nav{display:grid}.game-mode-nav[hidden]{display:none!important}
.game-mode-nav button{min-height:var(--mode-nav-height);display:flex;align-items:center;justify-content:center;gap:4px;cursor:pointer;touch-action:manipulation;padding:0 2px;white-space:nowrap}.game-mode-nav button[hidden]{display:none!important}
.game-mode-nav button:last-child{border-right:0}
/* ⚠️ 여기 있던 `font-size:15px` 는 **아이콘이 글자(이모지)이던 시절의 크기**였다(2026-08-29 제거).
   지금 아이콘은 `.gi` 로 px 가 고정이라 이 값이 닿는 곳은 라벨 span 둘(.battle-nav-label ·
   .world-boss-nav-label)뿐이었고, 버튼 기본값 9px 을 이겨서 **그 둘만 15px** 로 커져 있었다
   (3~5칸에서 눈에 띄고, 6·7칸에서만 [data-cols] 패치가 9px 로 되돌리고 있었다). */
.game-mode-nav button span{display:inline-block;line-height:1;margin:0}
.dungeon-shell{padding:12px 10px 28px;font-family:"Galmuri11","Galmuri9",sans-serif;min-height:calc(100vh - var(--mode-nav-height));min-height:calc(100dvh - var(--mode-nav-height) - env(safe-area-inset-bottom))}body.dungeon-open .dungeon-shell{min-height:calc(100dvh - var(--mode-nav-height) - var(--subnav-height) - env(safe-area-inset-bottom))}
.panel-title{display:flex;align-items:center;justify-content:space-between;gap:12px}.panel-title h2{margin:2px 0 0}.eyebrow{display:block;color:var(--dq-gold);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;letter-spacing:1.4px}.dungeon-summary{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}.dungeon-summary span{padding:7px 9px;}
.dungeon-state{margin:15px 0;padding:14px;text-align:center}.dungeon-state.error{color:#ffc1b5}.dungeon-state.warning{color:#ffe3a1;border-color:#8f682b}.dungeon-state button{margin-left:10px}
/* 던전 전용 2층 하단 탭 — 편성 / 아이템(파워스톤) 전환. 상세 배치·모션은 파일 하단 규칙. */
.dtab{flex:1;font-family:"Galmuri11","Galmuri9",sans-serif;cursor:pointer;font-size:12px;padding:11px 4px;color:var(--muted);background:var(--panel2);border:3px solid var(--line);touch-action:manipulation}
.dtab.active{color:var(--gold);background:var(--panel);box-shadow:inset 0 3px 0 var(--gold)}
.dungeon-tabpanel.hidden{display:none}
.dungeon-panel{margin-top:15px;padding:15px;}.panel-title>strong{padding:7px 9px;}
.dungeon-zone{padding:10px;margin-top:10px;}.dungeon-zone h3{margin:0 0 8px;}.stage-row{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:7px}.stage-node{min-height:48px;font:700 12px "Galmuri11","Galmuri9",sans-serif;overflow:hidden;cursor:pointer}.stage-node small{display:block;margin-top:2px}.stage-node.selected{outline:3px solid var(--dq-gold);transform:translateY(-2px)}.stage-node:disabled{opacity:.38;cursor:not-allowed;filter:grayscale(1)}
.repeat-reward-status{margin:9px 0 2px;padding:8px 10px;border:2px solid #755a47;background:#2b1f17;color:#e8dac5;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.6}.repeat-reward-status strong{color:#ffe09a}.repeat-reward-status.first-clear{border-color:#4b967d;background:#1c302a;color:#b9efd9}.repeat-reward-status.exhausted{border-color:#a7504c;background:#3a2023;color:#ffc1b8}.repeat-reward-status .quota{color:#fff0b2}
.dungeon-actions{display:grid;grid-template-columns:1.5fr 1fr;gap:8px;margin-top:12px}.cube-action{padding:11px;cursor:pointer;touch-action:manipulation}.cube-action:active{transform:translate(2px,2px);}.cube-action.rest{background:#387563;box-shadow:inset 0 3px 0 #6bb397,3px 3px 0 #110c09}.cube-action.small{padding:8px;}.system-note{line-height:1.7;margin:11px 0 0}
/* 편성 레인/슬롯 보드의 본 스타일은 파일 하단 '원탭 편성 개편' 섹션 참고. .assignment-empty 는 상대 상세 빈 상태에서 재사용. */
.assignment-empty{display:grid;place-items:center;min-height:30px;padding:4px;border:1px dashed #4e3d30;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;text-align:center;line-height:1.45}
.fatigue-guide{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:8px;padding:8px 9px;border:1px solid #564233;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;}.fatigue-guide>span{display:flex;align-items:center;gap:4px}.fatigue-dot{display:inline-block;width:8px;height:8px;border:1px solid #09070a}.fatigue-dot.ready{background:#71d8aa}.fatigue-dot.resting{background:#e9b959}.fatigue-dot.empty{background:#69404a}
.dungeon-pets{display:grid;grid-template-columns:1fr;gap:10px;margin-top:12px}.dungeon-pet-card{position:relative;order:0;border:3px solid #111;padding:10px;}.dungeon-pet-card.in-party{order:-30;}.pet-fatigue{margin-top:8px;padding:7px;background:#1c140f;border:1px solid #4d3b2e}.fatigue-label,.rest-progress{display:flex;align-items:center;justify-content:space-between;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.fatigue-label strong{color:#ffd36b;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.fatigue-meter{height:8px;margin:4px 0 7px;background:#452b34;border:1px solid #09070a;overflow:hidden}.fatigue-meter i{display:block;width:0;height:100%;transition:width .2s;background:linear-gradient(90deg,#e7b853,#71d8aa)}.rest-progress{color:#bcae98}.rest-pips{display:flex;gap:3px;margin-left:auto}.rest-pips i{width:12px;height:5px;background:#503e32;border:1px solid #0a080b}.rest-pips i.filled{background:var(--dq-blue)}.skill-list{display:grid;gap:4px}.pet-skill{display:block;border-left:3px solid #a47dc2;padding:6px}.pet-skill b,.pet-skill small{display:block}.pet-skill b{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;}.pet-skill small{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.55;margin-top:3px}.empty-note{text-align:center;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;padding:30px}

/* Compact pet grid: the same three-column scan view is used on mobile and desktop. */
.roster-lane-heading{display:flex;align-items:baseline;gap:7px;min-width:0;flex-wrap:wrap}
.dungeon-pets{grid-template-columns:repeat(3,minmax(0,1fr));gap:7px}.dungeon-pet-card{appearance:none;min-width:0;min-height:82px;padding:12px 6px 7px;display:flex;flex-direction:column;align-items:center;gap:5px;font-family:"Galmuri11","Galmuri9",sans-serif;text-align:center;touch-action:manipulation}.pet-grid-name{display:flex;align-items:center;justify-content:center;gap:3px;width:100%;line-height:1.35}.pet-name-txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.pet-grid-meta{display:flex;align-items:center;justify-content:center;gap:5px;width:100%;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.pet-grid-meta b{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.pet-grid-fatigue{width:100%;margin-top:auto}.pet-grid-fatigue-meter{height:6px;margin-top:3px;border:1px solid #09070a;overflow:hidden}.pet-grid-fatigue-meter i{display:block;height:100%;background:linear-gradient(90deg,#e7b853,#71d8aa)}

/* Accessible pet details dialog. */
body.pet-detail-open{overflow:hidden}.pet-detail-modal[hidden]{display:none!important}.pet-detail-modal{position:fixed;z-index:85;inset:0;display:grid;place-items:center;padding:calc(10px + env(safe-area-inset-top)) 10px calc(var(--mode-nav-height) + 10px + env(safe-area-inset-bottom));background:rgba(7,5,9,.78);font-family:"Galmuri11","Galmuri9",sans-serif}.pet-detail-dialog{position:relative;width:min(100%,440px);max-height:100%;overflow-y:auto;padding:15px;border:3px solid #0b080d;scrollbar-width:thin}.pet-detail-dialog:focus{outline:none}.pet-detail-close{position:absolute;z-index:2;top:8px;right:8px;width:34px;height:34px;border:2px solid #0b080d;background:#5c3540;color:#fff;font:700 18px/1 "Galmuri11","Galmuri9",sans-serif;cursor:pointer}.pet-detail-header{padding-right:30px}.pet-detail-title-wrap h2{margin:0;font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif;line-height:1.4}.pet-detail-title-wrap p{margin:5px 0 0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.6}.pet-detail-status{display:flex;gap:4px;flex-wrap:wrap;margin-top:7px}.pet-detail-status>span{padding:3px 6px;background:#35281f;border:1px solid #654c3a;color:#ccc0ad;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.pet-detail-status .pet-detail-element{display:inline-flex;align-items:center;gap:5px}.pet-detail-status .party{border-color:#55a98b;color:#a8f1d3}.pet-detail-status .training{border-color:#5589aa;color:#b9e8ff}.pet-detail-section{margin-top:11px;padding:9px;border:1px solid #594435}.pet-detail-section h3{margin:0 0 7px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.pet-detail-fatigue .pet-fatigue{margin:0}.pet-detail-stat-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px}.pet-detail-stat{min-width:0;padding:6px 4px;border:1px solid #594435;text-align:center}.pet-detail-stat span,.pet-detail-stat b{display:block}.pet-detail-stat span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.pet-detail-stat b{margin-top:3px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.pet-attribute-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:3px;margin-top:6px}.pet-attribute{min-width:0;padding:5px 2px;text-align:center}.pet-attribute span,.pet-attribute b{display:block}.pet-attribute span{overflow:hidden;text-overflow:ellipsis;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.pet-attribute b{margin-top:3px;color:#8fe0c2;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.pet-detail-section .skill-list{gap:5px}.pet-detail-section .pet-skill{padding:7px}.pet-detail-actions{position:sticky;bottom:-15px;display:grid;grid-template-columns:1fr 1fr;gap:6px;margin:12px -15px -15px;padding:10px 15px calc(10px + env(safe-area-inset-bottom));border-top:2px solid #110c09}.pet-detail-actions button{min-height:42px;padding:6px;border:2px solid #120d0a;background:#70533f;color:#fff;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;touch-action:manipulation}.pet-detail-actions button.team-active,.pet-detail-actions button.selected{background:#32715e;border-color:#b8ffe6}.pet-detail-actions button.danger{background:#753d45;border-color:#ffb2a9}.pet-detail-actions button:disabled{opacity:.5;cursor:not-allowed}
.stone-target{display:flex;align-items:center;gap:8px;width:max-content;margin-top:10px;padding:6px 8px;border:2px solid #110c09;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.stone-target select,.stone-card button{min-height:32px;border:2px solid #110c09;background:#5f4736;color:#fff;font:700 10px "Galmuri9","Galmuri11",sans-serif}.stone-target select{padding:0 6px}.dungeon-stones{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin-top:12px}.stone-card{display:grid;grid-template-columns:40px 1fr auto auto;align-items:center;gap:7px;padding:8px;border:2px solid #110c09}.stone-gem{width:36px;height:36px;display:grid;place-items:center;border:2px solid #100c08;color:#79c8f0;font-size:18px;font-family:"Galmuri11","Galmuri9",sans-serif}.stone-card.hp .stone-gem{color:#ef7f87}.stone-card strong,.stone-card span,.stone-card em{display:block}.stone-card strong{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.stone-card span{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;margin-top:3px}.stone-card em{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#87d9b9;margin-top:3px;font-style:normal}.stone-card button{padding:0 8px}.stone-card button.ghost{background:#3d3026}
.battle-panel{position:fixed;visibility:hidden;z-index:90;top:0;bottom:0;left:50%;right:auto;width:min(100%,var(--game-shell-max));height:100vh;height:100dvh;transform:translateX(-50%);overflow:hidden;background:#110c09;opacity:0;pointer-events:none;transition:opacity .2s;box-shadow:0 0 28px #000}.battle-panel.active{visibility:visible;opacity:1;pointer-events:auto}.dungeon-canvas,.dungeon-canvas canvas{position:absolute;inset:0;width:100%;height:100%;display:block;touch-action:none}.battle-top{position:absolute;z-index:4;top:calc(8px + env(safe-area-inset-top));left:8px;right:8px;display:flex;justify-content:space-between;align-items:flex-start;pointer-events:none}.battle-progress-box{display:flex;align-items:stretch;min-width:0;background:#1f1711dd;border:2px solid #e8c265}.battle-top strong{display:grid;place-items:center;padding:7px 9px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;white-space:nowrap}.battle-progress-box span{display:grid;place-items:center;min-width:0;padding:6px 8px;border-left:1px solid #7f6738;color:#f3e8c7;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.35}.battle-top button{pointer-events:auto;padding:7px;background:#5d2d32;color:#fff;border:2px solid #170b0c;font:700 10px "Galmuri9","Galmuri11",sans-serif;touch-action:manipulation}.battle-top button:disabled{opacity:.5;cursor:not-allowed}.battle-field-legend{position:absolute;z-index:3;top:calc(47px + env(safe-area-inset-top));left:8px;display:flex;align-items:center;gap:5px;padding:4px 6px;background:#100d13b8;border:1px solid #504259;color:#d4cadb;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.battle-field-legend i{color:#9f93a8;font-style:normal}.battle-field-legend .ally-side{color:#80dfbd}.battle-field-legend .enemy-side{color:#ff9385}.battle-camera-controls{position:absolute;z-index:5;top:calc(47px + env(safe-area-inset-top));right:8px;display:flex;flex-direction:column;align-items:flex-end;gap:5px;pointer-events:none}.battle-camera-controls button{pointer-events:auto;display:grid;place-items:center;min-width:32px;min-height:30px;padding:0;border:2px solid #0a080c;background:#37291fdd;color:#fbf8f3;font:700 10px "Galmuri9","Galmuri11",sans-serif;touch-action:manipulation}.battle-camera-controls .camera-follow{min-width:106px;padding:0 7px}.battle-camera-controls .camera-follow.active{border-color:var(--dq-mint);color:#baffdf;background:#254d42e8}.camera-dpad{display:grid;grid-template-columns:repeat(3,32px);grid-template-rows:repeat(3,30px);gap:2px}.camera-dpad #cameraUp{grid-column:2}.camera-dpad #cameraLeft{grid-column:1;grid-row:2}.camera-dpad #cameraReset{grid-column:2;grid-row:2;color:var(--dq-gold)}.camera-dpad #cameraRight{grid-column:3;grid-row:2}.camera-dpad #cameraDown{grid-column:2;grid-row:3}.battle-pets{position:absolute;z-index:4;left:5px;right:5px;bottom:calc(6px + env(safe-area-inset-bottom));display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px}.battle-pet-hud{min-width:0;background:#1f1711e8;border:2px solid #0b080d;padding:5px}.battle-pet-name{display:flex;align-items:center;gap:3px;min-width:0}.battle-pet-name span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.battle-pet-hud>span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.hp-track{height:6px;background:#4b2229;margin:4px 0;border:1px solid #0a0709}.hp-track i{display:block;height:100%;background:#67d296}.battle-skills{display:grid;grid-template-columns:1fr;gap:2px}.battle-skills button{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:4px 2px;background:#886246;color:#fff;border:1px solid #18110c;font:700 10px "Galmuri9","Galmuri11",sans-serif;touch-action:manipulation}.battle-skills button:disabled{opacity:.55}.battle-skills small{display:inline;margin-left:2px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#ffe89b}.battle-result{position:absolute;z-index:8;inset:0;display:grid;place-items:center;pointer-events:none}.result-card{width:calc(100% - 40px);max-width:330px;min-width:0;max-height:calc(100dvh - 40px);overflow:auto;padding:22px 16px;background:#19141eee;border:4px solid #ded2e7;text-align:center;box-shadow:0 0 40px #000}.result-card strong,.result-card span{display:block}.result-card strong{font-size:24px;font-family:"Galmuri11","Galmuri9",sans-serif;color:#ffd66d}.result-card span{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.7;margin-top:9px}.result-card button{pointer-events:auto;margin-top:12px;padding:9px 12px;background:#5b496d;color:#fff;border:2px solid #0d0911;font:700 10px "Galmuri9","Galmuri11",sans-serif}.result-card .result-return{width:100%;background:#3c8069;border-color:#b8ffe6}.result-card.lose strong{color:#ff8b7f}
.dungeon-toast{position:fixed;z-index:110;left:50%;bottom:calc(var(--mode-nav-height) + env(safe-area-inset-bottom) + 10px);transform:translate(-50%,20px);opacity:0;pointer-events:none;width:max-content;max-width:min(90%,420px);padding:10px 14px;transition:.2s}.dungeon-toast.show{opacity:1;transform:translate(-50%,0)}.dungeon-toast.error{border-color:#e46d60}
body.dungeon-open .dungeon-toast{bottom:calc(var(--mode-nav-height) + var(--subnav-height) + env(safe-area-inset-bottom) + 10px)}
/* 토스트를 하단 내비 위로 올리는 조건은 '던전 권한'이 아니라 '모드 내비가 보이는가'다 —
   game.js updateModeNavigation 이 game-mode-authorized 와 nav.hidden 을 함께 토글한다.
   dungeon-authorized 로 좁히면 월드만 열린 유저(던전 OFF + 월드 ON)의 토스트가 내비 뒤에 깔린다. */
body.game-ready.idle-open .toast{bottom:calc(var(--subnav-height) + env(safe-area-inset-bottom) + 10px)}body.game-mode-authorized.idle-open .toast{bottom:calc(var(--mode-nav-height) + var(--subnav-height) + env(safe-area-inset-bottom) + 10px)}
/* 상점 모드: 하단 모드 내비(방치/던전/월드/상점) 위로 토스트를 올려 겹침 방지 */
body.game-mode-authorized.shop-open .toast{bottom:calc(var(--mode-nav-height) + env(safe-area-inset-bottom) + 10px)}
@media(max-width:460px){.dungeon-shell{padding:10px 8px 24px}.dungeon-stones{grid-template-columns:1fr}.stone-card{grid-template-columns:38px 1fr auto}.stone-card select{grid-column:1/3}.panel-title{align-items:flex-start}}
@media(max-width:360px){.dungeon-summary{justify-content:flex-start}.dungeon-summary span{padding:6px}.roster-lanes{grid-template-columns:1fr}.dungeon-pets{gap:5px}.dungeon-pet-card{min-height:78px;padding:11px 4px 6px}.pet-grid-name{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.pet-detail-dialog{padding:12px}.pet-detail-title-wrap h2{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}.pet-detail-actions{bottom:-12px;margin:10px -12px -12px;padding-left:12px;padding-right:12px}.battle-camera-controls .camera-follow{min-width:94px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.camera-dpad{grid-template-columns:repeat(3,29px);grid-template-rows:repeat(3,27px)}.battle-camera-controls button{min-width:29px;min-height:27px}.battle-field-legend{max-width:165px}.battle-pet-hud{padding:4px 3px}.battle-skills button{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}}
.pet-grid-fatigue{display:block;width:100%}.pet-grid-fatigue-meter{display:block;width:100%;height:6px;box-sizing:border-box}.dungeon-zone h3>small{float:right;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-weight:400;line-height:1.6}.stage-node small{white-space:nowrap}.pet-experience-label{display:flex;align-items:center;justify-content:space-between;color:#cabdaa;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.pet-experience-label strong{color:#ffe09a;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.pet-experience-meter{height:8px;margin-top:5px;border:1px solid #09070a;overflow:hidden}.pet-experience-meter i{display:block;height:100%;background:linear-gradient(90deg,#7669dc,#68d6d2,#f0ca66)}.result-card .experience-summary{color:#9de2ca}.result-card .repeat-limit-summary{padding:6px;border:1px solid #8c6d36;background:#332817;color:#ffe1a0}
@media(prefers-reduced-motion:reduce){.battle-panel,.dungeon-toast{transition:none}}

/* Cube Pet HD — 목록/팀 3D 썸네일 */
.dungeon-pet-card .pet-grid-portrait { display:block; margin:2px auto 4px; line-height:0; }
.dungeon-pet-card .pet-grid-portrait .pet-portrait { width:72px; height:72px; display:block; margin:0 auto; }
/* 슬롯 보드 타일 얼굴 — 옛 편성 칩의 황금 얼굴판을 계승 */
.slot-face .pet-portrait { display:block; width:44px; height:44px; box-sizing:border-box; border:1px solid rgba(255,255,255,.14); border-radius:8px; background:rgba(255,255,255,.06); }
.slot-face .pet-portrait-face { border-color:#8b691e; background:linear-gradient(145deg,#fff4b8,#e8b42d); box-shadow:inset 0 2px 0 rgba(255,255,255,.48); }
/* GHUB 마스터: 이벤트 펫 얼굴 배경 = 애니메이션 그라디언트(시즌 보상 등 특별 펫).
   그라디언트는 portrait_fx.js 카탈로그의 프리셋을 인라인 --evt-bg 로 주입(기본 rainbow 폴백).
   기본 노란색·시즌 티어 무지개·인라인 단색보다 항상 우선(!important)이어야 특별함이 드러난다. */
.pet-portrait.pet-portrait-event{ background:var(--evt-bg,linear-gradient(125deg,#ff5db1,#ffd166,#6ee7a8,#7cf5ff,#a78bfa,#ff5db1))!important; background-size:320% 320%!important; border-color:#ffd9f2!important; animation:portraitHolo 6s ease-in-out infinite alternate; }
@keyframes portraitHolo{ from{background-position:0% 50%} to{background-position:100% 50%} }
@media(prefers-reduced-motion:reduce){ .pet-portrait.pet-portrait-event{ animation:none } }

/* Dungeon 3D presentation FX. The pulse/sweep keyframes are shared with the
   idle-game formation UI in style.css; the aura itself is baked by WebGL. */
.pet-portrait.pet-shiny{animation:minerShiny 1.5s ease-in-out infinite}
.slot-tile.shiny,.dungeon-pet-card.shiny{position:relative;isolation:isolate;animation:shinyPulse 1.6s ease-in-out infinite}
.slot-tile.shiny::after,.dungeon-pet-card.shiny::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;background:linear-gradient(105deg,transparent 28%,rgba(255,255,255,.08) 40%,rgba(255,246,176,.5) 49%,rgba(174,244,255,.18) 56%,transparent 69%);background-size:280% 100%;background-repeat:no-repeat;animation:shinySweep 2.6s ease-in-out infinite}
@media(prefers-reduced-motion:reduce){.pet-portrait.pet-shiny,.slot-tile.shiny,.dungeon-pet-card.shiny,.slot-tile.shiny::after,.dungeon-pet-card.shiny::after{animation:none}.pet-portrait.pet-shiny{filter:drop-shadow(0 0 7px #ffe27a)}.slot-tile.shiny,.dungeon-pet-card.shiny{box-shadow:0 0 16px #ffe27a}}

.pet-detail-header{display:grid;grid-template-columns:116px minmax(0,1fr);align-items:center;gap:13px;min-height:122px;padding:8px 38px 8px 8px;border:2px solid #0b080d;}
.pet-detail-portrait{width:112px;height:112px;display:grid;place-items:center;background:radial-gradient(circle,#fff9d9,rgba(255,255,255,.15) 55%,rgba(0,0,0,.13) 72%);border:2px solid rgba(255,255,255,.28);overflow:hidden}
.pet-detail-portrait .pet-portrait{display:block;width:112px;height:112px}
@media(max-width:360px){.pet-detail-header{grid-template-columns:92px minmax(0,1fr);gap:9px}.pet-detail-portrait,.pet-detail-portrait .pet-portrait{width:88px;height:88px}}

/* Dungeon battle cinematic state. World HP bars and numbers are rendered in WebGL. */
.battle-phase-banner{position:absolute;z-index:7;top:24%;left:50%;min-width:170px;max-width:calc(100% - 40px);padding:10px 16px;transform:translate(-50%,-10px) scale(.92);opacity:0;pointer-events:none;text-align:center;color:#fff8dc;background:#1f1711e8;border:3px solid #ffd66d;box-shadow:0 0 28px rgba(255,211,77,.26),inset 0 2px 0 rgba(255,255,255,.18);font:700 15px "Galmuri14","Galmuri11",sans-serif;letter-spacing:1px;transition:opacity .16s,transform .16s}
.battle-phase-banner.show{opacity:1;transform:translate(-50%,0) scale(1);animation:battlePhasePop .42s ease-out}
.battle-phase-banner[data-phase="enemy-focus"]{color:#ffd7d1;border-color:#ff7c70;box-shadow:0 0 28px rgba(255,84,74,.3)}
.battle-phase-banner[data-phase="ally-focus"]{color:#dff6ff;border-color:#6fc5ff;box-shadow:0 0 28px rgba(83,175,255,.3)}
.battle-phase-banner[data-phase="combat-start"]{color:#fff1a3;border-color:#ffe050;font-size:20px;font-family:"Galmuri11","Galmuri9",sans-serif}
.battle-phase-banner[data-phase="wave-transition"]{color:#dfffe9;border-color:#67d99b}
.battle-phase-banner[data-phase="battle-defeat"]{color:#ffd3cf;border-color:#ff655c;box-shadow:0 0 32px rgba(255,66,57,.38)}
.battle-camera-controls button:disabled{pointer-events:none;opacity:.32;filter:grayscale(1)}
@keyframes battlePhasePop{0%{transform:translate(-50%,-8px) scale(.82)}65%{transform:translate(-50%,1px) scale(1.06)}100%{transform:translate(-50%,0) scale(1)}}
@media(prefers-reduced-motion:reduce){.battle-phase-banner{transition:none}.battle-phase-banner.show{animation:none}}

.battle-pet-hud.skill-casting{border-color:#ffe06b;box-shadow:0 0 15px rgba(255,218,74,.42);animation:battleSkillHudPulse .46s ease-out 2}.battle-pet-name{position:relative}.battle-skill-callout{position:absolute;z-index:2;left:50%;bottom:calc(100% + 5px);max-width:130px;padding:4px 6px;transform:translateX(-50%);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:#34251be8;border:2px solid #ffe06b;color:#fff2a8;font:700 10px "Galmuri9","Galmuri11",sans-serif;font-style:normal;box-shadow:0 0 14px rgba(255,218,74,.42);animation:battleSkillCallout 1.3s ease-out both}.battle-skills button.skill-used,.battle-skills button.skill-used:disabled{filter:none;opacity:1;color:#251500;background:linear-gradient(100deg,#ffd55f,#fff4ae,#ffad50);border-color:#fff5bc;animation:battleSkillButton .5s ease-out 2}.battle-skills button.skill-used small{color:#7b2600}
.battle-skills button{position:relative;isolation:isolate}.battle-skills button:disabled{filter:none;opacity:.55}.battle-skills button.cooldown:disabled{opacity:1}.battle-skills .skill-cooldown-gauge{position:absolute;z-index:0;inset:0;display:block;background:rgba(48,51,58,.82);box-shadow:inset -1px 0 0 rgba(255,255,255,.3);pointer-events:none;transform:scaleX(var(--skill-cooldown,0));transform-origin:left;transition:transform .12s linear}.battle-skills .skill-button-label,.battle-skills button small{position:relative;z-index:1}.battle-skills .skill-button-label{display:inline-block;max-width:70%;overflow:hidden;text-overflow:ellipsis;vertical-align:middle}.battle-skills button.cooldown small{color:#f4f4f4;text-shadow:0 1px #24262b}.battle-skills button.ready .skill-cooldown-gauge{opacity:0}.battle-skills button.skill-used .skill-cooldown-gauge{background:rgba(54,55,59,.52)}
.battle-pet-hud.pet-down{position:relative;background:linear-gradient(145deg,rgba(51,34,42,.96),rgba(31,25,20,.96));border-color:#a84b55;box-shadow:inset 0 0 13px rgba(118,24,35,.45)}.battle-pet-hud.pet-down .battle-pet-name>span:first-child{color:#b4a897;text-decoration:line-through}.battle-death-state{flex:0 0 auto!important;display:inline-flex!important;align-items:center;gap:2px;min-width:max-content!important;padding:2px 3px;overflow:visible!important;background:#6d2831;border:1px solid #e6787f;color:#fff2f2!important;font-size:10px!important;font-family:"Galmuri9","Galmuri11",sans-serif!important;line-height:1;white-space:nowrap}.battle-death-state b{font-family:"Segoe UI Emoji",sans-serif;font-size:10px;line-height:1}.battle-pet-hud.pet-down .hp-track{background:#251d22;border-color:#4f333a}.battle-pet-hud.pet-down .hp-track i{background:#6f555b}.battle-pet-hud.pet-down .battle-skills{filter:grayscale(1);opacity:.38}.battle-pet-hud.pet-down .battle-skills button{cursor:not-allowed}
/* ── 상시 발동(패시브) 배지 ─────────────────────────────────────────────────────
   **버튼이 아니다** — 쿨다운도 시전도 없어 누를 게 없다. 그래서 버튼 색을 빌리지 않고,
   대신 *살아 있는 연출*을 준다: 이 펫이 남과 다른 기술을 늘 두르고 있다는 것을 글자가
   아니라 움직임으로 말한다(제보 #5315 "히든인데 기술이 2개로 보이니까 쩌리같아여").

   두 축으로 갈린다 — **움직임은 behavior(`data-fx`)**, **색은 속성**. 색은 새로 정하지 않고
   화면이 이미 쓰는 `.elem-*`(`--elem-c`, 아래 §속성 배지)에서 끌어온다 — 따로 적었더니
   전기 배지는 노랑인데 같은 펫 패시브 배지는 보라로 뜨는 일이 실제로 있었다.
   짝은 뜻 그대로다: burn 솟는 열기(공격) · spike 톱니(반사) · hunt 조준선(노림) ·
   stalk 흐르는 그림자(추격).

   ⚠️ **`--pfx-t` 없이는 연출이 한 번도 안 보인다.** `renderBattleHud` 가 120ms 마다
   `innerHTML` 을 통째로 갈아 끼우므로 배지 노드는 초당 8번 새로 태어나고, 그때마다
   CSS 애니메이션이 0% 로 되감긴다(2.2~5.2초짜리가 4~5% 만 재생되고 끊긴다).
   그래서 화면이 경과 초를 `--pfx-t` 로 실어 주고, 여기서 **음수 지연**으로 되돌린다 —
   새로 태어난 노드가 "이미 그만큼 재생된" 상태로 시작해 끊김 없이 이어진다.

   전투 화면이라 **읽기가 먼저다**: 연출은 전부 글자 뒤(z-index 0)에 깔리고 `transform`·
   `opacity` 만 움직인다(합성기가 돌려 메인 스레드 페인트가 0 — WebGL 프레임과 같은 스레드다).
   `background-position` 은 쓰지 않는다. 정지는 파일 끝 reduced-motion 블록이 맡는다. */
.battle-skills .skill-passive,.battle-pet-hud.has-passive{--pfx-core:var(--elem-c,#cebca1);--pfx-hot:color-mix(in srgb,var(--pfx-core) 52%,#fff);--pfx-edge:color-mix(in srgb,var(--pfx-core) 68%,#1e150f);--pfx-fx-delay:calc(var(--pfx-t,0) * -1s)}

.battle-skills .skill-passive{position:relative;isolation:isolate;contain:paint;display:flex;align-items:center;gap:3px;min-width:0;padding:4px 3px;overflow:hidden;background:#251b13;border:1px solid var(--pfx-edge);color:#f6ecde;font:700 10px "Galmuri9","Galmuri11",sans-serif;text-align:left;cursor:default}
.battle-skills .skill-passive>.passive-mark,.battle-skills .skill-passive>.skill-button-label,.battle-skills .skill-passive>small{position:relative;z-index:1}
.battle-skills .skill-passive>.passive-mark{flex:0 0 auto;padding:1px 3px;background:var(--pfx-edge);color:#faf4ec;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.25;font-style:normal}
.battle-skills .skill-passive>.skill-button-label{flex:1 1 auto;max-width:none;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}
.battle-skills .skill-passive>small{flex:0 0 auto;margin-left:0;color:var(--pfx-hot);text-shadow:0 1px 2px #0f0a07}
.battle-skills .skill-passive .passive-fx{position:absolute;inset:0;z-index:0;display:block;overflow:hidden;pointer-events:none}
.battle-skills .skill-passive .passive-fx::before,.battle-skills .skill-passive .passive-fx::after{content:'';position:absolute;display:block;animation-delay:var(--pfx-fx-delay)}
/* 반경 안에 적이 들어와 실제로 피해가 들어가는 순간 — 배지가 눈에 띄게 달아오른다. */
.battle-skills .skill-passive.hitting{border-color:var(--pfx-hot);color:#fff;box-shadow:inset 0 0 9px rgba(255,255,255,.12),0 0 7px -2px var(--pfx-core)}
.battle-skills .skill-passive.hitting .passive-fx{filter:brightness(1.4) saturate(1.25)}
.battle-skills .skill-passive.hitting>.passive-mark{background:var(--pfx-hot);color:#1c140f}

/* burn — 공격형 오라. 아래에서 열기가 솟고 사선 광택이 훑는다("세다"). */
.battle-skills .skill-passive[data-fx="burn"] .passive-fx{background:radial-gradient(ellipse 46% 58% at 16% 118%,var(--pfx-hot),transparent 70%),radial-gradient(ellipse 40% 64% at 52% 126%,var(--pfx-core),transparent 72%),radial-gradient(ellipse 44% 56% at 84% 120%,var(--pfx-hot),transparent 70%);opacity:.5;animation:pfxBurnRise 2.2s ease-in-out infinite;animation-delay:var(--pfx-fx-delay)}
.battle-skills .skill-passive[data-fx="burn"] .passive-fx::after{top:0;bottom:0;left:-120%;right:-120%;background:linear-gradient(104deg,transparent 46%,var(--pfx-hot) 50%,transparent 54%);opacity:.26;animation:pfxSheen 3s linear infinite}
/* spike — 반사. 위아래 모서리에서 톱니가 자라 서로 반대로 흐른다("뾰족하다"). */
.battle-skills .skill-passive[data-fx="spike"] .passive-fx::before,.battle-skills .skill-passive[data-fx="spike"] .passive-fx::after{left:-14px;right:-14px;height:5px;background-image:linear-gradient(45deg,var(--pfx-edge) 25%,transparent 25%),linear-gradient(-45deg,var(--pfx-edge) 25%,transparent 25%);background-size:7px 5px;background-repeat:repeat-x}
.battle-skills .skill-passive[data-fx="spike"] .passive-fx::after{top:0;opacity:.55;animation:pfxSaw 2.6s linear infinite}
.battle-skills .skill-passive[data-fx="spike"] .passive-fx::before{bottom:0;opacity:.75;animation:pfxSawFlip 2.6s linear infinite}
/* hunt — 강자 사냥. 네 귀퉁이 조준 브래킷 + 좌우로 훑는 스캔선("노린다"). */
.battle-skills .skill-passive[data-fx="hunt"] .passive-fx{background:linear-gradient(var(--pfx-core),var(--pfx-core)) 0 0/5px 1px no-repeat,linear-gradient(var(--pfx-core),var(--pfx-core)) 0 0/1px 5px no-repeat,linear-gradient(var(--pfx-core),var(--pfx-core)) 100% 100%/5px 1px no-repeat,linear-gradient(var(--pfx-core),var(--pfx-core)) 100% 100%/1px 5px no-repeat;opacity:.8;animation:pfxLock 2.4s ease-in-out infinite;animation-delay:var(--pfx-fx-delay)}
.battle-skills .skill-passive[data-fx="hunt"] .passive-fx::after{top:0;bottom:0;left:-120%;right:-120%;background:linear-gradient(90deg,transparent 46%,var(--pfx-hot) 50%,transparent 54%);opacity:.34;animation:pfxSheen 2.6s linear infinite}
/* stalk — 후열 추격. 그림자 덩어리가 옆으로 미끄러진다("숨어 돈다"). */
.battle-skills .skill-passive[data-fx="stalk"] .passive-fx{background:radial-gradient(ellipse 52% 130% at 22% 50%,#000,transparent 72%),radial-gradient(ellipse 46% 130% at 74% 50%,var(--pfx-core),transparent 74%);opacity:.45;animation:pfxDrift 4.2s ease-in-out infinite;animation-delay:var(--pfx-fx-delay)}

/* 상시 기술을 가진 펫은 칸 자체가 다르게 보인다 — 배지 하나가 아니라 칸이 "특별하다"고 말한다. */
.battle-pet-hud.has-passive{position:relative;border-color:var(--pfx-edge)}
.battle-pet-hud.has-passive::after{content:'';position:absolute;inset:-2px;border:1px solid var(--pfx-core);pointer-events:none;opacity:.12;animation:pfxPetBreath 3.4s ease-in-out infinite;animation-delay:var(--pfx-fx-delay)}

/* 쓰러지면 오라도 멈춘다(sim §8.5) — 화면도 같이 멈춘다.
   ⚠️ `!important` 는 게으름이 아니다. 계열 규칙이 `[data-fx=…]` 로 특이도가 한 단 높아서,
   특이도로 이기려면 계열이 늘 때마다 이 선택자를 다시 세야 한다. 한 번 못 세면 조용히 죽는다. */
.battle-pet-hud.pet-down .skill-passive .passive-fx,.battle-pet-hud.pet-down .skill-passive .passive-fx::before,.battle-pet-hud.pet-down .skill-passive .passive-fx::after,.battle-pet-hud.has-passive.pet-down::after{animation:none!important}
.battle-pet-hud.has-passive.pet-down::after{opacity:.06}

@keyframes pfxBurnRise{0%,100%{transform:translateY(8%) scaleY(1);opacity:.4}50%{transform:translateY(-7%) scaleY(1.22);opacity:.74}}
@keyframes pfxSheen{from{transform:translateX(-18%)}to{transform:translateX(18%)}}
@keyframes pfxSaw{from{transform:translateX(0)}to{transform:translateX(14px)}}
@keyframes pfxSawFlip{from{transform:scaleY(-1) translateX(0)}to{transform:scaleY(-1) translateX(-14px)}}
@keyframes pfxLock{0%,100%{opacity:.45}50%{opacity:1}}
@keyframes pfxDrift{0%,100%{transform:translateX(-8%)}50%{transform:translateX(8%)}}
@keyframes pfxPetBreath{0%,100%{opacity:.1}50%{opacity:.4}}
@media(max-width:360px){.battle-skills .skill-passive{gap:2px;padding:4px 2px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.battle-skills .skill-passive>.passive-mark{padding:1px 2px}}
@keyframes battleSkillHudPulse{0%{transform:scale(.97)}55%{transform:scale(1.035)}100%{transform:scale(1)}}@keyframes battleSkillCallout{0%{opacity:0;transform:translate(-50%,7px) scale(.72) rotateX(55deg)}18%{opacity:1;transform:translate(-50%,0) scale(1.08) rotateX(0)}72%{opacity:1}100%{opacity:0;transform:translate(-50%,-13px) scale(.96)}}@keyframes battleSkillButton{0%{transform:scale(.95)}55%{transform:scale(1.035)}100%{transform:scale(1)}}

.slot-tile.level-up,.dungeon-pet-card.level-up{position:relative;isolation:isolate;overflow:visible!important;animation:levelUpCardGlow 1s ease-in-out 4}.slot-tile.level-up::before,.dungeon-pet-card.level-up::after{content:"✦  ✧  ✦";position:absolute;z-index:5;inset:8% -4%;display:grid;place-items:center;color:#fff8a8;font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif;letter-spacing:14px;pointer-events:none;text-shadow:0 0 8px #fff,0 0 14px #ffce47;animation:levelUpSparkBurst 1.25s ease-out 3}.level-up-event{position:absolute;z-index:7;left:50%;top:50%;display:grid;place-items:center;min-width:max-content;pointer-events:none;transform-style:preserve-3d;perspective:180px;animation:levelUpEvent3d 4.8s cubic-bezier(.18,.8,.22,1) both}.level-up-event b{display:block;color:#fff28a;font:900 12px "Galmuri11","Galmuri9",sans-serif;letter-spacing:1px;text-shadow:0 1px 0 #f4a928,0 2px 0 #d87b13,0 3px 0 #93410c,0 0 7px #fff,0 0 18px #ffcb45}.slot-tile .level-up-event b{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.level-up-event small{display:block;margin-top:5px;padding:3px 5px;color:#fff;background:#5a2d78e8;border:1px solid #f6d474;font:700 10px "Galmuri9","Galmuri11",sans-serif;box-shadow:0 2px 0 #2b1f16}.result-card .level-up-summary{color:#fff0a3;background:#4c315e;padding:7px;border:1px solid #a67bc0}.result-card .result-return{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
@keyframes levelUpEvent3d{0%{opacity:0;transform:translate(-50%,-20%) rotateX(72deg) scale(.45)}10%{opacity:1;transform:translate(-50%,-62%) rotateX(-10deg) scale(1.18)}18%{transform:translate(-50%,-56%) rotateX(0) scale(1)}78%{opacity:1;transform:translate(-50%,-56%) rotateX(0) scale(1)}100%{opacity:0;transform:translate(-50%,-105%) rotateX(-20deg) scale(.82)}}@keyframes levelUpSparkBurst{0%{opacity:0;transform:scale(.25) rotate(-12deg)}22%{opacity:1}100%{opacity:0;transform:scale(1.45) rotate(9deg)}}@keyframes levelUpCardGlow{0%,100%{box-shadow:0 0 0 rgba(255,221,89,0)}50%{box-shadow:0 0 22px rgba(255,221,89,.8),inset 0 0 12px rgba(255,246,163,.32)}}

/* 원정 제한시간 시계. 남은 2분부터만 나타나므로(dungeon.js RUN_DEADLINE_HUD_FROM_SECONDS)
   대부분의 원정에서는 이 칸이 아예 없다 — 늘 떠 있는 카운트다운은 방치 게임의 결이 아니다. */
.battle-progress-box .battle-time-left{white-space:nowrap;color:#ffe9b0;background:#3f3018dd}
.battle-progress-box .battle-time-left.urgent{color:#fff;background:#7a2222ee;animation:battleTimeLeftPulse 1s steps(2,end) infinite}
@keyframes battleTimeLeftPulse{0%,100%{opacity:1}50%{opacity:.5}}
@media(prefers-reduced-motion:reduce){.battle-progress-box .battle-time-left.urgent{animation:none}}
.result-card .late-summary{color:#ffd9b0;background:#4a3324;padding:6px;border:1px solid #a87a52;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.result-card .trinket-summary{color:#cfe8ff;background:#24384a;padding:6px;border:1px solid #4f7fa8}

/* 장신구 가방 — 계열 필터 + 카드 목록. 파워스톤(.dungeon-stones)과 별도 스타일을 쓰는 이유는
   장착 단위가 다르기 때문이다(전역 슬롯 vs 펫별 부위). 섞으면 어느 쪽 규칙인지 헷갈린다. */
/* 공개 전 관리자 미리보기 배너 — 켜진 것과 헷갈리면 "왜 아무도 안 쓰지"가 된다. */
.admin-preview-note{margin-top:8px;padding:8px 10px;border:2px dashed #c9a227;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.6}
/* 길드 — 내 길드 / 목록. 1차 골격이라 보여줄 값이 적다(이름·인원·기여도). */
/* 내 부족 카드 — 부족원 목록뿐이다. 길드 목록·신청 줄(`.guild-row`/`.guild-list`)과
   가입 대기(`.guild-pending`)는 자유 결성 폐지와 함께 걷어냈다(2026-08-19). */
.guild-card{border:2px solid #8a6c57;padding:9px 10px;margin-top:8px}
.guild-card h3{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;margin:0}
.guild-card .g-meta{margin-top:3px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.5}
.guild-members{display:flex;flex-direction:column;gap:4px;margin-top:8px}
.guild-member{display:grid;grid-template-columns:1fr auto auto;align-items:center;gap:8px;padding:6px 8px;border:1px solid #cbbca6;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.guild-member .g-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.guild-member .g-contrib{font-variant-numeric:tabular-nums;color:#3f6b8f}
/* 부족장 — 소유권이 아니라 **파생 표시**다(위임·추방 같은 권한은 없다). */
.guild-member.is-chief{border-color:#d9a441;background:#fffaf0}
.guild-member .g-contrib.is-dim{opacity:.55}
.guild-actions{display:flex;flex-wrap:wrap;gap:5px;margin-top:9px}
.guild-actions button{padding:5px 9px;border:1px solid #55c797;background:#eafff5;color:#25705a;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer}
.guild-actions button.danger{border-color:#d98a8a;background:#fff0f0;color:#8f3f3f}
.guild-actions button:disabled{opacity:.45;cursor:default}
/* 영역 지도 모달 — 상시 화면이 아니라 고를 때만 연다. 지도는 **영역 구분만** 되면 되므로
   높이를 45vh 로 묶고 카드가 아래에서 스크롤되게 둔다(9:16 지도가 화면을 다 먹지 않도록). */
/* 지도는 탭 안에 그대로 깔린다(모달이 아니다). 세로 9:16 이라 높이를 묶어야 카드가 안 밀린다. */
/* 제목 줄이 없으므로 패널 안쪽 여백만 남긴다. */
.dungeon-panel.is-map{padding-top:10px}
.tribe-map{position:relative;border:2px solid #8a6c57;background:#251d17;text-align:center;line-height:0}
.tribe-map img{display:block;width:100%;max-height:46vh;object-fit:contain;margin:0 auto;image-rendering:auto}
/* 지도 위 클릭 영역. 좌표는 이미지 박스 기준 퍼센트라 화면 폭이 바뀌어도 따라간다. */
#tribeMapSpots{position:absolute;inset:0;pointer-events:none}
/* 클릭 영역은 **보이지 않는다** — 선택 표시는 지도 이미지가 바뀌는 것으로 충분하다.
   ⚠ `-webkit-tap-highlight-color` 를 끄지 않으면 모바일에서 파란 사각형이 번쩍인다. */
.tribe-spot{position:absolute;padding:0;border:0;background:transparent;cursor:pointer;
  pointer-events:auto;-webkit-tap-highlight-color:transparent;outline:none;appearance:none}
/* 키보드 이동은 보여야 한다(마우스·터치로는 안 뜬다). */
.tribe-spot:focus-visible{outline:2px solid #e6c76a;outline-offset:-2px}

/* 지도 위 인구 배지 — 설명 안의 작은 글씨는 안 읽힌다. 어디에 사람이 많은지는
   지도만 봐도 보여야 한다. ⚠ 클릭을 막으면 안 되므로 pointer-events 를 끈다. */
.tribe-pop{position:absolute;transform:translate(-50%,-50%);pointer-events:none;
  padding:4px 8px;border:2px solid var(--tribe,#8a6c57);border-radius:10px;text-align:center;
  background:rgba(16,12,8,.88);color:#fff;font:700 12px/1.1 "Galmuri11","Galmuri9",sans-serif;
  white-space:nowrap;box-shadow:0 2px 0 rgba(0,0,0,.45)}
/* 전투력은 인구 **바로 아래**에 묶는다 — 따로 떼면 어느 영역 값인지 눈으로 잇기 어렵다. */
.tribe-pop small{display:block;margin-top:3px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-weight:400;color:#e6d4b9}
.tribe-pop.is-mine{box-shadow:0 0 0 2px rgba(255,255,255,.55),0 2px 0 rgba(0,0,0,.45)}

/* 지도 위 오버레이 — 아래로 스크롤하지 않고 고른 영역을 읽고 바로 정할 수 있어야 한다. */
/* 지도 **아래** 제 자리(2026-09-09). 예전에는 `position:absolute;bottom:0` 으로 지도에
   얹혀 아래 27%(390px 화면에서 107px)를 덮었고, 그 자리의 인구 배지 하나와
   지도 안내문(`.tribe-map-note`)이 통째로 가려졌다.
   ⚠ 자리는 늘 비워 둔다(`min-height`) — 영역을 누를 때마다 판이 늘었다 줄면 눈이 흔들린다.
      112px 은 흔한 경우(설명 + 사유 한 줄) 실측 107px 를 담는 값이고, 단추까지 붙는
      가장 긴 경우(120px)에만 그만큼 늘어난다. */
.tribe-overlay{margin-top:8px;min-height:112px;
  padding:10px 10px calc(9px + env(safe-area-inset-bottom,0px));text-align:left;line-height:1.5;
  background:#251d17;border:2px solid var(--tribe,#8a6c57);color:#faf6ef}
.tribe-overlay[hidden]{display:none}
/* 아직 아무 영역도 안 눌렀을 때 — 빈 칸만 두면 고장 난 것처럼 보인다. */
.tribe-ov-hint{grid-column:1/-1;margin:0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#b6a387;line-height:1.7}
/* 좌측은 설명, **우측 상단은 선택 버튼**. 버튼을 아래에 두면 버튼이 없는 영역
   (공허의 숲·거인성)과 높이가 달라져 지도가 들썩인다. */
/* ⚠ 왼쪽은 `minmax(0,1fr)` 이다. 그냥 `1fr` 이면 오른쪽 `auto` 칸의 내용이 길 때
   왼쪽이 **글자 하나 폭까지** 밀린다(2026-09-06 제보: 부족 이름이 세로로 쌓였다). */
.tribe-overlay{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:start;
  column-gap:10px}
.tribe-ov-main{min-width:0}
.tribe-ov-head{display:flex;align-items:baseline;gap:6px;flex-wrap:wrap}
/* 이름은 줄이지 않는다 — 줄이면 세로로 쌓인다. 좁으면 지역명이 다음 줄로 내려간다. */
.tribe-ov-head b{flex:0 0 auto;white-space:nowrap;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:#fff}
.tribe-ov-head small{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#e3cfb1}
.tribe-ov-stats{display:flex;flex-wrap:wrap;gap:10px;margin-top:4px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#eee0cc;font-variant-numeric:tabular-nums}
.tribe-ov-stats em{font-style:normal;color:#bfae95;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.tribe-ov-blurb{margin:4px 0 0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#ddc9aa}
.tribe-ov-act{grid-column:2;grid-row:1;justify-self:end;display:flex;gap:6px}
.tribe-ov-act button{padding:6px 12px;border:1px solid #55c797;background:#1d4a3c;color:#c9ffe9;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;-webkit-tap-highlight-color:transparent}
.tribe-ov-act:empty{display:none}
/* 못 고르는 이유 — **전체 폭 한 줄**이다. 단추 자리(오른쪽 `auto` 칸)에 두면 문장 길이가
   곧 그 칸의 폭이 되어 왼쪽 설명을 짓누른다(2026-09-06). */
.tribe-ov-why{grid-column:1/-1;margin:7px 0 0;padding:5px 8px;
  border:1px dashed rgba(255,255,255,.28);
  font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#e3cfb1;line-height:1.6}

/* 하단 목록은 없앴다 — 인구·전투력이 지도 배지로 올라가면서 이름만 남는 줄이 됐다.
   세 부족 비교는 배지 셋을 한눈에 보는 것으로 충분하고, 상세는 오버레이가 맡는다. */
.tribe-note{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;}

/* ── 거점 점령전 ──────────────────────────────────────────────────────────────
   ⚠ 클래스 접두사는 `op-` 다(규칙 13) — 전역 클래스명이 얕아 `.spot`·`.ring` 은 충돌한다. */
.op-bar{display:flex;align-items:center;gap:8px;margin-bottom:6px}
.op-bar strong{flex:1;min-width:0;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.op-back{padding:5px 9px;border:2px solid #8a6c57;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;-webkit-tap-highlight-color:transparent}
.op-tribe{padding:3px 8px;border:2px solid var(--tribe,#b6a387);border-radius:999px;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;white-space:nowrap}
.op-tickets{padding:3px 8px;border:2px solid #d9a441;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;white-space:nowrap}
.op-field{border:3px solid #8a6c57;background:#100c08;line-height:0}
/* 마커 좌표(%)의 기준 상자 — **이미지와 정확히 같아야 한다.** `.op-field` 를 기준으로 두고
   거기에 여백을 주면 여백까지 100%에 들어가 마커가 아래로 밀린다. */
.op-canvas{position:relative;line-height:0}
.op-field img{display:block;width:100%;height:auto}
/* 점령 링 — 등각 타원. `padding-bottom` %는 부모 **폭** 기준이라 이미지 비율이 달라져도 안 찌그러진다. */
.op-ring{position:absolute;transform:translate(-50%,-50%);height:0;pointer-events:none;
  border:2px solid var(--op,#b6a387);border-radius:50%;
  box-shadow:0 0 10px var(--op,#b6a387),inset 0 0 10px rgba(255,255,255,.25)}
.op-ring.is-free{border-style:dashed;opacity:.65;box-shadow:none}
/* 공성 중 — 굵은 흰 테두리. ⚠ 상시 애니메이션을 쓰지 않는다(규칙 32 의 절전 배선을 끌어와야 한다). */
.op-ring.is-siege{border-width:4px;border-color:#fff;box-shadow:0 0 14px #fff,0 0 22px var(--op,#b6a387)}
/* 클릭 영역은 링과 **같은 자리**다. 테두리를 그리면 지도에 격자가 얹힌 것처럼 지저분해진다. */
.op-spot{position:absolute;transform:translate(-50%,-50%);height:0;padding:0;border:0;
  border-radius:50%;background:transparent;cursor:pointer;-webkit-tap-highlight-color:transparent}
.op-spot:focus-visible{outline:2px solid var(--dq-gold);outline-offset:2px}
.op-spot.is-active+.op-tag,.op-tag.is-mine{border-color:#fff}
.op-tag{position:absolute;transform:translate(-50%,4px);pointer-events:none;
  padding:3px 7px;border:2px solid var(--op,#b6a387);border-radius:8px;
  background:rgba(16,12,8,.88);color:#fff;font:400 10px/1.2 "Galmuri9","Galmuri11",sans-serif;
  white-space:nowrap;box-shadow:0 2px 0 rgba(0,0,0,.45)}
.op-tag b{color:var(--op,#b6a387);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;letter-spacing:1px}
/* 상세 카드 — **항상 화면 하단**에 고정한다(스크롤 위치와 무관).
   ⚠ `sticky` 로 했더니 컨테이닝 블록(`.op-field`) 밖으로 못 나가서 **화면 중앙에 걸렸다**
     (2026-08-22 제보). 하단 고정이 요구사항이므로 `fixed` 가 맞다.
   ⚠ 가로 위치는 하단 내비와 **같은 변수**를 쓴다 — 런타임이 측정해 넣는 값이라 어떤 해상도에서도
     탭 바와 정확히 겹쳐 선다. 따로 계산하면 두 값이 갈린다.
   ⚠ 하단 크롬 위로 띄운다: 모드 내비 + 던전 서브탭 + 안전영역. 안 빼면 탭 바 뒤로 들어간다.
   ⚠ `#outpostPanel` 이 `hidden` 이면 자손이라 함께 사라진다 — 다른 탭으로 가도 안 남는다. */
.op-overlay{position:fixed;z-index:60;
  left:var(--mode-nav-left,50%);
  width:var(--mode-nav-width,calc(min(100vw,460px) - 24px));
  transform:translateX(var(--mode-nav-shift,-50%));
  bottom:calc(var(--mode-nav-height) + var(--subnav-height) + env(safe-area-inset-bottom) + 6px);
  box-sizing:border-box;margin:0;padding:8px 9px;border:2px solid var(--op,#b6a387);
  background:rgba(16,12,8,.96);color:#fff5da;line-height:1.5;text-align:left;
  box-shadow:0 4px 14px rgba(0,0,0,.55)}
/* 카드가 떠 있는 동안 **지도를 그 위로 밀어 올릴 수 있게** 아래 여백을 준다.
   이게 없으면 지도 맨 아래 거점이 카드 뒤에서 영영 안 나온다(높이는 JS 가 실측해 넣는다). */
#outpostPanel.has-card{padding-bottom:calc(var(--op-card-h,150px) + 14px)}
.op-ov-head{display:flex;align-items:baseline;gap:6px;flex-wrap:wrap}
.op-ov-head b{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.op-ov-head small{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#cabeab}
/* 닫기 — 터치 타깃 30px. 없으면 아래쪽 거점이 카드에 영영 가린다(규칙 31). */
.op-ov-close{margin-left:auto;width:30px;height:30px;flex:0 0 auto;
  border:2px solid #8a6c57;background:#5c3540;color:#fff;cursor:pointer;
  font:700 15px/1 "Galmuri14","Galmuri11",sans-serif;-webkit-tap-highlight-color:transparent}
.op-guards{max-height:84px;overflow-y:auto;margin:6px 0 0}
.op-guard{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:6px;
  padding:3px 5px;border-left:3px solid var(--op,#b6a387);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.op-guard.is-me{background:rgba(255,255,255,.10)}
/* 중립 몬스터 수비대 — 사람 수비대와 한눈에 갈려야 한다. */
.op-guard.is-npc{border-left-color:#b6a387}
.op-guard.is-npc .op-who{color:#e6d4b9}
.op-slot{color:var(--op,#b6a387);font-weight:700;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.op-who{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.op-pow{color:#e6d4b9;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-variant-numeric:tabular-nums}
.op-empty{padding:8px 0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#cabeab;text-align:center}
.op-note{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#cabeab}
/* 집결 로비 — 수비 목록과 액션 사이에 낀다. */
.op-siege{margin-top:7px;padding:6px 7px;border:2px dashed #fff;background:rgba(255,255,255,.07)}
.op-siege-head{display:flex;align-items:baseline;justify-content:space-between;gap:6px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.op-clock{font:700 12px "Galmuri11","Galmuri9",sans-serif;color:#ffd9d5;font-variant-numeric:tabular-nums}
.op-fighters{display:flex;flex-wrap:wrap;gap:3px;margin:5px 0}
.op-fighter{padding:2px 5px;border:1px solid #8a6c57;background:rgba(16,12,8,.6);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.op-fighter.is-me{border-color:#55c797;color:#eafff5}
.op-siege-foot{display:flex;align-items:center;justify-content:space-between;gap:6px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#cabeab}
.op-siege-foot button{min-height:28px;padding:4px 10px;border:2px solid #55c797;background:#123;
  color:#eafff5;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.op-siege-foot button.danger{border-color:#d98a8a;background:#4a2a2f;color:#ffd9d5}
.op-attack{border-color:#d9a441!important;background:#3a2c12!important;color:#ffe9b8!important}
/* 이 거점에 걸린 전쟁 — 수비가 걸린 순간이 특히 중요하다(색만으로 말하지 않고 글자도 바뀐다). */
.op-war-note{margin:6px 0 0;padding:5px 7px;border:1px solid #d9a441;background:#2c2416;
  color:#ffe9b8;font:700 10px "Galmuri9","Galmuri11",sans-serif;line-height:1.6}
.op-war-note.is-defend{border-color:#d98a8a;background:#2e1c1c;color:#ffd9d5}
.op-front-go.is-defend{border-color:#d98a8a;color:#ffd9d5}
/* 선포 가능 시각 한 줄(2026-09-19) — 🔒 풀리는 때 · ⭐ 우리 부족만 선포 가능 · 🛡 보호 중.
   ⚠ 전쟁 색(금색 · 붉은색 · 주황)을 쓰지 않는다 — 전쟁이 아니라 기다림이다. 뜻은 글자와 그림 글자가 말한다. */
.op-when{margin:6px 0 0;padding:4px 7px;border:1px solid #8a6c57;background:#281d16;
  color:#f3e8d8;font:400 10px "Galmuri9","Galmuri11",sans-serif;line-height:1.6}
.op-when b{color:#fff}
.op-when small{margin-left:4px;color:#cabeab}
.op-tag .op-lock{font-style:normal;margin-left:3px;color:#f3e8d8}

/* ── 부족 금고 ─────────────────────────────────────────────────────────────
   '있어보이게' 를 장식이 아니라 **위계**로 만든다: 적립 속도 하나만 크게(20px), 나머지는
   9px 이하로 눌러 시선이 한 곳에 꽂히게. 금색은 이 카드에서 **숫자에만** 쓴다.
   ⚠ 상시 애니메이션을 두지 않는다(규칙 32) — 절전 배선을 카드 하나에 끌어오지 않는다. */
.tribe-vault{position:relative;margin-bottom:8px;padding:9px 10px 8px;
  border:2px solid #8a6c57;background:linear-gradient(180deg,#38291e 0%,#241a13 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10),0 2px 0 rgba(0,0,0,.35)}
/* 상단 금색 러너 — 3px 한 줄이 '값진 것' 신호를 가장 싸게 준다.
   ⚠ 테두리 밖으로 빼지 않는다(`-2px`). 2px 만 삐져나와도 모바일에서 **가로 스크롤**이 생긴다
     (2026-08-22 실측: scrollWidth 355 vs clientWidth 353). */
.tribe-vault::before{content:"";position:absolute;left:0;right:0;top:0;height:3px;
  background:linear-gradient(90deg,#7a5c1f,#f3c65b 45%,#fff0b8 50%,#f3c65b 55%,#7a5c1f);
  pointer-events:none}
.tribe-vault.is-idle{filter:saturate(.45)}
.tribe-vault.is-idle::before{background:#5d4a3c}
.tv-top{display:flex;align-items:baseline;gap:6px}
.tv-eyebrow{font:700 10px/1 "Galmuri9","Galmuri11",sans-serif;letter-spacing:1.5px;color:#a49277}
.tv-title{font:700 12px "Galmuri11","Galmuri9",sans-serif;color:#fff5da}
.tv-hold{margin-left:auto;padding:2px 5px;border:1px solid #8a6c57;background:#211811;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#e6d4b9;font-variant-numeric:tabular-nums}
/* 적립 속도 — 이 카드에서 **가장 큰 것 하나**. */
.tv-rate{display:flex;align-items:baseline;gap:5px;margin-top:7px}
.tv-rate b{font:700 20px/1 "Galmuri11","Galmuri9",sans-serif;color:var(--dq-gold,#f3c65b);
  font-variant-numeric:tabular-nums;text-shadow:0 2px 0 rgba(0,0,0,.55)}
.tv-unit{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#b6a894}
.tv-day{margin-left:auto;font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#a49277;text-align:right}
/* 오늘 쌓임 — 매초 오르는 자리. 숫자만 바뀌므로 **레이아웃이 흔들리면 안 된다**:
   `tabular-nums` 로 글자 폭을 고정한다(안 하면 1↔8 에서 줄이 들썩인다). */
.tv-today{display:flex;align-items:baseline;gap:5px;margin-top:6px;padding:5px 7px;
  border:1px solid #5d4a3c;background:#211811}
.tv-today-k{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#a49277}
.tv-today b{font:700 12px "Galmuri11","Galmuri9",sans-serif;color:#e6dcc4;
  font-variant-numeric:tabular-nums}
.tv-today-cap{margin-left:auto;font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#a49277}
.tv-today-cap.is-cap{color:var(--dq-gold,#f3c65b)}
/* 거점별 보유 단계 — 오래 쥔 순으로 위에 온다(서버가 정렬해 준다). */
.tv-holds{margin:7px 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:3px}
.tv-hold-row{display:grid;grid-template-columns:minmax(0,1fr) auto 54px 26px 58px;align-items:center;
  gap:5px;padding:3px 6px;border-left:2px solid #8a6c57;background:#211811;
  font:700 10px "Galmuri9","Galmuri11",sans-serif}
.tv-hold-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#e6d4b9}
.tv-pips{letter-spacing:1px;color:var(--dq-gold,#f3c65b)}
/* 이 거점이 실제로 내는 시간당 — 거점마다 다르다(GHUB 에서 개별 지정). */
.tv-rate-each{color:var(--dq-gold,#f3c65b);text-align:right;font-variant-numeric:tabular-nums;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tv-rate-each.is-off{color:#846b5a}
.tv-mult{color:#e6dcc4;text-align:right;font-variant-numeric:tabular-nums}
.tv-next{color:#a49277;text-align:right;white-space:nowrap}

/* 점령 진행 — 게이지 하나로 '얼마나 쥐고 있나'를 말한다. */
.tv-bar{height:7px;margin-top:7px;border:1px solid #120d0a;background:#1a120d;overflow:hidden}
.tv-bar i{display:block;height:100%;width:0;
  background:linear-gradient(90deg,#7a5c1f,#f3c65b);box-shadow:inset 0 1px 0 rgba(255,255,255,.25)}
/* 정산 문턱 — 도달하면 켜진다. */
.tv-tiers{margin:8px 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:4px}
.tv-tier{display:grid;grid-template-columns:14px 34px minmax(0,1fr);align-items:center;gap:5px;
  padding:4px 6px;border:1px solid #5d4a3c;background:#211811;opacity:.72}
/* ⚠ `opacity` 는 글자 대비를 **같이** 깎는다 — 색만 재면 과대평가된다. .55 에서 미달 티어의
   '개수' 실효 대비가 4.03:1 로 기준(4.5) 아래였다(2026-08-22 실측). .72 로 올려 5.3:1. */
.tv-tier.is-on{opacity:1;border-color:#8a6b2a;background:#241b17}
.tv-step{font:700 10px/1 "Galmuri9","Galmuri11",sans-serif;color:#8b6d57;text-align:center}
.tv-tier.is-on .tv-step{color:var(--dq-gold,#f3c65b)}
.tv-need{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#e6d4b9;font-variant-numeric:tabular-nums}
.tv-gain{display:flex;flex-wrap:wrap;gap:4px 8px;min-width:0}
.tv-item{display:inline-flex;align-items:center;gap:3px;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#e6dcc4;white-space:nowrap}
.tv-item img{width:12px;height:12px;image-rendering:pixelated}
.tv-note{margin:7px 0 0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#a49277;line-height:1.55}
.tv-claim{display:flex;align-items:center;gap:6px;margin-top:7px;padding-top:7px;
  border-top:1px solid #553f30}
/* ⚠ `hidden` 속성이 위 `display:flex` 에 지면 **안 숨는다**(HiddenAttributeGuardTests). */
.tv-claim[hidden]{display:none}
/* 2026-09-17 — 룬 · 시간당 아이템 · 되찾으면 · 현상금 */
.tv-claim-extra{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#e6d4b9}
.tv-items{margin:7px 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:3px}
.tv-items[hidden]{display:none}
.tv-item-row{display:grid;grid-template-columns:minmax(0,1fr) auto 52px;align-items:center;gap:6px;
  font:700 10px "Galmuri9","Galmuri11",sans-serif}
.tv-item-row .tv-item{min-width:0;overflow:hidden;white-space:nowrap}
.tv-item-rate{color:#a49277;white-space:nowrap}
.tv-item-today{color:var(--dq-gold,#f3c65b);text-align:right;font-variant-numeric:tabular-nums}
.tv-rune{color:#7fe0c4}
.tv-tier-done{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#7fe0c4}
.tv-extra{display:grid;grid-template-columns:62px minmax(0,1fr);align-items:center;gap:6px;margin-top:6px}
.tv-extra[hidden],.tv-bounty[hidden]{display:none}
.tv-extra-k{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#a49277}
.tv-note[hidden]{display:none}
.tv-claim-k{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#a49277}
.tv-claim b{font:700 12px "Galmuri11","Galmuri9",sans-serif;color:var(--dq-gold,#f3c65b);
  font-variant-numeric:tabular-nums}
.tv-claim-btn{margin-left:auto;min-height:32px;padding:6px 10px;cursor:pointer;
  border:2px solid var(--dq-gold,#d9a441);background:#3a2d1d;color:#fff5da;
  font:700 10px "Galmuri9","Galmuri11",sans-serif}
.tv-claim-btn:disabled{border-color:#5d4a3c;background:#2d2119;color:#846b5a;cursor:default}

/* 내 부족의 전쟁 — 금고와 같은 결의 어두운 카드다(두 테마에서 같게 읽힌다).
   ⚠ 색만으로 상태를 말하지 않는다 — 배지 글자가 늘 함께 바뀐다(§5.0). */
.tribe-war{margin-bottom:8px;padding:9px 10px 8px;
  border:2px solid #8a6c57;background:linear-gradient(180deg,#38291e 0%,#241a13 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10),0 2px 0 rgba(0,0,0,.35)}
.tribe-war.is-live{border-color:#ff8a3d}
.tribe-war.is-incoming{border-color:#d98a8a}
/* ⚠ 제목을 **줄이지 않는다**. flex 가 줄이면 360px 에서 "내 부족의 전쟁" 이 한 글자씩
   세로로 쌓인다(2026-09-06 하네스 실측). 좁으면 배지가 다음 줄로 내려간다. */
.tw-head{display:flex;align-items:baseline;gap:6px;flex-wrap:wrap}
.tw-eyebrow{flex:0 0 auto;font:700 10px/1 "Galmuri9","Galmuri11",sans-serif;letter-spacing:1.5px;color:#a49277}
.tw-title{flex:0 0 auto;white-space:nowrap;font:700 12px "Galmuri11","Galmuri9",sans-serif;color:#fff5da}
.tw-badge{margin-left:auto;padding:2px 6px;border:2px solid #8a6c57;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#b6a894;white-space:nowrap}
.tw-badge.is-proposed,.tw-badge.is-confirmed{border-color:#d9a441;color:#fff5da}
.tw-badge.is-live{border-color:#ff8a3d;color:#ffb37a}
.tw-badge.is-defend{border-color:#d98a8a;color:#ffd9d5}
.tw-line{margin:7px 0 0;font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#f3e6cf;
  line-height:1.6}
.tw-sub,.tw-people{margin:3px 0 0;font:700 10px "Galmuri9","Galmuri11",sans-serif;
  color:#b6a894;line-height:1.7}
.tw-people{color:#8de0bb}
.tw-bar{height:8px;margin-top:7px;border:2px solid #120d0a;background:#1a120d;overflow:hidden}
.tw-bar>i{display:block;height:100%;width:0;background:var(--dq-gold,#f3c65b)}
.tw-act{margin-top:8px}
.tw-act:empty{display:none}
.tw-main{width:100%;min-height:48px;padding:12px;cursor:pointer;
  border:2px solid #8a6c57;background:#35281f;color:#f3e6cf;
  font:700 12px "Galmuri11","Galmuri9",sans-serif}
.tw-main.is-primary{border-color:var(--dq-gold,#d9a441);background:#3a2d1d;color:#fff5da}
.tw-main:focus-visible{outline:2px solid var(--dq-gold,#d9a441);outline-offset:2px}
.tw-main + .tw-main{margin-top:6px}

/* 요약 스트립 — 모바일 375px 기준. 4칸 2줄이 한 화면에서 가장 읽기 쉽다(6칸은 글자가 깨진다). */
.tribe-strip{margin-bottom:8px;padding:8px}
.ts-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px}
.ts-cell{min-width:0;padding:5px 7px;border:2px solid #cbbca6;
  display:flex;flex-direction:column;gap:2px}
.ts-k{font:700 10px "Galmuri9","Galmuri11",sans-serif;}
.ts-cell b{font:700 12px "Galmuri11","Galmuri9",sans-serif;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 거점 칩 — 6개가 2줄로 접힌다. ⚠ `flex-wrap` 없으면 375px 에서 밀려 나간다. */
.ts-chips{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px}
/* ⚠ `min-height` 로 터치 타깃을 확보한다 — 글꼴이 8px 이라 padding 만으로는 22px 밖에 안 되어
   모바일에서 누르기 어렵다(2026-08-21 실측). 폰트를 키우면 이름이 잘리므로 높이로 푼다. */
.ts-chip{flex:1 1 calc(33.333% - 3px);min-width:0;min-height:34px;
  display:flex;align-items:center;gap:4px;
  padding:4px 6px;border:2px solid #cbbca6;cursor:pointer;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;
  -webkit-tap-highlight-color:transparent}
.ts-chip i{flex:0 0 auto;width:7px;height:7px;background:var(--chip,#b6a387);
  border:1px solid rgba(0,0,0,.35)}
.ts-chip span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ts-chip.is-free i{background:transparent;border-style:dashed}

/* '오늘 할 일' 안내 — 남은 단계가 있을 때만 뜬다. ⚠ 상시 애니메이션 없음(규칙 32). */
.tribe-guide{margin-bottom:8px}
.tg-head{display:flex;align-items:baseline;justify-content:space-between;gap:6px;
  font:700 12px "Galmuri11","Galmuri9",sans-serif;color:#4d3b2e}
.tg-head span{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-variant-numeric:tabular-nums}
.tg-steps{margin:7px 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:5px}
.tg-step{display:grid;grid-template-columns:16px minmax(0,1fr);gap:6px;align-items:start;
  padding:5px 6px;border:2px solid #cbbca6;}
.tg-step.is-done{opacity:.7}
.tg-mark{font:700 12px "Galmuri11","Galmuri9",sans-serif;color:#8b6d57;text-align:center}
.tg-body{min-width:0;display:flex;flex-direction:column;gap:2px}
.tg-body b{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;}
.tg-body span{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.5}
.tg-goal{margin:7px 0 0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.6}
/* 지도가 둘이라 관계를 적어 준다 — 지도 **아래**여야 누른 뒤 읽는 순서와 맞는다. */
.tribe-map-note{margin:6px 0 0;font:700 10px "Galmuri9","Galmuri11",sans-serif;line-height:1.6;text-align:center}
.op-er-why{display:block;margin-top:3px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.4}

/* 공허 침식 — 점령이 무엇을 주는지 한 줄로 보여준다. ⚠ 상시 애니메이션을 두지 않는다(규칙 32). */
.op-erosion{margin:0 0 7px;padding:6px 8px;border:2px solid #8a6c57;}
.op-er-head{display:flex;align-items:baseline;justify-content:space-between;gap:6px;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;}
.op-er-head b{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;}
.op-er-bar{height:10px;margin-top:4px;border:2px solid #8a6c57;overflow:hidden}
.op-er-bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,#7fd9a8,#2f7d5a)}
.op-er-note{display:block;margin-top:4px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.4}

.op-ov-act{display:flex;justify-content:flex-end;align-items:center;gap:6px;margin-top:7px}
.op-ov-act button{min-height:30px;padding:5px 11px;border:2px solid #55c797;background:#123;
  color:#eafff5;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.op-ov-act button.danger{border-color:#d98a8a;background:#4a2a2f;color:#ffd9d5}
.op-enter{min-height:30px;padding:5px 11px;border:2px solid var(--dq-gold);background:#35281f;
  color:#fff5da;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
/* 수비 편성 모달 */
.op-pick{position:relative;width:min(92vw,380px);max-height:80vh;display:flex;flex-direction:column;
  padding:14px 12px 12px;background:#211913;border:3px solid var(--dq-gold);color:#fff5da}
.op-pick-head{display:flex;flex-direction:column;gap:3px;padding:0 22px 8px 0}
.op-pick-head strong{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.op-pick-head span{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#cabeab}
.op-pick-list{flex:1;min-height:0;overflow-y:auto;display:grid;grid-template-columns:1fr 1fr;gap:5px}
.op-pet{display:flex;align-items:center;gap:5px;padding:4px 5px;border:2px solid #8a6c57;
  background:#35281f;color:#f4eadb;font:400 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;
  text-align:left;-webkit-tap-highlight-color:transparent}
.op-pet.is-on{border-color:#55c797;background:#1d3b30}
.op-pet img{width:28px;height:28px;object-fit:contain;flex:0 0 auto}
.op-pet-blank{width:28px;text-align:center}
.op-pet-face{width:28px;height:28px;flex:0 0 auto;display:flex;align-items:center;justify-content:center}
.op-pet-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.op-pet-lv{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#cabeab}
/* 예비 편성 — 팀 탭. 목록은 수비 편성과 같은 칸을 쓴다(규칙이 한 벌이다). */
.sq-tabs{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:7px}
.sq-tab{padding:5px 7px;min-height:28px;border:2px solid #8a6c57;background:#35281f;
  color:#e2d0b5;font:400 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.sq-tab.is-on{border-color:var(--dq-gold);background:#3a2f18;color:#fff5da}
.sq-tab.is-empty{opacity:.62}
/* 덜 찬 팀 — 비어 있는 것과 **다르게** 보여야 한다(빈 팀은 그냥 안 쓰는 칸이고,
   덜 찬 팀은 사람이 채우다 만 것이다). 저장 단추도 이때 잠긴다. */
.sq-tab.is-short{border-color:#d8734a;color:#ffd8c4}
.sq-tab.is-short b{color:#ff9b6a}
.sq-tab b{color:#8de0bb}
.sq-add{border-style:dashed;color:#b1a087}
/* 지금 고르는 팀에 든 펫 — 목록이 길어 스크롤하면 방금 넣은 것이 화면 밖으로 나간다. */
.sq-now{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin-bottom:7px;
  padding:5px 6px;background:#2d2119;border-left:3px solid var(--dq-gold);
  font:400 10px "Galmuri9","Galmuri11",sans-serif;color:#f4eadb}
.sq-now>b{color:#ffd98a;margin-right:2px}
.sq-chip{display:inline-flex;align-items:center;gap:3px;padding:3px 5px;background:#1d3b30;
  border:1px solid #55c797;color:#dffaee;cursor:pointer}
.sq-chip i{font-style:normal;color:#8fd8b8}
.sq-none{color:#b1a087}
.sq-clear{margin-right:auto;min-height:36px;padding:7px 12px;border:2px solid #8a6c57;
  background:#2f231a;color:#e2d0b5;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer}
.sq-clear:disabled{opacity:.4;cursor:default}
/* 다른 팀에 이미 든 펫 — 눌러도 안 들어간다는 것이 보여야 한다. */
.op-pet.is-other{opacity:.55;border-style:dashed}
.op-pet-team{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#ffd98a;white-space:nowrap}
.sq-pick .op-pet-lv{white-space:nowrap}
/* 전선 작전실 — 전쟁 카드와 편성 격자 */
.fr-warfixed h4{display:flex;align-items:baseline;gap:6px}
.fr-warfixed.is-live{border-color:#ff8a3d}
.fr-warfixed.is-incoming{border-color:#d98a8a}
.fr-warfixed.is-none{border-color:#664f3f}
.fr-war h4{display:flex;align-items:baseline;gap:6px}
.fr-war-state{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#ffd98a}
.fr-war.is-live{border-color:#ff8a3d}
.fr-war.is-live .fr-war-state{color:#ffb37a}
.fr-teams{display:grid;grid-template-columns:repeat(4,1fr);gap:4px;margin:6px 0}
.fr-team{display:flex;align-items:center;gap:3px;padding:4px 5px;background:#2d2119;
  border:1px solid #634d3d;font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#f4eadb}
.fr-team.is-empty{opacity:.45}
/* 덜 찬 팀 — 3마리를 못 채워 **출전하지 않는다**(2026-09-03 규칙 고정).
   빈 팀(그냥 안 쓰는 칸)과 달리 흐리게 두지 않고 눈에 띄게 둔다. */
.fr-team.is-short{border-color:#d8734a;color:#ffd8c4}
.fr-warn{margin:6px 0 0;font:700 10px "Galmuri9","Galmuri11",sans-serif;
  color:#ff9b6a;line-height:1.7}
.fr-team i{width:6px;height:6px;background:#634d3d;border-radius:50%}
.fr-team i.is-on{background:#8de0bb}
@media(max-width:420px){.fr-teams{grid-template-columns:repeat(2,1fr)}}
.op-pick-act{display:flex;justify-content:flex-end;margin-top:9px}
.op-pick-act button{min-height:36px;padding:7px 16px;border:2px solid #55c797;background:#123;
  color:#eafff5;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer}
.op-pick-act button:disabled{opacity:.45;cursor:default}
/* 전선 입구 — 교전 중에는 불이 탄다. 움직임을 줄이려는 사람에게는 정지시킨다. */
.op-front-go.is-ablaze{border-color:#ff8a3d;color:#fff1de;
  background:linear-gradient(180deg,#7a2d10,#3a1408);
  animation:frontAblaze 1.1s ease-in-out infinite alternate}
@keyframes frontAblaze{
  from{box-shadow:0 0 0 0 #ff6a1a00,inset 0 -6px 10px -6px #ffb15a}
  to{box-shadow:0 0 10px 1px #ff6a1a88,inset 0 -10px 14px -6px #ffd9a8}}
@media(prefers-reduced-motion:reduce){.op-front-go.is-ablaze{animation:none;
  box-shadow:0 0 8px 1px #ff6a1a66}}
.tribe-note.is-mine-note{color:#25705a;font-weight:700}
/* 주간 임무 — 진척 게이지 + 단계 카드. 순위가 아니라 달성형이라 남과 비교하는 칸이 없다.
   접두사 `gw-` 는 전역 클래스명 충돌을 피하려는 것(.mine 사고와 같은 이유). */
.gw-head{display:flex;align-items:baseline;gap:6px;margin-top:8px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;}
.gw-head b{font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif;font-variant-numeric:tabular-nums}
.gw-head em{margin-left:auto;font-style:normal;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.gw-bar{position:relative;height:12px;margin-top:6px;border:2px solid #8a6c57;overflow:hidden}
.gw-bar i{display:block;height:100%;background:#55c797}
.gw-bar u{position:absolute;top:0;bottom:0;width:2px;background:#8a6c57;transform:translateX(-1px)}
.gw-tiers{display:flex;flex-direction:column;gap:4px;margin-top:8px}
.gw-tier{display:grid;grid-template-columns:auto auto 1fr auto;align-items:center;gap:8px;padding:6px 8px;border:1px solid #cbbca6;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.gw-tier .gw-t{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-weight:700}
.gw-tier .gw-goal,.gw-tier .gw-state{font-variant-numeric:tabular-nums}
.gw-tier .gw-reward{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gw-tier.is-claimed{opacity:.6}
.gw-note{margin-top:8px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.6}
/* 미니게임 「박자 원정」 — 이번 주 곡 카드와 전체 화면 무대.
   카드 골격(아이콘 + 제목 + 작은 줄 둘)은 던전의 다른 안내 카드와 같은 모양을 쓴다.
   종목이 늘면 이 카드가 그대로 복제되는 자리다. */
.weekly-song{display:flex;align-items:center;gap:10px;margin-top:8px;padding:10px;border:2px solid #8a6c57;}
.weekly-song .weekly-disc{font-size:24px;font-family:"Galmuri11","Galmuri9",sans-serif;line-height:1}
.weekly-song b{display:block;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.weekly-song small{display:block;margin-top:3px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.5}
/* 종목 배너 — 관리자가 올렸으면 카드 본문은 그림만 둔다. 게임명·내 기록·도전은 카드 머리에
   모으므로 이미지 둘레에 설명/메타를 덧붙이지 않는다(관리 콘솔 ▸ 미니게임 ▸ 「종목별 공개」). */
.weekly-song.has-banner{display:block;margin-top:0;padding:0;overflow:hidden}
.mg-banner-frame{aspect-ratio:755/213;overflow:hidden}
.weekly-song.has-banner .mg-banner{display:block;width:100%;height:100%;object-fit:cover;object-position:center 27%}
.weekly-actions{display:flex;align-items:center;gap:10px;margin-top:8px;flex-wrap:wrap}
.weekly-play{flex:0 0 auto;padding:9px 18px;border:2px solid #8a6c57;
  font:700 12px "Galmuri11","Galmuri9",sans-serif;cursor:pointer}
.weekly-play:focus-visible{outline:2px solid #c9a227;outline-offset:2px}
/* 이번 주 종목이 아직 없을 때 — 버튼을 지우지 않고 **잠근다**. 사라지면 왜 못 하는지가 안 보인다. */
.weekly-play:disabled{opacity:.45;cursor:not-allowed}
/* 무대는 화면을 통째로 덮는다. z-index 는 하단 내비(게임 모드 바)보다 위여야 한다 —
   아래에 깔리면 나가기 버튼 위로 내비가 겹쳐 눌린다. */
.minigame-stage{position:fixed;inset:0;z-index:9000;background:#0b0d12}
.minigame-stage iframe{display:block;width:100%;height:100%;border:0}
/* 오른쪽 위 단추 줄 — 부족 대화 · BGM · 닫기(✕)가 나란히(2026-09-17 — 「✕ 나가기」 글자 단추가 머리줄을 가렸다).
   단추 한 칸 28px · 틈 4px — 줄 폭은 단추 셋 92px(BGM 없는 종목은 둘 60px). 종목 머리줄은 오른쪽을 그만큼 비운다
   (광차 · 피하기 · 박자 원정 · 갱도 확장은 각 html 의 `<style>` · 함께하기는 guess.css `.gq-bar`).
   ⚠️ 전역 [hidden] 규칙이 없는 저장소다 — 숨김을 직접 못 박는다. */
.minigame-stage-tools{position:absolute;top:calc(env(safe-area-inset-top,0px) + 8px);right:8px;z-index:1;display:flex;gap:4px}
.minigame-stage-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;
  border:1px solid #ffffff2e;border-radius:8px;background:#11151ecc;color:#fff;
  font:600 14px/1 system-ui,-apple-system,"Segoe UI",Roboto,"Noto Sans KR",sans-serif;cursor:pointer}
.minigame-stage-btn:hover{background:#2a3040}
.minigame-stage-btn[hidden],.minigame-stage-dot[hidden]{display:none}
/* BGM 꺼짐 — 흐리게 + 빗금 */
.minigame-stage-btn.is-off{opacity:.55}
.minigame-stage-btn.is-off::after{content:"";position:absolute;left:5px;right:5px;top:50%;height:2px;margin-top:-1px;
  background:#ff6b5a;transform:rotate(-45deg)}
.minigame-stage-dot{position:absolute;top:2px;right:2px;width:7px;height:7px;border-radius:50%;background:#ff6b5a}
/* 무대가 열려 있는 동안 뒤쪽 스크롤을 잠근다 — 폰에서 프레임을 쓸어내리면 게임이 함께 밀린다. */
body.minigame-stage-open{overflow:hidden}
/* ⚠️ 전역 [hidden] 규칙이 없는 저장소다(1531행과 같은 이유) — 직접 못 박는다. */
.minigame-stage[hidden]{display:none!important}
/* ── 미니게임 허브 ─────────────────────────────────────────────────────────
   종목이 계속 는다. 그래서 이 탭은 "이번 주 곡 카드 하나"가 아니라 **종목 목록**이고,
   순위표는 종목마다 두지 않고 **종합 하나**만 둔다 — 종목 수만큼 순위표가 늘면 화면이
   순위표 목록이 된다.
   카드의 겉(아이콘·제목·내 최고점)은 여기가 정하고, 속은 종목이 각자 그린다
   (dungeon.js `MINIGAME_BEHAVIOR`). 그래서 새 종목을 붙일 때 CSS 는 손댈 일이 없다. */
.mg-summary{display:flex;align-items:center;gap:10px;margin-top:8px;padding:10px;border:2px solid #8a6c57;}
.mg-summary .mg-sum-icon{font-size:24px;font-family:"Galmuri11","Galmuri9",sans-serif;line-height:1}
.mg-summary .mg-sum-main{flex:1 1 auto;min-width:0}
.mg-summary .mg-sum-main b{display:block;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;}
.mg-summary .mg-sum-main small{display:block;margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.5}
.mg-summary .mg-sum-rank{flex:0 0 auto;text-align:right}
.mg-summary .mg-sum-rank b{display:block;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;}
.mg-summary .mg-sum-rank small{display:block;margin-top:3px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
/* 미니게임 보상 — 지급이 켜진 주에만 dungeon.js 가 채운다(꺼져 있으면 빈 칸이라 안 보인다). */
.mg-rewards:empty{display:none}
.mg-rewards{margin-top:8px;padding:10px;border:2px solid #8a6c57;background:#fffdf5}
.mg-rw-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:#553f30;font-weight:700}
.mg-rw-head small{color:#8b6d57;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-weight:400}
.mg-rw-list{list-style:none;margin:7px 0 0;padding:0;display:flex;flex-direction:column;gap:5px}
.mg-rw-list li{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.mg-rw-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#553f30}
.mg-rw-claim{flex:0 0 auto;padding:4px 9px;border:2px solid #553f30;background:#ffd76a;color:#553f30;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-weight:700;cursor:pointer}
.mg-rw-claim:disabled{opacity:.5;cursor:default}
.mg-rw-done{flex:0 0 auto;color:#8b6d57;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.mg-rw-wait{flex:0 0 auto;color:#af9876;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-variant-numeric:tabular-nums}
.mg-list{display:flex;flex-direction:column;gap:10px;margin-top:10px}
.mg-card-head{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:9px;padding-bottom:7px;border-bottom:2px solid #f4eadb}
.mg-card-head .mg-card-icon{font-size:20px;font-family:"Galmuri11","Galmuri9",sans-serif;line-height:1}
.mg-card-head .mg-card-title{min-width:0}
.mg-card-head .mg-card-title b{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;}
.mg-card-head .mg-card-title small{display:block;margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.mg-card-head .mg-card-best{text-align:right}
.mg-card-head .mg-card-best b{display:block;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;}
.mg-card-head .mg-card-best small{display:block;margin-top:2px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
/* 이 종목이 **종합 점수에 낸 몫**(0~1000). 바로 위의 큰 숫자는 게임 안에서 본 점수라
   둘은 단위가 다르다 — 나란히 안 두면 "378점인데 총점은 왜 840 올랐지"를 못 푼다. */
.mg-card-head .mg-card-best .mg-card-points{display:block;margin-top:1px;font-style:normal;font-weight:700;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#b89e77}
/* 배너는 무엇을 하는 게임인지 그림이 이미 말한다. 머리줄은 제목·기록·행동만 한 줄로 압축한다. */
.mg-card.has-banner .mg-card-head{grid-template-columns:auto minmax(0,1fr) auto auto;gap:8px;padding-bottom:6px}
.mg-card.has-banner .mg-card-title small,.mg-card.has-banner .mg-card-points{display:none}
.mg-card.has-banner .mg-card-best b{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;white-space:nowrap}
.mg-card.has-banner .mg-card-best small{margin-top:1px}
.mg-card.has-banner .weekly-song.has-banner{border:0}
.mg-card-play{padding:7px 10px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;white-space:nowrap}
/* 운영은 껐는데 관리자라 보이는 종목 — 카드 제목 옆에 누구에게 보이는지 적는다. */
.mg-card-head .mg-card-title b .mg-hidden-tag{margin-left:5px;padding:1px 4px;border:1px solid #c9a227;font-style:normal;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;vertical-align:middle}
/* 아직 열리지 않은 자리 — 비워 두지 않고 "여기 하나 더 생긴다"를 눈에 보이게 남긴다. */
.mg-card.is-soon{border-style:dashed;opacity:.75}
.mg-soon-note{margin-top:8px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.6}
/* 열린 종목이 하나도 없을 때 — 카드 자리를 비우지 않고 이유를 적는다. */
.mg-empty{margin:10px 0 0;padding:14px;border:2px dashed #8a6c57;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.7;text-align:center}
.trinket-filters{display:flex;flex-wrap:wrap;gap:4px;margin:8px 0}
.trinket-filters button{padding:4px 8px;border:1px solid #8a6c57;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer}
/* 보유 칸은 본문 **아래**에 깔리므로 카드 폭을 늘릴 필요가 없다(오른쪽에 열을 더 만들었을 때는
   본문 몫이 음수가 되어 글자가 한 자씩 접혔다). 남은 제약은 '스트립 폭 ≤ 본문 폭' 하나뿐이다. */
.trinket-bag{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px}
.trinket-card{display:flex;gap:8px;align-items:flex-start;padding:8px;border:1px solid #8a6c57;}
.trinket-card .t-icon img{width:36px;height:36px;flex:none;image-rendering:pixelated}
/* 액션 버튼은 아이콘 **바로 아래**에 둔다 — 본문 오른쪽 끝에 있으면 카드마다 세로 위치가 달라져
   눈이 매번 버튼을 찾아야 했다(효과 줄 수에 따라 카드 높이가 다르다). */
.trinket-card .t-icon{flex:none;display:flex;flex-direction:column;align-items:center;gap:4px;width:44px}
.trinket-card .t-icon button{width:100%;padding:3px 2px;text-align:center}
/* 사용 중인 장신구는 테두리로 먼저 눈에 들어오고, 누가 끼고 있는지는 얼굴이 말한다. */
.trinket-card.tk-worn{box-shadow:inset 0 0 0 1px rgba(85,199,151,.35)}
/* 보유 칸 스트립(우측 상단, 5칸×2줄) — 칸 수=보유량, 빈 칸=남은 수량, 얼굴=착용 펫.
   숫자 문구('보유 N · 남음 N')를 이 칸들이 대신하므로 카드에서 그 줄을 없앴다. */
/* 스탯 줄 아래 여백에 깔린다. 폭은 본문 폭을 넘지 않아야 한다 — 넘으면 6번째 칸이 다음 줄로
   내려가 '5칸 × 2줄'이라는 읽는 규칙이 깨진다. 카드 150px 기준 본문 82px, 스트립 78px. */
.t-slots{display:grid;grid-template-columns:repeat(5,14px);gap:2px;margin-top:5px}
.t-slots i{display:grid;place-items:center;width:14px;height:14px;overflow:hidden;
  border:1px solid #cbbca6;font-style:normal}
/* 초상은 28px 로 렌더된 것을 여기서 줄여 쓴다(캐시 공유) — 크기를 여기서만 바꾸면 안 된다. */
.t-slots img{width:14px;height:14px;image-rendering:pixelated}
.t-slots .ts-off{border-style:dashed}
.t-slots .ts-more{border-style:dotted;font:700 10px "Galmuri9","Galmuri11",sans-serif}
.trinket-card .t-body{min-width:0;flex:1}
/* 한글은 어절 단위로 접는다 — 기본값은 글자 단위라 좁아지면 '진실/의/아이' 처럼 쪼개진다. */
.trinket-card b{display:block;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;margin-bottom:2px;word-break:keep-all}
.trinket-card small{display:block;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.4;word-break:keep-all}
.trinket-card .t-stats{margin-top:3px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.trinket-card button{padding:3px 7px;border:1px solid #55c797;background:#eafff5;color:#25705a;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer}
.trinket-card button:disabled{opacity:.45;cursor:default}
.trinket-empty{grid-column:1/-1;padding:14px;border:1px dashed #bdae97;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;text-align:center;line-height:1.6}

/* 장착할 펫 고르기 — 파워스톤 상세(.rune-modal)의 오버레이를 그대로 재사용하고 카드만 따로 둔다.
   ⚠ window.prompt 를 쓰지 않는 이유는 dungeon.js openTrinketEquipModal 주석 참조. */
.trinket-pick{position:relative;width:min(92vw,420px);max-height:82vh;display:flex;flex-direction:column;
  padding:14px;background:#211913;border:3px solid var(--dq-gold);color:#fff5da}
.trinket-pick .tpick-head{display:flex;align-items:center;gap:9px;margin-bottom:6px}
.trinket-pick .tpick-head img{image-rendering:pixelated}
.trinket-pick .tpick-head strong{display:block;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.trinket-pick .tpick-head span{display:block;color:#cabeab;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;margin-top:2px}
.trinket-pick .tpick-note-top{margin:0 0 8px;color:#cabeab;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.5}
.trinket-pick .tpick-list{flex:1;overflow-y:auto;margin:0;padding:0 4px 0 0;list-style:none;display:grid;gap:4px}

/* 모달 안쪽 스크롤 — 픽셀 스크롤바 공용 규칙.
   숨기지 않는 이유: 목록이 수백 줄까지 가므로 '아래에 더 있다'는 신호가 사라지면 안 된다.
   페이지 전체 스크롤바(파일 상단)는 계속 숨긴 채, 자체 스크롤을 가진 패널만 여기서 칠한다.
   새 스크롤 영역에는 `dq-scroll` 클래스를 붙이면 된다(아래 목록은 옛 요소들의 소급 적용). */
.dq-scroll,
.trinket-pick .tpick-list,
.pet-detail-dialog,
.expedition-party-dialog,
.stage-season-dialog,
.stage-season-list,
.battle-opponent-detail .opp-card.opp-scout-card{scrollbar-width:thin;scrollbar-color:#735642 #221912}
.dq-scroll::-webkit-scrollbar,
.trinket-pick .tpick-list::-webkit-scrollbar,
.pet-detail-dialog::-webkit-scrollbar,
.expedition-party-dialog::-webkit-scrollbar,
.stage-season-dialog::-webkit-scrollbar,
.stage-season-list::-webkit-scrollbar,
.battle-opponent-detail .opp-card.opp-scout-card::-webkit-scrollbar{width:10px;height:10px}
.dq-scroll::-webkit-scrollbar-track,
.trinket-pick .tpick-list::-webkit-scrollbar-track,
.pet-detail-dialog::-webkit-scrollbar-track,
.expedition-party-dialog::-webkit-scrollbar-track,
.stage-season-dialog::-webkit-scrollbar-track,
.stage-season-list::-webkit-scrollbar-track,
.battle-opponent-detail .opp-card.opp-scout-card::-webkit-scrollbar-track{background:#221912;border:2px solid #110c09}
/* 손잡이는 카드와 같은 픽셀 입체(위/왼쪽 하이라이트 + 아래/오른쪽 그림자) */
.dq-scroll::-webkit-scrollbar-thumb,
.trinket-pick .tpick-list::-webkit-scrollbar-thumb,
.pet-detail-dialog::-webkit-scrollbar-thumb,
.expedition-party-dialog::-webkit-scrollbar-thumb,
.stage-season-dialog::-webkit-scrollbar-thumb,
.stage-season-list::-webkit-scrollbar-thumb,
.battle-opponent-detail .opp-card.opp-scout-card::-webkit-scrollbar-thumb{background:#735642;border:2px solid #110c09;
  box-shadow:inset 1px 1px 0 rgba(255,255,255,.18),inset -1px -1px 0 rgba(0,0,0,.45)}
.dq-scroll::-webkit-scrollbar-thumb:hover,
.trinket-pick .tpick-list::-webkit-scrollbar-thumb:hover,
.pet-detail-dialog::-webkit-scrollbar-thumb:hover,
.expedition-party-dialog::-webkit-scrollbar-thumb:hover,
.stage-season-dialog::-webkit-scrollbar-thumb:hover,
.stage-season-list::-webkit-scrollbar-thumb:hover,
.battle-opponent-detail .opp-card.opp-scout-card::-webkit-scrollbar-thumb:hover{background:#936c50}
/* 장신구 모달은 금색 테두리라 손잡이도 금색 계열로 맞춘다(같은 카드 안에서 색이 겉돌지 않게). */
.trinket-pick .tpick-list{scrollbar-color:var(--dq-gold) #221912}
.trinket-pick .tpick-list::-webkit-scrollbar-thumb{background:#7a5c2c}
.trinket-pick .tpick-list::-webkit-scrollbar-thumb:hover{background:var(--dq-gold)}
.tpick-row{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"pet slot" "loadout loadout";column-gap:6px;row-gap:4px;padding:5px 6px;background:#2f231a;border:1px solid #564233}
.tpick-row.worn{border-color:var(--dq-mint)}
.tpick-pet{grid-area:pet;min-width:0;display:flex;align-items:center;gap:5px}
.tpick-pet img{width:22px;height:22px;flex:none}
/* 얼굴은 보이는 행만 만든다(hydratePortraits). 자리표시자가 같은 칸을 미리 잡아야
   채워지는 순간 행이 흔들리지 않는다 — 스크롤 중이면 위치가 튄다. */
.tpick-face{flex:none;width:22px;height:22px;line-height:0;display:block}
.tpick-face .pet-portrait{width:22px;height:22px;display:block}
.tpick-pet b{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tpick-pet em{font-style:normal;color:#a29178;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;white-space:nowrap}
.tpick-row button{padding:3px 8px;border:1px solid var(--dq-mint);background:#25705a;color:#eafff5;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;flex:none}
.tpick-row button:disabled{opacity:.4;cursor:default}
/* 슬롯이 곧 버튼이다 — 빈 칸을 누르면 끼우고, 착용 중인 칸을 누르면 뺀다(별도 해제 버튼 없음).
   ⚠ 칸 안의 그림만으로는 구분이 안 된다(아이콘이 계열당 하나) — 그래서 이름을 함께 싣고
   테두리로 상태를 나눈다: 점선=빈 칸, 민트=이 장신구, 금색=다른 장신구(누르면 교체). */
/* 이름이 붙는 건 '다른 장신구' 칸뿐이다 — 나머지는 아이콘만 남으므로 패딩을 균등하게 준다. */
.tpick-slot.tpick-mine,.tpick-slot.tpick-vacant{padding:3px}
.tpick-row .tpick-slot{grid-area:slot;align-self:center;flex:none;display:flex;align-items:center;gap:5px;max-width:54%;padding:3px 6px 3px 3px;
  border:2px solid #564233;background:#281d16;color:#f3e8d8;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer}
.tslot-box{position:relative;flex:none;display:grid;place-items:center;width:26px;height:26px;border:2px solid #735642;background:#18120e}
.tslot-box img{image-rendering:pixelated}
.tslot-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 선택 계열 슬롯과 별개로, 펫이 이미 낀 모든 장신구를 아이콘으로 압축해 보여 준다.
   상세 이름은 아이콘의 접근성 라벨·툴팁에만 둬 목록을 짧게 유지한다. */
.tpick-loadout{grid-area:loadout;display:flex;align-items:flex-start;gap:4px;min-width:0;padding-top:4px;border-top:1px dashed #644d3c}
.tpick-equipped-count{flex:none;padding:2px 3px;background:#3b2d20;color:#ffd88a;font:700 10px/1.35 "Galmuri9","Galmuri11",sans-serif;white-space:nowrap}
.tpick-equipped-items{min-width:0;display:flex;flex-wrap:wrap;gap:3px}
.tpick-equipped-item{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;padding:1px;border:1px solid #735642;background:#221912;color:#ebdeca;line-height:1.35}
.tpick-equipped-item img{width:14px;height:14px;flex:none;image-rendering:pixelated}
.tpick-equipped-empty{color:#a29178;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.65}
/* 빈 칸 = 들어갈 장신구의 **검은 실루엣**. 색을 통째로 죽여서(brightness 0) 채워진 칸과 헷갈리지
   않게 하면서도, 그 자리에 뭐가 들어가는지는 보여준다. 아이콘 파일은 계열당 하나뿐이라
   실루엣용 자산을 따로 만들지 않는다. */
.tpick-slot.tpick-vacant .tslot-box{border-style:dashed}
.tpick-slot.tpick-vacant .tslot-box img{filter:brightness(0);opacity:.42}
/* 착용 중 표시 — 라벨 대신 배지 하나. 누르면(호버·포커스) ✕ 로 바뀌어 '빠진다'를 예고한다. */
.tslot-badge{position:absolute;top:-5px;right:-5px;display:grid;place-items:center;width:13px;height:13px;
  border:1px solid #110c09;background:var(--dq-mint);color:#0f3f2d;font:700 8px/1 "Galmuri7","Galmuri9",sans-serif}
.tslot-badge::after{content:'✓'}
.tpick-slot.tpick-mine:hover .tslot-badge,
.tpick-slot.tpick-mine:focus-visible .tslot-badge{background:#e46d60;color:#2d0f0c}
.tpick-slot.tpick-mine:hover .tslot-badge::after,
.tpick-slot.tpick-mine:focus-visible .tslot-badge::after{content:'✕'}
.tpick-slot.tpick-mine{border-color:var(--dq-mint);background:#22503f;color:#d6ffee}
.tpick-slot.tpick-mine .tslot-box{border-color:var(--dq-mint);background:#17402f}
.tpick-slot.tpick-moving-out{border-style:dashed;border-color:#c99a52;background:#3b2d20;color:#ffe6b8;cursor:default}
.tpick-slot.tpick-moving-out .tslot-box{border-color:#c99a52;background:#261b13;filter:grayscale(.45)}
.tpick-slot.tpick-other{border-color:#8a6a2c;background:#33291a;color:#ffe6b8}
.tpick-slot.tpick-other .tslot-box{border-color:#8a6a2c;background:#241c11}
.tpick-row .tpick-slot:disabled{opacity:.42;cursor:default}
.battle-progress-box .battle-weather{white-space:nowrap;color:#dff7ff;background:#21313ddd}.battle-progress-box .battle-weather[data-weather="storm"]{color:#fff1a8;background:#30334ddd}.battle-progress-box .battle-weather[data-weather="ash"]{color:#ffd0a8;background:#452c28dd}.battle-progress-box .battle-weather[data-weather="snow"]{color:#efffff;background:#30435bdd}.battle-progress-box .battle-weather[data-weather="fog"]{color:#e5e9e5;background:#343a38dd}

@media(prefers-reduced-motion:reduce){.battle-skills .skill-passive .passive-fx,.battle-skills .skill-passive .passive-fx::before,.battle-skills .skill-passive .passive-fx::after,.battle-pet-hud.has-passive::after{animation:none!important}}
@media(prefers-reduced-motion:reduce){.battle-pet-hud.skill-casting,.battle-skill-callout,.battle-skills button.skill-used,.slot-tile.level-up,.dungeon-pet-card.level-up,.slot-tile.level-up::before,.dungeon-pet-card.level-up::after,.level-up-event{animation:none}.battle-skill-callout,.level-up-event{opacity:1;transform:translate(-50%,-56%)}}

/* 2026-07 pastel dashboard + dense expedition/roster layout. Battle HUD keeps
   its high-contrast theme; these overrides are scoped to the dashboard. */
.dungeon-shell{--dq-ink:#553f30;--dq-line:#8a6c57;--dq-gold:#f3ad38;--dq-mint:#55c797;--dq-blue:#64b9e8;padding:7px 7px 22px;background:linear-gradient(180deg,#d9f6ff 0,#faf6ef 38%,#fff3d2 100%);}.dungeon-summary{gap:4px}.dungeon-summary span{padding:5px 6px;}
.dungeon-panel{margin-top:8px;padding:9px;}.panel-title{gap:7px}.panel-title>strong{padding:5px 6px;}.system-note{margin:6px 0 0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.6}
.dungeon-zone{padding:5px 6px;margin-top:5px;}.dungeon-zone h3{margin:0 0 4px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.stage-row{gap:4px}.stage-node{min-height:42px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}.stage-node small{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;}.stage-node.selected{outline:2px solid #ef9e22;transform:translateY(-1px)}.dungeon-actions{margin-top:6px}.cube-action{padding:8px;}.cube-action.small{padding:6px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.fatigue-guide{margin-top:5px;padding:6px 7px;}
.dungeon-pets{gap:5px;margin-top:7px}.dungeon-pet-card{min-height:0;padding:4px;border-width:2px;cursor:default}.dungeon-pet-card.in-party{box-shadow:inset 0 2px 0 #e9fff7,0 0 0 1px rgba(58,178,134,.22)}
.dungeon-pet-card>.pet-stars{position:absolute;z-index:4;top:4px;left:4px;max-width:62%;text-align:left}.pet-stars{display:block;color:#f2a91f;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.15;letter-spacing:-1px;text-shadow:0 1px #fff,0 0 3px #ffd76c;overflow-wrap:anywhere}.pet-stars.empty{color:#c1b6a5;text-shadow:none}.pet-stars.compact{margin-top:2px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;white-space:normal}.pet-detail-title-wrap>.pet-stars{margin-top:4px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;letter-spacing:0}
.pet-card-hit{appearance:none;display:flex;flex:1;flex-direction:column;align-items:center;gap:3px;width:100%;min-width:0;padding:14px 0 2px;border:0;background:transparent;color:inherit;font-family:inherit;cursor:pointer}.pet-card-hit:focus-visible{outline:2px solid #e99b22;outline-offset:1px}.dungeon-pet-card .pet-grid-portrait{margin:0 auto}.dungeon-pet-card .pet-grid-portrait .pet-portrait{width:64px;height:64px}.pet-grid-name{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.pet-grid-fatigue-meter{height:5px;}
.pet-detail-star-bonus{margin:6px 0 0;padding:5px;border:1px solid #e4c36d;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.5}
@media(max-width:360px){.dungeon-shell{padding:5px 5px 20px}.dungeon-summary{margin-top:0}.dungeon-pet-card .pet-grid-portrait .pet-portrait{width:58px;height:58px}.dungeon-zone{padding:4px}.stage-node{min-height:38px}}

/* 2026-07 idle-game theme sync.
   Dungeon dashboard reuses the mining game's brown pixel panels and gold accents. */
.dungeon-shell{--dq-ink:var(--ink);--dq-dark:var(--bg);--dq-panel:var(--panel);--dq-line:var(--line);--dq-gold:var(--gold);--dq-mint:var(--unc);--dq-red:#ef765f;--dq-blue:var(--rare);padding:12px 12px 28px;color:var(--ink);background-size:16px 16px}
/* 턴·팀 요약 — 헤더가 네 화면 공용이 되면서 헤더 밖 독립 줄로 내려왔다. */
/* 던전 요약 줄(턴 · 팀) — 피로도 무제한 칩이 같은 줄에 선다. 폭이 모자라면 칩이 다음 줄로 넘어가 한 줄을 채운다. */
.dungeon-header-main{display:flex;min-width:0;align-items:center;gap:6px 8px;flex-wrap:wrap;margin-top:8px}
.dungeon-summary{flex:none;flex-wrap:nowrap;gap:4px;max-width:none;white-space:nowrap}.dungeon-summary span{padding:4px 6px;border:2px solid var(--line);background:var(--panel2);color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.dungeon-summary b{color:var(--gold)}
.dungeon-panel{margin-top:12px;padding:12px;}
.panel-title h2{font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}.dungeon-panel .eyebrow{color:var(--gold);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.panel-title>strong{padding:6px 8px;border:2px solid var(--line);background:var(--gold);color:#2a1d0c;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.dungeon-zone{padding:7px;margin-top:7px;border:2px solid var(--line);background:var(--panel2);box-shadow:inset -2px -2px 0 rgba(0,0,0,.28),inset 2px 2px 0 rgba(255,255,255,.05)}.dungeon-zone h3{color:var(--ink)}.dungeon-zone h3>small{color:var(--muted)}.stage-node.cleared{background:#376b4e;box-shadow:inset -2px -2px 0 #244a36,inset 2px 2px 0 rgba(255,255,255,.08)}.stage-node.selected{outline:2px solid var(--gold);transform:translateY(-1px)}
.assignment-empty{color:var(--muted);border-color:var(--dirt)}.fatigue-guide{border-color:var(--line);background:#4a3a24;color:#d5bd98}.fatigue-guide-title{color:var(--gold)}
.dungeon-pet-card{background:var(--panel2);color:var(--ink);box-shadow:inset -2px -2px 0 rgba(0,0,0,.32),inset 2px 2px 0 rgba(255,255,255,.05)}.dungeon-pet-card:hover{background:#443522}.dungeon-pet-card.common{border-color:var(--com)}.dungeon-pet-card.uncommon{border-color:var(--unc)}.dungeon-pet-card.rare{border-color:var(--rare)}.dungeon-pet-card.epic{border-color:var(--epic)}.dungeon-pet-card.legendary{border-color:var(--leg)}
.pet-grid-name{color:var(--ink)}.pet-grid-meta{color:var(--muted)}.pet-grid-meta b{color:var(--gold)}.pet-grid-fatigue-meter{border-color:var(--line);background:var(--dirt-lo)}
.pet-card-hit:focus-visible{outline-color:var(--gold)}
.pet-detail-dialog{border-color:var(--line);background:var(--panel);color:var(--ink);box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),inset 3px 3px 0 rgba(255,255,255,.06),0 12px 40px #000}.pet-detail-header,.pet-detail-section{border-color:var(--line);background:var(--panel2)}.pet-detail-title-wrap h2{color:var(--gold)}.pet-detail-title-wrap p,.pet-detail-stat span,.pet-attribute span,.pet-skill small{color:var(--muted)}.pet-detail-section h3,.pet-skill b{color:var(--gold)}.pet-detail-stat,.pet-attribute{border-color:var(--line);background:var(--panel)}.pet-detail-stat b{color:var(--ink)}.pet-detail-actions{border-color:var(--line);background:#231a13f2}.pet-detail-star-bonus{border-color:var(--gold-lo);background:#4a3921;color:#f1d894}.pet-skill{background:#3b2d20;border-left-color:var(--gold)}.pet-experience-meter{border-color:var(--line);background:var(--dirt-lo)}
.stone-target,.stone-card{border-color:var(--line);background:var(--panel2)}.stone-card strong{color:var(--ink)}.stone-card span,.empty-note{color:var(--muted)}.stone-gem{border-color:var(--line);background:var(--panel)}
/* 장신구도 스톤과 같은 3층(기본→파스텔→idle 테마)을 밟는다. 이 줄이 없으면 주변 패널이 갈색일 때
   가방 카드만 흰색으로 남는다 — 기본층의 #fff 를 덮는 규칙이 여기밖에 없기 때문. */
.weekly-song{border-color:var(--line);background:var(--panel2);color:var(--ink)}.weekly-song small{color:var(--muted)}
.weekly-play{border-color:var(--gold-lo);background:#4a3921;color:#f1d894}.weekly-play:hover{background:#5c4728}
.admin-preview-note{border-color:var(--gold-lo);background:#4a3921;color:#f1d894}
.mg-summary{border-color:var(--line);background:var(--panel2)}.mg-summary .mg-sum-main b,.mg-summary .mg-sum-rank b{color:var(--gold)}.mg-summary .mg-sum-main small,.mg-summary .mg-sum-rank small{color:var(--muted)}
.mg-card-head{border-bottom-color:var(--line)}.mg-card-head .mg-card-title b,.mg-card-head .mg-card-best b{color:var(--ink)}.mg-card-head .mg-card-title small,.mg-card-head .mg-card-best small,.mg-soon-note,.mg-empty{color:var(--muted)}
.mg-card-head .mg-card-title b .mg-hidden-tag{border-color:var(--gold-lo);background:#4a3921;color:#f1d894}.mg-empty{border-color:var(--line)}
.tribe-note{color:var(--muted)}.tribe-map{border-color:var(--line)}
.op-back{border-color:var(--line);background:var(--panel2);color:var(--ink)}.op-tribe{color:var(--ink)}
.op-tickets{background:var(--panel2);color:var(--ink)}
.ts-cell,.ts-chip{border-color:var(--line);background:var(--panel2);color:var(--ink)}
.ts-k{color:var(--muted)}.ts-cell b{color:var(--ink)}
.ts-cell b.is-empty{color:#ff9b9b}
.ts-chip.is-mine{border-color:var(--unc);background:var(--panel)}
.tg-step{border-color:var(--line);background:var(--panel2)}
.tg-head b,.tg-body b{color:var(--ink)}.tg-head span,.tg-body span,.tg-goal{color:var(--muted)}
.tg-step.is-done{border-color:var(--unc);background:var(--panel)}
.tg-step.is-done .tg-mark{color:var(--unc)}
.tribe-map-note{color:var(--muted)}.tribe-map-note b{color:var(--ink)}
.op-er-why{color:var(--ink)}
.op-erosion{border-color:var(--line);background:var(--panel2)}
.op-er-head b{color:var(--ink)}.op-er-head,.op-er-note{color:var(--muted)}
.op-er-bar{border-color:var(--line);background:var(--panel)}
/* ⚠ 밝은 배경용 초록(#2f7d5a)을 그대로 두면 어두운 패널에서 **대비 2.67:1** 이라 9px 글씨가
   묻힌다(2026-08-21 실측). 기존 '긍정' 토큰을 쓰면 7.1:1 이다. */
.op-er-head span.is-on{color:var(--unc)}
.gw-tier{border-color:var(--line);background:var(--panel2);color:var(--ink)}.gw-tier .gw-goal,.gw-tier .gw-state,.gw-head,.gw-note{color:var(--muted)}.gw-head b{color:var(--gold)}.gw-bar{border-color:var(--line);background:var(--panel)}.gw-tier.is-done{border-color:var(--unc);background:#2f4a3a}.gw-tier.is-done .gw-state{color:#bfe8d2}
.guild-card,.guild-member{border-color:var(--line);background:var(--panel2);color:var(--ink)}.guild-card .g-meta{color:var(--muted)}.guild-member{background:var(--panel)}
.trinket-card,.trinket-filters button{border-color:var(--line);background:var(--panel2);color:var(--ink)}.trinket-filters button[aria-selected="true"]{background:var(--gold);color:#2a1d0c}.trinket-card small{color:var(--muted)}.trinket-card .t-stats{color:var(--rare)}.trinket-empty{border-color:var(--line);color:var(--muted)}
.trinket-card.tk-worn{border-color:var(--unc)}.t-slots i{border-color:var(--line);background:var(--panel)}.t-slots .ts-on{border-color:var(--unc);background:var(--panel2)}.t-slots .ts-more{color:var(--muted)}
.dungeon-state{color:var(--ink);}

/* 스티커 장착 시에도 던전 패널의 기본 픽셀 테두리를 유지한다. 던전 헤더(.bar)는 idle .bar 규칙의
   외곽 글로우·타이틀 글로우·코너 핀을 상속하고, 상태 패널과 내부 활성 탭도 같은 색을 공유한다. */
body.has-sticker .dungeon-panel,
body.has-sticker .dungeon-state{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 .dungeon-tabs{filter:drop-shadow(0 0 3px var(--sticker))}
body.has-sticker .dtab.active{box-shadow:inset 0 3px 0 var(--sticker),0 0 6px var(--sticker);text-shadow:0 0 7px var(--sticker)}

/* The runtime measures the rendered Dungeon header so navigation keeps the
   exact same border-box width and horizontal position at every resolution. */
.game-mode-nav{left:var(--mode-nav-left,50%);width:var(--mode-nav-width,calc(min(100vw,460px) - 24px));max-width:none;transform:translateX(var(--mode-nav-shift,-50%));border-color:#08060a;}.game-mode-nav button{border-color:#08060a;}
body.has-sticker .game-mode-nav{box-shadow:0 -4px 0 rgba(0,0,0,.28),0 0 12px var(--sticker)}
body.has-sticker .game-mode-nav button.active{box-shadow:inset 0 3px 0 var(--sticker);text-shadow:0 0 8px var(--sticker)}
body.has-sticker .game-mode-nav button.active span{filter:drop-shadow(0 0 4px var(--sticker))}
.battle-top-actions{display:flex;align-items:stretch;gap:4px;pointer-events:auto}.battle-top-actions button{min-width:0}
@media(max-width:360px){.dungeon-shell{padding:8px 8px 24px}.dungeon-header-main{gap:5px;margin-top:6px}.dungeon-summary{gap:2px}.dungeon-summary span{padding:2px 3px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}}
@media(max-width:360px){.game-mode-nav{width:var(--mode-nav-width,calc(100vw - 16px))}.battle-top-actions{gap:2px}}
@media(max-width:320px){.dungeon-header-main{justify-content:flex-start}}

/* ===== 배틀 허브(비동기 PvP P1): 출전 분리 · 대표팀 편성 · 3D 단상 · TOP10 랭킹 ===== */
.cube-action.battle{background:#7c4a5e;color:#fff2f4;box-shadow:inset -3px -3px 0 #4e2c3b,inset 3px 3px 0 rgba(255,255,255,.12)}

.battle-podium{position:relative;height:206px;margin-top:4px;border:2px solid var(--line);background:linear-gradient(180deg,#453123 0%,#6a2d6e 30%,#c8506a 50%,#f09a5e 60%,#2b1f16 62%,#120d09 100%);overflow:hidden}
.battle-podium canvas{display:block}
/* 단상 자리 안내 — 3D 무대(관람차 · 조명) 위에 바로 얹혀 글자가 배경에 묻혔다. 어두운 받침을 깐다(2026-09-26). */
.battle-podium-hint{position:absolute;z-index:2;left:50%;top:50%;width:max-content;max-width:84%;transform:translate(-50%,-50%);padding:7px 12px;border:2px solid #553d2c;background:rgba(17,12,9,.8);box-shadow:0 4px 12px rgba(0,0,0,.4);text-align:center;color:#faf4ec;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.5}
.podium-fallback{position:absolute;inset:0;display:flex;align-items:flex-end;justify-content:center;gap:10px;padding:14px}
.podium-fallback .podium-slot{display:flex;flex-direction:column;align-items:center;width:76px}
.podium-fallback .podium-figure{display:grid;place-items:center;width:64px;height:64px}
.podium-fallback .podium-figure .pet-portrait{width:60px;height:60px}
.podium-fallback .podium-initial{color:#ffe6a6;font:700 12px "Galmuri11","Galmuri9",sans-serif}
.podium-fallback .podium-pillar{width:100%;border:2px solid #110c09;border-bottom:0}
.podium-fallback .podium-slot.center .podium-pillar{height:52px;background:#76553d}
.podium-fallback .podium-slot.left .podium-pillar{height:34px;background:#3f4760}
.podium-fallback .podium-slot.right .podium-pillar{height:34px;background:#5c4a30}
.podium-fallback .podium-empty{margin:auto;color:#e7d2b3;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}

.battle-hub-summary{display:flex;align-items:center;gap:8px;margin-top:8px}
.battle-hub-stats{display:grid;grid-template-columns:repeat(2,1fr);gap:5px;flex:1;min-width:0}
.battle-stat{padding:6px 5px;background:var(--panel2);border:2px solid var(--line);text-align:center}
.battle-stat:last-child{grid-column:1/-1}
.battle-stat span{display:block;color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.battle-stat b{display:block;margin-top:3px;color:var(--gold);font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}
.battle-stat b.battle-stat-depleted{color:#e08a8a}
#startBattle{position:relative}
/* 알림 배지는 버튼 모서리 '밖'에 걸친다 — 버튼(.cta-hero)이 스택 컨텍스트(isolation:isolate)라
   z-index 를 광택 스윕(::after=1)·아이콘/라벨(=2)보다 위로 올려야 숫자가 가려지지 않는다.
   클릭은 버튼이 받아야 하므로 pointer-events 는 뚫는다. ⚠ 부모 overflow 를 hidden 으로 되돌리면
   -7px 만큼 튀어나온 부분이 잘려 숫자가 안 보인다(2026-08-04 회귀 수정). */
.battle-inbox-badge{position:absolute;top:-8px;right:-8px;z-index:5;display:grid;place-items:center;min-width:22px;height:22px;padding:0 5px;border:2px solid #2b0b12;border-radius:11px;background:#ec5f78;color:#fff;font:700 10px "Galmuri9","Galmuri11",sans-serif;box-shadow:0 2px 7px rgba(0,0,0,.45);pointer-events:none}
.battle-section-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}.battle-section-head>div:first-child{min-width:0}.battle-section-head strong,.battle-section-head span{display:block}.battle-section-head strong{color:#ffe09a;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}.battle-section-head>div:first-child>span{margin-top:3px;color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.battle-section-head>#battleCandidateState{color:#9bd8c2;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;text-align:right}
.battle-matchmaking{margin-top:11px;padding:10px;border:2px solid var(--line);background:linear-gradient(150deg,rgba(92,57,131,.2),rgba(31,22,16,.88))}
.battle-matchmaking{border-color:#7858a6;box-shadow:inset 0 0 14px rgba(109,58,214,.12)}
.battle-candidate-list{display:flex;flex-direction:column;gap:6px}.battle-candidate-empty,.battle-activity-empty{padding:14px 8px;color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.6;text-align:center}
.battle-candidate-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:7px;width:100%;padding:8px;border:2px solid #75563f;background:linear-gradient(135deg,#443123,#2c2017);color:var(--ink);font-family:"Galmuri11","Galmuri9",sans-serif;text-align:left;cursor:pointer}.battle-candidate-row:hover{border-color:#a886d4;filter:brightness(1.08)}.candidate-pets{display:flex;gap:2px}.candidate-pets .pet-portrait,.candidate-pets .rank-pet-blank{width:32px;height:32px}.candidate-info{min-width:0}.candidate-info b,.candidate-info small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.candidate-info b{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#fff1c9}.candidate-info small{margin-top:3px;color:#b6a894;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.candidate-score{text-align:right}.candidate-score b,.candidate-score small{display:block;white-space:nowrap}.candidate-score b{color:#8fe0bd;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.candidate-score small{margin-top:3px;color:#e5cfad;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.battle-hub-actions{margin-top:11px}.battle-activity-open{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:10px;width:100%;min-height:56px;padding:9px 11px;border:2px solid #4c6970;background:linear-gradient(135deg,#1d3336,#172329);color:var(--ink);font-family:"Galmuri11","Galmuri9",sans-serif;text-align:left;cursor:pointer;box-shadow:inset 0 0 14px rgba(70,177,173,.10)}.battle-activity-open:hover{border-color:#79cfc6;filter:brightness(1.08)}.battle-activity-open:focus-visible{outline:2px solid var(--gold);outline-offset:2px}.battle-activity-open-icon{display:grid;place-items:center;width:34px;height:34px;border:1px solid #5c9d98;background:#153238;font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}.battle-activity-open-copy{min-width:0}.battle-activity-open-copy strong,.battle-activity-open-copy small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.battle-activity-open-copy strong{color:#ddfff7;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}.battle-activity-open-copy small{margin-top:4px;color:#a7d8d2;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.battle-activity-open-arrow{color:#95e4d8;font-size:24px;font-family:"Galmuri11","Galmuri9",sans-serif;line-height:1}.battle-activity-modal{position:fixed;z-index:94;inset:0;background:rgba(7,5,9,.78)}.battle-activity-dialog{display:flex;flex-direction:column;border:3px solid #526d72;background:linear-gradient(160deg,#37281e,#171c22);box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),inset 3px 3px 0 rgba(255,255,255,.06),0 12px 40px #000}.battle-activity-dialog-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;padding:13px 13px 11px;border-bottom:1px solid #45575e;background:linear-gradient(100deg,rgba(87,183,171,.12),transparent)}.battle-activity-dialog-head .eyebrow{color:#85d5cb;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;letter-spacing:.11em}.battle-activity-dialog-head h3{margin:3px 0 0;color:#fff0c3;font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}.battle-activity-dialog-head p{margin:4px 0 0;color:#a7d8d2;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.battle-activity-close{flex:0 0 auto;width:30px;height:30px;padding:0;border:2px solid var(--line);background:#5c3540;color:#fff;font:700 15px/1 "Galmuri14","Galmuri11",sans-serif;cursor:pointer}.battle-activity-close:hover{background:#754450}.battle-activity-dialog-body{overflow-y:auto;padding:10px}.battle-activity-dialog-body .battle-activity-tabs{margin-bottom:9px}.battle-activity-tabs{display:flex;gap:3px}.battle-activity-tabs button{padding:5px 7px;border:1px solid #614d3f;background:#30251d;color:#b0a089;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer}.battle-activity-tabs button.active{border-color:#d8b768;background:#554125;color:#ffe8aa}.battle-activity-list{display:flex;flex-direction:column;gap:5px;margin:0;padding:0;list-style:none}.battle-activity-row{position:relative;display:grid;grid-template-columns:48px minmax(0,1fr) auto;align-items:center;gap:7px;width:100%;padding:7px 8px;border:1px solid #59473b;background:#2a2018;color:var(--ink);font-family:"Galmuri11","Galmuri9",sans-serif;text-align:left;cursor:pointer}.battle-activity-row:hover{border-color:#7c9b9d;background:#273139}.battle-activity-row:focus-visible{outline:2px solid var(--gold);outline-offset:2px}.battle-activity-row.unread{border-color:#d4ad58;background:linear-gradient(90deg,rgba(212,173,88,.16),#2a2018)}.battle-activity-row.unread::before{content:"";position:absolute;left:-4px;top:50%;width:7px;height:7px;transform:translateY(-50%);border-radius:50%;background:#ffd56e;box-shadow:0 0 7px #ffd56e}.activity-kind{display:grid;place-items:center;min-height:31px;border:1px solid #5c4a3d;background:#1f1711;color:#c9bdaa;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.activity-kind.defense{border-color:#577b70;color:#9cdec8}.activity-main{min-width:0}.activity-main b,.activity-main small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.activity-main b{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.activity-main small{margin-top:3px;color:#a29178;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.activity-result{text-align:right}.activity-result b,.activity-result small{display:block;white-space:nowrap}.activity-result b{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.activity-result small{margin-top:3px;color:#9b90a1;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.activity-result.win b{color:#7fddb8}.activity-result.loss b{color:#ef9292}.activity-result.draw b{color:#c2b7c8}body.battle-activity-modal-open{overflow:hidden}

/* 최근 대전은 허브 레이아웃과 분리된 뷰포트 오버레이다. safe-area를 제외한 영역 안에서만 그린다.
   - height:100dvh(고정) 대신 inset:0 로 실제 표시 뷰포트에 핀한다. iOS 등에서 dvh 가 툴바 상태에 따라
     보이는 높이보다 커져 컨테이너가 넘치는 것을 막는다.
   - 중앙정렬은 place-items:center(=align-items:center) 대신 자식의 margin:auto 로 한다. align-items:center 는
     자식이 컨테이너보다 길면 위쪽을 뷰포트 밖으로 잘라먹지만, margin:auto 는 넘칠 때 상단부터 붙고
     컨테이너 overflow-y:auto 로 스크롤되어 상단이 잘리지 않는다. */
.battle-activity-modal{box-sizing:border-box;display:flex;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;padding:calc(12px + env(safe-area-inset-top)) calc(12px + env(safe-area-inset-right)) calc(12px + env(safe-area-inset-bottom)) calc(12px + env(safe-area-inset-left))}
.battle-activity-dialog{box-sizing:border-box;margin:auto;width:min(100%,420px);max-width:100%;max-height:100%;min-width:0;min-height:0;overflow:hidden}
.battle-activity-dialog-head{flex:0 0 auto}
.battle-activity-dialog-body{flex:1 1 auto;min-height:0;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
.battle-activity-list,.battle-activity-row{min-width:0}

/* 돌아가기 버튼을 가로로 넓혀 클릭 영역 확보(패널 타이틀 우측). */
#battleHubBack{min-width:104px;padding-left:18px;padding-right:18px;white-space:nowrap}

.rank-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:11px;padding-bottom:5px;border-bottom:2px solid var(--line)}
.rank-head strong{color:var(--gold);font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
#myBattleRank,#myMinigameRank{color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.rank-list{list-style:none;margin:8px 0 0;padding:0;display:flex;flex-direction:column;gap:5px}
.rank-list .rank-empty{padding:16px;text-align:center;color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.rank-row{display:grid;grid-template-columns:26px auto minmax(0,1fr) auto;align-items:center;gap:7px;width:100%;padding:6px 7px;border:2px solid var(--line);background:var(--panel2);color:var(--ink);font-family:"Galmuri11","Galmuri9",sans-serif;text-align:left;cursor:pointer;touch-action:manipulation}
.rank-row:hover{background:#3a2c1c}
.rank-row.me{border-color:var(--gold);box-shadow:inset 0 0 0 1px var(--gold)}
/* 상위 3위 강조 — 순위가 높을수록 카드가 크고 테두리 색이 다르다(1위 금 › 2위 하늘 실버 › 3위 초록 실버). */
.rank-row.r1{grid-template-columns:46px auto minmax(0,1fr) auto;padding:11px 10px;gap:9px;border:3px solid #ffd66d;background:linear-gradient(135deg,#5a4620,var(--panel2));box-shadow:0 0 0 1px rgba(255,214,109,.5),0 0 16px rgba(255,214,109,.32)}
.rank-row.r1 .rank-num{font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}
.rank-row.r1 .rank-media .pet-portrait,.rank-row.r1 .rank-media .rank-pet-blank{width:38px;height:38px}
.rank-row.r1 .rank-meta b{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.rank-row.r1 .rank-score b{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.rank-row.r2{grid-template-columns:42px auto minmax(0,1fr) auto;padding:9px 9px;gap:8px;border:2px solid #bcd8ec;background:linear-gradient(135deg,#3a4450,var(--panel2));box-shadow:0 0 0 1px rgba(188,216,236,.42),0 0 12px rgba(188,216,236,.24)}
.rank-row.r2 .rank-num{font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}
.rank-row.r2 .rank-media .pet-portrait,.rank-row.r2 .rank-media .rank-pet-blank{width:33px;height:33px}
.rank-row.r2 .rank-meta b{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.rank-row.r3{grid-template-columns:40px auto minmax(0,1fr) auto;padding:8px 8px;gap:8px;border:2px solid #a9d8b9;background:linear-gradient(135deg,#2f4636,var(--panel2));box-shadow:0 0 0 1px rgba(169,216,185,.4),0 0 12px rgba(169,216,185,.22)}
.rank-row.r3 .rank-num{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.rank-row.r3 .rank-media .pet-portrait,.rank-row.r3 .rank-media .rank-pet-blank{width:30px;height:30px}
.rank-row .rank-num{font:700 12px "Galmuri11","Galmuri9",sans-serif;text-align:center;color:var(--gold)}
/* 1~3위 순위 배지 이미지(메달 이모지 대체). 순위 열 폭에 맞춰 크기 차등. */
.rank-row .rank-badge{display:block;width:34px;height:34px;margin:0 auto;object-fit:contain;filter:drop-shadow(0 1px 2px rgba(0,0,0,.5))}
.rank-row.r1 .rank-badge{width:44px;height:44px}
.rank-row.r2 .rank-badge{width:40px;height:40px}
.rank-row.r3 .rank-badge{width:38px;height:38px}
.rank-row .rank-media{display:flex;gap:2px}
/* 그림이 없는 순위표(미니게임 종합) — 격자에서 그림 칸을 아예 뺀다. */
.rank-row--plain{grid-template-columns:26px minmax(0,1fr) auto}
.rank-row--plain.r1{grid-template-columns:46px minmax(0,1fr) auto}
.rank-row--plain.r2{grid-template-columns:42px minmax(0,1fr) auto}
.rank-row--plain.r3{grid-template-columns:40px minmax(0,1fr) auto}
/* 누를 데가 없는 줄은 버튼이 아니라 <div> 로 온다 — 손 모양·hover 를 주지 않는다. */
div.rank-row{cursor:default}
div.rank-row:hover{background:var(--panel2)}
.rank-row .rank-media .pet-portrait{width:26px;height:26px;border:1px solid var(--line);background:rgba(255,255,255,.06)}
/* 얼굴 초상 기본 배경(편성 슬롯과 동일한 금빛). GHUB 종별 portraitBg 인라인 스타일이 있으면 그 값이 우선한다. */
.rank-row .rank-media .pet-portrait-face{border-color:#8b691e;background:linear-gradient(145deg,#fff4b8,#e8b42d)}
.rank-pet-blank,.opp-pet-blank{display:grid;place-items:center;width:26px;height:26px;background:var(--panel);border:1px solid var(--line);color:var(--muted);font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.rank-row .rank-meta{min-width:0}
.rank-row .rank-meta b{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.rank-row .rank-meta b em{font-style:normal;color:#3ec78d;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.rank-row .rank-meta small{display:block;margin-top:2px;color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
/* 순위 줄의 **종목 표식**. 공통 부품(cube/util/rank_list.js)은 `tone` 이름만 찍고 색은 여기가 갖는다.
   ◆·◈ 두 색은 광차 화면(minigame/cart/cart.css 의 --shard/--gem)과 **같은 값**이다 —
   방금 주운 것이 어느 쪽이었는지 다시 세지 않게 하려는 것이라, 저쪽을 갈면 여기도 같이 간다. */
.rank-row .rank-tags{display:flex;flex-wrap:wrap;align-items:center;gap:1px 8px;margin-top:3px}
.rank-tag{display:inline-flex;align-items:center;gap:3px;font-style:normal;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.3;white-space:nowrap;color:var(--muted)}
.rank-tag>b{font-weight:400;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1}
.rank-tag--gold{color:#ffd66d}
.rank-tag--shard{color:#7fd4ff}
.rank-tag--gem{color:#ff8fd0}
/* 퍼펙트에만 붙는 무지개.
   🔴 처음에는 시상식 펫 이름(rewardName)을 그대로 빌렸다. 그건 그라디언트를 **옆으로 흘려**
      보내는 방식인데, 여기 글자는 '퍼펙트' 석 자(30px 남짓)라 한 번에 걸리는 폭이 좁아
      순간마다 **한 색**으로만 보였다 — 알록달록이 아니라 그냥 민트색 글자였다.
   그래서 스펙트럼을 **글자 폭에 한 번 다 깔고**(background-size 기본값), 대신 색상환을
   천천히 돌린다. 어느 순간에 봐도 석 자에 서로 다른 색이 얹힌다.
   자리를 옮기는 연출이 아니라 감속 모드에서도 그대로 재생한다(아래 절과 같은 판단).
   글자를 투명하게 만들어 배경을 비추는 방식이라, 아이콘 칸은 색을 되돌려 준다. */
.rank-tag--rainbow{font-weight:700;background:linear-gradient(90deg,#ff4d6d,#ff9f43,#ffd93d,#6ee7a8,#7cf5ff,#a78bfa);-webkit-background-clip:text;background-clip:text;color:transparent;filter:drop-shadow(0 1px 1px rgba(0,0,0,.85)) hue-rotate(0deg);animation:rankTagHue 5s linear infinite}
.rank-tag--rainbow>b{-webkit-background-clip:border-box;background-clip:border-box;color:#ffd166}
@keyframes rankTagHue{to{filter:drop-shadow(0 1px 1px rgba(0,0,0,.85)) hue-rotate(360deg)}}
.rank-row .rank-score{text-align:right}
.rank-row .rank-score b{display:block;color:var(--gold);font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.rank-row .rank-score small{display:block;color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
/* 표식이 있는 줄은 이름을 가운데, 점수·표식을 오른쪽 두 줄로 고정한다.
   미디어가 있는 배틀 줄(4열)과 없는 미니게임 줄(3열)을 모두 같은 음수 열 번호로
   가리켜, 표식이 생겼을 때 점수가 암시적 새 행으로 밀리지 않게 한다. */
.rank-row--tagged .rank-meta{grid-column:-3;grid-row:1/3}
.rank-row--tagged .rank-score{grid-column:-2;grid-row:1}
.rank-row--tagged .rank-tags{grid-column:-2;grid-row:2;margin-top:0}

/* 미니게임 TOP 10 — 순위 배지 · 프로필/종목 성과 · 총점의 세 구역만 남긴 점수 카드.
   칭호는 닉네임 왼쪽의 보조 배지다. 기본 칭호 판이 프로필 폭 전체를 먹지 않고, 없는 줄도
   닉네임이 같은 축에 와서 각 줄이 흔들리지 않는다.
   종목 표식은 점수 아래가 아니라 프로필 아래로 내려, 무엇으로 얻은 점수인지 왼쪽에서 한 번에 읽힌다. */
.rank-row--scorecard{grid-template-columns:38px minmax(0,1fr) max-content;grid-template-areas:"rank profile score" "rank stats score";column-gap:10px;row-gap:4px;min-height:50px;padding:7px 9px}
.rank-row--scorecard.rank-row--plain,.rank-row--scorecard.rank-row--plain.r1,.rank-row--scorecard.rank-row--plain.r2,.rank-row--scorecard.rank-row--plain.r3{grid-template-columns:38px minmax(0,1fr) max-content}
.rank-row--scorecard.r1{grid-template-columns:48px minmax(0,1fr) max-content;padding:9px 10px}
.rank-row--scorecard.r2{grid-template-columns:44px minmax(0,1fr) max-content;padding:8px 9px}
.rank-row--scorecard.r3{grid-template-columns:42px minmax(0,1fr) max-content;padding:8px 9px}
.rank-row--scorecard:not(.rank-row--tagged){grid-template-areas:"rank profile score"}
.rank-row--scorecard .rank-num{grid-area:rank;align-self:center}
.rank-row--scorecard .rank-meta{grid-area:profile;display:flex;align-items:center;gap:7px;align-self:center;min-width:0;overflow:hidden}
.rank-row--scorecard .rank-meta .np-plate{flex:0 1 auto;min-width:0;max-width:55%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.25}
.rank-row--scorecard .rank-meta .np-img{display:block;flex:0 1 auto;min-width:0;max-width:min(55%,132px);height:16px;object-fit:contain;object-position:left center}
.rank-row--scorecard .rank-meta>.np-plate+b,.rank-row--scorecard .rank-meta>.np-img+b{margin-top:0}
.rank-row--scorecard .rank-meta b{flex:1 1 auto;min-width:0;margin:0;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;line-height:1.3}
.rank-row--scorecard .rank-tags{grid-area:stats;min-width:0;max-width:100%;margin:0;gap:2px 7px}
.rank-row--scorecard .rank-tag{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.35}
.rank-row--scorecard .rank-score{grid-area:score;align-self:center;min-width:76px;padding-left:10px;border-left:1px solid color-mix(in srgb,var(--line) 72%,transparent);font-variant-numeric:tabular-nums}
.rank-row--scorecard .rank-score b{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;letter-spacing:-.025em;white-space:nowrap}
.rank-row--scorecard.r1 .rank-score b{font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}
.rank-row--scorecard.r2 .rank-score b{font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}
.rank-row--scorecard.r3 .rank-score b{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}

/* 좁은 화면에서는 순위·이름·점수의 고정 칸을 줄이고, 점수·표식을 이름 오른쪽에
   두 줄로 묶는다. 이름은 잘라내지 않고 두 줄까지 읽히게 하며, 표식은 폭이 모자라면
   자기 칸 안에서만 접힌다. */
@media(max-width:460px){
  .rank-row{
    grid-template-columns:30px auto minmax(0,1fr);
    grid-template-rows:auto auto;
    gap:2px 6px;
    padding:6px;
  }
  .rank-row.r1{padding:8px 7px;gap:4px 6px}
  .rank-row.r2{padding:7px;gap:3px 6px}
  .rank-row.r3{padding:7px;gap:3px 6px}
  .rank-row .rank-num{grid-row:1/3;grid-column:1;align-self:center;min-width:0}
  .rank-row .rank-media{grid-row:1/3;grid-column:2;align-self:center;min-width:0;gap:1px}
  .rank-media .pet-portrait,.rank-media .rank-pet-blank{width:22px;height:22px}
  .rank-row.r1 .rank-media .pet-portrait,.rank-row.r1 .rank-media .rank-pet-blank,
  .rank-row.r2 .rank-media .pet-portrait,.rank-row.r2 .rank-media .rank-pet-blank,
  .rank-row.r3 .rank-media .pet-portrait,.rank-row.r3 .rank-media .rank-pet-blank{width:22px;height:22px}
  .rank-row .rank-meta{grid-column:3;grid-row:1;min-width:0;white-space:normal;word-break:break-all}
  .rank-row .rank-meta b{white-space:normal;word-break:break-all;overflow:visible;text-overflow:clip;line-height:1.3}
  .rank-meta .np-plate{display:block;max-width:100%;overflow:visible;overflow-wrap:anywhere;word-break:break-all;white-space:normal}
  .rank-row .rank-score{grid-column:3;grid-row:2;display:flex;align-items:baseline;justify-content:flex-end;gap:5px;min-width:0;white-space:nowrap}
  .rank-row .rank-score b,.rank-row .rank-score small{display:inline;margin:0}
  .rank-row--plain .rank-meta{grid-column:2;grid-row:1/3}
  .rank-row--tagged{grid-template-columns:30px minmax(120px,1fr) minmax(0,1fr)}
  .rank-row--tagged .rank-meta{grid-column:2;grid-row:1/3;min-width:0}
  .rank-row--tagged .rank-score{grid-column:3;grid-row:1}
  .rank-row--tagged .rank-tags{grid-column:3;grid-row:2;min-width:0;max-width:100%;margin-top:0}
  .rank-row--tagged:not(.rank-row--plain) .rank-meta{grid-column:3}
  .rank-row--tagged:not(.rank-row--plain) .rank-tags{grid-column:3}
  .rank-row.r1 .rank-badge{width:30px;height:30px}
  .rank-row.r2 .rank-badge{width:28px;height:28px}
  .rank-row.r3 .rank-badge{width:26px;height:26px}
  /* 점수 카드의 종목 성과는 한 행을 온전히 쓴다. 칭호·닉네임은 같은 첫 행에서만 폭을 나눈다. */
  .rank-row--scorecard,.rank-row--scorecard.r1,.rank-row--scorecard.r2,.rank-row--scorecard.r3{grid-template-columns:32px minmax(0,1fr) max-content;grid-template-areas:"rank profile score" "rank stats stats";column-gap:7px;row-gap:4px;min-height:0;padding:7px}
  /* ⚠️ grid-area 뒤에 grid-column·grid-row 를 auto 로 덧붙이지 말 것 — 같은 블록의 뒤 칸이 이름 자리를
     지워 네 칸이 들어온 순서대로 채워진다(폰에서 표식이 총점 자리로, 총점이 배지 밑으로 떨어졌다 · 2026-09-15).
     위 공용 모바일 규칙의 칸 번호는 grid-area 한 줄이 이미 덮는다(선택자가 같거나 더 세고, 뒤에 온다). */
  .rank-row--scorecard .rank-num{grid-area:rank}
  .rank-row--scorecard .rank-meta,.rank-row--scorecard.rank-row--plain .rank-meta,.rank-row--scorecard.rank-row--tagged .rank-meta{grid-area:profile;display:flex;align-items:center;gap:5px;min-width:0;overflow:hidden;white-space:nowrap;word-break:normal}
  .rank-row--scorecard .rank-score,.rank-row--scorecard.rank-row--tagged .rank-score{grid-area:score;min-width:0;padding-left:7px}
  .rank-row--scorecard .rank-tags,.rank-row--scorecard.rank-row--tagged .rank-tags{grid-area:stats;max-width:none;margin:0;gap:2px 6px}
  /* 공통 모바일 줄은 긴 칭호/닉네임을 두 줄로 풀어 읽는 화면용이다.
     점수 카드는 칭호와 닉네임이 한 identity 줄을 공유하므로, 그 규칙을 그대로
     물려받으면 기본 판이 프로필 폭을 다시 전부 차지한다. 둘 다 이 칸 안에서만
     말줄임하고, 닉네임에는 최소 폭을 남긴다. */
  .rank-row--scorecard .rank-meta .np-plate{display:inline-block;min-width:0;max-width:48%;overflow:hidden;overflow-wrap:normal;text-overflow:ellipsis;white-space:nowrap;word-break:normal}
  .rank-row--scorecard .rank-meta .np-img{max-width:min(48%,112px);height:14px}
  .rank-row--scorecard .rank-meta b{flex:1 1 64px;min-width:64px;overflow:hidden;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.25;overflow-wrap:normal;text-overflow:ellipsis;white-space:nowrap;word-break:normal}
  .rank-row--scorecard .rank-score b,.rank-row--scorecard.r1 .rank-score b,.rank-row--scorecard.r2 .rank-score b{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
}

.battle-opponent-detail{position:fixed;z-index:95;inset:0;display:grid;place-items:center;padding:16px;background:rgba(7,5,9,.78)}
.battle-opponent-detail .opp-card{position:relative;width:min(100%,340px);padding:16px;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),0 12px 40px #000}
.opp-close{position:absolute;top:6px;right:6px;width:30px;height:30px;border:2px solid var(--line);background:#5c3540;color:#fff;font:700 15px/1 "Galmuri14","Galmuri11",sans-serif;cursor:pointer}
.opp-head{padding-right:28px}.opp-head b{color:var(--gold);font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}.opp-head span{display:block;margin-top:3px;color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
/* ⚠ `flex-wrap` 이 없으면 공성 수비 9마리가 한 줄에 눌려 카드 밖으로 밀린다(대전은 3마리라
   지금까지 드러나지 않았다). */
.opp-pets{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin:12px 0}
.opp-pet{display:grid;place-items:center;width:60px;height:60px;background:var(--panel2);border:2px solid var(--line)}
.opp-pet .pet-portrait{width:54px;height:54px}
.opp-pet.pet-rarity-legendary{border-color:var(--leg)}.opp-pet.pet-rarity-epic{border-color:var(--epic)}.opp-pet.pet-rarity-rare{border-color:var(--rare)}.opp-pet.pet-rarity-uncommon{border-color:var(--unc)}
/* 상대 펫 셀 = 클릭 시 상세보기(편성 화면과 동일). 버튼 기본 스타일 리셋 + 눌림 피드백. */
.opp-pet-btn{appearance:none;padding:0;color:inherit;font:inherit;cursor:pointer;touch-action:manipulation}
.opp-pet-btn:hover{filter:brightness(1.12)}
.opp-pet-btn:active{transform:translateY(1px)}
/* 상대 펫 상세 모달은 상대 상세(z-index 95) 위에 뜬다(편성 펫 상세 스타일 재사용). */
#oppPetDetailModal{z-index:100}
/* 이름 옆 속성 배지 정렬 + 상세 카드에 맞춰 또렷하게(작은 elem-sm 대신 24px 고정). */
.opp-detail-title{display:flex;align-items:center;gap:6px}
.opp-detail-title .elem-badge{flex:0 0 auto;width:24px;height:24px}
.opp-detail-title>span{min-width:0;overflow:hidden;text-overflow:ellipsis}
.opp-score{display:flex;justify-content:center;gap:14px;color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.opp-score b{color:var(--gold)}
.opp-challenge{width:100%;margin-top:12px;padding:10px;border:2px solid var(--line);background:#44372d;color:#c3b7a4;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:not-allowed;opacity:.7}
.opp-challenge-ready{background:#6d3ad6;color:#fff;border-color:#8f63d6;cursor:pointer;opacity:1}
.opp-challenge-ready:hover{background:#7d47e6}
.opp-challenge-ready:disabled{cursor:progress;opacity:.75}
/* 상대 스카우팅 리포트 — 팀 비교·대표 펫·시너지·도전 정보를 한 흐름으로 묶는다. */
.battle-opponent-detail .opp-card.opp-scout-card{--opp-accent:#b0b0b0;position:relative;width:min(100%,420px);max-height:calc(100dvh - 32px);overflow-y:auto;padding:0;border-color:var(--opp-accent);background:radial-gradient(circle at 12% 0,rgba(255,255,255,.08),transparent 34%),linear-gradient(160deg,#33261d,#1f1711 68%);box-shadow:inset -3px -3px 0 rgba(0,0,0,.35),inset 3px 3px 0 rgba(255,255,255,.06),0 0 18px rgba(0,0,0,.65),0 16px 42px #000;scrollbar-width:thin}
.opp-scout-card::before{content:"";position:absolute;z-index:1;top:0;left:12px;right:12px;height:2px;background:linear-gradient(90deg,transparent,var(--opp-accent),transparent);opacity:.9;pointer-events:none}
.opp-scout-card.opp-accent-fire{--opp-accent:#ff7a3c}.opp-scout-card.opp-accent-ice{--opp-accent:#6fd8ff}.opp-scout-card.opp-accent-storm{--opp-accent:#ffd23c}.opp-scout-card.opp-accent-water{--opp-accent:#4aa3ff}.opp-scout-card.opp-accent-void{--opp-accent:#c07de0}.opp-scout-card.opp-accent-light{--opp-accent:#ffe27a}.opp-scout-card.opp-accent-nature{--opp-accent:#6fd66a}.opp-scout-card.opp-accent-earth{--opp-accent:#d0a566}.opp-scout-card.opp-accent-beast{--opp-accent:#b0b0b0}
.opp-scout-card .opp-close{position:sticky;z-index:5;float:right;top:8px;margin:8px 8px -38px 0}
.opp-scout-head{display:grid;grid-template-columns:58px minmax(0,1fr);align-items:center;gap:10px;padding:16px 48px 13px 14px;border-bottom:1px solid #5c4637;background:linear-gradient(100deg,rgba(255,255,255,.045),transparent)}
.opp-rank-mark{display:grid;place-items:center;width:54px;height:54px;color:var(--gold);background:#1f1711dd;border:2px solid #634d3d;box-shadow:inset 0 0 0 2px #130e0a;font:700 15px "Galmuri14","Galmuri11",sans-serif}.opp-rank-mark img{display:block;width:46px;height:46px;object-fit:contain;filter:drop-shadow(0 2px 3px rgba(0,0,0,.55))}.opp-rank-mark.rank-1{border-color:#e8c265}.opp-rank-mark.rank-2{border-color:#bcd8ec}.opp-rank-mark.rank-3{border-color:#a9d8b9}
.opp-scout-identity{min-width:0}.opp-eyebrow{display:block;color:var(--opp-accent);font:700 10px "Galmuri9","Galmuri11",sans-serif;letter-spacing:.12em}.opp-scout-identity h2{overflow:hidden;margin:4px 0 0;color:#fff6dc;font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif;line-height:1.35;text-overflow:ellipsis;white-space:nowrap}.opp-scout-identity p{margin:5px 0 0;color:#c3b7a4;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.5}
.opp-record{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px;padding:9px 12px 0}.opp-record>span{min-width:0;padding:7px 4px;background:#1d150fb8;border:1px solid #554133;text-align:center}.opp-record small,.opp-record b{display:block}.opp-record small{color:#a5947b;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.opp-record b{overflow:hidden;margin-top:4px;color:#f8f2e9;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;text-overflow:ellipsis;white-space:nowrap}
.opp-scout-section{margin:9px 12px 0;padding:9px;background:#1d150fbd;border:1px solid #594537}.opp-section-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-bottom:8px}.opp-section-head b{color:#ffe09a;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.opp-section-head span{color:#a49277;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;text-align:right}.opp-scout-note{margin:0;color:#b6a995;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.6}
.opp-matchup-verdict.good{color:#82dfba}.opp-matchup-verdict.even{color:#e8dac5}.opp-matchup-verdict.warn{color:#efc66e}.opp-matchup-verdict.danger{color:#ff9488}.opp-power-row{display:grid;grid-template-columns:34px minmax(0,1fr) 68px;align-items:center;gap:6px;margin-top:5px;color:#af9f88;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.opp-power-row>b{text-align:right;color:#f8f1e7;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.opp-power-track{height:7px;overflow:hidden;background:#3c2d22;border:1px solid #110c09}.opp-power-track i{display:block;height:100%;min-width:5px}.opp-power-track .mine{background:linear-gradient(90deg,#3a806b,#79d9b7)}.opp-power-track .foe{background:linear-gradient(90deg,#74425a,var(--opp-accent))}.opp-matchup-meta{display:flex;justify-content:space-between;gap:8px;margin-top:7px;padding-top:6px;border-top:1px dashed #4c3a2e;color:#b7a994;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.opp-scout-pets{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}.opp-scout-pet{appearance:none;min-width:0;padding:7px 4px;background:linear-gradient(160deg,#413125,#2b1f17);border:2px solid #644d3c;color:#f6eddf;font-family:"Galmuri11","Galmuri9",sans-serif;text-align:center;cursor:pointer;touch-action:manipulation}.opp-scout-pet:hover{filter:brightness(1.1);transform:translateY(-1px)}.opp-scout-pet:active{transform:translateY(1px)}.opp-scout-pet:focus-visible{outline:2px solid var(--opp-accent);outline-offset:2px}.opp-scout-pet.loading{cursor:progress;opacity:.68}.opp-scout-pet.pet-rarity-legendary{border-color:var(--leg);box-shadow:inset 0 0 10px rgba(243,198,91,.12)}.opp-scout-pet.pet-rarity-epic{border-color:var(--epic)}.opp-scout-pet.pet-rarity-rare{border-color:var(--rare)}.opp-scout-pet.pet-rarity-uncommon{border-color:var(--unc)}
.opp-scout-portrait{position:relative;display:grid;place-items:center;width:72px;height:72px;max-width:100%;margin:0 auto 5px;background:var(--opp-portrait-bg,linear-gradient(145deg,#fff4b8,#e8b42d));border:1px solid #8b691e;box-shadow:inset 0 2px 0 rgba(255,255,255,.48),inset 0 -6px 12px rgba(90,52,0,.18)}.opp-scout-portrait.opp-scout-portrait-event{background:var(--opp-portrait-bg,linear-gradient(125deg,#ff5db1,#ffd166,#6ee7a8,#7cf5ff,#a78bfa,#ff5db1));background-size:320% 320%;border-color:#ffd9f2;animation:portraitHolo 6s ease-in-out infinite alternate}.opp-scout-portrait .pet-portrait{position:relative;z-index:1;width:70px;height:70px;max-width:100%}.opp-scout-pet-blank{position:relative;z-index:1;display:grid;place-items:center;width:70px;height:70px;max-width:100%;color:#6d5525;font-size:18px;font-family:"Galmuri11","Galmuri9",sans-serif}.opp-scout-pet>b{display:block;overflow:hidden;color:#fff4d8;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.4;text-overflow:ellipsis;white-space:nowrap}.opp-scout-pet-meta{display:block;overflow:hidden;margin-top:3px;color:#baac97;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;text-overflow:ellipsis;white-space:nowrap}.opp-role{display:inline-block;margin-top:5px;padding:2px 4px;background:#33271e;border:1px solid #644d3c;color:#dbc9ae;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.opp-role.role-tank{border-color:#6f9ec7;color:#a9d8ff}.opp-role.role-ranged{border-color:#62a77f;color:#a7e7bd}.opp-role.role-aoe{border-color:#a06dc2;color:#dcb4f5}.opp-role.role-support{border-color:#c1a35e;color:#ffe09a}.opp-role.role-melee{border-color:#b46868;color:#f2aaaa}
@media(prefers-reduced-motion:reduce){.opp-scout-portrait.opp-scout-portrait-event{animation:none}}
.opp-team-metrics{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px;margin-top:7px}.opp-team-metrics>span{min-width:0;padding:5px 3px;background:#2b1f17;text-align:center}.opp-team-metrics small,.opp-team-metrics b{display:block}.opp-team-metrics small{color:#a29076;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.opp-team-metrics b{overflow:hidden;margin-top:3px;color:#eadcc8;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;text-overflow:ellipsis;white-space:nowrap}
.opp-strategy-list,.opp-tactic-list{display:flex;flex-wrap:wrap;gap:5px}.opp-strategy-chip{display:flex;flex:1 1 130px;align-items:center;justify-content:space-between;gap:6px;padding:6px;background:rgba(141,99,214,.15);border:1px solid rgba(141,99,214,.45)}.opp-strategy-chip b{color:#ffe7a6;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.opp-strategy-chip small{color:#e9d3b3;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;white-space:nowrap}.opp-tactic-head{margin-top:9px}.opp-tactic-chip{padding:4px 6px;background:#21312e;border:1px solid #416d60;color:#a9e7d3;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.opp-strategy-empty,.opp-strategy-loading{color:#a99980;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.6}.opp-strategy-loading .opp-spin{margin-right:3px}
.opp-scout-actions{position:sticky;z-index:4;bottom:0;margin-top:10px;padding:8px 12px 12px;background:linear-gradient(180deg,rgba(31,23,17,.2),#1f1711 25%);border-top:1px solid #594537}.opp-challenge-meta{display:flex;flex-wrap:wrap;justify-content:space-between;gap:4px;color:#c7baa7;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.opp-challenge-meta span:first-child{color:#f0d58e}.opp-scout-actions .opp-challenge{margin-top:7px;min-height:40px}.opp-scout-actions .opp-challenge-ready{border-color:var(--opp-accent);box-shadow:0 0 10px rgba(109,58,214,.25)}
@media(max-width:380px){.battle-opponent-detail{padding:8px}.battle-opponent-detail .opp-card.opp-scout-card{max-height:calc(100dvh - 16px)}.opp-scout-head{grid-template-columns:50px minmax(0,1fr);padding-left:10px}.opp-rank-mark{width:48px;height:48px}.opp-rank-mark img{width:41px;height:41px}.opp-record,.opp-scout-section{margin-left:8px;margin-right:8px}.opp-record{padding-left:0;padding-right:0}.opp-scout-pets{gap:4px}.opp-scout-pet{padding-left:3px;padding-right:3px}.opp-scout-portrait{width:64px;height:64px}.opp-scout-portrait .pet-portrait,.opp-scout-pet-blank{width:62px;height:62px}.opp-power-row{grid-template-columns:30px minmax(0,1fr) 58px}.opp-scout-actions{padding-left:8px;padding-right:8px}}
/* 로딩 스피너(도전 버튼·랭킹) — 데이터 로드 전 COMING SOON 오표기 방지 */
/* `.rank-spin` 은 공용 순위 부품(cube/util/rank_list.js)이 쓰는 중립 이름이다 —
   `opp`(opponent)은 배틀 네임스페이스라 다른 화면이 쓰면 이름이 거짓말이 된다. */
.opp-spin,.rank-spin{display:inline-block;width:10px;height:10px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:opp-spin .7s linear infinite;vertical-align:-1px}
@keyframes opp-spin{to{transform:rotate(360deg)}}
.rank-loading{display:flex;align-items:center;justify-content:center;gap:8px;padding:22px;color:var(--muted);font:700 10px "Galmuri9","Galmuri11",sans-serif;list-style:none}
/* 대전 결과 카드 */
.battle-result-card{text-align:center}
.result-verdict{font:700 15px "Galmuri14","Galmuri11",sans-serif;margin:6px 0}
.result-win .result-verdict{color:var(--gold)}
.result-loss .result-verdict{color:#e08a8a}
.result-draw .result-verdict{color:#b7abbc}
.result-opponent{display:inline-block;margin:0 0 7px;padding:4px 7px;border:1px solid #527b74;background:rgba(65,133,122,.16);color:#b7efe0;font:700 10px "Galmuri9","Galmuri11",sans-serif}
.result-rating{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#c7bcd0;margin-bottom:10px}
/* 두 팀(각 3마리)을 세로로 쌓아 모달 폭을 넘지 않게(가로 나열 시 넘침 → 펫이 카드 밖으로 삐져나옴) */
.result-teams{display:flex;flex-direction:column;align-items:center;gap:8px;margin:8px 0}
.result-team{display:flex;flex-direction:column;align-items:center;gap:4px}
.result-team-label{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#9a8fa3}
.battle-result-card .opp-pets{margin:2px 0}
/* 편성 세트효과 발동 배지 */
.result-set-badges{display:flex;flex-wrap:wrap;justify-content:center;gap:4px;margin-top:2px;max-width:100%}
.set-badge{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#ffe7a6;background:rgba(141,99,214,.22);border:1px solid rgba(141,99,214,.5);border-radius:6px;padding:2px 6px;white-space:nowrap}
/* 속성 아이콘 배지(펫 카드·슬롯·상대 셀 공용) — SVG 글리프(속성색 currentColor) + 색상 링 */
.elem-badge{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;line-height:0;width:20px;height:20px;border-radius:50%;color:var(--elem-c,#8a8a8a);background:rgba(26,19,14,.78);border:1.5px solid var(--elem-c,#8a8a8a);box-shadow:0 0 6px var(--elem-c,#8a8a8a)}
.elem-svg{width:76%;height:76%;display:block}
.elem-sm{width:19px;height:19px}
.elem-fire{--elem-c:#ff7a3c}.elem-ice{--elem-c:#6fd8ff}.elem-storm{--elem-c:#ffd23c}.elem-water{--elem-c:#4aa3ff}
.elem-void{--elem-c:#c07de0}.elem-light{--elem-c:#ffe27a}.elem-nature{--elem-c:#6fd66a}.elem-earth{--elem-c:#d0a566}.elem-beast{--elem-c:#b0b0b0}.elem-metal{--elem-c:#8b98a8}.elem-wind{--elem-c:#2dd4bf}
.slot-tile{position:relative}
.opp-pet{position:relative}
.opp-pet-elem{position:absolute;top:-5px;right:-5px;z-index:3}
/* 편성 세트 미리보기 + 상대 세트 배지 */
.formation-set-preview{display:flex;flex-wrap:wrap;justify-content:center;gap:4px;margin-top:6px;min-height:16px}
.formation-set-badges{display:flex;flex-wrap:wrap;justify-content:center;gap:4px}
.formation-set-none{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#8d7c63}
.opp-set-badges{display:flex;flex-wrap:wrap;justify-content:center;gap:4px;margin:6px 0 2px}
/* VS 를 카드 폭 전체에 걸친 구분선으로 */
.result-vs{font:700 12px "Galmuri11","Galmuri9",sans-serif;color:#8f63d6;letter-spacing:1px}
.battle-result-card .result-vs{display:flex;align-items:center;gap:10px;align-self:stretch}
.battle-result-card .result-vs::before,.battle-result-card .result-vs::after{content:"";flex:1;height:2px;background:var(--line);opacity:.55}
.result-meta{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#8d8292;margin-top:8px}
/* PvP 3D 리플레이 컨트롤(배틀 패널 위 오버레이) */
.pvp-replay-controls{position:absolute;left:50%;bottom:calc(14px + env(safe-area-inset-bottom));width:max-content;max-width:calc(100% - 20px);transform:translateX(-50%);display:flex;flex-wrap:nowrap;align-items:center;justify-content:center;gap:10px;white-space:nowrap;z-index:40;background:rgba(26,19,14,.74);border:2px solid #6d3ad6;border-radius:9px;padding:6px 12px}
.pvp-replay-tag{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#f6eee1;letter-spacing:.02em}
.pvp-weather-tag{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#bfe3ff;background:rgba(60,120,180,.28);border:1px solid rgba(120,180,230,.5);border-radius:6px;padding:3px 8px}
.pvp-replay-skip{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#fff;background:#6d3ad6;border:none;border-radius:6px;padding:6px 11px;cursor:pointer}
.pvp-replay-skip:hover{background:#7d47e6}
@media(max-width:360px){.battle-podium{height:172px}.battle-hub-summary{flex-wrap:wrap}.battle-stat b{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}.battle-section-head{align-items:flex-start}.battle-candidate-row{grid-template-columns:auto minmax(0,1fr)}.candidate-score{grid-column:2;text-align:left}.battle-activity-row{grid-template-columns:42px minmax(0,1fr)}.activity-result{grid-column:2;text-align:left}}
@media(max-width:360px){.battle-activity-modal{padding:calc(8px + env(safe-area-inset-top)) calc(8px + env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom)) calc(8px + env(safe-area-inset-left))}.battle-activity-dialog-head{padding:11px}.battle-activity-dialog-body{padding:8px}.battle-activity-open{padding-left:9px;padding-right:9px}}

/* 이번 시즌 보상 — 3D 쇼케이스 + 티어 리스트 */
.season-rewards{margin-top:14px;padding-top:12px;border-top:2px solid var(--line)}
.season-head{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}
.season-title .eyebrow{color:var(--muted);letter-spacing:.06em}
.season-title h3{margin:2px 0 0;color:var(--gold);font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:210px}
.season-meta{display:flex;flex-direction:column;align-items:flex-end;gap:3px;text-align:right;flex:0 0 auto}
.season-status{padding:2px 7px;border:1px solid var(--line);font:700 10px "Galmuri9","Galmuri11",sans-serif;letter-spacing:.04em;color:var(--muted)}
.season-status.status-active{border-color:#3ec78d;color:#3ec78d}
.season-status.status-draft{border-color:var(--muted);color:var(--muted)}
.season-status.status-ended{border-color:var(--gold);color:var(--gold)}
.season-status.status-distributed{border-color:var(--rare);color:var(--rare)}
.season-countdown{color:#eeddc4;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
/* 트랙 B — 이번 시즌 출전 등급. 제한이 없는 시즌에는 아예 숨긴다(mode-hidden). */
.season-rarity-gate{color:#ffd8a8;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;border:1px solid rgba(255,190,110,.45);border-radius:6px;padding:1px 5px;white-space:nowrap}
.season-showcase{position:relative;height:220px;margin-top:8px;border:2px solid var(--line);background:#241a13;overflow:hidden;box-shadow:0 0 14px rgba(255,120,220,.30),0 0 28px rgba(124,245,255,.18)}
/* 썸네일 렌더러가 아직 로드되지 않았거나(콜드 로드) 초상 렌더에 실패했을 때 펫 그림 대신 들어가는
   자리지킴 — .reward-slot-figure 안. 보상 펫이 없는 티어는 애초에 슬롯에 오지 않는다. */
.reward-showcase-trophy{font-size:72px;line-height:1;filter:drop-shadow(0 0 12px rgba(255,210,122,.6))}
.season-tier-list{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-direction:column;gap:5px}
/* 얼굴 칸은 내용 폭 — 보상 펫이 여러 종이면 그만큼 가로로 늘어난다(고정 폭이면 2번째부터 잘린다). */
.season-tier-row{display:grid;grid-template-columns:auto max-content minmax(0,1fr);align-items:center;gap:9px;padding:6px 8px;border:2px solid var(--line);background:var(--panel2)}
.season-tier-row.pet-rarity-legendary{border-color:var(--leg)}
.season-tier-row.pet-rarity-epic{border-color:var(--epic)}
.season-tier-row.pet-rarity-rare{border-color:var(--rare)}
.season-tier-row.pet-rarity-uncommon{border-color:var(--unc)}
.season-tier-rank{color:var(--gold);font:700 10px "Galmuri9","Galmuri11",sans-serif;white-space:nowrap}
.season-tier-figure{display:flex;align-items:center;gap:3px;height:40px}
/* 종이 늘어날수록 얼굴을 줄여 한 줄에 담는다(줄바꿈 금지 — 넘치면 잘려 보인다). */
.season-tier-figure[data-count="3"] .pet-portrait{width:32px;height:32px}
.season-tier-figure[data-count="4"] .pet-portrait,.season-tier-figure[data-count="5"] .pet-portrait{width:26px;height:26px}
/* 시즌 보상 티어 얼굴 — 알록달록 배경(보상 펫 강조). 종별 커스텀 배경(인라인)·이벤트가 있으면 그쪽 우선. */
.season-tier-figure .pet-portrait{width:40px;height:40px;border:1px solid var(--line);background:linear-gradient(135deg,#ff8ac4,#ffd98a,#8af0c0,#8ad4ff,#c0a3ff)}
.season-tier-blank{display:grid;place-items:center;width:40px;height:40px;background:var(--panel);border:1px solid var(--line);font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}
.season-tier-reward{display:flex;align-items:center;justify-content:space-between;gap:8px;min-width:0}
.season-tier-pet{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.season-tier-points{color:var(--gold);font:700 10px "Galmuri9","Galmuri11",sans-serif;white-space:nowrap}
.season-tier-none{color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.season-tier-empty{padding:14px;text-align:center;color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.season-claim{margin-top:9px;padding:9px;border:2px solid #8b6ed8;background:linear-gradient(135deg,rgba(92,49,139,.35),rgba(36,26,19,.96));display:flex;align-items:center;justify-content:space-between;gap:10px}
.season-claim>div{display:flex;min-width:0;flex-direction:column;gap:4px}
.season-claim span{color:#ebd8bc;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.season-claim strong{color:#fff3bd;font:700 10px "Galmuri9","Galmuri11",sans-serif;line-height:1.5}
.season-claim button{flex:0 0 auto;border:1px solid #ffd166;background:#f0b94a;color:#2e2117;padding:7px 10px;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;box-shadow:0 0 10px rgba(255,209,102,.25)}
.season-claim button:hover:not(:disabled){filter:brightness(1.1);transform:translateY(-1px)}
.season-claim button:disabled{border-color:var(--line);background:var(--panel);color:var(--muted);cursor:not-allowed;box-shadow:none}
.season-claim.claimed{border-color:#4fc99a;background:rgba(34,121,90,.2)}
/* 시즌 미설정 → 예시(피카츄) 미리보기 상태를 명확히 구분 */
.season-preview .season-showcase{border-style:dashed}
.season-preview .season-tier-empty{opacity:.85}

/* ===== 시즌 보상 쇼케이스: 무지개 홀로그램 시상식 ===== */
/* 홀로그램 배경 — background-position(매 프레임 재페인트) 대신 오버사이즈 레이어를 transform 이동(GPU 합성). 부모 overflow:hidden 이 클립. */
.season-showcase::before{content:'';position:absolute;top:-50%;left:-50%;width:200%;height:200%;background:linear-gradient(125deg,#ff5db1,#ffd166,#6ee7a8,#7cf5ff,#a78bfa,#ff5db1);opacity:.85;will-change:transform;animation:rewardHolo 9s ease-in-out infinite alternate}
.reward-stage{position:absolute;inset:0;background:radial-gradient(circle at 50% 42%,rgba(19,14,10,0) 24%,rgba(19,14,10,.58) 100%)}
.reward-stage-rays{position:absolute;left:50%;top:44%;width:620px;height:620px;transform:translate(-50%,-50%);background:repeating-conic-gradient(rgba(255,255,255,0) 0 9deg,rgba(255,255,255,.11) 9deg 18deg);-webkit-mask:radial-gradient(circle,#000 0 34%,transparent 66%);mask:radial-gradient(circle,#000 0 34%,transparent 66%);will-change:transform;animation:rewardRays 26s linear infinite}
.reward-stage-confetti{position:absolute;inset:0;pointer-events:none}
.reward-stage-confetti i{position:absolute;top:-24px;width:var(--s);height:calc(var(--s)*.55);background:var(--c);border-radius:1px;box-shadow:0 0 6px var(--c);will-change:transform;animation:rewardConfetti var(--dur) linear var(--delay) infinite}
.reward-stage-confetti i:nth-child(3n){border-radius:50%;height:var(--s)}
.reward-stage-confetti i:nth-child(2n){opacity:.8}
/* 보상 펫 라인업 — 순위 순으로 왼쪽부터 **모두 같은 크기**로 세운다.
   슬롯 폭은 `flex:1 1 0` 이 남은 폭을 균등 분배해 정하므로(상한 160px = 1마리일 때의 기존 크기),
   보상 펫이 3마리든 5마리든 CSS 를 고치지 않아도 자동으로 줄어들며 들어간다.
   순위 뱃지·단상은 두지 않는다 — 바로 아래 '순위별 보상' 목록이 같은 정보를 이미 보여준다. */
.reward-lineup{position:absolute;left:8px;right:8px;top:47%;transform:translateY(-50%);display:flex;align-items:center;justify-content:center;gap:var(--reward-gap,10px)}
/* 단상은 없앴지만 시상식 문구는 남긴다(도형 없이 하단 캡션으로).
   펫 이름과 같은 무지개 흐름(rewardName)을 입혀 기존 연출 톤을 유지한다. */
/* 폭을 글자에 맞춘다 — left:0/right:0 으로 넓게 깔면 그라디언트(요소 폭의 2배)가 가운데 글자
   위를 거의 지나가지 않아 색이 멈춘 것처럼 보인다(펫 이름은 슬롯 폭이라 글자가 요소를 채운다). */
.reward-stage-caption{position:absolute;left:50%;bottom:7px;transform:translateX(-50%);white-space:nowrap;font:700 10px "Galmuri9","Galmuri11",sans-serif;letter-spacing:.14em;background:linear-gradient(90deg,#ff5db1,#ffd166,#6ee7a8,#7cf5ff,#a78bfa,#ff5db1);background-size:200% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:rewardName 3s linear infinite;filter:drop-shadow(0 1px 2px rgba(25,18,13,.95)) drop-shadow(0 0 6px rgba(255,200,120,.4))}
.reward-lineup[data-count="4"],.reward-lineup[data-count="5"]{--reward-gap:6px}
.reward-slot{position:relative;display:flex;flex-direction:column;align-items:center;flex:1 1 0;min-width:0;max-width:160px}
/* 정사각 비율 — 슬롯 폭이 곧 펫 크기가 된다(마리 수에 따라 자동 축소). */
.reward-slot-figure{width:100%;aspect-ratio:1;display:grid;place-items:center;will-change:transform;animation:rewardFloat 3.4s ease-in-out calc(var(--i,0) * .45s) infinite alternate}
.reward-slot-figure .pet-portrait{width:100%;height:100%;filter:drop-shadow(0 6px 10px rgba(13,9,6,.7)) drop-shadow(0 0 12px rgba(255,255,255,.35))}
.reward-slot-name{max-width:100%;margin-top:-2px;text-align:center;padding:0 2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font:700 12px "Galmuri11","Galmuri9",sans-serif;background:linear-gradient(90deg,#ff5db1,#ffd166,#6ee7a8,#7cf5ff,#a78bfa,#ff5db1);background-size:200% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:rewardName 3s linear infinite;filter:drop-shadow(0 1px 2px rgba(0,0,0,.9)) drop-shadow(0 0 4px rgba(0,0,0,.75))}
.reward-lineup[data-count="4"] .reward-slot-name,.reward-lineup[data-count="5"] .reward-slot-name{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.season-tier-row:first-child{background:linear-gradient(90deg,rgba(255,93,177,.16),rgba(255,209,102,.13),rgba(124,245,255,.16));box-shadow:0 0 10px rgba(255,170,235,.16)}
@keyframes rewardHolo{from{transform:translate3d(-12%,-12%,0)}to{transform:translate3d(12%,12%,0)}}
@keyframes rewardRays{to{transform:translate(-50%,-50%) rotate(360deg)}}
@keyframes rewardConfetti{0%{transform:translate(0,0) rotate(0)}100%{transform:translate(var(--drift),250px) rotate(660deg)}}
@keyframes rewardFloat{from{transform:translateY(0)}to{transform:translateY(-6px)}}
@keyframes rewardName{to{background-position:200% 0}}
/* 감속 모드 완화 버전 — 정지가 아니라 '약하게'.
   Windows '애니메이션 표시'(SPI_GETCLIENTAREAANIMATION)를 끈 PC 는 브라우저가 항상
   prefers-reduced-motion:reduce 를 보고한다. 사내 PC 다수가 이 상태라, 여기서 쇼케이스를
   통째로 animation:none 하면 시상식 연출이 전부 얼어붙는다(제보 2026-08-03 — 배경·펫 이름·
   하단 캡션이 안 움직인다). 그래서 위치가 움직이는 연출만 느리고 작게 완화하고,
   자리를 옮기지 않는 무지개 마퀴(rewardName: background-position 만 흐름)는 그대로 재생한다. */
@keyframes rewardHoloCalm{from{transform:translate3d(-5%,-5%,0)}to{transform:translate3d(5%,5%,0)}}
@keyframes rewardFloatCalm{from{transform:translateY(0)}to{transform:translateY(-2px)}}
@media (prefers-reduced-motion:reduce){
  .season-showcase::before{animation-name:rewardHoloCalm;animation-duration:22s}
  .reward-stage-rays{animation-duration:72s;opacity:.6}
  .reward-stage-confetti i{animation-duration:calc(var(--dur) * 1.9)}
  .reward-slot-figure{animation-name:rewardFloatCalm;animation-duration:5.2s}
}
@media(max-width:360px){.season-showcase{height:186px}.season-title h3{max-width:150px}.reward-lineup{--reward-gap:6px}.reward-slot{max-width:132px}.reward-slot-name{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}}

/* ===== 2026-07-17 원탭 편성 개편 — 슬롯 보드 + 편성 모드 도크 + 카드 배지 =====
   펫 카드마다 흩어져 있던 [팀 편성]/[⚔ 배틀] 버튼을 없애고,
   도크에서 모드를 고르면 카드 전체가 그 모드의 토글 버튼이 된다(원탭 편성). */
/* 슬롯 보드: 전투 팀(3)/배틀 대표팀(3)을 고정 칸으로 항상 노출. 빈 칸을 누르면 그 편성 모드가 열린다. */
.roster-lanes{display:grid;grid-template-columns:1fr;gap:8px;margin-top:10px}
.roster-lane{min-width:0;padding:8px;border:2px solid var(--line);background:var(--panel2);box-shadow:inset -2px -2px 0 rgba(0,0,0,.25),inset 2px 2px 0 rgba(255,255,255,.04)}
.roster-lane.party-lane{border-left:4px solid var(--unc)}
.roster-lane.battle-lane{border-left:4px solid var(--gold)}
.roster-lane-title{display:flex;align-items:center;justify-content:space-between;gap:6px;margin-bottom:7px}
.roster-lane-title strong{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:var(--ink);white-space:nowrap}
.roster-lane-title span{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:var(--muted)}
.roster-lane-actions{display:flex;gap:4px;flex:none}
.roster-lane-actions button{min-height:30px;padding:4px 9px;border:2px solid var(--line);background:#3f805c;color:#e7fff0;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;touch-action:manipulation}
.roster-lane-actions button.danger{background:#7c4038;color:#ffe3dc}
.roster-lane-actions button:disabled{opacity:.45;cursor:not-allowed}
.roster-lane-actions button.hidden{display:none}  /* 등록 완료(변경 없음)면 '대표팀 등록' 숨김 */
/* '대표팀 등록'이 눌러야 할 다음 동작일 때 — 공통 전광판 링(.mq-ring)을 배틀색으로 두른다.
   예전엔 버튼 배경에 직접 점선을 깔았는데 골드 배경과 겹쳐 지저분했다. */
.roster-lane-actions button.needs-register{color:#2a1d0c;background-color:var(--gold)}
@keyframes ctaGlow{0%,100%{box-shadow:0 0 4px var(--gold)}50%{box-shadow:0 0 13px var(--gold),0 0 5px #fff7dd}}
.battle-team-state{padding:3px 6px;border:2px solid var(--line);background:var(--panel);color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-weight:700;white-space:nowrap}
.battle-team-state.ok{color:#173b2a;background:var(--unc)}
.battle-team-state.dirty{color:#2a1d0c;background:var(--gold);animation:battleStatePulse 1.6s ease-in-out infinite}
@keyframes battleStatePulse{0%,100%{box-shadow:none}50%{box-shadow:0 0 8px var(--gold)}}
.roster-slot{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}
.slot-tile{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:3px;min-width:0;min-height:88px;padding:8px 4px 6px;border:2px solid var(--line);background:var(--panel);text-align:center}
.slot-tile.filled.party{box-shadow:inset 0 3px 0 rgba(95,211,138,.4)}
.slot-tile.filled.battle{box-shadow:inset 0 3px 0 rgba(242,193,78,.45)}
.slot-tile b{display:flex;align-items:center;justify-content:center;gap:3px;width:100%;color:var(--ink);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-weight:700;line-height:1.3}
.slot-name-txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.slot-tile small{display:block;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.3}
.slot-face{display:block;line-height:0}
.slot-order{position:absolute;top:-2px;left:-2px;z-index:2;display:grid;place-items:center;width:16px;height:16px;background:var(--unc);color:#173b2a;border:2px solid var(--line);font:700 10px "Galmuri9","Galmuri11",sans-serif;font-style:normal}
.slot-x{position:absolute;top:-2px;right:-2px;z-index:3;display:grid;place-items:center;width:22px;height:22px;padding:0;border:2px solid var(--line);background:#7c4038;color:#ffe3dc;font:700 10px/1 "Galmuri9","Galmuri11",sans-serif;cursor:pointer;touch-action:manipulation}
.slot-x:hover{background:#96504a}
.slot-tile.empty{justify-content:center;border-style:dashed;border-color:var(--dirt);background:transparent;color:var(--muted);cursor:pointer;font-size:20px;font-family:"Galmuri11","Galmuri9",sans-serif;line-height:1}
.slot-tile.empty:hover,.slot-tile.empty:focus-visible{border-color:var(--gold);color:var(--gold);outline:none}
/* 빈 슬롯의 '펫 선택 중' 강조는 공통 전광판 링(.mq-ring)이 담당한다 —
   파일 하단 '공통 전광판 링' 섹션 참고. 예전의 4변 점선(slotMarch)은 픽셀이 깨져 보이고
   레인마다 구현이 따로 놀아서 폐기했다. */
/* 편성 모드 도크(.assign-dock)는 2026-07-28 편성 보드 개편에서 없어졌다 —
   지금은 파일 하단 '편성 보드 재편' 섹션의 .formation-board / .fb-tabs 가 그 역할을 한다. */
/* 펫 목록 정렬 바 — 모드 안내 문구가 있던 자리(펫 목록 바로 위).
   기준이 7개라 좁은 화면에서는 줄바꿈 대신 가로 스크롤로 흘린다(스크롤바는 숨김 — 픽셀 UI 를 깬다). */
.pet-sort-bar{display:flex;align-items:center;gap:7px;margin:8px 2px 0}
/* ⚠️ 전역 `.hidden` 규칙이 없는 저장소다 — display 를 주는 요소는 숨김도 직접 준다.
   (방치 화면은 펫이 하나도 없으면 이 바를 감춘다.) */
.pet-sort-bar.hidden{display:none}
.pet-sort-label{flex:none;color:var(--muted);}
.pet-sort-btns{display:flex;gap:4px;min-width:0;overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}
.pet-sort-btns::-webkit-scrollbar{display:none}
.pet-sort-btns button{flex:none;min-height:28px;padding:4px 9px;border:2px solid var(--line);background:#35281f;color:#b6a894;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;touch-action:manipulation}
.pet-sort-btns button:hover{background:#413126;color:#e6d7c0}
.pet-sort-btns button.active{background:#70533f;border-color:#aa906a;color:#fff6df;box-shadow:inset 0 2px 0 #9b815b4d}
/* 카드 배지 — 어느 편성에 들어가 있는지를 카드 안에서 바로 보여준다.
   칩 본체(.pb / .pb-*)는 2026-07-28 아이콘화 때 파일 하단 '배치 라벨' 섹션으로 옮겼다. */
.pet-badges{display:flex;justify-content:center;width:100%}
/* 카드 우상단 ⓘ — 편성 모드 중에도 상세 정보로 가는 고정 통로 */
.dungeon-pet-card.ineligible{opacity:.55;filter:saturate(.6)}
/* 모드 활성 중 호버 — 카드 전체가 눌리는 버튼임을 레인 색으로 예고 */
.dungeon-pets[data-mode="party"] .dungeon-pet-card:not(.ineligible):hover{border-color:var(--unc)}
.dungeon-pets[data-mode="battle"] .dungeon-pet-card:hover{border-color:var(--gold)}
@media(max-width:360px){
  .roster-slot{gap:4px}
  .slot-tile{min-height:80px}
  .slot-face .pet-portrait{width:38px;height:38px}
  .roster-lane-actions button{padding:4px 6px}
}
@media(prefers-reduced-motion:reduce){.battle-team-state.dirty{animation:none}.roster-lane-actions button.needs-register{animation:none;border-color:#fff7dd;box-shadow:0 0 8px var(--gold)}}

/* ===== 던전 CTA 히어로 버튼 — '선택 스테이지 출전' / '배틀 허브' (2026-07-17) =====
   두 핵심 액션이 밋밋해 한눈에 안 들어오던 문제 개편. 픽셀 테마는 유지하되 네 가지 모션 어휘로
   시선을 잡는다: ① 대각선 광택 스윕(통과 후 한 사이클 쉼) ② 숨쉬는 오라 글로우(금색/진홍 위상 반대)
   ③ 살아있는 아이콘(⛏ 스윙 · ⚔ 진동) ④ 눌리는 픽셀 베벨. 전역 .cube-action 규칙(idle 테마 싱크·배틀
   허브 섹션) 뒤에 위치해 배경/베벨을 이긴다. 진행 중(:disabled)·prefers-reduced-motion 에서는
   과한 움직임을 멈추고 정적 글로우로 정착. 스코프는 .cta-hero/.cta-gold/.cta-ember 신규 클래스 전용. */
.dungeon-actions{gap:9px;margin-top:11px}
/* overflow 는 visible — 광택 스윕(::after)은 background 라 자기 박스를 넘지 않으므로 클립이 불필요하고,
   hidden 이면 버튼 모서리에 걸친 알림 배지(.battle-inbox-badge)가 잘려 숫자가 안 보인다. */
.cube-action.cta-hero{position:relative;isolation:isolate;overflow:visible;display:flex;align-items:center;justify-content:center;gap:8px;min-height:54px;padding:11px 10px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;line-height:1;}
.cta-hero .cta-icon{position:relative;z-index:2;display:inline-block;font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif;line-height:1;transform-origin:60% 80%;filter:drop-shadow(0 1px 0 rgba(0,0,0,.28))}
.cta-hero .cta-label{position:relative;z-index:2}

/* 광택 스윕 한 벌(2026-09-26) — 시작 단추(.cta-hero) · 던전 칸(.dtab-hero) · 방치 칸(.idle-subnav .tab)이 같은 빛줄기다.
   대각선 하이라이트가 지나간 뒤 한 사이클 쉬어 과하지 않게. text/icon 아래(z-index:1). 세 벌이 글자까지 같고
   밝기(--sheen-lo · --sheen-hi)와 주기(--sheen-dur)만 달랐다 — 그 셋만 각 칸 규칙에 둔다(기본값 = 던전 칸). */
.cta-hero::after,.dtab-hero::after,.idle-subnav .tab::after{content:"";position:absolute;z-index:1;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 34%,rgba(255,255,255,var(--sheen-lo,.1)) 43%,rgba(255,255,255,var(--sheen-hi,.48)) 50%,rgba(255,255,255,var(--sheen-lo,.1)) 57%,transparent 66%);
  background-size:250% 100%;background-repeat:no-repeat;background-position:-140% 0;
  animation:dtabSheen var(--sheen-dur,4.8s) cubic-bezier(.4,0,.2,1) infinite}
.cta-hero{--sheen-lo:.16;--sheen-hi:.62;--sheen-dur:4.6s}

/* 금색 출전(주인공) — 몰튼 골드가 천천히 흐르는 그라디언트 + 금빛 숨쉬는 오라 + ⛏ 스윙.
   오라는 filter(overflow 밖으로 번짐), 몰튼 드리프트는 background-position(스윕과 별개 축)로 표현. */
.cube-action.cta-gold{
  background-size:155% 155%;background-position:20% 50%;}
.cta-gold .cta-icon{animation:ctaPickSwing 2.6s ease-in-out infinite}
@keyframes ctaAuraGold{0%,100%{filter:drop-shadow(0 0 1px rgba(255,208,92,.25))}50%{filter:drop-shadow(0 0 8px rgba(255,206,80,.8))}}
@keyframes ctaGoldFlow{0%,100%{background-position:20% 50%}50%{background-position:80% 50%}}
@keyframes ctaPickSwing{0%,58%,100%{transform:rotate(0) translateY(0)}68%{transform:rotate(-16deg) translateY(-1px)}80%{transform:rotate(9deg)}90%{transform:rotate(-4deg)}}

/* 진홍 배틀 허브 — 잉걸불 그라디언트 + 진홍 오라(금색과 위상 반대: -1.3s 지연) + ⚔ 진동. */
.cube-action.cta-ember{background:linear-gradient(150deg,#b23350 0%,#8f2b45 46%,#7c2740 62%,#a5304e 100%);color:#fff1f3;
  box-shadow:inset -3px -3px 0 #5a2131,inset 3px 3px 0 rgba(255,255,255,.22);
  animation:ctaAuraEmber 2.6s ease-in-out infinite;animation-delay:-1.3s}
.cta-ember .cta-icon{animation:ctaSwordShiver 3.2s ease-in-out infinite}
@keyframes ctaAuraEmber{0%,100%{filter:drop-shadow(0 0 1px rgba(255,96,124,.2))}50%{filter:drop-shadow(0 0 9px rgba(255,72,104,.72))}}
@keyframes ctaSwordShiver{0%,84%,100%{transform:rotate(0) scale(1)}88%{transform:rotate(-8deg) scale(1.1)}92%{transform:rotate(8deg)}96%{transform:rotate(-4deg)}}

/* Hover(데스크톱 살짝 들림) · 포커스(고대비 아웃라인) · 눌림(픽셀 베벨 반전) · 진행 중 정지. */
.cube-action.cta-hero:hover{transform:translateY(-1px)}
.cta-hero:focus-visible{outline:3px solid #fff7df;outline-offset:2px}
.cube-action.cta-hero:active{transform:translate(2px,2px)}
.cube-action.cta-ember:active{box-shadow:inset 3px 3px 0 #5a2131,inset -2px -2px 0 rgba(255,255,255,.16)}
.cube-action.cta-hero:disabled{animation:none;cursor:not-allowed;opacity:.92}
.cta-hero:disabled::after{animation:none;opacity:0}
.cta-hero:disabled .cta-icon{animation:none}
@media(max-width:360px){.cube-action.cta-hero{min-height:50px;gap:6px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;padding:9px 7px}.cta-hero .cta-icon{font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}}
@media(prefers-reduced-motion:reduce){
  .cta-hero::after{animation:none;opacity:.4;background-position:58% 0}
  .cta-gold .cta-icon,.cta-ember .cta-icon{animation:none}
  .cube-action.cta-gold{animation:none;filter:drop-shadow(0 0 5px rgba(255,206,80,.55))}
  .cube-action.cta-ember{animation:none;filter:drop-shadow(0 0 5px rgba(255,80,110,.5))}
}

/* ===== 모드별 2층 하단 탭 — 방치 3개 / 던전 3개 공통 프레임 ===== */
.context-subnav{position:fixed;z-index:69;left:var(--mode-nav-left,50%);width:var(--mode-nav-width,calc(min(100vw,460px) - 24px));height:var(--subnav-height);box-sizing:border-box;transform:translateX(var(--mode-nav-shift,-50%));display:none;gap:0;margin:0;padding:0;background:#1d150f;border:3px solid #08060a;border-bottom:0;box-shadow:0 -4px 0 rgba(0,0,0,.24)}
.idle-subnav.tabs{bottom:env(safe-area-inset-bottom);grid-template-columns:repeat(3,minmax(0,1fr))}body.game-mode-authorized .idle-subnav.tabs{bottom:calc(var(--mode-nav-height) + env(safe-area-inset-bottom))}body.game-ready.idle-open .idle-subnav.tabs{display:grid}
.dungeon-tabs.dungeon-subnav{bottom:calc(var(--mode-nav-height) + env(safe-area-inset-bottom));grid-template-columns:repeat(4,minmax(0,1fr))}body.dungeon-authorized.dungeon-open .dungeon-tabs.dungeon-subnav{display:grid}
/* 미니게임은 **상시 노출**이라 기본 4칸이다(2026-09-02 — 그전에는 타임어택이 선택 탭이라
   기본이 3칸이었다). 부족만 운영이 켤 때 뜨고, 그때 5칸이 된다. 열 수를 함께 늘리지 않으면
   늘어난 버튼이 다음 줄로 접힌다(하단 내비는 높이가 고정이라 접힌 줄이 화면 밖으로 나간다).
   ⚠ 숨김은 반드시 `:not()` 으로 건다. 클래스 하나짜리 선택자로 쓰면
   뒤에 오는 `.dtab.dtab-hero{display:flex}`(671행)와 특정성이 같아 **나중 규칙이 이겨**
   꺼져 있어도 탭이 계속 보인다(2026-08-16 실제 발생).
   `body:not(...)` 는 클래스 하나만큼 특정성이 높아 순서에 기대지 않는다. */
body:not(.guild-open) .dungeon-subnav .dtab.dtab-guild{display:none}
body.guild-open .dungeon-tabs.dungeon-subnav{grid-template-columns:repeat(5,minmax(0,1fr))}
/* 미니게임 화면 끄기 — **운영자가 정한 경우에만** 탭이 사라진다.
   "이번 주 곡이 없다"로는 절대 숨기지 않는다(2026-09-02: 숨겼더니 "기능이 없어졌다"는
   신고를 받았다). 이건 자동 판단이 아니라 사람의 결정이라 오해가 생기지 않는다.
   열 수도 함께 줄인다 — 안 줄이면 하단 탭에 빈 칸이 하나 남는다. */
body.minigame-off .dungeon-subnav .dtab.dtab-minigame{display:none}
body.minigame-off .dungeon-tabs.dungeon-subnav{grid-template-columns:repeat(3,minmax(0,1fr))}
body.minigame-off.guild-open .dungeon-tabs.dungeon-subnav{grid-template-columns:repeat(4,minmax(0,1fr))}
.dtab.dtab-guild{background:linear-gradient(145deg,#5c3f22 0%,#8a6231 43%,#c99a52 55%,#714c28 100%);box-shadow:inset -3px -3px 0 #46301a,inset 3px 3px 0 rgba(255,238,205,.26)}
.dtab.dtab-minigame{background:linear-gradient(145deg,#1f4f63 0%,#2f7794 43%,#57b3d3 55%,#265f79 100%);box-shadow:inset -3px -3px 0 #173d4d,inset 3px 3px 0 rgba(214,244,255,.26)}

.dtab.dtab-hero{position:relative;isolation:isolate;overflow:hidden;display:flex;align-items:center;justify-content:center;gap:8px;min-height:50px;padding:10px;border:3px solid var(--line);font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;font-weight:700;letter-spacing:.35px;line-height:1;color:#fff;box-shadow:inset -3px -3px 0 rgba(0,0,0,.32),inset 3px 3px 0 rgba(255,255,255,.2);text-shadow:0 1px 0 rgba(0,0,0,.3);transform:translateY(0)}
/* 던전 하위 탭은 어떤 탭 수·브라우저에서도 아이콘 위, 라벨 아래의 한 줄 구조를 유지한다.
   Edge는 폭이 촘촘할 때 기본 가로 flex 배치를 유지해 '자동 훈련'을 두 줄로 분리했으므로,
   축과 줄바꿈 정책을 명시적으로 고정한다. */
.dungeon-subnav .dtab.dtab-hero{min-width:0;min-height:0;height:100%;flex:1 1 0;flex-flow:column nowrap;gap:2px;padding:6px 2px;border:0;border-right:2px solid #08060a;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;letter-spacing:0}.dungeon-subnav .dtab.dtab-hero:last-child{border-right:0}
.dtab-hero .dtab-icon,.dtab-hero .dtab-label{position:relative;z-index:2}.dtab-hero .dtab-icon{display:inline-block;font-size:17px;font-family:"Galmuri11","Galmuri9",sans-serif;line-height:1;transform-origin:50% 65%;filter:drop-shadow(0 1px 0 rgba(0,0,0,.3))}
.dungeon-subnav .dtab-hero .dtab-icon{display:block;flex:0 0 auto;font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}
.dungeon-subnav .dtab-hero .dtab-label{display:block;flex:0 0 auto;white-space:nowrap;word-break:keep-all;overflow-wrap:normal;line-height:1}
.dtab.dtab-team{background:linear-gradient(145deg,#285d4c 0%,#3c8067 43%,#65b891 55%,#2f715a 100%);box-shadow:inset -3px -3px 0 #1d493b,inset 3px 3px 0 rgba(210,255,235,.28);animation:dtabAuraTeam 2.8s ease-in-out infinite}.dtab.dtab-auto{background:linear-gradient(145deg,#7c3f2d 0%,#b96036 43%,#ef9d4e 55%,#a64d2e 100%);box-shadow:inset -3px -3px 0 #6d3027,inset 3px 3px 0 rgba(255,235,190,.28);animation:dtabAuraAuto 2.8s ease-in-out infinite;animation-delay:-.7s}.dtab.dtab-stones{background:linear-gradient(145deg,#71513a 0%,#5d4e9e 43%,#8172c7 55%,#4c4187 100%);box-shadow:inset -3px -3px 0 #543d2c,inset 3px 3px 0 rgba(249,243,235,.26);animation:dtabAuraStones 2.8s ease-in-out infinite;animation-delay:-1.4s}
/* 선택한 칸만 움직인다(2026-09-26) — 방치 줄(.idle-subnav)과 같은 규칙. 예전에는 편성 · 자동 훈련 · 아이템 세 칸이
   늘 빛나고(aura) 아이콘이 흔들려 **지금 어느 칸인지**가 안 보였고, 안 보는 칸까지 매 프레임 그렸다.
   빛줄기(::after)는 두 줄 모두 모든 칸에 남는다. 배틀 허브가 열려 있으면 선택 표시 자체를 걷는다(dungeon.js parkDungeonTabHighlight). */
.dungeon-subnav .dtab-hero:not(.active),.dungeon-subnav .dtab-hero:not(.active) .dtab-icon{animation:none}
.dtab-team .dtab-icon{animation:dtabShieldGuard 2.9s ease-in-out infinite}.dtab-auto .dtab-icon{animation:dtabSwordTap 1.9s ease-in-out infinite}.dtab-stones .dtab-icon{animation:dtabGemFloat 2.6s ease-in-out infinite}.dtab-hero.active{border-color:#ffe29c;color:#fffdf4;transform:translateY(-1px)}.dtab-hero:hover{transform:translateY(-2px);filter:brightness(1.08)}.dtab-hero:focus-visible{outline:3px solid #fff7df;outline-offset:2px}.dtab-hero:active{transform:translate(2px,2px)}

.idle-subnav .tab{position:relative;isolation:isolate;overflow:hidden;min-width:0;height:100%;padding:8px 3px;display:flex;align-items:center;justify-content:center;gap:4px;border:0;border-right:2px solid #08060a;color:#fff;font:700 12px "Galmuri11","Galmuri9",sans-serif;letter-spacing:.2px;line-height:1;text-shadow:0 1px 0 rgba(0,0,0,.3);box-shadow:inset -3px -3px 0 rgba(0,0,0,.3),inset 3px 3px 0 rgba(255,255,255,.18);transform:translateY(0);touch-action:manipulation}.idle-subnav .tab:last-child{border-right:0}
.idle-subnav .tab-icon,.idle-subnav .tab-label{position:relative;z-index:2}.idle-subnav .tab-icon{display:inline-block;font-size:17px;font-family:"Galmuri11","Galmuri9",sans-serif;line-height:1;transform-origin:50% 65%;filter:drop-shadow(0 1px 0 rgba(0,0,0,.3))}
.idle-subnav .tab{--sheen-lo:.08;--sheen-hi:.42;--sheen-dur:5.2s}   /* 빛줄기(::after)는 광택 스윕 한 벌(.cta-hero 절) */
.idle-subnav .idle-tab-pet{background:linear-gradient(145deg,#285d4c 0%,#3c8067 45%,#58a986 55%,#2f715a 100%)}.idle-subnav .idle-tab-item{background:linear-gradient(145deg,#71513a 0%,#5d4e9e 45%,#796abd 55%,#4c4187 100%)}.idle-subnav .idle-tab-ghub{background:linear-gradient(145deg,#876127 0%,#b98533 45%,#d7a84d 55%,#8f6728 100%)}
.idle-subnav .tab.active{color:#fffdf4;box-shadow:inset 0 3px 0 #ffe29c,inset -3px -3px 0 rgba(0,0,0,.3),inset 3px 3px 0 rgba(255,255,255,.2);filter:brightness(1.08);animation:idleTabAura 2.8s ease-in-out infinite}.idle-subnav .tab:hover{filter:brightness(1.12);transform:translateY(-1px)}.idle-subnav .tab:focus-visible{outline:3px solid #fff7df;outline-offset:-3px}.idle-subnav .tab:active{transform:translate(2px,2px)}
.idle-subnav .idle-tab-pet.active .tab-icon{animation:idlePetHop 2.8s ease-in-out infinite}.idle-subnav .idle-tab-item.active .tab-icon{animation:idleBagSway 2.7s ease-in-out infinite}.idle-subnav .idle-tab-ghub.active .tab-icon{animation:idleStarPulse 2.5s ease-in-out infinite}

@keyframes dtabSheen{0%{background-position:-140% 0}24%{background-position:170% 0}100%{background-position:170% 0}}@keyframes dtabAuraTeam{0%,100%{filter:drop-shadow(0 0 1px rgba(95,211,165,.22))}50%{filter:drop-shadow(0 0 8px rgba(95,211,165,.68))}}@keyframes dtabAuraAuto{0%,100%{filter:drop-shadow(0 0 1px rgba(255,150,82,.2))}50%{filter:drop-shadow(0 0 8px rgba(255,142,69,.66))}}@keyframes dtabAuraStones{0%,100%{filter:drop-shadow(0 0 1px rgba(176,150,255,.2))}50%{filter:drop-shadow(0 0 8px rgba(155,128,238,.65))}}
@keyframes dtabShieldGuard{0%,66%,100%{transform:rotate(0) scale(1)}76%{transform:rotate(-7deg) scale(.94)}86%{transform:rotate(4deg) scale(1.08)}93%{transform:rotate(-2deg)}}@keyframes dtabSwordTap{0%,64%,100%{transform:rotate(0) translateY(0)}72%{transform:rotate(-14deg) translateY(-1px)}82%{transform:rotate(9deg) translateY(1px)}}@keyframes dtabGemFloat{0%,100%{transform:translateY(0) rotate(0)}45%{transform:translateY(-2px) rotate(-5deg)}58%{transform:translateY(0) rotate(4deg)}72%{transform:translateY(-1px) rotate(0)}}
@keyframes idleTabAura{0%,100%{filter:brightness(1.05) drop-shadow(0 0 1px rgba(255,226,156,.25))}50%{filter:brightness(1.12) drop-shadow(0 0 7px rgba(255,226,156,.58))}}@keyframes idlePetHop{0%,68%,100%{transform:translateY(0) rotate(0)}76%{transform:translateY(-2px) rotate(-5deg)}86%{transform:translateY(0) rotate(4deg)}}@keyframes idleBagSway{0%,72%,100%{transform:rotate(0) scale(1)}80%{transform:rotate(-6deg) scale(.96)}90%{transform:rotate(5deg) scale(1.05)}}@keyframes idleStarPulse{0%,70%,100%{transform:scale(1) rotate(0)}80%{transform:scale(1.18) rotate(-10deg)}90%{transform:scale(1.04) rotate(8deg)}}

body.has-sticker .dtab-hero.active,body.has-sticker .idle-subnav .tab.active{box-shadow:inset 0 3px 0 var(--sticker),0 0 8px var(--sticker);text-shadow:0 0 7px var(--sticker)}
@media(max-width:360px){.dtab.dtab-hero{min-height:46px;gap:6px;padding:8px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}.dtab-hero .dtab-icon,.idle-subnav .tab-icon{font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}.idle-subnav .tab{gap:5px;padding:7px 4px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}}
@media(prefers-reduced-motion:reduce){
  .dtab.dtab-hero,.dtab-hero::after,.dtab-hero .dtab-icon{animation:none}
  .dtab-hero::after{opacity:.35;background-position:58% 0}
  .dtab.dtab-team{filter:drop-shadow(0 0 4px rgba(95,211,165,.5))}
  .dtab.dtab-stones{filter:drop-shadow(0 0 4px rgba(155,128,238,.48))}
  .idle-subnav .tab.active,.idle-subnav .tab::after,.idle-subnav .tab.active .tab-icon{animation:none}
  .idle-subnav .tab::after{opacity:.35;background-position:58% 0}
  .idle-subnav .tab.active{filter:brightness(1.08) drop-shadow(0 0 4px rgba(255,226,156,.5))}
}

/* ── 던전 자동 훈련: 3D 필드 사냥 ──────────────────────────────────────────
   원정 전투와 같은 렌더러/씬을 쓴다(dungeon.js `mountAutoField`). 여기서는
   캔버스를 담을 무대와 그 위에 얹는 HUD/배너만 정의한다. 화면 아래로는
   출전 펫 상세 → 성장 시뮬레이터 → 확장 예정 슬롯이 이어진다. */
.auto-training-panel{overflow:hidden}
.panel-title>strong.auto-running{background:#73d59d;color:#163e2a;animation:auto-state-pulse 1.8s ease-in-out infinite}

.auto-field{position:relative;width:100%;height:var(--auto-field-h,320px);margin-top:10px;overflow:hidden;
  border:3px solid var(--dq-line,#644a37);background:#16100c;
  box-shadow:inset 0 3px 0 rgba(255,255,255,.08),inset 0 -8px 0 rgba(0,0,0,.3)}
.auto-field-canvas,.auto-field-canvas canvas{position:absolute;inset:0;width:100%;height:100%;display:block;touch-action:none}
.auto-field-hud{position:absolute;z-index:4;left:6px;right:6px;top:6px;display:flex;align-items:center;gap:6px;pointer-events:none}
.af-tag{flex:0 0 auto;padding:3px 6px;border:2px solid #896851;background:rgba(19,14,10,.82);color:#ffd76a;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;white-space:nowrap}
.af-bar{flex:1 1 auto;height:8px;border:2px solid #896851;background:rgba(19,14,10,.72);overflow:hidden}
.af-bar>i{display:block;height:100%;width:0;background:linear-gradient(90deg,#7bd6a0,#ffd76a);transition:width .18s linear}
.af-count{flex:0 0 auto;color:#f3e7d4;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;text-shadow:1px 1px 0 #1d150f;white-space:nowrap}
.af-banner{position:absolute;z-index:6;left:50%;top:42%;padding:5px 9px;border:2px solid #ffdc62;background:#3d2a12;
  color:#fff7c9;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;white-space:nowrap;pointer-events:none;opacity:0;transform:translate(-50%,-50%) scale(.7)}
.af-banner.show{animation:af-banner 1.8s ease-out}
/* EXP 배율 뱃지(2026-09-22) — 자동 훈련 무대 **하단 가운데**. 배수권·버닝이 걸렸을 때만 서버가
   값을 주고(`autoTraining.xpMultiplier`), 화면은 그때만 글자를 채운다(빈 글자면 CSS 가 감춘다).
   생김새는 방치 채굴장의 ×N 뱃지(style.css `.mbf-badge`)와 같은 결이다 — 같은 뜻이면 같은 모양. */
/* 🔴 글자 테두리(-webkit-text-stroke)를 쓰지 않는다 — 15px 글자에 1px 테두리를 두르면 획을
   거의 다 먹어 숫자가 검붉게 뭉갠다(2026-09-22 헤드리스 확인). 대비는 배경·그림자로 낸다. */
.af-mult{position:absolute;z-index:6;left:50%;bottom:8px;transform:translateX(-50%);
  padding:3px 10px;border:2px solid #ffb703;border-radius:6px;background:rgba(19,14,10,.92);
  color:#ffe6a3;font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif;font-weight:700;letter-spacing:.02em;white-space:nowrap;pointer-events:none;
  text-shadow:0 0 9px #ff7a18,1px 1px 0 #1d150f;
  animation:afMultPulse 1.1s ease-in-out infinite}
.af-mult:empty{display:none}
.af-mult>i{font-style:normal;margin-left:6px;color:#e5d4ba;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-weight:400;letter-spacing:0;
  text-shadow:1px 1px 0 #1d150f}
@keyframes afMultPulse{0%,100%{transform:translateX(-50%) scale(1)}50%{transform:translateX(-50%) scale(1.08)}}
@media (prefers-reduced-motion:reduce){.af-mult{animation:none}}
body.power-save .af-mult{animation-play-state:paused}
.af-idle{position:absolute;z-index:5;inset:0;display:grid;place-items:center;padding:14px;text-align:center;
  color:#e5d4ba;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.7;background:rgba(15,11,8,.72)}
.af-idle.hidden{display:none}
.af-idle b{color:var(--gold,#ffd76a)}
.af-note{margin-top:6px;color:var(--muted,#cabca8);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.6}

/* 요약 지표 */
.auto-training-metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px;margin-top:8px}
.auto-training-metrics span{min-width:0;padding:6px;border:2px solid var(--dq-line,#644a37);background:var(--panel2,#3c2c21);color:var(--muted,#cabca8);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.auto-training-metrics b{display:block;margin-bottom:2px;color:var(--gold,#ffd76a);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.auto-training-notice{margin-top:8px;padding:6px;border:2px solid #a4763a;background:rgba(164,118,58,.16);
  color:#ffd9a0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.55}
.auto-training-notice.hidden{display:none}

/* 출전 펫 상세 */
.auto-training-roster-head{display:flex;justify-content:space-between;gap:8px;margin-top:11px;color:var(--dq-ink,#f7efe2);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.auto-training-roster-head span{color:var(--muted,#cabca8);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.auto-training-squad{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px;margin-top:6px}
.auto-squad-card{display:grid;grid-template-columns:30px minmax(0,1fr);grid-template-rows:auto auto auto auto;
  column-gap:5px;row-gap:2px;padding:5px;border:2px solid var(--dq-line,#644a37);background:var(--panel2,#3c2c21);
  color:#f7efe2;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.auto-squad-art{grid-row:1 / span 4;display:grid;place-items:center;width:30px;height:30px;overflow:hidden;background:#f2dda0}
.auto-squad-art .pet-portrait{width:30px;height:30px}
.auto-squad-card b,.auto-squad-card small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.auto-squad-card small{color:#b8dfb6;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.auto-squad-bar{display:block;height:5px;border:1px solid #211811;background:#2e2118}
.auto-squad-bar>i{display:block;height:100%;background:linear-gradient(90deg,#7bd6a0,#ffd76a);transition:width .3s ease}
.auto-squad-card em{color:var(--muted,#cabca8);font-style:normal;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.auto-squad-card.capped{filter:saturate(.55)}
.auto-squad-card.capped em{color:#e6a3a3}

/* 성장 시뮬레이터 */
.auto-sim-controls{display:flex;justify-content:flex-end;margin-top:6px}
.auto-sim-controls label{display:inline-flex;align-items:center;gap:5px;color:var(--muted,#cabca8);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.auto-sim-controls select{padding:4px 6px;border:2px solid var(--dq-line,#644a37);background:var(--panel2,#3c2c21);
  color:#f7efe2;font-family:"Galmuri9","Galmuri11",sans-serif;font-size:10px}
.auto-sim{margin-top:6px;padding:6px;border:2px solid var(--dq-line,#644a37);background:rgba(0,0,0,.16)}
.auto-sim-summary{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px}
.auto-sim-summary span{min-width:0;padding:5px;border:1px solid #644a37;background:var(--panel2,#3c2c21);
  color:var(--muted,#cabca8);}
.auto-sim-summary b{display:block;margin-bottom:2px;color:var(--gold,#ffd76a)}
.auto-sim-rows{display:grid;gap:3px;margin-top:6px}
.auto-sim-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:6px;
  padding:4px 5px;border:1px solid #553e2e;background:rgba(255,255,255,.03);color:#f7efe2;}
.auto-sim-row b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.auto-sim-row strong{color:#9ff0bb}
.auto-sim-row em{color:var(--muted,#cabca8);font-style:normal;}
.auto-sim-row.capped strong{color:#e6a3a3}

/* 확장 예정 자리 — 추후 기능이 이 슬롯에 들어간다 */
.auto-ext{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px;margin-top:6px}
.auto-ext-slot{display:grid;gap:3px;padding:9px 6px;border:2px dashed #715642;background:rgba(255,255,255,.02);
  color:var(--muted,#cabca8);text-align:center;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.auto-ext-slot b{color:#e2d0b5;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.auto-ext-slot small{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;opacity:.75}

/* 시작/종료 버튼 없이 편성만으로 굴러가므로, 그 자리에 동작 규칙만 안내한다. */
.af-auto-note{margin:11px 0 0;padding:7px;border:2px solid #4a6a55;background:rgba(74,106,85,.18);
  color:#bfe9cf;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.6}

/* 편성 탭 — 자동 훈련 편성 표시 (.pb-auto 칩은 하단 '배치 라벨' 섹션에 있다) */

@keyframes af-banner{0%{opacity:0;transform:translate(-50%,-50%) scale(.7)}18%{opacity:1;transform:translate(-50%,-50%) scale(1.06)}72%{opacity:1;transform:translate(-50%,-50%) scale(1)}100%{opacity:0;transform:translate(-50%,-72%) scale(.95)}}
@keyframes auto-state-pulse{0%,100%{filter:brightness(1)}50%{filter:brightness(1.16)}}

@media(max-width:360px){
  .auto-field{--auto-field-h:262px}
  .auto-training-squad{grid-template-columns:minmax(0,1fr)}
  .auto-sim-summary{grid-template-columns:minmax(0,1fr)}
  .auto-ext{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media(prefers-reduced-motion:reduce){
  .panel-title>strong.auto-running,.af-banner.show{animation:none}
  .af-banner.show{opacity:1;transform:translate(-50%,-50%)}
}

/* ── 파워스톤 v2: 전역 5슬롯 젬 소켓 보드(소닉 크리스탈 느낌) ─────────────── */
.stone-loadout{display:flex;justify-content:center;gap:10px;flex-wrap:wrap;margin:6px 0 10px;padding:14px 8px;border:3px solid var(--dq-line,#644a37);background:linear-gradient(180deg,#33241a,#221811)}
.stone-socket{position:relative;width:60px;height:74px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;border:0;background:transparent;font-family:inherit;padding:0}
.stone-socket .socket-index{width:34px;height:34px;transform:rotate(45deg);border:2px dashed #785b46;display:flex;align-items:center;justify-content:center;color:#8a6c56;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;background:rgba(255,255,255,.02)}
.stone-socket .socket-index>*{transform:rotate(-45deg)}
.stone-socket.filled{cursor:pointer}
.stone-socket .socket-gem{width:38px;height:38px;transform:rotate(45deg);display:flex;align-items:center;justify-content:center;font-size:17px;font-family:"Galmuri11","Galmuri9",sans-serif;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.5);border:2px solid rgba(255,255,255,.65);box-shadow:0 0 10px var(--g-glow),inset 0 2px 6px rgba(255,255,255,.5),inset 0 -4px 8px rgba(0,0,0,.35);background:radial-gradient(circle at 32% 28%,rgba(255,255,255,.85),var(--g-hi) 42%,var(--g-lo));animation:stone-bob 2.6s ease-in-out infinite}
.stone-socket .socket-gem>*{transform:rotate(-45deg)}
.stone-socket .socket-grade{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:var(--g-hi);letter-spacing:.5px}
.stone-socket.filled:hover .socket-gem{filter:brightness(1.12)}
.stone-socket.filled:active{transform:translateY(1px)}
@keyframes stone-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}
.stone-loadout-hint{text-align:center;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:var(--muted,#b6a387);margin:0 0 12px}
.stone-loadout-hint b{color:var(--gold,#ffd76a)}
.stone-inventory{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:8px}
.stone-inventory .empty-note{grid-column:1/-1}
.stone-chip-wrap{position:relative;display:flex;align-items:stretch;border:3px solid var(--g-lo);background:linear-gradient(180deg,#35261b,#281c14)}
.stone-chip-wrap:hover{border-color:var(--g-hi)}
.stone-chip{flex:1;min-width:0;display:flex;align-items:center;gap:9px;text-align:left;padding:8px 10px;border:0;background:transparent;color:var(--dq-ink,#f5ebdc);font-family:inherit;cursor:pointer}
.stone-chip:hover{background:rgba(255,255,255,.04)}
.chip-detail{flex:none;width:36px;display:flex;align-items:center;justify-content:center;border:0;border-left:2px solid rgba(255,255,255,.09);background:transparent;cursor:pointer}
.chip-detail::before{content:"i";display:flex;align-items:center;justify-content:center;width:20px;height:20px;border:2px solid currentColor;border-radius:50%;color:var(--muted,#b6a387);font:italic 700 12px/1 Georgia,serif}
.chip-detail:hover::before{color:var(--g-hi)}
.chip-detail:active{transform:translateY(1px)}
.stone-chip:active{transform:translateY(1px)}
.stone-chip .chip-gem{flex:none;width:26px;height:26px;transform:rotate(45deg);display:flex;align-items:center;justify-content:center;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:#fff;border:2px solid rgba(255,255,255,.6);box-shadow:0 0 7px var(--g-glow),inset 0 -3px 6px rgba(0,0,0,.3);background:radial-gradient(circle at 32% 28%,rgba(255,255,255,.85),var(--g-hi) 44%,var(--g-lo))}
.stone-chip .chip-gem>*{transform:rotate(-45deg)}
.stone-chip .chip-body{display:flex;flex-direction:column;line-height:1.35;min-width:0;flex:1}
.stone-chip .chip-body strong{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:var(--g-hi);white-space:nowrap}
.stone-chip .chip-body span{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:var(--muted,#b6a387);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.chip-more{display:inline-block;vertical-align:middle;font-style:normal;margin-left:7px;padding:1px 6px;border-radius:8px;background:rgba(255,255,255,.12);color:var(--g-hi);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.chip-affix{display:inline-block;vertical-align:middle;font-style:normal;margin-left:5px;padding:1px 6px;border-radius:8px;background:rgba(255,238,163,.16);color:#fff0a5;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.g1{--g-hi:#c3cdd8;--g-lo:#7f8a99;--g-glow:rgba(195,205,216,.5)}
.g2{--g-hi:#74e08b;--g-lo:#2f8f4b;--g-glow:rgba(116,224,139,.55)}
.g3{--g-hi:#6bb6ff;--g-lo:#2f6dbf;--g-glow:rgba(107,182,255,.6)}
.g4{--g-hi:#c58bff;--g-lo:#7a3fd0;--g-glow:rgba(197,139,255,.62)}
.g5{--g-hi:#ffc34d;--g-lo:#d98a1f;--g-glow:rgba(255,195,77,.7)}
.g6{--g-hi:#f58dff;--g-lo:#a53ec7;--g-glow:rgba(245,141,255,.76)}
.g7{--g-hi:#fff3a6;--g-lo:#e4a432;--g-glow:rgba(255,235,119,.96)}
.stone-socket.shiny .socket-gem{animation:stone-bob 2.6s ease-in-out infinite,stone-shiny 1.7s ease-in-out infinite}
.stone-chip-wrap.shiny{border-color:#fff0a5;box-shadow:0 0 12px rgba(255,221,91,.54),inset 0 0 14px rgba(255,235,152,.1);background:linear-gradient(180deg,#3a2f20,#211a25)}
.rune-card.shiny{border-color:#fff1a3;box-shadow:0 14px 44px rgba(0,0,0,.7),0 0 28px rgba(255,226,105,.82)}
@keyframes stone-shiny{0%,100%{filter:brightness(1);box-shadow:0 0 10px var(--g-glow),inset 0 2px 6px rgba(255,255,255,.5),inset 0 -4px 8px rgba(0,0,0,.35)}50%{filter:brightness(1.22);box-shadow:0 0 20px #fff1a3,0 0 36px rgba(255,209,67,.75),inset 0 2px 8px rgba(255,255,255,.8),inset 0 -4px 8px rgba(0,0,0,.3)}}
/* 아이템 탭: 던전 원정 패널을 실제로 숨기고(=.dungeon-panel엔 전역 .hidden 규칙이 없음) 젬 보드가 그 자리를 프로미넌트하게 차지 */
.expedition-panel.hidden{display:none}

/* Two saved PvE presets can be edited independently and chosen at launch. */
/* 전투 1팀/2팀 전환 탭(.party-preset-tabs)은 편성 보드의 .fb-tab.fb-party 로 흡수됐다(2026-07-28). */
.expedition-party-modal[hidden]{display:none!important}.expedition-party-modal{position:fixed;z-index:100;inset:0;display:grid;place-items:center;padding:calc(10px + env(safe-area-inset-top)) 10px calc(var(--mode-nav-height) + 10px + env(safe-area-inset-bottom));background:rgba(7,5,9,.78);font-family:"Galmuri11","Galmuri9",sans-serif}.expedition-party-dialog{width:min(100%,500px);max-height:100%;overflow:auto;padding:14px;background:linear-gradient(145deg,#443327,#261c15);color:var(--dq-ink);border:3px solid #0b080d;box-shadow:inset 0 3px 0 #7f614b,0 12px 40px #000;scrollbar-width:thin}.expedition-party-dialog:focus{outline:none}.expedition-party-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.expedition-party-head h3{margin:2px 0 0;color:#fff7df;font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}.expedition-party-close{flex:none;width:34px;height:34px;border:2px solid #0b080d;background:#5c3540;color:#fff;font:700 18px/1 "Galmuri11","Galmuri9",sans-serif;cursor:pointer}.expedition-party-description{margin:11px 0 10px;color:#dbcab1;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.65}.expedition-party-choices{display:grid;gap:8px}.expedition-party-choice{display:grid;gap:7px;width:100%;padding:10px;border:2px solid #110c09;background:#3f3026;color:#f5ede1;text-align:left;font-family:"Galmuri11","Galmuri9",sans-serif;cursor:pointer;touch-action:manipulation}.expedition-party-choice.ready{border-color:#3f9a6c;background:#284d3b}.expedition-party-choice.ready:hover{background:#326348}.expedition-party-choice:disabled{opacity:1;cursor:not-allowed}.expedition-party-choice.unavailable{border-color:#6f515a;background:#32272e}.expedition-party-choice-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px}.expedition-party-choice-head strong{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}.expedition-party-choice-head em{color:#aae8c9;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-style:normal;text-align:right}.expedition-party-choice.unavailable .expedition-party-choice-head em{color:#f2b7b0}.expedition-party-choice ul{display:flex;flex-wrap:wrap;gap:5px;margin:0;padding:0;list-style:none}.expedition-party-choice li{display:grid;grid-template-columns:34px minmax(0,1fr);grid-template-rows:auto auto;column-gap:5px;min-width:104px;flex:1;padding:4px;background:#211913;border:1px solid rgba(255,255,255,.13)}.expedition-party-choice li>span{grid-row:1 / span 2;display:grid;place-items:center;width:34px;height:34px;overflow:hidden;background:#2f231b}.expedition-party-choice li .pet-portrait{width:34px;height:34px}.expedition-party-choice li b,.expedition-party-choice li small{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.expedition-party-choice li b{align-self:end;color:#fff5dd;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.expedition-party-choice li small{align-self:start;color:#cdc0ac;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.expedition-party-choice li.empty{display:block;min-width:0;color:#b4a793;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;text-align:center}.expedition-party-close:focus-visible,.expedition-party-choice:focus-visible{outline:3px solid #fff4be;outline-offset:2px}
@media(max-width:360px){.expedition-party-dialog{padding:11px}.expedition-party-choice{padding:8px}.expedition-party-choice li{min-width:92px}}

/* Expedition season browser: completed seasons remain selectable for replay. */
.stage-browser-tools{margin:8px 0 2px}.stage-season-open{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:34px;padding:7px 10px;border:2px solid #8f6d35;background:#342a1c;color:#ffe3a4;box-shadow:inset 0 2px 0 #5c492b;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;touch-action:manipulation}.stage-season-open:hover{background:#4a3a22}.stage-season-open:focus-visible,.stage-season-choice:focus-visible,.stage-season-zone-tabs button:focus-visible,.stage-season-close:focus-visible{outline:3px solid #fff4be;outline-offset:2px}
.stage-season-modal[hidden]{display:none!important}.stage-season-modal{position:fixed;z-index:100;inset:0;display:grid;place-items:center;padding:calc(10px + env(safe-area-inset-top)) 10px calc(var(--mode-nav-height) + 10px + env(safe-area-inset-bottom));background:rgba(7,5,9,.78);font-family:"Galmuri11","Galmuri9",sans-serif}.stage-season-dialog{width:min(100%,500px);max-height:100%;overflow:auto;padding:14px;background:linear-gradient(145deg,#443327,#261c15);color:var(--dq-ink);border:3px solid #0b080d;box-shadow:inset 0 3px 0 #7f614b,0 12px 40px #000;scrollbar-width:thin}.stage-season-dialog:focus{outline:none}.stage-season-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}.stage-season-head h3{margin:2px 0 0;color:#fff7df;font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif}.stage-season-close{flex:none;width:34px;height:34px;border:2px solid #0b080d;background:#5c3540;color:#fff;font:700 18px/1 "Galmuri11","Galmuri9",sans-serif;cursor:pointer}.stage-season-description{margin:11px 0 9px;color:#dbcab1;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.65}.stage-season-zone-tabs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px}.stage-season-zone-tabs button{min-width:0;min-height:35px;padding:5px 4px;border:2px solid #110c09;background:#35281f;color:#dbc9ae;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer}.stage-season-zone-tabs button.active{border-color:#e7bd63;background:#705126;color:#fff4cf}.stage-season-summary{display:grid;gap:3px;margin:10px 0;padding:9px;background:#1f1711;border:1px solid #614a39;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.45}.stage-season-summary strong{color:#ffe09a;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}.stage-season-summary span{color:#e7d9c3}.stage-season-summary small{color:#91d9bd;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.stage-season-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(92px,1fr));gap:6px;max-height:min(48dvh,350px);padding:2px;overflow-y:auto}.stage-season-choice{display:grid;gap:3px;min-height:54px;padding:6px;border:2px solid #110c09;background:#3f3026;color:#f5ede1;text-align:left;font-family:"Galmuri11","Galmuri9",sans-serif;cursor:pointer;touch-action:manipulation}.stage-season-choice strong{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.stage-season-choice small{color:#d8c6ab;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.35}.stage-season-choice:hover{background:#5b4536}.stage-season-choice.selected{border-color:#e7bd63;background:#705126;color:#fff8df;box-shadow:inset 0 2px 0 #a98243}.stage-season-choice.selected small{color:#fff0be}.stage-season-choice.current:not(.selected){border-color:#5d957d}.stage-season-choice.current small{color:#a9ebcb}
@media(max-width:360px){.stage-season-dialog{padding:11px}.stage-season-zone-tabs button{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.stage-season-list{grid-template-columns:repeat(2,minmax(0,1fr));max-height:min(46dvh,300px)}}
#dtab-items>.dungeon-panel{min-height:min(56vh,440px);display:flex;flex-direction:column}
/* v2 젬보드는 구 stone-card용 2단 그리드를 쓰지 않고 전폭 세로 스택 — 5슬롯 한 줄·힌트/인벤은 그 아래로(PC/모바일 공통) */
#dtab-items .dungeon-stones{display:block;margin-top:0}
/* 5칸을 컨테이너 폭 기준 5등분(항상 한 줄에 딱 맞음 · 폭 넓을수록 크게) */
#dtab-items .stone-loadout{display:grid;grid-template-columns:repeat(5,1fr);justify-items:center;align-items:center;gap:clamp(5px,1.4vw,12px);padding:20px 8px;margin:0 0 2px}
#dtab-items .stone-socket{width:100%;max-width:82px;height:auto;min-height:clamp(84px,23vw,104px)}
#dtab-items .stone-socket .socket-gem{width:clamp(34px,9.5vw,52px);height:clamp(34px,9.5vw,52px);font-size:clamp(16px,4vw,21px)}
#dtab-items .stone-socket .socket-index{width:clamp(32px,8vw,44px);height:clamp(32px,8vw,44px)}
#dtab-items .stone-socket .socket-grade{font-size:clamp(10px,2.5vw,13px)}
#dtab-items .stone-loadout-hint{max-width:520px;margin:2px auto 14px}
#dtab-items .stone-inventory{margin-top:14px}
/* 인벤 헤더 + 조합 모드 토글 + 선택 + 중앙 조합 바 */
.stone-inventory-head{display:flex;justify-content:space-between;align-items:center;margin:14px 2px 8px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:var(--muted,#b6a387)}
.stone-inventory-head .inv-count{color:var(--gold,#ffd76a)}
.forge-toggle{font-family:"Galmuri11","Galmuri9",sans-serif;font-size:12px;padding:7px 13px;border:2px solid var(--dq-line,#644a37);background:#392a1f;color:var(--dq-ink,#f5ebdc);cursor:pointer}
.forge-toggle.on{background:var(--dq-gold,#ffd76a);color:#2a2010;border-color:#8b7041}
.forge-toggle:active{transform:translateY(1px)}
.forge-mode-hint{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:var(--muted,#b6a387);margin:0 2px 8px;text-align:center}
/* 일괄 합성(2026-09-10) — 조합 모드 머리줄 단추 + 목표 등급 칩 */
.forge-head-actions{display:flex;gap:6px;align-items:center}
.forge-bulk{background:#433023;border-color:#8b7041;color:var(--dq-gold,#ffd76a)}
.bulk-targets{display:flex;flex-wrap:wrap;gap:6px;margin:12px 0 4px}
.bulk-target{flex:1 1 auto;font-family:"Galmuri11","Galmuri9",sans-serif;font-size:12px;padding:7px 8px;border:2px solid var(--dq-line,#644a37);background:#392a1f;color:var(--dq-ink,#f5ebdc);cursor:pointer}
.bulk-target.on{background:var(--dq-gold,#ffd76a);color:#2a2010;border-color:#8b7041}
.forge-bulk-card .rune-btn:disabled{opacity:.5;cursor:not-allowed}
.stone-inventory.forge-on .stone-chip-wrap{border-style:dashed}
.stone-chip-wrap.sel{border-color:var(--dq-gold,#ffd76a);border-style:solid;box-shadow:0 0 0 2px rgba(255,215,106,.4)}
.chip-selnum{position:absolute;top:-9px;right:8px;width:20px;height:20px;border-radius:50%;background:var(--dq-gold,#ffd76a);color:#2a2010;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;display:flex;align-items:center;justify-content:center;border:2px solid #8b7041;z-index:2}
/* 파워스톤 상세 모달(룬 인스펙터) — 콤팩트 칩의 ⓘ 로 열림 */
.rune-modal{position:fixed;inset:0;z-index:130;display:flex;align-items:center;justify-content:center;padding:20px;background:rgba(6,4,10,.62)}
.rune-card{position:relative;width:min(340px,calc(100vw - 32px));max-height:calc(100vh - 40px);overflow:auto;border:3px solid var(--g-hi,#c39239);background:linear-gradient(180deg,#33241a,#211811);box-shadow:0 14px 44px rgba(0,0,0,.7),0 0 22px var(--g-glow);padding:20px 18px 18px;animation:offlinePop .2s ease-out}
.rune-close{position:absolute;top:8px;right:8px;width:30px;height:30px;border:0;background:transparent;color:var(--muted,#b6a387);font-family:"Galmuri14","Galmuri11",sans-serif;font-size:15px;cursor:pointer}
/* 확인 대화상자 — 목록 선택창(`.trinket-pick`)을 빌려 쓰면 폭이 420px 로 넓고
   `flex-direction:column` 이라 짧은 메시지에서 배치가 어긋난다. 메시지 상자는 따로 둔다.
   글은 가운데로 모으고 버튼은 2등분 그리드라 좌우 폭이 항상 같다. */
.rune-confirm{position:relative;width:min(86vw,320px);padding:18px 16px 16px;text-align:center;
  background:#211913;border:3px solid var(--dq-gold);color:#fff5da;
  box-shadow:0 10px 30px rgba(0,0,0,.5)}
/* 닫기(✕)와 겹치지 않게 좌우 같은 여백 — 한쪽만 주면 글이 가운데에서 밀린다. */
.rc-title{display:block;padding:0 20px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;line-height:1.55;color:#fff}
.rc-note{margin:10px 0 0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.75;color:#cabeab}
.rc-act{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:15px}
.rc-act button{min-height:40px;padding:8px 6px;border:2px solid #8a6c57;background:#35281f;
  color:#f4eadb;font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.rc-act button.danger{border-color:#d98a8a;background:#4a2a2f;color:#ffd9d5}
.rc-act button:hover{filter:brightness(1.15)}
.rc-act button:focus-visible{outline:2px solid var(--dq-gold);outline-offset:-2px}
.rune-close:hover{color:#fff}
.rune-head{display:flex;align-items:center;gap:12px;padding-right:26px}
.rune-gem{flex:none;width:46px;height:46px;transform:rotate(45deg);display:flex;align-items:center;justify-content:center;font-size:24px;font-family:"Galmuri11","Galmuri9",sans-serif;color:#fff;border:2px solid rgba(255,255,255,.65);box-shadow:0 0 12px var(--g-glow),inset 0 2px 6px rgba(255,255,255,.45),inset 0 -4px 8px rgba(0,0,0,.35);background:radial-gradient(circle at 32% 28%,rgba(255,255,255,.85),var(--g-hi) 42%,var(--g-lo))}
.rune-gem>span{transform:rotate(-45deg)}
.rune-title{display:flex;flex-direction:column;gap:3px;min-width:0}
.rune-title strong{font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif;color:var(--g-hi)}
.rune-title>span{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:var(--muted,#b6a387)}
.rune-stats{margin:15px 0 4px;display:flex;flex-direction:column;gap:6px}
.rune-stat{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 11px;border:2px solid var(--dq-line,#644a37);background:#241b14}
.rune-stat.primary{border-color:var(--g-hi);background:linear-gradient(180deg,#39291e,#281c14)}
.rune-affix-heading{margin:15px 0 -8px;color:#fff0a5;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-weight:700;letter-spacing:.4px}
.rune-stat.affix{border-color:rgba(255,231,141,.45);background:linear-gradient(90deg,rgba(245,173,255,.11),rgba(255,231,141,.09))}
.rune-stat.affix>b{color:#fff0a5}
.rune-stat>span{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:var(--muted,#b6a387);flex:none;letter-spacing:.5px}
.rune-stat>b{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:#f5ebdc;text-align:right}
.rune-stat.primary>b{color:var(--g-hi)}
.rune-note{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:var(--muted,#b6a387);line-height:1.6;margin:12px 0 0;text-align:center}
.rune-note b{color:var(--gold,#ffd76a)}
.rune-actions{margin-top:14px;display:flex}
.rune-btn{flex:1;font-family:"Galmuri14","Galmuri11",sans-serif;font-size:15px;font-weight:700;padding:12px;border:3px solid #8b7041;background:linear-gradient(180deg,#ffe27a,#e0a52f);color:#3a2a0a;cursor:pointer}
.rune-btn.ghost{background:#392a1f;color:var(--dq-ink,#f5ebdc);border-color:var(--dq-line,#644a37);font-weight:400}
.rune-btn:active{transform:translateY(1px)}
.forge-bar{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:120;display:flex;flex-direction:column;align-items:stretch;gap:11px;width:min(440px,calc(100vw - 16px));padding:16px 18px;border:3px solid var(--dq-gold,#ffd76a);background:linear-gradient(180deg,#38291e,#221811);box-shadow:0 12px 40px rgba(0,0,0,.7),0 0 24px rgba(255,215,106,.28);animation:forge-bar-in .18s ease}
.forge-bar::before{content:"";position:fixed;inset:0;z-index:-1;background:rgba(12,9,6,.5);pointer-events:none}
@keyframes forge-bar-in{from{opacity:0;transform:translate(-50%,-50%) scale(.92)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}
.forge-bar-preview{display:flex;align-items:center;justify-content:center;gap:8px}
.forge-bar-preview i{color:var(--muted,#b6a387);font-style:normal;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.forge-bar .fb-gem{width:28px;height:28px;border-radius:6px;display:flex;align-items:center;justify-content:center;font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif;color:#fff;border:2px solid rgba(255,255,255,.6);box-shadow:0 0 8px var(--g-glow);background:radial-gradient(circle at 32% 28%,rgba(255,255,255,.85),var(--g-hi) 44%,var(--g-lo))}
.forge-bar .fb-result{animation:stone-bob 1.6s ease-in-out infinite}
.forge-bar-odds{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:var(--dq-gold,#ffd76a);text-align:center;white-space:normal;line-height:1.5;letter-spacing:.2px}
.forge-bar-actions{display:flex;gap:10px;width:100%}
.forge-bar-actions button{flex:1 1 0;min-width:0;font-family:"Galmuri14","Galmuri11",sans-serif;font-size:15px;padding:12px 12px;border:3px solid #8b7041;cursor:pointer;white-space:nowrap}
/* 조합 버튼: 금빛 글로우 맥동 + 셔인 스윕으로 조합 유발 */
.forge-bar-actions .fb-go{position:relative;overflow:hidden;background:linear-gradient(180deg,#ffe27a,#e0a52f);color:#3a2a0a;font-weight:700;box-shadow:0 0 14px 2px rgba(255,216,121,.55);animation:fb-go-glow 1.25s ease-in-out infinite}
.forge-bar-actions .fb-go::after{content:"";position:absolute;top:0;left:-65%;width:45%;height:100%;background:linear-gradient(100deg,transparent,rgba(255,255,255,.85),transparent);transform:skewX(-18deg);animation:fb-go-shine 1.9s ease-in-out infinite;pointer-events:none}
.forge-bar-actions .fb-go:disabled{opacity:.5;cursor:not-allowed;animation:none;box-shadow:none}
.forge-bar-actions .fb-go:disabled::after{display:none}
@keyframes fb-go-glow{0%,100%{box-shadow:0 0 8px 1px rgba(255,216,121,.45)}50%{box-shadow:0 0 20px 5px rgba(255,216,121,.9),0 0 34px 10px rgba(255,150,60,.4)}}
@keyframes fb-go-shine{0%{left:-65%}55%,100%{left:135%}}
.forge-bar-actions .fb-cancel{background:#392a1f;color:var(--dq-ink,#f5ebdc);border-color:var(--dq-line,#644a37)}
.forge-bar-actions button:active{transform:translateY(1px)}
@media(prefers-reduced-motion:reduce){.forge-bar-actions .fb-go,.stone-socket.shiny .socket-gem{animation:none}.forge-bar-actions .fb-go::after{display:none}}

/* ── 버닝타임 던전 표시 (Phase 2) — 헤더 배너 + 3D 전투 틴트 + 보상 배지 ─────────── */
/* 던전 헤더 배너: 던전 EXP/조각 배율 표시(없으면 '버닝타임'). style=window.__BURNING__.style */
/* 자리 · 크기 · 모양은 전역 상단 배너와 **한 규칙**이다(style.css `.burn-banner,.dungeon-burn-banner` — 헤더 위 띠).
   여기는 던전 것만: #dungeonMode 안이지만 fixed 라 뷰포트 기준이고, 맥박(dbBurnPulse)이 더 뛴다. */
.dungeon-burn-banner{position:fixed;z-index:47;pointer-events:none;
  animation:dbBurnPulse 1.7s ease-in-out infinite,bannerEnter .55s cubic-bezier(.2,1.35,.4,1),bannerFloat 5.5s ease-in-out .55s infinite}
.dungeon-burn-banner.mode-hidden{display:none}
.dungeon-burn-banner[data-burn-style="aurora"]{background:var(--burn-grad-aurora)}
.dungeon-burn-banner[data-burn-style="meteor"]{background:var(--burn-grad-meteor)}
.dungeon-burn-banner[data-burn-style="festival"]{background:var(--burn-grad-festival)}
@keyframes dbBurnPulse{50%{box-shadow:0 4px 20px -2px #ff7a18,inset 0 0 0 1px rgba(255,255,255,.18)}}
/* 피로도 무제한 타임 — 던전 요약 줄(턴 · 팀) 안의 **칩**이다(2026-09-26).
   예전에는 버닝 배너와 같은 자리(fixed · 화면 위 가운데)에 떠서, 둘이 켜지면 `.stacked` 로 한 줄 아래에 섰다 —
   폰에서는 그 두 줄이 헤더(닉네임 · 지갑 · 도구 단추)를 통째로 가렸다. 이제 흐름 안에 서서 아무것도 덮지 않고,
   요약 칩과 같은 네모 칩 모양으로 남은 폭을 채운다(좁으면 다음 줄로 넘어가 한 줄을 채우고, 그래도 길면 말줄임). */
.dungeon-free-banner{flex:1 1 auto;min-width:0;display:block;padding:7px 9px;border:2px solid #120d0a;
  background:#16302a;color:#b9f5dd;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;text-align:center;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dungeon-free-banner.mode-hidden{display:none}
@media(max-width:360px){.dungeon-free-banner{padding:2px 6px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}}

/* 3D 전투 틴트 — #battlePanel 안, 캔버스(z0) 위·HUD(z4+) 아래. three.js 무수정 CSS 오버레이. */
.battle-burn-overlay{position:absolute;inset:0;z-index:1;pointer-events:none;opacity:0;transition:opacity .5s;
  mix-blend-mode:screen;
  background:radial-gradient(120% 92% at 50% 100%,rgba(255,90,30,.30),rgba(120,20,10,.06) 58%,transparent 74%)}
.battle-burn-overlay.active{opacity:1}
.battle-burn-overlay[data-burn-style="aurora"]{background:radial-gradient(120% 92% at 50% 100%,rgba(60,220,160,.26),rgba(20,80,60,.06) 58%,transparent 74%)}
.battle-burn-overlay[data-burn-style="meteor"]{background:radial-gradient(120% 96% at 50% 100%,rgba(140,110,255,.28),rgba(40,30,90,.06) 58%,transparent 76%)}
.battle-burn-overlay[data-burn-style="festival"]{background:radial-gradient(120% 92% at 50% 100%,rgba(255,90,180,.26),rgba(90,20,70,.06) 58%,transparent 74%)}

/* 보상 카드 버닝 배지 */
.result-card .burning-summary{display:inline-block;margin-top:4px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:#fff;
  padding:3px 11px;border-radius:6px;background:var(--burn-grad);
  box-shadow:0 0 12px -2px #ff7a18}

/* 던전 모드에선 전역 상단 배너(Phase1) 숨김 → 던전 헤더 배너로 대체(중복 방지) */
body.dungeon-open .burn-banner{display:none}

@media (prefers-reduced-motion:reduce){.dungeon-burn-banner,.dungeon-free-banner{animation:none}.battle-burn-overlay{transition:none}}

/* ── 던전 전용 아이템 가방(아이템 탭 상단) ─────────────────────────────────── */
.dungeon-bag-panel .system-note{margin-bottom:10px}

/* 영구 강화/잔여 스택 요약 칩 */
.dungeon-upgrade-strip{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}
.dus-chip{display:inline-flex;align-items:center;gap:6px;padding:6px 11px;border-radius:999px;
  background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.09);
  font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:#9fb0c4;line-height:1}
.dus-chip i{font-style:normal;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.dus-chip b{color:#e8eef6;font-weight:700}
.dus-chip.on{background:linear-gradient(135deg,rgba(243,184,63,.16),rgba(243,184,63,.05));
  border-color:rgba(243,184,63,.45);color:#f6dfae}
.dus-chip.on b{color:#ffd97a}

/* 아이템 카드 목록 */
.dungeon-bag{display:grid;gap:10px}
.dbag-item{display:grid;grid-template-columns:56px 1fr auto;align-items:center;gap:12px;
  padding:11px 13px;border-radius:14px;background:rgba(255,255,255,.035);
  border:1px solid rgba(255,255,255,.08)}
.dbag-item.permanent{border-color:rgba(243,184,63,.38);
  background:linear-gradient(135deg,rgba(243,184,63,.10),rgba(255,255,255,.03))}
.dbag-art{display:grid;place-items:center;width:56px;height:56px;border-radius:12px;
  background:rgba(0,0,0,.28);box-shadow:inset 0 0 0 1px rgba(255,255,255,.07)}
.dbag-art img{width:40px;height:40px;object-fit:contain;image-rendering:auto}
.dbag-body{display:flex;flex-direction:column;gap:3px;min-width:0}
.dbag-body strong{display:flex;align-items:center;gap:7px;font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif;color:#eef3f9}
.dbag-count{font-style:normal;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:#f3b83f;font-weight:700}
.dbag-short{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:#8fe3b6;letter-spacing:.02em}
.dbag-desc{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:#8c9bad;line-height:1.45;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.dbag-use{min-width:86px;padding:9px 12px;border-radius:10px;border:0;cursor:pointer;
  background:linear-gradient(135deg,#f3b83f,#d98222);color:#2b1a05;font-weight:800;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.dbag-use:disabled{opacity:.5;cursor:default}
.dbag-use.picking{background:linear-gradient(135deg,#7fd3f5,#2c9bd1);color:#04202f}
.dbag-item.r-legendary .dbag-art{box-shadow:inset 0 0 0 1px rgba(243,184,63,.5),0 0 14px -4px #f3b83f}

/* 변환권 대상 선택 모드 */
.forge-mode-hint.reroll{color:#9fe0ff}
.stone-inventory.reroll-on .stone-chip{box-shadow:inset 0 0 0 1px rgba(127,211,245,.45)}
.stone-socket.rerolling{outline:2px dashed rgba(127,211,245,.65);outline-offset:2px}

/* 출전 활력제 초과 스태미나(surge) 표시 */
.surge-badge{margin-left:6px;font-style:normal;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;font-weight:800;color:#2b1a05;
  padding:1px 7px;border-radius:999px;background:linear-gradient(135deg,#ffe066,#f3b83f)}
.fatigue-meter.surged i,.pet-grid-fatigue-meter.surged i{background:linear-gradient(90deg,#ffe066,#2fbf71)}

@media (max-width:520px){
  .dbag-item{grid-template-columns:44px 1fr;grid-template-areas:"art body" "use use";row-gap:9px}
  .dbag-art{grid-area:art;width:44px;height:44px}
  .dbag-art img{width:32px;height:32px}
  .dbag-body{grid-area:body}
  .dbag-use{grid-area:use;width:100%}
}

/* ── 칭호 선반(아이템 탭) ────────────────────────────────────────────────────
   판(`.np-plate`) 그림은 **style.css 「이름표 스킨(칭호)」 절**이 그린다. 여기서 판 모양·색을
   다시 손대면 순위표·3D 머리 위 칭호와 다른 물건이 된다 — 여기 규칙은 **배치**뿐이다.

   ⚠ 헤더의 칭호 서랍(`.title-opt`, style.css)과 다른 화면이다. 서랍은 한 줄씩 빠르게 고르는
     곳이고 여기는 미리보기·설명·능력치를 함께 보는 곳이라, 줄이 아니라 카드다.
   ⚠ 색은 **방치게임 토큰**(`--panel2`·`--line`·`--ink`…)으로만 쓴다. 이 파일에는 던전 대시보드
     테마가 두 벌 있고(파스텔 → idle 동기화 순), 색을 직접 박으면 아래 테마 블록에서 한 번 더
     덮어써야 한다 — 장신구 카드가 그래서 두 곳에 적혀 있다(709·913). */
.ttl-bar{display:flex;align-items:center;justify-content:space-between;gap:8px;
  margin:0 0 8px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:var(--muted)}
.ttl-bar b{color:var(--gold)}
.ttl-gone{font-style:normal;color:var(--dq-red,#ef765f)}

/* auto-fill 이라 좁은 화면에서 1열, 넓으면 2~3열로 저절로 접힌다(장신구 가방과 같은 방식). */
.ttl-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(208px,1fr));gap:8px}

.ttl-card{display:flex;flex-direction:column;gap:5px;min-width:0;
  padding:9px;border:2px solid var(--line);background:var(--panel2);color:var(--ink)}
/* 지금 걸고 있는 것 — 테두리 하나로만 말한다(판 자체가 이미 화려하다. 서랍의 `.title-opt.on` 과 같은 규칙). */
.ttl-card.is-on{border-color:var(--gold);background:rgba(242,193,78,.10)}

.ttl-head{display:flex;align-items:center;justify-content:space-between;gap:6px;min-width:0}
.ttl-plate{min-width:0;overflow:hidden}
.ttl-state{flex:none;font-style:normal;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:var(--muted)}
.ttl-card.is-on .ttl-state{color:var(--gold)}

.ttl-meta{margin:0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:var(--muted)}
/* 사용 설명 — 운영자가 적는 문장이라 길이가 들쭉날쭉하다. 줄 수를 묶어야 카드 높이가
   서로 어긋나지 않는다(3줄이 넘으면 말줄임). */
.ttl-desc{margin:0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.5;color:var(--ink);
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
/* 능력치 — 장신구 카드(`.t-stats`)와 **같은 색**이라야 같은 종류의 정보로 읽힌다. */
.ttl-stats{margin:0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.5;color:var(--rare)}
.ttl-stats.none{color:var(--muted)}
/* 비전투 효과 — 전투 수치와 **다른 색**이라야 한 줄로 뭉쳐 읽히지 않는다(민트=방치 쪽). */
.ttl-perks{margin:0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.5;color:var(--unc)}
/* 무대 연출 — 능력치 · 효과와 **다른 색**(보라)이라야 "장착하면 그 무대에서 보이는 그림"으로 따로 읽힌다. */
.ttl-looks{margin:0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.5;color:var(--epic)}

/* `margin-top:auto` — 카드마다 설명 줄 수가 달라도 버튼은 아래에서 나란히 선다. */
.ttl-act{margin-top:auto;padding:6px;font-family:"Galmuri9","Galmuri11",sans-serif;font-size:10px;cursor:pointer;
  color:#2a1d0c;background:var(--gold);border:2px solid var(--line)}
.ttl-act.off{color:var(--ink);background:var(--panel);}
.ttl-act:active{transform:translateY(1px)}

.ttl-foot{margin:8px 0 0;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:var(--muted)}
.ttl-empty{padding:18px 12px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.7;text-align:center;
  color:var(--muted);border:2px dashed var(--line)}

/* ===== 게임 아이콘 — 컬러 이모지 (2026-07-28) =====
   iOS/Android/Windows 어디서나 같은 컬러 이모지로 나오게 하는 두 가지 조건:
   1) **U+FE0F(변형 선택자-16)** — 🛡(U+1F6E1)·⚔(U+2694) 처럼 유니코드 기본이
      *텍스트 표현*인 문자는 VS16 을 붙여야 컬러로 강제된다. 안 붙이면 폰트 색을 따르는
      단색 글리프로 떨어져 서로 구분되지 않는다(🌿·👀·💪 는 기본이 emoji 라 없어도 된다).
   2) **이모지 폰트를 스택 맨 앞에** — 본문 폰트(Galmuri 픽셀)가 글리프를 가로채지 않도록.
   ⚠ 사람 이모지(🏋 등)는 플랫폼마다 성별·피부톤 표현이 갈리므로 피하고 사물/신체 단독을 쓴다. */
.emo{display:inline-block;font-style:normal;line-height:1;
  font-family:"Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji","Android Emoji","EmojiOne Color","Twemoji Mozilla",sans-serif}

/* ===== 2026-07-28 편성 보드 재편 + 등급 배경 + 실시간 EXP =====
   문제 1) 편성 레인 3종이 세로로 흩어져 있고 모드 도크는 또 따로라, 아래 펫 그리드에서
           카드를 눌러도 어느 칸이 채워지는지 보이지 않았다.
   문제 2) 자동 훈련만 슬롯 보드가 없어 카드 라벨로만 편성 여부를 알 수 있었다.
   해결) 탭(=배치 대상) + 그 편성의 슬롯만 담은 보드 하나로 합치고, 펫 목록 바로 위에
        sticky 로 붙여 스크롤해도 시야에서 벗어나지 않게 한다.
   top 은 0(=화면 최상단에 밀착). 예전 6px 는 스크롤 중 보드 위로 6px 띠가 남아 그 사이로
   아래 펫 카드가 지나다녔다. env() 는 viewport-fit=cover 대응 — 노치 기기에서만 상태바
   높이만큼 내려가고, 그 밖에는 0 이라 여백이 생기지 않는다. */
/* 보드가 붙는 순간을 재는 표식 — 레이아웃에 영향을 주지 않게 높이를 음수 마진으로 상쇄한다. */
.fb-sticky-sentinel{height:1px;margin-bottom:-1px;pointer-events:none}
/* 놓아 준 상태 — 보드가 제자리에 남고 화면을 따라오지 않는다. sticky 는 자리를 이미
   차지하고 있으므로(자리를 비우지 않는다) static 으로 바꿔도 아래 목록이 밀리지 않는다. */
.formation-board.is-released{position:static}
/* 따라오기 해제 태그 — 보드가 따라오는 동안에만 뜬다.
   예전에는 position:fixed 로 화면 우측 하단에 홀로 떠 있어, 무엇을 끄는 버튼인지
   보드와 이어 보이지 않았다. 지금은 보드 **안**에 넣고 오른쪽 아래 모서리에 절대배치해
   보드 밑변에 붙은 **태그 라벨**처럼 보이게 한다(보드가 sticky 라 태그도 같이 따라온다).
   - 기준 상자는 보드의 padding box 다. 보드 테두리가 3px 이므로
     right:-3px = 보드 바깥선과 딱 맞고, top:calc(100% + 3px) = 밑변 바로 아래에 붙는다.
   - border-top 을 없애 **보드의 밑변이 곧 태그의 윗변**이 된다(선이 두 겹으로 겹치지 않는다).
   - 0 4px 0 그림자는 보드의 0 5px 0 을 이어받아, 태그 밑에서도 같은 두께로 떨어진다.
   z-index 는 보드(24) 안쪽 값이면 충분하다 — 보드가 이미 아래 펫 목록 위에 얹힌다. */
.fb-unstick{position:absolute;top:calc(100% + 3px);right:-3px;z-index:1;
  display:grid;place-items:center;min-width:46px;min-height:26px;padding:0 9px 1px;
  border:3px solid var(--line);border-top:0;background:var(--panel);color:var(--gold);
  font:700 12px/1 "Galmuri11","Galmuri9",sans-serif;cursor:pointer;touch-action:manipulation;
  box-shadow:inset -2px -2px 0 rgba(0,0,0,.35),0 4px 0 rgba(0,0,0,.35)}
.fb-unstick:hover{background:var(--panel2);color:#fff3d6}
.fb-unstick:active{transform:translateY(2px)}
.fb-unstick:focus-visible{outline:2px solid var(--gold);outline-offset:-1px}
/* ⚠️ 전역 [hidden] 규칙이 없는 저장소다 — display 를 주는 요소는 숨김도 직접 줘야 한다. */
.fb-unstick[hidden]{display:none}
.formation-board{display:block;position:sticky;top:env(safe-area-inset-top,0px);z-index:24;margin-top:10px;padding:6px;
  border:3px solid var(--line);background:var(--panel2);
  box-shadow:inset -3px -3px 0 rgba(0,0,0,.3),0 5px 0 rgba(0,0,0,.35),0 10px 20px rgba(0,0,0,.4)}
.fb-tabs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px}
.fb-tab{display:flex;align-items:center;justify-content:center;gap:4px;min-width:0;min-height:33px;padding:4px 5px;
  border:2px solid var(--line);border-bottom-width:4px;background:var(--panel);color:var(--muted);
  font:700 10px/1.2 "Galmuri9","Galmuri11",sans-serif;cursor:pointer;touch-action:manipulation}
.fb-tab>.emo{flex:none;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.fb-tab>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fb-tab>b{flex:none;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-weight:800;font-variant-numeric:tabular-nums;opacity:.9}
.fb-tab:disabled{opacity:.45;cursor:not-allowed}
.fb-tab:focus-visible{outline:2px solid var(--gold);outline-offset:1px}
/* 비활성일 때도 아래 굵은 선 색으로 어느 편성인지 알 수 있다 */
.fb-tab.fb-view{border-bottom-color:#8d8272}
.fb-tab.fb-party{border-bottom-color:#2f8a5b}
.fb-tab.fb-battle{border-bottom-color:#b3892b}
.fb-tab.fb-auto{border-bottom-color:#7a44ad}
/* 비활성 탭 — 아이콘만 편성 고유색으로 세운다(글자는 muted 라 아이콘이 먼저 눈에 들어온다).
   활성 탭은 배경이 그 색으로 꽉 차므로 아이콘은 글자와 같은 어두운 색(currentColor)이라야 보인다. */
.fb-tab.active{border-bottom-color:var(--line);color:#2a1d0c;background:var(--gold)}
.fb-tab.fb-view.active{color:#2a1d0c;background:var(--ink);box-shadow:inset -2px -2px 0 #b0a48c}
.fb-tab.fb-party.active{color:#052414;background:#57e39a;box-shadow:inset -2px -2px 0 #2f8a5b}
.fb-tab.fb-battle.active{color:#382400;background:#ffd257;box-shadow:inset -2px -2px 0 #b3892b}
.fb-tab.fb-auto.active{color:#2e2117;background:#c98bff;box-shadow:inset -2px -2px 0 #7a44ad}
/* 고른 탭의 편성만 펼친다 — 나머지는 탭의 숫자로 확인한다 */
.fb-panes{margin-top:5px}
.fb-pane{display:none}
.formation-board[data-mode="view"] .fb-pane[data-pane="view"],
.formation-board[data-mode="party"] .fb-pane[data-pane="party"],
.formation-board[data-mode="battle"] .fb-pane[data-pane="battle"],
.formation-board[data-mode="auto"] .fb-pane[data-pane="auto"]{display:block}
.formation-board .roster-lane{padding:6px;border-width:2px}
.formation-board .roster-lane-title{margin-bottom:5px}
.formation-board .roster-lane.auto-lane{border-left:4px solid var(--epic)}
.formation-board .slot-tile{min-height:76px;padding:6px 3px 5px}
.formation-board .slot-face .pet-portrait{width:36px;height:36px}
.formation-board .roster-lane-actions button{min-height:26px;padding:3px 7px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.pet-sort-bar{gap:6px;margin:7px 3px 0}
.pet-sort-label{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.pet-sort-btns button{min-height:26px;padding:3px 7px}

/* 보기 탭 — 다섯 편성을 한 줄씩 요약. 줄을 누르면 그 편성 탭으로 바로 간다. */
.fb-summary{display:grid;gap:4px}
.fb-sum-row{display:grid;grid-template-columns:82px minmax(0,1fr) auto;align-items:center;gap:6px;
  width:100%;min-height:36px;padding:4px 6px;border:2px solid var(--line);border-left-width:4px;
  background:var(--panel);color:var(--ink);font:700 10px/1.3 "Galmuri9","Galmuri11",sans-serif;
  text-align:left;cursor:pointer;touch-action:manipulation}
.fb-sum-row:hover{background:#4a3a26}
.fb-sum-row:focus-visible{outline:2px solid var(--gold);outline-offset:1px}
.fb-sum-row.party{border-left-color:#57e39a}
.fb-sum-row.battle{border-left-color:#ffd257}
.fb-sum-row.auto{border-left-color:#c98bff}
.fb-sum-name{display:flex;align-items:center;gap:4px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fb-sum-name>.emo{flex:none;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
/* 레인 제목 — 레인 왼쪽 테두리 색과 같은 색으로 세운다 */
.roster-lane-heading>strong{display:inline-flex;align-items:center;gap:4px}
.roster-lane-heading>strong>.emo{flex:none;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.fb-sum-faces{display:flex;align-items:center;gap:3px;min-width:0;overflow:hidden}
.fb-sum-faces>em{flex:none;display:grid;place-items:center;width:26px;height:26px;overflow:hidden;
  border:2px solid var(--com);background:#f2dda0;font-style:normal;line-height:0}
.fb-sum-faces>em .pet-portrait{width:22px;height:22px}
.fb-sum-faces>em.r-uncommon{border-color:var(--unc)}
.fb-sum-faces>em.r-rare{border-color:var(--rare)}
.fb-sum-faces>em.r-epic{border-color:var(--epic)}
.fb-sum-faces>em.r-legendary{border-color:var(--leg)}
.fb-sum-faces>em.fb-sum-empty{width:auto;height:auto;border:0;background:none;color:var(--muted);
  font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-weight:400;line-height:1.4}
.fb-sum-count{flex:none;padding:2px 5px;border:2px solid var(--line);background:var(--dirt-lo);
  color:var(--ink);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-variant-numeric:tabular-nums}
.fb-sum-count.full{background:var(--gold);color:#2a1d0c}

/* 자동 훈련 레인 */
.auto-lane-state{padding:3px 6px;border:2px solid var(--line);background:var(--panel);
  color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;font-weight:700;white-space:nowrap}
.auto-lane-state.running{color:#002e29;background:#3ff0dc;animation:autoLaneRun 1.7s ease-in-out infinite}
@keyframes autoLaneRun{0%,100%{box-shadow:none}50%{box-shadow:0 0 9px #3ff0dc}}
.auto-lane-note{margin:6px 0 0;color:var(--muted);font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.55}
/* 실시간 EXP 바 — 정산과 정산 사이를 예측으로 채운다(autoLiveTick 이 width/글자만 갱신) */
.xp-live{position:relative;display:block;width:100%;height:12px;margin-top:4px;overflow:hidden;
  border:1px solid var(--line);background:#241a10}
.xp-live>i{display:block;width:0;height:100%;background:linear-gradient(90deg,#3f9d6a,#c8922c);
  transition:width .9s linear}
.xp-live>em{position:absolute;inset:0;display:grid;place-items:center;color:#fff9ea;
  font:800 10px/1 "Galmuri9","Galmuri11",sans-serif;font-style:normal;letter-spacing:-.2px;
  text-shadow:0 1px 0 #000,-1px 0 0 #000,1px 0 0 #000,0 -1px 0 #000}
.xp-live.capped>i{background:#6d5c46}
.xp-live.capped>em{color:#e7bfa0}
/* 다음 정산에서 레벨업이 확정된 상태 — 밝은 바 위에는 어두운 글자가 읽힌다 */
.xp-live.ready>i{background:linear-gradient(90deg,#ffd76a,#fff6d8)}
.xp-live.ready>em{color:#2b1a05;text-shadow:none}
.xp-live.ready{animation:xpReady .85s ease-in-out infinite}
@keyframes xpReady{0%,100%{box-shadow:none}50%{box-shadow:0 0 9px #ffe9a3}}
.xp-live.squad-xp{height:12px}
.xp-live.squad-xp>em{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
/* 이 아래 셋은 **위치가 움직이지 않는 글로우**다(box-shadow 만 변한다). 전정기관을 자극하는
   요소가 없고 '진행 중'을 알리는 유일한 신호라서 reduce 에서도 끄지 않는다. */
@media(prefers-reduced-motion:reduce){.xp-live>i{transition:none}}
/* 출전 펫 카드의 EXP 는 이제 실시간 바 한 줄이 대신한다(예전 바 + 숫자 두 줄) */
.auto-squad-card{grid-template-rows:auto auto auto}
.auto-squad-art{grid-row:1 / span 3}

/* 성장 시뮬레이터 — 값이 고정돼 있으면 "정말 오르고 있나"를 알 수 없다.
   숫자를 매초 실시간 예측으로 갈아 끼우고, 바뀌는 순간 한 번 튕겨 눈에 걸리게 한다. */
.auto-sim-summary{grid-template-columns:repeat(2,minmax(0,1fr))}
.auto-sim-summary span{display:flex;align-items:baseline;justify-content:space-between;gap:5px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.auto-sim-summary b{display:block;margin:0;flex:none}
.auto-sim-summary i{font-style:normal;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;font-weight:800;color:var(--ink);
  font-variant-numeric:tabular-nums;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 지금 이 순간 쌓이고 있는 값 — 다른 칸(예상치)과 구분되게 청록으로 세워 둔다 */
.auto-sim-summary .sim-live{border-color:#3ff0dc;background:rgba(63,240,220,.1)}
.auto-sim-summary .sim-live b{color:#8ef7ea}
.auto-sim-summary .sim-live i{color:#c9fff8}
.auto-sim-summary .sim-live i.bump{animation:simBump .5s ease-out}
@keyframes simBump{
  0%{transform:translateY(0);color:#fff}
  35%{transform:translateY(-3px);color:#fff;text-shadow:0 0 8px #3ff0dc}
  100%{transform:translateY(0)}
}
.auto-sim-row{grid-template-columns:minmax(0,1fr) auto auto;row-gap:4px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.auto-sim-row [data-sim-path]{color:#9ff0bb;font-weight:700;white-space:nowrap}
.auto-sim-row em{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.auto-sim-row .xp-live{grid-column:1 / -1;margin-top:0}
.auto-sim-row.capped [data-sim-path]{color:#e6a3a3}
.auto-sim-row.capped{filter:saturate(.6)}
/* bump 만 유일하게 위치가 움직인다 → reduce 에서는 색 번쩍임만 남긴다(숫자는 계속 오른다) */
@media(prefers-reduced-motion:reduce){.auto-sim-summary .sim-live i.bump{animation:simBumpFlat .5s ease-out}}
@keyframes simBumpFlat{0%{color:#fff}40%{color:#fff;text-shadow:0 0 8px #3ff0dc}100%{color:#c9fff8}}
/* 파일 위쪽 360px 규칙이 1열로 떨어뜨리지만, 라벨/숫자를 좌우로 나눈 뒤로는 2열도 들어간다 */
@media(max-width:360px){
  .auto-sim-summary{grid-template-columns:repeat(2,minmax(0,1fr))}
  .auto-sim-summary span{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
  .auto-sim-summary i{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
}

/* 배치 라벨 — 카드 폭이 120px 남짓이라 글자를 붙이면 두 줄로 늘어지거나 잘린다.
   그래서 **아이콘 칩 한 줄**로 고정하고, 숫자(팀 번호·남은 턴)만 모서리 첨자로 얹는다.
   편성 종류는 색으로 가른다(전투=연두 / 자동 대기=보라 / 자동 진행=청록 …). */
/* 가로 자리 — 한 줄에 다 못 담으면 **접는다**(예전엔 nowrap 이라 역할 라벨이 "원…"으로 잘렸다).
   칩은 크기가 고정(flex:none)이라 줄어들 수 없으니, 좁아지면 밀리는 쪽은 언제나 역할 라벨이었다.
   지금은 라벨도 안 줄어들게 두고(.pet-badges>.pet-role) 대신 칩 묶음이 아랫줄로 내려간다 —
   접히기 전까지는 예전과 똑같이 한 줄이고, 접혀도 역할 왼쪽·배치 오른쪽 배열은 그대로다.
   column-gap 은 첨자(칩 밖으로 1px 나온다 — 실측)가 옆 칩에 닿지 않을 만큼만 준다. */
/* 세로 자리 — 칩은 **아래로 삐져나오는 것들**이 있다: 숫자 첨자가 칩 밑변보다 1px,
   그림자(0 2px 0)가 2px 더 내려온다. 카드 안쪽 여백이 4px 뿐이라 그대로 두면 첨자와
   그림자가 카드 테두리에 거의 닿았다(실측: 첨자 3px · 그림자 2px 남음).
   그래서 위 여백에서 4px 을 떼어 아래로 옮긴다 — 줄 전체가 4px 올라가 밑에 숨 쉴 틈이
   생기고(첨자 7px · 그림자 6px), 카드 높이는 그대로다(위 10 + 아래 4 → 위 6 + 아래 8).
   위쪽은 피로도 막대까지 12px → 8px 로 줄지만 두 줄이 붙어 보이지는 않는다. */
.pet-badges{flex-wrap:wrap;gap:3px 4px;margin:1px 0 4px}
/* 컬러 이모지를 밝은 색 칩 위에 올리면 서로 묻힌다 → 칩 안쪽은 어둡게 두고
   편성 색은 **테두리와 숫자 첨자**가 맡는다(색 신호는 그대로, 아이콘 대비는 최대). */
.pb{position:relative;display:grid;place-items:center;flex:none;width:22px;height:22px;padding:0;
  border:2px solid var(--chip);background:#1b140d;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;font-style:normal;line-height:1;
  box-shadow:0 2px 0 rgba(0,0,0,.45),inset 0 0 0 1px rgba(0,0,0,.5)}
.pb>.emo{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.pb>b{position:absolute;right:-3px;bottom:-3px;min-width:11px;height:11px;padding:0 1px;
  border:1px solid rgba(0,0,0,.8);background:var(--chip);color:#17120c;
  font:800 8px/10px "Galmuri7","Galmuri9",sans-serif;font-variant-numeric:tabular-nums}
.pb-party{--chip:#57e39a}
.pb-battle{--chip:#ffd257}
.pb-auto{--chip:#c98bff}
.pb-auto-run{--chip:#3ff0dc;animation:pbAutoRun 1.5s ease-in-out infinite}
@keyframes pbAutoRun{0%,100%{box-shadow:0 2px 0 rgba(0,0,0,.45),inset 0 0 0 1px rgba(0,0,0,.5)}
  50%{box-shadow:0 2px 0 rgba(0,0,0,.45),inset 0 0 0 1px rgba(0,0,0,.5),0 0 10px #3ff0dc}}


/* 펫 등급 — 테두리만으로는 알아보기 어려워 배경 틴트 + 바닥 등급 띠를 함께 준다 */
.dungeon-pet-card{--rar:var(--com);--rar-soft:rgba(154,160,166,.20)}
.dungeon-pet-card.uncommon{--rar:var(--unc);--rar-soft:rgba(95,211,138,.22)}
.dungeon-pet-card.rare{--rar:var(--rare);--rar-soft:rgba(90,169,230,.22)}
.dungeon-pet-card.epic{--rar:var(--epic);--rar-soft:rgba(176,110,230,.26)}
.dungeon-pet-card.legendary{--rar:var(--leg);--rar-soft:rgba(242,161,62,.30)}
.dungeon-pet-card{border-color:var(--rar);background-color:var(--panel2);
  background-image:linear-gradient(180deg,var(--rar-soft) 0,rgba(0,0,0,0) 64%)}
.dungeon-pet-card:hover{background-color:#4a3a26}
.dungeon-pet-card.legendary{box-shadow:inset -2px -2px 0 rgba(0,0,0,.32),inset 2px 2px 0 rgba(255,255,255,.05),0 0 12px rgba(242,161,62,.28)}
/* 등급 문장(紋章) — 카드 좌상단 한 줄: [등급 젬][별].
   예전엔 등급이 카드 바닥 전폭 텍스트 띠였다(세로 21px 낭비 + 별과 따로 놀았다). */
.pet-crest{position:absolute;z-index:4;top:3px;left:3px;display:flex;align-items:center;gap:3px;
  max-width:calc(100% - 8px)}
/* 전투력 — 문장(등급·별) **바로 아래 줄**. '전투력' 정렬을 골랐을 때 이 숫자가 순서의 근거다.
   ⚠️ top 은 문장 줄 높이(.rar-gem 16px + top 3px + 3px)에 맞춘 값이다 — 젬 크기를 바꾸면
   이 값과 아래 .pet-card-hit padding-top 도 같이 움직여야 한다(작은 화면 값은 미디어쿼리에). */
.pet-power{position:absolute;z-index:4;top:22px;left:3px;max-width:calc(100% - 8px);
  padding:1px 4px;border:1px solid rgba(0,0,0,.5);background:rgba(0,0,0,.34);color:#ffd9a0;
  font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.5;letter-spacing:-.2px;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;font-variant-numeric:tabular-nums}
.pet-power b{color:#fff3d6}
.rar-gem{flex:none;display:grid;place-items:center;width:16px;height:16px;
  border:1px solid rgba(0,0,0,.65);background:var(--rar);color:#17120c;font-style:normal;
  font:800 10px/1 "Galmuri9","Galmuri11",sans-serif;
  box-shadow:inset -1px -1px 0 rgba(0,0,0,.28),inset 1px 1px 0 rgba(255,255,255,.42)}
.rar-gem.r-legendary{animation:gemLegend 2.4s ease-in-out infinite}
@keyframes gemLegend{0%,100%{box-shadow:inset -1px -1px 0 rgba(0,0,0,.28),inset 1px 1px 0 rgba(255,255,255,.42)}
  50%{box-shadow:inset -1px -1px 0 rgba(0,0,0,.28),inset 1px 1px 0 rgba(255,255,255,.42),0 0 8px var(--leg)}}

/* 별은 젬 오른쪽에 한 줄로. 5개 이상은 `★12` 로 접혀 줄바꿈되지 않는다(별 최대 20). */
.pet-crest .pet-stars{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.pet-crest .pet-stars.collapsed{letter-spacing:0;font-variant-numeric:tabular-nums}
/* 초상이 문장 줄과 겹치지 않도록 위쪽 여백을 맞춘다 — 젬 줄(16px) + 전투력 줄(약 15px). */
.dungeon-pet-card .pet-card-hit{padding-top:36px}
/* 슬롯 타일에도 같은 등급 신호를 준다 */
.slot-tile.filled{--rar:var(--com);--rar-soft:rgba(154,160,166,.18)}
.slot-tile.filled.r-uncommon{--rar:var(--unc);--rar-soft:rgba(95,211,138,.20)}
.slot-tile.filled.r-rare{--rar:var(--rare);--rar-soft:rgba(90,169,230,.20)}
.slot-tile.filled.r-epic{--rar:var(--epic);--rar-soft:rgba(176,110,230,.24)}
.slot-tile.filled.r-legendary{--rar:var(--leg);--rar-soft:rgba(242,161,62,.26)}
.slot-tile.filled{border-color:var(--rar);background-color:var(--panel);
  background-image:linear-gradient(180deg,var(--rar-soft) 0,rgba(0,0,0,0) 70%)}
.slot-tile.filled.auto{box-shadow:inset 0 3px 0 rgba(201,139,255,.5)}

/* 편성 상태 테두리는 등급색을 덮어쓴다(지금 어디에 들어가 있는지가 우선). 아래일수록 우선. */
.dungeon-pet-card.in-auto-party{order:-10;box-shadow:inset 0 0 0 2px rgba(201,139,255,.6)}
.dungeon-pet-card.in-battle{order:-15;border-color:#ffd257!important;box-shadow:inset 0 0 0 2px rgba(255,210,87,.45)}
.dungeon-pet-card.auto-running{order:-25;border-color:#3ff0dc!important;box-shadow:inset 0 0 0 2px rgba(63,240,220,.4)}
.dungeon-pet-card.in-party{order:-30;border-color:#57e39a!important}
/* 반짝이(shiny)는 편성 색보다도 위 — 원래 우선순위를 유지한다.
   단 아래 '편성 모드에서 담긴 펫' 규칙은 선택자가 더 강해 편성 모드에서만 이 색을 이긴다. */
.slot-tile.shiny,.dungeon-pet-card.shiny{border-color:#fff6b0!important}
.dungeon-pets[data-mode="auto"] .dungeon-pet-card:hover{border-color:#c98bff}

/* ══ 공통 전광판 링 (.mq-ring) ══════════════════════════════════════════════
   "지금 이 편성과 관련된 것"을 알리는 **단 하나의** 테두리 연출.
   빈 슬롯(여기 채우세요) · 담긴 펫 카드(이미 담김) · 대표팀 등록 버튼(눌러 확정)이
   모두 이 컴포넌트를 쓴다. 예전엔 셋이 각자 4변 점선을 구현해 픽셀이 깨져 보이고
   조금씩 달라져 있었다.
   쓰는 법: 요소에 `mq-ring` + 색 모디파이어(`mq-party|battle|auto`)를 준다.

   왜 색으로만 알리면 안 되나: 등급도 테두리 '색'을 쓴다. 언커먼(연두)↔전투 편성(연두),
   레전드(금)↔배틀(금)이 같은 색이라 색만으로는 구분이 안 됐다. */
.mq-party{--pick:#6effc0}
.mq-battle{--pick:#ffe27a}
.mq-auto{--pick:#e0b6ff}
/* 베이스 링은 편성색을 어둡게 — 그 위를 지나는 빛과 대비가 생긴다 */
.mq-ring{position:relative;border-style:solid!important;
  border-color:color-mix(in srgb,var(--pick) 38%,#0b0808)!important;
  animation:pickedPulse 1.7s ease-in-out infinite}
/* 빛은 배경이 아니라 ::before 레이어에 그린다 — 카드 background-image 는
   등급 틴트(--rar-soft)가 이미 쓰고 있어 덮으면 안 된다.
   inset 은 -2px 까지만(그리드 gap 5px — 더 나가면 옆 칸과 맞닿는다). */
.mq-ring::before{
  content:"";position:absolute;z-index:3;inset:-2px;padding:2px;pointer-events:none;
  /* @property 를 모르는 브라우저에서도 var() 가 유효하도록 초기값을 직접 깔아 둔다
     (없으면 conic-gradient 전체가 무효가 되어 링이 통째로 사라진다). */
  --marquee:0deg;
  background:conic-gradient(from var(--marquee),
    transparent 0deg 14deg,
    var(--pick) 26deg,#fff 34deg,var(--pick) 42deg,
    transparent 54deg 194deg,
    var(--pick) 206deg,#fff 214deg,var(--pick) 222deg,
    transparent 234deg 360deg);
  /* 가운데를 도려내 링(테두리)만 남긴다 */
  -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;
  animation:marqueeSpin 1.5s linear infinite}
/* 각도를 애니메이션하려면 커스텀 속성을 <angle> 로 등록해야 한다(미지원 시 정적 링) */
@property --marquee{syntax:"<angle>";initial-value:0deg;inherits:false}
@keyframes marqueeSpin{to{--marquee:360deg}}
@keyframes pickedPulse{
  0%,100%{box-shadow:0 0 4px color-mix(in srgb,var(--pick) 55%,transparent)}
  50%{box-shadow:0 0 14px var(--pick)}}
/* 빈 슬롯은 링이 테두리를 대신하므로 안쪽 점선/글자색만 링 색에 맞춘다 */
.slot-tile.empty.mq-ring{color:var(--pick)}
/* 담긴 펫은 목록 맨 앞으로 — 연출이 화면 밖에 있으면 소용이 없다 */
.dungeon-pet-card.mq-ring{order:-40}

/* 모션을 줄여 달라는 사용자에게도 **끄지 않는다** — 이 빛이 '지금 담겨 있다'를 알리는
   핵심 신호라 없애면 기능을 잃는다. 대신 현기증 유발 요소만 뺀다:
   번쩍이는 흰 하이라이트 제거 + 회전을 3배 이상 느리게 + 글로우도 완만하게.
   ⚠ 헤드리스 크롬은 **항상** reduce 로 보고한다 → 이 경로가 사실상 기본값이므로,
     애니메이션을 헤드리스로 검증할 때는 이 미디어쿼리를 걷어내고 측정해야 한다. */
@media(prefers-reduced-motion:reduce){
  .mq-ring{animation:pickedPulse 5s ease-in-out infinite}
  .mq-ring::before{animation:marqueeSpin 5s linear infinite;
    background:conic-gradient(from var(--marquee),
      transparent 0deg 24deg,var(--pick) 44deg,transparent 64deg 204deg,
      var(--pick) 224deg,transparent 244deg 360deg)}
}

@media(max-width:360px){
  .formation-board{padding:4px}
  .fb-tabs{gap:3px}
  .fb-tab{gap:2px;min-height:30px;padding:3px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
  .fb-tab>b{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
  .fb-sum-row{grid-template-columns:70px minmax(0,1fr) auto;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
  .formation-board .slot-tile{min-height:70px}
  .formation-board .slot-face .pet-portrait{width:32px;height:32px}
  .pb{width:20px;height:20px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
  .rar-gem{width:15px;height:15px;font-size:8px;font-family:"Galmuri7","Galmuri9",sans-serif}
  .pet-crest .pet-stars{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
  .pet-power{top:21px}
  .dungeon-pet-card .pet-card-hit{padding-top:34px}
}

/* 월드 비공개(개발자 우회) — 탭은 보이되 '공개됨'으로 오해하지 않게 자물쇠 + 흐린 라벨.
   조건은 world_access=true && world_open=false 하나뿐이고 game.js updateModeNavigation 이
   붙였다 뗀다(공개 전환 시 저절로 사라짐). 라이트/스티커 테마의 button 규칙보다 선택자가
   구체적이라 순서와 무관하게 이긴다. */
.game-mode-nav button.is-private{position:relative}
.game-mode-nav button.is-private::after{content:"🔒";position:absolute;top:3px;right:5px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1;opacity:.85;pointer-events:none}
.game-mode-nav button.is-private:not(.active){opacity:.68}

/* ── 펫 상점 출몰: 모드 내비 '상점' 버튼 무지개화 ─────────────────────────────
   ⚠ 이 PC(및 사내 다수 PC)는 Windows '애니메이션 표시' OFF 라 실제 크롬도 항상
   prefers-reduced-motion: reduce 다. 그래서 **색은 정적 background 로 먼저 칠하고**,
   @keyframes 는 '움직임'만 담당한다. 색을 keyframes 안에만 두면 그 PC 에서 단색 버튼이
   된다(animation:none 이면 keyframes 안의 속성이 기본값으로 튄다 — 공략집 wash 사례). */
body.pet-shop-live .game-mode-nav button[data-game-mode="shop"]{
  position:relative;color:#fff;text-shadow:0 1px 0 rgba(0,0,0,.55);
  background-image:linear-gradient(100deg,#ff4d6d,#ff9f1c,#ffe14d,#3ddc84,#4cc9f0,#b15cff,#ff4d6d);
  background-size:300% 100%;background-position:0% 50%;
}
/* 황금·전설 무드는 더 진하게 — 정지 상태에서도 구분된다 */
body.pet-shop-live[data-pet-shop-mood="golden"] .game-mode-nav button[data-game-mode="shop"],
body.pet-shop-live[data-pet-shop-mood="mythic"] .game-mode-nav button[data-game-mode="shop"]{
  background-image:linear-gradient(100deg,#ffd60a,#ff9f1c,#fff3b0,#ffd60a,#ff6b35,#ffd60a);
}
.pet-shop-nav-badge{
  position:absolute;top:2px;right:4px;min-width:15px;padding:1px 3px;
  background:#1c140e;color:#ffe14d;border:1px solid rgba(255,255,255,.6);
  font:700 10px "Galmuri9","Galmuri11",sans-serif;line-height:13px;text-align:center;
}
.pet-shop-nav-badge[hidden]{display:none!important}

/* ── 전쟁 신호(§4.14) — 하단 '던전게임' 단추 ────────────────────────────────
   ⚠ 색 언어는 거점 화면과 **같다**: 금색=우리가 공격 · 붉은색=우리가 수비 ·
     주황=교전 중(`.op-war-note` · `.op-front-go.is-ablaze`). 새 색을 만들면 같은
     전쟁이 화면마다 다른 색으로 보인다.
   ⚠ 절제한다. 이 자리는 상시 노출이고 월드보스가 이미 큰 연출을 쓴다 — 둘이 함께
     뜨는 저녁이 있어서, 여기까지 크게 만들면 어느 쪽도 안 읽힌다. */
.game-mode-nav button[data-game-mode="dungeon"]{position:relative;overflow:visible}
body.war-on .game-mode-nav button[data-game-mode="dungeon"]{
  color:#fff3d8;box-shadow:inset 0 3px 0 #d9a441,0 0 10px rgba(217,164,65,.5)}
body.war-on.war-defend .game-mode-nav button[data-game-mode="dungeon"]{
  color:#ffe4e0;box-shadow:inset 0 3px 0 #d98a8a,0 0 10px rgba(217,138,138,.5)}
body.war-on.war-live .game-mode-nav button[data-game-mode="dungeon"]{
  color:#fff1de;box-shadow:inset 0 3px 0 #ff8a3d,0 0 13px rgba(255,138,61,.66)}
.war-nav-badge{
  position:absolute;z-index:5;top:2px;right:3px;min-width:14px;padding:1px 3px;
  border:1px solid rgba(255,255,255,.6);background:#7a5514;color:#fff6dd;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;line-height:13px;text-align:center}
body.war-defend .war-nav-badge{background:#7a2c2c}
body.war-live .war-nav-badge{background:#8a3d10}
.war-nav-badge[hidden]{display:none!important}
/* 들어가는 길 — 부족 서브탭도 **모드 내비와 같은 배지**를 단다.
   ⚠ 예전에는 6px 금색 점(`::after`)이었는데 두 겹으로 안 보였다(2026-09-06 제보):
     ① 금색 점(#d9a441)을 **금색 그라데이션 탭**(#c99a52) 위에 얹어 대비가 없었다.
     ② `::after` 는 z-index 가 auto 인데 아이콘·라벨은 z-index:2 라 **그 아래로 깔렸다**.
     게다가 그 `::after` 자리는 셰인(빛 흐름)이 이미 쓰고 있어서, 전쟁 중에는 탭의
     광택까지 사라졌다 — 한 자리를 둘이 쓰면 늘 하나가 진다.
   그래서 **진짜 요소**로 옮기고(아이콘 위 z-index:3), 금색 위에서도 읽히도록
   어두운 판에 상태 색 테두리를 둘렀다. 문구는 `renderWarNav()` 한 곳에서 만든다. */
.dtab.dtab-guild{position:relative}
.dtab-war{
  position:absolute;z-index:3;top:2px;right:2px;min-width:16px;padding:1px 3px;
  border:1px solid #d9a441;background:#241708;color:#ffe6b0;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;line-height:11px;letter-spacing:0;
  text-align:center;text-shadow:none;pointer-events:none}
.dtab-war[hidden]{display:none!important}
body.war-defend .dtab-war{border-color:#d98a8a;color:#ffd9d5;background:#2a1010}
body.war-live .dtab-war{border-color:#ff8a3d;color:#ffdcc0;background:#2c1405}
/* 곁눈으로도 잡히게 — 탭 테두리에도 같은 색을 한 겹 두른다(배지는 작으니 혼자 두지 않는다).
   기존 베벨(inset 그림자 두 겹)을 지우면 탭이 납작해지므로 **앞에 한 겹 더** 얹는다. */
body.war-on .dungeon-subnav .dtab.dtab-guild{
  box-shadow:inset 0 0 0 2px #d9a441,inset -3px -3px 0 #46301a,inset 3px 3px 0 rgba(255,238,205,.26)}
body.war-on.war-defend .dungeon-subnav .dtab.dtab-guild{
  box-shadow:inset 0 0 0 2px #d98a8a,inset -3px -3px 0 #46301a,inset 3px 3px 0 rgba(255,238,205,.26)}
body.war-on.war-live .dungeon-subnav .dtab.dtab-guild{
  box-shadow:inset 0 0 0 2px #ff8a3d,inset -3px -3px 0 #46301a,inset 3px 3px 0 rgba(255,238,205,.26)}
@keyframes warNavPulse{0%,100%{filter:none}50%{filter:brightness(1.4)}}
@media (prefers-reduced-motion: no-preference){
  /* 움직이는 것은 둘뿐이다 — 지금 싸우는 중이거나, **내 승인이 없어 무산될 참**일 때. */
  body.war-on.war-live .game-mode-nav button[data-game-mode="dungeon"],
  body.war-on.war-needs-me .game-mode-nav button[data-game-mode="dungeon"]{
    animation:warNavPulse 1.5s ease-in-out infinite}
}

@keyframes petShopNavFlow{to{background-position:300% 50%}}
@media (prefers-reduced-motion: no-preference){
  body.pet-shop-live .game-mode-nav button[data-game-mode="shop"]{
    animation:petShopNavFlow 3.2s linear infinite;
  }
}

/* ══ 종별 지정색 (.bc) — GHUB 펫 마스터 '도감 색상' ═════════════════════════
   등급색 5종만으로는 히든·이벤트 종이 같은 레전드색에 묻힌다. 편성 상태가 쓰는 속성
   (.in-party/.in-battle 의 `border-color:!important`, .in-battle/.in-auto-party 의
   box-shadow)은 건드리지 않고, 아무도 안 쓰는 **outline(안쪽 링) + 배경 틴트**로만
   종 색을 얹는다 → 편성 중이어도 '무슨 종인지'와 '어디 편성됐는지'를 동시에 읽는다.
   ⚠ 두께를 border-width 로 내면 카드 높이가 종마다 달라져 그리드 정렬이 흔들린다. */
.dungeon-pet-card.bc{outline:3px solid var(--rar);outline-offset:-6px;
  background-image:linear-gradient(158deg,var(--rar-soft) 0%,rgba(0,0,0,0) 70%)}
.slot-tile.filled.bc{outline:3px solid var(--rar);outline-offset:-5px;
  background-image:linear-gradient(170deg,var(--rar-soft) 0%,rgba(0,0,0,0) 74%)}
/* 편성 링이 없는 카드는 바깥 테두리·글로우까지 종 색으로(가장 강한 신호) */
.dungeon-pet-card.bc:not(.in-party):not(.in-battle):not(.in-auto-party){
  border-color:var(--rar);
  box-shadow:inset -2px -2px 0 rgba(0,0,0,.32),inset 2px 2px 0 rgba(255,255,255,.05),0 0 11px var(--rar-glow)}

/* 편성 슬롯의 전투 역할 배지 — 레벨/피로와 같은 줄에 서므로 아주 작게 둔다. */
.pet-role{display:inline-flex;align-items:center;gap:2px;margin-right:4px;padding:0 3px;
  border-radius:3px;line-height:1.5;white-space:nowrap}
.pet-role i{font-style:normal;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}

/* 전투 역할 라벨 — 색은 상대 정찰 카드의 `.role-*` 를 그대로 쓴다(같은 축을 두 색으로 칠하지 않는다).
   카드에서는 역할이 왼쪽, 배치 칩이 오른쪽에 선다. */
/* 배치 칩이 3개(팀+배틀+자동)까지 붙을 수 있다. 칩 3개만으로 카드 안쪽 폭을 거의 다 먹으므로
   **어떤 배치로도 역할 라벨과 칩 3개가 한 줄에 들어가지 않는다** — 그때는 칩이 아랫줄로 내려간다. */
.pet-role{display:inline-block;min-width:0;overflow:hidden;text-overflow:ellipsis;
  padding:2px 4px;background:#33271e;border:1px solid #644d3c;
  color:#dbc9ae;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.4;white-space:nowrap}
/* 카드에서는 라벨이 **절대 줄어들지 않는다**(flex:none) — 좁으면 칩이 접히지, 글자가 깎이지 않는다.
   margin-right 는 위쪽 슬롯용 규칙에서 새어 들어온 4px 이다. 여기선 column-gap 이 그 일을 하므로
   지운다(그 4px 이 폰에서 칩 2개짜리를 괜히 아랫줄로 밀어내고 있었다).
   max-width 는 마지막 안전망 — 라벨 하나가 한 줄보다 길어지는 날에는 그때만 …로 줄인다. */
.pet-badges>.pet-role{flex:none;margin-right:0;max-width:100%}
/* 카드 content 끝(테두리에서 4px)에 딱 붙으면 배지가 박스라 답답해 보인다 — 2px 더 물린다.
   3px 이었는데, 그 1px 이 폰에서 접히느냐 마느냐를 갈라 한 칸 줄였다(위 피로도 막대는 0px 이다). */
.pet-badges{justify-content:space-between;align-items:center;padding:0 2px;box-sizing:border-box}
/* 칩 사이 간격 — 첨자가 칩 밖으로 1px 나오므로 4px 이면 3px 이 남는다(실측). */
.pb-set{display:flex;gap:4px;margin-left:auto}
/* 편성 슬롯은 폭이 좁다 — 레벨/피로와 한 줄에 서므로 더 작게. */
.slot-tile .pet-role{margin-right:4px;padding:1px 3px;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
/* 상세 모달 상태 줄 — '전투 팀 편성' 옆에 같은 크기로 선다. */
.pet-detail-status .role{background:#33271e}
/* ⚠️ `.role-*` 는 이 파일 앞쪽(상대 정찰용)에 있어 같은 특이도로는 위 `.pet-role` 에 밀린다.
   조합 선택자로 다시 얹어야 색이 산다(실측: 안 그러면 전부 기본 회색으로 나온다). */
.pet-role.role-tank,.pet-detail-status .role.role-tank{border-color:#6f9ec7;color:#a9d8ff}
.pet-role.role-ranged,.pet-detail-status .role.role-ranged{border-color:#62a77f;color:#a7e7bd}
.pet-role.role-aoe,.pet-detail-status .role.role-aoe{border-color:#a06dc2;color:#dcb4f5}
.pet-role.role-support,.pet-detail-status .role.role-support{border-color:#c1a35e;color:#ffe09a}
.pet-role.role-melee,.pet-detail-status .role.role-melee{border-color:#b46868;color:#f2aaaa}

/* BGM lives in each screen's own header, not in a page-covering overlay. */
/* 자리 규칙은 공통 헤더(.bar.has-bgm-control)가 이미 갖고 있다 — 던전 헤더도 .bar 다. */
/* 월드 화면의 도구 묶음 주차 칸 — bgm.js 가 월드일 때 묶음을 여기로 옮긴다. 월드는 자기 메뉴가 있어 **늘 숨긴다**(2026-09-24). */
.world-bgm-dock{display:none!important}
.battle-panel .battle-top-actions{flex-direction:column;align-items:flex-end;gap:4px}
.battle-top-actions .bgm-control{max-width:none}
.battle-top-actions .bgm-toggle,.battle-top-actions .bgm-next{background:#34291f;color:#d9d4c9;border-color:#170b0c}
.battle-top-actions .bgm-next{display:none}
.battle-top-actions .bgm-track-title{display:none}

/* ── 모바일 절전(무입력 60초) — 던전 화면 ─────────────────────────────────
   game.js 가 body.power-save 를 토글한다. 예전에는 이 클래스가 방치 화면에서만 붙어서
   3D 가 도는 던전이 통째로 절전 사각지대였다(2026-08-19 수정).
   선택자를 하나씩 나열하지 않고 컨테이너 단위로 묶는다 — 나열식은 새 애니메이션이 추가될
   때마다 조용히 새기 때문이다. animation-play-state 는 레이아웃에 영향이 없고, 해제하면
   멈춘 지점에서 이어서 재생된다.
   ⚠️ 전투 중에는 절전이 걸리지 않는다(dungeon.js 의 registerBlocker) — 그 가드가 빠지면
   진행 중인 전투 연출이 얼어붙는다. */
/* ⚠️ `*` 는 타입 선택자라 ::before/::after 를 매칭하지 않고 animation-play-state 는 상속되지도
   않는다. 확장하지 않으면 pseudo 애니메이션(shinySweep·rewardHolo·dtabSheen·marqueeSpin 등)이
   절전을 통째로 통과한다 — 옛 나열식 규칙이 오히려 커버하던 것들이다. */
body.power-save #dungeonMode *,
body.power-save #dungeonMode *::before,
body.power-save #dungeonMode *::after{animation-play-state:paused!important}

/* ══ 배틀 내비 버튼 — 불꽃 격투 연출 ═════════════════════════════════════════
   배틀 허브가 던전 화면 **안쪽**에 있어서 존재를 모르는 사람이 많았다. 하단 내비로
   끌어올리면서 "여기서 붙는다"가 한눈에 읽히도록 불이 붙은 버튼으로 만든다.
   ⚠️ 상시 노출이라 월드보스 드래곤(로비가 열린 동안**만** 뿜는다)만큼 크게 태우지 않는다 —
      평상시는 낮게 일렁이고, 그 화면에 있을 때(.active)와 누르는 순간에만 확 붙는다.
   ⚠️ **keyframes 로 바꾸는 속성은 시작 프레임 값을 규칙 본문에도 적는다.** reduce 환경에서는
      animation 이 죽어 속성이 기본값으로 되돌아가는데, opacity 를 keyframes 에만 두면 불꽃이
      버튼을 통째로 덮는다(2026-08-04 조합 공략집이 정확히 이 사고였다).
   ⚠️ 장식 레이어에는 pointer-events:none — 없으면 버튼 클릭을 장식이 먹는다. */
.game-mode-nav button[data-game-mode="battle"]{position:relative;isolation:isolate;overflow:hidden}
.game-mode-nav button[data-game-mode="battle"]>.battle-nav-icon,
.game-mode-nav button[data-game-mode="battle"]>.battle-nav-label{position:relative;z-index:2}
.battle-nav-label{text-shadow:0 1px 2px #2a0a02,0 0 6px rgba(255,142,58,.55)}
/* ⚠️ 여기 있던 `.battle-nav-icon{filter:drop-shadow(...)}` 는 지웠다 — 아이콘이 PNG 타일이
   된 뒤로는 두 상태 모두 다른 규칙이 filter 를 덮어써(비활성=saturate/brightness,
   활성=아래 금빛 글로우) 이 줄에 닿는 경우가 없었다. */
.game-mode-nav button[data-game-mode="battle"].active .battle-nav-icon{filter:drop-shadow(0 0 5px #ffb64a) drop-shadow(0 1px 2px #2a0a02)}

/* 화염 레이어 — 컨테이너 자체는 크기가 없고(font-size:0) 자식 넷이 층을 이룬다.
   ::before 화염 본체 / i 코어(속불) / b 임팩트 섬광 / em 불티. */
.battle-nav-flame{position:absolute;z-index:0;inset:0;display:block;overflow:hidden;pointer-events:none;font-size:0;opacity:.62}
.game-mode-nav button[data-game-mode="battle"].active .battle-nav-flame{opacity:.95}

.battle-nav-flame::before{content:"";position:absolute;left:-6%;right:-6%;bottom:-2px;height:20px;opacity:.82;transform:scaleY(1);transform-origin:50% 100%;
  background:radial-gradient(ellipse at 50% 100%,#fff3c4 0 9%,#ffd24a 16%,#ff8b21 34%,#e5401b 52%,rgba(150,26,10,.55) 68%,transparent 82%);
  clip-path:polygon(0 100%,6% 62%,17% 78%,24% 30%,34% 64%,42% 12%,50% 48%,58% 6%,66% 52%,75% 22%,82% 70%,93% 56%,100% 100%);
  filter:blur(.3px);animation:battleNavFlame 1.05s cubic-bezier(.45,0,.55,1) infinite}
.battle-nav-flame i{position:absolute;left:24%;right:24%;bottom:-1px;height:12px;opacity:.88;transform:scaleY(1);transform-origin:50% 100%;
  background:radial-gradient(ellipse at 50% 100%,#fffbe8 0 18%,#ffe27a 40%,rgba(255,150,40,.6) 70%,transparent 88%);
  clip-path:polygon(0 100%,12% 58%,26% 74%,36% 22%,50% 58%,62% 16%,72% 66%,88% 50%,100% 100%);
  animation:battleNavCore .72s ease-in-out infinite}

/* 임팩트 섬광 — 격투 히트의 "쾅". 평상시엔 숨어 있고 그 화면에 있을 때만 터진다. */
.battle-nav-flame b{position:absolute;left:50%;top:44%;width:26px;height:26px;margin:-13px 0 0 -13px;opacity:0;transform:scale(.4) rotate(0deg);
  background:radial-gradient(circle,#fff 0 18%,#ffe08a 34%,rgba(255,138,40,.75) 52%,transparent 72%);
  clip-path:polygon(50% 0,60% 34%,90% 12%,68% 42%,100% 50%,68% 58%,90% 88%,60% 66%,50% 100%,40% 66%,10% 88%,32% 58%,0 50%,32% 42%,10% 12%,40% 34%)}
.game-mode-nav button[data-game-mode="battle"].active .battle-nav-flame b{animation:battleNavImpact 2.4s ease-out infinite}
.game-mode-nav button[data-game-mode="battle"]:active .battle-nav-flame b{opacity:.95;transform:scale(1.15) rotate(18deg);animation:none}

/* 불티 — 점 하나에 box-shadow 로 네 개를 더 찍는다(요소를 늘리지 않으려고). */
.battle-nav-flame em{position:absolute;left:46%;bottom:9px;width:2px;height:2px;border-radius:50%;opacity:.8;transform:translateY(0);
  background:#ffd98a;box-shadow:-13px -3px 0 -.5px #ff9a3c,11px -6px 0 -.5px #ffc45e,-6px -9px 0 -1px #ff7a2a,17px -1px 0 -1px #ffae4d;
  animation:battleNavEmber 1.9s linear infinite}

@keyframes battleNavFlame{
  0%,100%{transform:scaleY(1);opacity:.85}
  28%{transform:scaleY(1.28) translateX(.6px);opacity:1}
  54%{transform:scaleY(.88) translateX(-.5px);opacity:.72}
  76%{transform:scaleY(1.16);opacity:.95}}
@keyframes battleNavCore{
  0%,100%{transform:scaleY(1);opacity:.9}
  40%{transform:scaleY(1.35);opacity:1}
  70%{transform:scaleY(.82);opacity:.78}}
@keyframes battleNavImpact{
  0%,72%{opacity:0;transform:scale(.4) rotate(0deg)}
  78%{opacity:.95;transform:scale(1.1) rotate(12deg)}
  86%{opacity:.45;transform:scale(.85) rotate(20deg)}
  92%{opacity:.8;transform:scale(1) rotate(26deg)}
  100%{opacity:0;transform:scale(.5) rotate(34deg)}}
@keyframes battleNavEmber{
  0%{opacity:0;transform:translateY(0)}
  18%{opacity:.85}
  100%{opacity:0;transform:translateY(-19px)}}

/* 활성 — 버튼 자체가 달아오른다. 기본 `.active`(보라)를 덮어야 하므로 특정성을 한 칸 올린다. */
/* ⚠️ 받침(background)을 두지 않고, 금빛 막대도 **아래**에 둔다 — 나머지 여섯 칸과 같아야
   한다(「타일이 곧 버튼」). 예전에는 이 칸만 채워진 판에 막대가 **위**로 붙어, 일곱 중
   하나만 선택 표시가 반대 방향을 가리켰다. 불꽃 레이어는 그대로라 이 칸의 정체성은 남는다. */
.game-mode-nav button[data-game-mode="battle"].active{color:#ffeacc;box-shadow:inset 0 -3px 0 #ff9c34,0 0 14px rgba(255,105,32,.34)}
body.has-sticker .game-mode-nav button[data-game-mode="battle"].active{box-shadow:inset 0 3px 0 #ff9c34,0 0 14px rgba(255,105,32,.34),0 0 10px var(--sticker)}
.game-mode-nav button[data-game-mode="battle"]:active{transform:translateY(1px)}

/* 절전(규칙 32) — 하단 내비는 `#dungeonMode` 밖이라 그 컨테이너 규칙에 안 걸린다.
   상시 도는 연출이므로 여기서 함께 재운다(월드보스 드래곤 불꽃도 같은 컨테이너다). */
body.power-save .game-mode-nav *,
body.power-save .game-mode-nav *::before,
body.power-save .game-mode-nav *::after{animation-play-state:paused!important}

/* reduce — 위치가 움직이는 것(불티 상승·임팩트 회전)만 멈추고 **불은 계속 타게** 둔다.
   이 버튼의 연출은 장식이 아니라 "여기가 대전"이라는 신호라, 통째로 끄면 다른 칸과
   구분이 사라진다. 정지 시 보이는 모습은 위 본문의 시작 프레임 값 그대로다. */
@media(prefers-reduced-motion:reduce){
  .battle-nav-flame em{animation:none;opacity:.7}
  .game-mode-nav button[data-game-mode="battle"].active .battle-nav-flame b{animation:none;opacity:0}
  .battle-nav-flame::before{animation-duration:2.6s}
  .battle-nav-flame i{animation-duration:2s}}

/* 칸이 많아지면 2줄로 접는다 — 6칸부터 "던전게임"(4글자)이 칸 폭을 넘겨 내비 전체가
   가로로 삐져나간다. 열 수는 JS 만 알기 때문에 game.js 가 data-cols 로 알려준다. */
/* ⚠️ 2026-08-29: 세로 접기·글자 축소는 이제 **칸 수와 무관하게 항상** 적용된다
   (파일 끝 「타일이 곧 버튼」 블록). 여기 있던 `flex-direction`·`gap`·`padding`·
   `font-size` 와 `button>span{font-size:13px}` 를 지운 이유가 그것이다 —
   특히 그 `13px` 이 아이콘 크기(`1.5em`)를 칸 수에 따라 22.5px→19.5px 로 줄여
   "7칸일 때만 아이콘이 작아지는" 원인이었다. 남긴 것은 7칸 전용 자간뿐이다. */
/* 라벨 9px 되돌리기 패치는 지웠다 — 위에서 `font-size:15px` 자체를 없애 라벨이 버튼
   기본값(9px)을 그대로 물려받는다. 칸 수와 무관하게 일곱 칸이 같은 크기다. */
/* 2줄 배치에서는 라벨이 아래로 내려와 화염과 같은 자리에 온다 — 불을 더 낮춘다.
   (라벨을 위로 올리는 대신 불을 낮추는 이유: 아이콘이 위, 이름이 아래라는 다른 칸의
    순서를 이 칸만 뒤집으면 내비 전체가 어긋나 보인다.) */
.game-mode-nav[data-cols="6"] .battle-nav-flame::before,
.game-mode-nav[data-cols="7"] .battle-nav-flame::before{height:15px}
.game-mode-nav[data-cols="6"] .battle-nav-flame i,
.game-mode-nav[data-cols="7"] .battle-nav-flame i{height:9px}
.game-mode-nav[data-cols="6"] .battle-nav-flame em,
.game-mode-nav[data-cols="7"] .battle-nav-flame em{bottom:6px}

/* ── 모드 내비 · 서브탭 아이콘: 「타일이 곧 버튼」 (2026-08-29) ─────────────────
   `web/assets/icon/` 17종은 금테와 받침을 가진 **완성된 버튼 면**이다. 그걸 또 다른
   버튼 면(#2a2232 + 구분선) 위에 작게 얹었더니 액자가 두 겹이 되어 겉돌았다.
   받침을 걷어내고 타일을 버튼 그 자체로 쓴다.

   ⚠️ **앞선 선언보다 뒤에 있어야 이긴다.** 위쪽에 `.game-mode-nav button` 이 세 벌
      (기본 16~18줄 · 파스텔 ~606줄 · 다크 재확인 ~665줄) 있고 전부 우선순위가 같아
      **순서로만** 갈린다 — 앞에 끼우면 조용히 진다. (파스텔 벌은 이미 죽은 코드다:
      665줄이 같은 특정성으로 같은 속성을 뒤에서 다시 선언한다.)
      "파일 맨 끝"이라고 적어 두지 않는다 — 이 블록 뒤로 거점 작전실 CSS 가 이어져
      그 말이 처음부터 사실이 아니었다. 지켜야 할 것은 **저 셋보다 뒤**라는 것뿐이다.
   ⚠️ 칸 수(data-cols)에 따라 가로↔세로가 뒤집히고 아이콘이 22.5px→19.5px 로 줄던
      규칙은 위에서 걷어냈다. 이제 3칸이든 7칸이든 타일 크기가 같다. */
.game-mode-nav button{
  flex-direction:column;gap:3px;padding:5px 1px 4px;
  border-right:2px solid #08060a;
  font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;line-height:1.15;
}
/* ⚠️ transition 은 transform 만이다. filter 는 넣어도 못 흐른다 — 비활성은
   `saturate() brightness()`, 활성은 `drop-shadow()` 라 함수 목록이 달라 CSS 가
   보간을 포기하고 중간에 뚝 끊는다. 적어 두면 "부드럽게 빛난다"고 오해하게 된다. */
.game-mode-nav button>span.gi{width:32px;height:32px;transition:transform .16s ease}
/* 안 고른 칸은 한 걸음 물러난다 — 일곱 개가 전부 쨍하면 지금 어디인지가 안 보인다. */
.game-mode-nav button:not(.active)>span.gi{filter:saturate(.72) brightness(.82)}
/* 선택 표시가 **색칠이 아니라 타일 자체**다. 받침을 지웠으니 칠할 면도 없거니와,
   커지고 빛나는 편이 좁은 칸에서 훨씬 빨리 읽힌다. */
.game-mode-nav button.active>span.gi{transform:scale(1.14);
  filter:drop-shadow(0 0 6px rgba(243,198,91,.75))}
/* 하단 메뉴 = 월드 블록 그림 (2026-10-12 · 사용자 S2 「C 월드 블록 자체 그래픽 · 방치게임 · 월드보스 · 상점은 대안 그림」 ·
   시안 https://claude.ai/artifact/NnYqEWEhWyR3P5Wbmwz2qf). 블록 그림에는 금테 · 받침이 없어 위 두 규칙이 칸 면(보라 칸 · 고른 칸 금빛 윗줄)을 되살렸다.
   그림은 **메뉴 안에서만** 바꾼다 — `.gi-door` 같은 클래스 자체를 바꾸면 부족 · 던전 다른 자리 그림까지 바뀐다. 그림 원본은 tools/world_block_icons.py. */
/* 10-13 메뉴 재구성 B5-1(S1 v3 승인) — 방치게임 → 「홈」(집) · 던전게임 → 「사냥」(칼). 키(idle · dungeon)는 그대로 — 옛 주소 · 알림 링크 · 시험이 그 키를 쓴다. */
.game-mode-nav [data-game-mode="idle"]>span.gi{background-image:url(/world/ui/block/home.svg?v=20261013nv)}
.game-mode-nav [data-game-mode="dungeon"]>span.gi{background-image:url(/world/ui/block/swords.svg?v=20261013nv)}
.game-mode-nav [data-game-mode="worldboss"]>span.gi{background-image:url(/world/ui/block/skull.svg?v=20261012nb)}
.game-mode-nav [data-game-mode="world"]>span.gi{background-image:url(/world/ui/block/globe.svg?v=20261012nb)}
.game-mode-nav [data-game-mode="shop"]>span.gi{background-image:url(/world/ui/block/chest.svg?v=20261012nb)}
.game-mode-nav [data-game-mode="collection"]>span.gi{background-image:url(/world/ui/block/book.svg?v=20261012nb)}

/* 서브탭·CTA 는 사정이 다르다 — 이미 **자기 색 그라디언트와 베벨**을 가진 버튼이라
   받침을 걷어내면 그 정체성(초록=편성·주황=자동훈련·보라=아이템·금색=적립)이 사라진다.
   그래서 여기는 규칙의 절반만 쓴다: 타일을 키우고, 어두운 그림자로 **바탕색에서
   떼어 놓는다**. 금테가 컬러 위에서 진동하던 것이 이 그림자 하나로 가라앉는다. */
.idle-subnav .tab-icon.gi,
.dungeon-subnav .dtab-hero .dtab-icon.gi,
.cta-hero .cta-icon.gi{filter:drop-shadow(0 2px 3px rgba(0,0,0,.55))}
/* 크기는 자리마다 다르다 — 방치 서브탭만 세로 배치라 높이 예산(53px)에 묶여 더 작다.
   그 값은 아래 「방치 서브탭도 세로로」 블록이 정한다(계산 주석도 거기 있다).
   여기 셋을 한 줄로 묶어 두면 그 값이 조용히 26px 로 덮여 계산이 어긋난다. */
.dungeon-subnav .dtab-hero .dtab-icon.gi,
.cta-hero .cta-icon.gi{width:26px;height:26px}

@media(max-width:360px){
  .game-mode-nav button>span.gi{width:28px;height:28px}
  .dungeon-subnav .dtab-hero .dtab-icon.gi,
  .cta-hero .cta-icon.gi{width:23px;height:23px}
}
@media(prefers-reduced-motion:reduce){
  .game-mode-nav button>span.gi{transition:none}
}

/* 방치 서브탭도 '아이콘 위 · 이름 아래' 로 맞춘다 (2026-08-29) ─────────────────
   원래 이 줄만 가로(아이콘 옆 이름)였다. 공통 컴포넌트라서가 아니라 **칸 폭 때문**이다 —
   던전 줄은 5칸이라 한 칸이 86px 이고 "자동 훈련"이 가로로 안 들어가 세로로 접었는데,
   방치 줄은 3칸이라 115px 씩 나와서 가로로도 들어갔다. 그래서 각자 따로 정해져 있었다.

   이제 바로 아래 모드 내비까지 항상 세로가 되면서 이 줄만 혼자 가로로 남았다. 맞춘다.

   ⚠️ 셀 높이는 53px 뿐이다(--subnav-height 56 - 테두리). 지금 값 그대로 세로로 세우면
      8+26+3+12+8 = 55px 라 **2px 넘친다**(실측). 그래서 패딩과 아이콘을 함께 줄인다:
      5+24+3+12+5 = 53px — 딱 맞는다. 셋 중 하나만 되돌리면 라벨 아랫부분이 잘린다. */
.idle-subnav .tab{flex-direction:column;gap:3px;padding:5px 3px}
.idle-subnav .tab-icon.gi{width:24px;height:24px}

@media(max-width:360px){
  /* 위쪽 좁은 화면 규칙(.idle-subnav .tab{gap:5px;padding:7px 4px})은 세로 배치에서
     53px 를 정확히 채워 여유가 0 이 된다 — 글꼴이 조금만 달라도 잘린다. 다시 줄인다. */
  .idle-subnav .tab{gap:2px;padding:4px 3px}
  .idle-subnav .tab-icon.gi{width:23px;height:23px}
}


/* ── 거점 작전실 (docs/plans/FRONT_DASHBOARD_UX_REDESIGN.md) ──────────────
   ⚠ 겉모습은 **던전 화면의 규칙을 그대로 따른다**: 픽셀 폰트(Galmuri)·2px 각진 테두리·
     무광 단색·토큰 색(`--line`/`--panel2`/`--ink`/`--muted`/`--dq-gold`).
     처음엔 둥근 모서리와 그라디언트로 그렸다가 "테마와 안 어울린다"는 제보를 받았다 —
     새 색을 만들지 말고 있는 토큰을 쓸 것.
   ⚠ **화면은 하나다.** 예전의 `.fr-map` / `.fr-battle` 두 층과 `is-battle` 전환은 폐기했다.
     그 전환 때문에 사용자가 자기 위치를 잃었다.
   ⚠ 조작 요소는 **44px 이상**이다(모바일 게이트). 8~10px 칩으로 줄이지 말 것.
   ⚠ 상태를 **색만으로** 말하지 않는다 — 아이콘·글자를 함께 둔다(색맹·고대비). */
.dungeon-panel.is-front{padding:8px}
.fr-bar{display:flex;align-items:center;gap:8px;margin-bottom:6px;min-height:28px}
.fr-head{display:flex;align-items:center;gap:6px;flex-wrap:wrap;flex:1;min-width:0}
.fr-me-tribe{display:inline-flex;align-items:center;gap:4px;padding:3px 8px;
  border:2px solid var(--tribe,#b6a387);background:#35281f;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#f3e6cf}
.fr-me-tribe.is-none{border-color:#89785e;color:var(--muted,#c9b491)}
/* 부족장 이름 — 본인이면 아래 `fr-chief` 뱃지가 대신 뜬다. */
.fr-chief-name{padding:3px 7px;border:2px solid #8a6c57;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:var(--muted,#c9b491);white-space:nowrap}
.fr-chief{padding:3px 7px;border:2px solid var(--dq-gold,#d9a441);
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#fff5da}
.fr-clock{margin-left:auto;font:700 10px "Galmuri9","Galmuri11",sans-serif;color:var(--muted,#c9b491)}

/* 실시간 전장 — 작전실 **밖**에 있다(작전실은 6초마다 다시 그려진다). */
.fr-live{position:relative;border:2px solid #8a6c57;background:#100c08;margin-bottom:6px;line-height:0}
.fr-live canvas{width:100%;aspect-ratio:16/10;display:block}
.fr-siege-canvas{min-height:180px}
.fr-siege-hud{position:absolute;inset:auto 6px 6px;z-index:2;pointer-events:none;line-height:normal}
.fr-stage-bar{position:absolute;z-index:4;inset:8px 8px auto;display:flex;align-items:center;gap:8px;
  pointer-events:none;line-height:normal}.fr-stage-name{min-width:0;overflow:hidden;text-overflow:ellipsis;
  color:#fff5da;font:700 12px "Galmuri11","Galmuri9",sans-serif;text-shadow:0 2px 4px #000}
.fr-stage-size{margin-left:auto;min-height:36px;padding:7px 10px;border:2px solid #b5996e;background:#1f1711e8;
  color:#fff5da;font:700 10px "Galmuri9","Galmuri11",sans-serif;pointer-events:auto;cursor:pointer}
.sg-hud{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px;align-items:end;pointer-events:none}
.sg-orders{grid-column:1/-1;display:flex;align-items:center;gap:5px;min-width:0;pointer-events:auto}
.sg-objectives{display:flex;gap:4px;min-width:0}
.sg-objective{min-height:36px;color:#f3e6cf;
  font:700 10px "Galmuri9","Galmuri11",sans-serif}
/* 예비 편성 눈금 — 읽는 값이라 단추처럼 보이면 안 된다(테두리 없음·커서 기본). */
.sg-teams{flex:0 0 auto;align-self:center;padding:5px 7px;white-space:nowrap;cursor:default;
  background:#261d16d0;color:#cbb98a;font:700 10px "Galmuri9","Galmuri11",sans-serif}
/* 다음 팀을 기다리는 동안 — 전장에 내 펫이 하나도 없다는 걸 색으로도 말한다. */
.sg-teams.is-waiting{color:#ffb37a;background:#3a241bd0}
/* 열세 보정 — 팀 눈금과 같은 결(읽는 값). 내 쪽이 받으면 푸른빛, 상대가 받으면 붉은빛. */
.sg-underdog{flex:0 0 auto;align-self:center;padding:5px 7px;white-space:nowrap;cursor:default;
  background:#16232ad0;color:#8fd3e8;font:700 10px "Galmuri9","Galmuri11",sans-serif}
.sg-underdog.is-theirs{color:#f0a0a0;background:#2e1a1cd0}
/* 리스폰 카운트 — 화면 한가운데. **조작을 가리지 않는다**(pointer-events:none).
   ⚠ `position:fixed` 다. HUD 는 `inset:auto 6px 6px` 로 **아래에 붙은 띠**라, 그 안에서
     `top:44%` 를 잡으면 화면 아래쪽에 뜬다. 전체 화면 무대일 때만 그린다 —
     작전실 안의 작은 상자 위에 화면 한가운데 글자를 띄우면 엉뚱한 자리다.
   ⚠ `display:flex` 가 `[hidden]` 을 이긴다 — 아래에서 다시 감춘다. */
.sg-respawn{position:fixed;left:50%;top:46%;transform:translate(-50%,-50%);
  display:flex;flex-direction:column;align-items:center;gap:4px;pointer-events:none;
  text-align:center;text-shadow:0 2px 0 #000,0 0 12px #000}
.sg-respawn[hidden]{display:none}
.fr-live:not(.is-full) .sg-respawn{display:none}
.sg-respawn b{font:700 46px "Galmuri11","Galmuri9",sans-serif;color:#ffd9a8;line-height:1}
.sg-respawn span{font:700 12px "Galmuri11","Galmuri9",sans-serif;color:#ffb37a}
@media(max-width:600px){.sg-respawn b{font-size:34px}}.sg-objectives{grid-column:1/-1}.fr-live.is-full .sg-objectives{position:fixed;z-index:5;top:calc(8px + env(safe-area-inset-top));left:calc(max(8px,env(safe-area-inset-left)) + 166px);right:calc(max(8px,env(safe-area-inset-right)) + 76px);justify-content:center;pointer-events:none}.sg-objective{flex:1 1 auto;min-width:0;max-width:560px;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:3px 8px;align-items:baseline;padding:6px 9px 7px;text-align:left;cursor:default;border:1px solid #7a5aa0;border-radius:4px;background:linear-gradient(90deg,#04040be8,#271c14e0 50%,#04040be8);box-shadow:0 6px 24px #0009}
.sg-objective b{grid-area:1/1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;color:#fff5da}.sg-objective span{grid-area:2/1/2/3;height:11px;border:1px solid #1a130e;background:#1f1711;background-image:repeating-linear-gradient(90deg,transparent 0 24.6%,#0007 24.6% 25.4%)}.sg-objective span i{display:block;height:100%;background:var(--sg-hp,#7fe08a);box-shadow:0 0 10px var(--sg-hp,#7fe08a);transition:width .18s linear}
.sg-objective small{grid-area:1/2;justify-self:end;font-size:15px;font-family:"Galmuri14","Galmuri11",sans-serif;line-height:1;color:#fff5da}.sg-objective[data-hp="ok"]{--sg-hp:#7fe08a}.sg-objective[data-hp="warn"]{--sg-hp:#ffc65a;border-color:#a8823f}.sg-objective[data-hp="danger"]{--sg-hp:#ff6b5e;border-color:#a8504a}
.sg-objective-empty{margin:0;padding:5px;color:#c9b491;font:700 10px "Galmuri9","Galmuri11",sans-serif;white-space:nowrap}
/* 아군 — **사람 단위** 한 줄(펫 150마리를 나열하지 않는다). 읽는 값이라 단추가 아니다. */
.sg-allies{grid-column:1/-1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  padding:4px 7px;background:#1f1711cc;border:1px solid #3f5a4a;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#8de0bb;pointer-events:none}
.sg-allies[hidden]{display:none}
/* 신호 — 정해진 셋뿐이다(자유 채팅 없음). 44px 은 손가락 최소 크기다. */
.sg-pings{grid-column:1/-1;display:flex;gap:5px;flex-wrap:wrap;pointer-events:auto}
.sg-ping{min-height:36px;padding:6px 9px;cursor:pointer;
  border:2px solid #8a6c57;background:#2e221ae8;color:#f3e6cf;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;touch-action:manipulation}
.sg-ping.is-cold{opacity:.45;cursor:default}
.sg-ping:focus-visible{outline:2px solid var(--dq-gold,#d9a441);outline-offset:2px}
/* 받은 신호 — 몇 초 떴다 접힌다(권위 상태가 아니라 부름이다). */
.sg-signal{grid-column:1/-1;padding:5px 8px;border:2px solid #d9a441;background:#3a2d1de8;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#fff5da;pointer-events:none}
.sg-signal[hidden]{display:none}
.sg-signal.is-help{border-color:#e46d60;background:#3a1f1de8;color:#ffd9d5}
.sg-signal.is-defend{border-color:#78bce8;background:#1d2a3ae8;color:#d8ecff}
/* 공성 사건 배너(10분 공성) — 성문이 무슨 짓을 했는지 한 줄. 신호 띠와 같은 결이되 사건마다 색이 다르다. */
.sg-event{grid-column:1/-1;padding:5px 8px;border:2px solid #9fd8ff;background:#1b2a3ae8;color:#e8f6ff;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;pointer-events:none}
.sg-event[hidden]{display:none}
.sg-event.is-oil-warn,.sg-event.is-oil{border-color:#ff8a3c;background:#3a221ae8;color:#ffe0c8}
.sg-event.is-slam,.sg-event.is-volley{border-color:#c9b08a;background:#2b2418e8;color:#f3e6cf}
.sg-event.is-repair{border-color:#7ddc9a;background:#1a2f22e8;color:#d8ffe4}
.sg-event.is-repair-blocked{border-color:#8a8a8a;background:#242424e8;color:#dddddd}
.sg-event.is-rally{border-color:#ff9b6b;background:#3a1f1ae8;color:#ffd9c8}
.sg-event.is-breach{border-color:#ffd9a8;background:#3a2a1ae8;color:#fff1d6;animation:sg-event-pop .5s ease-out}
@keyframes sg-event-pop{0%{transform:scale(.92)}60%{transform:scale(1.04)}100%{transform:scale(1)}}
/* 방어선 칸 — 방벽·수리 상태를 칸에도 적는다(배너가 지나간 뒤에도 남는 눈금). */
.sg-objective.is-barrier{border-color:#9fd8ff;box-shadow:inset 0 0 0 1px #9fd8ff80}.sg-objective.is-barrier span i{background:#9fd8ff}
.sg-objective.is-repair span i{background:#7ddc9a}
.sg-objective[data-sg-tag]::after{grid-area:3/1/3/3;content:attr(data-sg-tag);color:#9fd8ff;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}
.sg-squad{display:flex;gap:4px;min-width:0;overflow-x:auto;pointer-events:auto}
.sg-pet,.sg-skill{min-height:40px;border:2px solid #8a6c57;background:#2e221a;color:#f3e6cf;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;cursor:pointer}
.sg-pet{flex:1 0 66px;display:grid;gap:3px;padding:4px;text-align:left}
.sg-pet.is-on{border-color:var(--dq-gold,#d9a441);background:#382d1d}
.sg-pet.is-down{opacity:.58}.sg-pet b{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sg-hp{height:5px;border:1px solid #1a130e;background:#1f1711}.sg-hp i{display:block;height:100%;background:#83d78f}
.sg-skills{grid-column:1/-1;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;min-width:0;pointer-events:auto}.sg-pet-skills{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));align-content:start;gap:4px;min-width:0;padding:4px;border:1px solid #68503f;background:#1f1711cc}.sg-pet-skills h4{grid-column:1/-1;margin:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#fff5da}.sg-pet-skills>small{grid-column:1/-1;color:#b8aa95}.sg-skill{min-width:0;min-height:38px;padding:4px;display:grid;gap:3px;text-align:left}.sg-skill b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.sg-skill-meter{display:block;height:6px;border:1px solid #1a130e;background:#120d0a;overflow:hidden}.sg-skill-meter i{display:block;width:100%;height:100%;background:linear-gradient(90deg,#62d5ff,#a8f29b);transition:width .12s linear}.sg-skill.is-cold .sg-skill-meter i{background:#917e61}.sg-skill.is-cold{opacity:.7}.sg-skill.is-pending{border-color:#8ec2e0}.sg-skill.is-reject{border-color:#d98a8a}
/* 스킬 묶음 머리말 = 이름 + 체력 + 숫자. 분대 카드를 없애고 여기로 합쳤다(2026-09-01)
   — 같은 이름을 두 번 보여 주던 줄이 통째로 빠져 HUD 높이가 줄었다. */
.sg-pet-skills h4{display:flex;align-items:center;gap:5px;margin:0 0 3px}
.sg-pet-skills h4>span:first-child{flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sg-pet-skills h4 .sg-hp{flex:1 1 auto;min-width:24px}
.sg-pet-skills h4 small{flex:0 0 auto;opacity:.85}
.sg-pet-skills.is-down{opacity:.42;filter:grayscale(1)}/* 쓰러진 자리는 **지우지 않고 회색으로** 남긴다 — 카드가 사라지면 사람은 그 펫이   출전을 안 한 것으로 읽는다(2026-09-09 제보). 10초 뒤 다음 예비가 이 자리에 온다. */
.sg-squad:empty{display:none}
.sg-note{grid-column:1/-1;justify-self:end;max-width:70%;margin:0;padding:3px 6px;background:#1f1711cc;
  color:#f3e6cf;font:700 10px "Galmuri9","Galmuri11",sans-serif;line-height:1.45;pointer-events:none}
body.is-siege-stage{overflow:hidden;touch-action:none}
.fr-live.is-full{position:fixed;z-index:1200;inset:0;margin:0;border:0;min-height:100dvh;width:100vw;background:#06050a;line-height:0}
.fr-live.is-full .fr-siege-canvas{height:100dvh;min-height:100dvh}.fr-live.is-full canvas{width:100%;height:100dvh;aspect-ratio:auto}
.fr-live.is-full .fr-siege-hud{inset:auto max(8px,env(safe-area-inset-right)) max(8px,env(safe-area-inset-bottom)) max(8px,env(safe-area-inset-left))}
.fr-live.is-full .sg-hud{gap:8px}.fr-live.is-full .sg-pet,.fr-live.is-full .sg-skill{min-height:44px}
@media(max-width:600px){.fr-live.is-full .fr-stage-bar{inset:calc(7px + env(safe-area-inset-top)) 7px auto}.fr-live.is-full .fr-siege-hud{bottom:max(7px,env(safe-area-inset-bottom))}.sg-orders{gap:3px}}
@media(max-width:420px){.sg-hud{grid-template-columns:1fr}.sg-skills{justify-content:flex-end}.sg-skill{min-width:52px}}
/* 미니맵 — "다들 어디를 치고 있는지"를 한 장에(2026-09-08 제보). **읽는 그림**이라 눌리지 않는다.
   ⚠ `.sg-respawn` 처럼 `position:fixed` 다 — HUD 는 아래에 붙은 띠라 그 안에서는 무대 위쪽에 닿을 수 없다.
     전체 화면 무대일 때만 그린다 — 작전실 안 작은 상자는 띠가 상자를 다 덮어 자리가 없다.
   ⚠ 선택자가 긴 이유: 위 `.fr-live.is-full canvas{width:100%;height:100dvh}` 가 무대 캔버스뿐 아니라
     이 캔버스까지 잡는다 — 그보다 구체적이어야 크기가 산다(실측: 폰에서 358×798 로 퍼졌다).
   무대 이름 바(36px 단추 + 여백) 바로 아래 오른쪽. 스킬·방어선·신호 칸은 화면 반대편(아래)이라 안 겹친다. */
.fr-live.is-full .sg-map-card{position:fixed;z-index:5;top:calc(8px + env(safe-area-inset-top));left:max(8px,env(safe-area-inset-left));width:150px;pointer-events:none}.sg-map-card{position:relative}.sg-map-name{position:absolute;top:4px;left:6px;max-width:82%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#fff5da;font:700 10px "Galmuri9","Galmuri11",sans-serif;text-shadow:0 2px 4px #000}/* 지도 카드 폭 안에서 **접힌다**. 열세 보정 칩은 무엇이 올랐는지까지 적어서(체력·공격)
   한 줄로 두면 폰에서 카드 밖으로 삐져나온다 — 접히면 카드 아래에 두 줄로 앉는다. */
.sg-map-card .sg-underdog{display:inline-block;margin-top:4px;
  max-width:100%;white-space:normal;line-height:1.4}.sg-map-card .sg-underdog[hidden]{display:none}.fr-live.is-full .sg-map{display:block;
  width:150px;height:150px;border:1px solid #8a6c57b0;background:#100c08b8;pointer-events:none}
.fr-live:not(.is-full) .sg-map-card{display:none}
@media(max-width:600px){.fr-live.is-full .sg-objectives{top:calc(7px + env(safe-area-inset-top));left:calc(max(7px,env(safe-area-inset-left)) + 118px)}.fr-live.is-full .sg-map-card{top:calc(7px + env(safe-area-inset-top));width:104px}.fr-live.is-full .sg-map{width:104px;height:104px}.sg-map-name{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;top:3px;left:4px}.sg-objective{padding:5px 7px 6px}.sg-objective b{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif}.sg-objective small{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}.sg-objective span{height:9px}}

.fr-room{display:grid;gap:8px}
.fr-card{border:2px solid #8a6c57;background:#35281f;padding:10px}
.fr-card h4{margin:0 0 6px;font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#f3e6cf}

/* 선택 거점 요약 — 제목은 지명만. 부족은 아래 정체성 블록이 말한다. */
.fr-spot-name{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin:0 0 8px;
  font:700 15px "Galmuri14","Galmuri11",sans-serif;color:#f3e6cf}
.fr-badge{padding:2px 6px;border:2px solid var(--dq-gold,#d9a441);
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#fff5da}
.fr-state{margin-left:auto;padding:2px 7px;border:2px solid #8a6c57;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:var(--muted,#c9b491)}
.fr-state.is-live{border-color:#d98a8a;color:#ffd9d5}
.fr-state.is-held{border-color:#8ec2a0;color:#cfe8d8}
.fr-state.is-shut{border-color:#89785e}
.fr-facts{margin:6px 0 0;font:700 10px "Galmuri9","Galmuri11",sans-serif;
  color:var(--muted,#c9b491);line-height:1.7}
.fr-gate{height:8px;border:2px solid var(--line,#1a130d);background:#221913;margin:8px 0 0}
.fr-gate>i{display:block;height:100%;background:#d98a8a}

/* 요새 진행도 — 세 갈래와 본진 3단계를 한눈에 비교한다. 값은 서버 fort snapshot만 사용한다. */
.fr-fort-progress{margin-top:9px;padding-top:8px;border-top:1px solid #664f3f}
.fr-fort-progress-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:6px;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#f3e6cf}
.fr-fort-progress-head span{color:#d9a441;font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;text-align:right}
.fr-fort-lanes{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px}
.fr-fort-lane,.fr-fort-keep{display:grid;gap:4px;padding:5px;border:1px solid #664f3f;background:#2c2018}
.fr-fort-lane>strong,.fr-fort-keep>strong{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#c9b491}
.fr-fort-keep{grid-template-columns:repeat(3,minmax(0,1fr));margin-top:5px}
.fr-fort-keep>strong{grid-column:1/-1}
.fr-fort-node{display:grid;gap:2px;min-width:0;font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#c9b491}
.fr-fort-node>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fr-fort-node small{font-size:10px;font-family:"Galmuri9","Galmuri11",sans-serif;color:#b6a387}
.fr-fort-node.is-done{color:#8ec2a0}.fr-fort-node.is-done small{color:#8ec2a0}
.fr-fort-node.is-active{color:#ffd98b}.fr-fort-node.is-active small{color:#d9a441}
.fr-fort-node.is-locked{opacity:.55}
.fr-fort-bar{height:5px;overflow:hidden;border:1px solid #1f1610;background:#1f1610}
.fr-fort-bar>i{display:block;height:100%;background:#d98a8a;transition:width .25s linear}
.fr-fort-node.is-done .fr-fort-bar>i{background:#6ea785}
.fr-fort-node.is-active .fr-fort-bar>i{background:#d9a441}

/* 부족 정체성 — 문양 + 이름 + 관계. 셋이 함께여야 색을 못 읽어도 뜻이 산다. */
.fr-ident{display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto auto;
  gap:2px 8px;align-items:center}
.fr-ident .fr-emblem{grid-row:1/3}
.fr-ident-name{font:700 12px "Galmuri11","Galmuri9",sans-serif;color:#f3e6cf}
.fr-ident-rel{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:var(--muted,#c9b491)}
.fr-emblem .fr-emblem-shield{fill:#221913;stroke:var(--tribe,#b6a387);stroke-width:1.6}
.fr-emblem .fr-emblem-mark{fill:none;stroke:var(--tribe,#b6a387);stroke-width:1.4;
  stroke-linecap:round;stroke-linejoin:round;color:var(--tribe,#b6a387)}
.fr-ident.is-none .fr-emblem-shield{stroke:#89785e}

/* 거점 스트립 — 가로 스크롤. 세로 카드 열은 첫 화면을 목록만으로 채운다. */
.fr-strip{display:flex;gap:6px;overflow-x:auto;padding-bottom:4px;
  scrollbar-width:thin;-webkit-overflow-scrolling:touch}
.fr-spotchip{flex:0 0 auto;min-height:44px;min-width:88px;padding:6px 10px;
  display:grid;gap:2px;text-align:left;cursor:pointer;
  border:2px solid #8a6c57;background:#35281f;color:#c9b491}
.fr-spotchip b{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#f3e6cf}
.fr-spotchip small{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:var(--muted,#c9b491)}
.fr-spotchip.is-on{border-color:var(--dq-gold,#d9a441);background:#3a2d1d}
.fr-spotchip.is-live{border-color:#d98a8a}
.fr-spotchip:focus-visible{outline:2px solid var(--dq-gold,#d9a441);outline-offset:2px}

/* 지금 할 일 — 주행동은 화면마다 **하나**, 전체 폭, 44px 이상. */
.fr-why{margin:0;font:700 10px "Galmuri9","Galmuri11",sans-serif;
  color:var(--muted,#c9b491);line-height:1.8}
/* 이유 아래 한 줄 — 수치·시각만(서버 `front_action_hint`). 비면 그리지 않는다. */
.fr-hint{margin:4px 0 0;font:700 10px "Galmuri9","Galmuri11",sans-serif;
  color:#b6a387;line-height:1.7}
/* 승인자·현장 인원 이름 — 숫자만으로는 사람을 못 부른다. */
.fr-people{margin:4px 0 0;font:700 10px "Galmuri9","Galmuri11",sans-serif;
  color:#8de0bb;line-height:1.7}
.fr-people.is-defend{color:#ffd9d5}
/* 요새 진행은 교전 중에만 펼친다 — 접어 두지 않으면 첫 화면의 220px 을 먹는다. */
.fr-fort-more>summary{cursor:pointer;min-height:36px;display:flex;align-items:center;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#f3e6cf}
.fr-fort-more[open]>summary{margin-bottom:2px}
.fr-acts{display:flex;flex-direction:column;gap:6px;margin-top:8px}
.fr-main{width:100%;min-height:48px;padding:12px;cursor:pointer;
  border:2px solid #8a6c57;background:#35281f;color:#f3e6cf;
  font:700 12px "Galmuri11","Galmuri9",sans-serif}
.fr-main.is-primary{border-color:var(--dq-gold,#d9a441);background:#3a2d1d;color:#fff5da}
.fr-main.is-secondary{color:var(--muted,#c9b491)}
.fr-main.is-link{border-color:transparent;background:none;text-decoration:underline}
.fr-main:focus-visible,.fr-sub:focus-visible,.fr-op:focus-visible{
  outline:2px solid var(--dq-gold,#d9a441);outline-offset:2px}
/* 보조 행동은 텍스트다 — primary 와 색·형태를 공유하지 않는다. */
.fr-sub{min-height:44px;padding:10px;cursor:pointer;border:0;background:none;
  color:var(--muted,#c9b491);text-decoration:underline;
  font:700 10px "Galmuri9","Galmuri11",sans-serif}
.fr-warbar{height:8px;border:2px solid var(--line,#1a130d);background:#221913;margin:8px 0 0}
.fr-warbar>i{display:block;height:100%;background:var(--dq-gold,#d9a441)}

/* 주행동 고정 바 — 위 단추가 화면 밖일 때만 뜬다(§5.3.5).
   ⚠ `.op-overlay`(거점 상세 카드)와 **같은 자리**다. 두 화면은 동시에 열리지 않는다. */
.fr-dock{position:fixed;z-index:61;
  left:var(--mode-nav-left,50%);
  width:var(--mode-nav-width,calc(min(100vw,460px) - 24px));
  transform:translateX(var(--mode-nav-shift,-50%));
  bottom:calc(var(--mode-nav-height) + var(--subnav-height) + env(safe-area-inset-bottom) + 6px);
  box-sizing:border-box;display:grid;grid-template-columns:minmax(0,1fr) auto;
  align-items:center;gap:8px;padding:8px 9px;
  border:2px solid var(--dq-gold,#d9a441);background:rgba(16,12,8,.96);
  box-shadow:0 4px 14px rgba(0,0,0,.55)}
.fr-dock[hidden]{display:none}
.fr-dock .fr-main{width:auto;min-width:132px;min-height:44px;padding:10px 12px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif}
.fr-dock-why{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:var(--muted,#c9b491)}

/* 접힌 것들 — 첫 화면은 "지금 할 일"이 차지한다. */
.fr-more summary,.fr-ops summary{cursor:pointer;min-height:44px;display:flex;
  align-items:center;font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#f3e6cf}
.fr-journal{list-style:none;margin:6px 0 0;padding:0;display:grid;gap:3px}
.fr-journal li{display:flex;gap:6px;padding:2px 7px;
  font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#c9b491;line-height:1.7}
.fr-journal li>span{color:#b6a387;font-variant-numeric:tabular-nums}
.fr-empty{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:var(--muted,#c9b491)}

/* 운영 도구 — 일반 사용자에게는 **DOM 에 없다**(숨김이 아니다). */
.fr-ops{border-color:#8ec2e0;background:#22303a}
.fr-ops summary{color:#cfe8f5}
.fr-op{width:100%;min-height:48px;margin-top:6px;padding:8px 10px;cursor:pointer;
  display:grid;gap:2px;text-align:left;
  border:2px solid #8ec2e0;background:#1a2530;color:#cfe8f5}
.fr-op b{font:700 10px "Galmuri9","Galmuri11",sans-serif}
.fr-op small{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:#9ab6c6}
.fr-op.is-danger{border-color:#d98a8a;background:#3a2228;color:#ffd9d5}
.fr-op.is-danger small{color:#e0a8a8}

/* 공격로 — 갈래는 전장의 공간 자체다(태세와 달리 없앨 수 없다 — UX §10-1). */
.fr-sheet-row{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.fr-lane-pick{margin-top:8px;padding-top:8px;border-top:1px dashed #5b4434}
.fr-lane-label{font:700 10px "Galmuri9","Galmuri11",sans-serif;color:var(--muted,#c9b491)}
.fr-chip{min-height:44px;padding:10px 14px;cursor:pointer;
  border:2px solid #8a6c57;background:#35281f;color:#c9b491;
  font:700 10px "Galmuri9","Galmuri11",sans-serif}
.fr-chip.is-on{border-color:var(--dq-gold,#d9a441);background:#3a2d1d;color:#fff5da}

/* 밝은(파스텔) 테마 — 던전 패널의 3층 규칙을 그대로 밟는다. */
.dq-pastel .fr-card,.dq-pastel .fr-spotchip,.dq-pastel .fr-chip,
.dq-pastel .fr-main{background:var(--panel2);color:var(--ink)}

/* 넓은 화면 2단 배치는 걷어냈다(2026-09-08).
   ⚠ 여기서 재던 `@media (min-width:768px)` 는 **뷰포트** 폭이다. 그런데 이 판은
      `.game-shell{max-width:var(--game-shell-max)}` 로 **어떤 모니터에서든 460px** 에 갇혀 있다.
      그래서 데스크톱에서 2단이 켜지면 `.fr-room` 418px 를 7:5 로 쪼개 **229px / 181px** 이 됐다 —
      폰 1단(390px 화면에서 352px)보다도 좁아 글자가 접히고, 세 카드가 왼쪽에 몰려
      오른쪽 열보다 133px 일찍 끝나며 그 아래가 통째로 빈 채로 남았다(제보 화면).
   컨테이너 쿼리로 고쳐 보려 했으나 `container-type` 은 레이아웃 격리를 걸어
   `#frontPanel` 안의 `position:fixed` 인 `.fr-dock` 의 컨테이닝 블록이 돼 버린다
   (하단 내비와 자리를 맞추는 `--mode-nav-*` 계산이 어긋난다). 셸이 460px 인 한 2단은
   어차피 이득이 없으므로 **모든 폭에서 1단**으로 둔다 — 카드가 418px 를 온전히 쓴다.
   셸 상한(`--game-shell-max`)을 올리게 되면 그때 컨테이너 쿼리로 되살릴 것. */

/* 움직임을 줄여 달라고 한 사람에게는 부드러운 스크롤을 하지 않는다. */
@media (prefers-reduced-motion:reduce){
  .fr-strip{scroll-behavior:auto}
}


/* ══ 종 지정색 그라데이션 + 도감 연출 프리셋 (2026-09-08) ═══════════════════
   방치게임(style.css)과 **같은 클래스 이름**을 쓴다(`.grad` · `.pet-fx` · `.fx-*`) —
   운영자는 펫 마스터에서 연출을 한 번 고르고, 도감·방치·던전이 그걸 같은 이름으로 읽는다.
   다만 색을 담는 변수가 다르다: 방치는 `--pet-bc`, 던전은 예전부터 `--rar` 이다.
   그래서 `--fx-ring`(흐르는 띠) 정의는 **요소를 명시해 가른다** — 두 파일이 같은 페이지에
   실리므로 셀렉터 없이 `.fx-flow{--fx-ring:…}` 로 쓰면 서로를 덮어쓴다. */

.dungeon-pet-card.grad,.slot-tile.filled.grad,.opp-pet.grad,.fb-sum-faces>em.grad{
  border-image:linear-gradient(135deg,var(--rar),var(--rar2,var(--rar))) 1;
}

.dungeon-pet-card.pet-fx,.opp-pet.pet-fx{--fx-inner:var(--panel2)}
.slot-tile.filled.pet-fx{--fx-inner:var(--panel)}
/* ⚠ 띠는 양 끝 색이 같아야 한 바퀴가 이어진다 — 다르면 주기마다 색이 툭 끊긴다. */
.dungeon-pet-card.fx-flow,.slot-tile.filled.fx-flow,.opp-pet.fx-flow{
  --fx-ring:linear-gradient(90deg,var(--rar),var(--rar2,var(--rar)),var(--rar));
}
.dungeon-pet-card.fx-shimmer,.slot-tile.filled.fx-shimmer,.opp-pet.fx-shimmer{
  --fx-ring:linear-gradient(100deg,
    var(--rar) 0%,var(--rar2,var(--rar)) 34%,#ffffff 50%,var(--rar2,var(--rar)) 66%,var(--rar) 100%);
}
.dungeon-pet-card.fx-rainbow,.slot-tile.filled.fx-rainbow,.opp-pet.fx-rainbow{
  --fx-ring:linear-gradient(90deg,#f43f5e,#f59e0b,#22c55e,#0ea5e9,#8b5cf6,#f43f5e);
}
.dungeon-pet-card.fx-flow,.slot-tile.filled.fx-flow,.opp-pet.fx-flow,
.dungeon-pet-card.fx-shimmer,.slot-tile.filled.fx-shimmer,.opp-pet.fx-shimmer,
.dungeon-pet-card.fx-rainbow,.slot-tile.filled.fx-rainbow,.opp-pet.fx-rainbow{
  /* 테두리를 비워 아래 그라데이션이 그 자리에 보이게 한다. 편성 링(.in-party 등)의
     `border-color:!important` 보다 뒤에 오므로 편성 중에는 편성 링이 아니라 이쪽이 이긴다 —
     대신 안쪽 링(outline)이 남아 '어디 편성됐는지'는 그대로 읽힌다. */
  border-color:transparent!important;
  border-image:none;
  background-image:linear-gradient(var(--fx-inner),var(--fx-inner)),var(--fx-ring);
  background-origin:padding-box,border-box;
  background-clip:padding-box,border-box;
  background-repeat:no-repeat,repeat;
  background-size:auto,200% 100%;
  animation:petFxFlow 2.8s linear infinite;
}
/* box-shadow 가 아니라 filter 로 맥동한다 — 카드가 안쪽 링·편성 링을 box-shadow 로 그린다.
   맥동은 이름 글자에도 걸린다(색은 그대로 두고 글로우만). */
.dungeon-pet-card.fx-pulse,.slot-tile.filled.fx-pulse,.opp-pet.fx-pulse,.fb-sum-faces>em.fx-pulse{
  animation:petFxPulse 1.9s ease-in-out infinite;
}
.dungeon-pet-card.fx-pulse .pet-name-txt,.slot-tile.filled.fx-pulse .slot-name-txt{
  animation:petFxPulseText 1.9s ease-in-out infinite;
}
/* 이름 글자 연출 — 던전은 카드 이름이 흰색 고정이라 지정색 위에서만 켠다. */
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .dungeon-pet-card.fx-flow .pet-name-txt,.slot-tile.filled.fx-flow .slot-name-txt{
    background-image:linear-gradient(90deg,var(--rar),var(--rar2,var(--rar)),var(--rar));
    background-size:200% 100%;background-repeat:repeat;
    -webkit-background-clip:text;background-clip:text;
    color:transparent;-webkit-text-fill-color:transparent;
    animation:petFxFlowText 2.8s linear infinite;
  }
  .dungeon-pet-card.fx-shimmer .pet-name-txt,.slot-tile.filled.fx-shimmer .slot-name-txt{
    /* 양 끝이 같은 색이라 한 바퀴가 이어진다. */
    background-image:linear-gradient(100deg,
      var(--rar) 0%,var(--rar2,var(--rar)) 34%,#ffffff 50%,var(--rar2,var(--rar)) 66%,var(--rar) 100%);
    background-size:300% 100%;background-repeat:repeat;
    -webkit-background-clip:text;background-clip:text;
    color:transparent;-webkit-text-fill-color:transparent;
    animation:petFxShimmer 3s linear infinite;
  }
  .dungeon-pet-card.fx-rainbow .pet-name-txt,.slot-tile.filled.fx-rainbow .slot-name-txt{
    background-image:linear-gradient(90deg,#f43f5e,#f59e0b,#22c55e,#0ea5e9,#8b5cf6,#f43f5e);
    background-size:300% 100%;background-repeat:repeat;
    -webkit-background-clip:text;background-clip:text;
    color:transparent;-webkit-text-fill-color:transparent;
    animation:petFxShimmer 3.6s linear infinite;
  }
}

/* @keyframes 는 style.css 에도 같은 이름·같은 내용으로 있다. 두 파일이 늘 함께 실리지는
   않아서(던전 미리보기 페이지) 각자 한 벌씩 갖는다 — 값이 같으므로 어느 쪽이 이기든 같다. */
@keyframes petFxFlow{from{background-position:0 0,0% 50%}to{background-position:0 0,200% 50%}}
@keyframes petFxPulse{
  0%,100%{filter:drop-shadow(0 0 1px var(--rar-glow,var(--rar)))}
  50%{filter:drop-shadow(0 0 7px var(--rar-glow,var(--rar))) drop-shadow(0 0 13px var(--rar-glow,var(--rar)))}}
@keyframes petFxShimmer{from{background-position:0% 50%}to{background-position:300% 50%}}
@keyframes petFxFlowText{from{background-position:0% 50%}to{background-position:200% 50%}}
@keyframes petFxPulseText{
  0%,100%{filter:none}
  50%{filter:drop-shadow(0 0 3px var(--rar)) drop-shadow(0 0 7px var(--rar))}}

.fx-off{animation-play-state:paused!important}
/* 맥동만은 **멈추지 말고 끈다** — 일시정지는 filter 를 그 값에 얼려 두는 것이라,
   화면 밖 카드가 저마다 렌더 표면을 계속 들고 있게 된다(색 계열은 멈춰도 공짜다). */
.fx-off.fx-pulse{animation:none}
@media (prefers-reduced-motion:reduce){
  /* 움직임만 끄고 색은 남긴다 — 그라데이션 테두리는 그대로 보인다. */
  .pet-fx{animation:none!important}
}


/* ══ 미스틱 · 불멸 (2026-09-08) ═══════════════════════════════════════════
   던전은 등급색을 `--rar`(+ `--rar-soft`)로 읽는다 — 종 지정색(.bc)이 덮어쓰는 것도 그 변수다.
   style.css 가 함께 실리지 않는 미리보기 페이지를 위해 색 변수도 여기 한 벌 둔다(같은 값). */
:root{--mystic:#3fd8e8; --immortal:#ff6f8e}

.dungeon-pet-card.mystic{--rar:var(--mystic);--rar-soft:rgba(63,216,232,.28);border-color:var(--mystic)}
.dungeon-pet-card.immortal{--rar:var(--immortal);--rar-soft:rgba(255,111,142,.30);border-color:var(--immortal)}
.dungeon-pet-card.mystic:not(.in-party):not(.in-battle):not(.in-auto-party){
  box-shadow:inset -2px -2px 0 rgba(0,0,0,.32),inset 2px 2px 0 rgba(255,255,255,.05),0 0 12px rgba(63,216,232,.30)}
.dungeon-pet-card.immortal:not(.in-party):not(.in-battle):not(.in-auto-party){
  box-shadow:inset -2px -2px 0 rgba(0,0,0,.32),inset 2px 2px 0 rgba(255,255,255,.05),0 0 16px rgba(255,111,142,.34)}

.slot-tile.filled.r-mystic{--rar:var(--mystic);--rar-soft:rgba(63,216,232,.24)}
.slot-tile.filled.r-immortal{--rar:var(--immortal);--rar-soft:rgba(255,111,142,.26)}
.opp-pet.pet-rarity-mystic{border-color:var(--mystic)}
.opp-pet.pet-rarity-immortal{border-color:var(--immortal)}
.opp-scout-pet.pet-rarity-mystic{border-color:var(--mystic);box-shadow:inset 0 0 10px rgba(63,216,232,.14)}
.opp-scout-pet.pet-rarity-immortal{border-color:var(--immortal);box-shadow:inset 0 0 10px rgba(255,111,142,.16)}
.season-tier-row.pet-rarity-mystic{border-color:var(--mystic)}
.season-tier-row.pet-rarity-immortal{border-color:var(--immortal)}
.fb-sum-faces>em.r-mystic{border-color:var(--mystic)}
.fb-sum-faces>em.r-immortal{border-color:var(--immortal)}
.dbag-item.r-mystic .dbag-art{box-shadow:inset 0 0 0 1px rgba(63,216,232,.5),0 0 14px -4px #3fd8e8}
.dbag-item.r-immortal .dbag-art{box-shadow:inset 0 0 0 1px rgba(255,111,142,.5),0 0 14px -4px #ff6f8e}
/* 등급 보석 — 레전드가 쓰는 반짝임을 그대로 물려 최상위 둘도 눈에 띄게 둔다. */
.rar-gem.r-mystic,.rar-gem.r-immortal{animation:gemLegend 2.4s ease-in-out infinite}

/* ── 10-13 메뉴 재구성 B5(S1 v3 승인 · docs/plans/MOBILE_MINUTE_PLAY_PHASE1_PLAN.md B5) ─────────────────────────────
   하단 = 홈 · 사냥 · 펫 · 월드 · 상점(+ 월드보스). 하위 탭 막대 두 줄은 **숨기고 단추는 남긴다** — 옛 코드의 「단추 대신 누르기」가
   그대로 돌게. 막대가 없으니 그 높이(--subnav-height)도 0 — 쪽 아래 여백 · 알림 · 겹창이 하단 메뉴 바로 위로 내려온다. */
.idle-subnav,.dungeon-subnav{display:none!important}
body{--subnav-height:0px}
.game-mode-nav [data-game-mode="pet"]>span.gi{background-image:url(/world/ui/block/paw.svg?v=20261013nv)}
/* 사냥 화면 줄 단추 · 칸 「← 사냥」 */
.hunt-links,.home-links{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0 2px}
.hunt-links .cube-action,.home-links .cube-action{flex:1 1 0;min-width:96px}
.hunt-links.hidden{display:none}
#fatigueSummary.hidden{display:none}
.section-back{display:inline-flex;align-items:center;gap:4px;margin:2px 0 8px;padding:6px 10px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;cursor:pointer}
body:not(.guild-open) #huntGuildLink{display:none}
body.minigame-off #homeMinigame{display:none}
/* 홈 — 적립 상자 · 부스트가 채굴장 바로 아래 */
.home-claim{display:grid;grid-template-columns:minmax(0,1fr);gap:8px;margin-top:10px}
.home-claim .claim-box{margin:0}
/* 아래에서 올라오는 창(옛 방치 하위 탭 셋) — 겹침은 하단 메뉴(70) 위 · 오프라인 창(75) · 펫 상세(85) 같은 창 아래(창 안에서 연 상세가 밑에 깔리지 않게) */
.idle-sheet-shade{position:fixed;inset:0;z-index:72;}
.idle-sheet-shade[hidden]{display:none}
body.idle-sheet-open .toast{z-index:74}   /* 창 안에서 쓴 결과(아이템 사용 · 배치) 알림이 그늘 밑에 깔리지 않게 */
#app .panel.as-sheet{position:fixed;left:50%;bottom:0;transform:translateX(-50%);z-index:73;width:min(100vw,var(--game-shell-max,460px));
  max-height:min(82vh,820px);overflow:auto;margin:0;padding-top:46px;border-radius:14px 14px 0 0;}
.isheet-close{position:absolute;top:8px;right:8px;width:34px;height:34px;
  background:#34291f url(/world/ui/close.svg) center/18px no-repeat;cursor:pointer}
/* 펫 화면 — 칸 한 줄짜리 그리드는 화면 폭에 묶는다(minmax(0,1fr) · 홈 칸 셋도 같다). 비워 두면 줄이 가장 넓은 내용만큼 자라는데,
   아이폰(WebKit)은 검색칸 기본 폭을 한글 글꼴 평균 폭으로 넓게 잡아 편성 판이 화면 밖으로 잘렸다(10-13 폰 제보 · 머리 줄은 멀쩡) */
.pet-hub{display:grid;grid-template-columns:minmax(0,1fr);gap:10px}
.pet-hub-mine-slots .phm-count{color:var(--muted,#c9b491);font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;margin-bottom:6px;font-variant-numeric:tabular-nums}
.pet-hub-mine-slots .phm-count b{color:var(--ink,#f3e6cf)}
.pet-hub-mine-slots .phm-pets{display:flex;flex-wrap:wrap;gap:4px}
.pet-hub-mine-slots .phm-pet{display:inline-grid;place-items:center;width:38px;height:38px;border:2px solid var(--dq-line,#0e0a07);background:#2a2018}
.pet-hub-acts{display:grid;grid-template-columns:repeat(auto-fit,minmax(72px,1fr));gap:8px}

/* ── 10-13 B1 — 홈 자동사냥 카드 · 결과 한 장(S1 v3 승인 · 연출 「줄임」: 제자리에서 살짝 떠오름 · 흔들림 없음) ───────────── */
.home-hunt{display:grid;grid-template-columns:minmax(0,1fr);gap:6px;margin:8px 0;padding:8px 10px;}
.home-hunt[hidden]{display:none}
.hh-main{display:flex;align-items:center;gap:8px;width:100%;padding:0;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}
.hh-icon,.oh-icon{flex:none;width:30px;height:30px;background:url(/world/ui/block/swords.svg?v=20261013nv) center/contain no-repeat}
.oh-icon{width:18px;height:18px}
.hh-text{display:grid;flex:1 1 auto;min-width:0}
.hh-text b{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;}
.hh-text small{font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hh-chip,.oh-chip{flex:none;padding:2px 7px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;white-space:nowrap}
.hh-chip[hidden]{display:none}
.hh-day{display:flex;align-items:center;gap:8px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;}
.hh-day b{font-variant-numeric:tabular-nums}
.hh-bar{flex:1 1 auto;height:8px;overflow:hidden}
.hh-bar[hidden]{display:none}
.hh-bar i{display:block;height:100%;width:0;}
.offline-hunt{display:grid;grid-template-columns:minmax(0,1fr);gap:6px;margin-top:12px;padding-top:10px;text-align:left}
.offline-hunt[hidden]{display:none}
#offlineAway[hidden],#offlineMine[hidden]{display:none}
.oh-head{display:flex;align-items:center;gap:6px}
.oh-head b{margin-right:auto;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;}
.oh-pets{display:grid;gap:4px}
.oh-pet{display:flex;align-items:center;gap:6px;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;animation:ohRise .32s ease-out both;animation-delay:calc(var(--i,0) * 60ms)}
.oh-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.oh-lv{color:var(--muted,#c9b491);font-variant-numeric:tabular-nums}
.oh-lv b{color:#f3e6cf}
.oh-up{color:#70dbb0;font-weight:700;font-variant-numeric:tabular-nums}
.oh-items{margin:2px 0 0;font-size:12px;font-family:"Galmuri11","Galmuri9",sans-serif;}
.oh-items[hidden]{display:none}
@keyframes ohRise{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion: reduce){.oh-pet{animation:ohFade .2s ease-out both;animation-delay:0s}}
@keyframes ohFade{from{opacity:0}to{opacity:1}}
