/* 옥지의 퇴마록 · 모바일 1안 · "저승 출입국관리소"
   규칙: 모서리 최대 2px / 색은 먹·종이·먹글씨·인주·부적 5가지 / 그림자·그라데이션·발광 없음(말풍선 만화 그림자만) */
:root{
  --bg:#0f1311; --bg2:#161b18; --bg3:#1e2521; --line:#323c36; --line2:#4b5650;
  --text:#f1ead8; --muted:#bdb8a6; --dim:#94907f;
  --paper:#efe3c4; --paper2:#e4d5ae; --rule:#b9a26f; --ink:#231d14; --ink2:#5f523e;
  --seal:#c8372b; --tal:#f1cc45; --tal-d:#b8961f; --tal-ink:#241a05; --btn-ink:#72200e;   /* Primary 버튼 글자 = 키비주얼 현판의 어두운 빨강 */
  --r:2px; --head:48% 48% 44% 44%/52% 52% 40% 40%;
  /* 글꼴 2가지로 통일 (11.11 디자인 피드백): 제목·버튼·도장·이름표 = 붓글씨(--display) / 설명·본문·입력 = Pretendard(--body).
     글꼴·크기 위계는 type.css (디자인 시스템 스케일 + 역할 토큰 --t-*).
     --serif·--hand·--id-font는 예전 이름이라 남겨 두고 --display를 가리킨다. */
  --display:var(--font-solmoe);   /* type.css: 솔뫼 김대건체 */
  --body:var(--font-sans);        /* type.css: Pretendard */
  --serif:var(--display); --sans:var(--body); --hand:var(--display);
  --id-font:var(--display); --id-weight:var(--fw-solmoe); --id-scale:1;
  --nav-h:60px; --safe-b:env(safe-area-inset-bottom,0px);
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:#0a0d0c;color:var(--text);font:var(--t-body);letter-spacing:var(--t-body-ls);font-synthesis-weight:none;word-break:keep-all;line-break:strict;overflow-wrap:break-word}
h1,h2,h3,button,.bubble,#toast,#levelup,dt,dd,figcaption{text-wrap:balance}
p,li{text-wrap:pretty}
img{max-width:100%}
img.face{height:auto}
button,input,textarea{font:inherit;color:inherit}
button{cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent}
:focus-visible{outline:3px solid var(--tal);outline-offset:2px}
button:focus-visible,a:focus-visible,[role="button"]:focus-visible,input:focus,textarea:focus,select:focus{outline:none}   /* 11.12 버튼·입력란에는 초점 표시를 그리지 않는다. 버튼에는 초점 테두리를 그리지 않는다 — 휴대폰에서 글자 입력 뒤 누른 버튼에 노란 테두리가 간간이 남았다 */
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
[hidden]{display:none!important}

/* ---------- 데스크톱 프레젠테이션 ---------- */
.desktop-art{position:fixed;inset:0 40% 0 0;pointer-events:none;background:url('assets/ui/hero-900.webp') center 30%/cover;opacity:.07}
.phone{position:relative;width:430px;margin:32px max(3vw,calc(50vw - 600px)) 32px auto;background:var(--bg);overflow:hidden;border:1px solid var(--line);border-radius:var(--r)}

/* ---------- 화면 틀 (11.12 통일): 창 전체는 스크롤하지 않고, 본문만 안에서 스크롤 ----------
   .phone = 화면 높이(--ph: 휴대폰 100dvh · PC 시안 높이)에 고정된 세로 칸.
   위에서부터 제목(.scr-head, 고정) · 본문(.scr-body, 안쪽 스크롤) · 주 버튼(.scr-foot, 고정) · 하단 메뉴(.nav, 고정). 틀은 app.js shell.
   그림이 화면을 채우는 몰입 화면은 section 하나가 남는 높이를 다 차지한다(.phone>section).
   한지 한 장 화면(.reg-page)·개인정보(.pv-page)·쥐 안내(.guide)는 그 안에서 같은 세 칸을 쓴다 */
.phone{--ph:100dvh;--ctop:calc(22px + env(safe-area-inset-top,0px));--end:var(--safe-b);display:flex;flex-direction:column;height:var(--ph);overflow:clip}   /* --ctop: 화면 위 여백(위에 꽉 붙는 결과판 등이 음수 여백으로 쓴다) · --end: 본문 끝 safe-area(하단 메뉴가 있으면 메뉴가 맡는다) · clip: 틀 자체는 코드로도 스크롤되지 않게 */
.phone.has-nav{--end:0px}
.phone>*{flex:none}
.phone>section{flex:1 1 0;min-height:0}
.scr-body{flex:1 1 0;min-height:0;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:#3a4540 transparent}
.phone.hanji .scr-body,.reg-page .scr-body{scrollbar-color:rgba(35,29,20,.3) transparent}
.scr-head{position:relative;z-index:2;padding:var(--ctop) 20px 14px;border-bottom:1px solid transparent;transition:border-color .15s}
.scr-head>:last-child{margin-bottom:0}
.scr-head+.content{padding-top:8px}
.scr-head+.content>:first-child{margin-top:0}   /* 제목과 본문 첫 요소 사이는 늘 같은 간격(14 + 8px) */
.scr-foot{position:relative;z-index:2;padding:12px 20px calc(16px + var(--safe-b));border-top:1px solid transparent;transition:border-color .15s}
.scr-foot>:first-child,.scr-foot .cta-row{margin-top:0}
.content:has(+.scr-foot){padding-bottom:16px}
/* 스크롤 표시 (app.js scrollCue): 본문이 제목 밑으로 넘어갔거나 버튼 밑에 더 남았을 때만 먹선 한 줄 */
.scr-head:has(+.scr-body.scrolled),.scr-body.more+.scr-foot{border-color:var(--line2)}

/* ---------- 상단 ---------- */
/* 11.12 로고 머리띠(.topbar) 삭제. 위 여백은 .content가 safe-area부터 직접 둔다(--ctop) */
.db-acts{display:flex}
.iconbtn{width:44px;height:44px;border-radius:var(--r);border:1px solid var(--line2);background:none;font:700 17px var(--serif)}

/* ---------- 타이포 ---------- */
.content{padding:var(--ctop) 20px calc(28px + var(--end))}
h2{font:var(--t-title);letter-spacing:var(--t-title-ls);margin:0 0 10px}
h3{font:var(--t-subtitle);letter-spacing:var(--t-subtitle-ls);margin:0 0 10px}
.sub{color:var(--muted);font:var(--t-body);letter-spacing:var(--t-body-ls);margin:0 0 22px}
h2+:not(.sub){margin-top:18px}
.tip{font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls);color:var(--muted);margin:14px 0}
.footer-note{text-align:center;margin:14px 0 0}
.textbtn{background:none;border:0;padding:10px;color:var(--muted);font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls);min-height:44px}
.notice{font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls);color:var(--muted);margin:22px 0 12px;padding-top:14px;border-top:1px solid var(--line)}

/* ---------- 버튼 ---------- */
.primary,.secondary{position:relative;display:flex;align-items:center;justify-content:center;width:100%;min-height:56px;border-radius:var(--r);padding:12px 34px;font:var(--t-button);letter-spacing:var(--t-button-ls)}
/* 11.11 찢긴 한지 버튼 (_시안/버튼-한지-1111 2안): 주 = 노란 부적 한지, 보조 = 물들이지 않은 생한지를 한 톤 어둡게.
   종이 = paper-hanji 원화에 색(--hj)을 multiply로 들인다. 찢긴 가장자리 = 명부의 hanji-edge를 버튼 비율로 이어 붙인 hanji-edge-wide 마스크.
   ::before = 같은 마스크의 먹 그림자(아래로 4px), ::after = 종이. 둘 다 z-index:-1이라 글자·아이콘 뒤에 깔린다(isolation으로 버튼 안에 가둠).
   버튼 자체에는 바탕·테두리·그림자를 두지 않는다 — 덮어쓰면 찢긴 모양 밖으로 네모가 드러난다 */
