/* ── 글씨체를 안에 담습니다 (v2.41) ──────────────
   여섯 벌을 구글에서 받아오고 있었습니다. 인터넷이 없으면 4초 기다리다
   시스템 글씨로 떨어지는데, 그러면 **게임 전체의 결이 바뀝니다** —
   제목의 명조도, 쪽지의 손글씨도, 숫자의 고정폭도 다 사라집니다.
   앱으로 내려면 오프라인에서 같은 얼굴이어야 합니다.

   파일이 `assets/fonts/` 에 있으면 그것을 쓰고, 없으면 여태처럼
   구글에서 받아옵니다(`<head>` 의 링크가 그대로 살아 있습니다).
   `local()` 을 앞에 두어 기기에 이미 있으면 내려받지도 않습니다.

   `swap` 은 그대로 둡니다 — 안 두면 글씨가 올 때까지 **글자가 아예
   안 보입니다.** 첫 문에서 `document.fonts.ready` 를 기다리므로(v2.37)
   사람 눈에는 바뀌는 순간이 안 보입니다.

   담아야 할 파일(woff2) — 없으면 이 블록은 조용히 지나갑니다:
     GowunBatang-Regular · GowunBatang-Bold
     GowunDodum-Regular · Gaegu-Bold
     NanumMyeongjo-Regular · NanumBrushScript-Regular
     IBMPlexSansKR-Regular · IBMPlexSansKR-Medium · IBMPlexSansKR-SemiBold
     IBMPlexMono-Regular · IBMPlexMono-SemiBold                        */
@font-face{font-family:'Gowun Batang';font-style:normal;font-weight:400;font-display:swap;
  src:local('Gowun Batang'),url('assets/fonts/GowunBatang-Regular.woff2') format('woff2')}
@font-face{font-family:'Gowun Batang';font-style:normal;font-weight:700;font-display:swap;
  src:local('Gowun Batang Bold'),url('assets/fonts/GowunBatang-Bold.woff2') format('woff2')}
@font-face{font-family:'Gowun Dodum';font-style:normal;font-weight:400;font-display:swap;
  src:local('Gowun Dodum'),url('assets/fonts/GowunDodum-Regular.woff2') format('woff2')}
@font-face{font-family:'Gaegu';font-style:normal;font-weight:700;font-display:swap;
  src:local('Gaegu Bold'),url('assets/fonts/Gaegu-Bold.woff2') format('woff2')}
@font-face{font-family:'Nanum Myeongjo';font-style:normal;font-weight:400;font-display:swap;
  src:local('NanumMyeongjo'),url('assets/fonts/NanumMyeongjo-Regular.woff2') format('woff2')}
