/* 옥지의 퇴마록 · 저승 여정 홈: 종이 오림 아이콘 지도(5구역) + 지금 목표 고정 버튼 (구역 팝업은 11.12에 없앰)
   기획안 p10~12. 색은 먹(먹청)·종이·인주·부적, 그라데이션·발광 없음. 아이콘 테두리는 번짐 없는 딱딱한 외곽선 */

/* 홈: 지도가 하단 메뉴 위 화면 전체를 꽉 채우고(바깥 여백·종이 테두리 없음) 지도만 안에서 스크롤된다.
   신분 띠(.scr-head)는 지도 위에 얹혀 고정, 지금 목표 버튼도 지도 위에 뜬다 */
.route-home .scr-head{position:absolute;top:0;left:0;right:0;z-index:20;border:0;pointer-events:none;padding:calc(12px + env(safe-area-inset-top,0px)) 20px 12px}
.route-home .scr-head>*{pointer-events:auto}
.route-home .content{padding:0}
.route-home .id-strip{padding:7px 10px;gap:10px;box-shadow:3px 4px 0 #000}
.route-home .id-strip .face.sm{width:40px;height:42px}
.route-home .id-main strong{font-size:var(--fs-lg)}

/* ---------- 지도 ---------- */
/* 위 여백 = 신분 띠 높이(맨 위 구역이 띠에 가리지 않게), 아래 여백 = 지금 목표 버튼 자리. 여백에도 지도 바탕·골목길이 이어진다
   (.map은 390×1110 좌표 틀 그대로, 그림만 overflow로 여백까지 그리고 .map-wrap이 잘라 낸다) */
.map-wrap{position:relative;overflow:hidden;padding:calc(118px + env(safe-area-inset-top,0px)) 0 96px;background:#16202b}
.map{position:relative;aspect-ratio:390/1110;background:#16202b}
.map-svg{position:absolute;inset:0;width:100%;height:100%;display:block;overflow:visible}
/* 바탕 골목길 (예시 지도의 옅은 길) */
.m-street path{fill:none;stroke:#22334a;stroke-width:9;stroke-linecap:round}
.m-street path.thin{stroke-width:4}
.m-cloud path{fill:#e8e0c80d;stroke:#e8e0c814;stroke-width:1.5}
.m-river{fill:none;stroke:#0f2b36;stroke-width:34;stroke-linecap:round}
.m-ripple{fill:none;stroke:#2c5460;stroke-width:1.4;stroke-dasharray:10 14}
.m-name{font:var(--fw-solmoe) var(--fs-base)/var(--sl-lh-base) var(--font-solmoe);fill:#a9a08a;letter-spacing:var(--sl-ls);paint-order:stroke;stroke:#16202b;stroke-width:4px;stroke-linejoin:round}
.m-name.river{font-size:var(--fs-base);letter-spacing:4px;fill:#6c9993;stroke:none}
.m-bridge rect{fill:#5b4630;stroke:#000;stroke-width:1.5}
.m-bridge path{stroke:#2e2216;stroke-width:1.2}
.m-bridge .rail{stroke:#b08a4a;stroke-width:2.2}
/* 망자 마을 지붕 */
.m-house .wall{fill:#253041;stroke:#0b0e12;stroke-width:1.5}
.m-house .roof{fill:#33405a;stroke:#0b0e12;stroke-width:1.5}
.m-house .win{fill:#d9b43c}
/* 윤회의 방: 윤회 바퀴 */
.m-rebirth circle,.m-rebirth path{fill:none;stroke:#f1ead824;stroke-width:1.6}
.m-rebirth circle+circle{stroke-dasharray:4 6}
/* 길 */
.m-road{fill:none;stroke:#0b1118;stroke-width:12;stroke-linecap:round}
.m-route{fill:none;stroke:#4b5a6a;stroke-width:3.4;stroke-linecap:round;stroke-dasharray:1 9}
.m-route.on{stroke:var(--tal);stroke-width:4}
.m-route.go{animation:march 1.1s linear infinite}
@keyframes march{to{stroke-dashoffset:-20}}
/* 지도 가운데 제목 */
.map-title{position:absolute;width:34%;transform:translate(-50%,-50%) rotate(-4deg);z-index:1;pointer-events:none}

/* ---------- 구역 아이콘 (종이 오림) ---------- */
.lm{position:absolute;width:40%;transform:translate(-50%,-50%);padding:0;border:0;background:none;color:inherit;z-index:2}
.lm-icon{display:block;aspect-ratio:1/1}
/* 종이 오림 느낌: 번짐 없는 흰 외곽선 + 딱딱한 그림자 */
.lm-icon img{display:block;width:100%;height:100%;object-fit:contain;filter:drop-shadow(2px 0 0 #f4ecd8) drop-shadow(-2px 0 0 #f4ecd8) drop-shadow(0 2px 0 #f4ecd8) drop-shadow(0 -2px 0 #f4ecd8) drop-shadow(3px 4px 0 #000)}
.lm.current .lm-icon img{filter:drop-shadow(3px 0 0 var(--tal)) drop-shadow(-3px 0 0 var(--tal)) drop-shadow(0 3px 0 var(--tal)) drop-shadow(0 -3px 0 var(--tal)) drop-shadow(3px 4px 0 #000)}
.lm.locked .lm-icon img{filter:drop-shadow(2px 0 0 #8d8a80) drop-shadow(-2px 0 0 #8d8a80) drop-shadow(0 2px 0 #8d8a80) drop-shadow(0 -2px 0 #8d8a80);opacity:.9}
.lm-label{position:absolute;left:50%;bottom:-6px;transform:translateX(-50%);white-space:nowrap;padding:3px 10px;background:var(--paper);color:var(--ink);border:1.5px solid #000;border-radius:var(--r);font:var(--t-label);letter-spacing:var(--t-label-ls);box-shadow:2px 2px 0 #000;transition:background-color .35s,color .35s,border-color .35s,box-shadow .35s}
.lm.current .lm-label{background:var(--tal);color:var(--tal-ink)}
.lm.locked .lm-label{color:var(--dim);background:#0d1218;border-color:#4b5a6a;box-shadow:none}
.lm-lock{position:absolute;left:50%;top:46%;width:30%;transform:translate(-50%,-50%);z-index:2;pointer-events:none}
/* 녹슨 자물쇠 (app.js LOCK_SVG, 64×76). 종이 오림 테두리는 그림 안에, 딱딱한 그림자만 여기서 */
.lm-lock svg{display:block;width:100%;height:auto;overflow:visible;filter:drop-shadow(2px 3px 0 #000);transform-origin:50% 14%}
.lm.rattle .lm-lock svg{animation:rattle .75s cubic-bezier(.36,.07,.19,.97)}
@keyframes rattle{10%{transform:rotate(-16deg) translateX(-2px)}25%{transform:rotate(14deg) translateX(2px)}40%{transform:rotate(-11deg)}55%{transform:rotate(8deg)}70%{transform:rotate(-4deg)}85%{transform:rotate(2deg)}100%{transform:none}}
.lm-seal{position:absolute;right:2px;top:4px;font-size:var(--fs-sm);padding:3px 6px;background:var(--paper);border-color:#e0574a;color:#e0574a}
.lm.current{z-index:3}
/* 열린 구역(지금 차례)의 그림만 움직인다. 마친 구역·잠긴 구역은 멈춤.
   0%는 늘 쉬는 자세: 열림 연출에서 아이콘이 다 커진 뒤 여기서 출발한다. 박자는 app.js zmSync가 맞춰 다시 그려도 끊기지 않음.
   壹 명부는 등록과 동시에 통과라 지금 차례가 되는 일이 없어 움직임을 두지 않는다 */
.lm.current .lm-icon img{transform-origin:50% 100%;will-change:transform}
/* 옥졸: 칼 들고 제자리 뜀박질 */
.lm.current [data-z=village] img{animation:zmVillage .84s ease-in-out infinite}
@keyframes zmVillage{0%,100%{transform:none}25%{transform:translateY(-6%) rotate(-3deg)}50%{transform:scale(1.03,.96)}75%{transform:translateY(-6%) rotate(3deg)}}
/* 업경대: 둥실 떠서 살짝 흔들림 */
.lm.current [data-z=judge] img{animation:zmJudge 3s ease-in-out infinite}
@keyframes zmJudge{0%,100%{transform:none}25%{transform:translateY(-3.5%) rotate(-2deg)}50%{transform:translateY(-7%)}75%{transform:translateY(-3.5%) rotate(2deg)}}
/* 옥지: 주먹 쥐고 좌우로 몸풀기 */
.lm.current [data-z=duel] img{animation:zmDuel 1.1s ease-in-out infinite}
@keyframes zmDuel{0%,100%{transform:none}20%{transform:translate(-3%,1.5%) rotate(-5deg) scale(1.03,.97)}40%{transform:translateY(-6%)}60%{transform:translate(3%,1.5%) rotate(5deg) scale(1.03,.97)}80%{transform:translateY(-6%)}}
/* 빵빵 유령: 하늘하늘 떠다님 */
.lm.current [data-z=rebirth] img{transform-origin:50% 50%;animation:zmRebirth 3.4s ease-in-out infinite}
@keyframes zmRebirth{0%,100%{transform:none}30%{transform:translate(-3%,-8%) rotate(-5deg)}65%{transform:translate(3%,-4%) rotate(4deg)}}
.lm-pin{position:absolute;left:50%;top:-44px;margin-left:-27px;width:54px;animation:pinBob 1.4s ease-in-out infinite}
.lm-pin .face{display:block;width:54px;height:56px;object-fit:cover;background:#fee4c7;border:3px solid var(--tal);border-radius:var(--head)}
.lm-pin:after{content:'';position:absolute;left:50%;bottom:-9px;margin-left:-8px;border:8px solid transparent;border-top-color:var(--tal);border-bottom:0}
/* 지금 차례 구역의 핀은 12px 더 위: 움직이는 아이콘이 꼭대기에서 핀 밑으로 파고들지 않게.
   열림 연출의 걷는 핀은 환호(mwCheer) 끝에 같은 12px만큼 올라가 있어 지도를 다시 그릴 때 튀지 않는다. 지도 맨 위 壹 명부에서 출발하는 핀은 그대로라 잘리지 않음 */
.lm.current .lm-pin{top:-56px}
@keyframes pinBob{50%{transform:translateY(-6px)}}
.map-rat{position:absolute;width:6.5%;transform:translate(-50%,-50%);z-index:1;animation:ratWiggle 2.8s var(--d,0s) ease-in-out infinite}
.map-rat.flip{transform:translate(-50%,-50%) scaleX(-1)}
@keyframes ratWiggle{50%{translate:0 -3px}}

/* ---------- 다음 구역 열림 연출 (app.js playUnlock) ----------
   ① 마친 구역에 通過 도장 쾅 → ② 핀(내 망자)이 길을 따라 뒤뚱뒤뚱 → ③ 자물쇠가 점점 세게 덜그럭 → ④ 펑: 고리는 위로, 몸통은 아래로 튕겨 나가고
   종이 오림 별·녹 부스러기·연기 영상(자물쇠 크기에서 피어남) → 아이콘에 색이 돌아오며 통 튄다 → ⑤ 지금 목표 버튼이 올라온다 */
.lm.stamped .lm-seal{animation:sealSlam .5s .3s cubic-bezier(.2,1.5,.4,1) both}
@keyframes sealSlam{0%{opacity:0;transform:scale(2.6) rotate(-26deg)}55%{opacity:1;transform:scale(.9) rotate(-6deg)}100%{opacity:1;transform:rotate(-8deg)}}
.lm.stamped .lm-icon{animation:lmThud .34s .5s ease-out}
@keyframes lmThud{40%{transform:scale(.95) translateY(3px)}}
/* 지나온 길이 노랗게 밝혀지는 마스크 (JS가 dasharray·dashoffset을 길 길이에 맞춰 줄여 간다) */
.m-reveal{fill:none;stroke:#fff;stroke-width:16;stroke-dasharray:0 9999}
.map-walker{position:absolute;left:0;top:0;width:0;height:0;z-index:5;pointer-events:none}
.map-walker .lm-pin{animation:none;transform-origin:50% 100%}
.map-walker.walking .lm-pin{animation:mwStep .56s linear infinite}
@keyframes mwStep{0%,100%{transform:rotate(-6deg)}25%,75%{transform:translateY(-8px)}50%{transform:rotate(6deg)}}
.map-walker.landed .lm-pin{animation:mwLand .36s ease-out}
@keyframes mwLand{0%{transform:translateY(-6px)}45%{transform:scale(1.1,.86)}100%{transform:none}}
.map-walker.cheer .lm-pin{animation:mwCheer .62s cubic-bezier(.3,1.5,.5,1) forwards}
@keyframes mwCheer{35%{transform:translateY(-26px) rotate(-5deg)}70%{transform:translateY(-10px) scale(1.06,.92)}100%{transform:translateY(-12px)}}
/* 자물쇠: 점점 세게 흔들리다 움츠렸다 부푼 뒤(.shake) 고리·몸통이 따로 튕겨 나간다(.pop). 단위는 자물쇠 그림 좌표(64 폭) */
.lm-lock.shake svg{animation:lkShake 1.15s linear both}
@keyframes lkShake{
  0%{transform:none}6%{transform:rotate(-8deg)}12%{transform:rotate(8deg)}18%{transform:rotate(-11deg) translateX(-1px)}24%{transform:rotate(11deg) translateX(1px)}
  30%{transform:rotate(-14deg) translate(-2px,-1px)}36%{transform:rotate(14deg) translate(2px,-2px)}42%{transform:rotate(-18deg) translate(-3px,-1px)}48%{transform:rotate(18deg) translate(3px,-3px)}
  54%{transform:rotate(-21deg) translate(-3px,-2px) scale(1.03)}60%{transform:rotate(21deg) translate(4px,-4px) scale(1.04)}66%{transform:rotate(-24deg) translate(-4px,-3px) scale(1.06)}72%{transform:rotate(24deg) translate(4px,-5px) scale(1.08)}
  78%{transform:rotate(-28deg) translate(-5px,-2px) scale(1.1)}84%{transform:rotate(16deg) translateY(-6px) scale(1.12)}90%{transform:scale(.8,.88) translateY(4px)}100%{transform:scale(1.26) translateY(-3px)}}
.lm.quake .lm-icon{animation:lmQuake .08s .45s linear 8}
@keyframes lmQuake{25%{transform:translate(-2.5px,1.5px) rotate(-.8deg)}75%{transform:translate(2.5px,-1.5px) rotate(.8deg)}}
.lm-lock.pop svg{transform:scale(1.26) translateY(-3px)}
.lm-lock.pop .lk-shackle,.lm-lock.pop .lk-body{transform-box:fill-box;transform-origin:50% 60%}
.lm-lock.pop .lk-shackle{animation:lkShackle .7s cubic-bezier(.15,.7,.35,1) forwards}
@keyframes lkShackle{30%{opacity:1}100%{transform:translate(22px,-62px) rotate(120deg);opacity:0}}
.lm-lock.pop .lk-body{animation:lkBody .55s cubic-bezier(.45,0,.9,.5) forwards}
@keyframes lkBody{20%{transform:translate(-6px,-9px) rotate(-12deg);opacity:1}55%{opacity:.85}100%{transform:translate(-22px,56px) rotate(-55deg) scale(.8);opacity:0}}
/* 펑 순간 지도 전체가 한 번 쿵 울린다 (맵이 열리는 느낌) */
.map.jolt{animation:mapJolt .34s cubic-bezier(.36,.07,.19,.97)}
@keyframes mapJolt{20%{transform:translate(-3px,2px)}40%{transform:translate(3px,-2px)}60%{transform:translate(-2px,1px)}80%{transform:translate(1px,-1px)}}
.lm.unveil .lm-icon{animation:lmUnveil .7s cubic-bezier(.3,1.6,.5,1)}
@keyframes lmUnveil{0%{transform:scale(.8)}55%{transform:scale(1.12)}100%{transform:none}}
/* 펑 효과 층: 자물쇠 가운데에 놓인 0×0 점. --w = 자물쇠 폭 */
/* .lk-fx 자체엔 z-index를 주지 않는다: 쌓임 맥락이 생기면 연기 영상의 screen 블렌드가 지도 대신 빈 바탕과 섞여 검정이 그대로 보인다 */
.lk-fx{position:absolute;left:-999px;top:0;width:0;height:0;pointer-events:none}
.lk-fx>*{position:absolute;left:0;top:0;z-index:6;translate:-50% -50%;opacity:0}
.lk-boom{width:calc(var(--w) * 2.4);height:auto}
.lk-fx.go .lk-boom{animation:lkBoom .46s cubic-bezier(.2,.9,.3,1) both}
@keyframes lkBoom{0%{opacity:1;scale:.15;rotate:-12deg}50%{opacity:1;scale:1.05}100%{opacity:0;scale:1.3;rotate:10deg}}
.lk-bit{width:var(--s);height:var(--s);background:var(--c);border:1.5px solid #000}
.lk-fx.go .lk-bit{animation:lkBit .8s cubic-bezier(.2,.6,.4,1) both}
@keyframes lkBit{0%{opacity:1;transform:none}55%{opacity:1;transform:translate(calc(var(--x) * .8),calc(var(--y) * .8 - 10px)) rotate(calc(var(--r) * .6))}100%{opacity:0;transform:translate(var(--x),calc(var(--y) + 26px)) rotate(var(--r))}}
/* 업경대에서 쓴 연기 영상(검은 바탕 → screen 블렌드로 사라짐)을 자물쇠 크기로 잘라 쓴다. 가장자리는 둥근 마스크로 흐림 */
.lk-smoke{width:calc(var(--w) * 3.2);height:calc(var(--w) * 3.2);translate:-50% -58%;object-fit:cover;mix-blend-mode:screen;filter:brightness(2.8) contrast(1.3);
  -webkit-mask-image:radial-gradient(closest-side,#000 40%,transparent);mask-image:radial-gradient(closest-side,#000 40%,transparent)}
.lk-fx.vid .lk-smoke{animation:lkSmoke 2s cubic-bezier(.2,.6,.3,1) both}
@keyframes lkSmoke{0%{opacity:0;scale:.35}10%{opacity:1}55%{opacity:.9}100%{opacity:0;scale:1.45}}
.lk-puff{width:calc(var(--w) * 1.4);aspect-ratio:1;border-radius:50%;background:radial-gradient(closest-side,rgba(238,243,240,.9),rgba(214,224,219,0))}
.lk-fx.go .lk-puff{animation:lkPuff 1.3s var(--d,0s) ease-out both}
/* 영상이 돌면 연기 덩이는 옅은 속심으로만 남겨 뿌연 느낌을 받친다 */
.lk-fx.vid .lk-puff{--po:.5}
@keyframes lkPuff{0%{opacity:0;transform:scale(.3)}20%{opacity:var(--po,.95)}100%{opacity:0;transform:translate(var(--x),var(--y)) scale(1.6)}}
/* 연출 동안 터치로 화면을 끌어 스크롤·당겨서 새로고침하지 못하게 (app.js hookUnlock이 붙였다 뗌) */
html.map-unlocking,html.map-unlocking body{touch-action:none;overscroll-behavior:none}
/* 지금 목표 버튼: 연출 동안 숨었다가 구역이 열리면 올라온다 */
.quest-dock{transition:opacity .45s,translate .5s cubic-bezier(.3,1.4,.5,1)}
.quest-dock.qd-wait{opacity:0;translate:0 28px;pointer-events:none}

/* ---------- 지금 목표 (고정 버튼) ----------
   sticky: 지도가 스크롤되는 본문(.scr-body) 아래 끝, 하단 메뉴 바로 위에 떠 있다.
   흐름 안에 자리를 차지하므로 맨 아래로 내리면 지도 마지막 구역을 가리지 않는다. */
/* 지도 아래 여백(.map-wrap padding-bottom) 위로 겹쳐 올라가 지도 위에 뜬다. 맨 아래까지 내려도 끝은 지도 끝과 같다 */
.quest-dock{position:sticky;bottom:10px;z-index:15;margin:-74px 20px 10px}
.quest-fab.primary{justify-content:space-between;gap:12px;min-height:64px;padding:8px 34px 8px 32px;text-align:left}
.qf-main{display:flex;flex-direction:column;min-width:0}
.qf-main small{font:var(--fw-extrabold) var(--fs-xs)/var(--lh-xs) var(--font-sans);color:#6b4f0c;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.qf-main b{font:var(--t-subtitle);letter-spacing:var(--t-subtitle-ls);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.qf-go{flex:none;padding:6px 10px;background:var(--tal-ink);color:var(--tal);border-radius:var(--r);font:var(--t-label);letter-spacing:var(--t-label-ls)}
.quest-fab.done .qf-go{background:var(--seal);color:#fff}
/* 잠긴 구역을 고른 하단 버튼: 종이 결은 그대로 회색으로, 입장 칸은 어둡게 */
.quest-fab.locked{filter:grayscale(1) brightness(.78)}
.quest-fab.locked .qf-go{background:#2b2c30;color:#c9c2b0}

@media (max-width:374px){
  .quest-dock{margin-left:16px;margin-right:16px}
  .route-home .scr-head{padding-left:16px;padding-right:16px}
  .lm-label{font-size:var(--fs-sm);padding:2px 7px}
  .qf-main b{font-size:var(--fs-lg)}
  .qf-go{font-size:var(--fs-sm);padding:5px 8px}
  .quest-fab.primary{padding:8px 28px 8px 28px}
}
@media (prefers-reduced-motion:reduce){
  .m-route.go{stroke-dasharray:1 9}
  .lm-pin,.lm.current .lm-icon img{animation:none}
}