.primary,.secondary{isolation:isolate;border:0;background:none;box-shadow:none;--hj:#f0c94a;--hj-drop:4px}
.primary::before,.secondary::before,.primary::after,.secondary::after{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  -webkit-mask:url('assets/ui/hanji-edge-wide.webp') 0 0/100% 100% no-repeat;mask:url('assets/ui/hanji-edge-wide.webp') 0 0/100% 100% no-repeat}
.primary::before,.secondary::before{background:#000;translate:0 var(--hj-drop)}
.primary::after,.secondary::after{background:url('assets/ui/design-1111/paper-hanji.webp') 50% 50%/cover,var(--hj);background-blend-mode:multiply}
/* 같은 찢김이 줄줄이 반복돼 보이지 않게 짝수 번째 버튼은 좌우로 뒤집는다 */
:is(.primary,.secondary):nth-of-type(even)::before,:is(.primary,.secondary):nth-of-type(even)::after{scale:-1 1}
.primary:active,.secondary:active{transform:translateY(3px);--hj-drop:1px}
.primary{color:var(--btn-ink)}
.primary.big{min-height:60px}
.secondary{--hj:#d2c29b;--hj-drop:3px;color:var(--ink);font:var(--t-button-sm);letter-spacing:var(--t-button-sm-ls)}
/* 🔒 관리자 화면(PC 기획 패널 · 관리자 메뉴 · 화면 바로가기)은 고정이라 한지 버튼을 입히지 않고 예전 먹패 그대로 둔다 */
:is(.plan,#modal.review,#modal:has(.jump-grid)) .secondary{border:1.5px solid var(--muted);background:var(--bg2);color:var(--text);box-shadow:inset 0 0 0 3px var(--bg2),inset 0 0 0 4px var(--line2),0 3px 0 #000}
:is(.plan,#modal.review,#modal:has(.jump-grid)) .secondary:active{transform:translateY(2px);box-shadow:inset 0 0 0 3px var(--bg2),inset 0 0 0 4px var(--line2),0 1px 0 #000}
:is(.plan,#modal.review,#modal:has(.jump-grid)) .secondary::before,:is(.plan,#modal.review,#modal:has(.jump-grid)) .secondary::after{content:none}
.secondary.sm{min-height:46px;width:auto;padding:8px 18px}
.primary+.secondary,.secondary+.primary,.secondary+.secondary,.primary+.primary{margin-top:14px}
.cta-row{margin-top:24px}

/* ---------- 도장·말풍선 ---------- */
.stamp{display:inline-grid;place-items:center;text-align:center;border:2.5px solid var(--seal);color:var(--seal);font:var(--t-label);letter-spacing:var(--t-label-ls);padding:5px 9px;border-radius:var(--r);transform:rotate(-8deg)}
.stamp.mini{font-size:var(--fs-sm);line-height:var(--sl-lh-sm);padding:2px 6px;border-width:2px}
.talk{display:flex;align-items:flex-end;gap:8px;margin:26px 0 0}
.talk-art{width:64px;height:auto;flex:none}
.talk img[src*="kv-"]{width:60px;height:60px;object-fit:cover;border:2px solid #000;border-radius:50%}
.bubble{position:relative;margin:0 0 16px;background:#fbf6ea;color:#1a150d;font:var(--t-label);letter-spacing:var(--t-label-ls);padding:8px 13px;border-radius:var(--r);border:2px solid #000;box-shadow:3px 3px 0 #000}
.talk .bubble:before{content:'';position:absolute;left:-9px;bottom:10px;border:7px solid transparent;border-right-color:#000;border-left:0}
@keyframes float{50%{transform:translateY(-8px)}}

/* ---------- 종이 ---------- */
.paper{position:relative;background:var(--paper);color:var(--ink);border-radius:var(--r);padding:20px 18px;border:1px solid var(--rule)}

/* ---------- 첫 화면 ---------- */
.landing{display:flex;flex-direction:column}
.landing-kv{position:relative;height:min(62dvh,550px);min-height:320px;overflow:hidden;border-bottom:1px solid var(--line)}
.landing-kv img{width:100%;height:100%;object-fit:cover;object-position:50% 8%;display:block}
.landing-panel{position:relative;padding:28px 20px 24px}
.landing-panel h2{font-size:var(--fs-3xl);line-height:var(--sl-lh-3xl);margin-bottom:6px}
.landing-panel .sub{margin-bottom:22px}
.landing-ghost{position:absolute;width:70px;right:14px;top:-60px;animation:float 3.4s ease-in-out infinite}
.landing-bubble{position:absolute;right:88px;top:-50px;padding:5px 10px;margin:0}
.landing-bubble:after{content:'';position:absolute;right:-9px;bottom:7px;border:7px solid transparent;border-left-color:#000;border-right:0}

/* ---------- 신원 확인·신고서 ---------- */
.signboard{display:inline-flex;flex-direction:column;padding:9px 16px;margin:0 0 20px;background:#4a3320;border:2px solid #22160c;border-radius:var(--r);transform:rotate(-1deg)}
.signboard span{font:var(--t-caption);letter-spacing:var(--t-caption-ls);color:#d8c29a}
.signboard b{font:var(--fw-solmoe) var(--fs-lg)/var(--sl-lh-lg) var(--font-solmoe);color:#fbeed2}
/* 11.12 소셜 로그인 (톤앤매너 1구역): 한지 버튼과 같은 찢긴 가장자리(hanji-edge-wide 마스크) + 먹 그림자.
   브랜드 가이드 때문에 종이 질감·물들이기는 하지 않고 바탕은 브랜드 단색(구글 #fff · 카카오 #FEE500) 그대로, 로고도 공식 심벌 */
.login-btns{display:grid;gap:14px;margin-top:8px}
/* 먹선 = 찢긴 모양을 따라 도는 drop-shadow 두 겹(키비주얼 위에서 흰 종이가 그림에 묻히지 않게) + 아래로 민 먹 그림자 */
.login{position:relative;isolation:isolate;display:flex;align-items:center;justify-content:center;gap:10px;min-height:54px;padding:0 24px;border:0;background:none;font:var(--t-body-strong);letter-spacing:var(--t-body-strong-ls);--lg:#fff;--lg-drop:4px;
  filter:drop-shadow(0 0 .6px #000) drop-shadow(0 0 .6px #000) drop-shadow(0 var(--lg-drop) 0 #000)}
.login::after{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;background:var(--lg);
  -webkit-mask:url('assets/ui/hanji-edge-wide.webp') 0 0/100% 100% no-repeat;mask:url('assets/ui/hanji-edge-wide.webp') 0 0/100% 100% no-repeat}
.login.kakao::after{scale:-1 1}   /* 두 장의 찢김이 똑같아 보이지 않게 */
.login:active{transform:translateY(3px);--lg-drop:1px}
.login i{display:grid;place-items:center;width:20px;height:20px;flex:none}
.login i svg{display:block}
.login.google{color:#1f1f1f}
.login.kakao{--lg:#fee500;color:rgba(0,0,0,.85)}
.privacy-btn{margin-top:14px}
.login:disabled{opacity:.55}
/* 인앱 브라우저 안내 (로그인 화면) */
/* 11.12: 첫 화면을 막는 팝업으로 (app.js inAppGate). 찢긴 한지(.hanji-sheet, 결투 결과판과 같은 원화) + 금빛 한지 버튼. 닫기 없음 */
dialog.inapp-dlg{isolation:isolate;overflow:visible;max-width:360px;padding:30px 26px 28px;background:none;border:0;color:var(--ink);text-align:center}
dialog.inapp-dlg::backdrop{background:#000d}
dialog.inapp-dlg h3{margin:0 0 12px;color:var(--ink)}
dialog.inapp-dlg .dlg-body{margin-bottom:20px;color:var(--ink2);word-break:keep-all}
dialog.inapp-dlg .dlg-body p{margin:0}
dialog.inapp-dlg .inapp-how{margin-top:10px;padding-top:10px;border-top:1px dashed #16120e55;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--ink)}
dialog.inapp-dlg a.primary{text-decoration:none}
/* [마을 탐험 마치기] 확인 팝업 (11.12 점검판 요청): 명부 종이 여러 장이 어긋나게 겹친 더미. 같은 한지 원화(.hanji-sheet) 3장 — 뒤 2장은 뒤집고 기울여 조금 어둡게, 맨 앞 장에 글·버튼(가운데 정렬) */
dialog.stack-dlg{isolation:isolate;overflow:visible;max-width:350px;width:calc(100% - 56px);padding:34px 26px 28px;background:none;border:0;color:var(--ink);text-align:center}
dialog.stack-dlg::backdrop{background:#000d}
dialog.stack-dlg h3{margin:0 0 12px;color:var(--ink)}
dialog.stack-dlg .dlg-body{margin-bottom:22px;color:var(--ink2);word-break:keep-all}
dialog.stack-dlg .dlg-body p{margin:0 0 6px;text-wrap:balance}
dialog.stack-dlg .dlg-body p:last-child{margin:0}
dialog.stack-dlg .hanji-sheet.back1{rotate:-4deg;translate:-9px 4px;filter:drop-shadow(3px 4px 0 #000) brightness(.8)}
dialog.stack-dlg .hanji-sheet.back2{rotate:4.5deg;translate:9px 12px;filter:drop-shadow(3px 4px 0 #000) brightness(.62)}
dialog.stack-dlg .hanji-sheet.back1>i{scale:-1 1}
dialog.stack-dlg .hanji-sheet.back2>i{scale:1 -1}
.sign-out{display:block;margin:6px auto 0}
.form-sheet{margin-top:18px}
/* 11.12 문서 머리(망자 신원 등록부 · 망자 초상 결재) = 화면 제목 크기 */
.sheet-head{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding-bottom:12px;margin-bottom:18px;border-bottom:2px solid var(--ink);font:var(--t-title);letter-spacing:var(--t-title-ls)}
.sheet-no{font:var(--fw-solmoe) var(--fs-sm)/var(--sl-lh-sm) var(--font-solmoe);color:var(--ink2)}
.field{border:0;margin:0 0 18px;padding:0}
.field:last-child{margin-bottom:0}
.field legend,.field label{display:flex;align-items:baseline;gap:6px;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--ink);margin-bottom:10px;padding:0}
.field small{color:var(--ink2);font:var(--t-caption);letter-spacing:var(--t-caption-ls)}
.photo-pick{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.photo{position:relative;background:#f8f1df;border:1px solid var(--rule);border-radius:var(--r);padding:8px 8px 6px;display:flex;flex-direction:column;align-items:center;gap:6px;color:var(--ink)}
.photo-frame{width:100%;aspect-ratio:1/1.05;overflow:hidden;border:2px solid var(--ink);border-radius:var(--head);background:#fee4c7}
.photo-frame img{width:100%;height:100%;object-fit:cover;display:block}
.photo-cap{font-size:14px;font-weight:700}
.photo.selected{border:2px solid var(--seal);padding:7px 7px 5px}
.photo .stamp{position:absolute;right:6px;top:8px;background:#f8f1df}
.field input{width:100%;min-height:52px;border:0;border-bottom:2px solid var(--ink);background:#f8f1df;color:var(--ink);font:var(--fw-bold) var(--fs-xl)/var(--lh-xl) var(--font-sans);padding:10px 12px;border-radius:0;outline:none}
.field input::placeholder{color:#9b8a6a;font-weight:500}

/* ---------- 이승 심문 ---------- */
.answers{display:grid;gap:10px;margin:18px 0 16px}
.slip{position:relative;display:flex;align-items:center;gap:14px;width:100%;min-height:62px;text-align:left;padding:13px 50px 13px 14px;border:1px solid var(--rule);border-radius:var(--r);background:var(--paper);color:var(--ink);font:var(--t-body);letter-spacing:var(--t-body-ls)}
.slip b{flex:none;width:32px;height:32px;display:grid;place-items:center;border:1.5px solid var(--ink);font:var(--t-label);letter-spacing:var(--t-label-ls)}
.slip:active{background:var(--paper2)}
.slip.picked{border-color:var(--ink);box-shadow:inset 0 0 0 1px var(--ink)}
.slip.picked b{background:var(--ink);color:var(--paper)}
/* 심문: 질문(제목)은 위에 고정 · 보기만 안에서 스크롤 · [← ][다음 질문 →]은 아래 고정 칸 */
.phone.route-questions>.content{display:flex;flex-direction:column}
.route-questions .answers{margin-top:6px}
/* 11.12 심문 = 등록부와 같은 한지 위: 심판관 그림은 빼고 '심문 n / 3' 인주 태그만 제목 위에 */
.q-tag{display:inline-block;margin:0 0 12px;padding:5px 12px;background:var(--seal);color:#fff;font:var(--fw-solmoe) var(--fs-sm)/var(--sl-lh-sm) var(--font-solmoe)}
/* 보기 칸 = 등록부 머리·눈·코·입 값 칸(.pt-v)과 같은 기입란: 옅은 바탕 + 먹 밑줄 한 줄. 고르면 바탕만 진해짐 (퀴즈 .slip은 그대로) */
.route-questions .slip{border:0;border-bottom:1.5px solid var(--ink);border-radius:0;background:rgba(255,250,236,.45);background-image:none;box-shadow:none}
.route-questions .slip:active{background:rgba(255,250,236,.7)}
.route-questions .slip.picked{background:rgba(255,250,236,.75);box-shadow:none}
/* 유령 빵빵이: 보기 아래 오른쪽 끝에서 동동. 본문 흐름 안에 두어 보기를 가리지 않는다. 화면이 짧으면 보기 뒤로 밀려 함께 스크롤된다 */
.q-ghost{align-self:flex-end;flex:none;width:92px;height:auto;margin:auto 4px 0 0;padding-top:8px;pointer-events:none;animation:call-float 2.4s ease-in-out infinite}
@media (prefers-reduced-motion:reduce){.q-ghost{animation:none}}
.q-next-wrap{display:flex;gap:10px;align-items:stretch;min-height:60px}   /* 높이 고정: 보기를 골라 [다음 질문]이 나타나도 본문이 밀리지 않는다 */
.q-next-wrap>.q-prev,.q-next-wrap>.q-next{margin:0}   /* .secondary+.primary 위 여백을 덮어쓴다 */
.q-next{flex:1;gap:10px;animation:qUp .22s ease-out both}
.q-next[hidden]{display:none}
.q-prev{flex:none;width:56px;padding:0}
.q-arrow{display:block;flex:none;transition:transform .15s}
.q-next:active .q-arrow{transform:translateX(4px)}
.q-prev:active .q-arrow{transform:translateX(-4px)}
@keyframes qUp{from{opacity:0;transform:translateY(14px)}}

/* ---------- 망자 명부: passport.css (한지·연필 글씨·매달린 사진·관인) ---------- */
.lv{display:inline-block;font:var(--fw-solmoe) var(--fs-sm)/var(--sl-lh-sm) var(--font-solmoe);background:var(--ink);color:var(--paper);padding:1px 7px;border-radius:var(--r)}
.hell-chip{display:inline-block;font:var(--t-label);letter-spacing:var(--t-label-ls);padding:2px 9px;border-radius:var(--r);color:#fff;background:var(--seal)}
.hell-chip.sm{font-size:var(--fs-sm);line-height:var(--sl-lh-sm);padding:1px 6px}
/* 도장 ‘쾅’: 퀴즈 정답·결투·편지 부치기·업경대 판결·보너스에서 같이 쓴다 */
@keyframes slam{from{transform:scale(2.4) rotate(-24deg);opacity:0}}

/* ---------- 여정 홈 ---------- */
.id-strip{display:flex;align-items:center;gap:12px;width:100%;padding:10px 12px;background:var(--paper);color:var(--ink);border:1px solid var(--rule);border-radius:var(--r);text-align:left}
.face.sm{width:46px;height:48px;object-fit:cover;border:1.5px solid var(--ink);border-radius:var(--head);flex:none;background:#fee4c7}
.id-main{flex:1;min-width:0}
.id-main small{display:block;font:var(--fw-solmoe) var(--fs-sm)/var(--sl-lh-sm) var(--font-solmoe);color:var(--ink2)}
.id-main strong{display:block;font:var(--fw-solmoe) var(--fs-xl)/var(--sl-lh-xl) var(--font-solmoe);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.id-tags{display:flex;flex-direction:column;align-items:flex-end;gap:4px;flex:none}
/* 지도·지금 목표 버튼은 map.css */

/* ---------- 업경대 ---------- */
@keyframes faceUp{0%{transform:scale(.6) translateY(24px)}60%{transform:scale(1.06) rotate(-3deg)}100%{transform:none}}
.hell-seal{flex:none;width:64px;height:64px;border-radius:var(--r);display:grid;place-items:center;color:#fff;background:var(--seal);font:var(--fw-solmoe) var(--fs-3xl)/var(--sl-lh-3xl) var(--font-solmoe);transform:rotate(-6deg)}
.hell-seal.sm{width:46px;height:46px;font-size:var(--fs-2xl);line-height:var(--sl-lh-2xl)}
/* 현장 태그 (11.12 톤): 먹빛 한지 위 가운데에 밝은 한지색 몸체 + 굵은 먹선(#000 3px)으로 그린 만화풍 휴대폰 하나. 테두리 상자 없음.
   휴대폰은 제자리에서 살짝 떠오르며 기울고, 화면은 태그 대기 → 인식 완료를 오간다 / NFC 아이콘: Lucide(ISC) */
.tag-scene{position:relative;display:grid;place-items:center;height:250px;margin:22px 0 18px}
.tag-device{position:relative;width:104px;height:200px;animation:tagBob 3.2s ease-in-out infinite;filter:drop-shadow(0 12px 14px #000c)}
.ink-phone{position:relative;width:100%;height:100%;padding:14px 6px 14px;background:url('assets/ui/hanji-paper.webp') 50% 50%/cover,#efe3c4;border:3px solid #000;border-radius:18px;box-shadow:inset -5px -4px 0 #0000002e}
.ip-notch{position:absolute;left:50%;top:4px;width:24px;height:5px;margin-left:-12px;border-radius:3px;background:#000}
.mini-screen{display:grid;place-items:center;height:100%;background:#0f1311;border:2.5px solid #000;border-radius:9px;overflow:hidden}
.mini-screen>div{grid-area:1/1;display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center}
.mini-screen b{font:var(--fw-extrabold) 11px/1.3 var(--font-sans);color:#f1ead8}
.ms-ico{width:38px;height:38px;color:var(--tal)}
.ms-ico .nfc-ico{width:38px;height:38px;stroke-width:2.8}
.ms-done .face{width:52px;height:auto;border:2px solid #000;border-radius:var(--head);background:#fee4c7}
.ms-done b{color:var(--tal)}
.ms-wait{animation:msWait 3.2s infinite}
.ms-done{animation:msDone 3.2s infinite}
@keyframes tagBob{0%,100%{transform:translateY(4px) rotate(-3deg)}50%{transform:translateY(-6px) rotate(3deg)}}
@keyframes msWait{0%,42%{opacity:1}46%,88%{opacity:0}92%,100%{opacity:1}}
@keyframes msDone{0%,42%{opacity:0}46%,88%{opacity:1}92%,100%{opacity:0}}

/* ---------- 망자들의 마을 ---------- */
.dex-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;margin-bottom:12px}
.dex-cell{position:relative;aspect-ratio:3/4;border:1px dashed var(--line2);border-radius:var(--r);display:grid;place-items:center}
.dex-cell img{width:66%;height:70%;object-fit:contain;filter:brightness(0) opacity(.5)}
.dex-cell span{position:absolute;left:4px;bottom:2px;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--dim)}
.dex-cell.found{background:var(--paper);border:1px solid var(--rule)}
.dex-cell.found img{filter:none}
.dex-cell.found span{color:var(--ink)}
.back{min-height:44px;padding:0 14px;border-radius:var(--r);border:1px solid var(--line2);background:none;font:var(--t-button-sm);letter-spacing:var(--t-button-sm-ls)}
.quiz-visual{height:184px;margin-bottom:20px;display:grid;place-items:center;border-radius:var(--r)}   /* 그림 뒤 테두리 상자 없음 (점검판 요청 bkhasaav5rmrruoalcju) — 현장 단서 카드(.clue)만 자기 테두리 */
.quiz-visual.cut img{max-height:164px}
.quiz-visual.pair{display:flex;justify-content:center;gap:22px}
.quiz-visual.pair figure{margin:0;text-align:center}
.quiz-visual.pair img{width:108px;height:108px;object-fit:cover;border:2px solid #000;border-radius:50%}
.quiz-visual.pair figcaption{margin-top:8px;font:var(--t-label);letter-spacing:var(--t-label-ls)}
.quiz-visual.clue{background:var(--paper);color:var(--ink);border:1px solid var(--rule);outline:1px solid var(--rule);outline-offset:-8px;text-align:center;align-content:center}
.quiz-visual.clue b{font:var(--t-subtitle);letter-spacing:var(--t-subtitle-ls)}
.quiz-visual.clue p{margin:6px 0 0;font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls);color:var(--ink2)}
.quiz-q{margin-bottom:6px}
.quiz-result{display:flex;align-items:center;gap:14px;padding:16px;margin:16px 0 18px;border:1px solid var(--line2);border-radius:var(--r)}
.qr-face{width:80px;flex:none}
.quiz-result.wrong .qr-face{width:76px;height:76px;object-fit:cover;border:2px solid #000;border-radius:50%}
/* 정답·땡 도장 = 입국 허가 도장(seal-entry-ko)의 테두리 결 + 솔뫼 김대건체 글자로 만든 원화 질감 도장 (assets/quiz/seal-*.webp) */
.qr-stamp{display:block;width:auto;height:64px;max-width:none;transform:rotate(-7deg);transform-origin:30% 50%}
/* 결과 칸(정답·오답) = 얇은 선 상자 대신 명부와 같은 낡은 한지 쪽지, 도장이 종이에 배어들게 */
.quiz-result:is(.right,.wrong){border:0;background:url('assets/ui/hanji-age.webp') 0 0/100% 100% no-repeat,url('assets/ui/hanji-paper.webp') 50% 50%/cover,var(--paper);color:var(--ink);box-shadow:3px 3px 0 #000}
.quiz-result:is(.right,.wrong) .qr-stamp{mix-blend-mode:multiply}
.quiz-result.wrong .qr-stamp{height:60px}
.quiz-result.right .qr-stamp{height:66px}
.quiz-result p{margin:10px 0 0;font:var(--t-body);letter-spacing:var(--t-body-ls)}
.quiz-result.pop .qr-stamp{animation:slam .4s cubic-bezier(.3,1.6,.5,1) both}
.quiz-result.pop .qr-face{animation:faceUp .6s cubic-bezier(.3,1.5,.5,1) both}
.quiz-result.pop.wrong{animation:shake .35s .1s}

/* 쥐 발견 (dialog) */
dialog.found{text-align:center}
.found-rat{height:140px;margin:4px auto 0;display:block;animation:ratPop .6s cubic-bezier(.3,1.6,.5,1) both}
@keyframes ratPop{0%{transform:translateY(60px) scale(.5);opacity:0}100%{transform:none}}
.found-k{font:var(--t-title);letter-spacing:var(--t-title-ls);color:var(--tal);margin:8px 0 0}
dialog.found h3{font:var(--t-title);letter-spacing:var(--t-title-ls);margin-bottom:18px}

/* 등급 상승 */
#levelup{position:fixed;left:50%;top:22%;z-index:60;transform:translateX(-50%);opacity:0;pointer-events:none;text-align:center;padding:14px 24px;background:var(--tal);color:var(--tal-ink);border:2px solid #000;border-radius:var(--r);box-shadow:4px 4px 0 #000}
#levelup.show{animation:lvIn 2.8s ease-out both}
#levelup span{display:block;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls)}
#levelup b{display:block;font:var(--fw-solmoe) var(--fs-3xl)/var(--sl-lh-3xl) var(--font-solmoe);white-space:nowrap}
#levelup small{font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls)}
@keyframes lvIn{0%{opacity:0;transform:translate(-50%,16px)}10%{opacity:1;transform:translate(-50%,0)}85%{opacity:1}100%{opacity:0}}

/* ---------- 지옥문 결투: 대진 화면 (VS 판·이름판·왕펀치 컷인은 duel-vs.css) ---------- */
.arena-bg{position:absolute;inset:0;background:url('assets/ui/hero-900.webp') 50% 58%/cover;filter:grayscale(.35) brightness(.38)}
@keyframes spin{to{transform:rotate(1turn)}}
@keyframes bossIdle{50%{transform:scale(1.04) rotate(-1.5deg)}}
.primary.boss-cta{--hj:#d8483a;color:#fff;font-size:var(--fs-xl);line-height:var(--sl-lh-xl);min-height:64px}   /* 인주 물들인 한지 */

/* ---------- 결투 컨트롤러 ---------- */
.game{position:relative;display:flex;flex-direction:column;padding:10px 14px calc(14px + var(--safe-b));overflow:hidden;overflow:clip;background:#0b0d0c}
.game>.arena-bg{filter:grayscale(.5) brightness(.22)}
.game>*:not(.arena-bg):not(.fx-layer){position:relative;z-index:1}
.hud{display:flex;justify-content:space-between;align-items:center}
.hud-exit{min-height:44px;padding:0 14px;border-radius:var(--r);border:1.5px solid var(--muted);background:#000;font:var(--t-button-sm);letter-spacing:var(--t-button-sm-ls)}
.hud-time{display:flex;align-items:baseline;gap:2px;padding:2px 12px;background:#000;border:2px solid var(--tal);border-radius:var(--r);font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--tal)}
.hud-time b{font:var(--fw-solmoe) var(--fs-3xl)/var(--sl-lh-3xl) var(--font-solmoe);color:#fff}
.boss{display:grid;grid-template-columns:58px 1fr;gap:10px;align-items:center;margin:12px 0 6px;padding:8px;background:#000;border:2px solid var(--seal);border-radius:var(--r)}
.boss-face{width:58px;height:58px;object-fit:cover;border-radius:50%;border:2px solid var(--tal)}
.boss-row{display:flex;justify-content:space-between;align-items:baseline;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--muted)}
.boss-row b{font:var(--fw-solmoe) var(--fs-lg)/var(--sl-lh-lg) var(--font-solmoe);color:#fff}
.boss-row b i{font:var(--fw-bold) var(--fs-xs)/var(--lh-xs) var(--font-sans);font-style:normal;background:var(--tal);color:var(--tal-ink);padding:1px 5px;margin-right:6px;vertical-align:2px;border-radius:var(--r)}
.health{height:16px;margin:5px 0 0;background:#2a0f0c;border:1.5px solid #000;position:relative}
.health i{display:block;height:100%;background:var(--seal);transition:width .2s}
.health:after{content:'';position:absolute;inset:0;background:repeating-linear-gradient(90deg,transparent 0 9.6%,#000 9.6% 10%)}
.me-row{display:flex;justify-content:space-between;align-items:center;margin:4px 2px 0;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls)}
.me-name{color:var(--text)}
.lives{display:flex;gap:5px}
.lives i{width:14px;height:20px;border:1px solid var(--line2)}
.lives i.on{background:var(--tal);border-color:#000}
/* 옥지 무대 (11.11): 상자를 없애고 대형 화면(screen-duel.css 4. 옥지)과 같은 배치로 세운다. 포즈 그림 여섯 장을 겹치고 하나만 켠다(app.js okjiSync).
   --u = 대형 화면의 1cqh에 해당하는 단위. 무대 상자 크기에서 app.js okjiFit이 px로 넣는다(컨테이너 단위 cqh는 이 flex 배치에서 0으로 계산된다). 포즈별 키·가로 보정값은 대형 화면 값을 그대로 쓴다 */
.signal{flex:1;min-height:150px;display:flex;flex-direction:column;align-items:center;text-align:center;margin:8px 0 0}
.sig-stage{position:relative;flex:1;align-self:stretch;min-height:150px;--u:6px}
.sig-stage>*{position:absolute}
.sig-rays{left:50%;top:50%;width:calc(76*var(--u));aspect-ratio:1;translate:-50% -50%;border-radius:50%;background:repeating-conic-gradient(#c8372b55 0 4deg,transparent 4deg 12deg);-webkit-mask:radial-gradient(closest-side,#000 35%,transparent 80%);mask:radial-gradient(closest-side,#000 35%,transparent 80%);opacity:0;transition:opacity .2s}
.sig-glow{left:50%;bottom:calc(3*var(--u));width:calc(60*var(--u));height:calc(66*var(--u));translate:-50% 0;background:radial-gradient(ellipse 50% 50% at 50% 55%,#ff5a2855 0,#c8372b22 50%,transparent 75%)}
.sig-shadow{left:50%;bottom:calc(2*var(--u));width:calc(34*var(--u));height:calc(6*var(--u));translate:-50% 0;background:radial-gradient(closest-side,#000c,#0000)}
.sig-okji{left:50%;bottom:calc(4*var(--u));width:0;height:calc(56*var(--u))}
.so-mv,.so-br{position:absolute;inset:0;transform-origin:50% 100%}
.so-br{animation:okBreathe 1.6s ease-in-out infinite alternate}
.so-br>img{position:absolute;left:0;bottom:calc(-.4*var(--u));width:auto;max-width:none;opacity:0}
.so-br>img.on{opacity:1}
.so-br>[data-p=idle]{height:calc(58.06*var(--u));aspect-ratio:455/788;transform:translateX(-47.5%)}
.so-br>[data-p=ready]{height:calc(56*var(--u));aspect-ratio:571/760;transform:translateX(-56.7%)}
.so-br>[data-p=charge]{height:calc(56.37*var(--u));aspect-ratio:490/765;transform:translateX(-49.4%)}
.so-br>[data-p=smash]{height:calc(55.34*var(--u));aspect-ratio:486/751;transform:translateX(-58.6%)}
.so-br>[data-p=leap]{height:calc(56.66*var(--u));aspect-ratio:407/769;transform:translateX(-49.4%)}
.so-br>[data-p=down]{height:calc(52.24*var(--u));aspect-ratio:560/709;transform:translateX(-54.6%)}
.sig-okji.ko .so-mv{transform:translate(calc(2.7*var(--u)),calc(-3*var(--u))) scale(.78) rotate(-6deg)}
.sig-badge{left:calc(50% + 13*var(--u));top:max(0px,100% - 66*var(--u));width:calc(9*var(--u));height:calc(9*var(--u));display:none;place-items:center;translate:-50% 0;rotate:8deg;background:var(--tal);color:var(--tal-ink);border:3px solid #000;border-radius:50%;box-shadow:3px 3px 0 #000;font:var(--fw-solmoe) var(--fs-3xl)/1 var(--font-solmoe)}
.game.warn .sig-badge{display:grid}
.game.warn .sig-rays{opacity:1;animation:spin 3s linear infinite}
.game.fx-hit .so-mv,.game.fx-perfect .so-mv{animation:okFlinch .28s ease-out}
.game.fx-power .so-mv{animation:okKnock .67s}
.game.fx-hurt .so-mv{animation:okLeap 1.1s}
.game.warn .so-mv{animation:okWind .18s ease-in-out infinite alternate}
@keyframes okBreathe{from{transform:scale(1)}to{transform:scale(1.015)}}
@keyframes okWind{from{transform:scale(1.03) rotate(-3deg)}to{transform:scale(1.07) rotate(3deg)}}
@keyframes okFlinch{30%{transform:translateX(calc(2.1*var(--u))) rotate(3deg);filter:brightness(1.9)}}
@keyframes okKnock{0%,18%{transform:none}45%{transform:translate(calc(3.6*var(--u)),calc(-1*var(--u))) rotate(12deg) scale(.92);filter:brightness(2.2)}}
@keyframes okLeap{0%{transform:none;animation-timing-function:ease-in}22.7%{transform:translateY(calc(6*var(--u))) scale(2.2)}54.5%{transform:translateY(calc(6*var(--u))) scale(2.2);animation-timing-function:ease-out}100%{transform:none}}
.crack{position:absolute;inset:0;width:100%;height:100%;opacity:0}
.crack.go{animation:crackFade 1.2s ease-out both}
.crack path{fill:none;stroke-linejoin:round;stroke-linecap:round}
.crack .c-shadow{stroke:#000c;stroke-width:3.5}
.crack .c-line{stroke:#fff;stroke-width:1.3}
.crack .c-core{fill:#ffffffd9;stroke:#000;stroke-width:2}
@keyframes crackFade{0%{opacity:0}8%{opacity:1}70%{opacity:1}100%{opacity:0}}
.sig-info{position:relative;align-self:stretch;display:flex;flex-direction:column;align-items:center;padding:2px 0 6px}
.sig-info p{margin:6px 0 0}
#warning{font:var(--t-title);letter-spacing:var(--t-title-ls)}
.game-feedback{font:var(--t-body-strong);letter-spacing:var(--t-body-strong-ls);color:var(--muted);min-height:24px}
.combo{display:flex;align-items:center;gap:5px;margin-top:10px;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--dim)}
.combo i{width:30px;height:9px;background:var(--bg3);border:1px solid #000}
.combo i.on{background:var(--tal)}
.combo span{margin-left:4px}
/* 결투: 화살표 그림 하나(.arw, 위쪽)를 방향 클래스로 돌려 쓴다 */
.arw{display:block;width:1em;height:1em;fill:currentColor}
.ar-right .arw{transform:rotate(90deg)}
.ar-down .arw{transform:rotate(180deg)}
.ar-left .arw{transform:rotate(-90deg)}
/* 결투: 박자 표시 (11.11, app.js beatSVG·beatSpin. 예전 공격 버튼 둘레의 링 대신). 옥지 가슴께에 크게 겹친다.
   줄어드는 원(.beat-ring)이 과녁(.beat-aim)에 닿는 순간 친다. 노란 띠 = 좋음, 흰 띠 = 퍼펙트 구간(띠 두께가 판정 폭, 수치에서 계산).
   .now = 지금 퍼펙트 구간(띠가 밝아짐) · .spent = 이번 박자를 이미 쳤음 · 경고·쓰러짐 중엔 공격이 안 되므로 어둡게 · .off = 판 전·관전(숨김) */
.beat{left:50%;bottom:calc(32*var(--u));width:min(100%,calc(64*var(--u)));height:auto;aspect-ratio:1;translate:-50% 50%;overflow:visible;pointer-events:none;filter:drop-shadow(0 0 1.5px #000) drop-shadow(0 0 1.5px #000);transition:opacity .15s}
.beat circle{fill:none}
.beat-good{stroke:#f1cc4540}
.beat-perfect{stroke:#ffffff52}
.beat-aim{stroke:#000;stroke-width:1.5}
.beat-ring{stroke:var(--tal);stroke-width:5}
.beat.now .beat-good{stroke:#f1cc45a6}
.beat.now .beat-perfect{stroke:#ffffffd9}
.beat.spent{opacity:.28}
.game.warn .beat,.game.down .beat{opacity:.1}
.beat.off{opacity:0}
/* 11.12 두 번 쓸기: 쓸 방향을 순서대로 나란히. 이미 쓴 칸(.done)은 흐리게, 지금 쓸 칸(.cur)은 부적 노랑 */
.sig-arrow{left:50%;top:max(0px,100% - 68*var(--u));height:calc(15*var(--u));display:flex;align-items:center;gap:calc(2*var(--u));translate:-50% 0;font-size:calc(9*var(--u))}
.sig-arrow>i{width:calc(15*var(--u));height:calc(15*var(--u));display:grid;place-items:center;background:var(--paper);color:#000;border:3px solid #000;border-radius:50%;box-shadow:3px 3px 0 #000;transition:opacity .15s,background .15s}
.sig-arrow>i.cur{background:var(--tal);color:var(--tal-ink)}
.sig-arrow>i.done{opacity:.3}
.sig-arrow[hidden]{display:none}
.game.warn .sig-stage .sig-badge{display:none}   /* 화살표가 '!' 딱지를 대신한다 */
.sig-bar{display:block;width:72%;height:6px;background:var(--bg3);border:1px solid #000}
.sig-bar i{display:block;width:0;height:100%;background:var(--tal)}
/* 결투: 판정 (11.11) = 화면 전체 색 + 큰 한 단어. 휴대폰을 힐끗 봐도 읽히게 크게(화면 너비의 약 1/4 글자).
   색은 판정마다 다르게: 퍼펙트 = 부적 노랑 · 퍽 = 종이 · 왕펀치 = 부적 + 인주 테두리 · 헛손질·막힘 = 먹(화면이 어두워짐) · 휙 = 먹글씨 · 아야 = 인주 */
.fx-layer{position:absolute;inset:0;pointer-events:none;z-index:10;display:grid;place-items:center}
.fx-layer>span{font:var(--fw-solmoe) clamp(60px,21vw,108px)/1 var(--font-solmoe);opacity:0;-webkit-text-stroke:5px #000;paint-order:stroke fill;text-shadow:4px 4px 0 #000;white-space:nowrap}
.fx-layer>span.go{animation:popWord .6s cubic-bezier(.3,1.5,.5,1) both}
.pop-perfect{color:#fff}
.pop-hit{color:var(--paper)}
.fx-layer>.pop-power{color:var(--tal);font-size:clamp(68px,24vw,124px)}
.pop-miss{color:var(--dim)}
.pop-dodge,.pop-step{color:var(--text)}
.pop-hurt{color:#fff}
@keyframes popWord{0%{opacity:0;transform:scale(.4)}25%{opacity:1;transform:scale(1.12) rotate(-5deg)}70%{opacity:1}100%{opacity:0;transform:translateY(-36px)}}
.game:after{content:'';position:absolute;inset:0;pointer-events:none;opacity:0;z-index:9}
.game.fx-perfect:after{animation:fxFlash .5s;background:#f1cc45b8}
.game.fx-hit:after{animation:fxFlash .4s;background:#efe3c47a}
.game.fx-power:after{animation:fxFlash .55s;background:#f1cc45d1;box-shadow:inset 0 0 0 14px var(--seal)}
.game.fx-miss:after{animation:fxFlash .45s;background:#000000b8}
.game.fx-dodge:after{animation:fxFlash .45s;background:#f1ead880}
.game.fx-step:after{animation:fxFlash .3s;background:#f1ead84d}
.game.fx-hurt:after{animation:fxFlash .55s;background:#c8372bd1}
.game.fx-power,.game.fx-hurt{animation:shake .3s}
@keyframes fxFlash{20%{opacity:1}100%{opacity:0}}
@keyframes shake{20%{transform:translate(-6px,2px)}40%{transform:translate(6px,-2px)}60%{transform:translate(-4px,1px)}80%{transform:translate(3px,0)}}
/* 결투 패드 (11.11, app.js duelPad): 화면 전체가 패드라 끌어도 스크롤·확대·당겨서 새로고침이 되지 않고, 길게 눌러도 글자 선택·메뉴가 뜨지 않는다.
   .game 안에만 걸어 다른 화면의 스크롤에는 영향이 없다 ([나가기]는 button 기본값 manipulation) */
.game{touch-action:none;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
.game img{-webkit-user-drag:none}
html:has(.phone.is-game),html:has(.phone.is-game) body{overscroll-behavior:none}
/* 결투 조작 튜토리얼 그림 (11.11 탭·쓸기, app.js tutSteps). 팝업 틀(.tut-art 등)과 왕펀치·시작 장 그림은 duel-vs.css */
.t-phone{position:relative;width:108px;height:160px;background:#0b0d0c;border:3px solid var(--text);border-radius:8px;box-shadow:4px 4px 0 #000;overflow:hidden}
.t-phone .beat{position:absolute;left:50%;top:42%;width:100px;height:100px;translate:-50% -50%;filter:none}
.t-phone .beat-ring{transform-box:view-box;transform-origin:50% 50%;animation:tutBeat 1s linear infinite}
.t-finger{position:absolute;left:50%;top:80%;width:30px;height:30px;margin:-15px 0 0 -15px;background:#f1ead8d9;border:2px solid #000;border-radius:50%}
.t-tap .t-finger{top:86%;animation:tutTap 1s infinite}
.t-hit{position:absolute;right:12px;top:14px;font:var(--fw-solmoe) var(--fs-xl)/1 var(--font-solmoe);color:#fff;-webkit-text-stroke:3px #000;paint-order:stroke fill;opacity:0;animation:tutHit 1s linear infinite}
.t-arrow{position:absolute;left:50%;top:30%;width:56px;height:56px;margin:-28px 0 0 -28px;display:grid;place-items:center;background:var(--tal);color:var(--tal-ink);border:3px solid #000;border-radius:50%;font-size:32px}
.t-swipe .t-finger{top:72%;animation:tutSwipe 1.4s ease-in-out infinite}
.t-trail{position:absolute;left:calc(50% - 30px);top:72%;width:54px;height:8px;margin-top:-4px;background:var(--tal);border:1.5px solid #000;transform-origin:100% 50%;animation:tutTrail 1.4s ease-in-out infinite}
@keyframes tutBeat{0%{transform:scale(1);opacity:0}15%,55%{opacity:1}100%{transform:scale(.25);opacity:0}}
@keyframes tutTap{0%,42%,70%,100%{transform:scale(1.2);opacity:.45}50%{transform:scale(.85);opacity:1}}
@keyframes tutHit{0%,46%{opacity:0;scale:.6}52%{opacity:1;scale:1.1}80%{opacity:1;scale:1}86%,100%{opacity:0}}
@keyframes tutSwipe{0%,20%{transform:translateX(24px);opacity:0}30%{transform:translateX(24px);opacity:1}60%{transform:translateX(-30px);opacity:1}75%,100%{transform:translateX(-30px);opacity:0}}
@keyframes tutTrail{0%,30%{transform:scaleX(0);opacity:1}60%{transform:scaleX(1);opacity:1}75%,100%{transform:scaleX(1);opacity:0}}

/* ---------- 결투 결과 ---------- */
/* ---------- 지옥문 결투: 결과 (11.11, Cuphead 구조에서 출발) ----------
   패배 = 닫힌 지옥문 위로 '패배!'가 찍히고 기울어진 찢긴 한지가 떨어진다(망치 든 옥지 + 한마디 · 옥지 체력 게이지가 깎인 만큼 줄어든다). 점수는 없다.
   승리 = 쓰러진 옥지와 '녹다운!'이 지나간 뒤, 열린 지옥문 위 '결투 결과!' · 망자 전신 + 찢긴 한지 결과판의 점선 스탯 행 → 결투 점수.
   한지 = 망자 명부와 같은 hanji-age + hanji-paper, 가장자리는 hanji-edge 마스크. 그림자는 마스크 밖 감싸개에 drop-shadow로 */
.hanji-sheet{position:absolute;inset:0;z-index:-1;pointer-events:none;filter:drop-shadow(5px 7px 0 #000)}
.hanji-sheet>i{position:absolute;inset:0;
  background:url('assets/ui/hanji-age.webp') 0 0/100% 100% no-repeat,url('assets/ui/hanji-paper.webp') 50% 50%/cover,#eadcb8;
  -webkit-mask:url('assets/ui/hanji-edge.webp') 0 0/100% 100% no-repeat;mask:url('assets/ui/hanji-edge.webp') 0 0/100% 100% no-repeat}

.cup-death{position:relative;margin:calc(-1 * var(--ctop, 24px)) -20px 0;padding:calc(26px + env(safe-area-inset-top,0px)) 18px 28px;overflow:hidden;background:#0b0d0c}
.cup-death>.arena-bg{z-index:0;background:url('assets/duel/gate-3d-ko-closed.webp') 50% 40%/cover;filter:grayscale(.5) brightness(.22)}   /* 닫힌 지옥문 = 넘지 못한 문 */
.cup-death>*:not(.arena-bg){position:relative;z-index:1}
.cd-title{margin:0;text-align:center;font:var(--fw-solmoe) 58px/1.1 var(--font-solmoe);color:#f3e6c8;-webkit-text-stroke:6px #000;paint-order:stroke fill;text-shadow:4px 4px 0 #000;rotate:-4deg;animation:slam .45s .1s cubic-bezier(.3,1.6,.5,1) both}
.cd-card{isolation:isolate;margin:16px 2px 0;padding:26px 24px 26px;color:var(--ink);rotate:-3deg;animation:cd-drop .6s .45s cubic-bezier(.25,1.4,.5,1) both}
@keyframes cd-drop{from{translate:0 -60px;rotate:-13deg;opacity:0}}
.cd-boss{display:grid;grid-template-columns:96px 1fr;align-items:center;gap:10px}
.cd-okji{width:96px;height:148px;object-fit:contain;object-position:50% 100%}
.cd-quote{margin:0;font:var(--fw-solmoe) var(--fs-lg)/1.45 var(--font-solmoe)}
.cd-hp{margin-top:14px;padding-top:12px;border-top:1px dashed #16120e55}
.cd-hp-row{display:flex;justify-content:space-between;align-items:baseline;margin:0;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--ink2)}
.cd-hp-row b{font:var(--fw-solmoe) var(--fs-lg)/var(--sl-lh-lg) var(--font-solmoe);color:var(--ink)}
/* 결투 화면의 옥지 체력 막대를 한지 위 먹선으로: 남은 만큼 인주색, 깎인 자리는 먹 빗금. 처음엔 가득 찼다가 깎인 만큼 줄어든다 */
.cd-gauge{position:relative;height:18px;margin-top:6px;border:2px solid #16120e;border-radius:3px;background:repeating-linear-gradient(-45deg,#16120e40 0 2px,transparent 2px 7px)}
.cd-gauge>i{display:block;height:100%;width:var(--left);background:var(--seal);border-right:2px solid #16120e;animation:cd-drain 1.1s 1.1s cubic-bezier(.5,0,.3,1) both}
.cd-gauge:after{content:'';position:absolute;inset:0;background:repeating-linear-gradient(90deg,transparent 0 9.6%,#16120e80 9.6% 10%)}
@keyframes cd-drain{from{width:100%}}
.cd-hp-cap{margin:8px 0 0;text-align:center;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--ink2)}
.cd-hp-cap b{font:var(--fw-solmoe) var(--fs-xl)/1 var(--font-solmoe);color:var(--seal)}

.cup-results{position:relative;margin:calc(-1 * var(--ctop, 24px)) -20px 0;padding:calc(24px + env(safe-area-inset-top,0px)) 16px 26px;overflow:hidden;text-align:center;background:#0b0d0c;border-bottom:3px solid #000}
.cr-bg{position:absolute;inset:0;background:url('assets/duel/gate-3d-ko-open.webp') 50% 45%/cover;filter:brightness(.55) saturate(1.1)}   /* 열린 지옥문 = 문을 넘었다 */
.cr-bg:after{content:'';position:absolute;inset:0;background:linear-gradient(#0b0d0c00 40%,#0b0d0ccc)}
.cup-results>*:not(.cr-bg):not(.cr-ko){position:relative;z-index:1}
.cr-title{margin:0;font:var(--fw-solmoe) 46px/1.1 var(--font-solmoe);color:#fbeed2;-webkit-text-stroke:6px #000;paint-order:stroke fill;text-shadow:4px 4px 0 #000;rotate:-3deg;animation:slam .45s var(--ko) cubic-bezier(.3,1.6,.5,1) both}
.cr-body{display:grid;grid-template-columns:108px 1fr;align-items:end;gap:6px;margin-top:20px}
.cr-body>.cr-man{position:relative;width:108px;margin-top:40px;filter:drop-shadow(4px 4px 0 #000);animation:cr-rise .45s calc(var(--ko) + .15s) cubic-bezier(.3,1.4,.5,1) both}
@keyframes cr-rise{from{translate:-40px 0;opacity:0}}
.cr-board{isolation:isolate;padding:24px 22px 22px;text-align:left;color:var(--ink);rotate:1.5deg;animation:cr-rise .4s calc(var(--ko) + .2s) ease-out both}
.cr-board dl{margin:0}
.cr-board dl>div{display:flex;align-items:baseline;gap:6px;padding:3px 0;animation:cr-row .3s calc(var(--ko) + .5s + var(--i) * .25s) ease-out both}
.cr-board dt{display:flex;flex:1;gap:6px;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);white-space:nowrap}
.cr-board dt:after{content:'';flex:1;border-bottom:2px dotted #16120e55;translate:0 -4px}
.cr-board dd{margin:0;font:var(--fw-solmoe) var(--fs-xl)/var(--sl-lh-xl) var(--font-solmoe)}
.cr-board i{font-style:normal;font-size:.7em;color:var(--ink2)}
@keyframes cr-row{from{opacity:0;translate:-8px 0}}
.cr-score{display:grid;justify-items:center;margin-top:8px;padding-top:8px;animation:slam .45s calc(var(--ko) + .6s + var(--i) * .25s) cubic-bezier(.3,1.6,.5,1) both}
.cr-score small,.cr-score span{font:var(--t-caption);letter-spacing:var(--t-caption-ls);color:var(--ink2)}
.cr-score b{font:var(--fw-solmoe) var(--fs-4xl)/var(--sl-lh-4xl) var(--font-solmoe);color:var(--seal)}
.cr-ribbon{display:inline-block;margin:18px 0 0;padding:7px 18px;font:var(--fw-solmoe) var(--fs-lg)/var(--sl-lh-lg) var(--font-solmoe);color:#fff;background:var(--seal);border:2px solid #000;box-shadow:3px 3px 0 #000;rotate:-2deg;animation:slam .45s calc(var(--ko) + 1.8s) cubic-bezier(.3,1.6,.5,1) both}
.cr-note{margin:8px 0 0;font:var(--t-caption);letter-spacing:var(--t-caption-ls);color:#fbeed2}
/* 녹다운 컷 (승리 = 옥지를 한 번 이상 쓰러뜨림). 2.9초:
   영상(okji-ko.mp4, Higgsfield 생성) = 지옥문 앞에서 노려보던 옥지가 주먹에 맞고(.2s) 뒤로 밀려나다 엉덩방아를 찧는다(1.1s = '쾅', 먼지).
   CSS는 쾅에 맞춰 번쩍 + 흔들림 + 인주·먹 띠 → 인주 띠 위에 '녹·다·운·!' 한 자씩 → 종이 걷히듯 위로 빠진다.
   글자·띠·도장은 옥지가 앉는 자리(컷 아래쪽 절반)를 가리지 않게 위쪽에 둔다.
   .wait = 영상이 실제로 돌기 전(startKoCut). 컷과 결과판 연출을 모두 멈춰 두었다가 영상과 함께 출발시킨다.
   .still = 영상을 못 틀 때. 영상을 치우고 끝 그림(okji-ko-poster.webp = 주저앉은 옥지)을 컷 바탕에 깐다.
   결과판 연출은 --ko(컷이 끝나는 때) 뒤로 미룬다. 움직임 줄이기에서는 컷이 아예 보이지 않는다(기본 opacity 0) */
.cup-results{--ko:2.85s}
.cup-results.wait *,.cup-results.wait *:before,.cup-results.wait *:after{animation-play-state:paused}
.cr-ko{position:absolute;inset:0;z-index:5;overflow:hidden;pointer-events:none;background:#0b0d0c;opacity:0;animation:cr-ko 2.9s both,ko-shake .4s 1.1s linear both}
.cr-ko:after{content:'';position:absolute;inset:0;background:#fff;opacity:0;animation:ko-flash .3s 1.08s ease-out forwards}
.ko-clip{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.cup-results.still .cr-ko{background:#0b0d0c url('assets/duel/okji-ko-poster.webp') 50%/cover}
.cup-results.still .ko-clip{display:none}
.ko-band{position:absolute;left:-20%;width:140%;rotate:-12deg;border-top:3px solid #000;border-bottom:3px solid #000}
.ko-band.b1{top:14%;height:72px;background:var(--seal);animation:ko-band .35s 1.1s cubic-bezier(.2,.9,.25,1) both}
.ko-band.b2{top:31%;height:14px;background:#16120e;animation:ko-band-r .35s 1.15s cubic-bezier(.2,.9,.25,1) both}
.ko-word{position:absolute;left:0;right:0;top:15%;margin:0;text-align:center;white-space:nowrap;rotate:-12deg}
.ko-word span{display:inline-block;font:var(--fw-solmoe) 60px/1 var(--font-solmoe);color:#fbeed2;-webkit-text-stroke:7px #000;paint-order:stroke fill;text-shadow:4px 5px 0 #000;animation:slam .32s calc(1.27s + var(--i) * .09s) cubic-bezier(.3,1.7,.5,1) both}
.ko-word span:nth-child(odd){rotate:-5deg}.ko-word span:nth-child(even){rotate:6deg;translate:0 -5px}
@keyframes cr-ko{0%{opacity:0;clip-path:inset(0)}3%{opacity:1}87%{clip-path:inset(0 0 0 0)}100%{opacity:1;clip-path:inset(0 0 100% 0)}}
@keyframes ko-flash{0%{opacity:.95}100%{opacity:0}}
@keyframes ko-shake{0%,100%{translate:0 0}15%{translate:-9px 6px}30%{translate:8px -7px}45%{translate:-6px -4px}60%{translate:5px 5px}80%{translate:-2px 2px}}
@keyframes ko-band{from{translate:-110% 0}}
@keyframes ko-band-r{from{translate:110% 0}}
@media (prefers-reduced-motion:reduce){.cr-ko{display:none}}

/* ---------- 윤회의 방 ---------- */
.letter-sheet{position:relative;margin-top:18px;padding:20px 18px 14px;background:#f5ecd4;color:var(--ink);border:1px solid var(--rule);border-radius:var(--r)}
.letter-sheet:before{content:'';position:absolute;left:40px;top:0;bottom:0;width:1px;background:#c8372b40}
.ls-to{font:var(--fw-solmoe) var(--fs-lg)/var(--sl-lh-lg) var(--font-solmoe);margin:0 0 6px;padding-left:26px}
.ls-from{text-align:right;font:var(--t-label);letter-spacing:var(--t-label-ls);color:var(--ink2);margin:8px 0 0}
.letter-sheet textarea{display:block;width:100%;min-height:256px;resize:vertical;border:0;outline:none;background:transparent repeating-linear-gradient(180deg,transparent 0 31px,#b9a26f66 31px 32px);background-attachment:local;color:var(--ink);font:var(--t-body-lg);letter-spacing:var(--t-body-lg-ls);padding:0 4px 0 26px}
.letter-sheet textarea::placeholder{color:#9b8a6a}
.starter{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px}
.starter button{min-height:44px;padding:6px 12px;border-radius:var(--r);border:1px solid var(--line2);background:none;font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls);color:var(--muted)}
.letter-meta{display:flex;justify-content:space-between;font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls);color:var(--dim);margin:12px 0 16px}
.farewell{position:relative;text-align:center}
.route-letter-done .scr-head{text-align:center}
.envelope{position:relative;width:196px;height:120px;margin:0 auto 28px}
.letter-edit{margin-top:14px}
.envelope:before{content:'';position:absolute;inset:0;background:#c9b07a;border-radius:var(--r)}
.env-body{position:absolute;inset:0;background:#e6d6ac;border-radius:var(--r);clip-path:polygon(0 0,50% 52%,100% 0,100% 100%,0 100%);z-index:2}
.env-flap{position:absolute;left:0;right:0;top:0;height:70%;background:#dccb9b;clip-path:polygon(0 0,100% 0,50% 100%);z-index:3;transform-origin:top}
.env-seal{position:absolute;left:50%;top:44%;z-index:4;width:52px;height:52px;margin-left:-26px;background:var(--seal);color:#fbeed2;border:0;transform:rotate(-6deg)}
.envelope.anim .env-flap{animation:flap .6s .2s ease-in both}
.envelope.anim .env-seal{animation:slam .4s .85s cubic-bezier(.3,1.6,.5,1) both}
@keyframes flap{from{transform:rotateX(180deg)}}
.farewell-ghost{position:absolute;right:4px;top:8px;width:66px;animation:float 5s ease-in-out infinite}
.letter-read{padding:20px 18px}
.letter-text{font:var(--t-body-lg);letter-spacing:var(--t-body-lg-ls);white-space:pre-wrap;overflow-wrap:anywhere;padding-left:26px;min-height:64px}
.letter-read.compact{margin-top:16px}
.stampbook{margin:22px 0 0;padding:16px 16px 6px}
.sb-head{display:flex;justify-content:space-between;align-items:baseline;padding-bottom:8px;border-bottom:2px solid var(--ink);font:var(--fw-solmoe) var(--fs-lg)/var(--sl-lh-lg) var(--font-solmoe)}
.sb-head small{font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--ink2)}
.sb-list{list-style:none;margin:0;padding:0}
.sb-list li{display:grid;grid-template-columns:48px 1fr 54px;gap:12px;align-items:center;padding:10px 0;border-bottom:1px dashed var(--rule)}
.sb-list li:last-child{border-bottom:0}
.sb-art{width:48px;height:48px;display:grid;place-items:center}
.sb-art img{max-width:48px;max-height:48px;object-fit:contain}
.sb-art .face{width:42px;height:44px;object-fit:cover;border:1.5px solid var(--ink);border-radius:var(--head);background:#fee4c7}
.sb-list li:not(.ok) .sb-art img:not(.zi){filter:grayscale(1) opacity(.35)}
.sb-list li:not(.ok) .sb-art img.zi{opacity:.75}
.sb-list b{display:block;font:var(--t-label);letter-spacing:var(--t-label-ls)}
.sb-list span{font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls);color:var(--ink2)}
.sb-slot{width:52px;height:52px;display:grid;place-items:center;border:1.5px dashed var(--rule);border-radius:var(--r);font:var(--t-label);letter-spacing:var(--t-label-ls);color:#c9b88e}
.sb-list li.ok .sb-slot{border:2.5px solid var(--seal);color:var(--seal);transform:rotate(-9deg);line-height:var(--sl-lh-sm)}

/* ---------- 편지 입력 ---------- */
.field-label{display:block;font-weight:700;font-size:15px;margin:18px 0 8px}
.dark-area{width:100%;min-height:170px;border:1px solid var(--line2);background:var(--bg2);border-radius:var(--r);padding:14px;line-height:1.8;outline:none;resize:vertical}

/* ---------- PC 기획 패널 (밝은 문서형 · Pretendard) ---------- */
.plan{--pl-bg:#faf7f0;--pl-ink:#1d1a15;--pl-sub:#4f483c;--pl-dim:#7a7263;--pl-line:#e3dccd;--pl-amber:#8a6400;--pl-red:#b3291f;
  position:fixed;left:max(3vw,calc(50% - 600px));top:24px;bottom:24px;width:min(500px,calc(100vw - 430px - 10vw));overflow:auto;padding:24px 26px 28px;
  background:var(--pl-bg);color:var(--pl-ink);border:1px solid var(--pl-line);border-radius:var(--r);
  font-family:'Pretendard Variable',Pretendard,-apple-system,system-ui,sans-serif;word-break:keep-all;scrollbar-width:thin;scrollbar-color:#cfc6b3 transparent}
.plan button,.plan a{font-family:inherit}
.pl-demo{position:sticky;top:-24px;z-index:2;display:flex;justify-content:space-between;align-items:center;gap:12px;margin:-24px -26px 18px;padding:12px 14px 12px 26px;background:var(--pl-ink);color:#fff}
.pl-demo span{display:grid;gap:1px}
.pl-demo b{font-size:15px;font-weight:800}
.pl-demo small{font-size:13px;color:#cfc6b3}
.plan .pl-demo button{flex:none;min-height:42px;padding:0 16px;border:1.5px solid #000;border-radius:var(--r);background:var(--tal);color:var(--tal-ink);font-size:14px;font-weight:800;box-shadow:0 2px 0 #000}
.plan .pl-demo button:active{box-shadow:none;transform:translateY(2px)}
.pl-head{display:flex;align-items:center;gap:12px;padding:10px 12px;margin:-8px -10px 0;background:var(--bg);border-radius:var(--r)}
.pl-head img{width:84px;height:auto;display:block}
.pl-head span{font-size:13px;color:var(--muted);font-weight:600}
.pl-now{margin:22px 0 24px}
.pl-now small{font-size:13px;font-weight:700;color:var(--pl-amber)}
.pl-now h1{font-size:27px;font-weight:800;line-height:1.3;font-family:inherit;letter-spacing:-.6px;margin:4px 0 10px;color:var(--pl-ink)}
.pl-now p{margin:0;font-size:16px;line-height:1.75;color:var(--pl-ink)}
.pl-do{list-style:none;margin:14px 0 0;padding:0}
.pl-do li{position:relative;padding:4px 0 4px 16px;font-size:15px;color:var(--pl-sub);line-height:1.65}
.pl-do li:before{content:'';position:absolute;left:2px;top:13px;width:5px;height:5px;background:var(--pl-amber);transform:rotate(45deg)}
.plan h2{font-size:15px;font-weight:800;line-height:1.4;font-family:inherit;color:var(--pl-ink);margin:0 0 10px;padding-top:18px;border-top:1px solid var(--pl-line)}
.pl-notes ul{list-style:none;margin:0 0 22px;padding:0}
.pl-notes li{display:grid;grid-template-columns:46px 1fr;gap:10px;align-items:start;padding:6px 0;font-size:15px;line-height:1.6;color:var(--pl-sub)}
.tag{font-size:12px;font-weight:800;line-height:1.6;text-align:center;padding:0;border:1.5px solid #b9b09c;border-radius:var(--r);color:var(--pl-dim)}
.tag.t-draft{color:var(--pl-amber);border-color:var(--pl-amber)}
.tag.t-open{color:var(--pl-red);border-color:var(--pl-red)}
.tag.t-cmp{color:var(--tal-ink);background:var(--tal);border-color:#c9a51f}
.tag.t-check{color:#fff;background:var(--pl-red);border-color:var(--pl-red)}
.pl-flow ol{list-style:none;margin:0 0 22px;padding:0}
.pl-flow li{display:grid;grid-template-columns:104px 1fr;gap:10px;align-items:center;padding:7px 0;border-bottom:1px dashed var(--pl-line)}
.pl-g{font-size:14px;font-weight:700;color:var(--pl-dim)}
.pl-g i{font:900 14px var(--serif);font-style:normal;color:var(--pl-amber);margin-right:5px}
.pl-flow li.here .pl-g{color:var(--pl-ink)}
.pl-steps{display:flex;flex-wrap:wrap;gap:4px}
.pl-steps button{min-height:34px;padding:2px 10px;border:1px solid #d3cab7;border-radius:var(--r);background:#fff;color:var(--pl-sub);font-size:13px;font-weight:600}
.pl-steps button:hover{border-color:var(--pl-sub);color:var(--pl-ink)}
.pl-steps button.on{background:var(--tal);border-color:#000;color:var(--tal-ink);font-weight:800}
/* 화면별 제안 메모 (기획 패널) */
.pl-memo{margin:0 0 22px;padding:16px 18px 14px;background:#fff;border:1px solid var(--pl-line);border-left:4px solid var(--pl-amber);border-radius:var(--r)}
.pl-memo .tag{display:inline-block;padding:0 6px}
.plan .pl-memo h2{margin:8px 0 6px;padding:0;border:0;font-size:17px}
.pm-lead{margin:0 0 10px;font-size:15px;font-weight:700;line-height:1.6;color:var(--pl-ink)}
.pl-memo ul{list-style:none;margin:0 0 10px;padding:0}
.pl-memo li{position:relative;padding:3px 0 3px 16px;font-size:15px;line-height:1.65;color:var(--pl-sub)}
.pl-memo li:before{content:'';position:absolute;left:2px;top:12px;width:5px;height:5px;background:var(--pl-amber);transform:rotate(45deg)}
.pm-end{margin:0;padding-top:10px;border-top:1px dashed var(--pl-line);font-size:14px;line-height:1.6;color:var(--pl-dim)}
.pl-sw{margin-bottom:8px}
.pl-now small{display:block}
.pl-sec{margin-bottom:18px}
.pl-sec .pl-do{margin:0}
.pl-ol{margin:0;padding:0 0 0 24px;font-size:15px;line-height:1.65;color:var(--pl-ink);font-weight:600}
.pl-ol li{padding:3px 0 3px 4px}
.pl-ol li::marker{color:var(--pl-amber);font-weight:800}
.pl-note{margin:8px 0 0;font-size:14px;line-height:1.6;color:var(--pl-dim)}
.pl-ask{margin:4px 0 22px;padding:14px 18px 12px;background:#fbf1dc;border-left:4px solid var(--pl-amber);border-radius:var(--r)}
.plan .pl-ask h2{margin:0 0 6px;padding:0;border:0;font-size:14px;color:var(--pl-amber)}
.pl-ask ul{list-style:none;margin:0;padding:0}
.pl-ask li{position:relative;padding:3px 0 3px 16px;font-size:15px;font-weight:600;line-height:1.65;color:var(--pl-ink)}
.pl-ask li:before{content:'';position:absolute;left:2px;top:12px;width:5px;height:5px;background:var(--pl-amber);transform:rotate(45deg)}
.pl-scr{margin-bottom:14px}
.tool-row{display:flex;flex-wrap:wrap;gap:8px}
.plan .tool-row a.secondary.sm{display:inline-grid;place-items:center;text-decoration:none;padding:0 12px}
.pl-scr{margin:-6px 0 18px;padding:12px 14px;background:#fff;border:1.5px dashed var(--pl-amber);border-radius:var(--r)}
.pl-scr>small{display:block;margin-bottom:8px;font-size:13px;font-weight:800;color:var(--pl-amber)}
.plan .switch>span{color:var(--pl-sub)}
.plan .seg{border-color:#b9b09c;background:#fff}
.plan .seg button{color:var(--pl-sub);font-weight:600}
.plan .seg button+button{border-left-color:#b9b09c}
.plan .seg button.on{background:var(--tal);color:var(--tal-ink);font-weight:800}
.pl-tools{display:flex;flex-wrap:wrap;gap:8px;padding-top:14px;border-top:1px solid var(--pl-line)}
.plan .secondary.sm{margin:0;background:#fff;color:var(--pl-ink);border:1.5px solid var(--pl-ink);box-shadow:0 2px 0 var(--pl-ink);font-size:14px;font-weight:700;font-family:inherit;min-height:42px}
.plan .secondary.sm:active{box-shadow:none;transform:translateY(2px)}

/* 비교 전환 */
.switch{display:grid;gap:6px;margin:0 0 12px}
.switch>span{font-size:13px;font-weight:700;color:var(--muted)}
.seg{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;border:1.5px solid var(--line2);border-radius:var(--r);overflow:hidden}
.seg button{min-height:44px;border:0;background:none;color:var(--muted);font-size:14px;font-weight:700}
.seg button+button{border-left:1.5px solid var(--line2)}
.seg button.on{background:var(--tal);color:var(--tal-ink);font-weight:900}
.sw-hint{margin:0 0 10px;font-size:13px;color:var(--dim)}
.switch>span small{font-size:12px;font-weight:600;color:var(--dim);margin-left:4px}
.sw-desc{margin:4px 0 0;font-size:13px;line-height:1.55;color:var(--muted)}
.plan .sw-hint,.plan .switch>span small{color:var(--pl-dim)}
.plan .sw-desc{color:var(--pl-sub);font-size:14px}
.sw-where{margin:2px 0 0;font-size:13px;font-weight:700;line-height:1.5;color:var(--tal)}
.sw-others{display:grid;gap:6px;margin:0 0 12px}
.sw-others .sw-hint{margin:4px 0 0}
.sw-go{display:flex;justify-content:space-between;align-items:center;gap:8px;min-height:44px;padding:6px 12px;border:1px dashed var(--line2);border-radius:var(--r);background:none;color:var(--text);font-size:14px;text-align:left}
.sw-go span{font-size:13px;color:var(--dim);white-space:nowrap}
.sw-go span:after{content:' →'}
.plan .sw-where{color:var(--pl-amber);font-size:14px}
.plan .sw-go{background:#fff;border-color:#c9c0ac;color:var(--pl-ink)}
.plan .sw-go:hover{border-color:var(--pl-sub)}
.plan .sw-go span{color:var(--pl-dim)}
/* 데모 바 안의 단계별 비교 전환 */
.db-cmp{display:flex;align-items:center;gap:8px;min-width:0}
.db-cmp small{font-size:13px;font-weight:800;color:var(--tal);letter-spacing:.5px}
.seg.mini{border-color:var(--line2)}
.seg.mini button{min-height:32px;padding:0 12px;font-size:13px;white-space:nowrap}
a.secondary{text-decoration:none}

/* ---------- 쥐 찾기: 첫 안내 · 카메라 ---------- */
.guide,.scan{display:flex;flex-direction:column}
.guide>*,.scan>*{flex-shrink:0}
.scan{overflow-y:auto;overscroll-behavior:contain}   /* 아주 낮은 화면에서만: 카메라 칸 최소 높이를 지키고 안에서 스크롤 */
.scan-top{display:flex;align-items:center;justify-content:space-between;height:56px;padding:0}
.scan-top b{font:var(--fw-solmoe) var(--fs-lg)/var(--sl-lh-lg) var(--font-solmoe)}
/* 11.12 헤더 버튼은 테두리 없이 흐린 글자만 — 네모 테두리가 화면을 시끄럽게 했다 */
.scan-top .back{align-self:stretch;min-width:76px;height:auto;padding:0 18px;border:0;border-radius:0;color:var(--muted)}
.scan-top .back:active{background:var(--bg3);color:var(--text)}
.back.ghost{border-color:transparent;color:var(--muted)}
.guide-body{padding:20px 20px 8px;animation:guideIn .35s ease-out both}
@keyframes guideIn{from{opacity:0;transform:translateX(24px)}}
.guide-cta{padding:12px 20px calc(22px + var(--safe-b))}
.guide-cta .tip{margin:0 0 12px}
/* 11.12 톤앤매너 2차: 그림 칸 상자·한지 바탕을 걷고 어두운 화면 위에 원화만. 먹선이 바탕에 묻히지 않게 은은한 빛(--g-glow)만 두른다 */
.g-art{--g-glow:drop-shadow(0 0 10px rgba(239,227,196,.22));position:relative;height:clamp(220px,34dvh,300px);margin:0 0 24px;display:grid;place-items:center}
.g-art img{filter:var(--g-glow)}
.g-rat{position:absolute;bottom:22px;height:auto}
/* 숨은 쥐 둘은 한 톤만 눌러 가운데 쥐보다 뒤에 있게 (예전 .35는 바탕에 묻혀 알아보기 어려웠다) */
.g-rat.r1{left:8%;width:84px;transform:rotate(-8deg);filter:brightness(.68) var(--g-glow)}
.g-rat.r2{left:50%;width:118px;margin-left:-59px;bottom:30px;animation:ratPeek 2.6s ease-in-out infinite}
.g-rat.r3{right:6%;width:92px;filter:brightness(.68) var(--g-glow)}
@keyframes ratPeek{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px) rotate(-3deg)}}
.g-bubble{position:absolute;top:22px;left:50%;transform:translateX(-10%);margin:0}
.g-view{position:relative;width:200px;height:200px;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:6px;padding-bottom:22px}
.g-view>i,.cam-frame>i{position:absolute;width:30px;height:30px;border:0 solid var(--tal)}
.g-view>i:nth-child(1),.cam-frame>i:nth-child(1){left:0;top:0;border-width:4px 0 0 4px}
.g-view>i:nth-child(2),.cam-frame>i:nth-child(2){right:0;top:0;border-width:4px 4px 0 0}
.g-view>i:nth-child(3),.cam-frame>i:nth-child(3){left:0;bottom:0;border-width:0 0 4px 4px}
.g-view>i:nth-child(4),.cam-frame>i:nth-child(4){right:0;bottom:0;border-width:0 4px 4px 0}
.g-view-rat{width:86px;height:auto}
.g-qr{display:block;width:78px;height:78px;padding:5px;background:#fff}
.g-qr svg{width:100%;height:100%;display:block}
/* 11.12 안내 2/3: 배에 QR이 찍힌 쥐 원화 한 장 */
.g-cam-rat{position:absolute;left:50%;top:5%;height:90%;width:auto;transform:translateX(-50%) rotate(-3deg)}
.g-crowd{max-height:210px;width:auto}
.g-seal{position:absolute;right:22px;top:20px;width:58px;height:58px;display:grid;place-items:center;background:var(--tal);color:var(--seal);border:3px solid #000;border-radius:var(--r);font:var(--fw-solmoe) var(--fs-xl)/var(--sl-lh-xl) var(--font-solmoe);transform:rotate(8deg)}
.scan{padding-bottom:12px}
.cam{position:relative;flex:1 1 0;min-height:330px;margin:12px 12px 0;background:#000;border:2px solid #000;outline:1px solid var(--line2);border-radius:var(--r);overflow:hidden}
.cam video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .3s}
.cam.live video{opacity:1}
.cam-off{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:24px;text-align:center;color:var(--muted);font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls)}
.cam-off p{margin:0}
.cam-off b{font:var(--t-subtitle);letter-spacing:var(--t-subtitle-ls);color:var(--text)}
.cam-off-rat{width:76px;filter:brightness(.4);margin-bottom:6px}
.cam-off .secondary.sm{margin-top:10px}
.cam.live .cam-off{display:none}
/* 11.12 요청: 영상은 인식되는 가운데 정사각형(.cam-win)만 보인다. 조준 틀과 같은 자리·크기 */
.cam{container-type:size}   /* 바탕은 위 .cam의 검정. 현장 배경 그림은 쥐 찾기(.scan-rat)에만 — 업경대·결투 입장 QR 카메라는 검은 바탕 */
.cam-win,.cam-frame{position:absolute;left:50%;top:46%;width:min(84%,320px);width:min(84cqw,320px,calc(100cqh - 120px));aspect-ratio:1;transform:translate(-50%,-50%);pointer-events:none}
.cam-win{overflow:hidden;background:#111}
.cam:not(.live) .cam-win{visibility:hidden}
.cam-line{position:absolute;left:8%;right:8%;top:10%;height:2px;background:var(--seal);animation:scanline 2.2s ease-in-out infinite alternate}
@keyframes scanline{to{top:90%}}
.cam:not(.live) .cam-frame,.cam:not(.live) .cam-hint{display:none}
.cam.hit .cam-frame{animation:frameHit .45s ease-out}
.cam.hit .cam-frame>i{border-color:var(--seal)}
@keyframes frameHit{40%{transform:translate(-50%,-50%) scale(.88)}}
.cam-hint{position:absolute;left:50%;bottom:14px;transform:translateX(-50%);width:max-content;max-width:calc(100% - 24px);margin:0;padding:6px 12px;background:var(--paper);color:var(--ink);font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);border-radius:var(--r);text-align:center}
/* 11.12: 제목 헤더(여정·제목·사용법) 대신 저승 여정 지도와 같은 신분 띠. 크기·그림자도 지도(map.css .route-home .id-strip)와 맞춘다 */
.scan-id{margin:calc(12px + env(safe-area-inset-top,0px)) 12px 0}
.scan-id .id-strip{padding:7px 10px;gap:10px;box-shadow:3px 4px 0 #000}
.scan-id .id-strip .face.sm{width:40px;height:42px}
.scan-id .id-main strong{font-size:var(--fs-lg)}
/* 사용법: 헤더에서 빠져 카메라 칸 오른쪽 위 작은 쪽지로 (카메라를 켜지 못한 화면에서도 보인다) */
.cam-help{position:absolute;top:10px;right:10px;z-index:3;min-height:34px;padding:0 12px;border:1px solid var(--line2);border-radius:var(--r);background:#000a;color:var(--text);font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls)}
.cam-help:active{background:var(--bg3)}
/* 11.12 2차: 쥐·퀴즈 상자와 경험치 줄을 걷었다. 신분 띠 바로 아래, 배경 그림 위에 글자만 한 줄(쥐 / 퀴즈 ··· 도감), 세로 가운데 맞춤 */
.scan-hud{display:flex;align-items:center;justify-content:space-between;gap:8px;margin:6px 12px 0;padding:0 0 0 4px;color:var(--text);text-shadow:0 1px 3px #000,0 0 10px rgba(0,0,0,.7)}
.sh-main{margin:0;display:flex;flex-wrap:wrap;align-items:center;column-gap:6px;font:var(--t-label);letter-spacing:var(--t-label-ls)}
.sh-main span{white-space:nowrap}
.sh-main i{font-style:normal;color:var(--muted)}
.sh-main b{font-size:var(--fs-2xl);line-height:1;color:var(--tal)}
.sh-dex{flex:none;display:flex;align-items:center;gap:2px;min-height:40px;padding:0 6px 0 10px;border:0;background:none;color:var(--text);font:var(--t-button-sm);letter-spacing:var(--t-button-sm-ls);text-shadow:inherit}
.sh-dex:active{opacity:.6}
/* 11.12 2차: 현장 배경 그림이 카메라 칸이 아니라 쥐 찾기 화면 전체를 덮는다(검은 바탕이 보이지 않게).
   카메라는 테두리 상자 없이 가운데 정사각형(조준 틀)만, 예전보다 작게. 안내 쪽지는 정사각형 바로 아래 */
.scan-rat{background:linear-gradient(rgba(0,0,0,.18),rgba(0,0,0,.42)),#000 url(assets/req/odu97m6393vu4vvtyabe/cam-bg-site.webp) center/cover no-repeat}
.scan-rat .cam{--sq:min(64cqw,250px,calc(100cqh - 96px));--cy:calc(50% - 22px);min-height:290px;margin:4px 12px 0;background:none;border:0;outline:0;border-radius:0}
.scan-rat .cam-win,.scan-rat .cam-frame{top:var(--cy);width:var(--sq)}
.scan-rat .cam-win{border-radius:2px}
/* 11.12 요청(uf3lllrp): 안내 문구는 상자 없이 흰 글자만, 아래 버튼 줄 위 20px(.cam 아래 끝 8px + .scan-btns 위 여백 12px) 가운데.
   토스트도 버튼 위에 뜨므로 토스트가 떠 있는 동안은 감춘다 */
.scan-rat .cam-hint{top:auto;bottom:8px;padding:0;background:none;border-radius:0;color:#fff;text-shadow:0 1px 3px #000,0 0 10px rgba(0,0,0,.7);transition:opacity .2s}
body:has(#toast.show) .scan-rat .cam-hint{opacity:0}
/* 오른쪽 위 도구: 카메라 끄기·켜기 스위치 + 사용법 */
.cam-tools{position:absolute;top:0;right:0;z-index:3;display:flex;gap:6px}
.cam-tools .cam-help{position:static}
.cam-toggle{display:flex;align-items:center;gap:7px;min-height:34px;padding:0 10px;border:1px solid var(--line2);border-radius:var(--r);background:#000a;color:var(--muted);font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls)}
.cam-toggle.on{color:var(--text)}
.cam-sw{position:relative;width:30px;height:18px;border-radius:9px;background:#555;transition:background .2s}
.cam-sw::after{content:'';position:absolute;left:2px;top:2px;width:14px;height:14px;border-radius:50%;background:#ddd;transition:transform .2s}
.cam-toggle.on .cam-sw{background:var(--tal)}
.cam-toggle.on .cam-sw::after{transform:translateX(12px);background:#fff}
.scan-rat .cam-off{inset:auto;left:50%;top:var(--cy);transform:translate(-50%,-50%);width:min(100%,320px);border-radius:var(--r);background:rgba(0,0,0,.72);color:var(--text)}
.scan-rat .cam-off.paused{background:rgba(0,0,0,.72)}
.scan-rat .cam-off:not(.fail,.paused){background:none;text-shadow:0 1px 3px #000}
.scan-rat>.scan-wait{background:rgba(0,0,0,.6);color:var(--text)}
/* 아래 버튼 줄: 왼쪽 보조 [돌아가기](여정 지도로) · 오른쪽 주 [마을 탐험 마치기]. 마친 뒤에는 돌아가기만 한 줄 */
.scan-btns{display:flex;gap:10px;margin:12px 12px 0}
.scan-btns>:is(.primary,.secondary){margin:0}   /* .secondary+.primary 위 여백을 덮어쓴다 */
.scan-btns .secondary{flex:0 0 34%;padding:12px 8px}
.scan-btns .secondary:only-child{flex:1}
.scan-btns .primary{flex:1;padding:12px 14px}
.scan>.scan-wait{margin:12px 12px 0}
.scan-wait{margin:0;padding:10px 12px;border:1px dashed var(--line2);border-radius:var(--r);color:var(--muted);font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls)}
.scan-wait b{color:var(--tal)}
.found-lv{margin:-6px 0 16px}
.found-lv b{display:block;font:var(--t-subtitle);letter-spacing:var(--t-subtitle-ls);color:var(--tal)}
.found-lv span{font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--muted)}
.found-xp{margin:-12px 0 16px;font:var(--fw-solmoe) var(--fs-lg)/var(--sl-lh-lg) var(--font-solmoe);color:var(--tal)}
dialog.quiz-dlg{max-width:400px}
dialog.quiz-dlg .quiz-visual{height:150px}
dialog.quiz-dlg .quiz-visual.cut img{max-height:150px}   /* 상자가 없으니 그림이 칸 밖(질문 쪽)으로 넘치지 않게 칸 높이에 맞춘다 */
dialog.quiz-dlg .quiz-q{font-size:var(--fs-xl);line-height:var(--sl-lh-xl)}
.quiz-kicker{margin:0 0 12px;font:var(--fw-solmoe) var(--fs-sm)/var(--sl-lh-sm) var(--font-solmoe);letter-spacing:3px;color:var(--tal)}
dialog.found .found-lv{margin-top:-8px}

/* ---------- 윤회의 방: 방문별 편지 · 편지 벽 ---------- */
.prev-letters{margin-top:30px}
.prev-letters h3{font:var(--t-subtitle);letter-spacing:var(--t-subtitle-ls)}
.prev-letters .letter-read.compact{margin-top:10px}
.lr-date{margin:0 0 4px;padding-left:26px;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--ink2)}
.wall-note{margin:0 0 18px;padding-left:10px;border-left:3px solid var(--tal);font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls);color:var(--muted)}
/* 편지 벽: 출처 구분 없이 한 묶음 · 한 줄에 카드 3장 · 아래로 스크롤 (11.2 기획안 p18 카드형) */
.wall-sec{margin:0 -20px 26px;padding:16px 0 12px;background:var(--bg2);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.wall-h{display:flex;align-items:center;gap:10px;margin:0 20px 4px;font:var(--t-label);letter-spacing:var(--t-label-ls);color:var(--text);text-align:center}
.wall-h:before,.wall-h:after{content:'';flex:1;min-width:14px;height:0;border-top:1.5px solid var(--rule)}
.wall-h span{flex:0 1 auto}
.wall-count{margin:0 0 6px;text-align:center;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--dim)}
.wall-grid{padding:10px 0 6px}
/* 60장 묶음마다 화면 밖이면 그리기를 건너뛴다 (편지가 수천 통이어도 스크롤이 가볍게) */
.wall-chunk{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px 10px;align-items:start;padding:7px 20px;content-visibility:auto;contain-intrinsic-size:auto 2900px}
.wall-more{margin:6px 0 0;text-align:center;font:var(--t-caption);letter-spacing:var(--t-caption-ls);color:var(--dim)}
.note{position:relative;display:flex;flex-direction:column;width:100%;padding:12px 9px 8px;background:#f5ecd4;color:var(--ink);border:1px solid var(--rule);border-radius:var(--r);box-shadow:0 3px 0 #000;transform:rotate(var(--tilt,0deg));text-align:left;text-wrap:initial}
.note p{height:calc(4 * var(--lh-sm));margin:0;font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls);overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4;overflow-wrap:anywhere}
.note footer{margin-top:6px;padding-top:5px;border-top:1px solid #b9a26f80;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--ink2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.note:active{transform:rotate(var(--tilt,0deg)) translateY(2px);box-shadow:0 1px 0 #000}
.note.mine{background:var(--paper);border:2px solid var(--seal)}
.note-me{position:absolute;left:50%;top:-11px;translate:-50% 0;background:var(--paper);font-size:var(--fs-sm);line-height:var(--sl-lh-sm);padding:1px 6px;white-space:nowrap}
.note.mine p{margin-top:6px}
dialog.note-dlg .note-full{margin:0;padding:16px 14px;background:#f5ecd4;color:var(--ink);border:1px solid var(--rule);border-radius:var(--r);font:var(--t-body-lg);letter-spacing:var(--t-body-lg-ls);white-space:pre-wrap;overflow-wrap:anywhere}
dialog.note-dlg .note-by{margin:10px 0 16px;font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);color:var(--muted)}

/* 편지 거르기: 부치기 막힘 */
.letter-sheet.blocked{border-color:var(--seal);outline:2px solid var(--seal);animation:shake .35s}
.ls-warn{display:grid;gap:2px;margin:12px 0 0;padding:10px 12px;border:1.5px solid var(--seal);border-left-width:5px;border-radius:var(--r);background:#2a1310;font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls);color:var(--text)}
.ls-warn b{font:var(--t-label);letter-spacing:var(--t-label-ls);color:#f3b2a8}

/* 퀴즈: 장소 이름표 · 관련 에피소드(유튜브) */
.quiz-at{display:inline-block;margin:0 0 8px;padding:2px 10px;border:1.5px solid var(--rule);border-radius:var(--r);font:var(--fw-solmoe) var(--fs-sm)/var(--sl-lh-sm) var(--font-solmoe);color:var(--paper)}
.yt-link{gap:10px;margin-bottom:14px}
.yt-ico{width:24px;height:17px;flex:none;border-radius:2px;background:var(--seal);clip-path:none;position:relative}
.yt-ico:after{content:'';position:absolute;left:9px;top:4.5px;border-left:8px solid #fff;border-top:4px solid transparent;border-bottom:4px solid transparent}

/* 지옥문 결투: NFC 태그 · 환영 */
.duel-tag{display:flex;flex-direction:column;align-items:center;gap:14px;width:190px;margin:22px auto 6px;padding:18px 10px 16px;border-radius:var(--r);background:#3b2414;border:3px solid #b08a4a;box-shadow:inset 0 0 0 1px #000}
@media (max-width:374px){.wall-sec{margin-left:-16px;margin-right:-16px}.wall-h{margin:0 16px 4px}.wall-chunk{padding:7px 16px;gap:14px 8px}}

/* 결투: 경고 중 공격 막힘 (11.11부터 모든 프리셋. 터치는 경고 중 탭을 공격으로 보내지 않아 PC 스페이스·서버 판정에서만 나온다) */
.pop-block{color:var(--muted)}
.game.fx-block:after{animation:fxFlash .35s;background:#0000008c}
.game.fx-block .signal{animation:shake .25s}

/* ---------- 하단 메뉴 ---------- */
.nav{position:relative;height:calc(var(--nav-h) + var(--safe-b));padding-bottom:var(--safe-b);display:flex;background:var(--bg);border-top:1px solid var(--line2);z-index:20}
.nav button{flex:1;border:0;background:none;color:var(--dim);font:var(--t-button-sm);letter-spacing:var(--t-button-sm-ls);min-height:0;border-top:3px solid transparent}
.nav button.active{color:var(--tal);border-top-color:var(--tal)}

/* ---------- 토스트·다이얼로그 ---------- */
#toast{white-space:pre-line;width:max-content;position:fixed;bottom:calc(var(--nav-h) + 20px + var(--safe-b));left:50%;transform:translateX(calc(-50% - 1.5px));background:url('assets/ui/hanji-age.webp') 0 0/100% 100% no-repeat,url('assets/ui/hanji-paper.webp') 50% 50%/cover,var(--paper);color:var(--ink);padding:11px 16px;max-width:min(88vw,380px);font:var(--t-body-sm-strong);letter-spacing:var(--t-body-sm-strong-ls);border:2px solid var(--ink);border-radius:var(--r);box-shadow:3px 3px 0 #000;z-index:70;opacity:0;pointer-events:none;transition:opacity .2s;text-align:center}
#toast.show{opacity:1}

/* ---------- 전역 로딩 (화면 전환 사이 대기, app.js loading()) ----------
   진입 대기 화면과 같은 말투: 얇은 진행 바 + 대기 문구. 가운데 유령 빵빵이가 둥실거린다 */
#loader{position:fixed;inset:0;z-index:80;isolation:isolate;display:grid;place-items:center;padding:24px 32px calc(24px + var(--safe-b));background:var(--bg);animation:ldIn .2s ease-out both}
/* 11.12 톤앤매너: 빈 단색 대신 어두운 바탕에 한지 결만 옅게 비친다(장식은 더하지 않는다) */
#loader::before{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;background:url('assets/ui/hanji-paper.webp') 50% 50%/cover;mix-blend-mode:soft-light;opacity:.4}
#loader[hidden]{display:none}
#loader.out{opacity:0;transition:opacity .25s ease-out}
.ld-box{width:min(100%,264px);text-align:center}
.ld-art{display:block;width:104px;height:auto;margin:0 auto 22px;animation:ldFloat 1.4s ease-in-out infinite alternate}
.ld-text{margin:0 0 14px;min-height:1.4em;font:var(--t-subtitle);letter-spacing:var(--t-subtitle-ls);color:var(--text)}
/* 진행 표시: 버튼과 같은 찢긴 한지 띠(hanji-edge-wide 마스크). 바탕 = 먹물 든 한지, 차오르는 쪽 = 금빛 부적 한지 */
.ld-bar{position:relative;height:18px;
  background:url('assets/ui/design-1111/paper-hanji.webp') 50% 50%/cover,#3a3a30;background-blend-mode:multiply;
  -webkit-mask:url('assets/ui/hanji-edge-wide.webp') 0 0/100% 100% no-repeat;mask:url('assets/ui/hanji-edge-wide.webp') 0 0/100% 100% no-repeat}
.ld-bar b{position:absolute;inset:0;display:block;background:url('assets/ui/design-1111/paper-hanji.webp') 50% 50%/cover,var(--tal);background-blend-mode:multiply;clip-path:inset(0 100% 0 0);animation:ldBar linear forwards}
.ld-note{margin:14px 0 0;font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls);color:var(--dim)}
@keyframes ldIn{from{opacity:0}}
@keyframes ldFloat{from{transform:translateY(4px)}to{transform:translateY(-6px)}}
@keyframes ldBar{to{clip-path:inset(0 0 0 0)}}
@media (min-width:901px){ #loader{border:1px solid var(--line);border-radius:var(--r)} }
dialog{border:1px solid var(--line2);background:var(--bg2);color:var(--text);padding:22px 18px 18px;max-width:380px;width:calc(100% - 32px);border-radius:var(--r);max-height:86dvh;overflow:auto}
dialog.wide{max-width:420px}
dialog::backdrop{background:#000c}
dialog h3{font:var(--t-subtitle);letter-spacing:var(--t-subtitle-ls)}
.dlg-body{font:var(--t-body);letter-spacing:var(--t-body-ls);color:var(--muted);margin-bottom:16px}
.dlg-body p{margin:0 0 8px}
.dlg-body b{color:var(--text)}
dialog .primary+.secondary{margin-top:10px}
.jump-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-bottom:10px}
.jump{min-height:48px;border-radius:var(--r);border:1px solid var(--line2);background:none;font-weight:700;font-size:14px}

/* ---------- 반응형 ---------- */
@media (max-width:900px){
  .plan,.desktop-art{display:none}
  .phone{margin:0 auto;border:0;width:100%;max-width:480px}
  /* 창은 스크롤·당겨서 새로고침·고무줄 튕김 없이 고정. 스크롤은 본문(.scr-body) 안에서만 */
  html,body{height:100%;overflow:hidden;overscroll-behavior:none}
}
@media (max-width:374px){
  .phone{--ctop:calc(20px + env(safe-area-inset-top,0px))}
  .content{padding:var(--ctop) 16px calc(24px + var(--end))}
  .scr-head,.scr-foot{padding-left:16px;padding-right:16px}
}
@media (max-height:700px){
  .cam,.scan-rat .cam{min-height:240px}
  .g-art{height:200px;margin-bottom:16px}
  .sig-stage{min-height:96px}.signal{min-height:0}#warning{font-size:var(--fs-xl);line-height:var(--sl-lh-xl)}
  .landing-kv{height:52dvh;min-height:290px}
  .signal>b{font-size:46px}
}
@media (prefers-reduced-motion:reduce){
  *,*:before,*:after{animation:none!important;transition:none!important;scroll-behavior:auto!important}
  #levelup.show{opacity:1}
  .fx-layer>span.go{opacity:1;transform:translateY(-70px)}
  .game.fx-on:after{opacity:.85}   /* 판정 색: 깜빡이지 않고 JUDGE_MS 동안만 멈춰 보여 준다 (app.js effect) */
  .game.fx-power .sig-glow{background:radial-gradient(closest-side,#f1cc4588,transparent)}
  .game.fx-dodge .sig-glow{background:radial-gradient(closest-side,#f1ead866,transparent)}
  .game.fx-hurt .sig-glow{background:radial-gradient(closest-side,#c8372bcc,transparent)}
  .game.warn .sig-glow{background:radial-gradient(closest-side,#c8372b99,transparent)}
  .ms-wait{opacity:0}.ms-done{opacity:1}
  .crack.go{opacity:1}
}

/* ---------- PC: 휴대폰 시안 높이를 화면에 맞춘다 (틀·안쪽 스크롤은 휴대폰과 같은 규칙) ---------- */
@media (min-width:901px){
  .phone{--ph:min(calc(100vh - 64px), 932px)}
  /* 기획 패널이 있는 화면: 패널 오른쪽 남은 공간 가운데 · 없는 화면: 패널을 닫고 화면 가운데 */
  .phone{margin-right:max(3vw, 50vw - 465px)}
  body.no-plan .plan{bottom:auto;width:auto;padding:0;overflow:hidden}
  body.no-plan .pl-demo{position:static;margin:0;padding:14px 14px 14px 20px}
  body.no-plan .pl-scr{margin:0;border:0;border-radius:0;padding:12px 14px 14px 20px}
}

/* ---------- 현장 서버 연결 (net.js, 서버 모드에서만 그려짐) ---------- */
.net-off{position:fixed;left:50%;top:calc(12px + env(safe-area-inset-top,0px));transform:translateX(-50%);z-index:80;width:min(390px,calc(100vw - 32px));display:flex;flex-direction:column;gap:10px;padding:14px 16px;background:#fbf6ea;color:#1a150d;border:2px solid #000;border-radius:var(--r);box-shadow:3px 3px 0 #000;text-align:center}
.net-off p{margin:0;font:var(--t-body-strong);letter-spacing:var(--t-body-strong-ls)}
.net-off .primary{min-height:46px;font:var(--t-button-sm);letter-spacing:var(--t-button-sm-ls)}
.net-lobby{position:absolute;inset:0;z-index:5;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;padding:16px 14px;background:#0b0d0c;border:1px solid var(--line2);border-radius:var(--r);text-align:center}
.net-lobby[hidden]{display:none}
.net-lobby b{font:var(--t-subtitle);letter-spacing:var(--t-subtitle-ls);color:var(--text)}
.net-lobby span{color:var(--muted);font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls)}
.net-lobby i{font-style:normal;font-weight:900;color:var(--tal)}
.judge-call{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:center;gap:4px 12px;margin:0 0 14px;padding:10px 12px;border:1px solid var(--line2);border-radius:var(--r);background:var(--bg2)}
.judge-call b{font:var(--t-title);letter-spacing:var(--t-title-ls);color:var(--tal)}
.judge-call span{color:var(--muted)}
.judge-call i{font-style:normal;font-weight:900;color:var(--text)}
.judge-code{margin:14px 0}
.judge-code label{display:block;margin:0 0 8px;color:var(--muted);font:var(--t-body-sm);letter-spacing:var(--t-body-sm-ls)}
.jc-row{display:flex;gap:8px}
.jc-row input{flex:1;min-width:0;min-height:52px;padding:0 14px;border:1px solid var(--rule);border-radius:var(--r);background:var(--paper);color:var(--ink);font:var(--fw-extrabold) var(--fs-2xl)/var(--lh-2xl) var(--font-sans);letter-spacing:.3em;text-align:center}
.jc-row .primary{width:auto;flex:0 0 auto;padding:12px 26px}

/* ---------- 11.11 디자이너 에셋 ----------
   한지: 종이 카드의 바탕 질감을 새 한지(11.12 hanji-paper)로 (색은 var(--paper) 그대로 아래에 깔림). 되돌리려면 이 블록의 첫 규칙만 지운다 */
.paper,.slip,.id-strip,.dex-cell.found,.quiz-visual.clue{background-image:url('assets/ui/hanji-paper.webp');background-size:cover;background-position:50% 50%}
/* 붓글씨 현판 버튼: 글자가 그림에 들어 있어 그림 그대로 누른다 (저승 입장 · 지옥문 입장하기) */
.img-btn{display:block;width:100%;padding:0;border:0;background:none;line-height:0;filter:drop-shadow(0 4px 0 #000)}
.img-btn img{display:block;width:100%;height:auto;pointer-events:none}
.img-btn:active{transform:translateY(3px);filter:drop-shadow(0 1px 0 #000)}

/* ---------- 윤회의 방 · 전화 (11.11) ---------- */
.call-guide,.call-head{text-align:center}
.call-head .call-label{margin:6px 0 16px}
.call-guide-picture{margin:16px auto 24px;color:#c8b887}
.call-guide-ghost{display:block;width:130px;height:150px;object-fit:contain;margin:0 auto 16px}
.call-guide-picture svg{display:block;width:260px;max-width:100%;height:auto;margin:auto}
.call-guide-instruction{margin:22px 0 12px;font-size:18px;font-weight:700;line-height:1.65;color:var(--text);word-break:keep-all}
.call-guide-next{margin:0;color:var(--muted);font-size:14px;line-height:1.7;word-break:keep-all}
.call-guide-skip{margin:28px 0 8px;color:var(--muted);font-size:13px}
.call-guide-skip p{margin:0}
.call-guide-skip .textbtn{min-height:44px;font-size:14px}
.booth-call{overflow-y:auto;overscroll-behavior:contain;box-sizing:border-box;display:flex;flex-direction:column;align-items:center;padding:calc(40px + env(safe-area-inset-top,0px)) 24px calc(36px + env(safe-area-inset-bottom,0px));background:#101715;color:#f8f4e8;text-align:center}
.call-label{margin:0;color:#b9c4bd;font-size:13px;letter-spacing:.16em}
.call-ghost{width:174px;height:200px;object-fit:contain;margin:38px 0 22px;animation:call-float 2.4s ease-in-out infinite}
.booth-call h2{font-size:28px;line-height:1.3;letter-spacing:-.04em;margin:0 0 12px;word-break:keep-all}
.call-message{margin:0;max-width:310px;font-size:16px;line-height:1.65;word-break:keep-all;color:#dddcd2}
.call-time{font-size:20px;font-variant-numeric:tabular-nums;margin:26px 0 8px;color:#f8f4e8}
.call-hell{font-size:13px;color:#a5b2aa;margin:0 0 20px;min-height:20px}
.call-controls{margin-top:auto;padding-top:30px;width:100%;display:flex;flex-direction:column;align-items:center;gap:16px}
.call-button{display:flex;flex-direction:column;align-items:center;justify-content:center;width:88px;height:88px;border:0;border-radius:50%;gap:5px;color:white;font-size:15px;font-weight:750;cursor:pointer;box-shadow:0 0 0 8px #ffffff08}
.call-button svg{width:28px;height:28px;fill:currentColor}
.call-button.answer{background:#287d4d}
.call-button.hangup{background:#bb3c39}
.call-button.hangup svg{transform:rotate(135deg)}
.call-button:disabled{opacity:.45;cursor:wait}
.call-decline{min-height:44px;min-width:88px;color:#c9c7bd}
.call-audio{margin-top:12px;min-height:44px}
/* 11.12 수화기로 받기: 소리가 휴대폰이 아니라 수화기에서 나온다는 안내 */
.is-handset .call-ghost{width:136px;height:156px;margin:26px 0 16px}
.call-handset{margin:20px 0 0;padding:14px 18px;display:flex;align-items:center;gap:14px;border:1px solid #ffffff2b;border-radius:14px;background:#ffffff0d;text-align:left}
.call-handset svg{flex:none;width:58px;height:36px;color:#e9d9a6}
.call-handset p{margin:0;font-size:16px;font-weight:700;line-height:1.5;color:#f8f4e8;word-break:keep-all}
.is-handset .call-time{margin-top:16px;font-size:16px;color:#c9c7bd}
.call-button.wide{flex-direction:row;width:auto;min-width:220px;height:68px;padding:0 30px;border-radius:34px;gap:10px;font-size:18px}
.call-button.wide:not(:disabled){animation:call-pulse 1.6s ease-in-out infinite}
@keyframes call-pulse{0%,100%{box-shadow:0 0 0 8px #287d4d22}50%{box-shadow:0 0 0 16px #287d4d00}}
.is-talking .call-ghost,.is-ended .call-ghost{animation:none}
.is-ended .call-ghost{opacity:.65}
.phone-rebirth{position:relative;background:#13191d}
#rebirthScene{height:100%}
.rebirth-static{min-height:100%;padding:90px 24px 250px;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;background:#f8f5ec;color:#202722;box-sizing:border-box}
.rebirth-static .face{width:160px;height:160px;margin-bottom:35px}
.rebirth-static p{font-size:15px}
.rebirth-static h2{font-size:27px;line-height:1.45}
.rebirth-actions{position:absolute;z-index:5;bottom:calc(28px + env(safe-area-inset-bottom,0px));left:24px;right:24px;margin:0}
.rebirth-actions[hidden]{display:none}
@keyframes call-float{0%,100%{transform:translateY(0)}50%{transform:translateY(-8px)}}
@media (max-height:720px){.call-ghost{width:140px;height:150px;margin:18px 0}.booth-call{padding-top:24px}.call-controls{padding-top:18px}}
@media (max-height:720px){.is-handset .call-ghost{width:112px;height:124px;margin:14px 0 10px}.call-handset{margin-top:14px}}
@media (prefers-reduced-motion:reduce){.call-ghost,.call-button.wide{animation:none}}

/* ---------- 11.12 화면 = 한지 한 장 (사용자 요청: 등록부처럼 바깥 먹빛 여백 없이 한지가 화면을 꽉 채운다) ----------
   휴대폰 틀(.phone) 바탕 자체를 한지(종이 카드와 같은 hanji-paper)로 깐다 → .content 안쪽 여백이 곧 한지의 여백이고, 제목·버튼은 모두 한지 위.
   붙는 화면은 app.js HANJI_ROUTES. 몰입 화면(입장·로그인·지도·쥐 카메라·거울 닦기·판결문·결투·결과·전화·승천·편지 벽)은 그림이 화면을 채우므로 넣지 않는다.
   먹빛 바탕에 맞춘 밝은 글자 토큰(--text·--muted·--dim·--line)은 본문 안에서만 먹색으로 바꾼다(하단 메뉴 .nav는 먹빛 그대로).
   금빛(--tal) 글자는 한지 위에서 안 보여 인주색으로, 그림 칸(업경대 줄)은 먹빛 그대로 둔다 */
.phone.hanji{background:url('assets/ui/hanji-paper.webp') 50% 0/100% auto repeat-y,var(--paper)}
.phone.hanji>:is(.content,.pv-page,.scr-head,.scr-foot){color:var(--ink);--text:var(--ink);--muted:var(--ink2);--dim:#7a6b52;--line:rgba(35,29,20,.25);--line2:rgba(35,29,20,.45);--bg2:rgba(255,250,236,.4);--bg3:rgba(255,250,236,.6)}
.phone.hanji :is(.mq-n,.gate-rules b,.gate-left b,.judge-call b,.net-lobby i,.ms-done b,.found-k,.pv-draft){color:var(--seal)}
.phone.hanji .ms-ico{color:var(--ink)}
.phone.hanji .mq{background:#161b18}   /* 업경대 앞 줄 = 먹빛 그림 칸 그대로(안의 금빛 글자가 살도록) */
.phone.hanji .call-guide-picture{color:var(--ink2)}
.phone.hanji .call-label{color:var(--ink2)}
.phone.hanji :is(.pv-page,.pv-bar){background:none}
.phone.hanji .pv-bar{border-bottom-color:rgba(35,29,20,.45)}
/* 11.12 판관의 심판 · 내 차례(mirror-reveal)만 먹빛 한지: 같은 hanji-paper 결을 뒤집어 어둡게 깐 판(::before) 위에 글자는 다시 밝은 토큰으로.
   한지 버튼(.primary·.secondary)은 그대로 금빛·누런 한지 */
.phone.hanji.route-mirror-reveal{isolation:isolate;background:#14110d}
.phone.hanji.route-mirror-reveal::before{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:url('assets/ui/hanji-paper.webp') 50% 0/100% auto repeat-y;filter:invert(1) grayscale(1) sepia(.25) brightness(.5)}
.phone.hanji.route-mirror-reveal>:is(.content,.scr-head,.scr-foot){color:var(--text);--text:#f1ead8;--muted:#cfc8b4;--dim:#a39e8c;--line:#f1ead833;--line2:#f1ead866;--bg2:#ffffff0d;--bg3:#ffffff17}
.phone.hanji.route-mirror-reveal :is(.judge-call b,.ms-done b){color:var(--tal)}
.phone.hanji.route-mirror-reveal .ms-ico{color:var(--tal)}
.tag-tip{margin:0 0 14px;text-align:center;word-break:keep-all}   /* 내 차례: QR 안내 한 줄은 [카메라로 QR 찍기] 바로 위 가운데 */