@font-face{font-family:'Nanum Brush Script';font-style:normal;font-weight:400;font-display:swap;
  src:local('Nanum Brush Script'),url('assets/fonts/NanumBrushScript-Regular.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Sans KR';font-style:normal;font-weight:400;font-display:swap;
  src:local('IBM Plex Sans KR'),url('assets/fonts/IBMPlexSansKR-Regular.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Sans KR';font-style:normal;font-weight:600;font-display:swap;
  src:local('IBM Plex Sans KR SemiBold'),url('assets/fonts/IBMPlexSansKR-SemiBold.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;
  src:local('IBM Plex Mono'),url('assets/fonts/IBMPlexMono-Regular.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:600;font-display:swap;
  src:local('IBM Plex Mono SemiBold'),url('assets/fonts/IBMPlexMono-SemiBold.woff2') format('woff2')}


/* 노치와 홈 막대 자리까지 그림이 닿게 합니다.
   inset:0 만으로는 브라우저 표시줄이 접히고 펴질 때 아래가 종이색으로 비칩니다.
   dvh 로 실제 보이는 높이를 쓰고, 그림은 사방으로 1px 씩 더 물립니다. */
.title-screen{position:fixed;left:0;right:0;top:0;bottom:0;height:100dvh;min-height:100vh;
  z-index:200;display:grid;place-items:center;
  background:#0B1418;transition:opacity .45s ease}
/* 제목이 떠 있는 동안에는 문서 바탕도 어둡게 — 어디가 비어도 종이색이 새지 않게 */
/* body.paper 가 뒤에 오면서 같은 특이도로 이겨, 제목 아래에 종이색이 비쳤습니다.
   종이 테마일 때도 제목 동안에는 어둡게 둡니다. */
html.titleon,body.titleon{background:#0B1418}
body.paper.titleon{background:#0B1418}
.title-screen.gone{opacity:0;pointer-events:none}
/* ── 첫 문 (v2.31) ─────────────────────────────
   타이틀 그림도 아직 안 왔을 때 뜨는 자리라 **그림을 안 씁니다** —
   빛깔과 글자만으로 세웁니다. 안 그러면 로딩 화면이 로딩을 기다립니다. */
.load-screen{position:fixed;inset:0;z-index:900;display:flex;
  align-items:center;justify-content:center;background:#0B1418;
  transition:opacity .45s ease}
.load-screen.gone{opacity:0;pointer-events:none}
.load-screen .lin{text-align:center;padding:0 28px;width:min(320px,78vw)}
.load-screen .lname{font-family:'Gowun Batang',serif;font-size:20px;
  letter-spacing:.22em;color:#E8DCC0}
.load-screen .lbar{margin:18px 0 10px;height:3px;border-radius:2px;
  background:rgba(232,220,192,.16);overflow:hidden}
.load-screen .lbar i{display:block;height:100%;width:0;border-radius:2px;
  background:linear-gradient(90deg,#9A7A2E,#E8DCC0);transition:width .25s ease}
.load-screen .lsub{font-size:11px;letter-spacing:.06em;color:#7E8C90;
  /* 무엇을 받는 중인지 글이 바뀌므로 자리를 잡아 둡니다 —
     안 그러면 줄 높이가 오르내려 막대가 들썩입니다(v2.37). */
  min-height:15px}
.title-screen .tbg{position:absolute;inset:-1px;background-size:cover;background-position:center;
  image-rendering:pixelated;filter:saturate(.9)}
.title-screen .tveil{position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(11,20,24,.35) 0%,rgba(11,20,24,.55) 45%,rgba(11,20,24,.94) 100%)}
.title-screen .tin{position:relative;text-align:center;padding:0 24px}
.title-screen h1{font-family:'Gowun Batang','Nanum Myeongjo',serif;font-weight:700;
  font-size:46px;letter-spacing:.14em;margin:0 0 10px;color:#F0EDE4;
  text-shadow:0 2px 0 rgba(0,0,0,.55), 0 6px 26px rgba(0,0,0,.75)}
.title-screen p.tlead{line-height:1.75}
.title-screen p.tlead span{display:block;margin-top:6px;opacity:.86;font-size:.94em}
.title-screen p{margin:0 0 20px;color:#A9B8BB;font-size:13.5px;letter-spacing:.08em;
  font-family:'Gowun Dodum',sans-serif}
.title-screen .tstart{font:inherit;font-size:15px;padding:7px 0;line-height:1.15;
  width:236px;box-sizing:border-box;display:block;margin:0 auto;text-align:center;
  border:10px solid transparent;border-radius:0;
  border-image:var(--btnbig,url('assets/btn_gold.png')) 14 fill stretch;
  background:transparent;color:#F2E7C4;cursor:pointer;
  font-family:'Gowun Dodum',sans-serif;letter-spacing:.14em;
  text-shadow:0 1px 2px rgba(0,0,0,.7)}
.title-screen .tstart:active{background:rgba(201,164,76,.26)}
/* 어디를 눌러야 할지 눈이 먼저 가게. 깜박이 아니라 숨쉬기입니다 —
   확 꺼졌다 켜지면 오류처럼 보입니다. 4초에 한 번 천천히 밝아졌다 잦아듭니다.
   단추마다 조금씩 늦춰 셋이 한꺼번에 뛰지 않게 합니다. */
@keyframes tpulse{
  0%,100%{opacity:.80;filter:brightness(.94)}
  50%    {opacity:1;  filter:brightness(1.14)}}
.title-screen .tstart,
.title-screen .trow .tbtn{animation:tpulse 4s ease-in-out infinite}
.title-screen .trow .tbtn{animation-delay:.9s}
.title-screen .trow .tbtn.tclose{animation-delay:1.8s}
@media (prefers-reduced-motion:reduce){
  .title-screen .tstart,.title-screen .trow .tbtn{animation:none}}
.title-screen .tsub{display:block;margin-top:10px;font-size:12px;color:#6E8288}
/* 전투 기록 */
.flog{margin-top:9px;border-top:1px solid rgba(255,255,255,.09);padding-top:7px}
.flog .fhead{font-size:10.5px;color:#8B9BA0;letter-spacing:.04em;margin-bottom:5px}
.flog .fl{font-size:11.5px;line-height:1.55;color:#B9C6C9;
  font-family:'Gowun Dodum',sans-serif}
.flog .fl b{color:#E8C877;font-weight:400}
.flog .fl i{color:#8B9BA0;font-style:normal;font-size:10.5px}
.flog .fl:last-child{color:#DCE7E9}
.flog.fmini{margin-top:6px;padding-top:6px;min-height:52px}
.flog.fmini .fl{font-size:10.5px;line-height:1.5}
/* 타일 부채꼴 */
.fan{position:absolute;inset:0;z-index:40}
.fan .fdot{position:absolute;width:12px;height:12px;margin:-6px 0 0 -6px;border-radius:50%;
  background:rgba(201,164,76,.85);box-shadow:0 0 0 5px rgba(201,164,76,.16)}
.fan .fname{position:absolute;transform:translate(-50%,0);white-space:nowrap;
  font-size:11px;color:#DCE7E9;text-shadow:0 1px 3px #000;pointer-events:none}
.fan .fbtn{position:absolute;transform:translate(-50%,-50%) scale(.4);opacity:0;
  display:flex;flex-direction:column;align-items:center;gap:1px;
  width:58px;padding:7px 2px 5px;border-radius:12px;cursor:pointer;
  background:rgba(16,26,31,.96);border:1px solid rgba(201,164,76,.42);
  color:#E8DCC0;font:inherit;font-size:10.5px;line-height:1;
  box-shadow:0 3px 12px rgba(0,0,0,.55);
  animation:fanin .17s cubic-bezier(.2,1.5,.4,1) forwards}
@keyframes fanin{to{opacity:1;transform:translate(-50%,-50%) scale(1)}}
.fan .fbtn:active{background:rgba(201,164,76,.28)}
.fan .fbtn .fi{line-height:0}
/* 지도 위 전투 띠 — 한 줄, 누르면 큰 창 */
.fight .fbox{display:flex;align-items:center;gap:8px;padding:6px 10px;cursor:pointer}
.fight .fmini2{line-height:0;flex:none}
.fight .fmini2.elite{filter:drop-shadow(0 0 5px var(--danger))}
.fight .fnm{font-size:11.5px;color:#DCE7E9;white-space:nowrap;max-width:96px;
  overflow:hidden;text-overflow:ellipsis}
.fight .fnm .elt{color:var(--danger);font-weight:400}
.fight .fbars{flex:1;display:flex;flex-direction:column;gap:3px;min-width:70px}
.fight .fbars .fhp{display:block;height:4px;border-radius:2px;background:rgba(255,255,255,.10)}
.fight .fbars .fhp i{display:block;height:100%;border-radius:2px;background:var(--jade)}
.fight .fbars .fhp.m i{background:var(--danger)}
.fight .fcnt2{font-family:'IBM Plex Mono',monospace;font-size:10.5px;color:#8B9BA0;flex:none}
.fbig{margin:8px 0 4px}
.fbig .fnum{font-family:'IBM Plex Mono',monospace;font-size:10.5px;color:#8B9BA0;margin-top:3px}
.strow .gw{font-family:'IBM Plex Mono',monospace;font-size:10px;color:#5F7078;
  min-width:34px;text-align:right}
.strow .gw.on{color:var(--brass)}
/* 연대기 — 숫자 없이 문장만 */
.chron{border-left:2px solid rgba(201,164,76,.35);padding-left:10px;margin:2px 0 4px}
.chron .cr{display:flex;gap:8px;padding:3px 0;font-size:11.5px;line-height:1.5}
.chron .cd{font-family:'IBM Plex Mono',monospace;font-size:10px;color:#5F7078;
  flex:none;padding-top:1px;min-width:52px}
.chron .cx{color:#C7D3D6;font-family:'Gowun Dodum',sans-serif}
.chron .cr:first-child .cx{color:#E8DCC0}
/* 의뢰 게시판 — 판자에 붙은 벽보 */
/* 판자는 볕에 바랜 참나무입니다. 예전 검은 판자는 종이 창에 구멍이 뚫린 듯 보였습니다. */
.board{position:relative;border-radius:8px;padding:26px 22px;margin:4px 0 2px;
  background:#C9B48C;
  box-shadow:inset 0 1px 6px rgba(90,70,40,.35);overflow:hidden}
/* 어둠을 얇게만 남깁니다 — 쪽지가 떠 보일 만큼만 */
.board::after{content:'';position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 90% at 50% 0%,rgba(60,44,24,0),rgba(60,44,24,.16));
  border-radius:8px}
.board .notes{position:relative;z-index:1}
.notes{display:grid;grid-template-columns:1fr 1fr;gap:10px}
/* 바탕색을 깔면 찢긴 가장자리의 투명한 자리까지 메워져 종이가 네모로 보입니다.
   색은 그림이 없을 때만 씁니다. 여백은 백분율로 주어, 종이가 커지든 작아지든
   글자가 찢긴 테두리를 밟지 않습니다. */
.note{position:relative;border-radius:2px;cursor:pointer;
  color:#3A2E1C;
  aspect-ratio:192/240;                       /* 종이 비율을 지킵니다 */
  padding:11% 12% 9%;
  display:flex;flex-direction:column;
  filter:drop-shadow(0 3px 6px rgba(0,0,0,.5));transform:rotate(-.6deg)}
/* 홀수로 남은 마지막 한 장은 가운데로 — 왼쪽에 붙으면 오른쪽이 텅 빕니다 */
.notes .note:last-child:nth-child(odd){grid-column:1 / -1;justify-self:center;width:calc(50% - 5px)}
.notes .note:nth-child(2n){transform:rotate(.7deg)}
.note:active{transform:scale(.98)}
.note::before{content:'';position:absolute;left:50%;top:-5px;width:9px;height:9px;
  margin-left:-4px;border-radius:50%;background:#6B5B45;
  box-shadow:0 1px 2px rgba(0,0,0,.6)}
.note .nic{line-height:0;margin-bottom:7px}
.note .nt{font-family:'Gaegu','Nanum Brush Script',cursive;font-weight:700;
  font-size:15px;line-height:1.35;color:#2E2414;flex:1;
  /* 긴 의뢰 이름이 종이 밖으로 나가지 않게 세 줄에서 자릅니다 */
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
  overflow:hidden;word-break:keep-all;overflow-wrap:anywhere}
.note .nb{height:4px;border-radius:2px;background:rgba(58,46,28,.22);margin:0 0 5px}
.note .nb i{display:block;height:100%;border-radius:2px;background:#7A6034}
.note .nm{font-family:'Gaegu',cursive;font-weight:700;font-size:12px;color:#5A4A32;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.note .ng{font-family:'Gaegu',cursive;font-weight:700;font-size:12.5px;color:#8A4A16;
  margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.note.done{opacity:.5}
.note .nstamp{position:absolute;right:7px;top:7px;font-size:11px;padding:1px 6px;
  font-family:'Gaegu',cursive;font-weight:700;white-space:nowrap;
  border:1.5px solid rgba(138,42,30,.7);color:#8A2A1E;border-radius:3px;transform:rotate(6deg)}
.note .nstamp.ok{border-color:rgba(60,110,60,.7);color:#3C6E3C}
.peek{border-radius:2px;padding:30px 28px;margin:8px auto 0;
  aspect-ratio:192/240;max-width:280px;
  display:flex;flex-direction:column;justify-content:center;
  background-color:#DED2B4;color:#3A2E1C;background-repeat:no-repeat;
  filter:drop-shadow(0 4px 10px rgba(0,0,0,.5))}
.peek .pt{font-family:'Gaegu','Nanum Brush Script',cursive;font-weight:700;
  font-size:21px;line-height:1.4;color:#2E2414;word-break:keep-all;overflow-wrap:anywhere}
.peek .pm{font-family:'Gaegu',cursive;font-weight:700;font-size:15px;color:#5A4A32;margin-top:8px}
.peek .pg{font-family:'Gaegu',cursive;font-weight:700;font-size:16px;color:#8A4A16;margin-top:8px}
/* 대화 — 왼쪽 용사, 오른쪽 상대 */
.npcart{display:inline-block;background-repeat:no-repeat;image-rendering:pixelated;
  vertical-align:bottom}
/* 목록에서는 얼굴 언저리만 보이게 잘라 냅니다 */
.npcrow>.npcart{height:34px!important;background-position-y:0!important;
  object-fit:cover;border-radius:4px}
.pixel-off .npcart{image-rendering:auto}
.talk{position:relative;display:flex;align-items:flex-end;justify-content:space-between;
  gap:6px;margin:6px 0 0;padding:6px 4px 0;min-height:0;
  border-radius:12px 12px 0 0;overflow:hidden;
  background:linear-gradient(180deg,rgba(30,48,54,.55),rgba(16,26,31,0))}
/* flex 가 한쪽을 눌러 용사 그림이 반쯤 잘려 나갔습니다.
   두 쪽 다 제 너비를 지키게 둡니다 — 좁으면 넘치는 것이 낫습니다. */
.talk .side{text-align:center;max-width:48%;min-width:0;flex:0 0 auto}
.talk .side .npcart.ph{display:grid;place-items:center;background:var(--plate);
  border:1px solid var(--line);border-radius:8px}
/* 자리표는 사람이 아니므로 뒤집지 않습니다 */
.talk .side.me .npcart.ph{transform:none}
/* 이름표를 그림 위로 끌어올리던 -6px 이 글자를 다리에 겹치게 했습니다 */
/* 초상은 이미 오른쪽을 보고 그려졌습니다 — 뒤집지 않습니다.
   옛 픽셀 몸만 정면이라 뒤집어 씁니다. */
.talk .side.me .npcart{transform:scaleX(-1)}
.talk .side.me .npcart.face{transform:none}   /* 용사는 상대를 바라봅니다 */
.talk .side .npcart{display:block;margin:0 auto}
.talk .who{font-size:10.5px;color:#8B9BA0;margin-top:3px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;
  background:rgba(8,17,20,.55);border-radius:6px;padding:1px 7px;display:inline-block}
.talk .side.npc .who{color:#E8DCC0}
.say{border-radius:0 0 12px 12px;padding:12px 14px;margin-bottom:8px;
  background:rgba(16,26,31,.92);border:1px solid rgba(255,255,255,.09);border-top:none;
  font-family:'Gowun Dodum',sans-serif;font-size:13px;line-height:1.65;color:#DCE7E9}
/* 말이 한 마디로 끝나 더 들을 방법이 없었습니다 */
.say .more{display:block;margin:10px 0 0 auto;font:inherit;font-size:11.5px;
  padding:4px 12px;border-radius:999px;cursor:pointer;
  background:transparent;border:1px solid var(--line);color:var(--mute)}
.say .more:active{background:rgba(201,164,76,.18)}
.say .hint{margin-top:8px;padding-top:8px;border-top:1px dashed rgba(201,164,76,.3);
  font-size:12px;color:var(--brass)}
.srow{display:flex;gap:6px;margin:6px 0 4px}
.srow .chip{flex:1;justify-content:center;padding:9px 0}
/* 시작·이어하기와 같은 크기로 위아래에 놓습니다 */
.title-screen .trow{display:flex;flex-direction:column;align-items:center;gap:9px;margin-top:11px}
/* display:block 만 주면 부모의 text-align 이 안 먹어 왼쪽에 붙습니다.
   좌우 여백을 auto 로 두어야 가운데에 섭니다. */
.title-screen .tstart, .title-screen .trow .tbtn{width:236px;box-sizing:border-box;
  display:block;margin-left:auto;margin-right:auto;text-align:center;
  padding-left:0;padding-right:0}
.title-screen .trow .tbtn{font-size:15px;padding:7px 0;line-height:1.15;border-radius:0;
  border:10px solid transparent;
  border-image:var(--btnbig,url('assets/btn_gold.png')) 14 fill stretch;
  background:transparent;color:#F2E7C4;letter-spacing:.14em;
  font-family:'Gowun Dodum',sans-serif;text-shadow:0 1px 2px rgba(0,0,0,.7)}
.title-screen .trow .tbtn.warn{color:#E8C0B4}
.title-screen .trow .tbtn.tclose{width:236px;font-size:12.5px;letter-spacing:.06em}
.title-screen .tbtn{font:inherit;font-size:12px;padding:5px 15px;line-height:1.3;border-radius:999px;
  background:rgba(255,255,255,.04);border:1px solid rgba(201,164,76,.32);color:#C9A44C;cursor:pointer}
.title-screen .tbtn.warn{color:#9AA8AC;border-color:rgba(255,255,255,.16)}
.title-screen .tbtn:active{background:rgba(201,164,76,.2)}
.title-screen .tbtn.tclose{width:100%;margin-top:8px;color:#8B9BA0;border-color:rgba(255,255,255,.14)}
.title-screen .tload{display:none;margin-top:16px;text-align:left;
  max-width:340px;margin-left:auto;margin-right:auto}
.title-screen .tload.on{display:block}
.title-screen .tnote{margin:0 0 8px;font-size:11.5px;color:#8B9BA0;letter-spacing:0}
.title-screen textarea{width:100%;box-sizing:border-box;font-family:'IBM Plex Mono',monospace;
  font-size:11px;padding:9px;border-radius:8px;background:rgba(0,0,0,.35);
  border:1px solid rgba(255,255,255,.12);color:#D6E2E4;resize:vertical}
.title-screen .tver{display:block;margin:-4px 0 10px;font-size:11px;color:#7C8E93;
  letter-spacing:.16em;font-family:'IBM Plex Mono',monospace}
.verline{text-align:center;color:var(--line);font-size:10px;letter-spacing:.14em;
  font-family:'IBM Plex Mono',monospace;padding:14px 0 4px}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
:root{
  --ink:#0E1A1F; --panel:#16262D; --plate:#081114; --line:#2C444C;
  --chalk:#E4EDE9; --mute:#87A0A4; --brass:#C9A44C; --signal:#E2653A;
  --jade:#4FB89A; --danger:#D9455F; --violet:#9B7BD4; --r:10px;
  /* ── 안전 여백을 얼마나 되찾는가 ─────────────
     viewport-fit=cover 라 화면은 이미 노치 끝까지 갑니다. 그런데
     머리띠와 탭바가 제 안쪽으로 그만큼 물러나 앉아 그 띠가 통째로 비어 있었습니다.

     아이폰 15 프로 기준 위 59px · 아래 34px — 합쳐 93px 입니다.
     세로 956px 짜리 화면에서 한 할입니다.

     위는 다 못 먹습니다. 시계와 배터리가 그 자리에 그려집니다 —
     12px 만 남기고 당깁니다(59 → 47).
     아래는 홈 막대뿐이고 그 위도 눌립니다. 셋에 하나만 남깁니다(34 → 11).

     되찾은 것 34px. 더 당기려면 이 두 줄만 고치면 됩니다. */
  --padt: max(calc(env(safe-area-inset-top) - 12px), 8px);
  --padb: calc(env(safe-area-inset-bottom) * 0.34);
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0;height:100%}
body{background:var(--ink);color:var(--chalk);
  font-family:'IBM Plex Sans KR',system-ui,sans-serif;font-size:14px;line-height:1.55;
  overscroll-behavior:none}
#app{max-width:480px;margin:0 auto;min-height:100%;display:flex;flex-direction:column}

header{position:sticky;top:0;z-index:30;background:var(--ink);
  padding:var(--padt) 14px 9px;border-bottom:1px solid var(--line)}
.hrow{display:flex;align-items:center;gap:10px}
.gname{font-family:'Gowun Batang','Nanum Myeongjo',serif;font-weight:700;
  font-size:18px;line-height:1.2;letter-spacing:.04em}
.gsub{font-size:11px;color:var(--mute);letter-spacing:.05em}
.hnum{font-family:'IBM Plex Mono',monospace;font-size:11.5px;color:var(--mute);text-align:right}
.gver{font-family:'IBM Plex Mono',monospace;font-size:9.5px;color:#4E5F66;
  letter-spacing:.03em;margin-top:1px}
.daybar{position:relative;height:9px;border-radius:4px;background:var(--plate);
  overflow:hidden;margin-top:4px;width:132px;margin-left:auto}
.daybar i{display:block;height:100%;width:100%;
  background:linear-gradient(90deg,#1d3550 0%,#2e5f7a 22%,#c9a44c 46%,#e2653a 62%,#2a2f52 80%,#151d2c 100%)}
.daybar .sun{position:absolute;top:-2px;width:2px;height:13px;background:var(--chalk);
  box-shadow:0 0 5px rgba(232,228,217,.9);transition:left .5s linear}
.clock24{font-family:'IBM Plex Mono',monospace;font-size:20px;font-weight:600;
  color:var(--brass);letter-spacing:.06em;line-height:1.15;font-variant-numeric:tabular-nums}
.hnum b{color:var(--brass);font-weight:600}
.gear{width:34px;height:34px;border-radius:8px;flex:0 0 34px;background:transparent;
  border:1px solid var(--line);color:var(--mute);font-size:15px;cursor:pointer;
  display:inline-grid;place-items:center;padding:0;line-height:1}

#runs{padding:8px 12px 0;display:grid;grid-template-columns:1fr 1fr;gap:6px}
#runs .run.wide{grid-column:1/-1}
.run{background:var(--plate);border:1px solid var(--line);border-radius:var(--r);
  padding:6px 8px 7px;position:relative;overflow:hidden;min-width:0;
  animation:board .35s cubic-bezier(.2,.9,.3,1)}
@keyframes board{from{opacity:0;transform:translateY(-6px) scaleY(.9)}to{opacity:1;transform:none}}
.run.done{border-color:var(--brass)}
.run.boss{border-color:var(--danger)}
.run.dung{border-color:var(--violet)}
.run.done{border-color:var(--brass)!important}
.run-top{display:flex;align-items:center;gap:6px;margin-bottom:4px;min-width:0}
.run-name{font-size:11.5px;font-weight:500;line-height:1.2;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.run-kind{font-size:9px;color:var(--mute);letter-spacing:.06em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 시계는 아랫줄 왼쪽에 둡니다. 취소 버튼과 겹치던 문제를 없앴습니다. */
.run-mid{display:flex;align-items:center;gap:6px;margin-bottom:3px}
.clock{font-family:'IBM Plex Mono',monospace;font-size:12.5px;
  font-weight:600;color:var(--brass);letter-spacing:.02em}
.run-ph{font-family:'IBM Plex Mono',monospace;font-size:8.5px;color:var(--signal);
  letter-spacing:.08em;margin-left:auto;white-space:nowrap}
.route{position:relative;height:12px;margin:0 1px}
.route .rail{position:absolute;top:7px;left:0;right:0;height:2px;
  background-image:radial-gradient(circle,var(--line) 1px,transparent 1.2px);
  background-size:6px 2px;background-repeat:repeat-x}
.route .sailed{position:absolute;top:7px;left:0;height:2px;background:var(--signal);
  border-radius:1px;transition:width 1s linear;box-shadow:0 0 6px rgba(226,101,58,.5)}
.dot{position:absolute;top:3px;width:10px;height:10px;border-radius:50%;
  border:2px solid var(--line);background:var(--plate)}
.dot.a{left:-2px;background:var(--line)} .dot.b{right:-2px}
.run.done .dot.b{background:var(--brass);border-color:var(--brass)}
.marker{position:absolute;top:-2px;width:20px;height:20px;margin-left:-10px;
  display:grid;place-items:center;font-size:13px;transition:left 1s linear}
.settle{margin-top:5px;width:100%;padding:4px;border:7px solid transparent;
  border-image:var(--btnon,url('assets/btn_bar.png')) 14 fill stretch;border-radius:0;
  background:transparent;color:#F5EAC6;font-weight:600;font-size:12.5px;
  font-family:inherit;cursor:pointer;text-shadow:0 1px 0 rgba(0,0,0,.5)}
/* 파견 카드의 취소 표시도 선으로 긋습니다 */
.recall{position:absolute;top:4px;right:5px;width:18px;height:18px;line-height:0;
  font-size:0;color:var(--mute);background:none;border:none;cursor:pointer;
  font-family:inherit;padding:0}
.recall::before,.recall::after{content:'';position:absolute;left:50%;top:50%;
  width:11px;height:1.5px;border-radius:1px;background:currentColor}
.recall::before{transform:translate(-50%,-50%) rotate(45deg)}
.recall::after{transform:translate(-50%,-50%) rotate(-45deg)}
.rgem{width:100%;margin-top:4px;padding:3px;border:7px solid transparent;
  border-image:var(--btnred,url('assets/btn_rust.png')) 14 fill stretch;border-radius:0;
  background:transparent;color:#F0C2C2;font-size:11px;font-weight:600;
  font-family:inherit;cursor:pointer}
.rgem:disabled{filter:grayscale(.7) brightness(.55);color:var(--line)}
/* 종이 화면에서는 돌 단추가 배경에 묻히고 글자도 안 읽혔습니다.
   테두리를 걷어 내고 종이에 어울리는 금테 단추로 둡니다. */
body.paper .rgem{border:1px solid var(--brass);border-image:none;border-radius:8px;
  padding:7px 8px;background:rgba(122,92,24,.10);color:var(--brass);
  font-size:12px;letter-spacing:.02em}
body.paper .rgem:disabled{filter:none;background:transparent;
  border-color:var(--line);color:var(--mute);opacity:.7}

main{flex:1;padding:12px 14px calc(var(--navh,68px) + 22px)}
.eyebrow{font-family:'IBM Plex Mono',monospace;font-size:10px;letter-spacing:.18em;
  color:var(--mute);margin:16px 0 8px;display:flex;align-items:center;gap:8px}
.eyebrow:first-child{margin-top:2px}
.eyebrow::after{content:'';flex:1;height:1px;background:var(--line)}
h2.tt{font-family:'Gowun Batang','Nanum Myeongjo',serif;font-size:22px;margin:0 0 2px;
  font-weight:700;letter-spacing:.02em}
.sub{color:var(--mute);font-size:12px;margin:0 0 4px}

/* ── 지도 : 육각 타일 ──────────────────── */
.chips{display:flex;gap:6px;overflow-x:auto;padding:0 0 6px;-webkit-overflow-scrolling:touch}
/* ── 지도 중앙 전투 표시 ─────────────────── */
.fight{position:fixed;left:50%;transform:translateX(-50%);top:46%;z-index:9;
  width:min(340px,92vw);display:none;pointer-events:none}
body.mapmode .fight.on{display:block}
.fight .fbox{background:rgba(8,17,20,.86);backdrop-filter:blur(6px);
  border:1px solid var(--line);border-radius:12px;padding:10px 12px 8px}
.fight .frow{display:flex;align-items:flex-end;gap:10px}
.fight .fside{flex:1;min-width:0;text-align:center}
.fight .fside .spr{margin:0 auto}
.fight .fn{font-size:10.5px;color:var(--chalk);margin-top:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fight .fvs{font-family:'IBM Plex Mono',monospace;font-size:11px;color:var(--signal);
  padding-bottom:16px;letter-spacing:.06em}
.fight .fhp{height:5px;border-radius:3px;background:rgba(0,0,0,.6);overflow:hidden;margin-top:4px}
.fight .fhp i{display:block;height:100%;background:var(--jade);transition:width .35s}
.fight .fhp.m i{background:var(--danger)}
.fight .fmeta{display:flex;align-items:center;gap:6px;margin-top:7px;
  font-family:'IBM Plex Mono',monospace;font-size:9.5px;color:var(--mute)}
.fight .fbar{flex:1;height:3px;border-radius:2px;background:var(--plate);overflow:hidden}
.fight .fbar i{display:block;height:100%;background:var(--brass);transition:width .4s linear}
/* 전투 기록 창도 상대가 오른쪽입니다 — 뒤집지 않습니다 */
.fight .fmob, .fbig .fmob{transform:none}
.fight .fmob.elite{filter:drop-shadow(0 0 6px rgba(226,101,58,.95)) saturate(1.3)}
.fight .elt{color:var(--signal)}
.fight .fcb{font-family:'IBM Plex Mono',monospace;font-size:9px;color:var(--mute)}
/* 지도 하단 타이머 */
.mtimer{position:fixed;left:50%;transform:translateX(-50%);z-index:9;
  bottom:calc(var(--navh,68px) + 10px);display:none;
  background:rgba(8,17,20,.9);border:1px solid var(--line);border-radius:999px;
  padding:5px 14px;font-family:'IBM Plex Mono',monospace;font-size:12px;
  color:var(--brass);letter-spacing:.06em;white-space:nowrap;pointer-events:none}
body.mapmode .mtimer.on{display:block}
.goalline{display:flex;align-items:center;gap:6px;padding:3px 2px 5px;
  font-size:10.5px;color:var(--mute);letter-spacing:.02em;line-height:1.2}
.goalline span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.goalline b{color:var(--brass);font-family:'IBM Plex Mono',monospace;font-size:9.5px;
  border:1px solid var(--line);border-radius:4px;padding:1px 5px}
.hgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.hcard{background:var(--panel);border:1px solid var(--line);border-radius:10px;
  padding:10px 6px 8px;text-align:center;cursor:pointer;position:relative;
  display:flex;flex-direction:column;align-items:center;gap:2px}
.hcard .gmk{color:#FFD86B}
.hcard .hn{font-size:12px;font-weight:600;margin-top:4px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.hcard .hj{font-size:9.5px;color:var(--mute);letter-spacing:.02em}
.hcard .mini{width:100%}
.hcard .hst{font-size:9px;color:var(--mute);margin-top:3px;letter-spacing:.06em}
.hcard .hst.run{color:var(--signal)} .hcard .hst.pt{color:var(--brass)}
.hcard .hauto{position:absolute;top:4px;right:5px;font-size:8px;color:var(--jade);
  border:1px solid var(--jade);border-radius:4px;padding:0 3px}
.chip{flex:0 0 auto;padding:5px 12px;border-radius:14px;border:1px solid var(--line);
  background:var(--plate);color:var(--mute);font-size:11px;cursor:pointer;
  font-family:'IBM Plex Mono',monospace;letter-spacing:.02em;white-space:nowrap;
  display:inline-flex;align-items:center;gap:5px;line-height:1}
.chip.on{border-color:var(--brass);color:var(--brass);background:var(--panel)}
/* 지역 이름 아래에 그 땅의 격을 적습니다 — 어디가 내 자리인지 한눈에 */
.chip .rgv{display:block;font-family:'IBM Plex Mono',monospace;font-size:8.5px;
  font-style:normal;opacity:.7;letter-spacing:-.02em;line-height:1.1}
.chip.lk{opacity:.32}
.rgcard{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:9px 12px;display:flex;gap:10px;align-items:center;margin-bottom:2px}
.rgcard .rgi{font-size:22px;line-height:1}
.rgcard .rgn{font-family:'Gowun Batang','Nanum Myeongjo',serif;font-size:16px}
.rgcard .rgd{font-size:11px;color:var(--mute);margin-top:1px}
.hop{width:100%;padding:7px;border-radius:8px;border:1px dashed var(--line);
  background:transparent;color:var(--mute);font-family:'IBM Plex Mono',monospace;
  font-size:10.5px;cursor:pointer;letter-spacing:.06em;margin:6px 0}
.hop.on{border-style:solid;border-color:var(--brass);color:var(--brass)}
.hop:disabled{opacity:.3;cursor:default}
/* ── 표피 ─────────────────────────────────────
   그림이 없으면 var(...) 의 뒷값이 쓰여 지금까지의 모습 그대로입니다. */
#mapview::before{content:'';position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:var(--mapbg,none);background-repeat:repeat;background-size:220px 220px}
#mapview::after{content:'';position:absolute;inset:0;z-index:6;pointer-events:none;
  background-image:var(--mapedge,none);background-repeat:no-repeat;background-size:100% 100%}
#mapview{position:relative;margin:2px -4px 0;background:#6E5C44;
  border:1px solid var(--line);border-radius:var(--r);overflow:hidden;
  touch-action:none;cursor:grab;-webkit-user-select:none;user-select:none}

/* ── 지도 탭 : 전체화면 지도 위에 UI를 얹습니다 ───────── */
html.mapmode,body.mapmode{height:100%;overflow:hidden;overscroll-behavior:none}
body.mapmode{position:fixed;left:0;right:0;top:0;bottom:0}
body.mapmode #app{height:100%}
body.mapmode #mapview{position:fixed;top:0;bottom:0;left:50%;
  transform:translateX(-50%);width:100%;max-width:480px;
  margin:0;border:0;border-radius:0;z-index:1;background:#6E5C44}
/* 타일 위에서 시작한 터치도 지도가 가져갑니다 */
#mapview,#mapview *{touch-action:none;-webkit-touch-callout:none}
body.mapmode main{padding:0;min-height:0;flex:0 0 auto}
/* 지도에서만 머리띠를 흐릿하게 깔고 그 위로 지도를 지나가게 했었습니다.
   그래서 색이 다르게 보이고, 띠 옆 빈 곳을 누르면 지도가 끌려 왔습니다.
   다른 탭과 똑같이 불투명한 띠로 두고, 누르는 자리도 같게 맞춥니다. */
body.mapmode header{position:fixed;top:0;left:50%;transform:translateX(-50%);
  width:100%;max-width:480px;z-index:20;
  background:var(--ink);border-bottom:1px solid var(--line);
  padding-bottom:9px;pointer-events:auto}
/* 주인공 상자가 머리띠 바로 아래를 차지하므로 그만큼 더 내려갑니다.
   --pcwh 는 measureView 가 실제 높이를 재어 넣습니다. */
body.mapmode #runs{position:fixed;left:50%;transform:translateX(-50%);
  width:100%;max-width:480px;z-index:18;padding:0 14px;
  top:calc(var(--hh,132px) + var(--pcwh,0px))}
body.mapmode #runs .run{background:rgba(8,17,20,.93);backdrop-filter:blur(6px)}
body.mapmode nav{z-index:22}
/* 받은 머리띠 그림은 가운데가 균일한 띠가 아니라 사방이 닫힌 액자입니다.
   9조각으로 늘리면 끝 장식과 위아래 금테가 글자를 자릅니다.
   테두리로 쓰지 않고 배경으로 통째로 늘려, 액자가 온전히 보이게 합니다.
   대신 안쪽 여백을 금테 두께만큼 줍니다. */
/* 액자 안쪽으로 글자를 들입니다.
   끝 장식이 그림 폭의 4.5%(390px 화면에서 18px), 위아래 금테가 높이의 11% 입니다.
   그보다 넉넉히 주어야 '엘도리아 길드' 가 장식 위에 얹히지 않습니다. */
header .hrow{background-image:var(--barimg,none);background-size:100% 100%;
  background-repeat:no-repeat;padding:11px 28px 12px}
/* 액자 뒤에 덧대던 옅은 판은 이제 필요 없습니다 — 머리띠가 불투명합니다 */
nav{background-image:var(--barimg,none);background-size:100% 100%;
  background-repeat:no-repeat}
nav button{padding-top:14px;padding-bottom:12px}
nav{padding-left:10px;padding-right:10px}
header .chips{padding:8px 0 0;margin:0}
header .chips:empty{display:none}
header .legend{padding:7px 0 0;margin:0;justify-content:flex-start;gap:12px}
header .legend:empty{display:none}
#mapview.grabbing{cursor:grabbing}
#map{position:absolute;left:0;top:0;will-change:transform;transform-origin:0 0}
/* 늘이고 줄이는 단추는 **지도 위의 것들보다 위**여야 합니다(v1.27).
   용사 표(.pcar)가 z14 라, 표가 오른쪽 아래에 서면 단추를 덮어
   눌러도 표가 눌렸습니다. 파견 카드(z18)보다는 아래에 둡니다.
   아래 자리도 손으로 적던 70px 을 걷고 잰 탭바 높이를 씁니다. */
.zoomui{position:absolute;right:10px;bottom:calc(var(--navh,68px) + 12px);
  z-index:16;display:flex;flex-direction:column;align-items:center;gap:6px}
.zoomui button{width:38px;height:38px;border-radius:10px;border:1px solid var(--line);
  background:rgba(8,17,20,.86);backdrop-filter:blur(6px);color:var(--chalk);
  font-size:17px;line-height:1;cursor:pointer;font-family:inherit}
.zoomui button.fit{width:38px;height:auto;padding:6px 0;font-size:10px;letter-spacing:.02em}
.zoomui #zlabel{font-family:'IBM Plex Mono',monospace;font-size:9.5px;color:var(--mute)}
.hexbr.dim{opacity:.25}
.bandn{position:absolute;font-family:'IBM Plex Mono',monospace;font-size:9.5px;
  letter-spacing:.14em;color:var(--mute);background:var(--plate);padding:0 6px;
  border-radius:6px;white-space:nowrap}
.hexbr{position:absolute;background:#2C444C;border-radius:2px;transform-origin:center;
  z-index:2;opacity:.7}
.hexbr.open{background:var(--brass);opacity:.55}
/* 그림으로 그린 길. 아직 밟지 않은 길은 어둡게 깔립니다. */
/* z-index 를 주면 안 됩니다. 그림 타일이 z-index:auto 라
   길이 타일 위로 올라와 테두리를 덮습니다. DOM 순서(길 → 타일)에 맡깁니다. */
.hexrd{position:absolute;pointer-events:none;background-repeat:no-repeat;
  image-rendering:pixelated;opacity:.45;filter:grayscale(.5) brightness(.7)}
.hexrd.open{opacity:.85;filter:none}
/* 지역과 지역을 잇는 긴 길 */
.road{position:absolute;height:3px;transform-origin:0 50%;z-index:1;opacity:.5;
  background:repeating-linear-gradient(90deg,#3A5661 0 7px,transparent 7px 15px)}
.road.open{opacity:.45;
  background:repeating-linear-gradient(90deg,var(--brass) 0 7px,transparent 7px 15px)}
.hex{position:absolute;cursor:pointer;z-index:3}
.hex.art{z-index:auto}
/* 필드는 사이의 땅 — 낮게 깔리고 조용해야 목적지와 헷갈리지 않습니다 */
/* 필드도 갈 수 있는 곳입니다. 다른 구역과 똑같이 그리되 이름표만 살짝 눕힙니다. */
.hex.field .hn{letter-spacing:0}
.hexo{position:absolute;inset:0;background:var(--line);transition:background .2s;
  clip-path:polygon(50% 0,100% 25%,100% 75%,50% 100%,0 75%,0 25%)}
.hexi{position:absolute;inset:2px;background:var(--ink);
  clip-path:polygon(50% 0,100% 25%,100% 75%,50% 100%,0 75%,0 25%);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px}
.hexi .hi{line-height:1}
.hexi .hn{font-family:'IBM Plex Mono',monospace;letter-spacing:-.03em;color:var(--mute);
  max-width:84%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-align:center}
.hex.art{background-repeat:no-repeat;display:block}
.hex.art .hn{position:absolute;left:50%;bottom:9%;transform:translateX(-50%);
  text-shadow:0 1px 2px #000,-1px 0 2px #000,1px 0 2px #000,0 0 6px #000;
  max-width:94%;font-weight:600}
/* 아트 타일 : 실루엣을 따라가는 검은 윤곽선. 상태는 이름표 색으로 읽습니다. */
.hex.art{filter:drop-shadow(1px 0 0 #05090B) drop-shadow(-1px 0 0 #05090B)
  drop-shadow(0 1px 0 #05090B) drop-shadow(0 -1px 0 #05090B)
  drop-shadow(0 2px 3px rgba(0,0,0,.55))}
/* 아직 밟지 않은 옆 땅은 형태만 보입니다.
   brightness(0) 이면 그림이 통째로 검게 눌려 실루엣만 남습니다. */
.hex.art.locked{filter:brightness(.12) grayscale(1)
  drop-shadow(0 2px 4px rgba(0,0,0,.5));opacity:.85}
.hex.art .hn{color:#E4EDE9}
.hex.art.new .hn{color:#F08A5C}
.hex.art.town .hn{color:#E3C46B}
.hex.art.boss .hn{color:#F06A80}
.hex.art.dungeon .hn{color:#B79BE6}
.hex.art.boss.done .hn,.hex.art.dungeon.done .hn{color:#E4EDE9}
.hex.art.locked .hn{color:var(--mute)}
.hex.art.locked .hn{color:var(--mute)}
/* 종이 지도에서는 대체 타일도 잉크색으로 그립니다 */
body.paper .hexo{background:#8A7355}
body.paper .hexi{background:#EDE2C6}
body.paper .hexi .hn{color:#5A4A33}
body.paper .hex.unknown .hexo{background:#BCAA8A}
body.paper .hex.unknown .hexi{background:#DED2B4}
body.paper .hex.unknown .hexi .hn{color:#96866A}
body.paper .hex.new .hexi{background:#F0E3C2}
body.paper .hex.town .hexi{background:#F2E6C4}
body.paper .hex.done .hexi .hn{color:#3A2E22}
.hex.unknown .hexo{background:#16242A}
.hex.unknown .hexi{background:#0B1519}
.hex.unknown .hexi .hn{color:#374A52}
.hex.locked{opacity:.55}
.hex.new .hexo{background:var(--signal)}
.hex.new .hexi{background:#1B1614}
.hex.new .hexi .hn{color:var(--signal)}
.hex.done .hexo{background:var(--brass)}
.hex.done .hexi .hn{color:var(--chalk)}
.hex.town .hexo{background:var(--brass)}
.hex.town .hexi{background:#1D1B12}
.hex.town .hexi .hn{color:var(--brass)}
.hex.boss .hexo{background:var(--danger)}
.hex.boss .hexi{background:#1E1114}
.hex.boss .hexi .hn{color:var(--danger)}
.hex.boss.done .hexo{background:var(--brass)}
.hex.boss.done .hexi .hn{color:var(--chalk)}
.hex.dungeon .hexo{background:var(--violet)}
.hex.dungeon .hexi{background:#171326}
.hex.dungeon .hexi .hn{color:var(--violet)}
.hex.dungeon.done .hexo{background:var(--brass)}
.hex.dungeon.done .hexi .hn{color:var(--chalk)}
.hex .lair{position:absolute;top:8%;left:50%;transform:translateX(-50%);z-index:6;
  filter:drop-shadow(0 0 4px rgba(214,90,74,.9))}
.hex.lairy{box-shadow:inset 0 0 0 2px var(--danger)}
.hex .busy{position:absolute;top:14%;right:16%;width:8px;height:8px;border-radius:50%;
  background:var(--signal);border:1.5px solid var(--plate);animation:pulse 1.6s infinite;z-index:4}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}
.hm{position:absolute;width:34px;height:34px;margin:-30px 0 0 -17px;z-index:8;
  display:grid;place-items:center;pointer-events:none;
  transition:left 1s linear, top 1s linear}
.hm .hmi{width:34px;height:34px;display:grid;place-items:end center;font-size:13px;
  filter:drop-shadow(0 0 3px rgba(0,0,0,.9)) drop-shadow(0 0 7px rgba(226,101,58,.55))}
.hm .hmi .spr{display:block}
/* 머리 위 기력 막대 */
.hm .hbar{position:absolute;top:-7px;left:50%;transform:translateX(-50%);
  width:26px;height:3px;background:rgba(0,0,0,.65);border-radius:2px;overflow:hidden;
  box-shadow:0 0 0 1px rgba(0,0,0,.5)}
.hm .hbar i{display:block;height:100%;width:100%;background:var(--jade);transition:width .4s}
/* 전투 중에는 머리 위 막대가 기력이 아니라 남은 체력입니다 */
.hm .hbar.f i{background:var(--signal)}
.hm .hbar.f.low i{background:var(--danger)}
/* 싸우는 상대 — 지도 위 마커 옆에 그대로 세웁니다.
   맞붙는 동안에는 타일 한가운데를 기준으로 좌우 대칭으로 벌립니다.
   용사만 가운데 두고 상대를 오른쪽에 붙이면 한 쌍이 통째로 치우쳐 보입니다. */
.hm .foe{position:absolute;left:50%;bottom:0;display:none}
.hm.duo .hmi{transform:translateX(-15px)}
/* 이 규칙이 상대 막대까지 잡아 왼쪽으로 15px 밀고 있었습니다.
   상대 막대는 .foe 안에 있어 이미 제 스프라이트 위 가운데에 섭니다.
   바로 아래 자식(용사 막대)만 옮겨야 합니다. */
.hm.duo>.hbar{margin-left:-15px}
.hm.duo .foe{margin-left:0}
.hm.duo .cnt{transform:translateX(-15px)}
.hm .foe .hmob{filter:drop-shadow(0 0 3px rgba(0,0,0,.9))}
/* 몬스터 시트는 원래 왼쪽을 봅니다. 여기서는 상대가 오른쪽에 서므로
   그대로 두어야 용사 쪽을 바라봅니다. 뒤집으면 등을 돌립니다. */
.hm .foe .hmob .spr{display:block}
/* 상대 스프라이트가 4px 낮으므로 그만큼 더 올려, 두 막대가 같은 높이에 섭니다 */
.hm .foe .hbar{top:-11px}
.hm .foe .hbar i{background:var(--danger)}
.hm.elite .foe .hmob{filter:drop-shadow(0 0 4px rgba(0,0,0,.9))
  drop-shadow(0 0 9px rgba(226,101,58,.95)) saturate(1.25)}
/* 강한 개체 교전 중 */
.hm.elite .hmi{filter:drop-shadow(0 0 4px rgba(0,0,0,.9)) drop-shadow(0 0 10px rgba(226,101,58,1))}
.hex.elite .hexo{background:var(--signal)}
.hex.art.elite{filter:drop-shadow(0 0 6px rgba(226,101,58,.9)) saturate(1.25)}
.hex.elite{animation:elitepulse 1.1s ease-in-out infinite}
@keyframes elitepulse{
  0%,100%{filter:drop-shadow(0 0 4px rgba(226,101,58,.55))}
  50%{filter:drop-shadow(0 0 13px rgba(226,101,58,.95))}
}
.hm.ret .hmi{filter:drop-shadow(0 0 3px rgba(0,0,0,.9)) drop-shadow(0 0 7px rgba(79,184,154,.6))}
.hm.wait .hmi{filter:drop-shadow(0 0 3px rgba(0,0,0,.9)) drop-shadow(0 0 7px rgba(201,164,76,.6))}

.hm .cnt{position:absolute;right:-3px;bottom:-3px;font-family:'IBM Plex Mono',monospace;
  font-size:8.5px;background:var(--danger);color:#fff;border-radius:6px;padding:0 3px;line-height:1.5}
.hm .lbl{position:absolute;top:-25px;left:50%;transform:translateX(-50%);white-space:nowrap;
  font-family:'IBM Plex Mono',monospace;font-size:9px;letter-spacing:-.02em;
  background:rgba(8,17,20,.92);border:1px solid var(--line);border-radius:8px;
  padding:1px 6px;color:var(--signal);line-height:1.6}
.hm.wait .lbl{color:var(--brass);border-color:var(--brass)}
.hm.ret .lbl{color:var(--jade)}
.hm .lbl b{font-weight:600;color:var(--chalk);margin-left:4px}
/* ── 파견 창 ─────────────────────────────────
   묻는 것을 셋(누가·무엇을·얼마나)에서 둘로 줄이고, 줄 대신 칸으로 늘어놓습니다. */
.dhead{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:10px}
.actsw{background:transparent;border:1px solid var(--line);border-radius:7px;
  color:var(--brass);font:inherit;font-size:12px;padding:2px 9px;cursor:pointer}
.acts, .chips{display:flex;gap:6px;flex-wrap:wrap;margin:0 0 10px}
.acts button, .chips button{background:var(--panel);border:1px solid var(--line);border-radius:8px;
  color:var(--mute);font:inherit;font-size:12px;padding:5px 11px;cursor:pointer}
.acts button.on, .chips button.on{border-color:var(--brass);color:var(--chalk);
  background:rgba(201,164,76,.10)}
.acts button.warn{border-color:var(--danger);color:var(--danger)}
/* 칩에 붙는 개수. 다 채운 것은 초록으로 */
.chips.ico button{display:inline-flex;align-items:center;gap:5px}
.chips button .spr{flex:0 0 auto}
.acts button{display:inline-flex;align-items:center;gap:5px}
.dur b .spr{vertical-align:-3px}
.say .more{display:flex;align-items:center;gap:5px;justify-content:center}
/* 보는 방법 고르는 칸 — 셋이 붙어 한 덩어리로 보이게 */
.chips.seg{gap:0;margin-bottom:8px}
.chips.seg button{border-radius:0;margin-right:-1px}
.chips.seg button:first-child{border-radius:8px 0 0 8px}
.chips.seg button:last-child{border-radius:0 8px 8px 0;margin-right:0}
.chips button i{font-style:normal;font-family:'IBM Plex Mono',monospace;font-size:10px;
  color:var(--mute);margin-left:5px}
.chips button.on i{color:var(--brass)}
.chips button i.done{color:var(--jade)}
.chips.tabs{margin-bottom:12px}
.chips.tabs button{flex:1;text-align:center;padding:7px 4px;font-size:12.5px}
/* 가로로 꽉 찬 막대 셋 */
.hbars{display:flex;flex-direction:column;gap:7px;margin:2px 0 10px}
.hbar{display:flex;align-items:center;gap:9px}
.hbar>b{flex:0 0 34px;font-weight:400;font-size:11px;color:var(--mute)}
.hbar .ht{flex:1;height:11px;border-radius:6px;overflow:hidden;
  background:rgba(120,100,70,.18);border:1px solid var(--line)}
.hbar .ht i{display:block;height:100%;border-radius:6px;transition:width .3s}
.hbar>em{flex:0 0 auto;font-style:normal;font-size:11px;color:var(--chalk);
  font-family:'IBM Plex Mono',monospace;min-width:64px;text-align:right}
.hbar.hurtrow>em{color:#98283C}
/* ── 상점 격자 (v6.16) ─────────────────────────
   한 줄에 하나씩 늘어놓으니 아홉 가지에 화면 두 장이 넘었습니다.
   설명이 두 줄로 접히면 값이 어디 붙었는지도 흐려집니다.
   두 칸씩 세워 한눈에 들어오게 합니다 — 그림·이름·값이 한 덩어리입니다.

   설명은 칸 안에 두 줄까지만 보이고 넘치면 잘립니다.
   자세한 것은 눌러 보면 됩니다 — 여기서는 **고르는 것**이 일입니다. */
.sgrid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:10px}
.scell{background:var(--panel);border:1px solid var(--line);border-radius:10px;
  padding:9px 9px 8px;display:flex;flex-direction:column;gap:5px;
  color:inherit;font:inherit;text-align:left;cursor:pointer;position:relative;
  /* **button 으로 쓰는 칸입니다**(v6.29). 전역 button 초기화가 없어
     기기 기본 테두리와 글꼴이 걸리고, 아이폰에서는 바탕이 회색으로 덮여
     눌리지 않는 것처럼 보였습니다 — 마을에서 무기가 안 골라졌습니다. */
  -webkit-appearance:none;appearance:none;margin:0;width:100%;
  -webkit-tap-highlight-color:transparent;touch-action:manipulation}
.scell:disabled{pointer-events:none}
.scell.dim{opacity:.5;cursor:default}
.scell .sh{display:flex;align-items:center;gap:7px;min-height:32px}
.scell .sn{font-size:12.5px;font-weight:600;line-height:1.25;word-break:keep-all}
.scell .sd{font-size:10.5px;color:var(--mute);line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;min-height:28px}
.scell .sp{display:flex;align-items:center;justify-content:space-between;gap:6px;
  border-top:1px solid var(--line);padding-top:6px;margin-top:auto}
.picks{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px}
.pick{width:66px;background:var(--panel);border:1px solid var(--line);border-radius:10px;
  padding:7px 4px 6px;display:flex;flex-direction:column;align-items:center;gap:3px;
  color:var(--mute);font:inherit;cursor:pointer}
.pick.on{border-color:var(--brass);border-width:2px;padding:6px 3px 5px;
  background:rgba(201,164,76,.16);color:var(--chalk);
  box-shadow:0 0 0 1px var(--brass) inset, 0 2px 8px rgba(201,164,76,.25)}
/* 고른 사람 어깨에 표를 답니다 — 테두리만으로는 한 명일 때 알기 어렵습니다 */
.pick.on::after{content:'';position:absolute;right:-5px;top:-5px;width:16px;height:16px;
  border-radius:50%;background:var(--brass);
  box-shadow:0 1px 3px rgba(0,0,0,.35)}
.pick.on::before{content:'';position:absolute;right:0.5px;top:2.5px;width:5px;height:8px;
  border-right:2px solid var(--ink);border-bottom:2px solid var(--ink);
  transform:rotate(42deg);z-index:1}
.pick{position:relative}
.pick.dim{opacity:.42}
.pick .pn{font-size:10.5px;max-width:58px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pick .pp{font-family:'IBM Plex Mono',monospace;font-size:10.5px;color:var(--brass);font-weight:600}
.pick .pp.good{color:var(--jade)}
.pick .pp.bad{color:var(--danger)}
.pick .ps{width:46px;height:3px;border-radius:2px;background:rgba(0,0,0,.55);overflow:hidden}
.pick .ps i{display:block;height:100%;background:var(--jade)}
.pick.dim .ps i{background:var(--danger)}
.swrow{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--mute);margin-bottom:2px}
.sw{width:34px;height:19px;border-radius:11px;background:var(--plate);border:1px solid var(--line);
  position:relative;flex:none;cursor:pointer}
.sw i{position:absolute;top:1px;left:1px;width:15px;height:15px;border-radius:50%;
  background:var(--mute);transition:left .15s, background .15s}
.sw.on{background:rgba(79,184,154,.22);border-color:var(--jade)}
.sw.on i{left:16px;background:var(--jade)}
.dsum{font-family:'IBM Plex Mono',monospace;font-size:10.5px;color:var(--mute);
  margin:12px 0 8px;padding-top:10px;border-top:1px solid var(--line)}
.dsum b{color:var(--chalk);font-weight:400}
.dsum u{text-decoration:none;color:var(--jade)}
.dsum s{text-decoration:none;color:var(--danger)}
.durs{display:flex;gap:8px}
.dur{flex:1;background:var(--panel);border:1px solid var(--brass);border-radius:10px;
  padding:11px 4px;text-align:center;color:var(--chalk);font:inherit;cursor:pointer}
.dur:disabled{opacity:.38;border-color:var(--line);cursor:default}
.dur b{display:block;font-size:13px;font-weight:500}
.dur span{display:block;font-family:'IBM Plex Mono',monospace;font-size:9.5px;
  color:var(--mute);margin-top:3px;line-height:1.5}
.autotag{font-family:'IBM Plex Mono',monospace;font-size:10px;color:var(--jade);
  border:1px solid var(--jade);border-radius:3px;padding:0 4px;letter-spacing:.04em}
.logline{display:flex;gap:8px;padding:6px 0;border-bottom:1px solid var(--line);
  font-size:11.5px;color:var(--mute);align-items:baseline}
.logline .lt{font-family:'IBM Plex Mono',monospace;font-size:10px;flex:0 0 42px;color:var(--brass)}
.legend{display:flex;gap:9px;justify-content:center;padding:6px 4px 0;flex-wrap:wrap;
  font-family:'IBM Plex Mono',monospace;font-size:9.5px;color:var(--mute)}
.legend i{font-style:normal;color:var(--signal)}
.legend b{font-weight:400;color:var(--brass)}
.legend u{text-decoration:none;color:var(--danger)}
.legend s{text-decoration:none;color:var(--violet)}

.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:11px 12px;margin-bottom:8px;display:flex;gap:11px;align-items:center}
.card.lock{opacity:.45}
.card .body{flex:1;min-width:0}
.card .t{font-size:14px;font-weight:500;display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.card .d{font-size:11px;color:var(--mute);margin-top:2px}
.card .d.one{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tag{font-family:'IBM Plex Mono',monospace;font-size:10px;padding:1px 5px;
  border-radius:3px;background:var(--plate);color:var(--mute);letter-spacing:.04em}
.tag.ok{color:var(--jade)} .tag.warn{color:var(--signal)}
.tag.bad{color:var(--danger)} .tag.br{color:var(--brass)}
.tag.vi{color:var(--violet)}
.rk{font-family:'IBM Plex Mono',monospace;font-size:10px;font-weight:600;
  padding:1px 6px;border-radius:3px;border:1px solid currentColor;letter-spacing:.06em}
.rk.gm{background:linear-gradient(90deg,rgba(255,216,107,.22),rgba(226,101,58,.22));
  box-shadow:0 0 6px rgba(255,216,107,.35)}
.mini.m i{background:linear-gradient(90deg,var(--jade),#FFD86B)}
/* ── 버튼 테두리 ────────────────────────────
   9-슬라이스로 씌웁니다. 글자는 그대로 HTML 이라 문구가 바뀌어도 됩니다.
   이미지가 없으면 아래 border 선언이 그대로 살아 예전 모습으로 보입니다. */
.go{padding:8px 15px;border-radius:7px;border:1px solid var(--brass);background:transparent;
  color:var(--brass);font-family:inherit;font-size:12px;font-weight:600;cursor:pointer;flex:0 0 auto}
/* 테두리 두께가 곧 버튼 높이입니다. 얇게 잡아야 카드가 안 커집니다. */
.go.fr{border:7px solid transparent;border-radius:0;padding:4px 10px;
  border-image:var(--btngo,url('assets/btn_dark.png')) 14 fill stretch;
  color:var(--chalk);background:transparent}
.go.fr.solid{border-image-source:var(--btnon,url('assets/btn_bar.png'));color:#F0E6C8}
/* ── 못 누르는 단추 (v2.28) ────────────────────
   부서진 쇠(btn_iron)로 갈아 끼우고 있었습니다(v1.77). 그런데 그
   그림은 테두리가 실제로 끊겨 있어, 「골드가 모자랍니다」 가
   **그려지다 만 것처럼** 보였습니다 — 바로 위의 「구매」 와 견주면
   같은 단추로 안 읽힙니다.

   틀은 그대로 두고 **불만 끕니다.** 같은 자리에 같은 모양으로 서 되
   빛이 죽어 있으니 「그 단추인데 지금은 안 된다」 가 됩니다.
   글자는 읽혀야 합니다 — v1.77 에 데었던 자리입니다. */
.go.fr:disabled{filter:grayscale(.72) brightness(.86);opacity:.85;
  color:#EFE6CE;text-shadow:0 1px 2px rgba(0,0,0,.7)}
/* 한 줄에 단추가 둘 이상이면 세로로 쌓습니다.
   나란히 두면 좁은 화면에서 글자를 밀어내고 서로 겹칩니다. */
.opt .btns{display:flex;flex-direction:column;gap:5px;flex:0 0 auto}
.opt .btns .go.fr{white-space:nowrap}
.go:disabled{border-color:var(--line);color:var(--line);cursor:default}
.go.solid{background:var(--brass);color:#221A06}
.go.red{border-color:var(--danger);color:var(--danger)}
/* 붉은 것은 색을 돌려 만들던 것을 진짜 녹슨 테로 바꿉니다 */
.go.fr.red{border-image-source:var(--btnred,url('assets/btn_rust.png'));
  filter:none;color:#F3C9BC}
.go.fr.vi{border-image-source:var(--btngo,url('assets/btn_dark.png'));
  filter:hue-rotate(212deg) saturate(1.3) brightness(.9);color:#DCC9F2}
.go.red.solid{background:var(--danger);color:#fff}
.go.vi{border-color:var(--violet);color:var(--violet)}
.go.vi.solid{background:var(--violet);color:#160E24}

.spr{display:inline-grid;place-items:center;flex:0 0 auto;
  background-repeat:no-repeat;image-rendering:pixelated;line-height:1}
.spr.ph{background:var(--plate);border-radius:6px;border:1px solid var(--line)}
.pixel-off .spr{image-rendering:auto}

.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(72px,1fr));gap:7px}
/* 기술은 넉 줄로 못 박습니다(v1.38) — 자동으로 채우면 이름 길이에 따라
   셋이 되었다 다섯이 되었다 해서, 같은 기술이 늘 다른 자리에 있었습니다. */
/* 재료 고르기는 세 열 — 이름이 길어 넷은 줄바꿈이 납니다(v1.82). */
/* 등급 테두리(v1.85) — 일반은 안 두르고, 고급 초록 · 희귀 파랑. */
.tw{position:relative;display:inline-block;border-radius:7px;
  box-shadow:0 0 0 1.5px var(--tc), 0 0 6px -1px var(--tc);
  line-height:0}
/* ── 등급은 이름에도 붙습니다 (v2.31) ─────────────
   테두리 빛깔은 **그림 칸에만** 있었습니다(v1.85). 그래서 목록을
   훑을 때 이름만 읽는 자리 — 낱장 제목 · 잡화상 줄 · 제작 결과 —
   에서는 무엇이 좋은 물건인지 알 수 없었습니다.
   같은 빛깔을 이름에도 씁니다. 일반은 그대로 둡니다 — 지금 굴러가는
   물건이 거의 다 일반이라, 거기에도 색을 넣으면 색이 뜻을 잃습니다. */
.tn-g{color:#5FBF7A}
.tn-r{color:#5B9BD5}
body.paper .tn-g{color:#2F7D4C}
body.paper .tn-r{color:#2E6193}
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-bottom:8px}
.grid3 .cell{padding:8px 4px}
.grid3 .cn{font-size:12px;line-height:1.25;word-break:keep-all}
.grid3 .cq{font-size:13px;font-weight:700;color:var(--brass);margin-top:2px}
.grid4{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}
/* 상점은 다섯 열입니다(v1.69) — 그림과 값만 두고 설명은 낱장에서. */
/* v2.36 — `.grid5` 와 `.grid5x` 가 둘 다 다섯 줄인데 칸 높이와 아이콘
   자리가 달랐습니다. 같은 것을 두 이름으로 부르면 한쪽만 고쳐집니다.
   `.grid5` 는 `.grid5x` 의 결을 그대로 물려받습니다. */
.grid5{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;margin-bottom:10px}
.grid5 .cell{aspect-ratio:1;padding:4px 3px;overflow:hidden;
  container-type:inline-size;
  display:flex;flex-direction:column;
  justify-content:center;align-items:center;text-align:center;gap:0}
.grid5 .cell > *{flex:none;max-width:100%}
@container (max-width:76px){
  .grid5 .cn,.grid5 .n{font-size:8.5px;line-height:1.08}
  .grid5 .cq{font-size:8px;padding-top:0}
  .grid5{--ico:20px}
}
@container (max-width:62px){
  .grid5 .cn,.grid5 .n{font-size:8px}
  .grid5{--ico:17px}
}
/* 상점 격자도 같은 자(GICO) */
.grid5{--ico:24px}
.grid5 .ico{height:var(--ico);flex:none;display:flex;
  align-items:center;justify-content:center;margin-bottom:0}
.grid5 .ico .spr{width:var(--ico) !important;height:var(--ico) !important}
.grid5 .cell{padding:7px 3px 6px}
.grid5 .cn{font-size:10px;line-height:1.2;word-break:keep-all}
.grid5 .cq{font-size:9.5px;opacity:.75;margin-top:3px}
.grid4 .cell{padding:7px 3px 6px}
.grid4 .cn{font-size:11px;line-height:1.25;word-break:keep-all}
/* 숙련 아이콘은 이름 위에 작게 (v1.62). 그림이 없으면 글자가 그 자리를 씁니다. */
.grid4 .spr{display:block;margin:0 auto 3px}
.grid4 .cw{display:block;font-size:9px;letter-spacing:.06em;color:var(--mute);
  margin-bottom:2px}
.grid4 .cq{font-size:9.5px;opacity:.72;margin-top:3px}
/* ── 기술·숙련 격자 (v2.33) ────────────────────
   넉 줄이라 서른 개가 여덟 줄로 늘어졌습니다. 다섯 줄로 좁힙니다.

   **칸 높이가 들쭉날쭉했습니다.** 그림이 있는 칸은 26px 아이콘이,
   없는 칸은 「맨몸」 같은 **글자**가 그 자리를 씁니다(v1.62 의 물러나는
   길). 글자는 높이가 달라 그 칸만 주저앉았습니다.
   아이콘 자리를 26px 상자로 못 박고 칸에 바닥 높이를 줍니다 —
   물러나는 길은 그대로 두되 자리는 안 흔들립니다. */
/* ── 칸이 속을 딱 감쌉니다 (v2.41) ───────────────
   바닥 높이를 86px 로 못 박아 두었더니, 이름이 한 줄인 칸은 아래가
   휑하게 비고 두 줄인 칸은 빠듯했습니다. **칸이 속에 맞춰야지 속이
   칸에 맞출 일이 아닙니다.**

   높이를 풀고 여백만 남깁니다. 다만 한 줄에 다섯이 나란히 서므로
   **줄 안에서는 높이가 같아야** 합니다 — `align-items:stretch`(격자
   기본)가 그 몫을 합니다. 그래서 이름이 두 줄인 칸이 하나만 있어도
   그 줄은 다 같이 커집니다. */
/* ── 칸은 정사각입니다 (v2.43) ───────────────────
   높이를 풀어 속을 감싸게 했더니(v2.41), 이름이 두 줄인 칸 하나가
   **그 줄 전체를 늘렸습니다** — 「대나무 낚싯대」 가 있는 줄만 키가
   컸습니다. 줄마다 키가 달라 격자가 들쭉날쭉했습니다.

   칸을 정사각으로 못 박습니다(`aspect-ratio:1`). 속은 가운데로
   모으고, 이름이 길면 글자를 조금 줄여 두 줄까지 담습니다 —
   칸이 속에 맞추는 것이 아니라 **속이 칸에 담깁니다.** */
/* ── 칸은 정사각, 속은 안 잘립니다 (v2.45) ───────
   정사각으로 못 박았더니(v2.43) **긴 이름의 값이 칸 밖으로
   밀렸습니다** — 「대나무 낚싯대 / 61G」 의 61G 가 잘렸습니다.
   `overflow:hidden` 이 넘친 것을 그냥 자른 것입니다.

   칸은 정사각으로 두되, 속은 **세로로 고르게 나눕니다**.
   그림 자리는 줄어들 수 있게(`flex:0 1 auto` · `min-height:0`),
   이름과 값은 절대 안 줄어들게(`flex:none`) 두면,
   이름이 두 줄이 되어도 값이 밀려나지 않고 그림만 조금 작아집니다. */
.grid5x{display:grid;grid-template-columns:repeat(5,1fr);gap:6px}
/* ── 칸 너비에 맞춰 속이 함께 줍니다 (v2.45) ─────
   **520px 로 재고 있었습니다.** 그건 창의 최대 너비이고, 아이폰은
   390px 입니다.

     창 520px → 한 칸 94px · 속 84px    넉넉합니다
     창 390px → 한 칸 68px · 속 48px    그림26+이름23+값12 = 63px 이라
                                        **15px 이 넘쳐 잘립니다**

   좁은 기기에서만 잘리니 넓은 화면으로만 보면 안 보입니다.

   고정 px 을 버리고 **칸 너비(`cqw`)에 맞춰** 글자와 그림이 함께
   줄게 합니다. 칸이 정사각이므로 너비를 알면 높이도 아는 셈입니다.
   `container-type:inline-size` 로 칸을 자로 삼습니다.

   스프라이트는 여전히 **안 줄입니다** — 줄이면 작아지는 게 아니라
   잘립니다. 대신 `--ico` 로 그림 자리 자체를 작게 잡고, `spr` 이
   그 크기로 그려지게 합니다. */
.grid5x .cell{aspect-ratio:1;padding:4px 3px;overflow:hidden;
  container-type:inline-size;
  display:flex;flex-direction:column;
  justify-content:center;align-items:center;text-align:center;gap:0}
.grid5x .cell > *{flex:none;max-width:100%}
@container (max-width:76px){
  .grid5x .cn,.grid5x .n{font-size:8.5px;line-height:1.08}
  .grid5x .cq{font-size:8px;padding-top:0}
  .grid5x .skg{font-size:7.5px}
  .grid5x{--ico:20px}
}
@container (max-width:62px){
  .grid5x .cn,.grid5x .n{font-size:8px;-webkit-line-clamp:2}
  .grid5x{--ico:17px}
}
/* ── 상자와 그림이 한 숫자를 씁니다 (v2.46) ──────
   상자를 22px 로 조이면서 그림은 26px 로 그리고 있었습니다.
   4px 이 넘쳐 **이름 위로 올라앉았습니다** — 「대참」 이 제 그림에
   겹쳐 읽혔습니다.

   `--ico` 하나가 상자와 그림을 함께 정합니다. 좁아지면 둘이 같이
   줄어듭니다. 스프라이트는 여기서만 늘였다 줄였다 해도 됩니다 —
   `background-size` 를 함께 잡아 주니까요. */
/* JS 의 `GICO`(24) 와 **같은 값**이어야 합니다 — 둘이 어긋나면
   그림이 넘쳐 잘리거나 헐거워집니다(v2.47 의 그 고장 · v2.52). */
.grid5x{--ico:24px}
.grid5x .ico{height:var(--ico);flex:none;display:flex;
  align-items:center;justify-content:center;margin-bottom:0}
.grid5x .ico .spr{width:var(--ico) !important;height:var(--ico) !important}
.grid5x .ico .spr{display:block;margin:0}
/* 마법 그림은 갈래 그림을 빌려 쓰므로, 겹치는 것을 빛깔로 가릅니다(v2.41) */
.icv{display:inline-block;line-height:0}
.grid5x .cw{font-size:9px;letter-spacing:.06em;color:var(--mute);line-height:1.1}
.grid5x .cn{font-size:10px;line-height:1.2;word-break:keep-all}
/* 이름과 값 사이를 붙입니다 — 두 줄짜리 이름이 있는 칸에서 이 틈이
   값을 칸 밖으로 밀어내고 있었습니다(v2.45). */
.grid5x .cq,.grid5 .cq{font-size:9px;opacity:.75;padding-top:0;
  margin-top:-1px;line-height:1.1;letter-spacing:-.01em;white-space:nowrap}
/* 이름은 두 줄까지. 다섯 열이면 한 칸이 60px 남짓이라 열 자가 겨우
   두 줄입니다 — 9.5px 로 조이고 자간을 좁혀 「기운 회복 물약」 같은
   여섯 자도 담습니다(v2.45). */
.grid5x .cn,.grid5x .n{font-size:9.5px;line-height:1.1;
  letter-spacing:-.02em;word-break:keep-all;white-space:normal;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;text-overflow:clip}
.grid5 .cn,.grid5 .n{font-size:9.5px;line-height:1.1;
  letter-spacing:-.02em;word-break:keep-all;white-space:normal;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;text-overflow:clip}
/* ── 숙련도 칸 (v2.43) ──────────────────────────
   정사각으로 못 박고 그림으로 꽉 채웁니다. 글자는 없습니다 —
   숙련도는 **아래에서 차오르는 높이**로 읽습니다.
   `.pa` 는 빈 몫(흐림) · `.pb` 는 찬 몫(또렷)이고, `--p` 가 그 경계를
   정합니다. 두 겹을 겹쳐 두고 아래쪽만 잘라 보이는 방식이라
   그림이 하나여도 됩니다. */
/* ── 숙련도 칸도 같은 짜임 (v2.55) ───────────────
   여기만 「칸을 통째로 채우는 그림」 이었습니다. 갈래 표로 나란히
   오가는 셋인데 결이 다르면 딴 화면처럼 보입니다.
   스킬·채집과 같은 짜임(그림 · 이름 · 값)으로 두되, **차오르는 것은
   그림 안에서만** 일어납니다 — 그것이 숙련도만의 값입니다. */
.pgrid .cell.pcell{aspect-ratio:1;position:relative}
.pcell .pw{position:relative;display:flex;
  align-items:center;justify-content:center}
.pcell .pa,.pcell .pb{position:absolute;inset:0;display:flex;
  align-items:center;justify-content:center}
/* 빈 몫이 너무 바래 「없는 그림」 처럼 보였습니다 — 무엇인지는
   알아볼 만큼 남기고 찬 몫과 갈리게만 합니다(v2.46). */
.pcell .pa{filter:grayscale(.85) brightness(.9);opacity:.5}
.pcell .pb{clip-path:inset(calc(100% - var(--p,0%)) 0 0 0);
  transition:clip-path .35s ease-out}
/* 그림 크기는 다른 격자와 같은 자(--ico)를 씁니다 */
.pcell .pa .spr,.pcell .pb .spr{width:var(--ico);height:var(--ico)}
/* 차오른 자리에 물빛 금을 한 줄 — 높이가 어디까지인지 또렷해집니다 */
/* 차오른 자리에 물빛 금 한 줄 — 그림 안에서만 그립니다 */
.pcell .pw::after{content:'';position:absolute;left:8%;right:8%;
  bottom:var(--p,0%);height:1px;background:var(--brass);opacity:.55}
.pcell .pl{position:absolute;right:3px;top:2px;font-size:10px;
  color:var(--brass);text-shadow:0 1px 2px rgba(0,0,0,.6)}
body.paper .pcell .pl{text-shadow:0 1px 2px rgba(255,255,255,.7)}
/* 개수 고르는 밀대 — 자판을 안 띄웁니다(v2.51) */
.cslide{width:100%;height:28px;-webkit-appearance:none;appearance:none;
  background:transparent;margin:2px 0}
.cslide::-webkit-slider-runnable-track{height:6px;border-radius:3px;
  background:var(--plate);border:1px solid var(--line)}
.cslide::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;
  width:22px;height:22px;margin-top:-9px;border-radius:50%;
  background:var(--brass);border:1.5px solid var(--panel)}
.cslide::-moz-range-track{height:6px;border-radius:3px;background:var(--plate)}
.cslide::-moz-range-thumb{width:22px;height:22px;border-radius:50%;
  background:var(--brass);border:1.5px solid var(--panel)}
/* 채집 창의 스킬 줄 — 싸움의 `dacts` 를 그대로 빌립니다(v2.50) */
.gacts{margin-bottom:6px}
.gacts .q{display:flex;flex-direction:column;align-items:center;gap:1px;
  font-size:11.5px;padding:7px 6px}
.gacts .q .e{font-size:9px;opacity:.7}
/* ── 못 본 것은 그림자로 (v2.49) ─────────────────
   그림을 새로 그려 만드는 것이 아닙니다. 시트 그림에 이미 투명이
   있으니(68%) **까맣게 물들이면** 그 자리에서 그림자가 됩니다 —
   물고기든 광석이든 나무든, 나중에 더할 것까지 저절로 됩니다.
   **테두리도 감춥니다.** 까맣게만 물들이면 윤곽이 남아, 물고기인지
   광석인지 나무인지 한눈에 드러납니다 — 궁금할 것이 없어집니다.
   흐리게 뭉개어 「무언가 어두운 것」 으로만 보이게 합니다.
   크기는 그대로라 칸이 흔들리지 않습니다. */
.zd.shade i{filter:brightness(0.10) contrast(1.4) blur(2.6px);
  opacity:.78;transform:scale(.92)}
.zd.shade b{color:var(--mute);letter-spacing:.10em}
body.paper .zd.shade i{filter:brightness(0.28) contrast(1.2) blur(2.6px);
  opacity:.6}
/* 탭의 점을 띄운 그 칸에도 같은 점을 답니다(v2.48) */
.bslot{position:relative}
.bslot .badge,.grid5x .cell .badge{position:absolute;right:3px;top:3px;
  width:7px;height:7px;border-radius:50%;background:var(--signal);
  box-shadow:0 0 0 1.5px var(--panel)}
/* ── 자동 사냥 중지 (v2.48) ──────────────────────
   자동 사냥을 멈추려면 야영 창을 다시 찾아 들어가야 했습니다. 그
   사이에도 판은 계속 붙습니다. 어디서든 손가락 밑에 있어야 합니다.
   창 위에 뜨되(z-index 90) 아래쪽에 앉혀 창의 단추를 안 가립니다. */
#autostop{position:fixed;left:0;right:0;z-index:90;pointer-events:none;
  bottom:calc(84px + var(--padb,0px));display:flex;justify-content:center}
#autostop button{pointer-events:auto;display:flex;flex-direction:column;
  align-items:center;gap:1px;padding:8px 18px;border-radius:20px;
  border:1.5px solid var(--brass);background:rgba(22,38,45,.94);
  color:#F0E6CC;font-family:inherit;box-shadow:0 6px 18px rgba(0,0,0,.45)}
#autostop b{font-size:12.5px;letter-spacing:.02em}
#autostop span{font-size:9.5px;opacity:.72}
body.paper #autostop button{background:rgba(246,238,220,.96);color:#3A2E22}
/* 낀 것이 제 성능을 못 내면 그 자리에 적습니다(v2.47) */
.slot{position:relative}
.slot .eff{position:absolute;right:3px;top:3px;font-size:9px;font-weight:700;
  color:var(--signal);text-shadow:0 1px 2px rgba(0,0,0,.7)}
body.paper .slot .eff{text-shadow:0 1px 2px rgba(255,255,255,.7)}
/* ── 장착한 것은 테가 굵습니다 (v2.46) ───────────
   퀵슬롯에 걸린 칸이 「장착됨」 이라는 **글자**로만 갈렸습니다.
   예순 칸을 훑을 때 눈이 읽는 것은 글자가 아니라 테입니다. */
.grid5x .cell.on{border-color:var(--brass);border-width:2px;
  box-shadow:inset 0 0 0 1px rgba(201,164,76,.35)}
body.paper .grid5x .cell.on{border-color:#9A7A2E}
/* 퀵슬롯 넷은 한 줄에 — 다섯째 칸을 비워 두지 않습니다 */
.grid5x.qpick{grid-template-columns:repeat(4,1fr)}
.grid5x.qpick .cell.mine{border-color:var(--signal)}
/* 스킬 등급 — 물건 등급과 같은 빛깔을 씁니다(v2.42) */
.skg{font-size:9px;letter-spacing:.04em;opacity:.9;margin-top:1px}
.tn-e{color:#B07BD6}
body.paper .tn-e{color:#7A4FA0}
/* 물건 칸은 이름이 아래에 옵니다(`.n`) — 기술 칸(`.cn`)과 자리가
   다르므로 함께 맞춥니다(v2.36). 도감의 실루엣·자물쇠도 여기 삽니다. */
.grid5x .n{font-size:10px;line-height:1.2;word-break:keep-all;
  white-space:normal;overflow:visible;text-overflow:clip}
.grid5x .q{font-size:9.5px}
/* ── 단추에는 빛깔을 정해 두어야 합니다 (v2.31) ──
   `.cell` 은 `<button>` 인데 글자 빛깔을 안 정해 두었습니다. 그래서
   브라우저가 제 것을 씁니다 — iOS 에서는 **시스템 링크 파랑**입니다.
   상점의 물건 이름과 값이 다 파랗게 떴고, 하필 그 파랑이 v1.85 의
   **희귀 등급 빛깔**과 같은 자리에 있어 뜻이 겹쳤습니다.
   일반은 여느 글자색으로 돌려놓습니다 — 색이 뜻을 가지려면
   바탕이 무색이어야 합니다. */
.cell{background:var(--panel);border:1px solid var(--line);border-radius:8px;
  padding:8px 4px 6px;text-align:center;position:relative;cursor:pointer;
  color:var(--chalk);
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start}
.cell .cn{color:var(--chalk)}
.cell .cq{color:var(--brass)}
.cell .n{font-size:10px;color:var(--mute);margin-top:4px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cell .q{position:absolute;top:3px;right:5px;font-family:'IBM Plex Mono',monospace;
  font-size:10px;color:var(--brass)}
.cell.unk{opacity:.35;cursor:default}
.cell.lk{border-color:var(--brass)}
.cell .lkm{position:absolute;top:3px;left:4px;line-height:0;opacity:.95}
/* 선공 표. 오른쪽 위는 .q 가 쓰므로 왼쪽 아래에 답니다. */
/* ── 갈 곳 표시 (v2.07) ────────────────────────
   큰 느낌표가 칸 위에 뜨고 위아래로 까딱입니다. 보스 칸이면
   붉게 — 「여기가 끝이다」 를 빛깔로 압니다. */
.qbang{position:absolute;left:50%;top:-18px;transform:translateX(-50%);
  font-style:normal;font-weight:800;font-size:22px;line-height:1;
  color:#F2C14E;text-shadow:0 2px 4px rgba(0,0,0,.75),0 0 10px rgba(242,193,78,.5);
  animation:qBob 1.1s ease-in-out infinite;pointer-events:none;z-index:6}
.qbang.boss{color:#E2653A;text-shadow:0 2px 4px rgba(0,0,0,.8),0 0 12px rgba(226,101,58,.6)}
@keyframes qBob{0%,100%{transform:translateX(-50%) translateY(0)}
  50%{transform:translateX(-50%) translateY(-5px)}}
/* 그 칸으로 가는 화살표는 깜박입니다 — 눈이 저절로 따라갑니다. */
/* 이름 있는 놈이 나와 있는 칸 (v2.10). 느낌표와 겹치지 않게
   반대쪽 위에 섭니다. */
/* 지도 위 한 줄 — 남은 시간이 오른쪽에 섭니다. */
.nbar{margin:0 0 6px;padding:7px 10px;border-radius:10px;cursor:pointer;
  background:rgba(88,52,116,.22);border:1px solid rgba(200,139,232,.45);
  font-size:12px;color:#E9DDF4;display:flex;align-items:center;gap:6px}
.nbar b{color:#C88BE8}
.nbar i{margin-left:auto;font-style:normal;font-size:11px;opacity:.8}
.nmark{position:absolute;right:-4px;top:-14px;font-style:normal;
  font-size:17px;line-height:1;color:#C88BE8;
  text-shadow:0 2px 4px rgba(0,0,0,.8),0 0 10px rgba(200,139,232,.6);
  animation:qBob 1.4s ease-in-out infinite;pointer-events:none;z-index:6}
/* ── 길이 아니라 화살표가 깜박입니다 (v2.37) ─────
   v2.07 부터 길 그림 통째로 깜박였습니다. 길은 지도의 바탕이라,
   그것이 사라졌다 나타나면 **지도가 흔들려 보입니다** — 눈이 갈 곳을
   찾는 것이 아니라 어지러워집니다.
   길은 밝게 켜 두기만 하고, 그 위의 화살표만 깜박입니다. */
.hexrd.lit{opacity:1;filter:none}
.hexbr.lit{background:var(--brass);opacity:.9}
.goalarrow{position:absolute;z-index:5;pointer-events:none;
  font-size:13px;line-height:1;color:var(--brass);
  text-shadow:0 1px 3px rgba(0,0,0,.85),0 0 8px rgba(201,164,76,.7);
  animation:qBlink 1.1s ease-in-out infinite}
body.paper .goalarrow{color:#9A7A2E;text-shadow:0 1px 2px rgba(255,255,255,.6)}
@keyframes qBlink{0%,100%{opacity:1}50%{opacity:.25}}
/* 못 배운 제작법은 실루엣으로 (v2.08) */
.silh{display:inline-block;filter:brightness(0) opacity(.42)}
.agrs{position:absolute;left:4px;bottom:4px;display:flex;gap:2px;align-items:center;
  line-height:0;pointer-events:none}
.agrs .agr{position:static}
.agrs b{font-size:8px;color:#7C8F84;line-height:1}
.agr.none{position:absolute;left:4px;bottom:4px;width:6px;height:6px;border-radius:999px;
  background:transparent;border:1px dashed rgba(255,255,255,.22)}
.cell .agr{position:absolute;left:4px;bottom:4px;width:6px;height:6px;border-radius:999px;
  box-shadow:0 0 0 1px rgba(0,0,0,.55);pointer-events:none}
/* 층 목록의 작은 그림 : 타일 가운데를 잘라 씁니다 */
.fspr{border-radius:4px;background-repeat:no-repeat}
.fspr.lk{filter:grayscale(1) brightness(.45)}
/* 가방 칸 — 지고 올 수 있는 짐의 크기를 눈으로 보여 줍니다 */
/* 마을 칸 — 두 칸씩 */
/* ── 마을 그림 화면 ───────────────────────────
   가로로 넘기는 세 폭. 건물 그림이 아직 없어 판과 간판으로 세웁니다. */
/* ── 구역의 얼굴 ────────────────────────────── */
/* ── 들판 파노라마 ────────────────────────────
   .zpano 가 굴러가는 창, .zstrip 이 그 안의 한 줄입니다.
   줄은 width:max-content — inline-block 은 shrink-to-fit 이라
   화면 폭을 못 넘습니다(마을이 이것 때문에 다섯 판 동안 안 밀렸습니다).
   min-width:100% 는 몬스터가 둘뿐일 때 배경이 쪼그라들지 않게 잡아 둡니다. */
.zpano{margin:8px 0 2px;border-radius:10px;border:1px solid var(--line);
  overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;
  scrollbar-width:none}
.zpano::-webkit-scrollbar{display:none}
.zstrip{position:relative;width:max-content;min-width:100%;height:150px;
  display:flex;align-items:flex-end;padding:0 16px 14px;box-sizing:border-box;
  background-size:cover;background-position:center;
  background-color:var(--dsky,transparent)}
.zfog{position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(20,28,32,.05),rgba(20,28,32,.42))}
.zline{position:absolute;left:0;right:0;bottom:0;height:34px;
  background:linear-gradient(180deg,rgba(20,28,32,0),rgba(20,28,32,.5))}
.zmob{position:relative;z-index:2;flex:0 0 auto;background:none;border:0;padding:0;
  font:inherit;cursor:pointer;display:flex;flex-direction:column;align-items:center;
  transform:scale(var(--zs,1)) translateY(calc(-1 * var(--zu,0px)));
  transform-origin:50% 100%;opacity:var(--zo,1)}
.zmob .zmb{display:block;filter:drop-shadow(0 4px 6px rgba(0,0,0,.5))}
.zmob .zmn{display:block;max-width:84px;font-size:10px;color:#EDE1C4;
  text-shadow:0 1px 3px rgba(0,0,0,.9);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;margin-top:3px}
.zmob.un .zmn{color:#C7B79A}
.zmob:active .zmb{transform:translateY(1px)}
.zhint{text-align:center;font-size:10px;color:var(--mute);margin:2px 0 4px;opacity:.75}
.znone{position:absolute;inset:0;display:grid;place-items:center;
  color:#EDE1C4;font-size:12px;text-shadow:0 1px 3px rgba(0,0,0,.9)}
/* 네모칸을 걷었습니다. 칸 폭이 52px 로 못 박혀 있는데 이름은 안 잘려서,
   「기운 회복 물약」·「전리품 주머니」 가 두 줄로 흘러 아랫줄 아이콘을 밀었습니다.
   칸을 없애고 한 줄로 흘리면 겹칠 데가 없습니다.
   테두리 색으로 알리던 갈래(덤·장비)는 글자 색이 그대로 맡습니다. */
.zdrop{display:flex;flex-wrap:wrap;gap:5px 10px;margin-top:4px;align-items:center}
.zd{display:inline-flex;align-items:center;gap:4px;white-space:nowrap}
.zd i{display:inline-grid;place-items:center}
.zd b{font-weight:400;font-size:10.5px;color:var(--mute);line-height:1.2}
.zd.w b{color:var(--brass)}
.zd.g b{color:var(--jade)}
.tbar{display:flex;gap:6px;overflow-x:auto;padding:2px 0 8px;
  -webkit-overflow-scrolling:touch;scrollbar-width:none}
.tbar::-webkit-scrollbar{display:none}
.tchip{flex:0 0 auto;display:flex;align-items:center;gap:5px;
  padding:7px 11px;border-radius:999px;border:1px solid var(--line);
  background:var(--plate);color:var(--chalk);font:inherit;font-size:11.5px;
  cursor:pointer;white-space:nowrap}
.tchip.warn{border-color:rgba(226,101,58,.5);color:#98421A}
.tchip:active{background:rgba(201,164,76,.2)}
/* 브라우저가 알아서 굴립니다. 손으로 가로채는 것이 없습니다. */
/* **양끝이 안 잡혔습니다**(v1.10). 아이폰은 끝을 지나쳐 튕기는데
   그때 .tscene 바탕(#DCCBA4)이 드러나 거리가 끊겨 보였습니다.
     overscroll-behavior-x:contain  끝에서 안 튕깁니다
     scroll-snap                    첫 칸과 끝 칸에 붙습니다
   바탕도 거리 흙빛으로 바꿔, 혹 드러나도 안 튑니다. */
.tscene{overflow-x:auto;overflow-y:hidden;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;
  overscroll-behavior-x:contain;
  scroll-snap-type:x proximity;
  border:1px solid var(--line);border-radius:10px;background:#6B5A42;
  position:relative}
/* 첫 칸과 끝 칸에만 붙입니다 — 가운데까지 붙이면 밀 때 덜컹입니다. */
.tscene .trow>*:first-child{scroll-snap-align:start}
.tscene .trow>*:last-child{scroll-snap-align:end}
.tscene::-webkit-scrollbar{display:none}
.tscene::-webkit-scrollbar{display:none}

/* 배경은 좌우로 되풀이됩니다. 길도 좌우로 이어 붙습니다. */
/* ── 깊이 ──────────────────────────────────
   재 보니 앞이 뒤보다 밝았습니다 — 나무 켜 92, 마당·길 96.
   가까울수록 어둡고 진해야 깊이가 생기는데 맨 앞에서 거꾸로 갔습니다.
   아래를 눌러 앞이 가장 어둡게 만듭니다(.16 → .46, 마디도 넷으로). */
.tfog{position:absolute;inset:0;pointer-events:none;z-index:1;
  background:linear-gradient(180deg,rgba(237,225,196,.34) 0%,
             rgba(237,225,196,0) 34%,rgba(58,46,34,.10) 58%,
             rgba(52,40,28,.34) 80%,rgba(38,29,19,.62) 100%)}
/* ── 빛의 방향 ─────────────────────────────
   좌우 밝기 차가 어느 켜나 10~14 뿐이라 해가 머리 꼭대기에 있는
   정오처럼 보였습니다. 배경은 새벽인데 앞의 것만 정오였습니다.
   왼쪽 위에서 드는 빛으로 가로로 한 겹 씌웁니다. */
.tlight{position:absolute;inset:0;pointer-events:none;z-index:1;
  /* 배경 다섯 장을 재 보니 해가 **오른쪽**입니다
     (아셴 왼 183 · 오른 200 / 카른 150 · 154 / 항구 167 · 173).
     왼쪽에서 비추면 배경의 빛과 맞부딪혀 서로 지웁니다 —
     실제로 좌우 차가 14 에서 2 로 줄었습니다. */
  background:linear-gradient(255deg,rgba(255,226,170,.26) 0%,
             rgba(255,226,170,.08) 24%,rgba(40,30,20,0) 50%,
             rgba(40,30,20,.20) 80%,rgba(32,24,15,.32) 100%)}
/* ── 맨 앞 켜 ──────────────────────────────
   화면 아래 끝이 그냥 길이었습니다. 깊이는 아주 가까운 것이 있어야 납니다.
   흐릿하고 어두운 띠를 아래 끝에 깔아 「눈앞의 풀숲」 으로 둡니다.
   그림을 새로 안 받고 결로만 냅니다. */
.tfore{position:absolute;left:0;right:0;bottom:-6px;height:52px;z-index:5;
  pointer-events:none;filter:blur(3px);
  background:
    radial-gradient(ellipse 90px 26px at 8% 100%,rgba(34,26,16,.62),transparent 70%),
    radial-gradient(ellipse 120px 20px at 34% 100%,rgba(34,26,16,.52),transparent 72%),
    radial-gradient(ellipse 70px 30px at 58% 100%,rgba(34,26,16,.58),transparent 68%),
    radial-gradient(ellipse 140px 22px at 82% 100%,rgba(34,26,16,.50),transparent 74%),
    linear-gradient(180deg,rgba(34,26,16,0) 0%,rgba(34,26,16,.34) 100%)}
/* ── 마당과 길 ────────────────────────────────
   여태 모두가 한 금 위에 서 있었습니다. 건물도 사람도 물건도요.
   길이 하나뿐이니 「건물 앞을 지나간다」 가 아니라
   「건물 사이에 끼어 있다」 로 보였습니다.

   두 켜로 가릅니다.
     뒤   마당 — 건물이 앉는 자리. 다져진 흙
     앞   길   — 사람과 물건이 다니는 자리. 돌이 깔림

   건물은 --yard 만큼 올라가 앉고, 사람과 물건은 길 위에 그대로 섭니다.
   사이에 마당 끝선을 옅게 그어 두 켜가 눈으로도 갈립니다. */
/* 길 윗변이 자로 그은 듯 떨어져 마당과 갈라져 보였습니다.
   위쪽만 흐려 마당으로 스미게 합니다. */
.troad{position:absolute;left:0;right:0;bottom:0;height:var(--yard);z-index:1;
  pointer-events:none;
  background-image:var(--road,none);background-repeat:repeat-x;
  /* 시트를 줄 수만큼 세로로 늘려 놓고 그 줄만 보이게 밀어 올립니다.
     --yard 로 미는 것이 핵심입니다 — 띠 높이가 곧 한 줄이므로
     숫자를 따로 적으면 마당 두께를 고칠 때 여기가 어긋납니다. */
  background-size:auto calc(var(--roadn,1) * 100%);
  background-position:0 calc(var(--roadrow,0) * var(--yard) * -1);
  opacity:.95;
  -webkit-mask-image:linear-gradient(180deg,transparent 0%,#000 26%,#000 100%);
  mask-image:linear-gradient(180deg,transparent 0%,#000 26%,#000 100%)}
/* ── 나무가 선 자리의 아지랑이 ────────────────
   나무 밑동이 그냥 벌판 한가운데에 놓이면 붙여넣은 것으로 보입니다.
   그 높이에 옅은 띠를 하나 깔아 밑동이 땅에 스미게 합니다.
   먼 것일수록 흐린 결이라, 위로 갈수록 짙어집니다. */
/* 나무 밑동이 서는 자리에 깔려야 합니다 — 벌판 한가운데 놓이면
   붙여넣은 것으로 보입니다. 앞 켜가 118 로 내려와 함께 내립니다(v1.05). */
.thaze{position:absolute;left:0;right:0;bottom:122px;height:78px;z-index:1;
  pointer-events:none;
  background:linear-gradient(180deg,
    rgba(226,214,186,.00) 0%, rgba(226,214,186,.26) 46%,
    rgba(226,214,186,.30) 78%, rgba(226,214,186,.00) 100%)}
/* 마당 — 길 위쪽으로 한 뼘. 건물이 여기 앉습니다. */
.tyard{position:absolute;left:0;right:0;bottom:var(--yard);height:46px;z-index:1;
  pointer-events:none;
  background:linear-gradient(180deg,rgba(74,58,38,0) 0%,rgba(74,58,38,.16) 62%,
             rgba(48,38,24,.30) 100%)}
/* 마당이 끝나고 길이 시작되는 금. 바짝 긋지 않고 흐리게 둡니다. */
/* 또렷한 금 한 줄을 그어 뒀더니 마당과 길이 **두 장의 판**으로 보였습니다.
   건물은 위 판에, 우물과 사람은 아래 판에 붙어 있는 꼴이었습니다.
   금을 지우고 위아래로 스미는 그늘만 남깁니다. */
.tedge{position:absolute;left:0;right:0;bottom:calc(var(--yard) - 14px);
  height:30px;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(48,38,24,0) 0%,rgba(48,38,24,.20) 46%,
             rgba(48,38,24,.10) 72%,rgba(48,38,24,0) 100%)}

/* 줄이 스스로 가로로 스크롤하면 넘김 손짓을 통째로 삼킵니다 —
   손가락이 거리에 닿아 있는 한 폭이 안 넘어갔습니다.
   한 폭에 셋까지만 세우고 줄은 안 스크롤합니다.

   .tscene 안으로 묶어 둡니다 — 타이틀 화면의 단추 줄도 이름이 trow 입니다.
   묶지 않으면 position:absolute 가 그쪽까지 먹어 제목 위로 단추가 겹칩니다.
   실제로 v5.01~5.09 에서 그랬습니다. */
/* 줄 하나가 곧 길입니다. width:max-content 라 안에 든 만큼 길어집니다 —
   inline-block 은 화면 폭에서 멈춰 버려 밀리지 않았습니다.
   사이는 건물마다 다릅니다(margin-right) — gap 으로 고르게 두면 담장이 됩니다. */
/* 290 → 620 → 590 → 화면에 맞춤.
   590 으로 박아 두니 창이 위아래로 밀렸습니다. 마을을 보러 들어왔는데
   거리를 보려고 또 밀어야 했습니다.

   창 안에서 거리 말고 차지하는 것이 218px 입니다 —
   안쪽 여백 32 · 머리띠 60 · 제목 30 · 한 줄 24 · 보관할 것 44 · 밀라는 줄 28.
   창은 화면의 84% 이므로 84vh - 218px 이 거리에 남는 자리입니다.

   박아 두지 않고 화면에 맞춥니다. 작은 기기(SE)에서는 342px,
   큰 기기에서는 585px 까지 저절로 벌어집니다.
   윗도리는 480px — 그보다 커지면 마을이 화면을 잡아먹습니다. */
/* ── 땅에 앉는 금 하나 ─────────────────────────
   여태 셋이 제각기 놀았습니다. 건물은 아래 여백 42 + 마당 64 만큼 올라앉고,
   길은 바닥에서 64px 이라, 건물 밑변(y374)과 길 윗변(y416)이 42px 떴습니다.
   --gnd 로 묶고 0 으로 둡니다. 서는 것은 다 이 금에 발을 붙입니다. */
.tscene .trow{--yard:64px;--gnd:0px;position:relative;
  height:min(480px, max(320px, calc(84vh - 218px)));
  display:flex;align-items:flex-end;gap:0;
  /* 아래 여백 42px 이 건물만 밀어 올려, 건물 밑변(y374)과
     길 윗변(y416)이 42px 떠 있었습니다. --gnd 로 묶어 0 으로 둡니다. */
  /* 양끝 여백이 32px 뿐이라 첫 건물과 끝 건물이 창에 딱 붙어
     잘린 듯 보였습니다 — 한 칸 몫을 띄웁니다(v1.10). */
  padding:0 44px var(--gnd);overflow:visible;
  width:max-content;min-width:100%;box-sizing:border-box;
  /* background-size 를 여기 두면 townBg 가 넘긴 값(500% calc(100%+150px))을
     덮어써서 **하늘이 아니라 아래가 잘립니다**.
     자르기는 townBg 가 정합니다 — 여기서는 되풀이만 말합니다(v5.79). */
  background-repeat:repeat-x}
/* pan-x 를 걸면 그 위에서 창을 위아래로 못 굴립니다 —
   가로 손짓은 bindScene 이 알아서 가로채므로 세로만 열어 둡니다. */
/* 뒤 켜는 작고 높고 흐리게 — 거리가 깊어 보입니다. */
/* margin-bottom 으로 마당에 앉힙니다 — 길 위로 --yard 만큼 올라갑니다. */
.tb{margin-bottom:var(--yard);position:relative;z-index:2;flex:0 0 auto;display:flex;flex-direction:column;
  align-items:center;gap:0;background:none;border:0;font:inherit;cursor:pointer;
  padding:0;transform:scale(var(--ts,1)) translateY(calc(var(--tu,0px) * -1));
  transform-origin:bottom center;opacity:var(--to,1);
  filter:saturate(calc(0.45 + var(--to,1) * 0.55))}
/* 간판이 지붕에 바짝 붙어 있었습니다 — 사이가 2+3=5px 뿐이었고,
   .tb 가 scale() 을 먹으므로 뒷켜에서는 4px 로 더 줄었습니다. */
.tsign{display:block;padding:3px 8px;border-radius:5px;max-width:100%;
  margin-bottom:10px;
  overflow:hidden;text-overflow:ellipsis;
  background:rgba(244,235,214,.94);border:1px solid var(--brass);color:var(--brass);
  font-size:11.5px;white-space:nowrap;position:relative;z-index:3;
  box-shadow:0 1px 4px rgba(30,24,16,.3)}
.tbody{display:grid;place-items:end center;margin-top:0}
.tbi{display:block;background-repeat:no-repeat;pointer-events:none;
  filter:drop-shadow(0 4px 6px rgba(30,24,16,.4))}

.tb:active .tbody{filter:brightness(1.08)}
.tb.gone{opacity:.42}
.tb.gone .tsign{border-style:dashed;color:var(--mute)}
.tb.gone .tbody{background:none;border-style:dashed}

/* ── 뒤에 선 나무 ─────────────────────────────
   거리가 허전했습니다. 건물과 사람 사이에 하늘밖에 없었습니다.

   흐름 안에 끼우지 않고 켜 하나를 따로 깝니다 — 흐름에 넣으면
   나무가 길 폭을 늘려 거리가 그만큼 길어집니다. 배경은 폭을 안 늘려야 합니다.
   자리는 몫(%)으로 잡습니다. .trow 가 max-content 라 폭이 정해진 뒤에 놓입니다. */
/* ── 하늘 (v6.34) ────────────────────────────
   나무(z1)보다도 뒤에 둡니다. 배경 그림 바로 위에서 아주 느리게 흘러야
   「지나가는 구름」 이 됩니다 — 나무 흔들림(7~9.8초)과 결이 겹치면
   둘 다 안절부절못해 보입니다. 한 바퀴에 삼사 분을 씁니다. */
/* 하늘 자리는 **지평선 위**입니다. 62% 로 두었더니 구름이 산과 물 위로
   내려와 지평선과 건물을 가렸습니다 — 32% 로 올립니다(v6.34). */
/* **overflow:hidden 이 구름을 32% 선에서 칼로 잘랐습니다**(v1.06) —
   화면에 가로선이 죽 그어져 배경이 두 조각으로 보였습니다.
   상자를 넓게 두고 **밑을 흐려 사라지게** 합니다 — 자르지 않습니다.
   구름 자리(--cy)가 상자 안쪽 몫이므로 높이가 바뀌면 그 값도 함께 줄입니다. */
/* ── 마을 끝에 갈색이 보이던 것 (v1.25) ──────────
   구름은 하늘 칸을 -10~110% 에 흩어 놓고 제 폭의 240% 까지 흘러갑니다.
   하늘 켜가 `overflow:visible` 이라 **구름이 거리 밖으로 삐져나갔고**,
   `.tscene` 이 그 삐져나간 만큼까지 밀리는 자리로 셌습니다. 그래서 거리
   끝을 지나 밀면 배경도 길도 없는 자리 — `.tscene` 의 바탕인
   흙빛(#6B5A42) 이 드러났습니다.

   **하늘 켜를 직접 자르면 안 됩니다.** v1.06 에 그렇게 했다가 62% 선에서
   칼로 자른 가로줄이 죽 그어져 배경이 두 조각으로 보였습니다 —
   밑을 흐려 사라지게 하는 것이 그 자리의 결입니다.

   그래서 **자르는 상자를 하나 밖에 둡니다.** 좌우는 거리 폭에서 자르고,
   위아래는 거리 전체 높이라 구름이 이미 마스크로 사라진 뒤입니다. */
.tskyclip{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0;
  pointer-events:none;overflow:hidden}
.tsky{position:absolute;left:0;right:0;top:0;height:62%;z-index:0;
  pointer-events:none;overflow:visible;
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 62%,transparent 96%);
  mask-image:linear-gradient(180deg,#000 0%,#000 62%,transparent 96%)}
.tcloud{position:absolute;top:var(--cy,10%);
  animation:cdrift var(--cd,240s) linear infinite;
  will-change:transform}
@keyframes cdrift{from{transform:translateX(-40%)}to{transform:translateX(240%)}}
@media (prefers-reduced-motion:reduce){.tcloud{animation:none}}
.ttrees{position:absolute;left:0;right:0;bottom:0;top:0;z-index:1;
  pointer-events:none;overflow:hidden}
/* 채도를 .62 로 빼고 밝기를 올려 두었더니 나무가 배경에 묻혔습니다.
   빛깔을 되살리고 조금 눌러 무게를 줍니다. */
.ttree{position:absolute;bottom:var(--tb,34px);transform:translateX(-50%);
  opacity:var(--tto,.85);filter:saturate(.94) brightness(.92)
    drop-shadow(0 5px 10px rgba(30,24,16,.42))}
/* ── 흔들림 ───────────────────────────────────
   아주 조금만 움직입니다. 크게 흔들면 종이 인형처럼 보입니다.
   나무는 켜마다 늦춰 한꺼번에 안 흔들리게 합니다. */
@keyframes tsway{0%,100%{transform:translateX(-50%) rotate(-.5deg)}
                 50%    {transform:translateX(-50%) rotate(.6deg)}}
.ttree{transform-origin:50% 100%;animation:tsway 7s ease-in-out infinite}
.ttree:nth-child(3n+2){animation-duration:8.5s;animation-delay:-2.2s}
.ttree:nth-child(3n)  {animation-duration:9.8s;animation-delay:-4.6s}
@keyframes tswayo{0%,100%{transform:rotate(-.7deg)}50%{transform:rotate(.8deg)}}
.tobj[data-k="linen"] .spr,.tobj[data-k="netrack"] .spr{
  transform-origin:50% 12%;animation:tswayo 5.5s ease-in-out infinite}
@media (prefers-reduced-motion:reduce){
  .ttree,.tobj .spr,.tdp[data-k="lanthook"]::after{animation:none}}
/* ── 말풍선 ───────────────────────────────────
   사람마다 여덟 줄씩 적어 두고 대화창을 열어야만 보였습니다.
   밀다 멈추면 그 자리 사람이 한마디 합니다. */
.tbub{position:absolute;left:50%;bottom:100%;transform:translateX(-50%);
  margin-bottom:8px;z-index:5;pointer-events:none;
  /* 말풍선이 사람(73px) 안에 갇혀 「무기는 / 손에 맞는 / 것이」 처럼
     잘게 끊어졌습니다. max-width 만으로는 안 됩니다 —
     max-content 로 제 길이를 잡고 min-width 로 바닥을 깝니다(v5.79).

     230px 은 무대(440px)의 절반이 넘어 **건물 한 채를 통째로 덮었습니다.**
     실기로 재니 치료소의 문과 신전의 왼쪽 기둥이 가려졌습니다.
     180 으로 줄입니다 — 거리 대사 204줄이 평균 25자, 가장 긴 것이 39자라
     한 줄에 열다섯 자면 평균 두 줄, 가장 긴 것도 세 줄입니다(v6.09).

     바탕도 조금 비칩니다. 가려도 뒤가 보이면 덮은 것으로 안 읽힙니다. */
  width:max-content;min-width:130px;max-width:180px;
  padding:6px 10px;border-radius:9px;
  background:rgba(244,235,214,.90);border:1px solid var(--brass);
  color:#3A2E22;font-size:10.5px;line-height:1.45;text-align:center;
  white-space:normal;word-break:keep-all;overflow-wrap:normal;
  box-shadow:0 2px 8px rgba(30,24,16,.35);
  opacity:0;animation:tbubIn .22s ease-out forwards}
.tbub::after{content:'';position:absolute;left:50%;top:100%;
  transform:translateX(-50%);border:5px solid transparent;
  border-top-color:var(--brass)}
@keyframes tbubIn{from{opacity:0;transform:translateX(-50%) translateY(4px)}
                  to{opacity:1;transform:translateX(-50%) translateY(0)}}
@media (prefers-reduced-motion:reduce){.tbub{animation:none;opacity:1}}
/* ── 땅에 드리우는 그림자 ─────────────────────
   여태 drop-shadow 뿐이었습니다. 그건 그림 뒤로 번지는 것이라
   물건이 땅에 붙지 않고 떠 있는 것처럼 보였습니다.
   발밑에 납작한 타원을 하나 깔면 그제야 땅을 딛습니다.

   ::before 로 답니다 — 예순 군데 마크업을 고치지 않아도 됩니다.
   .tb 는 scale() 을 먹으므로 뒷켜에서는 그림자도 함께 작아집니다. */
.tb::before,.tobj::before,.tnpc::before,.tdp::before{
  content:'';position:absolute;left:50%;z-index:0;pointer-events:none;
  /* 빛이 오른쪽 위에서 드니 그림자는 왼쪽으로, 그리고 **뒤로** 눕습니다.
     앞으로 눕혀 두었더니 그림자가 길을 덮어
     건물이 제 그림자를 밟고 선 꼴이었습니다(v5.65). */
  /* -64% 는 **그림자 제 폭**의 64% 라, 폭 249px 짜리가 160px 이나
     왼쪽으로 밀려 몸에서 뚝 떨어졌습니다.
     가운데(-50%)에 두고 기울기로만 뒤로 눕힙니다. */
  transform:translateX(-50%) skewX(22deg);
  /* 뒤로 가면 몸에 가려 덜 보이므로 더 진하게 깝니다(.74 → .88).
     가운데를 눌러 두고 가장자리는 흐리게 풀어 땅에 스미게 둡니다. */
  background:radial-gradient(ellipse at center,
    rgba(18,13,7,.88) 0%, rgba(18,13,7,.56) 46%,
    rgba(18,13,7,.22) 66%, rgba(18,13,7,0) 80%)}
/* **그림보다 넓게, 조금 아래로.** 처음에 76% 로 좁게 깔았다가
   건물(132px) 밑에 통째로 숨어 하나도 안 보였습니다.
   실루엣 밖으로 삐져나와야 눈에 들어옵니다. */
/* bottom 이 양수면 발보다 위 — 곧 뒤입니다.
   폭은 그대로 넓게 둡니다. 몸에 가려도 옆으로는 삐져나와야 보입니다. */
/* bottom 은 그림자 **가운데**의 높이입니다. 높이의 절반보다 크면
   아랫변이 발에서 떠 버립니다 — 6px 에 높이 30 이면 발보다 9px 위였습니다.
   절반보다 조금 작게 두어 발에 걸치고 뒤로 뻗게 합니다. */
.tb::before  {width:126%;height:34px;bottom:12px}
/* ── 샛길을 걷었습니다 (v5.96) ─────────────────
   문에서 길까지 밟아 다져진 자국을 하나씩 냈던 것입니다(v5.53~v5.93).
   결을 셋으로 갈라 길과 톤까지 맞췄는데도(붉은기 차이 -0.8~-7.1)
   거리에서는 **건물마다 달린 부챗살**로 읽혔습니다 —
   길이 아니라 무대 조명처럼 보입니다.

   ::after 는 이제 비어 있습니다. 다시 넣으실 일이 있으면
   v5.95 의 zip 에 그림(paths.png)과 도구(path_pack.py)가 있습니다. */
.tobj::before{width:132%;height:22px;bottom:8px}
.tnpc::before{width:158%;height:18px;bottom:6px}
/* 문 앞 물건은 작으므로 그림자도 얕게 깝니다. 높이의 절반보다
   조금 작은 자리에 두어 밑변이 발에 걸치게 합니다(4 < 14/2). */
.tdp::before{width:128%;height:14px;bottom:4px}
.tb .tbody,.tobj>i,.tnpc .npcart,.tdp>i{position:relative;z-index:1}
/* ── 갈 수 있는 길 ────────────────────────────
   길 위에 놓이고 천천히 숨을 쉽니다. 누르면 그리로 걷습니다. */
.pcar{position:absolute;transform:translate(-50%,-50%);z-index:14;
  width:34px;height:34px;padding:0;border:0;background:none;cursor:pointer;
  animation:pcarb 2.4s ease-in-out infinite}
/* SVG 로 그리다가 그림으로 갈았습니다(v5.73).
   그림 자리는 코드에서 넘깁니다 — 시트가 없으면 이모지로 넘어갑니다. */
/* 회전을 바깥 <i> 에 걸었더니 안 돌았습니다 —
   spr() 이 만든 .spr 이 제 크기를 인라인으로 들고 앉아
   바깥 껍데기가 하는 일이 화면에 안 나타났습니다.
   **그림 자체(.spr)에 직접 겁니다.** */
.pcar i{display:block;width:100%;height:100%;
  filter:drop-shadow(0 1px 3px rgba(0,0,0,.85))}
.pcar i .spr{display:block;width:100%!important;height:100%!important;
  transform:rotate(var(--ad,0deg));transform-origin:50% 50%}
.pcar:active{transform:translate(-50%,-50%) scale(.88)}
@keyframes pcarb{0%,100%{opacity:.42}50%{opacity:1}}
@media (prefers-reduced-motion:reduce){.pcar{animation:none;opacity:.85}}
/* ── 싸움이 붙는 순간 ─────────────────────────
   전투창이 아무 예고 없이 툭 떴습니다. 한 박자를 둡니다. */
.dstart{position:fixed;left:0;right:0;top:38%;z-index:60;pointer-events:none;
  text-align:center;font-size:26px;font-weight:700;letter-spacing:.06em;
  color:#F3E7C8;text-shadow:0 2px 10px rgba(0,0,0,.8),0 0 26px rgba(226,101,58,.5);
  animation:dstart 1s ease-out forwards}
.dstart.amb{color:#F0C0A8;text-shadow:0 2px 10px rgba(0,0,0,.85),0 0 30px rgba(226,101,58,.75)}
@keyframes dstart{
  0%  {opacity:0;transform:scale(.86)}
  18% {opacity:1;transform:scale(1.04)}
  70% {opacity:1;transform:scale(1)}
  100%{opacity:0;transform:scale(1.02)}}
/* ── 배웠습니다 ───────────────────────────────
   기술과 마법이 늘 때 토스트 한 줄로만 알렸습니다.
   한 판에 여러 줄이 겹치면 스쳐 지나갑니다 —
   무엇을 익혔는지는 한 박자 두고 크게 보여 줍니다. */
.learnb{position:fixed;left:0;right:0;top:34%;z-index:60;pointer-events:none;
  text-align:center;animation:learnb 1.8s ease-out forwards}
.learnb .lk{display:block;font-size:12px;letter-spacing:.22em;
  color:#9BC7D9;text-shadow:0 2px 8px rgba(0,0,0,.8)}
.learnb .ln{display:block;margin-top:4px;font-size:24px;font-weight:700;
  color:#F3E7C8;text-shadow:0 2px 10px rgba(0,0,0,.85),0 0 26px rgba(155,199,217,.55)}
.learnb .ld{display:block;margin-top:5px;font-size:11.5px;color:#CFC3A4;
  text-shadow:0 1px 6px rgba(0,0,0,.8)}
@keyframes learnb{
  0%  {opacity:0;transform:translateY(8px) scale(.94)}
  14% {opacity:1;transform:translateY(0) scale(1.03)}
  74% {opacity:1;transform:translateY(0) scale(1)}
  100%{opacity:0;transform:translateY(-6px) scale(1)}}
@media (prefers-reduced-motion:reduce){.learnb{animation:none;opacity:1}}
/* ── 먼저 덤비는 것 ───────────────────────────
   「먼저 덤빕니다」 라고 글로만 적혀 있었습니다.
   몸에 붉은 테를 두르고 숨을 쉬게 합니다 — 눈이 먼저 알아봅니다.
   알아보는 동안에는 숨이 가빠집니다. */
/* 숨결이 곧 눈입니다 — 잘 알아보는 것일수록 가쁩니다(--aggb).
   눈으로 재는 것과 실제 굴림이 같은 값에서 나와야 거짓말이 안 됩니다. */
.pfmob.agg .zmb{filter:drop-shadow(0 4px 6px rgba(0,0,0,.5))
  drop-shadow(0 0 3px rgba(226,101,58,.95)) drop-shadow(0 0 7px rgba(226,101,58,.6));
  animation:aggBreath var(--aggb,2.2s) ease-in-out infinite}
.pfmob.agg.spot .zmb{animation-duration:.42s}
@keyframes aggBreath{
  0%,100%{filter:drop-shadow(0 4px 6px rgba(0,0,0,.5))
    drop-shadow(0 0 2px rgba(226,101,58,.55)) drop-shadow(0 0 5px rgba(226,101,58,.28))}
  50%    {filter:drop-shadow(0 4px 6px rgba(0,0,0,.5))
    drop-shadow(0 0 5px rgba(226,101,58,1)) drop-shadow(0 0 12px rgba(226,101,58,.7))}}
@media (prefers-reduced-motion:reduce){.pfmob.agg .zmb{animation:none}}
/* 길가에 놓인 것. 누를 수 없고 사람보다 뒤, 건물보다 앞입니다. */
/* ── 띠 안으로 들였습니다 (v5.92) ─────────────
   아래 여백이 음수(-10)라 밑변이 띠 밖으로 나가 있었습니다.
   `.tscene` 이 `overflow-y:hidden` 이라 거기서 잘립니다 —
   발밑에 깔아 둔 타원 22px 중 20px 만 남았습니다.

   길은 바닥에서 64px 입니다. 그 안에 세우면 잘릴 것이 없습니다.
   차례는 그대로 둡니다 — 사람(4)이 가장 앞, 물건(10)이 그 뒤,
   문 앞 물건(59), 건물(64) 순으로 뒤로 물러납니다. */
.tobj{position:relative;flex:0 0 auto;display:block;margin:0 18px 10px 0;z-index:3;
  pointer-events:none;opacity:.92;
  filter:drop-shadow(0 3px 4px rgba(30,24,16,.45))}
/* ── 문 앞에 놓인 것 ──────────────────────────
   흐름 밖에 둡니다 — 흐름에 넣으면 건물 폭이 늘어 간판이 밀립니다.
   .tb 안에 있으므로 켜(--ts·--to)를 건물과 함께 먹습니다.
   뒷켜 건물의 물건은 저절로 작고 흐려집니다.

   bottom 이 음수라 건물 밑선보다 조금 앞(아래)에 섭니다 —
   같은 금에 두면 벽에 붙어 서서 마당이 안 보입니다. */
.tdp{position:absolute;bottom:-5px;transform:translateX(-50%);z-index:2;
  pointer-events:none;
  /* 빛이 오른쪽 위에서 드니 드리우는 빛도 왼쪽으로 1px 눕습니다.
     길가 물건(0 3px)보다 얕게 — 작은 것이 크게 뜨면 안 붙어 보입니다. */
  filter:drop-shadow(-1px 2px 3px rgba(30,24,16,.42))}
.tdp>i{display:block}
/* 등불만 빛을 냅니다. 흔들지 않고 숨만 쉽니다 — 크게 깜빡이면
   거리에서 눈이 거기로만 갑니다. 유리가 깨진 등이라 옅게 둡니다. */
.tdp[data-k="lanthook"]::after{content:'';position:absolute;z-index:0;
  left:26%;top:26%;width:54%;height:34%;transform:translate(-50%,-50%);
  pointer-events:none;border-radius:50%;
  background:radial-gradient(circle,rgba(255,198,116,.60) 0%,
    rgba(255,186,96,.26) 44%,rgba(255,178,88,0) 72%);
  animation:tdplit 5.2s ease-in-out infinite}
@keyframes tdplit{0%,100%{opacity:.72}50%{opacity:1}}
/* 사람은 건물 사이에 서서 길 쪽으로 내려옵니다 — 늘 맨 앞 켜입니다.
   -18 이던 것을 4 로 올렸습니다. 발이 18px 잘리고 있었고
   발밑 그림자 18px 은 6px 만 보였습니다 — 한 번도 제 일을 못 했습니다. */
.tnpc{position:relative;flex:0 0 auto;background:none;border:0;padding:0;font:inherit;
  cursor:pointer;display:block;margin:0 22px 4px 0;z-index:4;
  filter:drop-shadow(0 4px 6px rgba(30,24,16,.5))}
.tnpc .npcart{display:block}
/* 머리 위(top:-6px)에 두었더니 **사람 얼굴을 가렸습니다** —
   그림이 커서 표가 이마에 얹혔습니다(v1.10).
   가슴께(48%)로 내리고 붉은빛에서 **노란빛**으로 바꿉니다. */
.tbang{position:absolute;top:48%;left:50%;transform:translate(-50%,-50%);
  width:21px;height:21px;border-radius:50%;
  background:linear-gradient(180deg,#F6D77A,#D9A72E);
  border:1px solid #8A6614;color:#3A2A06;
  font-size:13px;font-weight:700;line-height:1;
  display:grid;place-items:center;z-index:5;
  box-shadow:0 2px 5px rgba(30,24,16,.5)}
/* 폭 이름·형편 글씨는 걷었습니다. 그림 위에 글자가 겹겹이 얹혀
   거리가 안 보였습니다. 간판만 남깁니다. */
/* 한 번 밀면 사라지는 안내 */
.thint{text-align:center;margin-top:7px;font-size:10.5px;color:var(--mute);
  letter-spacing:.04em;transition:opacity .3s}
/* ── 첫 걸음 안내 (v6.40) ──────────────────────
   촌장에게 `!` 는 붙는데 **거기까지 어떻게 가는지**를 안 알려 줬습니다.
   처음 여는 사람은 지도만 보고 무엇을 눌러야 할지 모릅니다.
   지금 할 차례 하나만 한 줄로 적습니다 — 다 하면 사라집니다. */
.tutbar.go{cursor:pointer;border-color:var(--brass)}
.tutbar.go .tgo{margin-left:auto;color:var(--brass);font-size:18px;line-height:1}
.tutbar{margin:8px 10px 0;padding:9px 12px;border-radius:12px;
  background:linear-gradient(180deg,rgba(201,164,76,.16),rgba(201,164,76,.07));
  border:1px solid rgba(201,164,76,.42);
  display:flex;align-items:center;gap:9px;font-size:12px;line-height:1.45}
.tutbar b{color:var(--gold);font-weight:600}
.tutbar .tn{flex:none;width:20px;height:20px;border-radius:50%;
  background:var(--gold);color:#241a09;font-size:11px;font-weight:700;
  display:flex;align-items:center;justify-content:center}
.tutbar .tx{flex:1;min-width:0}
.tutbar .tm{display:block;color:var(--mute);font-size:10.5px;margin-top:2px}
/* ── 처음 나설 사람 고르기 ─────────────────── */
.mkrow{height:auto!important;padding:10px 14px!important;align-items:flex-end;gap:10px}
.mkone{flex:0 0 auto;background:none;border:2px solid transparent;border-radius:12px;
  padding:4px;cursor:pointer;opacity:.5;transition:opacity .2s,border-color .2s}
.mkone.on{opacity:1;border-color:var(--brass);background:rgba(201,164,76,.12)}
.mkone .npcart{display:block}
.mkdots{margin-top:8px}
.mkdots i{width:7px;height:7px;border-radius:50%;background:rgba(120,100,70,.3);
  cursor:pointer}
.mkdots i.on{background:var(--brass);transform:scale(1.25)}
/* 이름 적는 칸. v5.18 에 .tin 이라 지었다가 v5.21 에 고쳤습니다 —
   타이틀 화면의 속상자가 이미 .tin 이었습니다. 홑 규칙이라 특이도는 졌지만
   width·background·border·radius 는 저쪽에 없어서 그대로 얹혔고,
   제목 화면 한가운데에 종이색 상자가 생겼습니다.
   .trow(v5.10) · faces(v5.18) 와 똑같은 꼴입니다. */
.bossart{margin:2px auto 8px;display:block}
/* ── 밤이 지나갑니다 (v1.72) ─────────────────
   여관에서 쉬면 숫자만 바뀌고 화면은 그대로였습니다. 잠을 잤는데
   아무 일도 안 일어난 것처럼 보였습니다.

   화면을 서서히 덮었다가 걷습니다. **밥은 짧게 한 번 어둑해지고**
   (한 끼 먹고 일어서는 결), **잠은 깊게 덮였다가 아침 빛으로**
   걷힙니다. 글자는 덮개가 가장 짙을 때만 뜹니다. */
#nite{position:fixed;inset:0;z-index:99;pointer-events:none;opacity:0;
  background:#0A0908;display:flex;align-items:center;justify-content:center;
  transition:opacity .5s ease}
#nite.on{opacity:1}
#nite.dawn{background:linear-gradient(180deg,#2A2118 0%,#6B4A22 55%,#C98A3C 100%)}
#nite b{color:#E8DCC0;font-size:15px;letter-spacing:.22em;font-weight:600;
  opacity:0;transition:opacity .45s ease}
#nite.on b{opacity:1}
/* 그림 마을(v1.76). 자리는 그림 위에 얹히고, 이름은 아래쪽에 옅게
   적혀 어디를 누르는지 알려 줍니다 — 누르면 밝아집니다. */
.tpic{position:relative;width:100%;background-size:100% 100%;
  background-repeat:no-repeat;border-radius:12px;overflow:hidden;
  border:1px solid var(--line);margin-bottom:10px}
/* ── 이름표를 건물 밑으로 (v1.80) ─────────────
   네모 **안쪽 아래**에 붙어 있어, 네모가 건물을 덮는 만큼 이름표도
   지붕과 창문 위에 얹혔습니다. 그림에서 가장 볼 만한 데를 가린
   셈입니다.

   네모 **바깥 아래**로 뺍니다 — 건물은 온전히 보이고, 이름은 그
   건물 발치에 놓입니다. */
.tspot{position:absolute;background:transparent;border:0;padding:0;
  display:flex;align-items:flex-end;justify-content:center;cursor:pointer}
.tspot span{position:absolute;top:100%;margin-top:2px}
/* 그림 맨 아래에 걸린 것은 안쪽 위에 답니다 — 밖으로 밀리면
   사람 줄에 가립니다. */
.tspot.up span{top:auto;bottom:100%;margin:0 0 2px}
.tspot span{font-size:12px;font-weight:600;letter-spacing:.04em;color:#FFF6DC;
  background:rgba(14,11,8,.82);border:1px solid rgba(201,164,76,.45);
  border-radius:8px;padding:3px 9px;white-space:nowrap;
  text-shadow:0 1px 2px rgba(0,0,0,.9)}
.tspot:active span{opacity:1;background:var(--brass);color:#1A1510}
/* 사람은 그림 아래에 줄로 섭니다 — 거리에 흩뿌리면 어지럽습니다. */
.tfolk{position:absolute;left:0;right:0;bottom:0;display:flex;gap:6px;
  padding:8px 8px 9px;overflow-x:auto;scrollbar-width:none;
  background:linear-gradient(180deg,rgba(20,16,12,0) 0%,rgba(20,16,12,.78) 42%)}
.tf{position:relative;flex:0 0 auto;background:rgba(20,16,12,.66);
  border:1px solid rgba(201,164,76,.35);border-radius:10px;padding:4px 8px 3px;
  color:#F0EDE4;
  display:flex;flex-direction:column;align-items:center;gap:2px;cursor:pointer}
.tf span{font-size:10px;color:#F0EDE4;white-space:nowrap}
.tf .tbang{position:absolute;top:-5px;right:-4px;background:var(--brass);
  color:#1A1510;border-radius:50%;width:15px;height:15px;font-size:11px;
  font-style:normal;line-height:15px;text-align:center;font-weight:700}
/* 이야기 한 장의 그림 (v2.01) — 세로 2:3, 폭에 맞춰 앉힙니다. */
/* 이야기 한 장 (v2.02) — 가로 16:9. */
.tart{width:100%;aspect-ratio:16 / 9;background-size:100% 100%;
  background-repeat:no-repeat;border-radius:10px;border:1px solid var(--line);
  margin-top:10px}
.prol{width:100%;aspect-ratio:2 / 3;background-size:100% 100%;
  background-repeat:no-repeat;border-radius:12px;border:1px solid var(--line)}
.mkone{position:relative}
/* 고른 것이 무엇인지 그림 아래에 한 마디로 적습니다(v1.56). */
.mkone .mkn{position:absolute;left:0;right:0;bottom:6px;text-align:center;
  font-size:12px;letter-spacing:.08em;color:#F0EDE4;
  text-shadow:0 1px 3px rgba(0,0,0,.85)}
.mkone.on .mkn{color:var(--brass)}
.mkin{width:100%;box-sizing:border-box;padding:11px 13px;border-radius:8px;
  border:1px solid var(--line);background:var(--plate);color:var(--chalk);
  font:inherit;font-size:15px;text-align:center}
.tgrid{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:8px 0 4px}
.tcell{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:3px;text-align:center;padding:9px 5px;min-height:74px;box-sizing:border-box;
  border-radius:0;cursor:pointer;font:inherit;background:var(--plate);
  border:9px solid transparent;
  border-image:var(--btncell,url('assets/btn_cell.png')) 14 fill stretch;
  color:var(--chalk)}
/* ── 못 누름은 한 가지로 (v2.36) ────────────────
   v2.33 에 `.go.fr:disabled` 를 「틀은 그대로 두고 불만 끈다」 로
   바꿨습니다. 부서진 쇠(btn_iron)는 테두리가 실제로 끊겨 있어
   **그려지다 만 것처럼** 보였기 때문입니다.
   그런데 마을 시설 칸(`.tcell.dim`)만 옛 결로 남아, 같은 「지금은
   못 누른다」 가 화면마다 다르게 보였습니다.
   틀은 그대로, 불만 끕니다 — 단추와 같은 자입니다. */
.tcell.dim{filter:grayscale(.72) brightness(.86);opacity:.85}
.tcell.warn{border-color:var(--signal)}
.tcell.dim{opacity:.42;cursor:default}
.tcell .tn{font-size:13px}
.tcell .tm{font-family:'IBM Plex Mono',monospace;font-size:10px;color:var(--mute)}
/* 가방은 다섯 열로 못 박습니다(v1.51) — 자동으로 채우면 화면 폭에
   따라 여섯이 되었다 일곱이 되었다 해서, 같은 물건이 늘 다른 자리에
   있었습니다. 칸도 커져서 손가락이 닿기 좋습니다. */
.bagg{display:grid;grid-template-columns:repeat(5,1fr);gap:7px;margin-bottom:10px}
/* 가방 칸도 격자와 같은 짜임 — 그림 · 이름 · 개수(v2.55) */
.bslot .cn{font-size:8.5px;line-height:1.1;letter-spacing:-.02em;
  word-break:keep-all;text-align:center;margin-top:1px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;max-width:100%;opacity:.85}
.bslot{aspect-ratio:1;border:1px dashed var(--line);border-radius:8px;background:var(--plate);
  position:relative;display:grid;place-items:center}
.bslot.on{border-style:solid;border-color:var(--brass);background:var(--panel);cursor:pointer}
.bslot .bq{position:absolute;right:2px;bottom:0;font-family:'IBM Plex Mono',monospace;
  font-size:9.5px;color:var(--brass)}
.slots{display:flex;gap:8px;margin-bottom:12px}
.slot{flex:1;background:var(--plate);border:1px dashed var(--line);border-radius:9px;
  padding:10px 6px;text-align:center;cursor:pointer}
.slot.on{border-style:solid;border-color:var(--brass);background:var(--panel)}
.slot .sn{font-size:10px;color:var(--mute);margin-top:5px}
/* 슬롯 아래 내구 막대 */
.slot .dbar{margin-top:4px;height:3px;border-radius:2px;background:var(--plate);overflow:hidden}
.slot .dbar i{display:block;height:100%;background:var(--jade)}
.slot .dbar.mid i{background:var(--brass)}
.slot .dbar.low i{background:var(--danger)}

.strow{display:flex;align-items:center;gap:10px;padding:7px 0;border-bottom:1px solid var(--line)}
.strow .k{width:46px;font-size:12px;color:var(--mute)}
.strow .v{font-family:'IBM Plex Mono',monospace;font-size:15px;font-weight:600;width:32px}
.strow .e{font-size:11px;color:var(--mute);flex:1}
.plus{width:26px;height:26px;border-radius:6px;border:1px solid var(--brass);
  background:transparent;color:var(--brass);font-size:15px;cursor:pointer;line-height:1}
.plus:disabled{border-color:var(--line);color:var(--line)}
.mini{height:3px;background:var(--plate);border-radius:2px;overflow:hidden;margin-top:5px}
.mini i{display:block;height:100%;background:var(--brass);
  background-image:repeating-linear-gradient(90deg,rgba(0,0,0,.25) 0 1px,transparent 1px 3px)}
.mini.g i{background:var(--jade)}

nav{position:fixed;bottom:0;left:0;right:0;z-index:30;max-width:480px;margin:0 auto;
  display:flex;background:rgba(8,17,20,.96);backdrop-filter:blur(8px);
  border-top:1px solid var(--line);padding-bottom:var(--padb)}
nav button{flex:1;background:none;border:none;color:var(--mute);padding:9px 0 8px;
  font-family:inherit;font-size:10px;cursor:pointer;display:flex;flex-direction:column;
  align-items:center;gap:3px;letter-spacing:.04em;position:relative}
nav button .ni{font-size:16px;opacity:.7;line-height:1;
  display:grid;place-items:center;width:24px;height:24px}
nav button.on{color:var(--brass)} nav button.on .ni{opacity:1}
nav button .badge{position:absolute;top:6px;right:calc(50% - 16px);width:6px;height:6px;
  border-radius:50%;background:var(--signal)}

/* ── 창 ────────────────────────────────────────
   아래에서 올라오는 띠(bottom sheet)였습니다.
   내용이 길 때는 그 편이 맞는데, 창을 여럿 간추리고 나니
   대부분이 반 화면도 안 됩니다. 그때 아래에 붙어 있으면
   위쪽 절반이 통째로 빈 장막이 됩니다.

   가운데 뜨는 팝업으로 바꿉니다. 짧으면 짧은 대로 뜨고,
   길면 84vh 안에서 스스로 스크롤합니다. */
/* ── 창을 화면 가득 (v1.77) ────────────────────
   창마다 크기가 제각각이라 열 때마다 화면이 들썩였습니다 — 짧은 창은
   가운데 떠 있고 긴 창은 위아래로 넘쳤습니다. 폰에서는 **늘 같은
   자리에 같은 크기**로 서는 편이 눈이 편합니다.

   창을 화면 가득 채우고, **뒤로 가기를 맨 아래에 붙박이로** 둡니다 —
   길게 밀어 내려가지 않아도 늘 손가락 밑에 있습니다. */
.scrim{position:fixed;inset:0;background:rgba(4,10,12,.72);z-index:50;
  display:flex;align-items:center;justify-content:center;
  padding:14px;animation:fade .18s}
@keyframes fade{from{opacity:0}to{opacity:1}}
.scrim{align-items:stretch;padding:0}
.sheet{width:100%;max-width:520px;margin:0 auto;border-radius:0;
  height:100dvh;overflow-y:auto;-webkit-overflow-scrolling:touch;
  display:flex;flex-direction:column;
  /* 창이 화면 꼭대기에서 시작해 **제목이 노치에 물렸습니다**(v1.78).
     머리띠는 `--padt` 를 쓰는데 창은 안 쓰고 있었습니다.
     안전 여백에 50px 을 더해 내립니다 — 노치가 없는 기기에서도
     제목 위에 숨 쉴 자리가 생깁니다. */
  /* v1.91 — 50px 로는 아직 창이 높아 100px 로 내립니다.
     안전 여백에 더하는 꼴이라 노치 없는 기기에서도 그만큼 남습니다. */
  padding:calc(var(--padt,0px) + 100px) 14px calc(12px + var(--padb,0px));
  background:var(--panel);border:1px solid var(--line);
  border-image:var(--panelimg,none) 110 fill stretch;
  box-shadow:0 18px 48px rgba(0,0,0,.45);
  animation:pop .2s cubic-bezier(.2,.9,.3,1)}
/* ── 가운데 정렬을 되돌립니다 (v1.82) ───────────
   v1.79 에 남는 자리를 위아래로 나눴더니, **짧은 창이 화면 한복판까지
   밀려 내려갔습니다** — 창고·여관·치료소가 위쪽 절반을 통째로 비워
   두고 아래에 붙어 있었습니다. 읽을 것을 찾아 눈이 내려가야 했습니다.

   위에서부터 시작합니다. 노치를 비키고 50px 아래에 첫 줄이 섭니다.
   나가기 줄만 맨 아래에 붙박입니다. */
/* ── 나오는 줄이 안 뜹니다 (v1.77 · v2.38) ────────
   「길게 밀어 내려가지 않아도 늘 손가락 밑에 있게」 붙박이로 두었는데,
   그 대가로 **창을 굴리는 동안 글 위에 떠서** 밑에 깔린 줄을
   가렸습니다. 반투명을 걷고(v2.28) 잠근 창을 풀고(v2.28) 창 밖의
   줄까지 덮게 했는데(v2.36) — **뜬다는 것 자체**가 남아 있었습니다.

   글과 함께 굴러갑니다. 창을 나가는 길은 오른쪽 위 ✕ 가 늘 있고,
   마지막 줄이 가려지는 것보다 한 번 더 굴리는 편이 낫습니다. */
/* ── 붙박이로 두되 안 가립니다 (v2.41) ───────────
   v1.77 붙박이 → v2.36 정적 → v2.41 다시 붙박이.
   두 번 뒤집힌 자리라 까닭을 적어 둡니다.

     붙박이면   늘 손가락 밑에 있지만 굴리는 동안 글 위에 떠서 가림
     정적이면   안 가리지만 맨 아래까지 굴려야 나갈 수 있음

   **둘 다 됩니다.** 붙박이로 두고, 창 안쪽 바닥에 줄 높이만큼 자리를
   비워 둡니다(`padding-bottom`) — 마지막 글이 그 자리 위에서 끝나니
   무엇도 줄 밑으로 들어가지 않습니다.
   높이가 바뀌면 자리도 바뀌어야 하므로 `--barh` 로 묶습니다. */
/* ── 자리를 비우면 되레 틈이 생겼습니다 (v2.41) ───
   창 바닥에 줄 높이만큼 자리를 비우고(`--barh`) 줄이 그만큼 내려가
   앉게 했더니, **짧은 창에서 줄 아래에 빈칸이 남았습니다.**
   음수 자리와 비운 자리가 서로를 상쇄하지 못하고 겹쳤습니다.

   비우지 않습니다. `margin-top:auto` 가 줄을 창 바닥으로 밀고,
   바탕이 불투명하므로 굴러 올라온 글은 줄 뒤로 숨습니다 —
   가리는 것이 아니라 **덮는 것**이고, 줄은 어차피 맨 끝입니다. */
.sheet .backbar,.sheet .sbar{position:sticky;bottom:0;z-index:6;
  margin:auto -14px calc(-12px - var(--padb,0px));
  /* 위쪽 auto 는 나가기 줄만 씁니다 — 내용은 위에서부터 흐릅니다 */
  padding:12px 14px calc(8px + var(--padb,0px));
  /* ── 밑에 깔린 글이 비쳤습니다 (v2.28) ──────────
     띠의 위 절반이 투명이라, 상점처럼 긴 창에서는 가방 줄이 나무틀
     단추 옆으로 비쳐 **단추와 글이 겹쳐** 보였습니다.
     열 픽셀만 스미고 그 아래는 덮습니다. */
  background:linear-gradient(180deg,rgba(233,224,196,0) 0,var(--panel) 10px)}
/* ── 창 안의 것은 안 쪼그라듭니다 (v2.36) ────────
   `.sheet` 는 세로 flex 입니다. flex 칸은 **자리가 모자라면 스스로
   줄어듭니다**(flex-shrink 기본 1). 그래서 창고처럼 긴 화면에서
   탭 줄과 격자가 눌려 아래 것에 깔린 것처럼 보였습니다 —
   겹친 것이 아니라 **눌린 것**이었습니다.
   단추만 `flex:0 0 auto` 로 막아 두었는데(`.go`), 나머지가 다
   열려 있었습니다. 창은 어차피 넘치면 굴러가므로 아무것도 안
   줄어들어야 합니다. */
.sheet > *{flex-shrink:0}
.sheet .sbar .sback{width:100%}
/* ── 팝업 낱장 (v2.28) ─────────────────────────
   창은 다 화면 가득입니다(v1.77) — 열 때마다 화면이 들썩이지 않게
   한 결로 세운 것입니다. 다만 **목록에서 하나를 눌러 보는 낱장**은
   그 결이 안 맞습니다. 상점에서 물건 하나를 눌렀을 뿐인데 상점이
   통째로 사라지고, 돌아가려면 나가는 단추를 찾아야 했습니다.

   목록 위에 **얹습니다.** 뒤가 비쳐 「상점 안에서 하나를 들여다보는
   중」 이 그대로 보이고, 사거나 물러나면 목록이 그 자리에 있습니다.
   길이는 내용만큼이라 짧은 낱장이 화면을 다 먹지 않습니다. */
.scrim.pop{align-items:center;justify-content:center;padding:16px}
.sheet.pop{height:auto;max-height:82dvh;border-radius:14px;
  padding:16px 14px calc(10px + var(--padb,0px))}
body.paper .sheet.pop{border-width:26px;padding:4px 0 6px}
/* 짧은 창에서는 붙박일 까닭이 없습니다 — 붙박이면 내용을 덮습니다 */
.sheet.pop .sbar{position:static}
@keyframes pop{from{transform:translateY(2%) scale(.994);opacity:0}to{transform:none;opacity:1}}
/* ── 종이 창 ───────────────────────────────────
   테두리 그림이 있으면 창 안쪽을 종이색으로 뒤집습니다.
   대부분의 부품이 아래 변수를 쓰므로 한 번에 갈아입습니다. */
/* 종이 그림이 붙으면 앱 전체가 종이로 갑니다.
   머리띠만 바꾸면 크림·검정·크림 이 층층이 쌓여 오히려 어수선합니다. */
body.paper{
  --ink:#EDE1C4; --panel:#E6D6B0; --plate:#F1E6CC; --line:#C7AE7E;
  --chalk:#3A2E22; --mute:#6B5B40; --brass:#7A5C18; --signal:#98421A;
  --jade:#256B57; --danger:#98283C; --violet:#57398E;
  background:#EDE1C4; color:#3A2E22}
/* ── 종이 결이 여백을 지우고 있었습니다 (v1.96) ──
   `.sheet` 에 위 여백 100px 을 주었는데 **여기서 `padding:0` 으로
   덮고** 있었습니다 — `body.paper` 가 더 세서, 두 판을 내렸는데도
   화면은 그대로였습니다.

   테두리 34px 은 종이 무늬라 그대로 두고, 여백만 되살립니다. */
body.paper .sheet{
  background:none; border-radius:0;
  border-width:34px; border-style:solid; border-color:transparent;
  padding:calc(var(--padt,0px) + 66px) 0 calc(12px + var(--padb,0px)); box-shadow:none}
/* 어두운 화면을 전제로 박아 둔 색들만 따로 되돌립니다 */
body.paper .flog{border-top-color:rgba(58,46,34,.18)}
body.paper .flog .fhead,
body.paper .flog .fl i,
body.paper .chron .cd,
body.paper .strow .gw,
body.paper .talk .who{color:#7A6A4C}
body.paper .flog .fl{color:#4A3D2C}
body.paper .flog .fl b{color:#8A6A1E}
body.paper .flog .fl:last-child,
body.paper .chron .cx,
body.paper .say{color:#3A2E22}
body.paper .chron{border-left-color:rgba(154,122,46,.45)}
body.paper .chron .cr:first-child .cx{color:#2B2118}
body.paper .talk .side.npc .who{color:#5A4A32}
body.paper .talk .who{background:rgba(243,234,211,.85)}
body.paper .mud{background:rgba(58,46,34,.07)}
/* 종이 테두리(34px) 안쪽 오른쪽 위 끝에 딱 붙입니다. */
/* ── 나가는 길은 늘 보입니다 (v2.59) ─────────────
   아래 줄이 **내용 끝**에 붙어 있어, 긴 창에서는 바닥까지 굴려야
   ✕ 가 나왔습니다. 창 아래에 붙박아 스크롤과 무관하게 늘 보이게
   합니다.
   `position:sticky` 라 팝업(짧은 창)에서는 제자리에 그대로 섭니다 —
   붙박이가 내용을 덮을 까닭이 없습니다. */
   비치는 자리는 좁게 둡니다 — 넓으면 줄 뒤의 글이 반쯤 비쳐
   겹쳐 읽힙니다(v2.36 에 그것으로 한 번 걸렸습니다). */
.sheet .sbar{position:sticky;bottom:0;z-index:6;
  background:linear-gradient(180deg,transparent,var(--panel) 12px);
  padding-top:12px;margin-top:6px}
body.paper .sheet .sbar{
  background:linear-gradient(180deg,transparent,#F3EAD3 12px)}
/* ── 스크롤 막대를 감춥니다 (v2.59) ──────────────
   오른쪽에 회색 막대가 서서 양피지 테를 가로질렀습니다. 굴릴 수
   있다는 것은 내용이 잘리는 자리에서 이미 보입니다. */
.sheet{scrollbar-width:none;-ms-overflow-style:none}
.sheet::-webkit-scrollbar{width:0;height:0;display:none}
/* ── 제목은 한 줄로 (v2.59) ──────────────────────
   「아셴 마을」 아래에 「새벽 초원」 이 또 한 줄을 먹었습니다.
   같은 것을 가리키는 말이라 한 줄에 붙입니다. */
.sheet h3.oneline{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.sheet h3.oneline .rg{font-size:12.5px;font-weight:400;opacity:.62;
  font-family:'IBM Plex Sans KR',sans-serif}
/* ── 나가는 길은 아래 한 줄 (v2.57) ──────────────
   창 안에 박힌 ✕ 일흔여섯은 감춥니다 — 자리를 옮기려고 그 군데를
   다 고치면 하나는 반드시 빠집니다. 아래 줄이 대신 냅니다. */
.sheet .close{display:none !important}
.sbar.bothx{display:flex;gap:8px;align-items:stretch}
.sbar.bothx .sback{flex:1 1 auto;min-width:0}
.sbar.bothx .sgap{flex:1 1 auto}
/* ✕ 는 오른쪽 끝 네모 — 엄지가 늘 닿는 자리입니다 */
.sbar.bothx .sxout{flex:0 0 auto;width:52px;padding:0;
  display:flex;align-items:center;justify-content:center;
  font-size:16px;line-height:1}
body.paper .sheet .close{color:#7B6A4E;right:0;top:0}
body.paper .hcard .gmk, body.paper .gmk{color:#B08A20}
/* 대화 상자 · 부채꼴 · 전투 기록 숫자도 종이 쪽으로 */
body.paper .say{background:rgba(243,234,211,.94);border-color:#C7AE7E;border-top:none}
body.paper .fbig .fnum{color:#7A6A4C}
body.paper .fan .fbtn{background:rgba(243,234,211,.96);border-color:rgba(138,106,34,.55);
  color:#3A2E22;box-shadow:0 3px 12px rgba(90,74,51,.35)}
body.paper .fan .fbtn:active{background:rgba(201,164,76,.35)}
body.paper .fan .fname{color:#3A2E22;text-shadow:0 1px 3px rgba(243,234,211,.95)}
body.paper .fan .fdot{background:rgba(138,106,34,.9);box-shadow:0 0 0 5px rgba(138,106,34,.18)}
/* 창을 열 때 뒤를 덮는 장막도 먹색으로 */
body.paper .scrim{background:rgba(58,46,34,.55)}
/* ── 지도 화면 겉옷 ───────────────────────────
   종이 지도 위에 검은 띠가 얹혀 있으면 두 겹이 따로 놉니다.
   머리띠·탭바·파견 카드·마커 이름표까지 같은 종이색으로 맞춥니다. */
body.paper header{background:#EDE1C4;border-bottom-color:#C7AE7E}
body.paper.mapmode header{background:#EDE1C4;border-bottom-color:#C7AE7E}
body.paper .gver{color:#8C7B58}
body.paper .gear{border-color:#C7AE7E;color:#7B6A4E}
body.paper nav{background:#EDE1C4;border-top:1px solid #C7AE7E}
body.paper.mapmode #runs .run{background:rgba(243,234,211,.94);border-color:#C7AE7E}
body.paper .zoomui button{background:rgba(243,234,211,.92);border-color:#C7AE7E;color:#3A2E22}
body.paper .daybar{background:#DCCBA4}
/* 마커 이름표도 종이 쪽지처럼 */
body.paper .hm .lbl{background:rgba(243,234,211,.94);border-color:#B9A075;color:#8A4A1E}
body.paper .hm.wait .lbl{color:#8A6A22;border-color:#B9A075}
body.paper .hm.ret .lbl{color:#2E6E5C}
body.paper .hm .lbl b{color:#3A2E22}
/* 아직 열지 않은 곳은 먹으로 옅게 눌러 둔 자국처럼 */
/* 종이 위에서는 먹으로 눌러 찍은 자국처럼 */
body.paper .hex.art.locked{filter:brightness(0)
  drop-shadow(0 2px 4px rgba(90,74,51,.3));opacity:.62}
/* 타일과 종이는 밝기보다 색온도가 어긋나 있었습니다 —
   종이 온기(R-B) 34 · 타일 6. 종이를 어둡게 하는 대신 타일을 종이 쪽으로
   당깁니다. 지도 위에 '그려 넣은 것' 으로 읽혀야 하니까요. */
body.paper .hex.art{filter:sepia(.45) saturate(1.05) brightness(1.35) contrast(.95)
  drop-shadow(1px 0 0 rgba(58,46,34,.5))
  drop-shadow(-1px 0 0 rgba(58,46,34,.5)) drop-shadow(0 1px 0 rgba(58,46,34,.5))
  drop-shadow(0 3px 5px rgba(90,74,51,.32))}
body.paper .hex.art .hn{color:#F3EAD3;text-shadow:0 1px 2px #3A2E22,-1px 0 2px #3A2E22,
  1px 0 2px #3A2E22,0 0 6px rgba(58,46,34,.9)}
body.paper .hex.art.locked .hn{color:#4A3D2C;font-weight:600;
  text-shadow:0 1px 2px rgba(243,234,211,.95),0 0 5px rgba(243,234,211,.9)}
body.paper .road{opacity:.35;background:repeating-linear-gradient(90deg,#8A7355 0 7px,transparent 7px 15px)}
body.paper .hexbr{background:#B9A075}
body.paper .hexrd{filter:sepia(.5) brightness(1.28) contrast(.95)}
body.paper .hexrd.open{filter:sepia(.4) brightness(1.22)}
body.paper .bandn{background:rgba(243,234,211,.9);color:#7B6A4E}
body.paper .sheet .close:active{background:rgba(154,122,46,.18)}
/* 창 왼쪽 위. 닫기(✕)는 오른쪽 위에 그대로 있습니다. */
/* ── 창 머리띠 ─────────────────────────────────
   창이 예순여섯인데 나오는 길이 창마다 달랐습니다 —
   ✕ 만 있는 것, ‹ 돌아가기가 붙는 것, 둘 다인 것, 스크롤을 내리면
   ✕ 가 따라 올라가 버리는 것. 어디를 눌러야 나가는지 매번 달랐습니다.

   머리띠 하나로 모읍니다. openSheet 가 창 내용 위에 늘 붙이고,
   sticky 라 아무리 내려도 맨 위에 붙어 있습니다.
   왼쪽이 나가는 길(돌아가기 또는 닫기), 오른쪽이 ✕ 입니다.

   창마다 적혀 있던 ✕ 는 지우지 않고 CSS 로 감춥니다 —
   예순여섯 군데를 손대는 것보다 한 곳을 잠그는 편이 덜 깨집니다. */
/* 위에 두었다가 아래로 옮겼습니다(v5.45).
   나오는 길이 창마다 둘이었습니다 — 위 머리띠와 아래 큰 단추.
   어디는 둘, 어디는 하나여서 매번 눈으로 찾아야 했습니다.
   아래 하나로 모읍니다. 엄지가 닿는 자리이기도 합니다. */
/* bottom:-16px 이라 창 아래 여백(16px) 밖으로 나가 **단추가 잘렸습니다.**
   sticky 는 넘어간 만큼 그대로 잘립니다 — 0 으로 붙여 세웁니다. */
/* ── 나오는 줄은 안 뜹니다 (v2.38) ───────────────
   `position:sticky` 라 창을 굴리는 동안 **글 위에 떠서** 밑에 깔린
   줄을 가렸습니다. 반투명을 걷고(v2.28), 잠근 창을 붙박이에서
   풀고(v2.28), 창 밖의 줄까지 덮게 했는데(v2.36) — 그래도 **뜬다는
   것 자체**가 남아 있었습니다.

   글과 함께 굴러갑니다. 창을 나가는 길은 오른쪽 위 ✕ 가 늘 있습니다.
   맨 아래 줄이 가려지는 것보다 한 번 더 굴리는 편이 낫습니다. */
.sbar{position:sticky;bottom:0;z-index:6;display:flex;
  margin:14px -16px -16px;padding:10px 16px 16px;
  /* 창 밖에서 쓰는 줄도 밑을 덮어야 합니다(v2.36) — `.sheet .sbar` 만
     고치고 이것을 두었더니 겹침 훑기가 여기서 걸렸습니다.
     열 픽셀만 스미고 그 아래는 덮습니다. */
  background:var(--panel);
  border-radius:0 0 16px 16px}
.sheet .close{display:none}
.sxit{background:none;border:0;padding:0;width:34px;height:34px;flex:0 0 auto;
  position:relative;color:var(--mute);cursor:pointer;border-radius:8px}
.sxit::before,.sxit::after{content:'';position:absolute;left:50%;top:50%;
  width:17px;height:2px;border-radius:1px;background:currentColor}
.sxit::before{transform:translate(-50%,-50%) rotate(45deg)}
.sxit::after{transform:translate(-50%,-50%) rotate(-45deg)}
.sxit:active{background:rgba(201,164,76,.18)}
/* 잠근 창(처음 사람 고르기)은 나가는 길이 아예 없습니다. */
/* ── 잠근 창의 줄은 붙박이가 아닙니다 (v2.28) ───
   `position:sticky` 라 내용이 화면보다 길면 **맨 아래에 떠서 마지막
   줄을 덮었습니다** — 프롤로그에서 「읽고 나서 길을 나섭니다」 가
   「길을 나선다」 단추 위에 겹쳐 앉았습니다.
   여기에는 누를 것이 없습니다. 붙박일 까닭도 없습니다. */
.sbar.slock{justify-content:center;position:static}
.sbar.slock .sback,.sbar.slock .sxit{display:none}
.sbar .slockn{font-size:12px;color:var(--mute);letter-spacing:.06em}
/* 종이 창은 테두리가 34px 그림이라 음수 여백을 걷습니다. */
body.paper .sbar{margin:12px 0 0;padding:12px 0 0;border-radius:0;
  background:linear-gradient(180deg,rgba(241,230,204,0) 0,var(--plate) 10px)}
body.paper .sxit{color:#7B6A4E}
/* 나무틀 단추(.go.fr)를 그대로 씁니다. 밋밋한 띠로 바꿨다가 되돌렸습니다 —
   창마다 아래에 서 있던 그 생김새가 「나가는 문」 으로 익어 있습니다.
   창 폭을 다 써서 한가운데를 눌러도 나가집니다. */
.sback{flex:1;display:inline-flex;align-items:center;justify-content:center;
  gap:2px;margin:0;padding:6px 10px;min-height:34px;font-size:13px;
  padding:6px 12px 6px 9px;border-radius:999px;
  background:var(--plate);border:1px solid var(--line);color:var(--brass);
  font:inherit;font-size:12px;cursor:pointer;letter-spacing:.02em}
.sback:active{background:rgba(201,164,76,.22)}
.sheet h3{font-family:'Gowun Batang','Nanum Myeongjo',serif;font-weight:400;font-size:19px;margin:0 0 3px}
/* 닫기 표시는 글자가 아니라 선으로 긋습니다.
   ✕ 는 본문 글꼴에 없으면 시스템 글꼴로 떨어져 굵기가 제각각이 됩니다.
   선으로 그으면 창 테두리와 굵기를 맞출 수 있고, 색도 테마를 따라옵니다. */
/* 창 오른쪽 위 끝에 붙입니다. 손가락으로 누르기 좋게 키웠습니다. */
.sheet .close{position:absolute;right:0;top:0;margin:0;background:none;border:none;
  width:42px;height:42px;padding:0;font-size:0;line-height:0;border-radius:0 12px 0 12px;
  color:var(--mute);cursor:pointer;border-radius:8px}
.sheet .close::before,.sheet .close::after{content:'';position:absolute;
  left:50%;top:50%;width:19px;height:2px;border-radius:1px;background:currentColor}
.sheet .close::before{transform:translate(-50%,-50%) rotate(45deg)}
.sheet .close::after{transform:translate(-50%,-50%) rotate(-45deg)}
.sheet .close:active{background:rgba(201,164,76,.18)}
/* ── 그려 넣는 기호 ───────────────────────────
   ？ ＋ 는 전각이라 폭이 어색하고 글꼴마다 모양이 다릅니다.
   칸 안에 직접 그으면 어디서나 같고, 색은 currentColor 를 따라옵니다. */
.mk{position:relative;display:inline-flex;flex:0 0 auto;color:var(--mute)}
.mk::before,.mk::after{content:'';position:absolute;left:50%;top:50%;background:currentColor;
  border-radius:1px}
.mk-plus::before{width:44%;height:2px;transform:translate(-50%,-50%)}
.mk-plus::after{width:2px;height:44%;transform:translate(-50%,-50%)}
.mk-x::before{width:46%;height:2px;transform:translate(-50%,-50%) rotate(45deg)}
.mk-x::after{width:46%;height:2px;transform:translate(-50%,-50%) rotate(-45deg)}
/* 두 팔이 한 점(38%,66%)에서 만나도록 자리와 길이를 풀어 두었습니다 */
.mk-chk::before{left:31%;top:58%;width:21%;height:2px;
  transform:translate(-50%,-50%) rotate(45deg)}
.mk-chk::after{left:53%;top:50%;width:44%;height:2px;
  transform:translate(-50%,-50%) rotate(-45deg)}
.mk-q{align-items:center;justify-content:center;font-family:'IBM Plex Mono',monospace;
  font-weight:500;opacity:.75}
.mk-q::before,.mk-q::after{content:none}
.mud{font-family:'IBM Plex Mono',monospace;font-size:11.5px;line-height:1.85;
  color:var(--chalk);background:var(--plate);border-left:2px solid var(--brass);
  padding:10px 12px;border-radius:0 7px 7px 0;margin:10px 0 4px}
.mud.d{border-left-color:var(--danger)}
.mud.v{border-left-color:var(--violet)}
.exits{font-family:'IBM Plex Mono',monospace;font-size:10.5px;color:var(--mute);
  margin-top:6px;letter-spacing:.03em}
/* ── 눌리는 것의 결 ──────────────────────────
   단추가 세 가지 꼴이었습니다 — .go(황동 띠) · .opt(판 한 줄) · .cell(격자).
   같은 '고른다' 인데 화면마다 모양이 달라 손이 다른 데를 찾았습니다.

   .opt 는 div 로 되어 있습니다. 태그를 바꾸면 닫는 짝 쉰여덟을 다 찾아야 하고
   그 가운데 여럿이 조건부 문자열이라 위험합니다.
   대신 눌리는 자리와 반응을 CSS 로 맞춥니다 — 손에는 그것이 전부입니다. */
/* ── 구역 창의 한 줄 ─────────────────────────
   접기 넷보다 이쪽이 낫습니다 — 무엇이 있는지가 바로 보입니다.
   왼쪽에 이름, 오른쪽에 낱말들이 줄바꿈하며 흐릅니다. */
/* ── 이름과 값이 줄을 맞춥니다 (v2.28) ──────────
   이름 칸을 58px 로 못 박아 두었습니다. 「오르는 솜씨」·「좋은 것이
   나올 확률」 처럼 긴 이름은 그 칸을 넘어 값 쪽으로 흘러들었고,
   값은 왼쪽에 붙어 있어 줄마다 시작점이 달랐습니다.

   이름은 제 길이만큼 쓰되 절반을 못 넘고, 값은 **오른쪽 끝**에
   맞춥니다 — 위아래로 한 줄이 섭니다. 이름이 없는 줄(제작 재료)은
   그대로 왼쪽으로 흐릅니다. */
.zrow{display:flex;gap:9px;padding:7px 0;border-bottom:1px solid var(--line);
  align-items:baseline;font-size:12px}
.zrow>b{flex:0 0 auto;min-width:58px;max-width:52%;
  color:var(--mute);font-weight:400;letter-spacing:.04em}
.zrow>span{display:flex;flex-wrap:wrap;gap:4px 6px;flex:1;min-width:0}
.zrow>b+span{justify-content:flex-end;text-align:right}
.zrow i{font-style:normal;color:var(--chalk);white-space:nowrap}
.zrow i.q{color:var(--mute)}
.zrow i.w{color:var(--brass)}
.zrow i.g{color:var(--jade)}
/* 아직 안 마주친 것은 까맣게만 눌러 그립니다 — 윤곽으로 짐작하게 */
.sil{display:inline-flex}
.sil .spr{filter:brightness(0) saturate(0);opacity:.42}
.zrow span>i:not(:last-child)::after{content:' ·';opacity:.35;margin-left:4px}
.zdesc{margin:9px 0 2px;font-size:11.5px;line-height:1.65;color:var(--mute)}
.fold{display:flex;align-items:center;width:100%;margin-top:10px;padding:7px 2px;
  background:none;border:0;border-bottom:1px solid var(--line);
  color:var(--mute);font-family:inherit;font-size:11px;letter-spacing:.06em;
  cursor:pointer;text-align:left}
.fold.on{color:var(--brass);border-color:rgba(201,164,76,.3)}
.fold i{margin-left:auto;font-style:normal;font-size:10px;opacity:.7}
.foldb{padding-top:2px}
.opt .why{margin-left:auto;font-size:10px;color:#E8C0B4;white-space:nowrap;
  opacity:.85;flex-shrink:0}
.opt,.go,.cell,.hcard,.sock.pick,.tcell,.note{
  -webkit-tap-highlight-color:transparent;
  touch-action:manipulation;
  user-select:none;-webkit-user-select:none}
/* 누르면 들어갑니다. 반응이 없으면 안 눌린 줄 알고 또 누릅니다. */
/* ── 누르면 눌린 느낌이 나야 합니다 (v2.52) ──────
   퀵슬롯 칸 · 가방 칸 · 장비 칸 · 갈래 표 넷이 빠져 있었습니다 —
   눌리기는 하는데 **눌린 티가 안 나** 「안 눌렸나」 하고 다시 누르게
   됩니다. 손이 가는 것은 다 여기 적어야 합니다.

   누르는 자리를 더할 때는 이 줄에도 함께 넣으세요. 못이 봅니다. */
.opt:active,.go:active,.cell:active,.hcard:active,
.sock.pick:active,.tcell:active,.note:active,
.qs:active,.bslot.on:active,.slot:active,.chips button:active,
.zd:active,.sd:active{
  transform:scale(.97);
  filter:brightness(1.12);
  transition:transform .06s ease-out}
/* 눌린 뒤 손을 떼면 제자리로 — 안 적으면 튕기듯 돌아옵니다 */
.qs,.bslot.on,.slot,.chips button{transition:transform .12s ease-out}
/* 못 누르는 것은 흐릴 뿐 아니라 손도 안 탑니다 */
.opt.dim,.go.dim,.cell.dim,.tcell.dim{pointer-events:none}
.opt.dim:active,.go.dim:active{transform:none;filter:none}
/* ── 흐리되 눌립니다 (v2.28) ───────────────────
   `.cell.dim` 은 **흐리게 하지도 않으면서 손만 막고** 있었습니다
   (opacity 규칙이 아예 없습니다). 그래서 「못 사는 것도 눌러서 볼
   수는 있습니다」(v1.69) · 「못 배운 것은 실루엣을 눌러 어디서
   오는지 봅니다」(v2.08) 가 넉 자리에서 통째로 죽어 있었습니다 —
   여느 칸과 똑같이 보이는데 눌러도 아무 일이 없었습니다.

   **못 하는 것과 볼 수 없는 것은 다릅니다.** 지금 못 사거나 아직
   못 익힌 것은 `faint` 로 흐리게만 두고 낱장은 그대로 엽니다.
   `dim` 은 누를 것이 아예 없는 칸(없는 재료)에만 씁니다. */
.cell.faint{opacity:.5}
.opt{display:flex;align-items:center;gap:10px;padding:11px 12px;margin-top:8px;
  background:var(--plate);border:1px solid var(--line);border-radius:9px;cursor:pointer}
.opt.dim{opacity:.4;cursor:default}
/* ── 줄 다음에 오는 것과 붙지 않습니다 (v2.28) ───
   `.opt` 는 위로만 8px 을 띄웁니다. 그래서 바로 뒤에 격자가 오면
   두 상자의 테두리가 맞닿아 **한 줄이 두 겹으로** 보였습니다 —
   창고에서 「간편 이동」 상자와 「돌덩이」 칸이 겹쳐 보인 자리입니다.
   창은 세로 flex 라 바깥 여백이 서로 먹히지 않으므로, 아래로도
   띄우면 줄과 줄 사이가 두 배가 됩니다. 뒤에 오는 것에만 줍니다. */
.opt + .grid,.opt + .grid3,.opt + .grid4,.opt + .grid5,.opt + .grid5x,
.opt + .empty,.opt + .chips,.opt + .cellwrap{margin-top:8px}
.opt.sel{border-color:var(--brass);background:var(--panel)}
.opt .ot{flex:1;font-size:13px;min-width:0}
/* 켜고 끄는 표는 제목 줄 오른쪽 끝에. 설명은 그 아래로 줄 전체를 씁니다(v2.28) */
.opt .ot .otr{display:flex;align-items:center;justify-content:space-between;gap:8px}
.opt .om{font-family:'IBM Plex Mono',monospace;font-size:11px;color:var(--mute)}
.chk{width:20px;height:20px;border-radius:5px;border:1px solid var(--line);
  display:grid;place-items:center;font-size:12px;color:var(--brass);flex:0 0 20px}
.opt.sel .chk{border-color:var(--brass);background:var(--brass);color:#221A06}
label.f{display:block;font-size:11px;color:var(--mute);margin:10px 0 4px}
input.f,textarea.f{width:100%;padding:9px 10px;background:var(--plate);
  border:1px solid var(--line);border-radius:7px;color:var(--chalk);
  font-family:'IBM Plex Mono',monospace;font-size:12px;resize:vertical}
input.f:focus,textarea.f:focus{outline:none;border-color:var(--brass)}
.loot{display:flex;align-items:center;gap:9px;padding:6px 0}
/* 정산 전리품 칸 */
.lgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin-top:8px}
.lcell{position:relative;background:var(--panel);border:1px solid var(--line);
  border-radius:9px;padding:8px 4px 5px;display:flex;flex-direction:column;
  align-items:center;justify-content:flex-start}
.lcell.g{border-color:var(--brass)}
.lcell.c{border-color:var(--jade)}
.lcell .lq{position:absolute;top:3px;right:5px;font-family:'IBM Plex Mono',monospace;
  font-size:10px;color:var(--brass);font-weight:600}
.lcell .ln{font-size:9px;color:var(--mute);margin-top:4px;text-align:center;
  line-height:1.2;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 경험치·골드 두 칸 */
.lhead{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.lbox{background:var(--panel);border:1px solid var(--line);border-radius:9px;
  padding:9px 8px;display:flex;align-items:center;gap:8px}
.lbox b{margin-left:auto;font-family:'IBM Plex Mono',monospace;font-size:14px;color:var(--brass)}
/* 아이콘은 어디서든 칸 한가운데에 옵니다 */
.opt .spr,.card .spr,.loot .spr,.cell .spr{flex:0 0 auto}
.settle,.rgem,.go{display:inline-flex;align-items:center;justify-content:center;gap:5px;line-height:1.15}
.recall{display:grid;place-items:center}
.loot .lq{margin-left:auto;font-family:'IBM Plex Mono',monospace;color:var(--brass);font-size:13px}
.gauge{height:8px;border-radius:4px;background:var(--plate);overflow:hidden;
  margin:8px 0 4px;position:relative}
.gauge i{display:block;height:100%;transition:width .3s;
  background-image:repeating-linear-gradient(90deg,rgba(0,0,0,.22) 0 1px,transparent 1px 4px)}
.gauge .mark{position:absolute;top:-2px;bottom:-2px;width:2px;background:var(--chalk);opacity:.7}

#toast{position:fixed;left:50%;bottom:calc(var(--navh,68px) + 14px);transform:translateX(-50%);z-index:60;
  display:flex;flex-direction:column;gap:6px;align-items:center;pointer-events:none}
.tst{background:var(--plate);border:1px solid var(--line);padding:8px 14px;
  border-radius:20px;font-size:12px;animation:tin .25s;white-space:nowrap}
@keyframes tin{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.empty{text-align:center;color:var(--mute);font-size:12px;padding:26px 20px;
  border:1px dashed var(--line);border-radius:var(--r);line-height:1.7}
/* ── 들판 · 지도 위 ────────────────────────────
   사냥터에 닿아도 「남은 기척 3」 이라는 글자 한 줄뿐이었습니다.
   무엇이 있는지 보려면 구역 창을 따로 열어야 했습니다.

   닿은 자리에 무엇이 어른거리는지 지도 위에 그대로 늘어놓습니다.
   구역 창의 파노라마(.zpano)와 같은 결이되, 여기 것은 「명부」가 아니라
   지금 그 자리에 있는 무리입니다 — 누르면 곧바로 붙습니다. */
.pfield{margin:0 10px 6px;border-radius:10px;border:1px solid var(--line);
  overflow:hidden;display:none}
.pfield.on{display:block}
/* ── 지도 위 두 줄 ────────────────────────────
   지도에서는 #mapview 가 position:fixed · z-index:1 로 화면을 통째로 덮습니다.
   흐름 안에 두면 그 뒤에 깔려 아무것도 안 보입니다 —
   주인공 줄이 여태 그랬고(오래된 것), 들판도 v5.23·v5.24 두 판 동안 그랬습니다.

   둘을 한 상자에 담아 머리띠 바로 아래에 띄웁니다.
   아래에 뒀다가 위로 옮겼습니다 — 엄지는 멀어지지만, 눈이 먼저 가는 자리가
   위입니다. 닿자마자 무엇이 있는지 보이는 것이 먼저입니다. */
.pcwrap{display:block}
body.mapmode #pcwrap{position:fixed;left:50%;transform:translateX(-50%);
  width:100%;max-width:480px;z-index:19;pointer-events:none;
  top:var(--hh,132px)}
body.mapmode #pcwrap > *{pointer-events:auto}
body.mapmode #pfield{box-shadow:0 6px 20px rgba(0,0,0,.45)}
/* 몬스터 줄만 옆으로 굴러갑니다. 나오는 것 줄은 그 아래에 붙박입니다. */
.pfscroll{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;
  scrollbar-width:none}
.pfscroll::-webkit-scrollbar{display:none}
/* 몬스터가 적으면 왼쪽에 몰려 서고 오른쪽이 텅 비었습니다.
   가운데로 모읍니다 — 넘칠 때는 max-content 가 이겨 왼쪽부터 채우고
   밀어서 볼 수 있으므로, justify-content 는 안 넘칠 때만 듣습니다.
   (flex-start 로 두면 안 넘칠 때도 왼쪽에 붙습니다.) */
.pfstrip{position:relative;width:max-content;min-width:100%;height:104px;
  display:flex;align-items:flex-end;justify-content:center;
  padding:0 12px 10px;box-sizing:border-box;
  background-size:cover;background-position:center;
  background-color:var(--dsky,transparent)}
.pfield .zfog,.pfield .zline{pointer-events:none}
/* 아래 줄 — 여기서 나오는 것. 구역 창을 안 열어도 벌이가 보입니다. */
.pfdrop{display:flex;gap:8px;overflow-x:auto;overflow-y:hidden;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;
  padding:6px 10px;background:var(--plate);border-top:1px solid var(--line)}
.pfdrop::-webkit-scrollbar{display:none}
.pfd{flex:0 0 auto;display:flex;align-items:center;gap:4px;
  font-size:9.5px;color:var(--mute);white-space:nowrap}
.pfd b{font-weight:400}
.pfd.w b{color:var(--brass)} .pfd.g b{color:var(--jade)}
.pfmob{position:relative;z-index:2;flex:0 0 auto;background:none;border:0;padding:0;
  font:inherit;cursor:pointer;display:flex;flex-direction:column;align-items:center;
  transform:scale(var(--zs,1)) translateY(calc(-1 * var(--zu,0px)));
  transform-origin:50% 100%;opacity:var(--zo,1)}
.pfmob .zmb{display:block;filter:drop-shadow(0 4px 6px rgba(0,0,0,.5))}
.pfmob .pfn{display:block;max-width:92px;font-size:9.5px;color:#EDE1C4;
  text-shadow:0 1px 3px rgba(0,0,0,.9);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;margin-top:2px}
.pfmob.hard .pfn{color:#E8C0B4}
.pfmob:active .zmb{transform:translateY(1px)}
.pfnone{position:absolute;inset:0;display:grid;place-items:center;
  color:#C7B79A;font-size:11px;text-shadow:0 1px 3px rgba(0,0,0,.9)}
/* ── 전투 팝업 ────────────────────────────────
   화면을 통째로 덮던 것을 창으로 바꿉니다. 뒤로 지도가 비쳐야
   '지금 저 자리에서 벌어지는 일' 로 읽힙니다.
   겹침 — 지도와 머리띠(40) 위, 시트 덮개(50)와 토스트(60) 아래. */
.duel{display:none;position:fixed;inset:0;z-index:45;
  background:rgba(4,10,12,.74);backdrop-filter:blur(2px);
  align-items:center;justify-content:center;padding:12px;
  padding-bottom:calc(12px + var(--padb))}
.duel.on{display:flex;animation:dIn .18s ease-out}
@keyframes dIn{from{opacity:0}to{opacity:1}}
.duel .dwrap{width:100%;max-width:420px;max-height:100%;display:flex;flex-direction:column;
  border:1px solid rgba(201,164,76,.34);border-radius:4px;overflow:hidden;
  background:linear-gradient(180deg,#1B2325,#141A1C);
  box-shadow:0 18px 46px rgba(0,0,0,.62);animation:dPopIn .2s cubic-bezier(.2,.9,.3,1.2)}
/* 테두리 그림이 들어오면 갈아입습니다. 없으면 위의 황동 실선이 그대로 남습니다.
   border-image 는 border-width 만큼만 그려지므로 폭을 함께 키워야 합니다 —
   1px 로 두면 그림이 실오라기처럼 눌려 나옵니다. */
/* stretch 가 아니라 round 입니다.
     늘이면 창이 길어질수록 톱니 하나가 같이 커져 위아래 무늬가 서로 달라집니다.
     되풀이하면 톱니 크기가 유지되고 개수만 늘어납니다.

     자를 폭 25 는 눈대중이 아니라 실측입니다 — 384 짜리 그림에서 황동이
     차지하는 폭이 정확히 25px 이고, 모서리 장식도 그 안에 다 들어갑니다.
     46 으로 잡았을 때는 안쪽 어두운 판까지 21px 을 함께 잘라
     테두리가 실제보다 두툼해 보이고 무늬가 눌려 있었습니다.
     그릴 폭을 26 으로 두어 거의 1:1 로 그립니다 — 확대·축소가 없어 선명합니다. */
.duel .dwrap.framed{border:26px solid transparent;border-radius:0;overflow:visible;
  background:none;border-image:var(--duelframe) 25 fill round}
.duel .dwrap.framed>*{position:relative;z-index:1}
.duel .dwrap.framed .dstage{border-radius:2px}
/* 테두리를 두르면 창이 그만큼 커집니다. 좁은 화면에서 넘치지 않게 줄입니다. */
.duel .dwrap.framed{max-width:400px}
/* 좁은 화면에서도 1:1 에서 크게 벗어나지 않게 한 단계만 줄입니다 */
@media (max-width:400px){ .duel .dwrap.framed{border-width:21px} }
@keyframes dPopIn{from{transform:translateY(14px) scale(.96)}to{transform:none}}
.duel .dtop{text-align:center;color:#8B9BA0;font-size:11px;letter-spacing:.08em;
  padding:7px 10px;border-bottom:1px solid rgba(255,255,255,.07)}

/* 무대 — 배경 그림 한 칸 위에 양쪽이 마주 섭니다 */
.duel .dstage{position:relative;height:132px;flex:none;overflow:hidden;
  background:linear-gradient(180deg,var(--dsky,#39474C) 0%,var(--dsky,#39474C) 54%,var(--dgnd,#222B2D) 54%,var(--dgnd,#222B2D) 100%)}
.duel .dstage.shake{animation:dQuake .3s}
@keyframes dQuake{0%,100%{transform:translate(0,0)}
  20%{transform:translate(-4px,2px)}40%{transform:translate(3px,-2px)}
  60%{transform:translate(-2px,1px)}80%{transform:translate(2px,0)}}
.duel .dstage:after{content:'';position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 80% at 50% 118%,rgba(0,0,0,.42),transparent 62%)}
.duel /* 주인공과 상대가 **같은 쪽을 보고** 있었습니다(v5.89) —
   둘 다 오른쪽을 봐서, 주인공이 상대에게 등을 돌린 꼴이었습니다.
   왼쪽에 선 주인공만 뒤집어 마주 보게 합니다.
   뒤집는 것은 그림(.dsp)이고 자리(.dfig)는 그대로입니다 —
   틀을 뒤집으면 이름표와 숫자까지 거울이 됩니다. */
.dfig{position:absolute;bottom:12px;z-index:2}
.dfig.me .dsp{transform:scaleX(-1)}
.dfig.foe .dsp{transform:none}
.duel .dfig.me{left:14%;transform:translateX(-50%)}
.duel .dfig.foe{right:14%;transform:translateX(50%)}
.duel .dfig .sh{position:absolute;left:50%;bottom:-6px;width:44px;height:10px;
  transform:translateX(-50%);border-radius:50%;background:rgba(0,0,0,.42);filter:blur(3px)}
.duel .sockrow{display:flex;gap:6px;flex-wrap:wrap;margin-top:4px}
.sock{flex:1 1 46%;min-width:110px;border:1px dashed var(--line);border-radius:8px;
  padding:8px 9px;font-size:11px;color:var(--mute);text-align:left;background:none}
.sock.on{border-style:solid;color:var(--ink)}
.sock.pick{border-style:solid;cursor:pointer}
.sock b{display:block;font-size:12px;margin-bottom:2px}
.sock i{font-style:normal;font-size:10px;color:var(--mute);line-height:1.3}
.gemdot{display:inline-block;width:8px;height:8px;border-radius:999px;
  margin-right:5px;vertical-align:1px;box-shadow:0 0 0 1px rgba(0,0,0,.5)}
.dmercs{position:absolute;left:2px;bottom:2px;display:flex;gap:3px;
  pointer-events:none;z-index:3}
.dmerc{display:flex;flex-direction:column;align-items:center;
  font-size:8px;color:var(--mute);line-height:1.1;opacity:.9}
.dmerc i{font-style:normal;font-size:8px}
.dproj{position:absolute;left:16%;top:50%;width:64px;height:64px;
  transform:translate(-50%,-50%);pointer-events:none;z-index:5;
  opacity:0;
  animation:projfly var(--projms,340ms) linear 1 both,
            projspin .3s steps(6) infinite}
@keyframes projfly{
  0%   {left:16%; opacity:1}
  92%  {opacity:1}
  100% {left:84%; opacity:0}
}
@keyframes projspin{ from{background-position-x:0} to{background-position-x:-600%} }
/* 걸려 있는 것은 몬스터 그림 위에 얹힙니다. 가운데가 빈 그림이라
   아래·좌우에서만 타오르고 몬스터는 그 안에 보입니다. */
.dstat{position:absolute;left:50%;top:50%;width:72px;height:72px;
  transform:translate(-50%,-50%);pointer-events:none;z-index:3;opacity:.92;
  animation:statplay .9s steps(6) infinite}
@keyframes statplay{ from{background-position-x:0} to{background-position-x:-600%} }
/* 같은 줄이라도 크기·기울기·빠르기·빛깔을 조금씩 흔듭니다(v2.35).
   변수가 없으면 여태와 똑같이 그립니다 — 옛 자리는 안 흔들립니다. */
.dfx{position:absolute;left:50%;top:50%;width:74px;height:74px;
  transform:translate(-50%,-50%) rotate(var(--fxr,0deg)) scale(var(--fxs,1));
  filter:hue-rotate(var(--fxh,0deg));
  pointer-events:none;z-index:4;
  opacity:0;
  /* forwards 는 마지막 칸을 붙잡습니다. 같은 턴을 다시 그리지 않으므로
     다음 턴까지 그대로 남아 있었습니다. 끝나면 스스로 사라지게 둡니다. */
  animation:fxplay var(--fxms,.5s) steps(6) 1 both}
@keyframes fxplay{
  0%   {background-position-x:0;    opacity:1}
  99%  {opacity:1}
  100% {background-position-x:-600%;opacity:0}
}
/* 평타가 남기는 자국. 턴마다 진하게 터지면 기술을 쓴 턴이
   묻히므로 옅고 빠르게 지나갑니다. */
.dfx.soft{animation-duration:.34s;animation-name:fxsoft}
@keyframes fxsoft{
  0%   {background-position-x:0;    opacity:.62}
  99%  {opacity:.44}
  100% {background-position-x:-600%;opacity:0}
}
.dsp{position:relative;display:block;filter:drop-shadow(0 4px 6px rgba(0,0,0,.6))}
/* 서로 마주 보게 하려면 한쪽을 뒤집어야 할 수 있습니다.
   어느 쪽을 보는 그림인지는 눈으로 봐야 알 수 있으므로 여기 한 곳만 고칩니다 —
   상대를 뒤집으려면  none → scaleX(-1)  로.
   (예전에 화소 분포로 궁수 방향을 재려다 반대로 읽은 적이 있습니다) */
/* 몬스터 그림은 대개 왼쪽을 봅니다. 나도 왼쪽을 보고 있어
   둘이 같은 쪽을 보고 서 있었습니다. 상대를 뒤집어 마주 보게 합니다. */
.duel .dfig.me  .dsp .spr{transform:scaleX(-1)}   /* 상대를 봅니다 */
/* 찌는 사람이 아닙니다 — 뒤집지도 않고 발밑 그림자도 없습니다.
   물 위에 떠 있는 것이라 조금 낮게 앉힙니다. */
/* 뒤에 섰던 놈이 앞으로 나섭니다 — 커지면서 들어옵니다 */
.duel .dfig.step .dsp{animation:dStep .34s ease-out both}
@keyframes dStep{0%{opacity:.4;transform:translateX(16px) scale(.7)}
                 100%{opacity:1;transform:none}}
.duel .dfig.back{position:absolute;z-index:1;pointer-events:none;
  transition:right .3s ease-out, bottom .3s ease-out, opacity .3s}
.duel .dfig.back .dsp{transition:transform .3s ease-out}
.duel .dfig.back .dsp .spr{transform:scaleX(-1)}
.duel .dfig.back .hb{position:absolute;left:50%;top:-6px;transform:translateX(-50%);
  width:22px;height:3px;background:rgba(0,0,0,.6);border-radius:2px;overflow:hidden}
.duel .dfig.back .hb i{display:block;height:100%;background:#96483A}
/* 금이 간 나무. 예전에는 🌲 가 💥 로 바뀌어 「곧 넘어간다」를 알렸습니다.
   그림으로 바꾸면서 그 신호가 없어져, 대신 밑동을 축으로 기울입니다. */
.duel .dfig.lean .dsp{transform-origin:50% 100%;animation:tLean .7s ease-in-out infinite}
@keyframes tLean{0%,100%{transform:rotate(-1.5deg)}50%{transform:rotate(2.5deg)}}
/* 창 머리에 그림 한 장. 무엇을 하는 자리인지 글자보다 빨리 읽힙니다. */
.shead{display:flex;justify-content:center;margin:-2px 0 6px;
  filter:drop-shadow(0 3px 5px rgba(0,0,0,.45))}
.duel .dfig.bobfig{bottom:4px}
.duel .dfig.bobfig .sh{display:none}
.duel .dfig.bobfig .dsp .spr{transform:none}
.duel .dfig.bobfig .caught{position:absolute;left:50%;bottom:34px;
  transform:translateX(-50%);animation:dPop 1.1s ease-out both}
.duel .dfig.bobfig .pop{color:#C9E8DC}
.duel .dfig.foe .dsp .spr{transform:scaleX(-1)}
/* 돌진 — 때리는 쪽이 앞으로 나갔다 돌아옵니다 */
.duel .dfig.me.lunge .dsp{animation:dLungeR .42s ease-out}
.duel .dfig.foe.lunge .dsp{animation:dLungeL .42s ease-out .40s}
/* ── 달려들 때 등을 보이던 버그 (v2.05) ──────────
   `.dfig.me .dsp` 에 `scaleX(-1)` 로 몸을 돌려 두었는데, 달려드는
   애니메이션이 같은 `transform` 을 `translateX` 로 **통째 덮어써서**
   그 순간만 뒤집기가 풀렸습니다 — 때리러 가면서 등을 보였습니다.

   애니메이션이 뒤집기를 **함께 지니게** 합니다. transform 은 하나뿐이라
   한쪽만 적으면 다른 쪽이 사라집니다. */
@keyframes dLungeR{
  0%{transform:scaleX(-1) translateX(0)}
  22%{transform:scaleX(-1) translateX(4px)}      /* 몸을 잠깐 뒤로 뺍니다 */
  46%{transform:scaleX(-1) translateX(-16px)}    /* 앞으로 내딛습니다 */
  70%{transform:scaleX(-1) translateX(-6px)}
  100%{transform:scaleX(-1) translateX(0)}}
/* 상대는 안 뒤집힌 채로 섭니다 — 그쪽은 그대로 둡니다. */
@keyframes dLungeL{
  0%{transform:translateX(0)}
  22%{transform:translateX(4px)}
  46%{transform:translateX(-16px)}
  70%{transform:translateX(-6px)}
  100%{transform:translateX(0)}}
/* 흔들림 — 맞은 쪽이 휘청입니다 */
.duel .dfig.foe.hurt .dsp{animation:dShake .34s .14s}
.duel .dfig.me.hurt .dsp{animation:dShakeM .34s .54s}
@keyframes dShake{
  0%{transform:translate(0,0) rotate(0)}
  18%{transform:translate(-4px,1px) rotate(-2.5deg)}
  38%{transform:translate(3px,-1px) rotate(2deg)}
  60%{transform:translate(-2px,0) rotate(-1deg)}
  80%{transform:translate(1px,0) rotate(0.5deg)}
  100%{transform:translate(0,0) rotate(0)}}
/* 내 몸은 뒤집혀 서 있습니다 — 흔들림도 그 뒤집기를 지녀야
   합니다. 안 그러면 맞는 순간 등을 보입니다(v2.05). */
@keyframes dShakeM{
  0%{transform:scaleX(-1) translate(0,0) rotate(0)}
  18%{transform:scaleX(-1) translate(-4px,1px) rotate(-2.5deg)}
  38%{transform:scaleX(-1) translate(3px,-1px) rotate(2deg)}
  60%{transform:scaleX(-1) translate(-2px,0) rotate(-1deg)}
  80%{transform:scaleX(-1) translate(1px,0) rotate(0.5deg)}
  100%{transform:scaleX(-1) translate(0,0) rotate(0)}}
/* 섬광 — 급소를 쳤을 때 한 번 하얗게 */
.duel .dfig.foe.flash .dsp{animation:dShake .34s .14s, dFlash .3s .14s}
.duel .dfig.me.flash .dsp{animation:dShakeM .34s .54s, dFlash .3s .54s}
@keyframes dFlash{0%{filter:brightness(4) saturate(.2) drop-shadow(0 0 8px #fff)}
  100%{filter:drop-shadow(0 4px 6px rgba(0,0,0,.6))}}
/* 쓰러짐 */
.duel .dfig.down .dsp{animation:dDie .55s forwards .14s}
@keyframes dDie{0%{opacity:1}100%{opacity:0;transform:translateY(12px) rotate(14deg) scale(.86)}}
/* 떠오르는 숫자 */
/* ── 머리 위에서 흩어져 내립니다 (v2.35) ─────────
   여태는 발치에서 위로 떠올랐습니다. 맞은 자리가 아니라 **맞은 것의
   머리 위**에서 나야 어디가 맞았는지 눈이 따라갑니다.
   흩어지는 방향은 `--dx` 로 한 대에 한 번 정해집니다 — 안 그러면
   연타 세 대가 정확히 겹쳐 하나처럼 보입니다.
   피해는 붉은 마이너스입니다. 급소만 더 밝게 터집니다. */
.duel .pop{position:absolute;left:50%;top:4px;transform:translateX(-50%);
  font-size:17px;font-weight:800;letter-spacing:-.02em;pointer-events:none;z-index:3;
  text-shadow:0 2px 4px rgba(0,0,0,.85);opacity:0;white-space:nowrap}
.duel .dfig.foe .pop{color:#FF5A4A;animation:dFall 1.05s ease-in .16s}
.duel .dfig.me  .pop{color:#FF3B30;animation:dFall 1.05s ease-in .56s}
.duel .pop.crit{color:#FF8A3D;font-size:20px}
.duel .pop.miss,.duel .pop.blk{font-size:12px;font-weight:700;color:#9AA8AC}
/* ── 전투 시작 (v2.38) ──────────────────────────
   판이 붙은 것이 화면에 안 났습니다. 한 박자 크게 띄웠다 사라집니다.
   무대 한가운데라 손을 안 받아야 합니다. */
.duel .dbanner{position:absolute;left:50%;top:34%;transform:translate(-50%,-50%);
  z-index:7;pointer-events:none;white-space:nowrap;
  font-family:'Gowun Batang',serif;font-size:19px;letter-spacing:.30em;
  color:#F0E6CC;text-shadow:0 2px 6px rgba(0,0,0,.9),0 0 18px rgba(226,101,58,.55);
  animation:dban 1.4s ease-out forwards}
@keyframes dban{
  0%{opacity:0;transform:translate(-50%,-50%) scale(.82)}
  14%{opacity:1;transform:translate(-50%,-50%) scale(1.06)}
  70%{opacity:1;transform:translate(-50%,-50%) scale(1)}
  100%{opacity:0;transform:translate(-50%,-58%) scale(1)}}
body.paper .duel .dbanner{color:#4A3A22;text-shadow:0 1px 3px rgba(255,255,255,.7)}
/* ── 모으는 막대 (v2.37) ────────────────────────
   발치에 섭니다 — 머리 위는 뜬 숫자가 쓰는 자리입니다.
   한 턴 길이에 맞춰 차오르므로 「이 턴이 값이다」 가 눈에 보입니다.
   손은 안 받습니다. */
.duel .castbar{position:absolute;left:50%;bottom:-2px;width:62px;height:5px;
  transform:translateX(-50%);border-radius:3px;pointer-events:none;z-index:5;
  background:rgba(10,16,20,.72);box-shadow:0 0 0 1px rgba(226,101,58,.5)}
.duel .castbar i{display:block;height:100%;width:0;border-radius:3px;
  background:linear-gradient(90deg,#8A3A1E,#E2653A);
  animation:castfill linear 1 forwards}
.duel .castbar b{position:absolute;left:50%;top:-14px;transform:translateX(-50%);
  font-size:9.5px;font-weight:600;letter-spacing:.02em;white-space:nowrap;
  color:#E2653A;text-shadow:0 1px 3px rgba(0,0,0,.9)}
@keyframes castfill{from{width:0}to{width:100%}}
body.paper .duel .castbar{background:rgba(58,46,34,.35)}
@keyframes dFall{
  0%{opacity:0;
     transform:translateX(calc(-50% + var(--dx,0px) * .15)) translateY(-8px) scale(.7)}
  16%{opacity:1;
     transform:translateX(calc(-50% + var(--dx,0px) * .35)) translateY(2px) scale(1.18)}
  100%{opacity:0;
     transform:translateX(calc(-50% + var(--dx,0px))) translateY(44px) scale(1)}}

.duel .dvs{display:flex;align-items:flex-start;gap:8px;padding:9px 10px 4px}
.duel .dside{flex:1;min-width:0}
.duel .dside.foe{text-align:right}
.duel .dside .dn{font-size:12px;color:#E8DCC0;font-weight:700;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.duel .dsub{font-size:10px;color:#8B9BA0;margin-top:1px}
.duel .dmid{align-self:center;color:#6E8288;font-size:10px;letter-spacing:.1em;padding-top:8px}
.duel .dbar{height:7px;border-radius:999px;background:rgba(255,255,255,.09);overflow:hidden;margin-top:4px}
.duel .dbar i{display:block;height:100%;border-radius:999px;transition:width .3s ease-out}
/* 낚시·채광·벌목의 눈금은 한 박자(1초)에 걸쳐 고르게 찹니다 —
   싸움의 체력 눈금처럼 튕기면 물때를 기다리는 결이 안 삽니다. */
.duel .dbar.slow i{transition:width 1s linear}
.duel .dbar.me i{background:linear-gradient(90deg,#4A7C6E,#6FB39C)}
.duel .dbar.foe i{background:linear-gradient(90deg,#B4534A,#D8756A)}
.duel .dnum{font-size:10px;color:#9AA8AC;margin-top:2px}
/* ── 걸린 것 ─────────────────────────────── */
.duel .pill{display:flex;gap:3px;flex-wrap:wrap;margin-top:3px}
.duel .dside.foe .pill{justify-content:flex-end}
.duel .pill span{font-size:9.5px;line-height:1.5;padding:0 5px;border-radius:999px;
  white-space:nowrap;border:1px solid currentColor;opacity:.92}
.duel .pill .pr{color:#E2653A}.duel .pill .pb{color:#7FC7D9}
.duel .pill .py{color:#C9A44C}.duel .pill .pg{color:#6FB39C}
.duel .pill .pm{color:#B69AC4}
.duel .dlog{height:82px;overflow-y:auto;border-top:1px solid rgba(255,255,255,.07);
  border-bottom:1px solid rgba(255,255,255,.07);
  background:rgba(0,0,0,.26);padding:7px 10px;margin:6px 0 0}
.duel .dl{font-size:11.5px;color:#B8C6CA;line-height:1.5;padding:1px 0}
.duel .dl b{color:#E8C0B4}
/* ── 숫자가 무엇인가 (v6.18) ──────────────────
   v6.12 에 **누가** 넣었는지로 갈랐습니다 — 내 것 옥빛, 상대 것 붉은빛.
   그런데 누가 때렸는지는 이미 문장 첫머리에 이름으로 적혀 있습니다.
   색까지 그 일을 하면 같은 말을 두 번 하는 셈입니다.

   색은 **무엇인지**를 말하게 합니다. 피는 붉고, 아무는 것은 푸르고,
   마법은 다른 결입니다 — 한눈에 갈리는 것은 이쪽입니다.

     피해(누가 넣었든)  붉은빛   회복  초록빛   마법  파란빛 */
.duel .dl i{font-style:normal;color:#E2653A}
.duel .dl i.mg{color:#7FC7D9}
.duel .dl em{font-style:normal;color:#7FC08F;font-weight:600}
.duel .dl.sys{color:#8B9BA0}
.duel .dacts{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;padding:9px 10px 10px}
.duel .dacts button{font:inherit;font-size:12.5px;padding:10px 0;border-radius:3px;
  border:1px solid rgba(201,164,76,.34);background:rgba(201,164,76,.10);color:#E8DCC0}
.duel .dacts button:active{background:rgba(201,164,76,.24)}
.duel .dacts button:disabled{opacity:.34}
.duel .dacts button span{display:block;font-size:10px;color:#8B9BA0;margin-top:2px}
.duel .dacts button.wide{grid-column:1 / -1}
/* 퀵슬롯 줄(넉 칸) 아래에서도 한 줄을 통째로 씁니다. 셋만 차지하면
   오른쪽 한 칸이 비어 단추가 왼쪽으로 밀려 보였습니다. */
.duel .dacts.q button.wide{grid-column:1 / -1;flex-direction:row;gap:7px;
  justify-content:center;align-items:center;margin-top:2px;padding:11px 0}
.duel .dacts.q button.wide span{margin-top:0;font-size:12.5px;color:inherit}
.duel .dacts button.warn{border-color:rgba(232,192,180,.3);color:#E8C0B4;background:rgba(232,192,180,.07)}
/* 퀵슬롯 — 전투는 저절로 굴러가고 손은 여기에만 갑니다 */
.duel .dacts.q{grid-template-columns:repeat(4,1fr)}
.duel .qb{display:flex;flex-direction:column;align-items:center;gap:1px;
  font:inherit;font-size:11px;padding:7px 0;border-radius:3px;
  border:1px solid rgba(201,164,76,.34);background:rgba(201,164,76,.10);color:#E8DCC0}
.duel .qb.off{opacity:.35}
.duel .qb.e{opacity:.45;border-style:dashed}
.duel .qb span{font-size:11px}
.duel .qb i{font-style:normal;font-size:9.5px;color:#8B9BA0}
.duel .qb.wide{grid-column:span 4;flex-direction:row;gap:6px}
.qrow{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin:4px 0}
.qs{display:flex;flex-direction:column;align-items:center;gap:2px;font:inherit;font-size:11px;
  padding:9px 0;border-radius:3px;border:1px dashed var(--line);
  background:rgba(255,255,255,.03);color:var(--chalk)}
.qs.on{border:9px solid transparent;border-radius:0;background:transparent;
  border-image:var(--btnplate,url('assets/btn_plate.png')) 14 fill stretch;
  color:#3A2E1C}
/* 넣은 것의 개수는 인라인으로 황동색이 박혀 있습니다 —
   양피지 위에서는 안 읽혀 여기서만 눌러 덮습니다. */
.qs.on b{color:#6B4E12 !important}
.qs .e{color:var(--mute)}
.duel .dend{text-align:center;padding:10px 12px 2px}
/* 판이 남긴 솜씨 한 줄(v1.01). 전리품 아래에 조용히 붙습니다. */
.duel .dend .dprof{margin-top:8px;padding-top:7px;
  border-top:1px solid rgba(201,164,76,.22);
  font-size:11px;color:var(--mute);line-height:1.6}
.duel .dend .dprof b{color:var(--gold);font-weight:600;margin-right:7px}
.duel .dend .dprof em{font-style:normal;color:#7FC08F}
.duel .dend h4{margin:0 0 4px;font-size:15px;color:#E8DCC0;
  font-family:'Gowun Batang','Nanum Myeongjo',serif}
.duel .dend p{margin:0;font-size:12px;color:#9AA8AC}
/* ── 전리품 격자 ─────────────────────────── */
.duel .lsum{display:flex;justify-content:center;gap:12px;margin:2px 0 6px;
  font-size:12px;color:#E8DCC0}
.duel .lsum span{display:inline-flex;align-items:center;gap:3px}
.duel .lsum i{font-style:normal;font-size:9.5px;color:#C9A44C;margin-left:2px}
.duel .lgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:5px;
  max-height:132px;overflow-y:auto;padding:2px}
.duel .lc{position:relative;display:flex;flex-direction:column;align-items:center;
  gap:1px;padding:5px 2px 4px;border-radius:3px;
  border:1px solid rgba(255,255,255,.10);background:rgba(255,255,255,.04);
  animation:lpop .3s cubic-bezier(.2,.9,.3,1.3) both}
.duel .lc.hi{border-color:rgba(201,164,76,.5);background:rgba(201,164,76,.12)}
.duel .lc:nth-child(2){animation-delay:.05s}.duel .lc:nth-child(3){animation-delay:.10s}
.duel .lc:nth-child(4){animation-delay:.15s}.duel .lc:nth-child(5){animation-delay:.20s}
.duel .lc:nth-child(6){animation-delay:.25s}.duel .lc:nth-child(7){animation-delay:.30s}
@keyframes lpop{from{opacity:0;transform:translateY(6px) scale(.85)}to{opacity:1;transform:none}}
.duel .lc .q{position:absolute;right:3px;top:2px;font-size:10px;font-weight:700;
  color:#E8DCC0;text-shadow:0 1px 2px rgba(0,0,0,.9)}
.duel .lc .n{font-size:9.5px;color:#9AA8AC;line-height:1.15;text-align:center;
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.duel .lc i{font-style:normal;font-size:9px;color:#C9A44C}
.duel .lfull{font-size:10.5px;color:#E8C0B4;margin-top:4px}
.hm.pc .hmi{filter:drop-shadow(0 0 5px rgba(201,164,76,.85))}
.hm.pc .lbl{color:#E8DCC0}
/* ── 머리띠의 주인공 ──────────────────────────
   길드 수치 대신 지금 걷고 있는 사람을 놓습니다. 눌러서 바꿉니다. */
.pcchip{font:inherit;font-size:11.5px;color:var(--chalk);
  border:1px solid rgba(201,164,76,.40);border-radius:999px;
  background:rgba(201,164,76,.12);padding:2px 9px;white-space:nowrap;
  max-width:100%;overflow:hidden;text-overflow:ellipsis}
.pcchip b{color:var(--brass)}
.rchip{font-size:11px;color:var(--mute);margin-left:6px;white-space:nowrap}

/* ── 숙련 묶음 ─────────────────────────────── */
.pgrp{display:flex;align-items:center;gap:7px;width:100%;margin:5px 0 0;
  padding:9px 10px;border:1px solid var(--line);border-radius:3px;
  background:rgba(255,255,255,.03);color:var(--chalk);font:inherit;text-align:left}
.pgrp.on{background:rgba(201,164,76,.09);border-color:rgba(201,164,76,.34)}
.pgrp .ga{color:var(--brass);font-size:11px;width:10px}
.pgrp .gn{font-weight:700;font-size:13px;white-space:nowrap}
.pgrp .gm{margin-left:auto;font-size:11px;color:var(--mute);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.plist{border:1px solid var(--line);border-top:0;border-radius:0 0 3px 3px;
  padding:4px 8px 6px;background:rgba(0,0,0,.16)}
.prow{display:flex;align-items:center;gap:7px;padding:5px 0;
  border-bottom:1px solid rgba(255,255,255,.05);flex-wrap:wrap}
.prow:last-child{border-bottom:0}
.prow .lk{font:inherit;font-size:10px;line-height:1;padding:3px 5px;border-radius:3px;
  border:1px solid var(--line);background:rgba(255,255,255,.04);color:var(--mute)}
.prow .lk.up{color:#6FB39C;border-color:rgba(111,179,156,.35)}
.prow .lk.lock{color:var(--mute)}
.prow .lk.down{color:#E8C0B4;border-color:rgba(232,192,180,.35)}
.prow .pn{font-size:12.5px;color:var(--chalk);min-width:52px}
.prow .pn .own{color:var(--brass);font-size:10px;font-weight:700}
.prow .mini{flex:1;min-width:60px;height:5px;border-radius:999px;
  background:rgba(255,255,255,.09);overflow:hidden}
.prow .mini i{display:block;height:100%;border-radius:999px;
  background:linear-gradient(90deg,#4A7C6E,#6FB39C)}
.prow.done .mini i{background:linear-gradient(90deg,#8A7434,#C9A44C)}
.prow .pv{font-size:11.5px;color:var(--mute);min-width:30px;text-align:right}
.prow .pt{font-size:10.5px;color:var(--mute);min-width:34px;text-align:right}
.prow .pt.ok{color:#6FB39C}.prow .pt.hi{color:var(--brass)}
.prow .pd{flex-basis:100%;font-size:10.5px;color:var(--mute);opacity:.75;
  padding-left:0;line-height:1.35}
button:focus-visible,.opt:focus-visible,.node:focus-visible{outline:2px solid var(--brass);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ══ 글자는 늘 단추 한가운데 ═══════════════════
   테두리 그림마다 두께가 달라 글자가 칸마다 다르게 앉았습니다.
   padding 으로 맞추면 그림을 갈 때마다 다시 맞춰야 합니다 —
   누르는 것은 전부 flex 로 가운데에 세우고, 높이만 정해 둡니다.
   그래야 테두리를 갈아도 글자는 그대로 가운데에 있습니다. */
.go,.settle,.rgem,.tag,.rk,.qs,.tcell,.pick{
  align-items:center;justify-content:center;text-align:center;
  box-sizing:border-box}
.go{display:inline-flex;line-height:1.15}
.go.fr{min-height:32px}
.settle,.rgem{display:flex;width:100%}
.settle{min-height:30px} .rgem{min-height:28px}
.tag,.rk{display:inline-flex;min-height:17px;line-height:1}
.qs{display:flex;flex-direction:column}
.title-screen .tstart,.title-screen .trow .tbtn{
  display:flex;align-items:center;justify-content:center;text-align:center;
  min-height:46px;padding-top:0;padding-bottom:0;line-height:1.15}
/* 단추 안에 아이콘과 글자가 함께 있으면 둘을 한 덩어리로 가운데에 둡니다 */
.go .spr,.settle .spr,.tcell .spr{flex:0 0 auto}
