/* ===== 글꼴 =====
   docs/폰트원본 의 ttf·otf 를 `_폰트굽기.py` 가 woff2 로 줄여 구운 것이다.
   바깥 글꼴 서버를 타지 않는다 — 비행기 모드에서도 같은 글씨가 나온다.

   본문(400)과 굵은명조(700~900)를 **한 식구로 묶어 두었다.**
   그래서 font-weight:700 이 걸린 자리는 저절로 굵은명조를 집는다 —
   브라우저가 획을 부풀려 만드는 가짜 굵기가 끼지 않는다.
   글자를 더 넣거나 갈았으면 `python _폰트굽기.py --쓰기` 를 돌리고 아래 ?v= 를 올린다 */

/* ── 본문 식구 "Chosun Body" — **조선100년체가 게임의 공식 기본 글꼴이다.**
   굵기와 상관없이 글자는 100년체다. 100년체에는 굵은 판이 없어 굵은 자리는 브라우저가 획을 부풀린다.
   **숫자만 예외로 명조**다 — 아래 "KW Num" 이 숫자만 가로챈다.
   ⚠ 100년체는 상용 2,350자만 구워져 있다(폰트 기획 §4). 거기 없는 글자는 뒤의 "Chosun"(명조 11,172자)이 받는다 */
@font-face{font-family:"Chosun Body";src:url("assets/fonts/chosun-story.woff2?v=5") format("woff2");
  font-weight:400;font-style:normal;font-display:swap}
/* ── 숫자 "KW Num" — **숫자(0~9)만** 명조로 그린다. 글꼴 줄의 맨 앞에 서서 숫자만 가로챈다.
   100년체는 숫자 폭이 466·614·634 로 제각각이라 재화·시계가 구를 때 자릿수가 흔들린다.
   명조·굵은명조는 숫자 폭이 고정이다. 글자는 뒤의 100년체가 그대로 받는다 */
@font-face{font-family:"KW Num";src:url("assets/fonts/chosun-nm.woff2?v=5") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;unicode-range:U+0030-0039}
@font-face{font-family:"KW Num";src:url("assets/fonts/chosun-km.woff2?v=5") format("woff2");
  font-weight:700;font-style:normal;font-display:swap;unicode-range:U+0030-0039}

/* ── 명조 식구 "Chosun" — 이제 받침 노릇을 한다.
   100년체에 없는 글자를 받고, 붓글씨에 없는 한자도 여기로 떨어진다 */
@font-face{font-family:"Chosun";src:url("assets/fonts/chosun-nm.woff2?v=5") format("woff2");
  font-weight:400;font-style:normal;font-display:swap}
/* 굵기는 **700 하나만** 적는다. `700 900` 같은 범위 표기는 CSS Fonts 4 문법이라
   옛 사파리가 못 읽고 **@font-face 를 통째로 버린다** — 휴대폰에서만 글꼴이 안 나오던 까닭이다.
   700 하나만 적어도 800·900 인 자리는 글꼴 고르기 규칙에 따라 이 얼굴로 내려온다 */
@font-face{font-family:"Chosun";src:url("assets/fonts/chosun-km.woff2?v=5") format("woff2");
  font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:"Chosun Story";src:url("assets/fonts/chosun-story.woff2?v=5") format("woff2");
  font-weight:400;font-style:normal;font-display:swap}
/* 붓글씨는 한자밖에 없다. 범위를 한자로 묶어 두면 한글·숫자가 잘못 집히지 않고,
   한자가 화면에 없는 동안에는 내려받지도 않는다 */
@font-face{font-family:"KW Brush";src:url("assets/fonts/kw-brush.woff2?v=5") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
  unicode-range:U+4E00-9FFF,U+F900-FAFF}

:root{
  /* 잉크 먹빛 — 바탕 그림(bg_app_silk)의 채도에 맞춘다.
     색상(265도)은 원래도 그림과 같았다. 다른 것은 채도뿐이었다 — 25퍼센트는 그림(9퍼센트) 옆에서 보랏빛으로 튀었다.
     면은 11퍼센트로 내리고 강조색(--seal 계열·도 색)은 그대로 둔다. 면이 잠잠해야 강조가 산다 */
  --ink:#110f13; --ink-2:#19171c;
  --panel:#201d24; --panel-2:#29252e;
  --line:#393441; --line-soft:#2d2833;
  --fg:#ece5dc; --fg-mid:#8f94ae; --fg-faint:#62667f;   /* 보조 글자도 푸른 쪽(230도)으로 */
  /* 화면을 거드는 색. 스크롤·칩·화살표·초점 테두리가 다 이 색이다.
     보랏빛이 바탕과 따로 놀아 230도 푸른 쪽으로 옮기고 채도를 28퍼센트로 눌렀다.
     정파 파랑(215도/채도68)과는 색상도 채도도 갈려 헷갈리지 않는다 */
  --seal:#7c86b6; --seal-deep:#333957;
  /* 도(道) */
  --jeong:#5b93e0; --sa:#5fae62; --ma:#e05242; --yo:#a97cff; --hwang:#d4a843; --hyeol:#8c2f2f; --mudo:#8e8a9b;
  /* 카드 테두리 전용 — 도 색의 채도를 3할로 눌러(상한 26퍼센트) 명도 31퍼센트에 맞춘 것.
     원색을 그대로 두르면 카드 한 장 한 장이 소리를 질러 정작 그림이 안 보인다.
     글자·문양·막대에는 위의 원색을 그대로 쓴다 */
  --jeong-e:#3f4c5f; --sa-e:#475748; --ma-e:#60413e; --yo-e:#493a64; --hwang-e:#5f5236; --hyeol-e:#5b4343; --mudo-e:#4e4d51;
  /* 재화 */
  --chungi:#d4a843; --yeong:#a97cff; --jin:#7fd4b0;
  --ok:#6fcf97; --warn:#e8b45f; --danger:#e8695f; --ready:#4dffa0;
  /* 전체보기로 보면 위쪽을 카메라가 문다. 기기가 알려 주면 그 값을, 안 알려 주면 최소치를 쓴다.
     아티팩트는 iframe 안이라 env() 가 0 으로 오는 일이 잦아 최소치가 실제로 일하는 값이다 */
  --top-gap:max(env(safe-area-inset-top),20px);
  --bot-gap:env(safe-area-inset-bottom);
  /* 심경 */
  --simma:#e05a3c; --myeong:#6f7fd8; --chukgi:#57c9a6;
  /* 본문 기본 — 조선100년체. 뒤의 "Chosun"(명조)은 100년체에 없는 글자를 받는다 */
  --sans:"KW Num","Chosun Body","Chosun","Apple SD Gothic Neo","Malgun Gothic",system-ui,serif;
  /* 제목도 본문과 한 가족이다. 굵기와 자간으로만 층을 나눈다 */
  --serif:var(--sans);
  /* 숫자 자리도 본문과 같은 줄을 쓴다 — 숫자는 맨 앞의 "KW Num"(명조)이, 글자는 100년체가 받는다 */
  --mono:var(--sans);
  --num:var(--sans);
  /* 한자는 붓글씨로 — 한글과 결이 갈려 표식으로 읽힌다.
     이 글꼴에 없는 글자(綠·緣)는 뒤의 명조가 받는다. **본문을 바꿔도 한자는 건드리지 않는다** */
  --han:"KW Brush","KW Num","Chosun Body","Chosun",serif;
  /* 카드 이야기 — 이제 본문과 같은 얼굴이다(둘 다 100년체). 자리를 따로 두는 것은
     나중에 이야기만 다른 글꼴로 되돌리고 싶을 때를 위해서다 */
  --story:"KW Num","Chosun Story","Chosun",serif;
  /* **명조 자리** (v0.225) — 기본은 100년체지만, 이름처럼 **또렷이 서야 하는 글**은 조선명조로 되돌린다.
     메인 단추 이름 · 하단 이름표 · 카드 이름 · 명운 이름 · 인연첩 이름이 여기를 쓴다 */
  --mjo:"Chosun","Apple SD Gothic Neo","Malgun Gothic",serif;
  --r-s:4px; --r-m:8px; --app-w:430px; --view-w:430px;
  /* ⚠⚠ **판의 너비는 늘 430 이다** (v0.321). 넓은 화면에서 커지는 것은
     자리나 글자 크기가 아니라 **판 전체의 배율(`--k`)**이라, 모바일에서 잡아 둔 것이 그대로 커진다.
     ⚠ **세로는 화면을 다 쓴다** — 높이를 못 박으면 길쭉한 휴대폰에서 위아래에 띠가 생긴다.
        못 박는 것은 배율의 상한뿐이고, 그래서 판은 **10:16 보다 넓어지지 않는다.**
        남는 자리는 뒤에 깔린 강호의 산 그림이 받는다.
     ⚠ 둘 다 `ui.js` 의 `fitApp()` 이 재서 넣는다. 아래 값은 그것이 돌기 전의 첫 한 겹이다 */
  --app-h:688px; --k:1;
  /* ⚠⚠ **수라 연출의 배율** — `ui.js` 가 `document.body` 에 `position:fixed` 로 붙이는
     열한 자리(드로우 · 소환 · 황천 가는 카드 · 피격 · 태그 박스)가 이 값을 곱해 쓴다.
     그것들은 판(`.app`) **바깥**이라 `zoom:var(--k)` 를 못 받는다 — 그대로 두면 치수가
     폰에 맞춘 px 로 굳어 **판만 커지고 연출은 안 커진다.** 2026-10-14 기획자 제보가 이 자리다.
     ⚠ 기본은 판 배율(`--k`)과 같다 — 그래야 어느 화면에서나 **폰에서 보던 그 비**다.
     ⚠⚠ **연출만 한 단 줄이고 싶으면 여기 한 줄만 고친다** (예: `calc(var(--k) * .85)`).
        열한 자리를 따로 손대지 마라 — 그러면 다음 사람이 어디를 고쳐야 할지 못 찾는다.
     ⚠ 자리(`left`·`top`)에는 안 곱한다. 그쪽은 `ctr()` 이 준 화면 좌표라 배율이 이미 녹아 있다 */
  --fxk:var(--k);
}
*{box-sizing:border-box}
body{margin:0;background:var(--ink);color:var(--fg);font-family:var(--sans);font-size:14px;line-height:1.55;-webkit-text-size-adjust:100%;
  /* 글자를 더 또렷하게 새긴다 — 넓은 화면에서 판을 키우면 흐릿함이 먼저 눈에 띈다 */
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility}
/* ⚠⚠ **글자를 고를 수 없게 한다 — 화면 전체에 한 번만 걸고 다시는 손대지 않는다** (v155) ⚠⚠
   이것은 게임이지 웹페이지가 아니다. 단추나 하단 바를 연달아 두드리면 브라우저가
   **파란 선택 상자**를 쳐 버린다 — 눌린 것도 아니고 고른 것도 아닌 그 네모가 뜨면 판이 문서처럼 보인다.
   예전에는 자리마다 `user-select:none` 을 하나씩 붙였다. 그래서 화면을 고칠 때마다
   새로 만든 자리에 그게 빠져 같은 것이 되풀이해 살아났다 — **여러 번 고쳤고 그때마다 다시 났다.**
   이제 여기 한 줄이 다 맡는다. **새 요소에 따로 붙이지 말고, 이 줄을 지우지도 말 것.**
   글자를 집어야 하는 자리는 아래 `input·textarea` 뿐이다 (§9 · 인수인계 §8) */
html,body{-webkit-user-select:none;user-select:none;
  -webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
/* 사람이 글자를 치는 칸만 되돌린다 — 명호·명운 코드처럼 집어서 지우고 붙여야 하는 자리다 */
input,textarea{font:inherit;color:inherit;-webkit-user-select:text;user-select:text}
:focus-visible{outline:2px solid var(--seal);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;transition-duration:.01ms!important}}

.stage{height:100svh;display:flex;justify-content:center;align-items:center;overflow:hidden;
  background:
    radial-gradient(900px 420px at 50% -8%,#2a1f3dcc 0%,transparent 62%),
    linear-gradient(90deg,#06080db8 0%,#110f1373 22%,#110f13c7 42%,#110f13c7 58%,#110f1373 78%,#06080db8 100%),
    url("assets/ui/bg_mountain_night.webp") center/cover no-repeat,
    var(--ink)}
/* ⚠⚠ **가로·세로가 못 박힌 한 장이다.** 화면에 맞추는 것은 `zoom` 하나뿐이다 (v0.321).
   ⚠ `transform:scale` 이 아니라 `zoom` 인 까닭 — `scale` 은 그려 놓은 것을 **잡아 늘리는** 것이라
      넓은 화면에서 글자가 자글자글해진다(제보받은 자리다). `zoom` 은 그 크기로 **다시 셈해서 그린다** —
      글꼴이 제 해상도로 다시 새겨져 선명하다.
   ⚠ 안쪽의 `clamp(…vw…)` 들은 그대로 두었다. 넓은 화면에서는 어차피 px 상한에 걸려 멎으므로,
      **지금 넓은 화면에서 보이던 그 모습**이 그대로 배율만 커진다. 자리가 튀지 않는다.
   ⚠ `zoom` 을 못 쓰는 낡은 판에서는 아래 `@supports` 가 `scale` 로 물러선다 */
.app{width:var(--app-w);height:var(--app-h);flex:none;zoom:var(--k);
  display:flex;flex-direction:column;
  background:var(--ink-2);border-inline:1px solid var(--line-soft);position:relative;overflow:hidden;
  box-shadow:0 0 72px 18px #03050ad9}
@supports not (zoom:2){
  .app{zoom:normal;transform:scale(var(--k));transform-origin:center center}
}
/* ⚠ 좌우 여백은 **어느 화면이든 강호의 산 그림**이다 (v0.247).
   예전에는 수라 중에만 흙바닥 그림(`bg_battle_outer`)으로 갈아, 판이 화면 끝까지 이어져 보이게 했다.
   판 폭을 `--app-w` 로 못 박은 뒤로는 그 흙바닥이 좌우를 통째로 덮어 **흙밭만 넓은 화면**이 됐다.
   ⚠ 되돌릴 거면 아래 한 줄을 살리면 된다 — 다만 그때는 판과 여백의 경계가 흐려진다 */
@media (max-width:519px){.stage,.stage.inbattle{background:var(--ink)}.app{box-shadow:none}}
/* 비단 바탕 — 순례길과 수라장을 뺀 모든 화면에 깐다.
   좌우 여백을 채우는 산 그림(.stage) 위에 한 겹 더 얹는 것이라 .app 쪽에 둔다.
   화면(.screen)은 .app 안에서 따로 구르므로 바탕은 스크롤해도 제자리에 있는다 */
.app.silk{background-color:var(--ink-2);
  background-image:
    linear-gradient(180deg,#0b0912c9 0%,#0b09124d 24%,#0b091240 64%,#0b0912d9 100%),
    url("assets/ui/bg_app_silk.webp");
  background-size:cover,cover;background-position:center top,center top;background-repeat:no-repeat}
/* 바탕이 생긴 화면에서는 상자를 딤드로 깔아 뒤가 비치게 한다 — 꽉 막으면 바탕을 깐 뜻이 없다 */
.app.silk .tile{background:linear-gradient(160deg,#201d24bf,#29252ebf);backdrop-filter:blur(3px)}
.app.silk .tile:hover{background:linear-gradient(160deg,#201d24d9,#29252ed9)}
.app.silk .fbtn{background:#201d24a8;backdrop-filter:blur(3px)}
.app.silk .fbtn.pri{background:color-mix(in srgb,var(--seal-deep) 82%,transparent)}
.app.silk .fbtn.dg{background:#241417a8}
.app.silk .ubtn,.app.silk .chip,.app.silk .fsel,.app.silk .fq{background:#201d24a0;backdrop-filter:blur(2px)}
.app.silk .chip.on{background:color-mix(in srgb,var(--seal-deep) 84%,transparent)}
.app.silk .topbar{background:#191320d9;backdrop-filter:blur(7px)}
.app.silk .ftog,.app.silk .askbox,.app.silk .jinbox,.app.silk .devbox{background:#1c1626c4;backdrop-filter:blur(3px)}
.app.silk .signin .si{background:#191320bf}
/* 한지 결 */
.app::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;opacity:.5;
  background:repeating-linear-gradient(90deg,#ffffff04 0 1px,transparent 1px 3px)}
.app > *{position:relative;z-index:1}
/* ===== 빛무리 (v221 — 장작 연기를 걷고 새로 지었다) =====
   ⚠ **왜 연기를 걷었나.** v178 부터 v220 까지 여덟 판을 손봤지만
   **휴대폰에서 화면이 깜빡이는 것**을 끝내 못 잡았다. 까닭은 연기의 생김새 자체였다 —
   흐릿한 기둥 일곱을 겹치려니 `filter:blur()` 가 필요했고, 그것이 매 프레임 다시 그려졌다.
   v220 에 흐림을 걷었더니 이번에는 **연기처럼 안 보였다.**
   **값싸게 만들 수 없는 연출은 값을 깎는 것이 아니라 바꾸는 것이 맞다.**

   지금 것 — **흰 빛무리 셋**이 배경 바로 위, 다른 UI 뒤에서 천천히 돌아다닌다.
   빛이 스며 비치는 것처럼 보이게 하는 것이 전부다.

   ⚠⚠ **움직이는 것은 `transform` 과 `opacity` 뿐이다.** 그 둘은 다시 그리지 않고 **합치기만** 한다.
   `filter` · `box-shadow` · `backdrop-filter` 를 여기에 **절대 넣지 않는다** — 그 순간 v220 으로 돌아간다.
   부드러운 가장자리는 **그라디언트 멈춤점 여럿**이 만든다. 공짜다.

   ⚠ **가장자리에서 반드시 알파 0 으로 끝낸다.** 0 이 아닌 채로 칸이 끝나면
   그 둘레가 **선으로 보인다** — v221~v222 가 그랬다. 자세한 것은 아래 `.glow i` 주석.
   ⚠ 짙기를 만지는 자리는 **`background` 의 알파 한 곳**이다. 복판이 `26`(=15%)이고
   가장자리로 가며 0 이 된다. 더 흐리게 하려면 그 수만 내린다 —
   `.glow` 나 `i` 의 `opacity` 를 건드리면 숨쉬기(`glowbreathe`)와 겹쳐 셈이 엉킨다.

   수라장은 제 배경과 연출이 따로 있으므로 `.app.fog` 일 때만 켠다. */
.glow{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  opacity:0;transition:opacity .7s ease}
.app.fog .glow{opacity:1}
/* 원 하나. `aspect-ratio:1` 이라 폭만 주면 정원이 된다 */
.glow i{position:absolute;display:block;
  width:var(--gw,60%);aspect-ratio:1;
  left:var(--gx,20%);top:var(--gy,40%);
  /* ⚠⚠ **테두리 선이 보이던 까닭 셋** (v223). 셋 다 여기서 고쳤다.

     ① **`circle` 만 적으면 그라디언트의 100% 가 「가장 먼 모서리」다.**
        칸이 정사각이니 그 거리는 반지름의 1.41배다. 그래서 `border-radius:50%` 로 자르는
        자리(반지름)에서 그라디언트는 아직 **70% 지점**이었고, 알파가 `0.025` 쯤 남아 있었다.
        **남은 채로 잘리니 그 둘레가 선으로 보인다.**
        → `closest-side` 를 적어 **100% 를 칸의 가장자리에 맞췄다.** 거기서 알파가 0 이다.
     ② **`border-radius:50%` 를 걷었다.** 그라디언트가 가장자리에서 0 이면 자를 것이 없다.
        자르는 일 자체가 선을 만든다.
     ③ **`transparent` 를 `#ffffff00` 으로 바꿨다.** `transparent` 는 규격상 **투명한 검정**이라
        흰빛에서 그리로 건너가는 동안 **잿빛이 섞여 테가 진다.** 같은 흰빛의 알파 0 으로 적어야
        빛깔이 안 흔들린다.

     멈춤점도 여덟 → **열하나**로 늘렸다. 바깥 세 겹은 `04 · 02 · 01 · 00` 으로
     **한 칸(1/255)씩** 내려간다 — 눈이 띠로 못 잡는 폭이다 */
  background:radial-gradient(circle closest-side,
    #ffffff26 0%,#ffffff22 10%,#ffffff1b 22%,#ffffff14 34%,
    #ffffff0e 46%,#ffffff09 58%,#ffffff06 68%,#ffffff04 77%,
    #ffffff02 85%,#ffffff01 92%,#ffffff00 100%);
  will-change:transform,opacity;
  /* 도는 것과 숨쉬는 것을 **따로** 돌린다. 주기가 서로 나눠떨어지지 않아야
     셋이 같은 박자로 뛰지 않는다 — 소수(37·53·71 과 23·29·31)를 쓴다 */
  animation:var(--ga,glowdrift1) var(--gd,53s) ease-in-out infinite,
            glowbreathe var(--gb,29s) ease-in-out infinite}
.glow i:nth-child(1){--gw:66%;--gx:-12%;--gy:26%;--ga:glowdrift1;--gd:53s;--gb:29s}
.glow i:nth-child(2){--gw:52%;--gx: 46%;--gy: 4%;--ga:glowdrift2;--gd:71s;--gb:23s;animation-delay:-19s,-8s}
.glow i:nth-child(3){--gw:44%;--gx: 14%;--gy:58%;--ga:glowdrift3;--gd:37s;--gb:31s;animation-delay:-11s,-17s}
/* 셋 다 **처음과 끝이 같은 자리**다 — 그래야 한 바퀴 돌 때 튀지 않는다.
   길은 서로 다르게 그렸다. 같으면 셋이 줄지어 다니는 것처럼 보인다 */
@keyframes glowdrift1{
  0%,100%{transform:translate(  0%,  0%) scale(1)}
  25%    {transform:translate( 46%,-18%) scale(1.10)}
  50%    {transform:translate( 88%, 22%) scale(.92)}
  75%    {transform:translate( 34%, 46%) scale(1.04)}}
@keyframes glowdrift2{
  0%,100%{transform:translate(  0%,  0%) scale(1)}
  30%    {transform:translate(-52%, 34%) scale(.94)}
  60%    {transform:translate( 18%, 78%) scale(1.12)}
  82%    {transform:translate(-26%, 28%) scale(1)}}
@keyframes glowdrift3{
  0%,100%{transform:translate(  0%,  0%) scale(1)}
  22%    {transform:translate( 62%, 26%) scale(1.06)}
  48%    {transform:translate(104%,-14%) scale(.9)}
  74%    {transform:translate( 40%,-38%) scale(1.08)}}
/* 숨쉬기 — 밝기만 오르내린다. 자리와 따로 도므로 되풀이가 눈에 안 잡힌다 */
@keyframes glowbreathe{0%,100%{opacity:.62} 50%{opacity:1}}
@media (prefers-reduced-motion:reduce){ .glow i{animation:none;opacity:.7} }
/* ⚠⚠ **휴대폰에서는 `backdrop-filter` 를 끈다** (v220).
   `backdrop-filter` 는 **제 뒤에 깔린 것을 매 프레임 다시 읽어** 흐린다.
   그런데 그 뒤에서 연기가 **쉬지 않고 움직인다** — 그래서 이 딱지가 붙은 것들
   (윗줄 · 큰 칸 · 단추 · 칩 · 고르개 · 찾기 칸 · 필터 접기 · 물음 상자)이
   **전부 매 프레임 다시 그려진다.** 연보에서는 그런 칸이 열 개가 넘는다.

   휴대폰에서 3px 흐림은 **눈에 보이지도 않으면서 값은 가장 비싸다.** 끄고,
   대신 바탕을 조금 더 진하게 해 글자가 묻히지 않게 한다.
   ⚠ 넓은 화면(데스크톱)은 그대로 둔다 — 거기서는 값이 문제가 안 되고 보기에도 낫다 */
@media (max-width:640px){
  .app.silk .tile{backdrop-filter:none;background:linear-gradient(160deg,#201d24ef,#29252eef)}
  .app.silk .fbtn{backdrop-filter:none;background:#201d24e6}
  .app.silk .ubtn,.app.silk .chip,.app.silk .fsel,.app.silk .fq{backdrop-filter:none;background:#201d24e0}
  .app.silk .topbar{backdrop-filter:none;background:#191320f7}
  .app.silk .ftog,.app.silk .askbox,.app.silk .jinbox,.app.silk .devbox{backdrop-filter:none;background:#1c1626f0}
  /* ⚠ `.varr` 는 이 블록보다 **한참 아래**에 정의돼 있다. 같은 촘촘함이면 뒤가 이기므로
     `.app` 을 앞에 붙여 한 칸 올린다 — 자리와 상관없이 이긴다 */
  .app .varr{backdrop-filter:none;background:#0b0908ef}
  /* 빛무리는 셋뿐이라 줄일 것이 없다. `transform`·`opacity` 만 도므로 값이 거의 안 든다 */
}
/* 초식 시전 자리 — 눌러야 나간다. 패에서 누르자마자 나가면 되돌릴 틈이 없다.
   보이지 않을 때도 자리는 지킨다(visibility). display 로 감추면 고를 때마다 수라장이 위아래로 튄다 */
/* 폭은 수라장 한 줄과 같게 — 칸 5개(각 64px)와 사이 4군데(각 4px) */
/* 초식 시전 자리 — 누르면 나간다는 것이 색으로 읽혀야 한다.
   무채색으로 두면 그냥 빈 칸으로 보여 무엇을 더 해야 하는지 모른 채 멈춘다 */
/* ⚠ **각연권속을 놓을 빈 칸(`.slot.open`)과 같은 꼴이다** (v0.225) — 점선 초록 테 · 옅은 초록 바탕 ·
   같은 빠르기(1.1s)로 같은 깜빡임(`sp`). 「여기를 누른다」는 자리는 판 위에서 한 가지 얼굴이어야 한다 */
.castzone{flex:none;height:46px;width:min(100%,calc(64px*5 + 4px*4));margin:2px auto 0;display:flex;align-items:center;justify-content:center;
  border:1.5px dashed var(--ok);border-radius:2px;background:#6fcf972e;
  font-size:12px;font-weight:700;letter-spacing:.3em;text-indent:.3em;color:var(--ok);
  text-shadow:0 1px 3px #000;box-shadow:inset 0 0 12px #6fcf9733,0 0 6px #6fcf9740;
  visibility:hidden;opacity:0;transition:opacity .16s,transform .08s}
.castzone.on{visibility:visible;opacity:1;animation:sp 1.1s ease-in-out infinite}
/* 누르는 순간 눌려 들어간다 */
.castzone.on:active{transform:translateY(1px) scale(.994);animation:none;
  background:#6fcf9759;border-color:#b6f5cf;box-shadow:inset 0 0 18px #6fcf9766,0 0 14px #6fcf9780}
.rule{height:1px;flex:none;background:linear-gradient(90deg,transparent,var(--line) 12%,var(--fg-faint) 50%,var(--line) 88%,transparent);opacity:.7}

/* 하단 — 모바일에서 엄지가 닿는 자리다. 뒤로가기도 여기 있다.
   좌우 여백은 화면 본문(.screen)과 같은 16px 로 맞춘다 — 얼굴·이름이 타일 왼쪽 줄에 선다 */
.app.battle-wide .topbar{border-top:0;background:#0b0a0ceb}
/* **높이를 못 박는다** (v153). 예전에는 그 화면에서 가장 큰 아이가 높이를 정해,
   메인(65px)과 나머지(77px)가 달라 화면을 옮길 때마다 바가 들썩였다.
   이제 안쪽 60px 로 고정이라 무엇이 들고 나든 꿈쩍하지 않는다 */
.topbar{flex:none;position:relative;display:flex;align-items:center;gap:8px;
  height:calc(60px + var(--bot-gap));padding:0 16px var(--bot-gap);
  background:var(--panel);border-top:1px solid var(--line-soft)}
/* 뒤로가기가 없는 화면에서는 자리까지 비운다 — visibility 로 숨기면 빈 칸이 남아 줄이 밀린다.
   v152 에 오른쪽 끝으로 옮겼다 — 재화가 왼쪽을 차지하므로 여기서 남은 자리를 다 밀어낸다 */
.backbtn{width:44px;height:40px;flex:none;margin-left:auto;display:flex;align-items:center;justify-content:center;
  border-radius:var(--r-s);color:var(--fg-mid);font-size:20px;-webkit-tap-highlight-color:transparent}
/* 이름은 **두 줄까지** 접고, 길면 글씨를 줄인다 (v176). 크기는 `fitName()` 이 재서 넣는다 —
   글자 수만 보고 정하면 「가나다라마바사아자차」와 「WWWWWWWWWW」의 폭이 딴판이라 한쪽이 넘친다.
   ⚠ **태그(#0000)는 절대 안 줄인다** — 이름이 밀려도 태그까지는 온전히 보여야 한다 */
.screen-name{font-family:var(--mjo);font-weight:700;font-size:14.5px;letter-spacing:.06em;
  line-height:1.16;min-width:0;text-align:left;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  word-break:break-all;overflow-wrap:anywhere}
/* 메인에서만 눌린다 — 누르면 로그아웃을 묻는다 */
.whoami{position:relative;display:flex;align-items:center;gap:8px;min-width:0;padding:3px 6px;margin-left:-6px;margin-right:-4px;border-radius:2px}
/* 이름만 줄어들고 얼굴·태그는 제 크기를 지킨다 */
.whoami .tface,.whoami .tag-mini{flex:none}
.whoami .screen-name{flex:0 1 auto}
/* 뒤로가기가 숨으면 이름표가 제 손으로 오른쪽 끝까지 민다 */
.backbtn[hidden] + .whoami{margin-left:auto}
.whoami[hidden]{display:none}
/* 손가락 기기에서는 두드린 자리에 hover 가 들러붙는다 — 되돌아왔을 때
   왼쪽 아래 이름표가 골라진 것처럼 남았다 (v146) */
@media (hover:hover) and (pointer:fine){ .whoami.live:hover{background:var(--panel-2)} }
.whoami:not(.live){pointer-events:none}
/* 화살표 하나(38px)로는 엄지가 짚기에 좁다. **옆에 붙은 화면 이름까지가 뒤로가기 자리다** —
   결연이든 순례든 혈투든, 글씨를 짚어도 돌아간다. 메인에서는 그 자리가 계정(.live)이라 그대로 둔다.
   **이 규칙은 바로 위 `:not(.live)` 보다 뒤에 와야 한다.** 둘의 우선순위가 같아서
   앞에 두면 나중 것(pointer-events:none)이 이겨 글씨가 끝내 안 눌린다 — v126 에서 그랬다 */
.whoami.asback{pointer-events:auto;cursor:pointer;
  padding:12px 34px 12px 8px;margin-left:-8px;margin-right:-26px;border-radius:var(--r-s)}
/* **누를 때 상자를 띄우지 않는다** (v129) — 눌린 네모가 뜨면 고른 것처럼 보인다.
   화살표 쪽도 같다. 눌렸다는 것은 화면이 넘어가는 것으로 이미 알 수 있다 */
.whoami.asback:active,.whoami.asback:hover{background:none}
.backbtn:hover,.backbtn:active{background:none;color:var(--fg)}
.tface{width:26px;height:26px;flex:none;font-size:13px}
/* 얼굴 오른쪽 위 구석 — `.whoami` 는 얼굴·이름·태그가 가로로 선 줄이라
   오른쪽 끝에 붙이면 태그 옆으로 가 버린다. 얼굴 폭(26px)에서 되짚어 자리를 잡는다 */
.whoami .nudot{right:auto;left:26px;top:1px}
/* ⚠ **뒤로가기 노릇을 할 때는 딱지를 걷는다** (v192).
   `.whoami` 는 강호에서는 「내 이름」이고 다른 화면에서는 **뒤로가기**다.
   뒤로가기 옆의 점은 「이 화면에 볼 것이 있다」로 읽혀 거짓말을 한다 —
   결연에 서 있는데 무훈의 점이 거기 떠 있었다. 알림은 **강호에서만** 켠다 */
.whoami.asback .nudot{display:none}
/* 명호의 아이콘 단추 — 「바꾸기」 딱지(.edit)가 오른쪽 **아래**에 있으므로 위 구석을 쓴다 */
.avatar .nudot{right:2px;top:2px;width:9px;height:9px}
/* 고르기 격자의 낱낱 — 그 아이콘 하나가 새것이라는 표다 */
.facepick{position:relative}
.facepick .nudot{right:-1px;top:-1px}
.tface[hidden]{display:none}
.tag-mini{font-size:10.5px;color:var(--fg-faint);font-variant-numeric:tabular-nums;margin-left:-4px}
/* 전체보기 — **맨 왼쪽**이다 (v152). 그 옆이 천기·영석·연진 */
.fsbtn.far{margin-left:0}
.fsbtn{width:34px;height:34px;flex:none;margin-left:-6px;margin-right:2px;
  display:flex;align-items:center;justify-content:center;border-radius:2px;
  font-size:15px;line-height:1;color:var(--fg-faint)}
.fsbtn:hover{background:var(--panel-2);color:var(--fg)}
.fsbtn.on{color:var(--seal)}
/* 100년체는 명조보다 폭이 넓다 — 재화 사이를 좁혀 이름(「무명자」)이 한 줄에 서게 자리를 넘긴다 */
.purse{display:flex;gap:6px;font-family:var(--mono);font-size:11.5px;font-variant-numeric:tabular-nums}
.coin{display:flex;align-items:center;gap:4px;white-space:nowrap;padding:3px 3px;border-radius:var(--r-s)}
.coin:active{background:#ffffff14}
/* 재화를 누르면 뜨는 풀이 — 바 바로 위에 붙는다 */
.tip{position:absolute;left:12px;right:12px;z-index:45;padding:12px 14px;border-radius:var(--r-s);
  background:#1c1727f2;border:1px solid var(--line);box-shadow:0 12px 30px -12px #000;
  animation:fade .16s ease}
.tip h4{margin:0 0 6px;font-family:var(--serif);font-size:14px;font-weight:700;letter-spacing:.06em;
  display:flex;align-items:center;gap:7px}
.tip h4 .sig{font-family:var(--han);font-size:17px;color:var(--seal);margin-right:2px}
.tip p{margin:0;font-size:12px;line-height:1.75;color:var(--fg-mid)}
.tip p + p{margin-top:7px;color:var(--fg-faint)}
.tip b{color:var(--fg)}
/* ===== 각성 풀이의 빛깔 (v179) =====
   딱지(`.simg.심마` …)가 이미 각성마다 제 빛깔을 갖고 있다. **눌러서 뜨는 풀이도 같은 빛깔**이라야
   무엇을 눌렀는지가 상자에서 다시 읽힌다 — 딱지는 붉은데 풀이는 회색이면 둘이 남남으로 보인다.
   ⚠ 빛깔은 딱지와 **한 벌**이다. 한쪽을 고치면 다른 쪽도 같이 고친다 */
.tip.awk{border-color:var(--awkl,var(--line));
  background:linear-gradient(180deg,var(--awkb,#1c1727) 0%,#1c1727f2 62%);
  box-shadow:0 12px 30px -12px #000,inset 0 1px 0 var(--awkl,transparent)}
.tip.awk h4{color:var(--awkc,var(--fg))}
.tip.awk h4 .sig{color:var(--awkc,var(--seal))}
.tip.awk.심마{--awkc:var(--simma);--awkl:#5c2620;--awkb:#33150fee}
.tip.awk.명경지수{--awkc:var(--myeong);--awkl:#22375c;--awkb:#131f33ee}
.tip.awk.축기{--awkc:var(--chukgi);--awkl:#1e4d3e;--awkb:#0f2a22ee}
.tip.awk.무아지경{--awkc:#c3a9e8;--awkl:#463a5c;--awkb:#2a2333ee}
.tip.awk.결의{--awkc:var(--chungi);--awkl:#5c4a1e;--awkb:#2e2410ee}
.token-img{display:inline-block;width:18px;height:18px;object-fit:contain;vertical-align:middle;filter:drop-shadow(0 1px 2px #000b)}
.mini-token{display:inline-block;width:15px;height:15px;object-fit:contain;vertical-align:-3px;margin-right:2px;filter:drop-shadow(0 1px 1px #000a)}
.tip h4 .token-img{width:25px;height:25px}
.coin.chungi{color:var(--chungi)} .coin.yeong{color:var(--yeong)} .coin.jin{color:var(--jin)}
.vpurse{grid-area:1/1;justify-self:start;margin-left:0;gap:9px;font-size:11px}

.screens{flex:1;min-height:0;position:relative}
.screen{position:absolute;inset:0;overflow-y:auto;overscroll-behavior:contain;
  padding:calc(10px + var(--top-gap)) 16px 28px;display:none;flex-direction:column;gap:18px}
.screen.on{display:flex}
@keyframes fade{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
/* ── 화면 넘김 — 안개 ─────────────────────────────────────
   흐려졌다 또렷해지며 조금 올라온다. 수라장 대전 화면은 이 조정을 받지 않는다.
   방향을 가리지 않으므로 들어가든 나오든 같다 — 고를 것이 없는 편이 조용하다.
   (책갈피·먹 번짐·두루마리·비단 장막·검흔도 만들어 봤으나 이것으로 정했다) */
.screen.on{animation:mistin .3s ease}
.screen.on:not(#s-battle){animation:mistin-soft .28s cubic-bezier(.22,.8,.25,1)}
/* ⚠ **여기에 `filter:blur()` 를 되살리지 않는다** (v220).
   화면 하나를 통째로 흐리는 것은 **그 화면의 모든 것을 한 장으로 그려 두었다가 흐리는 일**이다.
   연보처럼 카드가 150장 깔린 화면에서는 그 한 장이 엄청나게 크다 —
   **명운 ↔ 강호를 오갈 때마다 깜빡이던 것이 이것이었다.**
   흐림 없이 작은 이동과 배율만으로 넘김을 느끼게 한다 */
@keyframes mistin{
  from{opacity:0;transform:scale(1.03)}
  to{opacity:1;transform:none}}
@keyframes mistin-soft{
  from{opacity:0;transform:translateY(6px) scale(1.012)}
  to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .screen.on{animation:fade .18s ease}
}
/* ===== 표제 =====
   게임 이름은 한자 無名者 한 덩이다. 붓글씨라 자간을 크게 벌리지 않는다 —
   획이 서로 이어지는 맛으로 읽히는 글꼴이라 널찍이 떼어 놓으면 끊어져 보인다.
   줄높이를 1 로 두면 삐침이 위아래로 잘린다 */
.logo{display:flex;flex-direction:column;align-items:center}
.title{position:relative;display:flex;flex-direction:column;align-items:center;
  padding:26px 0 6px;isolation:isolate}
/* ⚠ **글꼴이 아니라 그림이다** (v182). 붓으로 쓴 로고 한 장(`title_logo_mumyeongja_v2.webp`)을
   건다 — 글꼴로는 같은 획이 안 나온다. 그림의 잉크는 크림빛(246,237,221)이라
   `brightness(0) invert(1)` 로 **알파만 남기고 흰빛으로 다시 칠한다.**
   `filter` 로 칠하는 까닭: 흰 그림을 따로 두면 로고를 갈 때 두 장을 다 갈아야 한다.
   그림자도 `text-shadow` 가 아니라 `drop-shadow` 다 — 글자가 아니라 **모양**을 따라 진다 */
.t-main{position:relative;z-index:1;display:block;
  width:min(calc(var(--app-w) * .518),210px);height:auto;
  filter:brightness(0) invert(1)
         drop-shadow(0 2px 14px #000) drop-shadow(0 0 30px #a97cff2e);
  -webkit-user-select:none;user-select:none;pointer-events:none}
/* 한글 로고 아래에는 설치 없이 즐기는 웹 게임임을 한 줄로 알린다. */
.brandfoot{flex:none;margin-top:-2px;text-align:center;
  font-family:var(--story);font-size:12.5px;letter-spacing:.06em;white-space:nowrap;
  color:#a49b8b;opacity:.62;text-shadow:0 1px 4px #000;
  -webkit-user-select:none;user-select:none;pointer-events:none}
/* ===== 접속하고 들어가는 순간 (v187) =====
   전에는 단추를 누르는 즉시 강호로 튀었다 — 어디서 어디로 간 것인지 몸이 못 따라갔다.
   이제 **입력칸·단추·낙관이 먼저 스러지고, 로고만 남아 화면 한가운데로 내려간 뒤** 넘어간다.
   로고가 얼마나 내려갈지는 CSS 로 알 수 없다(폼 높이가 화면마다 다르다) — `titleBye()` 가 재어 넣는다.
   ⚠ 되돌아올 자리를 남긴다. `go("title")` 이 `bye` 와 인라인 값을 걷어 준다 */
/* 떠나는 접속 화면 — 강호가 떠오르는 **그 위에서** 스러진다 (v191).
   `.screen{display:none}`(0,1,0)을 이겨야 하므로 아이디로 적는다. 손은 이미 안 닿는다 */
#s-title.leaving{display:flex;z-index:30;pointer-events:none;animation:none}
#s-title.bye .signin,#s-title.bye .brandfoot{
  opacity:0;transform:translateY(12px);pointer-events:none;
  transition:opacity .42s ease,transform .42s ease}
/* ═══ 「강호에 입장하는 중입니다」 (2026-10-13 기획자) ══════════════════
   「설치 없이~」가 사라지는 그 연출을 **그대로 뒤집어** 쓴다 — 같은 .42s, 같은 12px,
   같은 결의 글꼴이다. 한 줄이 아래로 스러지면 같은 자리에서 다음 줄이 아래에서 떠오른다.
   ⚠⚠ **자리를 안 차지한다**(`absolute`). 흐름 안에 두면 로고가 그만큼 밀려 올라가,
      가운데로 내려가는 1.1초 한가운데에서 **로고가 한 번 튄다.**
   ⚠ `bottom` 은 `.title` 의 아래 여백(6px)과 같다 — 「설치 없이~」의 밑금과 같은 줄이다.
   ⚠ `translate` 안에 `-50%` 가 함께 들어 있으므로 **옮김을 따로 적지 마라** —
      `transform:translateY(12px)` 만 적으면 가운데 맞춤이 풀려 글이 왼쪽으로 튄다 */
.enterfoot{position:absolute;left:50%;bottom:6px;
  font-family:var(--story);font-size:12.5px;letter-spacing:.06em;white-space:nowrap;
  color:#a49b8b;text-shadow:0 1px 4px #000;
  opacity:0;transform:translate(-50%,12px);
  transition:opacity .42s ease,transform .42s ease;
  -webkit-user-select:none;user-select:none;pointer-events:none}
.enterfoot.on{opacity:.72;transform:translate(-50%,0)}
/* 접속 화면 */
.signin{width:min(300px,100%);margin-top:46px;display:flex;flex-direction:column;gap:9px;
  transition:opacity .42s ease,transform .42s ease}
.signin .si{padding:11px 12px;font-size:13px;text-align:center}
.signin .fbtn{flex:none}
.sns-btn{position:relative;min-height:42px;display:flex;align-items:center;justify-content:center;
  font-weight:600;letter-spacing:.01em}
.sns-icon{display:block;width:24px;height:24px;object-fit:contain;flex:none}
.sns-btn .sns-icon{position:absolute;left:12px}
.sns-btn[data-auth="facebook"] .sns-icon{width:22px;height:22px}
.sns-btn[data-auth="x"] .sns-icon{width:20px;height:20px}
/* 개발 중에만 쓰는 자리 — 단추처럼 보이지 않게 낮춰 둔다 */
.linkb{margin-top:6px;padding:7px;font-size:11px;letter-spacing:.06em;color:var(--fg-faint)}
.linkb:hover{color:var(--danger)}
/* ⚠ `.linkb.devskip` 은 **지웠다** (2026-09-30) — 접속 화면의 개발용 단추가 없어졌다.
   되살릴 일이 있거든 `index.html` 의 `#siDev` · `ui.js` 의 `devEnter` 도 함께 되살린다 */
/* ===== 메인 메뉴 =====
   **상자를 두르지 않는다.** 테와 바탕을 걷어내고 물건만 늘어놓는다 —
   격자에 담으면 게임이 아니라 설정 화면처럼 보인다.
   위에서부터 혈투·순례·결연이 굵게 서고, 자주 드나드는 넷은 하단 바 바로 위에 작게 깐다 */
/* .screen 이 이미 좌우 16px 과 카메라 자리(--top-gap)를 비워 둔다. 여기서 또 주지 않는다 */
.mscene{flex:1;min-height:0;position:relative;isolation:isolate;display:flex;flex-direction:column;padding:0}
/* 메뉴 뒤 비단 위로 흐르는 구름 그림자. 움직임 범위를 화면 안에 둔다.
   .screen 의 세로 스크롤은 가로도 auto 로 바꾸므로 밖으로 뻗은 장식이 가로·세로 스크롤을 만든다. */
.mscene::before{content:"";position:absolute;inset:8%;z-index:0;pointer-events:none;
  background:radial-gradient(ellipse 40% 24% at 23% 29%,#c7bfd12e,#c7bfd100 100%),
             radial-gradient(ellipse 48% 30% at 76% 72%,#05030b85,#05030b00 100%);
  opacity:.65;will-change:transform,opacity;animation:mainCloudShade 18s ease-in-out infinite}
.mscene > *{position:relative;z-index:1}
@keyframes mainCloudShade{
  0%,100%{transform:translateX(-8%);opacity:.48}
  50%{transform:translateX(8%);opacity:.82}}
/* 맨 윗줄 — 왼쪽에 전서구·소리, 오른쪽에 이름 */
.mtop{position:relative;flex:none;display:flex;align-items:center;gap:8px}
.mic{position:relative;flex:none;width:34px;height:34px;display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line);border-radius:var(--r-s);background:#0d0b11a6;
  font-family:var(--han);font-size:16px;line-height:1;color:#cfc6b6;
  -webkit-tap-highlight-color:transparent;transition:border-color .14s,color .14s,opacity .14s}
/* 상단 세 기능은 아이콘만 남기고 네모 테와 바탕을 걷는다. */
.mtop > .mic{border-color:transparent;background:none}
.mtop > .mic:focus-visible{outline:1px solid var(--seal);outline-offset:2px}
.mtop > .mic.more.on{border-color:transparent}
.mic:focus,.mic:focus-visible{outline:none}
.mic:active{border-color:var(--seal);color:var(--fg)}
.mic-pic{width:22px;height:22px;display:block;background:center/contain no-repeat;pointer-events:none}
.mic-pic.mail{background-image:url(assets/ui/icon_mail.webp?v=1)}
.mic-pic.chat{background-image:url(assets/ui/icon_chat.webp?v=2)}
.mic-pic.morepic{background-image:url(assets/ui/icon_more.webp?v=2);transition:filter .15s}
/* 열려 있는 동안은 **밝아지기만 한다.** 돌리지 않는다 —
   세 줄짜리 그림은 돌아가도 같은 모양이라 뜻이 안 나고, 눌린 자리가 흔들려 보인다 */
.mic.more.on .mic-pic.morepic{filter:brightness(1.18)}
.mic-pic.sound{background-image:url(assets/ui/icon_sound.webp?v=1)}
/* 교서 물음표 — 전서구·소리와 **같은 네모, 같은 크기**다 (v172 · v176 에 그림으로) */
.mic-pic.help{background-image:url(assets/ui/icon_help.webp?v=1)}
/* 제보 — 두루마리와 붓, 그리고 경고 인장 (v196). 편지·소리와 같은 슬레이트 빛깔이다 */
.mic-pic.report{background-image:url(assets/ui/icon_report.webp?v=1)}
/* 언어 — 한·EN 두 글자를 세로로 겹쳐 세우고, 쓰는 쪽만 밝힌다 */
/* 언어 단추 — 지금 쓰는 말의 국기 (v0.226). 한글 「한」·「EN」 글자를 걷었다 */
.mic-pic.flag{background-image:url(assets/ui/icon_lang_ko.png?v=1)}
/* 더보기 속에서도 같은 국기를 쓴다 — `.mic` 와 `.mmi` 양쪽에 걸린다 */
.lang.en .mic-pic.flag{background-image:url(assets/ui/icon_lang_en.png?v=1)}
/* ===== 더보기 (v0.229) =====
   맨 윗줄은 **우편 · 대화 · 교서 · 더보기** 넷이다. 소리와 언어는 자주 건드리는 것이 아니라
   더보기 안으로 들어갔다 — 늘 나와 있으면 윗줄이 여섯 칸이 되어 낙관이 밀린다 */
/* 열리면 새 아이콘이 돌아가며 밝아져 다시 누르면 닫힌다는 것을 알린다. */
.mic.more.on{border-color:var(--seal);color:var(--fg)}
/* ⚠⚠ **둘로 갈린 뒤로 넓어졌다** (2026-10-14). 왼쪽 가락집이 곡 이름·게이지·단추 다섯을
   쥐므로 162px 로는 안 된다. 다만 **화면을 넘지 않게 묶는다** — 오른쪽 끝에 붙어 자라는
   것이라, 폭을 못 박으면 좁은 손말틀에서 왼쪽이 화면 밖으로 나간다 */
.mmore{position:absolute;z-index:9;right:0;top:calc(100% + 9px);
  width:min(246px,calc(var(--app-w) - 24px));min-width:0;padding:6px;
  display:flex;flex-direction:column;gap:2px;transform-origin:top right;
  border:1px solid var(--line);border-radius:var(--r-s);
  /* ⚠ **속이 비치면 안 된다** (2026-10-14). 0.95 에서 혐투 타일의 큰 글자가
     아래 줄을 받치고 올라왔다 — 차림표는 읽히는 것이 먼저다 */
  background:#0d0b11;
  box-shadow:0 15px 36px #000c,inset 0 0 0 1px #ffffff0a}
.mmore[hidden]{display:none}
.mmore.in{animation:mmorein .18s cubic-bezier(.2,.9,.3,1)}
@keyframes mmorein{from{opacity:0;transform:scale(.88) translateY(-7px)}to{opacity:1;transform:none}}
.mmore.out{animation:mmoreout .13s ease-in forwards}
@keyframes mmoreout{to{opacity:0;transform:scale(.93) translateY(-5px)}}
.mmi{display:flex;align-items:center;gap:9px;padding:8px 10px;border:0;border-radius:var(--r-s);
  background:none;color:var(--fg-mid);font-size:12.5px;text-align:left;cursor:pointer;
  -webkit-tap-highlight-color:transparent;transition:background .14s,color .14s}
/* 약관 둘은 `a` 라 `button` 과 기본 꾸밈이 다르다 — 밑줄을 걷고 같은 줄로 세운다 (v0.294). */
/* ⚠ `.mmi.doc` 와 `.mic-pic.privacy|terms` 는 **더는 쓰지 않는다** (v0.313) —
   약관·방침·운영정책을 더보기에서 빼고 무명자 화면(`.docrow`)으로 옮겼다.
   되돌릴 날을 위해 규칙만 남겨 둔다. 그림 파일도 `assets/ui` 에 그대로 있다 */
.mmi.doc{text-decoration:none}
.mmi:active{background:#ffffff12;color:var(--fg)}
.mmi .mic-pic{position:relative;width:19px;height:19px;flex:none}
/* ⚠ `.off` 를 다는 것은 소리 둘뿐이다(`paintMute`). 바탕에 붉은 기를 넣지 않는다 */
.mmi.off .mic-pic{opacity:.3;filter:grayscale(1) brightness(.7)}
.mmi.off{color:var(--fg-faint)}
/* ═══ 더보기 속 — 왼쪽 가락집 · 오른쪽 효과음과 말 (2026-10-14 기획자) ═══════════
   ⚠ 가른 줄은 **테 한 줄**이다. 칸을 상자로 두르면 차림표 안에 또 창이 선 것처럼 보인다 */
/* ⚠ **한 칸이다** (2026-10-14 기획자가 자리를 다시 정함 — 「SFX 켜짐을 플레이리스트 기능
   하단 좌측에, 언어 변경을 하단 우측에」). 좌우로 갈랐던 것을 걷고 위아래로 세운다 */
.mm-wrap{display:flex;flex-direction:column;gap:6px;min-width:0}
/* 아래 한 줄 — 왼쪽 효과음, 오른쪽 말. 가르는 것은 **테 한 줄**이다 */
.mm-foot{display:grid;grid-template-columns:1fr 1fr;gap:3px;
  margin-top:1px;padding-top:5px;border-top:1px solid var(--line)}
.mm-foot .mmi{padding:7px 8px;font-size:11.5px;min-width:0}
.mm-foot .mmi-t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mm-h{margin:1px 0 0;padding:0 4px;font-family:var(--serif);font-size:10.5px;font-weight:700;
  letter-spacing:.08em;color:var(--fg-faint)}
/* 곡 줄과 소리 손잡이가 나란히 선다 (2026-10-14 기획자 — 「플레이리스트 옆에 볼륨」).
   ⚠ 손잡이는 **곡 줄과 같은 키**로 선다(`align-items:stretch`) — 짧게 두면 끄는 거리가
     모자라 손끝이 조금만 움직여도 소리가 확 뛴다 */
/* ⚠⚠ **키를 곡 수와 무관하게 못 박는다**(곡 줄의 윗키와 같은 112px). 두 까닭이다 —
   ① 곡이 둘일 때는 줄이 88px 라 **손잡이의 길이 35px 밖에 안 남아** 한 화소가 3%씩 뛴다.
   ② 곡을 더하면 패널 키가 들쭉날쭉해진다. 여기서 묶어 두면 줄이 늘어도 자리가 안 움직인다 */
.bgrow{display:flex;align-items:stretch;gap:7px;min-width:0;height:112px}
.bgrow .bgl{flex:1;min-width:0;max-height:none}
/* 곡 줄 — 곡이 늘면 **이 안에서 구른다**. 넷째 줄부터 구르게 키를 묶는다 */
.bgl{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1px;
  max-height:112px;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:none}
.bgl::-webkit-scrollbar{display:none}
.bgi{width:100%;display:flex;align-items:center;gap:7px;padding:6px 6px;border:0;
  border-radius:var(--r-s);background:none;color:var(--fg-mid);
  font:inherit;font-size:12px;text-align:left;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.bgi:active{background:#ffffff12}
.bgi-n{flex:none;width:12px;font-family:var(--mono);font-size:10px;color:var(--fg-faint);
  font-variant-numeric:tabular-nums}
.bgi-t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bgi.on{color:var(--fg)}
.bgi.on .bgi-n{color:var(--og-hi,#9b8fbb)}
/* 지금 흐르는 곡 — **세 줄이 춤춘다**. 멈추면 선 채로 남는다(`.go` 가 빠진다) */
.bgi-eq{flex:none;display:none;align-items:flex-end;gap:1.5px;height:11px}
.bgi.on .bgi-eq{display:flex}
.bgi-eq i{display:block;width:2px;height:3px;border-radius:1px;background:var(--og-hi,#9b8fbb)}
.bgi.go .bgi-eq i{animation:bgeq .9s ease-in-out infinite}
.bgi.go .bgi-eq i:nth-child(2){animation-delay:-.3s}
.bgi.go .bgi-eq i:nth-child(3){animation-delay:-.6s}
/* ⚠ 키만 흔든다 — `transform` 으로 늘리면 둥근 끝이 같이 눌린다. 세 줄뿐이라 값이 싸다 */
@keyframes bgeq{0%,100%{height:3px}50%{height:11px}}
@media (prefers-reduced-motion:reduce){ .bgi.go .bgi-eq i{animation:none;height:7px} }
/* ═══ 소리 크기 손잡이 — 세로 (2026-10-14 기획자) ═══════════════════
   **BGM 과 효과음을 함께** 줄인다. 끄고 켜는 것은 아래의 SFX 단추가 따로 쥔다 —
   크기와 끄기는 뜻이 다른 둘이라 한 값에 담지 않는다(§가락집의 「끄기와 멈춤」과 같은 법).
   ⚠ 위에서 아래로 수 · 길 · 나팔 차례다. 수를 맨 위에 두는 것은 끌 때 손가락이
     **아래쪽을 가리기** 때문이다 — 위에 있어야 끄는 동안에도 값이 보인다.
   ⚠ `touch-action:none` 이 목숨줄이다. 없으면 브라우저가 세로 끌기를 **곡 줄 구르기**로
     먼저 가져가 손잡이가 움직이지 않는다 */
.bgvol{flex:none;width:34px;display:flex;flex-direction:column;align-items:center;gap:6px;
  padding:7px 0 6px;border-radius:10px;
  background:linear-gradient(180deg,#ffffff0d,#ffffff05);border:1px solid var(--line);
  cursor:pointer;touch-action:none;-webkit-tap-highlight-color:transparent;
  user-select:none;-webkit-user-select:none}
.bgvol:focus-visible{outline:2px solid var(--og-hi,#9b8fbb);outline-offset:2px}
.bv-n{flex:none;font-family:var(--mono);font-size:9.5px;line-height:1;
  font-variant-numeric:tabular-nums;color:var(--fg-faint);transition:color .12s}
.bgvol.live .bv-n{color:var(--og-hi,#9b8fbb)}
/* 길 — 가운데를 길게 쓴다. `overflow` 를 막지 않는 것은 **구슬이 끝에서 걸치기** 때문이다 */
.bv-rail{position:relative;flex:1;min-height:34px;width:5px;border-radius:3px;
  background:#ffffff1c;box-shadow:inset 0 0 4px #0007}
.bv-fill{position:absolute;left:0;right:0;bottom:0;height:100%;border-radius:3px;
  background:linear-gradient(180deg,var(--og-hi,#9b8fbb),#6f638f);
  box-shadow:0 0 8px #9b8fbb55}
/* 구슬 — 채운 자리의 꼭대기에 걸터앉는다. `bottom` 을 %로 주고 제 키의 절반만큼 내린다 */
.bv-knob{position:absolute;left:50%;bottom:100%;width:11px;height:11px;border-radius:50%;
  transform:translate(-50%,50%);background:#f2ecdf;
  box-shadow:0 1px 5px #000b,0 0 0 1px #00000066,0 0 10px #9b8fbb66;
  transition:transform .09s cubic-bezier(.2,.9,.3,1)}
.bgvol.live .bv-knob{transform:translate(-50%,50%) scale(1.22)}
/* 나팔 — 소리 크기에 따라 물결이 하나씩 꺼진다. 0 이면 통째로 흐려진다 */
.bv-ic{flex:none;display:block;width:15px;height:15px;color:var(--fg-mid);transition:color .12s,opacity .12s}
.bv-ic svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.bv-ic svg .f{fill:currentColor;stroke:none}
.bgvol.lv0 .bv-ic{opacity:.3}
.bgvol.lv0 .bv-ic .w,.bgvol.lv1 .bv-ic .w2{opacity:0}
.bgvol.lv0 .bv-fill{background:#ffffff26;box-shadow:none}
.bgvol.lv0 .bv-knob{background:#8b8597;box-shadow:0 1px 4px #000a}
@media (prefers-reduced-motion:reduce){ .bv-knob{transition:none} }
/* 게이지 — **누르는 자리가 아니다**(기획자가 일부러 뺐다). 손길을 아예 안 받는다 */
.bgbar{position:relative;height:3px;margin:1px 4px 0;border-radius:2px;
  background:#ffffff1c;overflow:hidden;pointer-events:none}
.bgbar i{position:absolute;left:0;top:0;bottom:0;width:0;border-radius:2px;
  background:linear-gradient(90deg,var(--og,#6b5d8c),var(--og-hi,#9b8fbb))}
.bgtime{display:flex;justify-content:space-between;margin:0;padding:0 4px;
  font-family:var(--mono);font-size:9.5px;color:var(--fg-faint);font-variant-numeric:tabular-nums}
/* 단추 다섯 — 가운데가 크다 */
.bgctl{display:flex;align-items:center;justify-content:space-between;gap:2px;padding:1px 2px 2px}
.bgc{flex:none;width:28px;height:28px;display:flex;align-items:center;justify-content:center;
  padding:0;border:0;border-radius:50%;background:none;color:var(--fg-mid);cursor:pointer;
  -webkit-tap-highlight-color:transparent;transition:color .14s}
.bgc svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.bgc svg .f{fill:currentColor;stroke:none}
.bgc:active{color:var(--fg)}
.bgc.on{color:var(--og-hi,#9b8fbb)}
/* ⚠⚠ **켜고 끄는 둘은 꺼지면 흑백으로 가라앉는다** (2026-10-14 기획자 — 「on/off 표기가
   너무 약해, 꺼져 있으면 아이콘을 아예 비활성화 흑백 처리」). 빛깔만 바꿔서는
   켜진 것인지 꺼진 것인지 한눈에 안 들어왔다 — 밝기까지 함께 내린다.
   ⚠ `filter` 는 **누를 때만** 바뀐다(상태가 바뀌는 그 순간뿐) — 늘 도는 연출이 아니라
     v220 의 그 함정과는 다른 자리다 */
.bgc.tg{opacity:.34;filter:grayscale(1) brightness(.75)}
.bgc.tg.on{opacity:1;filter:none}
.bgc.big{width:34px;height:34px;color:var(--fg);
  background:linear-gradient(160deg,#2b2535,#171320);
  border:1px solid var(--og,#6b5d8c);box-shadow:inset 0 1px 0 #ffffff1f,0 2px 7px #0008}
.bgc.big svg{width:17px;height:17px}
/* 재생과 멈춤은 **한 단추**다 — 도는 동안에는 멈춤 그림이 선다 */
.bgc .ic-pause,.bgc.on .ic-play{display:none}
.bgc.on .ic-pause{display:block}
/* 되풀이 단추의 「1」 — 켜졌을 때만 보인다 */
.bgc #bgRepOne,.bgc svg text.one{fill:currentColor;stroke:none;font-size:9px;font-weight:800;
  text-anchor:middle;opacity:0;font-family:var(--mono)}
.bgc.on svg text.one{opacity:1}
.mmi-t{flex:1;min-width:0;white-space:nowrap}
.mic-pic.privacy{background-image:url(assets/ui/icon_privacy.webp?v=4)}
.mic-pic.terms{background-image:url(assets/ui/icon_terms.webp?v=4)}


/* ⚠ 켜짐·꺼짐은 **밝기 하나로만** 가른다 (v0.313).
   예전에는 켜짐에 청록 불을, 꺼짐에 붉은 빗금을 달았는데 **과했다** —
   차림표에서 소리 둘만 색을 쥐고 있으면 그 둘이 경고처럼 읽힌다.
   글자가 이미 「켜짐·꺼짐」이라 말하고 있으니 흐려지는 것으로 족하다 */
.mmi.sound-toggle.off{color:var(--fg-faint)}
.mmi.sound-toggle.off .mic-pic{opacity:.3;filter:grayscale(1) brightness(.7)}

/* ===== 전서구 (v187) =====
   갈래 셋(우편함·업데이트·개발자 노트)이 한 화면을 나눠 쓴다. 갈래 단추는 **교서와 같은 것**(`.hptab`)이다 —
   같은 손놀림에 같은 모양을 쓴다. 다만 셋뿐이라 가로를 고르게 나눈다.
   상자는 **무훈 상자(`.ftbox`)와 한 식구**다. 테·바탕·모서리를 그대로 쓰고,
   받을 것이 있을 때 테를 밝히는 것까지 같다 — 화면마다 상자 모양을 새로 지으면 같은 판으로 안 읽힌다 */
#s-mail .hptabs{gap:6px;margin-bottom:12px;flex:none}
#s-mail .hptab{flex:1;text-align:center;position:relative;padding:8px 6px;font-size:12px}
/* 갈래 위의 붉은 점 — 받을 우편이 있으면. 하단 바의 무훈 점과 같은 빛깔이다 */
.tabdot{position:absolute;right:5px;top:5px;width:5px;height:5px;border-radius:50%;
  background:var(--warn);box-shadow:0 0 6px #e8b34dcc}
/* ⚠ 목록 칸이 **남은 높이를 다 먹는다** (v0.226) — 안 그러면 아래 「모든 우편을 확인하셨습니다」가
   40vh 띠 안에서만 가운데라 화면 위쪽으로 치우쳐 보였다. 우편이 있을 때는 여전히 위에서부터 쌓인다 */
.mllist{display:flex;flex-direction:column;gap:9px;padding-bottom:6px;flex:1 1 auto}
/* 받을 것이 없을 때 — 갈래 단추 아래 **남은 자리의 한가운데**에 한 줄 (v192).
   빈 목록을 맨 위에 붙여 두면 화면이 잘못 열린 것처럼 보인다.
   `.screen` 이 세로 flex 라 `flex:1` 이면 남은 자리를 다 먹는다 */
/* ⚠ 높이는 **판 기준**이다 (v0.321). `vh` 로 두면 판이 아니라 진짜 화면을 재므로,
   넓은 화면에서 판보다 큰 값이 나와 넘친다 */
.mlnone{flex:1;min-height:calc(var(--app-h) * .4);display:flex;align-items:center;justify-content:center;
  margin:0;text-align:center;font-size:12.5px;letter-spacing:.02em;color:var(--fg-faint)}
/* ⚠⚠ **격자 안에서는 줄을 통째로 쓴다** (2026-10-14 기획자 — 「안내 텍스트는 가로폭에서
   가운데 정렬이야」). `.grid` 가 3열이라 안내문이 **첫 칸 하나에만** 들어가,
   제 칸 안에서는 가운데인데 화면으로 보면 왼쪽 3분의 1에 치우쳐 있었다.
   `flex`·`text-align` 을 아무리 걸어도 **칸이 좁은 것**이 원인이라 고쳐지지 않는다 */
.grid > .mlnone{grid-column:1 / -1}
.mlbox{border:1px solid var(--line);border-radius:var(--r-s);background:var(--panel);
  padding:12px 13px;transition:border-color .16s,opacity .16s}
/* 받을 것이 있는 우편은 테를 밝혀 둔다 — 무훈의 `.ftbox.ok` 와 같은 규칙이다 */
.mlbox.ok{border-color:var(--seal);background:linear-gradient(180deg,#221b2acc,var(--panel))}
.mlbox.off{opacity:.46}
/* 우편 한 통 — **그림 · 글 · 단추** 세 칸이 가로로 선다.
   글 칸만 늘어나고(minmax 0) 나머지는 제 크기를 지킨다 — 제목이 길어도 단추가 밀리지 않는다 */
.mlbox.ok,.mlbox.off{display:grid;grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;gap:11px}
.ml-ico{flex:none;display:flex;align-items:center;justify-content:center;gap:2px;
  width:46px;height:46px;border-radius:var(--r-s);
  background:#0e0b14;border:1px solid var(--line-soft);box-shadow:inset 0 0 12px #0009}
.ml-ico img{width:26px;height:26px;object-fit:contain;filter:drop-shadow(0 1px 2px #000b)}
/* 보상이 둘 이상이면 한 칸에 겹쳐 세운다 — 칸을 늘리면 글 자리가 줄어든다 */
.ml-ico img + img{width:20px;height:20px;margin-left:-6px}
.ml-t{font-family:var(--serif);font-size:13.5px;font-weight:800;letter-spacing:.02em;color:var(--fg);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ml-d{margin-top:3px;font-size:11px;line-height:1.5;color:var(--fg-mid);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* 고객 문의 답변은 읽는 편지다. 길이에 따라 상자를 늘리고 줄바꿈을 모두 보존한다. */
.mlbox.reply .ml-d{display:block;overflow:visible;-webkit-line-clamp:unset;
  white-space:pre-wrap;overflow-wrap:anywhere}
.mlbox.reply{align-items:start}
.ml-f{display:flex;align-items:center;gap:8px;margin-top:6px}
.ml-pays{display:flex;align-items:center;gap:8px;min-width:0}
/* 재화마다 제 빛깔이다 — 하단 바(`.coin.*`)와 같은 색을 쓴다.
   셋을 한 색으로 적으면 아이콘을 들여다봐야 무엇인지 알 수 있다 */
.ml-pay{display:inline-flex;align-items:center;gap:3px;
  font-family:var(--mono);font-size:11px;font-variant-numeric:tabular-nums;color:var(--fg-mid)}
.ml-pay.chungi{color:var(--chungi)} .ml-pay.yeong{color:var(--yeong)} .ml-pay.jin{color:var(--jin)}
.ml-pay .mini-token{margin:0}
/* 단추와 기한은 **한 기둥**이다 (v191) — 기한은 그 단추에 붙은 말이라 바로 아래 선다.
   글 칸 안에 두었더니 보상 줄과 나란히 서서 **보상의 일부처럼** 읽혔다 */
.ml-act{flex:none;display:flex;flex-direction:column;align-items:center;gap:5px}
/* 남은 기간 — 평소엔 조용하고, 사흘 안이면 경고 빛깔로 돈다 */
.ml-left{flex:none;text-align:center;white-space:nowrap;
  font-family:var(--mono);font-size:10px;letter-spacing:.04em;color:var(--fg-faint)}
.ml-left.soon{color:var(--warn)}
.ml-left.over{color:var(--danger)}
/* 수령 — 무훈의 수령 단추(`.ft-go`)와 같은 치수·같은 빛깔이다 */
.ml-go{flex:none;min-width:62px;padding:9px 12px;border-radius:var(--r-s);
  border:1px solid var(--chungi);background:#2a2110;color:var(--chungi);
  font-family:var(--serif);font-size:12px;font-weight:700;letter-spacing:.04em;
  box-shadow:0 0 10px -2px #d4a84355;-webkit-tap-highlight-color:transparent;transition:.14s}
.ml-go:not([disabled]):active{transform:scale(.97);background:#3a2d14}
.ml-go[disabled]{border-color:var(--line);border-style:dashed;background:var(--panel-2);
  color:var(--fg-faint);box-shadow:none}
/* 업데이트·개발자 노트 — 읽는 상자다. 가로로 나누지 않고 위에서 아래로 흐른다 */
.note-box{display:block}
.ml-h{display:flex;align-items:baseline;gap:9px;margin-bottom:7px;
  padding-bottom:7px;border-bottom:1px solid var(--line-soft)}
.ml-v{font-family:var(--mono);font-size:12.5px;font-weight:700;letter-spacing:.06em;color:var(--seal)}
/* 개발자 노트의 머리는 판 번호가 아니라 **글의 제목**이다 — 명조 대신 본문 얼굴로 */
.ml-v.alt{font-family:var(--serif);font-size:13.5px;font-weight:800;letter-spacing:.02em;color:var(--fg)}
/* 카테고리 꼴 판 (v0.225) — 인사말 · 머리글 · 맺음말. `docs/업데이트 내역 작성법.md` */
/* ⚠⚠ **업데이트 내역 글씨는 개발자 노트 본문(`.ml-p`)과 같은 크기다** (2026-10-16
   기획자 — 「업데이트 내역 폰트를 개발자노트 본문 크기에 맞춰」). 둘은 같은 탭에서
   나란히 읽히는 글이라 크기가 갈리면 한쪽이 공지처럼, 한쪽이 잡담처럼 보인다.
   ⚠ 고치려거든 **`.ml-p` 와 함께** 고친다 — 한쪽만 바꾸면 다시 갈린다 */
.ml-greet{margin:0 0 10px;font-size:11.5px;line-height:1.75;color:var(--fg-mid)}
.ml-greet.end{margin:12px 0 0}
.ml-cat{margin:12px 0 5px;font-size:11.5px;font-weight:800;color:var(--fg);letter-spacing:.04em;
  padding-left:8px;border-left:2px solid var(--seal)}
/* 가장 위의 판에만 서는 「최신」 딱지 (v0.225) */
.ml-new{font-size:10px;font-weight:700;line-height:1;padding:3px 6px 2px;border:1px solid var(--seal);border-radius:3px;
  color:var(--seal);background:#c9524a1a;letter-spacing:.08em;align-self:center}
.ml-date{margin-left:auto;font-family:var(--mono);font-size:10px;color:var(--fg-faint)}
.ml-li{margin:0;padding-left:15px;display:flex;flex-direction:column;gap:5px}
.ml-li li{font-size:11.5px;line-height:1.75;color:var(--fg-mid)}
.ml-li li::marker{color:var(--fg-faint)}
/* ⚠⚠ **줄바꿈을 그대로 세운다** (2026-10-15, 집법전 §3.3.4). 개발자 노트의 광대 글은
   「~했습니다.」로 끊는 리듬이 글의 반이다 — HTML 기본값은 그 줄바꿈을 뭉개 한 줄로 만든다.
   문단은 빈 줄로 나뉘고(`notes.js`), 문단 **안의** 줄바꿈은 여기서 산다 */
.ml-p{margin:0 0 7px;font-size:11.5px;line-height:1.75;color:var(--fg-mid);white-space:pre-line}
.ml-p:last-child{margin-bottom:0}
/* ⚠⚠ **마디 제목** — 글 안에서 `[대괄호]` 한 줄이 이것이 된다 (2026-10-15 기획자가 정함).
   긴 글은 마디가 눈에 보여야 읽힌다 — 「시작하며」부터 「끝 맺으며」까지 일곱 마디다.
   ⚠ 본문보다 **밝고 조금 크게**, 그리고 앞에 세로 획을 세워 글줄과 갈린다.
   ⚠ 첫 마디는 위 여백을 줄인다 — 제목 바로 밑에 붙어 서면 두 번 띄운 것처럼 보인다 */
.ml-sec{margin:14px 0 8px;padding:5px 10px;border-left:3px solid var(--og,#6b5d8c);
  border-radius:0 3px 3px 0;background:#ffffff0a;
  font-family:var(--serif);font-size:12.5px;font-weight:800;letter-spacing:.02em;color:var(--fg)}
.ml-sec:first-child{margin-top:2px}
/* ⚠⚠ **접힌 글에 「펼치기 ▼」를 적는다** (2026-10-16 기획자 — 「펼쳐지는지 알기 어려워」).
   ⚠ **누르는 자리가 아니다** — 상자 아무 데나 누르면 펼쳐지고, 이 줄은 그 사실을 말해 주는
     표시다. `pointer-events:none` 이라 이 글자를 눌러도 **상자가 받는다** */
.ml-more{margin:9px 0 0;padding-top:7px;border-top:1px dashed var(--line-soft);
  text-align:center;font-size:10.5px;letter-spacing:.06em;color:var(--fg-faint);
  pointer-events:none;user-select:none}
.note-box:not(.open)[data-note] .ml-h{margin-bottom:0;padding-bottom:0;border-bottom:0}
.note-box.open .ml-more{color:var(--fg-faint);opacity:.75}

/* 맺는 한 줄 — 편지의 낙관이다. 오른쪽 끝에 붙이고 한 칸 띄운다 */
.ml-sig{margin:11px 0 0;text-align:right;
  font-family:var(--serif);font-size:11.5px;letter-spacing:.04em;color:var(--fg-faint)}

/* ===== 무훈 (v172 · 무훈 기획 §4.2) =====
   격자를 쓰지 않는다 — 글이 길고 하나씩 읽고 하나씩 누르는 자리라 **가로 폭을 꽉 채워** 세로로 쌓는다 */
/* 「받을 무훈이 N개 있습니다」 줄(`.ftnote`)은 걷었다 (v186) —
   **하단 바의 붉은 점이 이미 그 말을 한다.** 받을 것은 상자마다 천기 단추가 켜져 있어 눈으로 세진다 */
.ftlist{display:flex;flex-direction:column;gap:9px;padding-bottom:6px}
/* 무훈 진행도 — 위에 보상 넷, 가운데 막대, 아래 눈금 수. 끝 칸(100%)은 막대 끝에 붙는다 */
.ftprog{flex:none;margin-bottom:12px;padding:12px 14px 10px;border:1px solid var(--line);
  border-radius:var(--r-s);background:linear-gradient(180deg,#1d1824e6,var(--panel))}
.fp-h{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.fp-t{font-family:var(--serif);font-size:14px;font-weight:800;letter-spacing:.04em;color:var(--fg)}
.fp-p{font-family:var(--num);font-size:15px;font-weight:800;color:var(--chungi);font-variant-numeric:tabular-nums}
/* 좌우 끝 보상이 상자 밖으로 안 나가게 안쪽으로 한 뼘 들인다 */
.fp-track{position:relative;margin:10px 26px 0 8px}
.fp-rws{position:relative;height:44px}
.fp-rw{position:absolute;bottom:4px;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:2px;min-width:46px;padding:4px 5px 3px;
  border:1px dashed var(--line);border-radius:var(--r-s);background:var(--panel-2);
  font-family:var(--mono);font-size:9.5px;font-weight:700;color:var(--fg-faint);font-variant-numeric:tabular-nums;
  -webkit-tap-highlight-color:transparent;transition:.14s}
.fp-rw .mini-token{width:16px;height:16px;margin:0;filter:grayscale(1) opacity(.7)}
/* 받을 수 있다 — 무훈 수령 단추와 같은 천기 빛 */
.fp-rw.ok{border:1px solid var(--chungi);color:var(--chungi);background:#2a2110;
  box-shadow:0 0 10px -1px #d4a84377;animation:fpglow 1.6s ease-in-out infinite}
.fp-rw.ok .mini-token{filter:none}
.fp-rw.ok:active{transform:translateX(-50%) scale(.95)}
@keyframes fpglow{50%{box-shadow:0 0 16px 1px #d4a843aa}}
/* 이미 받았다 — 빛을 빼고 체크를 얹는다 */
.fp-rw.got{border-style:solid;border-color:#3d5a3f;opacity:.7}
.fp-ck{position:absolute;top:-6px;right:-6px;width:15px;height:15px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-style:normal;font-size:10px;
  background:#2f7d45;color:#fff;box-shadow:0 1px 3px #000a}
.fp-bar{position:relative;height:6px;border-radius:3px;background:#ffffff12;border:1px solid #2a2530;overflow:hidden}
.fp-bar > i{display:block;height:100%;border-radius:3px;
  background:linear-gradient(90deg,#8a6f3a,var(--chungi));transition:width .4s ease}
.fp-tks{position:relative;height:16px}
.fp-tk{position:absolute;top:-10px;transform:translateX(-50%);display:flex;flex-direction:column;align-items:center}
.fp-tk::before{content:"";width:7px;height:7px;border-radius:2px;background:#4a4352;border:1px solid #0008}
.fp-tk.on::before{background:var(--chungi)}
.fp-tk b{margin-top:2px;font-family:var(--mono);font-size:9.5px;font-weight:700;color:var(--fg-faint)}
.fp-tk.on b{color:#e6dccb}
.ftbox{border:1px solid var(--line);border-radius:var(--r-s);background:var(--panel);
  padding:12px 13px 11px;transition:border-color .16s,opacity .16s}
/* 받을 것이 있으면 테를 밝혀 둔다 — 목록에서 눈이 먼저 간다 */
.ftbox.ok{border-color:var(--seal);background:linear-gradient(180deg,#221b2acc,var(--panel))}
.ftbox.done{opacity:.46}
.ft-h{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.ft-n{font-family:var(--serif);font-size:14.5px;font-weight:800;letter-spacing:.03em;color:var(--fg)}
.ft-t{font-family:var(--mono);font-size:10px;color:var(--fg-faint);white-space:nowrap;flex:none}
.ft-d{margin:4px 0 9px;font-size:11.5px;line-height:1.55;color:var(--fg-mid)}
.ft-bar{height:5px;border-radius:3px;background:#ffffff12;border:1px solid #2a2530;overflow:hidden}
.ft-bar > i{display:block;height:100%;border-radius:3px;
  background:linear-gradient(90deg,#6f5ba8,#b79bff);transition:width .3s ease}
.ftbox.ok .ft-bar > i{background:linear-gradient(90deg,#8a6f3a,var(--chungi))}
.ft-f{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:9px}
.ft-c{font-family:var(--mono);font-size:11px;font-variant-numeric:tabular-nums;color:var(--fg-mid)}
/* 수령 단추 — 글자 대신 **천기 아이콘과 수**다. 무엇을 받는지가 한눈에 읽힌다 (v174).
   켜고 끄는 것이 눈에 보여야 한다 — 끈 것은 테도 글씨도 죽이고 아이콘까지 빛을 뺀다 */
.ft-go{flex:none;min-width:88px;padding:7px 13px;border:1px solid var(--line);border-radius:var(--r-s);
  display:inline-flex;align-items:center;justify-content:center;gap:4px;
  font-family:var(--mono);font-size:12px;font-weight:700;font-variant-numeric:tabular-nums;
  color:var(--fg-faint);background:var(--panel-2);
  -webkit-tap-highlight-color:transparent;transition:.14s}
.ft-go .mini-token{width:14px;height:14px;margin:0;transition:filter .14s}
/* 켜짐 — 천기 빛깔로 */
.ft-go:not(.off){border-color:var(--chungi);color:var(--chungi);background:#2a2110;
  box-shadow:0 0 10px -2px #d4a84355}
.ft-go:not(.off):active{transform:scale(.97);background:#3a2d14}
/* 꺼짐 — 아이콘의 빛을 빼서 「아직 아니다」가 그림에서도 읽히게 한다 */
.ft-go.off{opacity:.42;border-style:dashed}
.ft-go.off .mini-token{filter:grayscale(1) opacity(.7)}
/* 하단 넷의 붉은 점 — 받을 무훈이 있으면 */
.mdk{position:relative}
.mdk-dot{position:absolute;right:calc(50% - 30px);top:-2px;width:7px;height:7px;border-radius:50%;
  background:var(--warn);box-shadow:0 0 7px #e8b34dcc;pointer-events:none}
.mdk-dot[hidden]{display:none}
/* ⚠ 큰 칸(`.mbig`)에 붙는 점은 **오른쪽 위 귀**에 선다 — 하단 넷의 자리셈
   (`right:calc(50% - 30px)`)은 그림표 옆에 붙이려고 잡은 것이라 큰 칸에서는 한가운데에 뜬다 */
.mbig .mdk-dot{right:8px;top:8px;width:8px;height:8px}
/* 거저 열 봉이 있다는 금빛 — 「1일 무료」 글자와 같은 빛이다 */
.buy span.free{color:var(--warn);font-weight:800;letter-spacing:.02em}
/* ═══ 「1일 무료」 단추 — 점과 숨 (2026-10-06 기획자) ════════════════════════
   메인에서 결연에 점을 보고 들어와도 **안에서는 어느 단추인지 말해 주지 않았다.**
   점은 다른 데와 같은 `.nudot` 이고(`ui.js` 의 `packBuy` 가 끼운다), 여기서는 **자리만** 잡는다.
   ⚠ 빛깔은 금빛(`--warn`)이다 — 「1일 무료」 글자·메인의 결연 점과 같은 빛이라야
      셋이 한 가지를 가리키는 것으로 읽힌다. 붉은 점은 「받을 것이 있다」의 자리다.
   ⚠⚠ **두 켜의 수를 양끝에서 같게 둔다.** 수가 다르면 브라우저가 모자란 쪽을 뒤에서 채워
      한가운데에서 툭 끊긴다 — 출석 칸(`a7now`)에서 같은 것을 밟았다(2026-10-06).
      그래서 0% 에도 바깥 빛을 **투명한 채로** 세워 둘을 둘에 맞춘다.
   ⚠ 빠르기와 숨결은 출석 칸·「지금 갈 관문」과 **같은 1.9s 사인 곡선**이다 —
      한 화면에서 두 숨이 따로 뛰면 어지럽다.
   ⚠ 테두리는 숨이 아니라 **그냥 금빛으로 둔다.** 테까지 함께 뛰면 단추가 들썩여 보인다 */
.buy .nudot{--nx:5px;--ny:5px}
.buy.freepick{border-color:var(--warn);
  animation:buyfree 1.9s cubic-bezier(.37,0,.63,1) infinite}
@keyframes buyfree{
  0%,100%{box-shadow:0 0 0 1px #e8b45f4d,0 0 12px 1px #e8b45f00}
  50%    {box-shadow:0 0 0 1px #e8b45fcc,0 0 18px 3px #e8b45f59}}
@media (prefers-reduced-motion:reduce){
  .buy.freepick{animation:none;box-shadow:0 0 0 1px var(--warn),0 0 12px 1px #e8b45f45} }
/* ===== 새로 열린 것을 알리는 노랑 딱지 (v179) =====
   `.mdk-dot` 과 **같은 빛깔·같은 크기**다. 다른 것은 자리를 잡는 방식뿐이라
   여기는 `--nx`·`--ny` 로 붙일 자리를 받는다. 빛깔을 두 벌로 두지 않는다 —
   한쪽만 고쳐지면 같은 뜻이 화면마다 다른 색으로 나온다 */
.nudot{position:absolute;right:var(--nx,-1px);top:var(--ny,-1px);
  width:7px;height:7px;border-radius:50%;
  background:var(--warn);box-shadow:0 0 7px #e8b34dcc;pointer-events:none;
  animation:nudotb 1.7s ease-in-out infinite}
.nudot[hidden]{display:none}
@keyframes nudotb{50%{box-shadow:0 0 12px 2px #e8b34d}}
/* 소리를 껐으면 눌린 채로 둔다 — 지금 어느 쪽인지 한눈에 보여야 한다 */
.mic.off{opacity:.42;border-style:dashed;color:var(--fg-faint)}
/* 좌상단 프로필을 먼저 세운다. 나머지 상단 기능 단추는 오른쪽에 모인다. */
.mbrand{order:-1;margin-right:auto;display:flex;flex-direction:column;align-items:flex-start;gap:3px;min-width:0}
/* 무명자 로고는 메인의 우측 하단, 기존 무명자 진입 단추에 둔다. */
.bottom-brand{display:none;width:clamp(36px,calc(var(--app-w) * .11),47px);height:auto;opacity:.86;
  filter:brightness(0) invert(1)
         drop-shadow(0 1px 7px #000) drop-shadow(0 0 16px #a97cff22);
  -webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}
.whoami.live .bottom-brand{display:block}
.whoami.live{pointer-events:none;position:absolute;right:16px;top:0;height:60px;margin:0;padding:0;
  flex-direction:column;align-items:flex-end;justify-content:center;gap:2px}
.bottom-copy{display:none;font-family:var(--mono);font-size:7px;
  font-weight:600;line-height:1.05;letter-spacing:.02em;color:var(--fg-faint);white-space:nowrap;text-align:right}
.whoami.live .bottom-copy{display:block}
/* 작은 판에서는 재화와 한 줄 문구의 가로폭이 겹친다. 글자를 줄이지 않고 둘로 접는다. */
@media (max-width:390px){.whoami.live .bottom-copy{max-width:105px;white-space:normal}}
@media (max-width:340px){
  .whoami.live .bottom-copy{max-width:100px}
  .topbar:has(.whoami.live) .purse{gap:3px;font-size:10px}
  .topbar:has(.whoami.live) .coin{gap:2px;padding-inline:1px}
  .topbar:has(.whoami.live) .token-img{width:15px;height:15px}}
.whoami.live .tface,.whoami.live .screen-name,.whoami.live .tag-mini{display:none}
.whoami.live .nudot{right:-1px;left:auto;top:0}

/* 혈투·결연·순례 — 맨 윗줄과 하단 넷 사이 남은 자리를 다 차지하고, 그 안에서 세로 정중앙에 선다 (v126).
   지난 배치: 반개짜리 판 셋(v126) → 왼쪽 정렬(v150) → 판을 걷고 좌우로 흩음(v153) → 격자(v166) */
/* v166 — **혈투가 위 한 칸, 아래를 결연·순례가 반씩.**
   v150~v153 은 셋을 좌우로 흩어 놓고, 하단 넷의 그림 자리를 JS(`alignMenu()`)가 재어
   `--mpad`·`--mvx` 에 넣어야 줄이 맞았다. 격자로 세우니 CSS 혼자 선다 — 그 함수는 걷었다.
   **결연이 왼쪽인 것은 아래 「명운」 바로 위이기 때문이다** — 명운과 결연은 한 몸이다.

   ⚠ **단추 그림을 새로 그릴 때 볼 값은 이 둘뿐이다.**
     --arh  혈투     4 : 3 = 1.3333   (원본 1536 × 1152 권장)
     --arf  결연·순례  1 : 1 = 1        (원본 1024 × 1024 권장)
   **가로 ÷ 세로**를 숫자로 적는다 (`4/3` 이 아니라 `1.3333`). 아래 셈에 그대로 들어가기 때문이다 —
   `aspect-ratio` 는 숫자도 받으므로 한 값으로 둘을 다 쓴다. 세로로 긴 그림이면 `--arh:.8333` (5:6).
   그림이 칸을 **꽉 채우게** 되면 `--fit:cover` 로 바꾼다 — 지금은 귀퉁이가 비어 있어 `contain` 이다 */
.mmenu{flex:1;min-height:0;display:flex;align-items:center;justify-content:center;
  /* 아래 `.mmg` 가 이 칸의 **높이**를 알아야 한다. `inline-size` 로는 모자라 `size` 로 잰다 */
  container-type:size}
/* 반 칸의 너비 하나로 셋이 다 정해진다. **가로로도 세로로도 안 넘치는 값**을 고른다 —
   비율만 박아 두면 짧은 화면(320×568)에서 혈투가 위로 17px 삐져나갔다 (v166 에 실제로 그랬다).
     세로로 다 쓰면  (2w+g)/arh + g + w/arf = 높이
     → w = (높이 − g(1 + 1/arh)) / (2/arh + 1/arf)
   비율을 바꿔도 이 셈이 따라오므로 짧은 화면을 다시 안 봐도 된다.
   ⚠ 이름이 `.mmg` 인 까닭 — `.mgrid` 는 **멀리건 패 격자**가 이미 쓰고 있다(§1483). 그걸 쓰면 덮인다 */
.mmg{
  --mgap:clamp(8px,calc(var(--app-w) * .026),14px);
  --arh:1.52;                 /* 혈투 칸 — 4:3 이던 것을 낮췄다 (v178) */
  --arf:1;
  /* 그림이 칸을 **가득 채운다** (v176). 세 그림의 비율이 칸과 같아(4:3 · 1:1) 잘리는 데가 없다 */
  --fit:cover;
  /* ⚠ 끝의 `* .93` — 칸을 **꽉 채우지 않는다** (v0.226). 큰 화면(S25+)에서 단추가 화면을 다 먹어 빽빽했다 */
  --half:calc(min((100cqw - var(--mgap))/2,
             (100cqh - var(--mgap)*(1 + 1/var(--arh))) / (2/var(--arh) + 1/var(--arf))) * .93);
  display:grid;grid-template-columns:repeat(2,var(--half));gap:var(--mgap)}
.mbig{position:relative;min-width:0;padding:0;background:none;border:0;
  -webkit-tap-highlight-color:transparent;transition:transform .14s}
.mbig.hero{grid-column:1/-1;aspect-ratio:var(--arh)}
.mbig.half{aspect-ratio:var(--arf)}
/* 순례·비무 — 반 칸 하나를 위아래로 가른다. 바깥 틀은 결연과 같은 크기라 격자가 흔들리지 않는다 */
.mstack{aspect-ratio:var(--arf);min-width:0;display:grid;grid-template-rows:1fr 1fr;gap:var(--mgap)}
.mbig.quarter{min-height:0}
.mbig.quarter .mb-n::after{margin-top:2px}
.mbig.quarter .mb-e{font-size:clamp(6px,round(calc(var(--app-w) * .016), 1px),7.5px);letter-spacing:.1em;text-indent:.1em}
/* 비무 — 아직 열리지 않았다. 그림은 쌍검과 두루마리(`menu_main_bimu_v1.webp`) */
/* 흐리게 하는 것은 **그림뿐**이다 (v0.226) — 칸 전체를 흐리면 이름까지 잿빛이 되어 다른 칸과 글씨 빛이 갈렸다 */
.mbig.lockd .mb-img{opacity:.66}
/* 네 메뉴의 테두리는 걷었다. 그림 아래 바탕과 얕은 그림자만 남긴다. */
.mbig::before{content:"";position:absolute;inset:0;border-radius:var(--r-m);
  background:#14111c;
  box-shadow:0 6px 18px #0009;
  transition:box-shadow .14s}
/* 그림의 **자리와 배율**은 단추마다 다를 수 있다 (v185) — `--ipos`·`--isz` 로 받는다.
   기본은 「가운데에 꽉 채우기」이고, 그림 한 귀퉁이를 잘라 내야 할 때만 단추에 적는다.
   ⚠ 값은 `index.html` 의 그 단추에 `--img` 와 **나란히** 적는다 —
   그림과 그 그림을 어떻게 앉힐지는 한 몸이라, 떨어뜨려 두면 그림을 갈 때 한쪽만 남는다 */
.mb-img{position:absolute;inset:0;border-radius:var(--r-m);overflow:hidden;
  background:var(--img) var(--ipos,center)/var(--isz,var(--fit)) no-repeat;
  isolation:isolate;transition:filter .14s;pointer-events:none}
/* **일러스트는 뒷배경이다** (v176) — 그대로 두면 글씨를 삼킨다. 한 겹 어둡게 덮는다.
   가운데를 조금 더 어둡게 해서 글씨가 앉을 자리를 만든다 */
.mb-img::after{content:"";position:absolute;inset:0;z-index:1;border-radius:var(--r-m);
  background:radial-gradient(120% 90% at 50% 50%,#000000a6 0%,#00000073 55%,#000000a8 100%)}
/* 강호의 세 그림만 숨을 쉰다. 가벼운 합성(transform·opacity)만 움직이고
   글씨·알림 금점·버튼 크기는 그대로 둔다. 잠긴 비무에는 움직임을 넣지 않는다. */
.mb-img::before{content:"";position:absolute;inset:-18%;z-index:2;pointer-events:none;opacity:0}
#tPvp .mb-img::before{
  background:radial-gradient(ellipse 49% 27% at 25% 78%,#c94343ad 0%,#c9434300 100%),
             radial-gradient(ellipse 43% 24% at 76% 70%,#9c6595a1 0%,#9c659500 100%);
  will-change:transform,opacity;animation:mainBloodMist 14s ease-in-out infinite}
.mbig[data-go="shop"] .mb-img::before{
  /* 이 그림은 123% 확대되어 양끝 등잔이 잘린다. 실제 화면에 남는 부채꼴 카드에 빛을 모은다. */
  inset:0;mix-blend-mode:screen;
  background:radial-gradient(ellipse 37% 32% at 52% 70%,#fff1bfed 0%,#f5ad6888 47%,#f5ad6800 100%),
             radial-gradient(ellipse 16% 23% at 35% 61%,#ffe5aeb8 0%,#e9a24f00 100%),
             radial-gradient(ellipse 16% 23% at 69% 61%,#ffe5aeb8 0%,#e9a24f00 100%);
  will-change:transform,opacity;animation:mainCardGlow 8s ease-in-out infinite}
.mbig[data-go="camp"] .mb-img::before{
  background:radial-gradient(ellipse 45% 18% at 24% 55%,#f4ecdfc9 0%,#f4ecdf00 100%),
             radial-gradient(ellipse 45% 17% at 67% 76%,#d7d5e5bf 0%,#d7d5e500 100%);
  will-change:transform,opacity;animation:mainMountainMist 16s ease-in-out infinite}
@keyframes mainBloodMist{
  0%,100%{transform:translate(-7%,3%);opacity:.32}
  50%{transform:translate(7%,-3%);opacity:.57}}
@keyframes mainCardGlow{
  0%,100%{transform:translateY(1%) scale(.98);opacity:.08}
  43%{transform:translateY(-1%) scale(1.02);opacity:.23}
  49%{transform:translateY(-1.5%) scale(1.03);opacity:.16}
  56%{transform:translateY(-1%) scale(1.02);opacity:.25}}
@keyframes mainMountainMist{
  0%,100%{transform:translate(-11%,2%);opacity:.25}
  50%{transform:translate(12%,-2%);opacity:.47}}
@media (prefers-reduced-motion:reduce){
  .mscene::before{animation:none;opacity:.55;transform:none}
  #tPvp .mb-img::before,.mbig[data-go="shop"] .mb-img::before,.mbig[data-go="camp"] .mb-img::before{
    animation:none;opacity:.35;transform:none}
  .mbig[data-go="shop"] .mb-img::before{opacity:.125}
  .mbig[data-go="camp"] .mb-img::before{opacity:.25}}
.mbig:focus,.mbig:focus-visible,.mdk:focus,.mdk:focus-visible{outline:none}
/* 이름은 칸 **정중앙**이다 (v176) — 영문 줄까지 묶어 한 덩이로 가운데에 앉힌다.
   일러스트를 이미 어둡게 덮어 두었으므로 글씨 밑에 먹을 따로 깔지 않는다 */
.mb-cap{position:absolute;inset:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  padding:8px;pointer-events:none}
/* ⚠ 줄 높이를 카드명(`.c-name`)과 같은 1.3 으로 (v0.225) — 기본값(normal)이면 글자 아래에 빈 줄이 붙어
   가름선이 이름에서 멀리 떨어져 보였다 */
.mb-n{font-family:var(--mjo);font-size:clamp(15px,round(calc(var(--app-w) * .044), 1px),20px);font-weight:800;line-height:1.12;
  letter-spacing:.2em;text-indent:.2em;color:#f6f0e4;
  /* 일러스트 위에 얹히므로 그림자를 겹겹이 준다 — 가까운 먹으로 획을 세우고, 먼 먹으로 바탕에서 띄운다 */
  text-shadow:0 1px 2px #000,0 2px 6px #000,0 3px 14px #000e,0 0 26px #000c;white-space:nowrap}
/* 이름 아래 가름선 — **카드명 밑줄(`.c-name::after`)과 같은 규격**이다 (v177).
   폭 25% · 두께 1px · 알파 0x80. ⚠ 1px 미만으로 내리지 않는다 (인수인계 §8) */
.mb-n::after{content:"";display:block;width:38%;height:1px;margin:2px auto 0;
  background:#ffffff8c;box-shadow:0 1px 3px #000c;pointer-events:none}
.mbig.hero .mb-n{font-size:clamp(19px,round(calc(var(--app-w) * .058), 1px),26px)}
/* 그 밑에 영문 한 줄 — 읽으라고 둔 것이 아니라 무엇을 하는 자리인지 가리키는 표다 */
.mb-e{font-family:var(--mjo);font-size:clamp(6.5px,round(calc(var(--app-w) * .018), 1px),8px);font-weight:700;line-height:1.3;
  letter-spacing:.1em;text-indent:.1em;color:#d6cab4;opacity:.72;
  text-shadow:0 1px 3px #000,0 2px 8px #000d;white-space:nowrap}
.mbig.hero .mb-e{font-size:clamp(7px,round(calc(var(--app-w) * .02), 1px),8.5px)}
.mbig:active{transform:scale(.97)}
/* 누른 표는 **기본 강조색**(`--seal`)이다 (v178). 초록(`--ready`)은 수라장에서
   「이 연은 칠 수 있다」를 뜻하는 색이라, 메인에서까지 쓰면 그 뜻이 묽어진다 */
.mbig:active .mb-img{filter:drop-shadow(0 0 4px var(--seal)) drop-shadow(0 0 12px #7c86b68c)}
/* **`hover:hover` 만으로는 모자란다** (v145) — 손가락으로 두드리는 기기도 이 질문에 참이라
   답할 때가 있어, 눌렀던 단추가 돌아와도 밝은 채로 남았다(「무명자 단추가 골라져 있다」).
   `pointer:fine` 을 같이 물어 **마우스가 있는 자리에서만** 밝힌다 */
@media (hover:hover) and (pointer:fine){
  .mbig:hover .mb-img{filter:drop-shadow(0 0 6px #ffffff45) drop-shadow(0 7px 16px #000c)} }
/* 아직 열리지 않은 자리 */
#tPvp .mb-img{opacity:.66}

/* 하단 바 바로 위 네 칸 — 자주 드나드는 것들. **아래로는 아무것도 두지 않는다** */
/* 하단 넷은 하단 바에 붙이지 않는다 — 한 줄 띄워야 「바의 일부」로 안 읽힌다 (v178) */
/* ⚠ **칸 너비는 넷일 때로 못 박는다** (v0.266). 웹에서는 만보각이 빠져 셋만 서는데,
   lex:1 로 두면 셋이 폭을 나눠 가져 아이콘 사이가 휑하게 벌어졌다.
   너비를 넷일 때 그대로 두고 **남는 자리는 양옆으로 나눠** 가운데로 모은다 */
/* ⚠ 칸 수를 **변수로 받는다**(`--dkn`, v0.344) — 예전에는 4 가 값으로 박혀 있었다.
   웹에서는 만보각이 빠져 넷이 되고(`paintDock`), 연심이 들어와 다섯이 되었다.
   숫자를 박아 두면 단추를 하나 넣을 때마다 두 군데를 고쳐야 하고, 한쪽을 잊으면 줄이 넘친다 */
.mdock{--dkn:5;flex:none;display:flex;justify-content:center;align-items:flex-end;gap:4px;padding:4px 0 0;
  margin-bottom:clamp(10px,calc(var(--app-w) * .032),20px)}
/* 접속 인원 — 낙관 아래(.mbrand). 붙일 서버가 없으면 아예 안 뜬다 */
.mlive{font-family:var(--mono);font-size:10px;letter-spacing:.1em;
  color:var(--fg-faint);white-space:nowrap}
.mlive:empty{display:none}
.mlive b{color:var(--ok);font-weight:700;font-variant-numeric:tabular-nums}
.mdk{flex:0 0 calc((100% - (var(--dkn) - 1) * 4px) / var(--dkn));min-width:0;display:flex;flex-direction:column;align-items:center;gap:4px;
  padding:0;-webkit-tap-highlight-color:transparent;transition:transform .14s}
.mdk-img{width:100%;max-width:58px;aspect-ratio:1;   /* v0.225 — 66→58 */
  background:var(--img) center/contain no-repeat;
  filter:drop-shadow(0 0 4px #ffffff20) drop-shadow(0 3px 8px #000a);
  transition:filter .14s}
/* 명운과 만보각은 그림이 판을 꽉 채워 나머지 둘보다 커 보인다. 그 둘만 한 치수 내린다 (v129).
   명운은 거기서 한 번 더 내린다 — 책이 네모라 같은 폭이어도 가장 커 보인다 (v131).
   둘 다 그림 아래쪽에 여백이 없어 글씨에 붙어 보이므로 1px 만 끌어올린다 */
.mdk[data-go="deck"] .mdk-img,.mdk[data-go="store"] .mdk-img{transform:translateY(-1px)}
.mdk[data-go="store"] .mdk-img{max-width:52px}
.mdk[data-go="deck"] .mdk-img{max-width:48px}
/* 그림이 아직 없는 자리 — 빈 칸이 아니라 「자리가 있다」로 보여야 한다 */
.mdk-img.none{background:none;border:1px dashed #4a4455;border-radius:var(--r-s);opacity:.5}
/* 잠긴 단추 — **눌리기는 한다.** 눌러야 왜 잠겼는지 말해 줄 수 있다 (v0.344).
   자물쇠는 `disabled` 를 대신하는 표지일 뿐이다. `disabled` 를 걸면 누름조차 안 와
   손가락이 몇 번을 눌러도 아무 일이 없어 고장으로 읽힌다 — 무훈에서 겪은 그 일이다 */
/* ⚠ 그림을 **한 번 더 눌러 둔다** — 자물쇠가 그 위에 얹히는데, 원화가 복잡하면 묻힌다 */
.mdk.lockd .mdk-img{opacity:.34;filter:grayscale(.95) brightness(.72) drop-shadow(0 3px 8px #000a)}
.mdk.lockd .mdk-n{color:#9a93a6}
/* ⚠ 자물쇠 밑에 **어두운 받침**을 깐다 (v0.346) — 받침 없이 얹으니 연심 원화(옥패 한 쌍)
   위에서 무엇인지 안 읽혔다. 끌기 표식에서 배운 것과 같다: **바쁜 그림 위의 표는 제 땅이 있어야 한다** */
.mdk-lock{position:absolute;left:50%;top:calc(50% - 9px);transform:translate(-50%,-50%);
  width:30px;height:30px;border-radius:50%;pointer-events:none;
  background:#12101ae0 url(assets/ui/icon_deck_slot_lock.webp?v=1) center/18px 18px no-repeat;
  box-shadow:0 0 0 1px #ffffff1f,0 2px 8px #000b}
.mdk-lock[hidden]{display:none}
.mdk-n{font-family:var(--mjo);font-size:10.5px;font-weight:800;letter-spacing:.06em;text-indent:.06em;
  color:#e8e0d2;text-shadow:0 2px 6px #000;white-space:nowrap;pointer-events:none}
.mdk:active{transform:scale(.95)}
.mdk:active .mdk-img{filter:drop-shadow(0 0 3px var(--seal)) drop-shadow(0 0 11px #7c86b6aa)}
@media (hover:hover) and (pointer:fine){ .mdk:hover .mdk-img{filter:drop-shadow(0 0 4px #ffffff40) drop-shadow(0 5px 12px #000b)} }
@media (max-width:360px){ .mdk-n{font-size:9.5px} .mb-n{font-size:16px} }

/* 메인 타일 (옛 격자 — 지금은 쓰지 않는다) */
.tiles{display:grid;grid-template-columns:1fr 1fr;gap:9px}
.tile{position:relative;min-height:98px;border:1px solid var(--line);border-radius:var(--r-s);
  background:linear-gradient(160deg,var(--panel),var(--panel-2));display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:3px;overflow:hidden;transition:border-color .16s,transform .1s}
/* 수라 — 맨 위 큰 자리 */
.tile.hero,.tile.wide{grid-column:1/-1;aspect-ratio:auto;flex-direction:row;justify-content:flex-start;
  gap:15px;padding:0 20px}
.tile.hero{min-height:126px}
.tile.wide{min-height:70px;gap:13px;padding:0 18px}
.t-txt{display:flex;flex-direction:column;align-items:flex-start;gap:2px}
.t-en{font-size:9px;font-weight:500;letter-spacing:.3em;color:var(--fg-faint)}
.tile.hero .t-glyph{font-size:52px} .tile.hero .t-name{font-size:25px;letter-spacing:.14em;margin:0}
.tile.t2 .t-txt,.tile.t3 .t-txt{align-items:center;gap:1px}
.tile.wide .t-glyph{font-size:31px} .tile.wide .t-name{font-size:17px;margin:0}
.tile.hero::after{background:radial-gradient(56% 130% at 18% 120%,var(--tc),transparent 72%)}
.tile.wide::after{background:radial-gradient(48% 150% at 16% 130%,var(--tc),transparent 72%)}
.tile.hero{--tc:#e05a3c4d}
.tile::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(70% 55% at 50% 118%,var(--tc,#a97cff33),transparent 70%)}
.tile:hover{border-color:var(--seal)} .tile:active{transform:translateY(1px)}
.tile.t1{--tc:#d4a84338} .tile.t2{--tc:#4fb39a38} .tile.t3{--tc:#7c86b638} .tile.t4{--tc:#e05a3c38}
.tile.t5{--tc:#c9a85c38} .tile.t6{--tc:#6f7fae38} .tile.t7{--tc:#c4453a38}
.t7 .t-glyph{color:var(--seal)}
.tile.t7{opacity:.62} .tile.t7 .t-en{color:var(--fg-faint)}
.t5 .t-glyph{color:#d8b96b} .t6 .t-glyph{color:#8fa0d0}
.tile.t5 .t-txt,.tile.t6 .t-txt{align-items:center;gap:1px}
.t-glyph{font-family:var(--han);font-size:34px;font-weight:700;line-height:1;opacity:.9}
.t1 .t-glyph{color:var(--chungi)} .t2 .t-glyph{color:var(--jeong)}
.t3 .t-glyph{color:var(--seal)} .t4 .t-glyph{color:var(--ma)}
.t-name{font-family:var(--serif);font-size:15px;font-weight:700;letter-spacing:.1em;margin-top:4px}
/* 타일 밑에 붙이던 잔글씨 대신, 무슨 화면인지 아래에 한 번만 적는다 */
/* 강호 화면은 메뉴가 높이를 통째로 먹으므로 칸 사이 간격을 없앤다.
   아래 여백도 거의 없앤다 — **하단 넷은 하단 바에 붙어 서야 한다** */
#s-main{gap:0;padding-bottom:6px}
/* 누른 자리가 잠깐 눈에 남는다 — :active 만으로는 손가락을 떼는 순간 풀려서,
   화면이 넘어가는 동안 무엇을 눌렀는지 안 보인다 */
/* ⚠ 큰 칸은 **그림만** 빛낸다 (v197). 예전에는 `.mbig` 통째에 걸어
   테와 글씨까지 함께 빛나서 하단 넷보다 훨씬 무거웠다 — 하단 넷은 원래 그림만 빛난다 */
.mbig.press .mb-img,.mdk.press .mdk-img{
  filter:drop-shadow(0 0 3px var(--seal)) drop-shadow(0 0 11px #7c86b68c)}
.mdk.press .mdk-img.none{border-color:var(--seal);opacity:.9}
/* 명호 맨 아래 로그아웃 — 되돌릴 수 없는 쪽이라 붉고, 다른 단추와 떨어져 선다 */
.fbtn.dg.out{margin-top:20px;padding:13px;color:#ff9a8e;border-color:#5f2c26;background:#241417}
/* 고객센터는 로그아웃 바로 위 — 둘이 한 묶음으로 맨 아래에 선다 */
#pHelpdesk{margin-top:20px;padding:13px}
#pHelpdesk + .fbtn.dg.out{margin-top:8px}
[hidden]{display:none!important}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:7px}
/* 격자 안에 안내 글 한 줄만 있을 때 — **칸 하나에 갇혀 좁게 접힌다** (v175).
   줄을 통째로 차지하고 가운데에 선다. 명운 고르기·출전 화면이 같이 쓴다 */
.note.none{grid-column:1/-1;margin:0;padding:22px 16px;text-align:center;line-height:1.85;
  border:1px dashed var(--line);border-radius:var(--r-s);background:#ffffff05}
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:7px}
.grid2 .prow,.grid3 .prow{flex-direction:column;align-items:flex-start;gap:2px;padding:10px 11px}
.grid3 .prow{align-items:center;text-align:center}
.grid3 .prow span{margin-top:1px}
#s-title{justify-content:safe center;align-items:center;text-align:center;gap:0;padding:26px}
.brand-en{margin-top:11px}
.brand{font-family:var(--serif);font-weight:900;font-size:58px;letter-spacing:.3em;line-height:1;color:var(--fg);
  text-indent:.24em;text-shadow:0 0 34px #c4453a2e}
.brand-han{font-family:var(--han);font-size:15px;letter-spacing:.7em;color:var(--seal);margin-top:14px;text-indent:.7em}
.brand-en{font-family:var(--mono);font-size:9.5px;letter-spacing:.36em;color:var(--fg-faint);margin-top:9px}
.seal{width:44px;height:44px;margin:26px 0 22px;border:2px solid var(--seal);border-radius:3px;
  display:flex;align-items:center;justify-content:center;font-family:var(--serif);font-size:19px;font-weight:700;
  color:var(--seal);transform:rotate(-3deg);box-shadow:0 0 22px #c4453a33}
.han{font-family:var(--han)}
.epigraph{max-width:26ch;font-family:var(--han);font-size:15px;line-height:2;color:var(--fg-mid);text-wrap:balance}
.epigraph em{color:var(--fg);font-style:normal}
.start-btn{margin-top:30px;padding:12px 44px;border:1px solid var(--seal);border-radius:2px;
  font-family:var(--serif);font-size:16px;font-weight:700;letter-spacing:.34em;text-indent:.34em;color:#f0e2dd;
  background:linear-gradient(180deg,#3a201c,#241412);transition:box-shadow .3s,transform .12s}
.start-btn:hover{box-shadow:0 0 26px #c4453a44}
.start-btn:active{transform:translateY(1px)}
.title-foot{margin-top:24px;font-family:var(--mono);font-size:9.5px;color:var(--fg-faint);letter-spacing:.1em}

/* 진입구 */
.gate{display:flex;align-items:center;gap:13px;text-align:left;width:100%;padding:15px 14px;
  border:1px solid var(--line);border-radius:var(--r-s);background:var(--panel);transition:border-color .18s,background .18s}
.gate:hover{border-color:var(--seal);background:var(--panel-2)}
.gate-mark{width:40px;height:40px;flex:none;border-radius:2px;display:flex;align-items:center;justify-content:center;
  font-family:var(--han);font-size:18px;font-weight:700;border:1px solid var(--line);background:var(--ink-2)}
.g1 .gate-mark{color:var(--chungi);border-color:#5c4a22}
.g2 .gate-mark{color:var(--jeong);border-color:#2f4f48}
.g3 .gate-mark{color:var(--yeong);border-color:#27505b}
.g4 .gate-mark{color:var(--seal);border-color:#5c2620}
.gate-body{flex:1;min-width:0}
.gate-name{font-family:var(--serif);font-size:16px;font-weight:700;letter-spacing:.06em;display:block}
.gate-desc{font-size:11.5px;color:var(--fg-mid);margin-top:2px;display:block}
.gate-arrow{color:var(--fg-faint);flex:none}
/* 명운 칸은 한 줄에 하나씩 — 두 줄로 깔면 이름도 장수도 잘려 무슨 명운인지 알아볼 수가 없다 */
/* 명운 격자 — 카드 뒷면을 늘어놓는다. 좁은 화면에서 셋, 넓으면 넷.
   **`minmax(0,1fr)` 이라야 한다** (v146) — 그냥 `1fr` 이면 격자 칸의 최소 너비가
   내용(줄바꿈 없는 긴 이름)을 따라가서 칸마다 폭이 달라진다. 실제로 430px 에서
   85~104px 로 제각각이었다 */
.gates{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px 10px}
@media (min-width:400px){ .gates{grid-template-columns:repeat(4,minmax(0,1fr))} }
/* 도움말 */
#s-help{gap:0}
.hpsearch{flex:none;position:relative;padding:2px 0 10px}
.hpq{width:100%;padding:11px 34px 11px 13px;font:inherit;font-size:13.5px;color:var(--fg);
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r-s);outline:none}
.hpq:focus{border-color:var(--seal)}
.hpq::-webkit-search-cancel-button{display:none}
.hpx{position:absolute;right:6px;top:2px;width:34px;height:44px;background:none;border:0;
  color:var(--fg-faint);font-size:19px;cursor:pointer}
.hpbody{flex:1;min-height:0;overflow-y:auto;padding-bottom:12px}
.hpn{font-family:var(--mono);font-size:10px;letter-spacing:.14em;color:var(--fg-faint);padding:2px 0 8px}
.hplist{display:flex;flex-direction:column;gap:7px;margin-bottom:13px}
.hpitem{border:1px solid var(--line-soft);border-radius:var(--r-s);background:#ffffff05;padding:10px 12px}
.hpk{font-family:var(--serif);font-size:14px;font-weight:700;letter-spacing:.04em;color:var(--fg);margin-bottom:5px}
.hpt{font-size:11.5px;line-height:1.8;color:var(--fg-mid);white-space:pre-line}
.hpitem mark{background:#c4453a3d;color:var(--fg);border-radius:2px}
.head{display:flex;flex-direction:column;gap:3px}
.head h2{margin:0;font-family:var(--serif);font-size:19px;font-weight:800;letter-spacing:.08em}
.head p{margin:0;font-size:11.5px;color:var(--fg-mid)}
.sec{font-family:var(--mono);font-size:9.5px;letter-spacing:.24em;color:var(--fg-faint);text-transform:uppercase;
  display:flex;align-items:center;gap:8px}
.sec::after{content:"";flex:1;height:1px;background:var(--line-soft)}
.note{font-size:11px;color:var(--fg-faint);line-height:1.7}

/* 결연 */
/* ===== 순례길 (v135) =====
   그림 한 장이 곧 화면이다. 세로로 아주 길어(724×4216) 화면은 세로로 구른다.
   첫 관문이 **맨 아래**이고 위로 올라간다 — 산을 오르는 길이라 그렇다.
   관문은 그림 위의 자리(%)에 점으로 얹는다. `CAMP[].x/.y` 가 그 좌표다 */
#s-camp{padding:0;gap:0}
/* ═══ 순례 — 관문 패를 옆으로 민다 (2026-10-01) ═══════════════════════════
   예전의 `.road`·`.rnode`(순례길 그림 위의 점 열여섯)를 걷었다. 점이 작아 어느 생의
   무명자인지 알 길이 없었다. 순례길 그림은 **화면 바탕**으로 내려 분위기만 남긴다.
   ⚠ **혈투 경지 줄(`.pvrail`)과 같은 버릇이다.** 좌우 여백으로 첫 패·끝 패도 가운데까지 오고,
      가운데 패가 살짝 커진다. 두 자리가 다르게 움직이면 손이 헷갈린다. 고칠 때 둘을 같이 본다 */
/* ⚠ **배경을 제 것으로 두지 않는다** (2026-10-02 기획자가 정함) — 메인 화면과 같은 비단 바탕을
   쓴다. 그래서 `ui.js` 의 `silk` 토글에서 `camp` 를 뺐다. 여기서 배경을 다시 깔면 그 비단이 가려진다.
   ⚠ 되돌릴 거면 `bg_campaign_pilgrimage.webp` 를 다시 깔고 토글에 `camp` 를 되돌린다 — 두 자리다 */
/* ═══ 순례길 — **네모 패가 지그재그로 올라간다** (2026-10-03 기획자가 정함) ═══════
   ⚠⚠ 앞선 꼴(먹 받침에 세로로 긴 낯짝 패)을 통째로 걷었다. 바뀐 것 다섯:
     ① 패가 **모서리가 굴곡진 네모**다 — 메인 단추와 같은 양식(`--r-m`).
        ⚠ 2026-10-03~04 에는 정팔각이었고 **2026-10-05 에 기획자가 네모로 물렸다.**
          틀을 얹을 자리(`.cm8-fr`)는 그대로 비워 두었다 — 네모 틀을 받으면 거기 넣는다.
     ② 패 안에 **그 관문의 일러스트**가 들어간다.
     ③ 글자는 **메인 화면 양식**(`.mb-n`·`.mb-e`)을 그대로 쓴다 — 큰 한글 이름에 밑줄,
        그 아래 작은 한 줄. 두 화면이 한 집으로 보여야 한다.
     ④ **지금 보고 있는 관문의 일러스트가 뒤에 크게 깔린다**(`.cmback`) — 먹으로 짙게 덮어서.
     ⑤ **지그재그로 올라간다** — 정중앙으로만 오르면 길이 아니라 목록으로 보인다.
   ⚠ 아래가 0관문, 위로 갈수록 높아진다(`paintCamp` 가 차례를 뒤집어 그린다).
   ⚠ 배경은 제 것을 두지 않는다 — 메인과 같은 비단 바탕을 쓴다(`ui.js` 의 `silk` 토글) */
/* ⚠⚠ **`position` 을 여기서 건드리지 마라** (2026-10-03 에 밟았다). `.screen` 이 이미
   `position:absolute;inset:0` 이라 **높이가 정해져** 있고, 그 덕에 `.cmrail{height:100%}` 이
   화면 높이로 묶여 **줄이 제 안에서 구른다.** `relative` 로 덮었더니 높이가 내용만큼 늘어나
   `scrollHeight == clientHeight` 가 되어 **구르지 않았고**, 가운데 맞추기도 통째로 죽었다.
   ⚠ `absolute` 그 자체가 `.cmback` 의 담는 틀이기도 하다 — 따로 `relative` 를 줄 까닭이 없다 */
/* ⚠⚠ **제 먹바탕을 깐다.** `ui.js` 의 `silk` 토글에서 순례를 뺐으므로 여기가 비면
   **그 자리가 맨바탕**이 된다.
   ⚠ 이 먹은 **일러스트가 갈리는 틈**도 메운다 — 관문을 갈 때 `.cmback` 이 잠깐 흐려지는데,
      그 틈에 뒤가 비면 보는 사람은 「메인 화면이 뒤에 있다」고 읽는다. 그래서 둘 다 고쳐야 한다.
   ⚠ 2026-10-03 에는 「메인 화면 배경을 빼고 일러만」이었다. **2026-10-05 에 기획자가
      비단을 일러 바로 위에 다시 얹으라 물렸다**(`.cmsilk`) — 그 겹은 `.app` 쪽 토글이 아니라
      순례 제 것이라, 토글은 그대로 순례를 뺀 채 둔다 */
#s-camp{justify-content:center;overflow:hidden;background:#000}
/* ⚠ 진행도는 **맨 위에 떠 있다** — 줄(`.cmrail`)이 화면을 꽉 채우고 제 안에서 구르므로
   글 흐름에 끼워 넣으면 줄이 그만큼 짧아지고 가운데 맞추기(`50vh`)가 어긋난다.
   ⚠ `.ftprog` 의 틀 꼴을 그대로 쓰되(한 집으로 보이게) 자리만 여기서 잡는다.
   ⚠ 손짓을 먹으면 그 아래 관문을 못 민다 — 읽기만 하는 것이라 `pointer-events:none` 이다 */
.cmprog{position:absolute;left:12px;right:12px;top:10px;z-index:2;
  margin:0;padding:9px 12px 8px;pointer-events:none;
  background:linear-gradient(180deg,#1d1824f0,#12101ae8)}
.cmprog .fp-track{margin:8px 2px 0}

/* ── 뒤에 깔리는 일러스트 ──────────────────────────────────────
   ⚠⚠ **그림에 `opacity` 를 걸지 않는다** (2026-10-03 기획자가 물림 — 「기본 배경 때문에
      일러가 잘 안 보이네」). 한때 `opacity:.34` 로 내렸더니 **밑의 비단 바탕이 비쳐 올라와**
      그림과 섞였다 — 그림은 희뿌옇고 바탕 무늬는 어른거려 **둘 다 안 읽혔다.**
      이제 그림은 **꽉 차게 깔고**(`opacity:1`) 어둡기는 **위에 덮는 먹**(`::after`)이 쥔다.
      그러면 아래에서 비쳐 올라오는 것이 없고, 어두운 데는 어둡고 밝은 데만 뜬다.
      ⚠ 2026-10-05 에 비단을 **위에** 한 겹 얹었다(`.cmsilk`) — 아래에서 비치는 것과 다른 일이다.
        위에 얹는 것은 짙기를 한 줄(`--cmsilk`)로 쥘 수 있어 그림과 섞여 흐려지지 않는다.
   ⚠ 먹은 **위아래를 더 짙게** — 맨 위 머리글과 맨 아래 바가 거기 앉는다.
      가운데가 옅은 것은 **거기가 지금 보는 관문의 자리**이기 때문이다.
   ⚠ **잿빛으로 걷지 않는다** (기획자: 「잠긴 관문도 해당 일러스트로 나오게」) —
      「아직 못 간 데」는 패 쪽(`.cmcell.lock`)이 말한다. 뒤까지 걷으면 길의 절반이 뿌옇다.
   ⚠ 갈아 끼우는 때와 잦기는 `ui.js` 의 `campBack` 이 쥔다 — **자석이 붙고 나서** 간다 */
.cmback{position:absolute;inset:0;z-index:0;pointer-events:none;
  background:var(--cmimg,none) center/cover no-repeat;
  opacity:0;transition:opacity .34s ease}
.cmback.on{opacity:1}
/* ⚠ **한 겹 더 어둡게** (2026-10-03 기획자가 정함 — 「일러스트에도 검정 딤드 추가」).
   가운데가 73(45%)이던 것을 a3(64%)으로 내렸다 — 관문 패와 노란 길이 그 위에 서야 하는데
   그림이 너무 살아 있으면 **셋이 맞선다.** 그림은 「여기가 어디인가」까지만 말한다 */
.cmback::after{content:"";position:absolute;inset:0;
  background:linear-gradient(to bottom,#000000e0 0%,#00000080 16%,#00000022 48%,#0000008a 84%,#000000e4 100%)}

/* ── 일러 **바로 위**에 얹는 메인 화면 배경 (2026-10-05 기획자가 정함) ──────────
   ⚠⚠ **`.app.silk` 과 같은 한 벌이다** — 바탕 빛깔·비단 그림·위에 덮는 먹기울기까지 같은 값이다.
      순례는 `silk` 토글에서 빠져 있어(`ui.js` 의 `go`) `.app` 쪽 비단이 안 깔린다. 그래서
      여기서 **그 꼴을 그대로 다시 적는다.** ⚠ 한쪽을 고치면 **둘 다** 고친다 — 갈리면
      순례의 비단과 다른 화면의 비단이 서로 다른 바탕이 된다.
   ⚠ 짙기는 `--cmsilk` 한 줄이다. 2026-10-05 기획자가 **80%** 로 못 박았다
      (「메인화면 배경을 투명도 80% 준 다음 얹혀줘」).
      ⚠ 옅게 하려면 그 수만 내린다 — 비단 그림이나 먹기울기를 손대지 않는다.
   ⚠ 자리는 `index.html` 의 **줄 차례**가 쥔다(`.cmback` 다음, `.cmrail` 앞). 여기서 `z-index` 를
      올리지 마라 — 올리면 관문 패(z 1)와 진행도(z 2)를 덮는다.
   ⚠ 손짓을 먹지 않는다 — 먹으면 패를 못 민다 */
.cmsilk{position:absolute;inset:0;z-index:0;pointer-events:none;
  opacity:var(--cmsilk,.8);
  /* ⚠⚠ **비단 그림만 깐다 — 바탕색도 먹기울기도 쓰지 않는다** (2026-10-05).
     처음엔 `.app.silk` 의 꼴을 그대로 베껴 와 **불투명 바탕색(`--ink-2`)과 짙은 먹기울기**를
     함께 깔았다. 그것이 탈이었다 — 이 겹이 **무늬가 아니라 어두운 막**으로 작동해서,
     짙기를 어떻게 돌려도 「일러가 덮이거나 / 무늬가 안 보이거나」 둘 중 하나였다.
     기획자가 세 번 물린 자리다(「거꾸로다」 → 「아예 안 보인다」 → 「또 안 보인다」).
     아래가 일러라 가려 줄 것이 없으니 **그림 한 장이면 된다.** */
  background:url("assets/ui/bg_app_silk.webp") center top/cover no-repeat}

/* ── 구르는 줄 ────────────────────────────────────────────────
   ⚠ `flex-direction:column-reverse` 를 쓰지 않는다 — 구르는 자리의 셈(`scrollTop`·`offsetTop`)이
      브라우저마다 갈려 가운데 맞추기가 흔들린다. **차례를 뒤집어 그리는 것**으로 끝낸다.
   ⚠ `scroll-behavior:smooth` 를 걸지 않는다 — `scrollTop=…` 이 부드러운 이동으로 바뀌는데
      화면이 막 켜진 참이면 그 이동이 끝나지 못해 **아예 안 움직인다**(`.pvrail` v152 에서 당했다).
   ⚠⚠ `position:relative` 다 — 길(`.cmpath`)이 이 안에 `absolute` 로 깔려 **같이 굴러야** 한다.
      빼면 길이 화면에 붙박여 패와 따로 논다 */
.cmrail{position:relative;z-index:1;
  display:flex;flex-direction:column;align-items:center;
  /* 패 한 변 · 가운데에서 좌우로 비키는 폭 · 패 사이 */
  /* ⚠⚠ **마름모로 갈면서 키웠다** (2026-10-13 기획자 — 「순례 패도 마름모 형태로」).
     마름모의 **쓸 수 있는 속은 내접 정사각형**이라 한 변이 패의 0.707 밖에 안 된다 —
     네모 시절 치수를 그대로 두면 이름 두 줄이 비스듬한 변에 잘린다.
     그래서 1.35 배로 키워 **속이 전과 비슷하게** 남도록 맞췄다(124→168 · 158→214) */
  /* ⚠⚠ **창(`vw`·`vh`)이 아니라 판(`--app-w`·`--app-h`)으로 잰다** (2026-10-14).
     예전에는 `clamp(168px,46vw,214px)` 이었다. `vw` 는 **브라우저 창**이라 넓은 화면에서는
     늘 윗값 214px 에 붙는데, 정작 그런 화면일수록 `fitApp()` 이 배율을 키워 **판 높이가 짧다**
     (폰 844 · 1920 최대화 687 · 1920×1040 640). 그래서 한 화면에 드는 관문이
     **폰 4.2칸 → 데스크톱 2.6칸**으로 줄었다 — 기획자 제보 「순례 스테이지도 잘 안 보인다」.
     ⚠⚠ **폰에서는 한 화소도 안 바뀐다.** 폰(판 390×844)에서 두 기준이 같은 값에 떨어지도록
        비율을 잡았다 — `390×.46 = 179.4`, `844×.212 = 178.9`. 그래서 `min()` 이 어느 쪽을
        집든 예전의 `46vw`(=179.4)와 같다. 바뀌는 것은 **판이 넓고 낮은 화면뿐**이다.
     ⚠ 작은 쪽(`min`)을 쓰는 까닭 — 폭만 보면 낮은 판에서 관문이 또 2칸이 되고,
        높이만 보면 좁고 긴 판에서 타일이 판 폭을 넘는다. 둘 다 넘지 않아야 한다.
     ⚠⚠ **아랫값 168 을 내리지 마라.** 2026-10-14 에 132 로 내렸다가 **되물렸다** —
        마름모의 속은 내접 정사각(한 변이 0.707)인데 `.cm8-cap` 이 다시 `34% 26%` 를 베어
        쓸 수 있는 세로가 `--cm8 × .32` 밖에 안 된다. 168 에서 53.8px 이고 이름 두 줄(34.8)과
        가름선(4)을 빼면 무명자 명(`.cm8-e`)에 15px 이 남는다. **145 로 내리면 그 자리가 5.6px 로
        줄어 명이 통째로 사라진다** — 기획자 제보 「순례는 무명자 명도 안 보인다」가 그 자리다.
        한 화면에 드는 관문은 2.64 → **3.41칸**으로 는다. 더 늘리려면 `.cm8-cap` 의 패딩부터 줄인다.
     ⚠ 비켜나는 폭과 사이는 **타일에 매단다** — 예전 폰 값과 같은 비(`46.8/179`·`21/179`)다.
        따로 `vw` 로 적으면 타일만 줄고 여백은 그대로라 줄이 성기게 벌어진다 */
  --cm8:clamp(168px,min(var(--app-w) * .46,var(--app-h) * .212),214px);
  --cmoff:calc(var(--cm8) * .261);
  --cmgap:calc(var(--cm8) * .117);
  gap:var(--cmgap);
  /* 위아래 여백이 **첫 패와 끝 패를 가운데까지** 오게 한다.
     ⚠⚠ **`50vh` 가 아니라 `--app-h`/2 다** (2026-10-14). `vh` 는 창이라 `zoom` 밖의 수다 —
        1920×1040 에서 520px 을 깔아 **판(640) 한가운데가 아니라 한참 아래**를 가운데로 잡았다.
        폰은 판 높이가 곧 창 높이라 예전과 같은 값이다 */
  margin:0;padding:calc(var(--app-h)/2 - var(--cm8)/2) 12px;
  overflow-y:auto;overflow-x:hidden;scrollbar-width:none;
  /* ⚠⚠ **자석처럼 붙는다** (2026-10-03 기획자가 정함 — 「자석붙듯이」).
     손을 떼면 가장 가까운 관문이 **화면 한가운데로 빨려 든다.** 어중간한 자리에 멎으면
     지금 무엇을 보고 있는지가 흐려지고, 뒤에 깔 그림도 고를 수가 없다.
     ⚠ `mandatory` 다 — `proximity` 는 어중간한 데서 그냥 서 버려 자석이라 할 수 없다.
     ⚠⚠ **`center` 라야 한다.** 패는 `campMid()` 가 `scale` 로 늘였다 줄였다 하는데,
        `transform:scale` 의 기준점이 한가운데라 **가운데는 안 움직인다** —
        `start`·`end` 로 두면 붙는 자리가 미는 동안 계속 흔들려 줄이 꿈틀거린다.
     ⚠ 길(`.cmpath` SVG)에는 붙임을 걸지 않는다. 줄 전체 높이라 자석이 거기 먹히면
        아무 데나 선다 */
  scroll-snap-type:y mandatory;
  -webkit-overflow-scrolling:touch;overscroll-behavior-y:contain;
  height:100%}
.cmrail::-webkit-scrollbar{display:none}

/* ── 패를 잇는 길 ─────────────────────────────────────────────
   ⚠⚠ **자리는 `ui.js` 가 재서 그린다**(`campPath`). 지그재그라 기울기가 제각각인데,
      CSS 로는 빗변 길이를 셈할 수가 없다(`sqrt()` 는 아직 못 믿는다).
      재서 그리면 패 크기가 화면 폭 따라 바뀌어도 늘 맞는다 — 창 크기가 바뀌면 다시 잰다.
   ⚠ 길은 패 **뒤**(z 0)다. 패가 줄어들어도(`campMid` 의 `scale`) 길은 제자리라,
      줄어든 패 밑으로 길이 조금 드러난다 — 그것이 오히려 「지나온 길」로 읽힌다 */
.cmpath{position:absolute;left:0;top:0;z-index:0;pointer-events:none;overflow:visible}
.cmpath line{fill:none;stroke-linecap:round}
/* ⚠ **앞으로 갈 길은 가늘고 희미하다** (2026-10-03 기획자가 정함 — 「점선이 너무 굵어」).
   아직 안 간 데라 **있다는 것만** 알리면 된다 */
.cmpath line.yet{stroke:#6b6276;stroke-width:.8;stroke-dasharray:4 7;opacity:.42}
/* ⚠⚠ **지나온 길은 노란 실선이다** — 순례의 뜻이 여기 있다. 걸어온 자취가 아래에서부터
   이어져 올라와 **지금 선 자리에서 끊긴다.** 그 끊기는 데가 「여기까지 왔다」를 말한다 */
.cmpath line.go{stroke:color-mix(in srgb,var(--warn) 62%,#120d05);stroke-width:1.4;opacity:.92;
  filter:drop-shadow(0 0 2px #e8b45f3d)}

/* ── 관문 패 — **네모 박스** (2026-10-05 기획자가 정함) ──────────
   「메인화면 버튼처럼 모서리가 굴곡진 박스로 동일 양식」. 모서리는 `--r-m` 하나를 메인 단추와
   나눠 쓴다. ⚠ **여기에 숫자를 박지 마라** — 메인 단추를 고치는 날 둘이 갈린다.
   ⚠ 2026-10-03~04 에는 **정팔각**이었다(모서리 잘림 29.29% · 나무틀 `--frame`).
     그 꼴로 되돌릴 거면 `git show` 에서 꺼내고, **틀 그림도 팔각으로 함께** 되돌린다 —
     한쪽만 바꾸면 틀의 네 귀가 패 밖으로 삐져나온다. */
/* 겉(`.cm8`)과 그림(`.cm8-in`)은 같은 크기·둥글기다. 틈으로 만든 단색 테는
   없애고, 그림 안쪽에서 중앙으로 사그라드는 금빛만 둔다. */
.cmcell{
  /* ⚠⚠ **네모 박스로 갈았다** (2026-10-05 기획자가 정함 — 「메인화면 버튼처럼 모서리가
     굴곡진 박스로 동일 양식」). 그래서 모서리는 메인 단추와 **같은 `--r-m`** 하나를 쓴다 —
     여기에 숫자를 박으면 메인 단추를 고칠 때 둘이 갈린다.
     ⚠ 옛 정팔각 `--oct` 는 걷었다. 되살릴 거면 `git show` 에서 꺼낸다 —
       `clip-path` 는 테를 못 둘러 바깥·안쪽 두 겹으로 꼴을 잡아야 했고, 그 탓에
       번호·「격파」가 **잘린 네 귀**를 자리로 삼고 있었다(15% 꼭지). 네모에서는 그 자리가 넉넉하다 */
  flex:none;position:relative;padding:0;border:0;background:none;
  width:var(--cm8);aspect-ratio:1;
  scroll-snap-align:center;    /* 자석이 붙는 자리 — 줄의 `scroll-snap-type` 과 한 짝이다 */
  -webkit-tap-highlight-color:transparent;
  /* ⚠ `transform` 은 `campMid()` 가 쥔다 — 여기서 쓰면 덮어쓴다. 비키는 것은 **여백**으로 한다.
     ⚠⚠ **투명도를 주지 않는다** (2026-10-03 기획자가 정함). 뒤에 일러스트가 또렷하게
        깔리고부터 **흐려진 패가 그 그림에 녹아** 몇 관문이 있는지조차 안 보였다.
        멀고 가까움은 **크기 하나로만** 말한다 */
  transform:scale(.66);
  transition:filter .15s}
/* ── 지그재그 ─────────────────────────────────────────────────
   ⚠ **관문 번호로 가른다** — 그리는 차례로 가르면 관문이 하나 늘 때 길 전체가 뒤집힌다.
   ⚠ 여백으로 비킨다. `transform:translateX` 를 쓰면 `campMid()` 의 `scale` 이 지워 버린다 */
.cmcell.zL{margin-right:calc(var(--cmoff) * 2)}
.cmcell.zR{margin-left:calc(var(--cmoff) * 2)}

/* 가운데 관문의 대화는 진행도와 패 사이에 중앙 정렬한다. 줄 바깥이어야 잘리지 않는다.
   폭은 판 너비를 기준으로 하여 한 문장을 최대한 길게 읽게 한다. */
/* ⚠⚠ **스미는 결은 심안녀 대화창과 같은 값을 쓴다** (2026-10-06 기획자 — 「심안녀 대화
   등장은 되게 부드럽게 느껴지거든」). 그쪽은 `.tguide.in .tg-bubble` 의
   `.24s cubic-bezier(.2,.9,.3,1)` 이다. 한 사람이 하는 말이 자리마다 다른 결로 들어오면 안 된다.
   ⚠ 두 성질(`opacity`·`transform`)에 **같은 참과 같은 곡선**을 준다 — 따로 주면
     글이 먼저 떠 있고 자리가 뒤따라와 미끄러지는 것처럼 보인다 */
/* `vw` 는 바깥 브라우저 창을 재므로 `--app-w` 로 판 안에서만 폭을 잰다. */
.cmsay{position:absolute;z-index:6;pointer-events:none;width:calc(var(--app-w) - 28px);max-width:430px;
  text-align:center;opacity:0;transform:translate(-50%,calc(-50% + 7px));
  transition:opacity .24s cubic-bezier(.2,.9,.3,1),transform .24s cubic-bezier(.2,.9,.3,1)}
.cmsay[hidden]{display:none}
.cmsay.on{opacity:1;transform:translate(-50%,-50%)}
/* 초상화 없는 공통 대화창. 심안녀 말칸의 한지·금속 결을 작은 자리에도 쓸 수 있게
   그림 자산 대신 테와 귀 장식을 CSS로 짓는다. 다른 글 대화도 이 양식을 재사용한다. */
.plain-dialog{position:relative;isolation:isolate;padding:14px 18px;
  border:1px solid #806b4d;border-radius:3px;
  background:linear-gradient(180deg,#26232af2,#121116f2);
  box-shadow:0 9px 22px #000b,inset 0 0 0 1px #c2a97726,inset 0 0 20px #6b558020}
.plain-dialog::before{content:"";position:absolute;z-index:0;inset:5px;border:1px solid #c2a97730;
  pointer-events:none}
.plain-dialog::after{content:"";position:absolute;z-index:0;inset:-1px;pointer-events:none;
  background:linear-gradient(135deg,#b79860 0 6px,transparent 6px) top left/15px 15px no-repeat,
             linear-gradient(225deg,#b79860 0 6px,transparent 6px) top right/15px 15px no-repeat,
             linear-gradient(45deg,#b79860 0 6px,transparent 6px) bottom left/15px 15px no-repeat,
             linear-gradient(315deg,#b79860 0 6px,transparent 6px) bottom right/15px 15px no-repeat}
.cmsay-in{display:block}
/* ⚠ **말하는 이의 이름줄은 걷었다** (2026-10-06 기획자). 패 안에 이미 「무명자: 마졸」이
   적혀 있어, 바로 옆에서 같은 말을 또 하면 같은 것을 두 번 읽게 된다 */
/* ⚠⚠ **두 문장을 줄로 가른다**(기획자: 「2문장씩이니까 띄어쓰고」). 한 덩이로 붙이면
   좁은 폭에서 통째로 뭉쳐 읽히지 않는다. 낱말 가운데는 자르지 않는다 — 한국말이다 */
.cmsay-t{display:block;position:relative;z-index:1}
.cmsay-t b{display:block;font-family:var(--mjo);font-weight:400;
  font-size:clamp(11px,round(calc(var(--app-w) * .03), 1px),13px);line-height:1.55;color:#eee7de;
  word-break:keep-all;overflow-wrap:break-word;text-shadow:0 2px 6px #000}
.cmsay-t b + b{margin-top:5px}
/* 관문 옆을 가리키던 꼬리는 중앙 배치에서 의미가 없다. */

/* 외곽 단색 테는 걷었다. 노란 길의 흐름은 `.cmpath line.go`와 패 안쪽 빛이 잇는다. */
/* ═══ **둥근 마름모** (2026-10-13 기획자가 정함 — 「인과에 쓰이는 박스 모양으로」) ═══
   ⚠⚠ **초타원(지수 1.42)으로 깎았던 것을 걷었다** (2026-10-13 저녁, 기획자가 보고 물림).
      초타원은 변이 바깥으로 불러 **마름모가 아니라 모서리 뭉개진 원**으로 읽혔다.
      기획자가 말한 마름모는 **인과의 `.ig-dia`** 다 — **변은 곧고 꼭지만 둥근** 네모다.
   ⚠⚠ **그래서 `clip-path` 가 아니라 `rotate(45deg)+border-radius` 다.**
      `clip-path` 는 **점을 잇는 다각형**이라 꼭지를 둥글릴 수가 없다 — 둥글리려면 점을
      늘려 변까지 휘게 되고, 그것이 위의 초타원이었다. `border-radius` 는 **꼭지만** 깎는다.
   ⚠ 돌린 네모는 겉넓이가 1.414배라 칸 밖으로 비어져 나간다 — 그래서 한 변을 패의
      **70.71%**(=1/√2)로 줄여 세운다. **꼭지가 패 네 변에 닿는다** — 마름모의 크기는 전과 같다.
   ⚠⚠ **속은 되돌려 세운다.** 글자 넷(`.cm8-no`·`.cm8-cap`·`.cm8-done`·`.cm8-fr`)은
      `.cm8` 의 **형제**라 애초에 안 돈다. 도는 것은 `.cm8-in` 안의 일러스트 하나뿐이고,
      그것만 `rotate(-45deg)` 로 되세운다 — 인과가 「판은 돌리고 알맹이는 되돌린다」 한 그 법이다.
   ⚠ 되세운 그림은 **141.4%** 로 키워야 마름모를 덮는다. 70.71% × 141.4% = **100%** 라
      그림 칸의 크기는 **패 그대로**다 — 확대되지 않는다. 둘 중 하나만 고치면 그림이 커진다.
   ⚠ 꼭지의 둥글기는 **12px** 이다. 인과(`.ig-dia`)가 66px 패에 6px 이라 그 비율(9%)을 따랐다 —
      패가 168~214px 이다. 두 겹의 크기·둥글기를 맞춰 밖으로 단색 선이 새지 않게 한다 */
.cm8{position:absolute;left:50%;top:50%;width:70.71%;height:70.71%;
  transform:translate(-50%,-50%) rotate(45deg);border-radius:12px;
  background:transparent;
  /* 메인 단추(`.mbig::before`)와 같은 그늘 — 두 화면의 칸이 한 집으로 보여야 한다 */
  box-shadow:0 6px 18px #0009}
/* 안쪽 칸 — 일러스트와 글자가 여기 산다. 겉과 같은 크기라 단색 테가 없다.
   ⚠ `.cm8` 의 자식이 아니라 **형제**라 돌리기·크기를 똑같이 한 번 더 적는다.
      자식으로 옮기지 마라 — `.cm8` 이 그늘을 지고 있어 그림이 그 위에 얹힌다 */
.cm8-in{position:absolute;left:50%;top:50%;
  width:70.71%;height:70.71%;
  transform:translate(-50%,-50%) rotate(45deg);border-radius:12px;
  background:radial-gradient(76% 62% at 50% 34%,#2b2536,#13101a);
  overflow:hidden}
/* ⚠ 되세운 그림 — 위 덩이의 「141.4%」 주석을 함께 본다 */
.cm8-in img{position:absolute;left:50%;top:50%;width:141.43%;height:141.43%;
  transform:translate(-50%,-50%) rotate(-45deg);
  object-fit:cover;display:block;pointer-events:none}
/* **일러스트는 뒷배경이다**(메인 화면 `.mb-img::after` 와 같은 법) — 그대로 두면 글씨를 삼킨다.
   가운데를 조금 더 어둡게 해서 글씨가 앉을 자리를 만든다 */
/* ⚠ 메인 단추의 `.mb-img::after` 와 **같은 값**이다 — 한쪽을 고치면 둘 다 본다 */
.cm8-in::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 90% at 50% 50%,#000000a6 0%,#00000073 55%,#000000ad 100%);
  box-shadow:inset 0 0 13px 2px var(--cm-edge,#e8b45f30)}
/* 그림이 아직 없는 패 — 빈 칸이 아니라 「자리가 있다」로 (`.mdk-img.none` 과 같은 뜻) */
.cmcell.noart .cm8-in img{display:none}

/* ═══ 틀을 얹을 자리 — **지금은 비어 있다**(`--frame:none`) ════════════════════
   경위 — 2026-10-03 에 기획자가 정팔각 나무틀(`pilgrimage_stage_frame_muk.png`)을 그려 왔고,
   **2026-10-04 에 「과해서 일단 빼줘」로 걷었다.** 지금 상태 구분은 안쪽 금빛이 맡는다.

   ⚠⚠ **틀을 다시 얹으려면 네모 틀을 새로 받아야 한다** (2026-10-05 에 패가 네모가 되었다).
      옛 팔각 틀을 그대로 얹으면 네 귀가 패 밖으로 삐져나온다.
   ⚠ 얹을 때 함께 할 것 — ① `--frame` 을 채운다 ② 안쪽 금빛과 겹치지 않는지 본다
      ③ 틀 그림의 안쪽 구멍을 재서 `.cm8-in` 을 그만큼 물린다.
   ⚠ 글과 번호(z 3)는 **틀 위**다 — 틀의 위아래 장식에 가리면 안 된다.
   ⚠ 크기는 `background-size:100% 100%` 라 패를 늘리고 줄이는 대로 **같이 늘고 준다**.
   ⚠ 손짓을 먹지 않는다(`pointer-events:none`) — 먹으면 패가 안 눌린다 */
.cm8-fr{position:absolute;inset:0;z-index:2;pointer-events:none;border-radius:var(--r-m);
  background:var(--frame,none) center/100% 100% no-repeat;
  transition:filter .15s}
/* 상태는 **한 틀을 물들여** 말한다 — 틀이 하나뿐이라 그 길밖에 없고, 그 편이 한 집으로 보인다 */
.cmcell.done .cm8-fr{filter:saturate(.62) brightness(.74)}
.cmcell.lock .cm8-fr{filter:grayscale(.82) brightness(.52)}

/* ── 글자 — **메인 화면 양식 그대로** ────────────────────────
   ⚠ `.mb-n`·`.mb-e` 와 같은 값이다(글꼴·굵기·자간·밑줄·그림자). 한쪽을 고치면 **둘 다** 본다.
   ⚠ 위에 번호, 아래에 「격파」가 앉으므로 글자 덩이는 **그 사이**에 든다.
   ⚠ 네모가 되어 좌우가 넉넉해졌다 (2026-10-05) — 빗변에 닿을 일이 없으니 옆 여백을
     21% 에서 12% 로 줄였다. 관문 이름이 두 줄로 접히던 자리가 한 줄에 선다 */
/* ⚠⚠ **이름은 내접 정사각 안에만 선다.** 마름모의 좌우 꼭지로 밀면 비스듬한 변에 잘린다 —
   좌우 여백을 패의 **26%** 로 두어 글이 그 안에서만 접히게 한다(위아래는 번호·격파가 쥔다) */
.cm8-cap{position:absolute;inset:0;z-index:3;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  padding:34% 26%;pointer-events:none}
/* ⚠⚠ **글자도 창이 아니라 패(`--cm8`)를 따라간다** (2026-10-14). `3.4vw`·`1.9vw` 였는데,
   넓은 화면에서는 **패는 줄고 글자만 윗값에 붙어** 속이 두 배로 좁아졌다 — 무명자 명이
   사라진 까닭의 절반이 이것이다. 폰(390)에서 `3.4vw=13.26`·`1.9vw=7.41` 이고 그때 패가 179 라,
   비를 `.074`·`.0414` 로 잡으면 **폰에서 예전과 같은 수에 떨어진다.** */
.cm8-n{font-family:var(--mjo);font-size:clamp(12px,calc(var(--cm8) * .074),15px);font-weight:800;line-height:1.16;
  letter-spacing:.14em;text-indent:.14em;color:#f6f0e4;text-align:center;word-break:keep-all;
  text-shadow:0 1px 2px #000,0 2px 6px #000,0 3px 14px #000e,0 0 26px #000c}
.cm8-n::after{content:"";display:block;width:38%;height:1px;margin:3px auto 0;
  background:#ffffff8c;box-shadow:0 1px 3px #000c;pointer-events:none}
.cm8-e{font-family:var(--mono);font-size:clamp(7px,calc(var(--cm8) * .0414),8.5px);font-weight:700;line-height:1.3;
  letter-spacing:.2em;text-indent:.2em;color:#d6cab4;opacity:.72;text-align:center;
  text-shadow:0 1px 3px #000,0 2px 8px #000d;
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* 관문 번호 — 패 **위쪽 가운데**에 앉힌다.
   ⚠ 팔각 시절에는 잘린 위 꼭지가 제자리라 15% 였다. 네모에서는 그만큼 내려와 있을 까닭이 없어
     9% 로 올렸다 (2026-10-05) — 이름 덩이와 겹치지 않는 가장 바깥이다 */
/* ⚠ 마름모의 **위 꼭지는 뾰족해서 아무것도 못 앉힌다.** 번호를 안쪽으로 들인다 —
   내접 정사각이 시작되는 자리가 패 높이의 25% 다(팔각 시절의 15% 와 같은 까닭) */
.cm8-no{position:absolute;z-index:3;left:50%;top:25%;transform:translateX(-50%);
  min-width:19px;height:17px;padding:0 5px;border-radius:9px;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--mono);font-size:10.5px;font-weight:700;font-variant-numeric:tabular-nums;
  color:var(--fg-faint);background:#12101ad9;border:1px solid var(--line)}
.cmcell.done .cm8-no{color:var(--pc)}

/* ⚠ **깬 관문은 「격파」로 못 박는다**(2026-10-02 기획자가 정함).
   ⚠⚠ **이름을 가리지 않는다** (2026-10-03 에 보고 고쳤다). 한때 가운데에 큼직한 딱지를 놓고
      이름을 숨겼더니, 깬 관문이 줄줄이 **「격파」만 스물한 번** 서서 **길에서 관문 이름이
      사라졌다** — 어디가 어디인지 알 수가 없다. 번호가 **위 꼭지**에 앉았듯
      「격파」는 **아래쪽 가운데**에 앉힌다. ⚠ 팔각 시절에는 잘린 아래 꼭지가 제자리라
      15% 였고, 네모가 된 뒤에는 번호와 짝을 맞춰 9% 다 (2026-10-05).
   ⚠ 가운데 맞추기를 `left:50%`+`transform:translateX(-50%)` 로 하되 `white-space:nowrap` 을
      함께 둔다 — 안 두면 폭을 화면 절반으로 잡아 글자가 접힌다(§11 의 그 함정) */
.cm8-done{position:absolute;z-index:3;left:50%;bottom:25%;transform:translateX(-50%);
  display:none;align-items:center;justify-content:center;pointer-events:none;white-space:nowrap}
.cmcell.done .cm8-done{display:flex}
/* ⚠ **노랑 톤이다** (2026-10-03 기획자가 정함 — 「노랑 테두리만 쓰고 박스 안에는 검정 딤드」).
   초록은 「이롭다」는 말이고 순례길의 노랑은 **「여기를 지났다」**는 말이다 —
   지나온 선(`.cmpath line.go`)·깬 관문의 테와 **한 빛깔**이라야 한 줄기로 읽힌다.
   ⚠ 안은 **채우지 않고 먹으로 가라앉힌다** — 노란 바탕에 노란 테면 딱지가 되고,
      그 밑의 일러스트도 통째로 가려진다 */
.cm8-done i{font-style:normal;font-family:var(--serif);font-size:10px;font-weight:800;
  letter-spacing:.1em;padding:1px 7px 2px;border-radius:9px;
  color:#e8cf9e;background:#0b0804e0;border:1px solid color-mix(in srgb,var(--warn) 62%,#120d05);
  box-shadow:0 2px 8px #000a,inset 0 0 0 1px #0006;
  text-shadow:0 1px 3px #000,0 0 10px #000c}
/* ═══ 깬 관문 ════════════════════════════════════════════════
   ⚠⚠ **테는 노랑, 안은 먹** (2026-10-03 기획자가 정함). 지나온 선과 **한 빛깔**이라야
      아래에서부터 노랗게 이어져 올라오는 한 줄기로 읽힌다 — 그것이 순례의 자취다.
   ⚠ 다만 **숨 쉬지 않는다.** 숨 쉬는 것은 **지금 갈 관문 하나뿐**이다(기획자가 못 박음) —
      지나온 것까지 깜빡이면 어디를 해야 하는지 도로 알 수 없어진다.
   ⚠ 빛깔을 걷지 않는다 — **먹 한 겹**으로 가라앉힌다(못 간 관문 .52 보다 옅은 .32).
      지난 데는 조용하되 무슨 그림이었는지는 남아야 한다 */
/* 지나온 관문은 같은 노랑을 더 어둡게 한다. 지나온 선(`.cmpath line.go`)도 낮춘다. */
.cmcell.done{--cm-edge:#e8b45f5c}
.cmcell.done .cm8-in::before{opacity:.32}

/* 가운데 온 패 — 크기와 밝기는 `campMid()` 가 쥔다. 여기서는 그늘만 깊게 준다.
   ⚠ `drop-shadow` 를 그대로 둔다 — 네모가 되었어도 모서리가 굴곡져 있어,
     네모 그늘(`box-shadow`)을 깔면 둥근 귀 바깥에 그늘 귀퉁이가 삐져나온다 */
.cmcell.mid{filter:drop-shadow(0 7px 15px #000c)}

/* ═══ 지금 갈 관문 — 안쪽 금빛이 가장 밝고, 바깥 잔광만 옅게 숨 쉰다 ═══
   ⚠ 이것이 없으면 스물한 패가 다 비슷해 어디를 해야 하는지 알 수가 없다. */
.cmcell.open{--cm-edge:#e8b45f80}
.cmcell.open{animation:cmcall 1.9s ease-in-out infinite}
@keyframes cmcall{
  0%,100%{filter:drop-shadow(0 0 2px #e8b45f40)}
  50%    {filter:drop-shadow(0 0 7px #e8b45f85)}}
@media (prefers-reduced-motion:reduce){
  .cmcell.open{animation:none;filter:drop-shadow(0 0 5px #e8b45f70)} }

/* ═══ 못 깬 관문 ════════════════════════════════════════════════
   ⚠ **눌리긴 한다**(2026-10-01 기획자가 정함) — 눌러서 무엇을 받는지 보라고 열어 둔 것이다.
      그러니 `disabled` 를 걸지 않는다. 걸면 누름조차 안 와 고장으로 읽힌다(§13-10 과 같은 규칙).
   ⚠⚠ **빛깔을 걷지 않는다** (2026-10-03 기획자가 물림 — 「패 안의 것은 제 빛으로」).
      한때 `grayscale(1)` 로 잿빛을 만들었는데, 그러면 **무슨 그림인지 알 수가 없어**
      앞으로 무엇이 기다리는지가 안 보였다. 기다리는 것을 보여 주는 것이 순례길의 할 일이다.
   ⚠⚠ **투명도로도 말하지 않는다** — 그쪽은 아예 안 쓴다(`.cmcell` 머리말).
      「아직 못 간 데」는 **검은 겹 한 장**이 맡는다. 빛깔은 그대로 두고 **어둡게만** 한다.
   ⚠ 겹은 그림 바로 위, 가운데 먹(`.cm8-in::after`) **아래**다 — 그 둘이 겹쳐야
      가장자리까지 고르게 가라앉는다. 글자(z 3)는 이 위라 그대로 읽힌다 */
.cm8-in::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:#05040a;opacity:0;transition:opacity .15s}
/* ⚠ **.52 → .72** (2026-10-06 기획자: 「아직 열리지 않은 스테이지는 박스 안을 더 어둡게」).
   잠긴 패가 갈 수 있는 패와 너무 비슷해, 길을 훑을 때 어디까지 왔는지가 한눈에 안 들어왔다.
   ⚠ 1 까지 올리지 않는다 — 무슨 그림인지는 보여야 한다(위 머리말). 앞에 무엇이 기다리는지
     보여 주는 것이 순례길의 할 일이다 */
.cmcell.lock .cm8-in::before{opacity:.72}
/* 안쪽 빛과 이름은 한 단 가라앉힌다 — 「갈 수 있는 곳」과 섞이지 않게 */
.cmcell.lock{--cm-edge:#e8b45f25}
.cmcell.lock .cm8-n{color:var(--fg-mid)}
/* ⚠ 누른 표를 `transform` 으로 내지 않는다 — `campMid()` 가 넣어 둔 크기를 덮어써
   손을 떼기 전까지 패가 제자리를 잃는다. 밝기로 낸다 */
.cmcell:active{filter:brightness(1.18)}

/* 관문 이야기 — 바깥을 누르면 닫힌다 */
/* ⚠⚠ **보상 창과 같은 결이다 — 테도 바탕도 없이 딤드 위에 그냥 뜬다**
   (2026-10-13 기획자 — 「딤드 검은 투명도를 활용한 보상 획득 팝업 식으로」).
   어두운 띠는 **가림막이 깐다 — 상자가 아니다.** 상자에 깔면 `overflow` 와 폭에 걸려
   **사라지기 전에 모서리에서 잘려** 어두운 네모가 그대로 보인다. 보상 창(`#vGain`)에서
   그 자리를 한 번 밟았고 까닭을 거기 적어 두었다. 가운데가 가장 짙고 밖으로 가며 옅어져
   **어디까지가 창인지 눈에 안 잡힌다.** */
.veil.stg{align-items:center;justify-content:center;padding:26px 18px;
  background:
    radial-gradient(118% 40% at 50% 50%,#050408e8 0%,#050408c4 38%,#05040866 72%,#05040800 100%),
    #0a080ca6;
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px)}
.stgbox{width:100%;max-width:340px;max-height:80%;overflow-y:auto;scrollbar-width:none;
  text-align:center;padding:20px 18px 18px}
/* ⚠⚠ **겹테를 걷는 자리는 여기다.** 위의 `.ornate` 묶음에 `.stgbox` 가 들어 있어
   `--og` 빛깔은 물려받되, **그리는 것(테·꺾쇠·바탕·그림자)은 전부 지운다.**
   ⚠ `background-image` 까지 지워야 한다 — 겹테와 꺾쇠는 테가 아니라 **배경 층**이다
     (위 머리말). `border` 만 지우면 꺾쇠 넷이 그대로 남는다 */
.veil.stg .stgbox{border:0;border-radius:0;box-shadow:none;background:none}
.stgbox::-webkit-scrollbar{display:none}
/* ⚠ **이 창만 갈라 둔다.** `.stgbox` 는 문양 고르기·명운 고르기·시즌 보상도 쓰는 굴림 상자다 —
   거기까지 안 구르게 만들면 그 창들의 긴 목록이 통째로 잘린다 */
.veil.stg #stgBody{display:flex;flex-direction:column;overflow:hidden}
.stg-scroll{flex:1 1 auto;min-height:0;overflow-y:auto;scrollbar-width:none;
  /* ⚠ 위 모서리에서 글이 **싹둑 잘리지 않게** 살짝 흐려 둔다. 머리글 바로 아래라
     자르는 자리가 눈에 띈다 */
  /* ⚠ **위아래 둘 다** 흐려 둔다. 위는 머리글, 아래는 단추가 바로 붙어 있어
     양쪽 모두 싹둑 잘리는 자리가 눈에 띈다 */
  -webkit-mask-image:linear-gradient(180deg,#0000 0,#000 10px,#000 calc(100% - 10px),#0000 100%);
  mask-image:linear-gradient(180deg,#0000 0,#000 10px,#000 calc(100% - 10px),#0000 100%)}
.stg-scroll::-webkit-scrollbar{display:none}
/* ⚠⚠ **단추는 늘 보인다** (2026-10-13 기획자). 카드가 여섯 장 깔리는 관문에서는 단추가
   화면 밖으로 밀려 **들어갈 길이 없는 창**처럼 보였다 — 굴릴 수 있다는 것을 아무도 안 알려 준다.
   ⚠ 위에 가는 줄 하나를 둔다. 굴림이 끝나는 자리를 알려 주어 「아래 더 있나」를 가늠하게 한다 */
.stg-foot{flex:none;padding-top:12px;margin-top:2px;
  border-top:1px solid #ffffff12}
/* 관문 이름과 무명자는 **붙박이 머리글**이다 (v0.282) — 아래로 내려도 어느 관문인지가 남는다.
   ⚠ 상자의 위 여백(20px)만큼 위로 물려 붙여야 글이 위로 흘러 나가지 않는다.
      바탕을 깔지 않으면 지나가는 글이 비쳐 겹쳐 보인다 */
/* ⚠⚠ **머리글은 굴림 바깥에 선다** (2026-10-13 기획자 — 「스크롤되는 영역이 마름모
   스테이지명 무명자명까지 올라가서 겹쳐지더라」).
   v0.282 부터 붙박이(`sticky`)로 두었는데, 테 없는 창으로 바꾸면서 **바탕을 반투명으로**
   돌렸더니 지나가는 글이 그대로 비쳐 표식과 이름 위에 글자가 겹쳤다.
   바탕을 도로 칠해 가리는 길도 있으나 그러면 **네모 한 장**이 떠올라 딤드가 깨진다.
   그래서 상자를 **머리글 + 굴림 자리**로 갈랐다 — 가릴 일 자체가 없어진다.
   ⚠ `position:sticky` 와 음수 여백을 **되살리지 마라.** 굴림 밖으로 나왔으니 둘 다 할 일이 없고,
     음수 여백을 남기면 머리글이 상자 위로 삐져나간다 */
.stg-hd{flex:none;padding:0 0 10px;
  box-shadow:0 8px 12px -8px #000a}
.stg-t{margin:0;font-family:var(--serif);font-size:21px;font-weight:800;letter-spacing:.04em}
/* ⚠ 상대는 **제목 아래 한 줄**이다 (2026-10-13). 오른쪽 끝에 붙여 제목과 마주 보게 두던 것을
   가운데로 내렸다 — 보상 창의 「보상 획득 / 최초 클리어 보상」과 같은 자리, 같은 결이다 */
.stg-w{margin-top:5px;text-align:center;font-family:var(--serif);font-size:12.5px;font-weight:700;
  color:var(--seal);letter-spacing:.03em}
/* 사연은 머리글보다 한 단 작게 (v0.284) — 이름과 무명자가 먼저 읽히고 이야기가 뒤따르게 한다 */
/* ⚠ **사연도 가운데 맞춤이다** (2026-10-13 기획자). 어제 이 자리를 왼쪽으로 두었는데
   (「여러 줄 글은 가운데로 세우면 줄 끝이 들쭉날쭉해 읽기가 더디다」) 기획자가 가운데로 물렸다 —
   창의 모든 글이 가운데에 서 있는데 사연만 왼쪽이면 **그 덩이만 떠 보인다.**
   ⚠ `white-space:pre-line` 이라 글에 적힌 줄바꿈은 그대로 산다 — 한 문단이 통째로
     가운데로 모이는 것이 아니라, **줄마다** 가운데에 선다 */
.stg-s{margin:14px 2px 0;font-size:11.5px;line-height:1.95;color:#ded6c8;white-space:pre-line;
  text-align:center}
/* ⚠ 위 여백은 `.stg-foot` 가 쥔다 — 여기에 또 두면 단추가 아래로 밀려 내려간다 */
.stg-go{width:100%;margin-top:0;padding:13px}
/* 잠긴 단추 — **까닭을 적은 자리**다. 눌리지 않지만 읽히긴 해야 한다 */
.stg-go.stg-lock{font-size:12.5px;letter-spacing:.02em;color:var(--fg-faint);
  background:#17141c;border-color:var(--line);cursor:default;opacity:1}
/* ── 관문 클리어 보상 (v0.271) ────────────────────────────────────
   **들어가기 전에 무엇을 받는지 보인다.** 카드는 작게 깔고 눌러서 펼친다 */
/* ⚠⚠ **판을 걷었다** (2026-10-13 기획자). 테 없는 창 위에 네모난 상자가 하나 떠 있으면
   그것만 옛 꼴로 남아 딤드가 깨진다. 가르는 일은 **여백이 한다** — 보상 창과 같은 길이다 */
.stg-pay{margin-top:14px;padding:0;border:0;border-radius:0;background:none}
/* 머리글은 가운데 한 줄 — 좌우로 벌려 놓던 것을 모았다(벌릴 둘째 글이 없다) */
.stg-ph{display:block;text-align:center;
  font-family:var(--serif);font-size:12px;font-weight:700;letter-spacing:.06em;color:var(--fg-mid)}
/* 이미 받았으면 **통째로 죽인다** (v0.282) — 카드 그림까지 어둡게 하여 「끝난 일」로 읽히게 한다.
   ⚠ 머리글만은 죽이지 않는다. 죽은 칸에서 유일하게 읽혀야 할 것이 그 한 줄이다 */
.stg-pay.done{opacity:.55;filter:saturate(.35)}
.stg-pay.done .stg-ph{opacity:1;filter:none;color:var(--ok)}
/* ⚠⚠ **관문 창에서는 목록이 따로 굴러가지 않는다.** 보상 창은 창이 화면에 꽉 차 목록만
   굴리지만, 관문 창은 **상자(`.stgbox`)가 통째로 굴러간다** — 안쪽에 또 굴림을 두면
   손가락이 어느 쪽을 미는지 몰라 사연을 읽다가 목록에 걸려 멈춘다 */
.stg-list{overflow:visible;flex-wrap:wrap;padding-top:10px;padding-bottom:2px}
/* 눌러서 펼치는 칸 — 단추로 세웠으므로 단추의 기본 꾸밈을 걷는다 */
button.gain-item{padding:0;border:0;background:none;font:inherit;color:inherit;cursor:pointer}
/* ⚠ **옛 보상란 꾸밈(`.stg-pc`·`.stg-card`·`.stg-cn`·`.stg-pw`·`.stg-w1`)은 2026-10-13 에 걷었다.**
   카드와 재화가 서로 다른 꼴이었고 그 둘이 또 보상 창과 달라, 같은 보상을 세 가지 모양으로
   보여 주고 있었다. 이제 셋 다 `.gain-item` 하나다. 되짚을 일이 있으면 `git show` 로 본다 */

/* 출전 화면 머리글 — 어느 관문에 나가는지 한 줄로 */
.sthead{display:flex;align-items:center;gap:12px;padding:13px 14px;border:1px solid var(--line);
  border-radius:var(--r-s);background:linear-gradient(140deg,var(--panel),var(--panel-2))}
.st-bar{flex:none;width:3px;align-self:stretch;border-radius:1px}
.st-no{flex:none;width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line);background:var(--ink-2);font-size:12.5px;font-weight:800;font-variant-numeric:tabular-nums}
.st-b{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.st-n{font-family:var(--serif);font-size:14px;font-weight:700;letter-spacing:.04em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.st-s{font-size:10.5px;color:var(--fg-faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 만보각은 위에서부터 쌓는다 — 월정액 한 칸, 그 아래 영석 넷 */
#s-store{justify-content:flex-start}
/* 월정액 — 그림이 위, 글이 아래. 잔여 기간은 오른쪽 위 구석에 선다 */
.mpass{position:relative;flex:none;display:flex;flex-direction:column;align-items:stretch;gap:10px;
  width:100%;padding:14px 15px 13px;margin-bottom:6px;text-align:left;
  border:1px solid #4a3a6e;border-radius:var(--r-s);
  background:radial-gradient(120% 90% at 50% 0%,#2a2140,transparent 70%),linear-gradient(160deg,var(--panel),var(--panel-2));
  -webkit-tap-highlight-color:transparent;transition:border-color .16s,transform .1s}
.mpass:hover{border-color:var(--yeong)}
.mpass:active{transform:scale(.99)}
.mp-left{position:absolute;top:10px;right:12px;z-index:1;padding:3px 8px;border-radius:999px;
  font-size:10.5px;letter-spacing:.03em;color:var(--fg-faint);background:#0d0b11c0;border:1px solid var(--line)}
.mp-left.on{color:var(--yeong);border-color:#6a4fb0}
.mp-art{display:flex;align-items:center;justify-content:center;height:clamp(104px,calc(var(--app-w) * .3),150px)}
.mp-img{max-width:100%;max-height:100%;object-fit:contain;
  filter:drop-shadow(0 0 16px #a97cff55) drop-shadow(0 5px 12px #000b)}
.mp-body{display:flex;flex-direction:column;gap:5px}
.mp-name{font-family:var(--serif);font-size:16px;font-weight:800;letter-spacing:.05em;color:var(--fg)}
.mp-row{display:flex;flex-wrap:wrap;gap:4px 14px;font-size:12.5px;color:var(--fg-mid)}
.mp-row b,.mp-sub b,.mp-p b{color:var(--yeong);font-variant-numeric:tabular-nums}
.mp-row .mini-token,.mp-sub .mini-token,.mp-p .mini-token{margin:0 2px 0 4px;vertical-align:-3px}
.mp-sub{font-size:11px;color:var(--fg-faint)}
/* 월정액 풀이 창 */
.mpbox .mp-art{margin:12px 0 6px}
.mp-p{margin:8px 0 0;font-size:12.5px;line-height:1.75;color:#ded6c8}
.mp-p.warn{font-size:11.5px;color:var(--fg-faint)}
.mp-now{margin:12px 0 12px;font-size:12px;color:var(--yeong);text-align:right}
.ystack{display:flex;flex-direction:column;gap:9px}
.yrow{display:flex;align-items:center;gap:13px;padding:14px 15px;border:1px solid var(--line);
  border-radius:var(--r-s);background:linear-gradient(140deg,var(--panel),var(--panel-2));
  text-align:left;transition:border-color .16s,transform .1s}
.yrow:hover{border-color:var(--yeong);transform:translateY(-1px)}
/* 상품 그림 — 묶음이 클수록 크게 놓는다. 뒤에 깔아 둔 빛이 영석임을 알린다 */
.ygem{flex:none;width:84px;height:58px;object-fit:contain;
  filter:drop-shadow(0 0 12px #4fb3c855) drop-shadow(0 4px 9px #000a)}
/* 자리 폭은 고정하고 높이만 키운다 — 그래야 이름 왼쪽 끝이 네 줄 다 맞는다 */
.yrow.s .ygem{height:46px}
.yrow.m .ygem{height:55px}
.yrow.l .ygem{height:65px}
.yrow.x .ygem{height:78px;filter:drop-shadow(0 0 18px #4fb3c877) drop-shadow(0 5px 11px #000b)}
.ybody{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.yname{font-family:var(--serif);font-size:15px;font-weight:700;letter-spacing:.06em}
.yamt{font-size:12px;color:var(--yeong);font-variant-numeric:tabular-nums}
.yprice{flex:none;font-size:11.5px;color:var(--fg-faint);letter-spacing:.08em}
/* 명호 */
/* 아이콘 (v176) — 한자 표식이 아니라 **그림**이다. 각연자 그림은 위쪽을 잡아 얼굴이 나오게 한다 */
.face{display:block;width:100%;height:100%;border-radius:50%;overflow:hidden;
  background:#1a1622 center 22% / cover no-repeat;
  box-shadow:inset 0 -2px 6px #00000055,inset 0 0 0 1px #ffffff12}
/* 그림이 아직 없는 자리 — 첫 글자로 버틴다 */
.face.none{display:flex;align-items:center;justify-content:center;
  font-family:var(--han);font-size:.62em;font-weight:700;color:#8d8397;background:#221d2c}
/* 일곱 칸(무명자 + 각연자 여섯)이라 넷씩 두 줄이 딱 맞는다 */
.facegrid{display:grid;grid-template-columns:repeat(4,1fr);gap:11px 9px}
.facepick{display:flex;flex-direction:column;align-items:center;gap:5px;
  padding:0;border:0;background:none;font-size:22px;-webkit-tap-highlight-color:transparent}
.facepick .face{aspect-ratio:1;height:auto;border:1px solid var(--line);transition:.14s}
.facepick.on .face{border-color:var(--seal);box-shadow:0 0 0 1px var(--seal),0 0 14px #c4453a44}
/* 지금 쓰는 초상화 — 오른쪽 아래에 체크 (v0.228). 테만으로는 「고른 것」인지 「눌린 것」인지 갈리지 않는다 */
.fc-ck{position:absolute;right:-1px;bottom:15px;width:20px;height:20px;border-radius:50%;
  display:none;align-items:center;justify-content:center;pointer-events:none;
  background:var(--seal);color:#fff;border:2px solid #0d0b11;box-shadow:0 1px 4px #000a}
.fc-ck svg{width:12px;height:12px}
.facepick.on .fc-ck{display:flex}
@media (hover:hover) and (pointer:fine){ .facepick:not(.lock):hover .face{border-color:var(--seal)} }
.facepick:not(.lock):active .face{transform:scale(.95)}
.fc-n{font-size:9.5px;line-height:1.3;color:var(--fg-mid);text-align:center;
  width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 잠긴 아이콘 — 흐리게 죽이고 「잠김」을 얹는다. 누르면 무엇을 해야 열리는지 아래에 적힌다 */
.facepick.lock{position:relative}
.facepick.lock .face{filter:grayscale(1) brightness(.45);border-style:dashed}
.facepick.lock .fc-n{color:var(--fg-faint)}
.fc-lk{position:absolute;left:50%;top:38%;transform:translate(-50%,-50%);
  font-family:var(--mono);font-size:8.5px;letter-spacing:.1em;color:#cfc4b4;
  padding:2px 6px;border-radius:2px;background:#000000b3;pointer-events:none}
/* 고른 잠긴 칸은 테를 밝혀 어느 것을 눌렀는지 보여 준다.
   ⚠ 이름이 `.fc-sel` 인 까닭 — `.pick` 은 **명운 격자**가 이미 쓰고 있다(display:grid) */
.facepick.lock.fc-sel .face{border-color:var(--warn)}
.facemsg{min-height:1px;margin-top:14px;text-align:center;line-height:1.7}
.facemsg:empty{display:none}
.fc-way{display:block;margin-top:5px;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.08em;color:var(--seal)}
/* 단추의 기본 좌우 여백을 지운다 — 안 지우면 얼굴이 가로로 눌려 타원이 된다 */
.avatar{position:relative;width:78px;height:78px;font-size:34px;flex:none;padding:0}
.avatar .edit{position:absolute;right:-2px;bottom:-2px;width:25px;height:25px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-size:11px;
  background:var(--panel);border:1px solid var(--line);color:var(--fg-mid)}
.avatar:hover .edit{border-color:var(--seal);color:var(--fg)}
/* 경지는 왼쪽, 승수·수집률·진행률 네 칸은 오른쪽 2×2다. */
.wrow{display:flex;gap:9px;width:100%;align-items:stretch}
.wside{flex:1;min-width:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px}
.wcell{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;padding:11px 6px;
  border:1px solid var(--line-soft);border-radius:var(--r-s);background:#ffffff05}
.wcell b{font-size:26px;font-weight:900;color:var(--ok);font-variant-numeric:tabular-nums;line-height:1}
.wcell.pvp b{color:var(--seal)}
/* 좁은 프로필과 팝업에도 네 칸이 같은 열 너비로 선다. */
.wside .wcell{flex-direction:column;align-items:center;justify-content:center;gap:4px;padding:9px 3px;min-height:49px}
.wside .wcell b{font-size:17px}
.wside .wcell span{font-size:9.5px;letter-spacing:0;white-space:nowrap}
/* 경지 — 문양이 들어가므로 왼쪽 큰 칸을 차지한다 */
.wcell.gy{flex:0 0 34%;gap:6px;padding:13px 8px}
.wcell.gy .pg-em{--em:clamp(48px,calc(var(--app-w) * .15),62px)}
.wcell.gy .pg-ko{font-family:var(--serif);font-size:13.5px;font-weight:800;color:#f0e8da;letter-spacing:.04em}
/* 문양이 아직 없는 경지 — 한자로 버틴다 */
.wcell.gy .pg-han{font-family:var(--han);font-size:19px;font-weight:400;color:#e6d9b8;letter-spacing:.02em}
.wcell span{font-size:10.5px;color:var(--fg-faint);letter-spacing:.1em}
.namebox{display:flex;flex-direction:column;align-items:center;gap:14px;padding:26px 16px;
  border:1px solid var(--line);border-radius:var(--r-s);background:linear-gradient(160deg,var(--panel),var(--panel-2))}
.namebox .ightop,.namebox .igbar{width:100%}
#s-prof{gap:10px;padding-bottom:10px}
#s-prof .namebox{gap:8px;padding:13px 14px}
#s-prof .avatar{width:58px;height:58px;font-size:26px}
#s-prof .avatar .edit{width:21px;height:21px}
#s-prof .uname{font-size:22px}
#s-prof .namebox .ightop{margin:0}
#s-prof .namebox .igbar{margin:0}
.prof-tabs{display:grid;grid-template-columns:1fr 1fr;gap:6px;flex:none}
.prof-tab{position:relative;min-height:38px;border:1px solid var(--line);border-radius:var(--r-s);
  background:var(--panel);color:var(--fg-mid);font-family:var(--serif);font-size:13px;font-weight:700;cursor:pointer}
.prof-tab[aria-selected="true"]{border-color:var(--seal);color:var(--fg);background:var(--panel-2)}
.prof-tab .nudot{--nx:9px;--ny:8px}
.prof-pane.ingwa{display:flex;flex:1 0 auto;flex-direction:column;gap:0;min-height:0}
.prof-pane.account{display:flex;flex-direction:column;gap:18px}
.prof-pane[hidden]{display:none}
.nameline{display:flex;align-items:baseline;gap:3px}
.uname{font-family:var(--mjo);font-size:27px;font-weight:800;letter-spacing:.08em}   /* 명조 — 하단 이름표와 같게 (v0.226) */
.utag{font-size:13px;color:var(--fg-faint);font-variant-numeric:tabular-nums}
.namein{width:100%;padding:11px 12px;border:1px solid var(--line);border-radius:var(--r-s);
  background:var(--ink-2);color:var(--fg);font-family:inherit;font-size:15px;text-align:center}
.namein:focus{outline:none;border-color:var(--seal)}
.pkbar{display:flex;align-items:center;justify-content:space-between;gap:10px}
.pkname{font-family:var(--mjo);font-size:14px;font-weight:700;letter-spacing:.06em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pkstage{position:relative;display:flex;align-items:center}
/* ⚠⚠ **`overflow-x:auto` 는 세로도 함께 잘라낸다** (2026-10-05 기획자 제보 — 「이펙트가 선에
   잘려서 어색해보여」). CSS 가 그렇게 정해 두었다: 한 축이 `visible` 이 아니면 **다른 축도
   `visible` 로 남지 못한다.** 그래서 송이 밖으로 번지는 빛이 줄의 위아래 모서리에서 **직선으로
   뚝 끊겼다.** 한지 외피의 검은 그늘도 내내 잘리고 있었으나 먹빛이라 아무도 못 봤다.
   ⚠ 그래서 **위아래에 번질 자리를 준다.** 가로 여백은 주지 않는다 — `paintShop` 의 가운데
     맞추기가 `clientWidth` 로 재므로 가로에 손대면 그 셈이 통째로 어긋난다.
   ⚠ 빛을 더 키우거든 이 여백도 함께 키운다. 둘은 한 짝이다 */
.pkrail{flex:1;min-width:0;display:flex;overflow-x:auto;scroll-snap-type:x mandatory;
  padding:14px 0;
  scrollbar-width:none;touch-action:pan-x pan-y}
.pkrail::-webkit-scrollbar{display:none}
/* 표지 하나만 가운데에 세운다 (v126) — 옆에 세우던 각연자 줄을 걷어냈다 */
.pkslide{flex:0 0 70%;scroll-snap-align:center;display:flex;justify-content:center;align-items:flex-start;
  gap:12px;padding:4px 6px;
  /* ⚠⚠ **안 고른 봉은 조금 작게 선다** (2026-10-05 기획자가 정함 — 순례 관문 패와 같은 결).
     「포커싱이 제대로 안 보여」가 그 자리였다 — 셋이 같은 크기로 서면 어느 것이 고른 것인지
     표지 말고는 말해 주는 것이 없었다.
     ⚠ `transform` 은 자리를 안 먹으므로 **자석(`scroll-snap`)이 흔들리지 않는다** —
       여백이나 너비로 줄이면 멈추는 자리가 통째로 밀린다.
     ⚠ 순례처럼 미는 내내 이어서 키우고 줄이지는 않는다. 봉은 둘셋뿐이라 두 꼴로 넉넉하고,
       매 프레임 `transform` 을 다시 적으면 표지 그림이 자글거린다.
     ⚠ 두 자리 모두 **또렷한 `scale()`** 로 적는다. 한쪽을 `none` 으로 두면 브라우저가
       「변형 없음 ↔ 변형 있음」을 사이에서 이어 그리느라 어떤 판에서는 전환이 제자리에 멎는다.
     ⚠⚠ **줄어드는 자리는 한가운데다**(`transform-origin:center`, 2026-10-05 기획자가 물림 —
       「커진 팩의 세로폭에서 중앙 정렬로」). 한때 `center top` 이라 작아진 봉이 **위에 붙어**
       아래쪽만 훅 비었다. 송이들은 줄의 flex 항목이라 **키가 서로 같으므로**(기본 `stretch`),
       한가운데에서 줄이면 그대로 큰 봉의 세로 한가운데에 선다 */
  transform:scale(.88);transform-origin:center;
  transition:transform .18s ease}
.pkslide.mid{transform:scale(1)}
/* 표지 + 「등장 카드 확인」 을 한 덩어리로.
   옆에 세울 것이 없어졌으니 폭은 화면에 맞춰 잡는다 — 너무 키우면 종이팩이 화면을 다 먹는다 */
.pkcover{flex:0 0 min(88%,208px);display:flex;flex-direction:column;align-items:center;gap:7px;
  padding:0;border:0;background:none;cursor:pointer}
.pkcover .packart{flex:none;width:100%}
/* 한지 외피 — 표지를 종이에 끼운 것처럼 보이게 뒤에 깔아 둔다.
   그림(1061×1482) 안쪽 판이 x 11.87~88.69%, y 8.97~88.93% 이라
   표지가 그 판에 정확히 들어가도록 밖으로 물린 만큼을 음수로 준다 */
/* 물린 만큼을 바깥에 여백으로 돌려놓는다 — 안 그러면 접힌 종이가 「등장 카드 확인」 을 덮는다 */
.pkskin{position:relative;flex:none;align-self:stretch;display:flex;
  margin:15.7% 0 19.3%}
.pkskin::before{content:"";position:absolute;z-index:0;pointer-events:none;
  left:-15.5%;right:-14.7%;top:-11.2%;bottom:-13.8%;
  background:url(assets/ui/pack_hanji.webp?v=1) center/100% 100% no-repeat;
  filter:drop-shadow(0 12px 24px #000b)}
/* ═══ 고른 봉만 **테두리에 옅은 노랑으로 숨 쉰다** (2026-10-05 기획자가 정함) ═══════
   「선택된 팩에 약간 노랑색 점멸 이펙트 테두리에 조금만」. 순례의 `cmcall` 과 같은 결이다.
   ⚠ `drop-shadow` 는 **그려진 알파를 따라간다** — 한지 외피의 윤곽을 타고 돌아
      네모 빛이 뜨지 않는다. 그래서 굳이 테를 긋지 않고 이 한 겹으로 끝낸다.
   ⚠⚠ **본래의 그늘을 두 키프레임에 다 적는다.** `filter` 는 통째로 갈리는 자리라
      한쪽에서 빼면 숨 쉬는 동안 **표지가 바닥에 붙어 보인다**(그늘이 사라진다).
   ⚠ 짙기는 `#e8b45f` 의 알파 두 자리, **번지는 폭은 흐림 반지름**이다.
   ⚠⚠ **번지는 폭을 좁혔다** (2026-10-05 기획자가 물림 — 「팩 선택 이펙트 범위를 조금 더 줄여줘」).
      11px 은 표지 둘레로 넓게 퍼져 봉보다 빛이 먼저 보였다. 지금은 **테두리에 얹힌** 정도다.
   ⚠ 이 값을 다시 키우거든 `.pkrail` 의 위아래 여백(14px)도 함께 키운다 — 안 그러면
     줄의 모서리에서 빛이 직선으로 잘린다 */
.pkslide.mid .pkskin::before{animation:pkcall 1.9s ease-in-out infinite}
@keyframes pkcall{
  0%,100%{filter:drop-shadow(0 12px 24px #000b) drop-shadow(0 0 2px #e8b45f4d)}
  50%    {filter:drop-shadow(0 12px 24px #000b) drop-shadow(0 0 6px #e8b45f8a)}}
@media (prefers-reduced-motion:reduce){
  .pkslide.mid .pkskin::before{animation:none;
    filter:drop-shadow(0 12px 24px #000b) drop-shadow(0 0 4px #e8b45f70)} }
/* ⚠⚠ **가르치는 동안에는 봉이 숨쉬지 않는다** (2026-10-07 기획자 제보 — 「결연 들어가면 움찔움찔」).
   처음 들어온 사람은 튜토리얼이 봉을 짚고 선다. 그때 **같은 자리에서 셋이 따로 숨쉰다** —
   빛테(`tgfocus` 1.25초) · 손끝(`tghand` 0.86초) · 봉의 금빛(`pkcall` 1.9초).
   주기가 다 달라 서로 어긋나며 겹치니, 하나가 빛나는 것이 아니라 **그 자리가 떠는 것**으로 보인다.
   ⚠⚠ **「한 자리에는 한 갈래만 선다」**(인수인계 §11)가 이것이다. 새 연출을 더하기 전에
     그 자리에 이미 서는 것이 있는지 본다 — 여기는 **가르침이 먼저**다.
     빛테가 이미 「여기를 보라」고 말하므로 봉의 금빛은 그동안 쉰다.
   ⚠ 가르침이 끝나면(`#tGuide` 가 숨으면) 저절로 도로 돈다 — 따로 걷는 손이 없다.
   ⚠ 멈추되 **그늘은 그대로 둔다.** 빼면 표지가 바닥에 붙어 보인다(위 메모와 같은 까닭) */
body:has(#tGuide:not([hidden])) .pkslide.mid .pkskin::before{
  animation:none;
  filter:drop-shadow(0 12px 24px #000b) drop-shadow(0 0 4px #e8b45f70)}
.pkskin .packart{position:relative;z-index:1}
.pk-see{font-size:11px;letter-spacing:.06em;color:var(--fg-mid);
  padding:3px 10px;border:1px solid var(--line);border-radius:999px;background:#0e121880}
/* ═══ ⚠ **아직 열리지 않은 인연첩** (2026-10-03) ═══════════════════════════
   표지는 그대로 보여 준다 — 무엇이 올지 알리는 것이 이 자리의 할 일이다.
   다만 **한 겹 가라앉히고** 이름 위에 「준비 중」을 얹어, 눌러 보기 전에 알게 한다.
   ⚠ 가리지는 않는다(`opacity` 로 통째로 내리지 않는다) — 그림을 보여 주려고 세운 것이다 */
.pkslide:has(.pk-soon) .packart{filter:saturate(.72) brightness(.78)}
.pk-soon{position:absolute;left:50%;top:50%;z-index:3;transform:translate(-50%,-50%);
  white-space:nowrap;font-family:var(--mjo);font-size:13px;font-weight:800;letter-spacing:.22em;
  text-indent:.22em;color:#f0e6cf;padding:5px 14px 6px;border-radius:3px;
  background:#0b0908d9;border:1px solid var(--line);
  box-shadow:0 2px 10px #000a,inset 0 0 0 1px #0006;
  text-shadow:0 1px 3px #000,0 0 10px #000c}
.pkcover:hover .pk-see{color:var(--fg);border-color:var(--seal)}
/* ⚠ **옆 봉이 내다보이는 자리를 먹지 않게** 좁고 옅게 둔다 (2026-10-03) —
   봉이 둘 이상이 되면서 오른쪽 끝이 「다음 봉이 있다」를 말하는 자리가 되었다.
   화살표는 그 위에 겹치므로, 가리지 않을 만큼만 남긴다 */
.parr{position:absolute;top:50%;transform:translateY(-50%);z-index:2;width:22px;height:40px;
  display:flex;align-items:center;justify-content:center;font-size:12px;color:var(--fg-mid);
  background:#0b0908cc;border:1px solid var(--line);border-radius:var(--r-s)}
.parr:hover{color:var(--fg);border-color:var(--seal)}
.parr.l{left:0} .parr.r{right:0}
/* ═══ ⚠⚠ **첫 봉과 끝 봉도 화면 한가운데에 선다** (2026-10-03 기획자가 물림 —
   「강호초출이 좌측으로 치우쳐져 있다」) ═══════════════════════════════════
   `scroll-snap-align:center` 만으로는 안 된다 — **첫 송이는 왼쪽으로 더 구를 수가 없어서**
   `scrollLeft:0` 에 멈추고, 그 자리에서는 송이의 한가운데가 줄의 한가운데보다 왼쪽이다.
   끝 봉도 같은 까닭으로 오른쪽에 치우친다.
   ⚠ 그래서 **첫과 끝에 여백을 준다** — 송이가 70% 이니 남는 30% 의 절반, 15% 다.
      이 값은 `.pkslide` 의 너비와 **한 짝**이라 한쪽을 고치면 둘 다 고친다.
   ⚠ 줄(`.pkrail`)에 `padding` 으로 주지 않는다 — 구르는 틀의 **끝 여백**은 판에 따라
      먹히지 않아 끝 봉만 안 가운데에 선다. 송이에 `margin` 으로 주는 쪽이 어디서나 맞는다 */
.pkslide:first-child{margin-left:15%}
.pkslide:last-child{margin-right:15%}
.pkdots{display:flex;justify-content:center;gap:7px}
.pkdot{width:7px;height:7px;border-radius:50%;background:var(--line);padding:0;border:none}
.pkdot.on{background:var(--seal);box-shadow:0 0 8px #c4453a88}
.packbox{display:flex;flex-direction:column;align-items:center;gap:13px}
.packart{width:160px;aspect-ratio:63/88;border-radius:3px;position:relative;border:1px solid #5c4a22;
  background:radial-gradient(120% 70% at 50% 0%,#4a3a18 0%,transparent 60%),
             repeating-linear-gradient(122deg,#221c14 0 8px,#2a2218 8px 16px);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;overflow:hidden;
  box-shadow:0 12px 30px -14px #000}
.packart::after{content:"";position:absolute;left:10%;right:10%;top:50%;height:1px;
  background:linear-gradient(90deg,transparent,var(--chungi),transparent);box-shadow:0 0 14px 1px #d4a84366}
/* 표지 그림이 있으면 장식 선과 안개는 비킨다 */
.packart[style*="background-image"]::after,.packart[style*="background-image"]::before{display:none}
/* 이름 자리 — 아래쪽에 그늘을 깔고 그 위에 얹는다. 그늘이 없으면 밝은 표지에서 글자가 묻힌다 */
.packart .pk-n{position:absolute;left:8%;right:8%;bottom:0;padding-bottom:7%;z-index:2;text-align:center;
  font-family:var(--mjo);font-size:16px;font-weight:700;letter-spacing:.2em;text-indent:.2em;
  color:#f6ecd6;text-shadow:0 2px 6px #000,0 0 14px #0009}
.packart .pk-n::before{content:"";position:absolute;left:-12%;right:-12%;bottom:0;top:-72%;z-index:-1;
  background:linear-gradient(180deg,transparent,#0b0908c4 46%,#0b0908e8 100%)}
.pk-han{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-family:var(--han);font-size:66px;font-weight:700;letter-spacing:.06em;
  background:linear-gradient(120deg,var(--t1),var(--t2));-webkit-background-clip:text;
  background-clip:text;color:transparent;opacity:.5}
.packart::before{background:radial-gradient(70% 48% at 50% 34%,var(--t1,#d4a84333),transparent 70%)}
.pkslide .pk-s{font-family:var(--mono);font-size:8.5px;letter-spacing:.24em;color:#b39a5e;z-index:1}
.pack-meta{text-align:center}
.pack-meta h3{margin:0;font-family:var(--serif);font-size:17px;font-weight:700;letter-spacing:.06em}
.pack-meta p{margin:5px 0 0;font-size:11.5px;color:var(--fg-mid);line-height:1.6}
.buys{display:grid;grid-template-columns:1fr 1fr;gap:8px;width:100%}
.buy{position:relative;border:1px solid var(--line);border-radius:var(--r-s);padding:11px 8px;background:var(--panel);
  display:flex;flex-direction:column;align-items:center;gap:4px;transition:.18s}
.buy:hover:not([disabled]){border-color:var(--seal);background:var(--panel-2)}
.buy[disabled]{opacity:.4;cursor:default}
.buy b{font-family:var(--serif);font-size:14px;font-weight:700}
.buy span{font-family:var(--mono);font-size:11px;font-variant-numeric:tabular-nums}
.buy.pg span{color:var(--chungi)} .buy.py span{color:var(--yeong)}
.links{display:flex;justify-content:center;gap:16px;flex-wrap:wrap}
.tlink{font-size:11.5px;color:var(--fg-mid);text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--line)}
.tlink:hover{color:var(--seal)}
.tbl{border:1px solid var(--line-soft);border-radius:var(--r-s);overflow:hidden}
.trow{display:flex;justify-content:space-between;gap:10px;padding:9px 12px;font-size:12px;border-bottom:1px solid var(--line-soft)}
/* 무리의 합 — 낱낱보다 먼저 나오므로 굵게 세워 둔다 (v153) */
.trow.sum{color:var(--fg);font-weight:700;background:#ffffff08}
/* 바로 위 줄에 딸린 낱낱 — 「일반 카드」 밑의 내공별 연진이 그 자리다 (2026-10-05).
   한 칸 들여 적어 **윗줄의 가지**로 읽히게 한다 */
.trow.sub{padding-left:26px;font-size:11.5px;color:var(--fg-mid);border-bottom-color:#ffffff0d}
.trow.sub .n{color:var(--fg-faint)}
.trow.sum .v{color:var(--fg)}
.trow:last-child{border-bottom:none}
.trow.h{background:var(--panel);font-family:var(--mono);font-size:9.5px;letter-spacing:.18em;color:var(--fg-faint);text-transform:uppercase}
.trow .v{font-family:var(--mono);font-variant-numeric:tabular-nums}
.trow.acc .n{color:var(--chungi)}
/* 확률표의 「자리당」 밝힘 줄 — 값이 없는 한 줄이라 왼쪽으로만 흐르게 둔다 (v0.429) */
.trow.note-row{color:var(--fg-faint);font-size:11px;line-height:1.45}
.trow.note-row b{color:var(--fg);font-weight:700}

/* ===== 카드 ===== */
.card{aspect-ratio:63/88;border-radius:3px;position:relative;overflow:hidden;border:1px solid #0b0d11;
  background:var(--panel);font-size:10px;container-type:inline-size}
/* 카드틀 — 실물 카드처럼 안쪽으로 둘러친다. 카드 폭을 따라 두께가 같이 커진다(cqw).
   ::after 는 이미 쓰는 데가 있어(.hcard.no) ::before 로 둔다 */
.card::before{content:"";position:absolute;inset:0;z-index:6;pointer-events:none;border-radius:2px;
  border:clamp(1.2px,1.7cqw,3px) solid var(--pc,var(--line));
  box-shadow:inset 0 0 0 1px #00000059,0 0 0 1px #00000070}
/* 틀에 사선 줄무늬 — 오른쪽 위에서 왼쪽 아래로 흐른다.
   테두리 칸에만 칠하려고 마스크로 안쪽을 도려낸다. 마스크를 못 쓰는 환경에서는
   위의 민무늬 테두리가 그대로 남도록 @supports 로 감싼다 — 안 그러면 줄무늬가 그림을 덮는다 */
@supports (mask-composite:exclude) or (-webkit-mask-composite:xor){
  .card::before{
    border-color:transparent;
    background:repeating-linear-gradient(135deg,
      var(--pc,var(--line)) 0 .8px,
      color-mix(in srgb,var(--pc,var(--line)) 54%,#000) .8px 1.6px) border-box;
    -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
    -webkit-mask-composite:xor;
    mask:linear-gradient(#000 0 0) content-box exclude,linear-gradient(#000 0 0)}
}
/* 보유하지 않은 카드 — 연보·엮기에서 쓸 수 없다는 것이 한눈에 보여야 한다 */
/* 미보유 카드 — 흑백으로 눌러 두되 **속은 비치지 않는다.**
   opacity 를 내리면 뒤 배경이 관통해 보여, 화면이 움직일 때 카드가 아니라 배경이 따라 움직인다 */
.card.locked{filter:grayscale(1) brightness(.42) contrast(.95)}
/* ⚠⚠ **각연자는 테두리만 제빛으로 남긴다** (2026-10-05 기획자) —
   「아직 못 만난 연」임은 흑백이 말하고, 「이것이 각연자다」는 금테가 말한다. 둘은 다른 말이다.
   ⚠ `filter` 는 그 요소의 **그림자까지** 흑백으로 돌린다. 각연자 금테는 `.card.eng` 의
     `box-shadow` 로 그리므로, 카드에 `filter` 를 걸면 **금테가 같이 죽는다.**
     그래서 카드에서는 걷고 **속엣것에만** 건다 — 그림자는 걸리지 않아 금빛이 그대로 산다.
   ⚠ 일러는 흑백 그대로다(기획자: 「일러는 흑백 동일」) — 값도 위와 똑같이 맞춰 둔다.
     위 줄을 고치거든 **여기도 같이** 고쳐라. 안 그러면 각연자만 다른 농도로 뜬다 */
.card.eng.locked{filter:none}
.card.eng.locked>*{filter:grayscale(1) brightness(.42) contrast(.95)}
/* ⚠⚠ **그림이 아직 안 왔을 때 검은 구멍이 되지 않게 한다** (2026-10-08 기획자 제보 —
   「검은 화면이었다가 저화질이 나오는 것들이 있다」). 작은 판이 캐시에 없으면 받는 동안
   그 자리가 **까맣게** 비었다. 카드가 아니라 구멍으로 보인다.
   이제 **그 도의 빛깔**이 밑에 깔린다 — 받는 동안에도 카드로 읽히고, 다 받아지면 덮인다.
   ⚠ `--pc` 는 카드가 제 도 색으로 이미 들고 있는 값이다(`cardHTML` 이 심는다) — 새로 만들 것이 없다.
   ⚠ 그림이 아예 없는 카드(「ART TBD」)는 제 꾸밈을 따로 들고 오므로 이 줄에 기대지 않는다.
   ⚠⚠ **작은 판은 `--th` 로 받는다.** 인라인으로 `background-image` 를 적으면 **이 줄을 통째로 덮어**
     빛깔이 사라진다 — 두 겹으로 쌓아야 작은 판 밑에 빛깔이 남는다 (2026-10-08 에 한 번 헛디뎠다) */
.c-art{position:absolute;inset:0;background-size:cover;background-position:center;
  background-image:var(--th,none),radial-gradient(90% 62% at 50% 18%,color-mix(in srgb,var(--pc) 42%,#000) 0%,#000 100%)}
.c-art::before{content:"";position:absolute;inset:0;background:repeating-linear-gradient(118deg,#0000 0 6px,#ffffff07 6px 7px)}
.c-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
/* 큰 카드의 원본 — 받는 동안은 숨고 밑에 깔린 작은 판이 보인다 (v0.229) */
.c-img.cfull{opacity:0;transition:opacity .22s}
.c-img.cfull.on{opacity:1}
.c-sigil{position:absolute;left:0;right:0;top:27%;text-align:center;font-family:var(--han);font-weight:700;
  font-size:clamp(26px,32cqw,58px);line-height:1;opacity:.2;color:#fff;pointer-events:none}
.c-tbd{position:absolute;left:0;right:0;bottom:38%;text-align:center;font-family:var(--mono);
  font-size:clamp(5.5px,4.4cqw,7.5px);letter-spacing:.14em;color:#ffffff3d}
/* 위쪽 어둠은 얕게 — 이름이 아래로 내려갔으니 얼굴을 덮을 이유가 없다. 아래는 글이 얹히므로 깊게 */
.c-veil{position:absolute;inset:0;background:linear-gradient(180deg,#00000059 0 9%,transparent 20% 40%,#000000d6 62%,#000000f2 100%)}
/* 배지 도안은 `assets/ui/` 그림이다. 숫자는 그 위에 CSS 가 얹는다 — 그림에는 숫자가 없다.
   그림을 갈아 끼우면 `?v=` 뒤 숫자를 올려야 브라우저가 새로 받는다 (카드 그림과 달리 자동이 아니다) */
.c-cost,.c-atk,.c-hp{position:absolute;border-radius:50%;display:flex;align-items:center;justify-content:center;
  font-family:var(--num);font-weight:700;font-variant-numeric:tabular-nums;
  width:clamp(16px,19cqw,27px);aspect-ratio:1;font-size:clamp(9.5px,10.5cqw,14.5px);
  line-height:1;text-shadow:0 1px 2px #000c;
  /* 명조 숫자는 잉크가 줄 가운데보다 0.0345em 위에 앉는다(글꼴 상승 13 / 하강 3 의 비대칭).
     가운데 맞춤은 줄상자를 맞출 뿐이라 눈에는 위로 뜬다 — 그만큼 위쪽에 여백을 줘 눌러 앉힌다.
     여백이 도안까지 밀지 않도록 배경 기준을 border-box 로 못 박는다 */
  padding-top:.069em;
  background-size:100% 100%;background-repeat:no-repeat;background-origin:border-box}
.c-cost{top:4%;left:4%;background-image:url(assets/ui/badge_cost.png?v=3);color:#f4f2ec}
/* 비용이 제값이 아닌 카드 — 싸졌으면 초록, 비싸졌으면 붉다.
   숫자만 바뀌면 원래 그 값이었는지 손을 탄 것인지 알 수가 없다 */
.c-cost.dn{color:#7dffb4;text-shadow:0 0 7px #4dffa08c,0 1px 2px #000}
.c-cost.up{color:#ff9a8e;text-shadow:0 0 7px #e8695f8c,0 1px 2px #000}
.c-atk{bottom:3.5%;left:4%;background-image:url(assets/ui/badge_atk.png?v=3);color:#fff0e8}
.c-hp{bottom:3.5%;right:4%;background-image:url(assets/ui/badge_hp.png?v=3);color:#effaf0}
.c-path{position:absolute;top:3%;right:3%;width:clamp(18px,20cqw,28px);aspect-ratio:1;
  display:flex;align-items:center;justify-content:center;color:#fff;filter:drop-shadow(0 2px 2px #000c)}
/* 도 표식은 밝은 것(정파 같은)이 밝은 그림 위에 얹히면 묻힌다 — 검은 선을 한 겹 둘러 떼어 놓는다 */
.c-path-img{display:block;width:100%;height:100%;object-fit:contain;
  filter:drop-shadow(1px 0 0 #000) drop-shadow(-1px 0 0 #000) drop-shadow(0 1px 0 #000) drop-shadow(0 -1px 0 #000)}
.c-sigil-img{width:92px;height:92px;object-fit:contain;opacity:.38;filter:drop-shadow(0 3px 4px #000c)}
/* 이름은 그림 위가 아니라 아래 글상자 맨 윗줄이다 — 일러스트의 얼굴이 위쪽에 있어 가린다 */
.c-name{padding:0 3px;text-align:center;font-family:var(--mjo);font-weight:700;
  font-size:clamp(7.5px,6.4cqw,12px);line-height:1.3;color:#fff;text-shadow:0 1px 3px #000;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* 수라장과 손패에서는 한 치수 내린다 (v128) — 60~70px 카드에서 이름이 두 줄로 접혀
   효과 태그를 밀어냈다. 자세히 보기·연보의 큰 카드는 그대로 둔다 */
.unit .c-name,.hcard .c-name{font-size:clamp(6px,5.6cqw,10px);line-height:1.22}
/* 결연 결과(여러 장을 한눈에) — 한 치수 작게 (v0.226). 두 줄로 접혀 효과 태그를 밀어내던 이름이 한 줄에 선다 */
.g5 .c-name{font-size:clamp(7px,5.7cqw,11px)}
.unit .c-name::after,.hcard .c-name::after{margin-top:2px}
/* 이름과 효과 문구는 한 덩어리로 아래에서 쌓아 올린다.
   바닥은 코스트·공력·기력 구슬 바로 위 — 구슬 높이가 카드 크기마다 달라지므로 그 값 그대로 계산해 띄운다.
   (구슬 = 아래 3.5%(=4.9cqw) + 지름 clamp(16px,19cqw,27px)) */
/* 이름과 효과 문구 사이의 가름선 — **그림을 걷어내고 흰 줄 하나로** 바꿨다 (v128).
   뇌문 띠는 작은 카드에서 뭉개져 무늬가 아니라 때처럼 보였다.
   카드 폭을 다 채우지 않는다 — 절반만 그어야 이름 아래에 붙은 줄로 읽힌다 */
/* ⚠ **두께는 1px 이다. 1 미만으로 내리지 말 것** (v158).
   v139 에 0.34px 로 두었다 — 화소 밀도 3인 휴대폰에서 딱 1화소로 떨어지라고 잡은 값인데,
   밀도가 1·2인 화면에서는 줄이 놓인 세로 자리가 화소 경계에 맞느냐 아니냐에 따라
   **어떤 카드는 그어지고 어떤 카드는 통째로 사라졌다.** 있다 없다 하는 선은 없느니만 못하다.
   가늘어 보이게 하는 것은 두께가 아니라 **알파**가 맡는다.
   폭은 25% — 카드 폭을 다 채우면 가름선이 아니라 테두리로 읽힌다 */
.c-name::after{content:"";display:block;width:25%;height:1px;margin:3px auto 0;
  background:#ffffff80;pointer-events:none}
.c-foot{position:absolute;left:5%;right:5%;bottom:calc(4.9cqw + clamp(16px,19cqw,27px) + 3px);
  display:flex;flex-direction:column;gap:2px;pointer-events:none;max-height:70%;overflow:hidden}
/* 카드 종류(권속·각연자·초식…)는 맨 윗줄, 코스트 구슬과 도 표식 사이에 앉힌다.
   아래 글상자에서 빼내야 효과 문구가 쓸 자리가 그만큼 넓어진다 */
.c-type{position:absolute;top:4%;left:50%;transform:translateX(-50%);z-index:2;max-width:42%;
  text-align:center;font-family:var(--mjo);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  font-size:clamp(5px,4.1cqw,7px);line-height:1.55;letter-spacing:.06em;text-indent:.06em;
  color:#efe6d6;padding:0 3px;border-radius:7px;background:#000000ab;text-shadow:0 1px 2px #000}
/* ⚠ **효과 자리는 비어 있어도 한 줄을 잡아 둔다** (v157).
   효과가 없는 카드와 한 줄짜리 효과를 가진 카드가 나란히 서면 이름 높이가 들쭉날쭉했다.
   한 줄만 잡아 둔다 — 두 줄짜리(길흉 같은 것)는 어차피 한 줄 더 넘어간다.
   `min-height` 는 줄높이(1.45)와 같은 em 이다. **글꼴 크기를 고치면 이 값은 따라온다** */
.c-text{font-size:clamp(5.5px,4.4cqw,8px);line-height:1.45;min-height:1.45em;color:#e9e2d6;
  text-align:center;white-space:pre-line;display:-webkit-box;-webkit-line-clamp:5;-webkit-box-orient:vertical;overflow:hidden}
/* 손패만 한 카드에서는 효과 문구가 6px 이라 어차피 안 읽힌다. 이름과 유형만 남긴다.
   컨테이너 쿼리는 특이도를 올려 주지 않으므로 반드시 `.c-text` 뒤에 와야 이긴다 */
@container (max-width:95px){ .c-text{display:none} }
/* 각연자 표식 — 아래 가운데는 보유 수량이 쓰는 자리라 서로 부딪혔다. 코스트 바로 아래로 옮긴다 */
.c-eng{position:absolute;left:4%;top:calc(4% + clamp(16px,19cqw,27px) + 1.6cqw);
  width:clamp(16px,19cqw,27px);text-align:center;font-family:var(--han);font-weight:800;
  font-size:clamp(5.5px,4.9cqw,8.5px);letter-spacing:0;line-height:1.05;color:var(--chungi);
  text-shadow:0 1px 3px #000,0 0 7px #000a}
/* 보유 수량은 공력·기력 구슬과 같은 줄, 두 구슬 사이 한가운데에 앉힌다.
   구슬 중심 높이 = 아래 4.9cqw + 지름의 절반 */
.c-own{position:absolute;left:50%;bottom:calc(4.9cqw + clamp(16px,19cqw,27px)/2);
  transform:translate(-50%,50%);padding:2px 6px;font-family:var(--mono);
  font-size:clamp(8px,7cqw,10px);font-weight:700;white-space:nowrap;
  background:#000000cc;color:var(--fg);z-index:3;border-radius:9px;border:1px solid #ffffff1f}
.c-own.z{color:var(--fg-faint)}
/* 자세히 보기 */
[data-cid],[data-pkpool]{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}
.pkcover[data-pkpool]{cursor:pointer}
.lp-on{outline:1px solid var(--seal);outline-offset:1px}

/* 연보 */
.chips{display:flex;gap:6px;overflow-x:auto;padding-bottom:2px;scrollbar-width:none}
/* 줄 이름을 .frow 에서 .fline 으로 바꿨다 — 수라장의 줄(.frow, min-height:72px)과 이름이 겹쳐
   필터 다섯 줄이 저마다 72px 을 차지하고 있었다. 이름이 부딪치면 조용히 이런 일이 난다 */
/* ⚠ **거르개는 전부 명조다** (v0.226) — 연보·명운 엮기가 이 한 벌을 쓴다. 이름표·칩·고르기·찾기·접힌 줄까지 */
.filters{display:flex;flex-direction:column;gap:5px;font-family:var(--mjo)}
.filters .flab,.filters .ftog-t,.filters .ftog-s,.filters .chip,.filters .fsel,.filters .fq{font-family:var(--mjo)}
.fline{display:flex;align-items:center;gap:8px;min-width:0;min-height:0}
.flab{flex:none;width:28px;font-size:10px;letter-spacing:.14em;color:var(--fg-faint)}
.fchips{flex:1;min-width:0;display:flex;gap:5px;overflow-x:auto;scrollbar-width:none;padding-bottom:1px}
.fchips::-webkit-scrollbar{display:none}
/* ⚠ **넷째 칸이 생겼다** (2026-10-14) — 내공·보유·차례에 효과가 붙었다.
   손말틀(375px)에서 넷이 한 줄에 서면 한 칸이 78px 이라 「내공 전체」가 말줄임에 먹힌다.
   그래서 **둘씩 두 줄**로 접는다 — 좁으면 접히고 넓으면 한 줄로 선다 */
/* ⚠⚠ **한 줄에 넷이다** (2026-10-14 기획자 — 「한 줄에 4칸 안 들어가냐, 굳이 2줄로 할 필요가」).
   둘씩 두 줄로 두었더니 아랫줄을 잘 안 누른다. 판 폭이 430 으로 못 박혀 있어
   넷이 들어간다 — 글자 11px 에 칸 하나가 80px 쯤이고 「내공 전체」가 55px 다.
   ⚠ 여백을 5 → 4 로, 칸 안 좌우를 6 → 4 로 줄여 좁은 폰(375)에서도 글이 안 잘리게 했다 */
.fsels{flex:1;min-width:0;display:grid;grid-template-columns:repeat(4,1fr);gap:4px}
.fsels .fsel{padding-inline:4px}
@media (min-width:430px){.fsels{grid-template-columns:repeat(4,1fr)}}
/* 명운 엮기에서는 필터를 접어 둔다 — 서른 장을 골라 담는 화면에서
   필터가 첫 화면의 반을 먹으면 카드를 보려고 계속 밀어 내려야 한다.
   접힌 채로도 무엇이 걸려 있는지는 한 줄로 보여 준다 */
.ftog{width:100%;display:flex;align-items:center;gap:9px;padding:7px 10px;
  border:1px solid var(--line);border-radius:2px;background:var(--panel);text-align:left}
.ftog-t{flex:none;font-size:10px;letter-spacing:.14em;color:var(--fg-faint)}
.ftog-s{flex:1;min-width:0;font-size:11.5px;color:var(--fg-mid);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ftog-s.off{color:var(--fg-faint)}
.ftog-i{flex:none;font-size:9px;color:var(--fg-faint);transition:transform .18s}
.filters.open .ftog{border-color:var(--seal)}
.filters.open .ftog-i{transform:rotate(180deg)}
.fbody{display:flex;flex-direction:column;gap:5px;margin-top:6px}
.fq{flex:1;min-width:0;padding:6px 10px;border:1px solid var(--line);border-radius:2px;
  font-size:12px;color:var(--fg);background:var(--panel);font-family:inherit}
.fq::placeholder{color:var(--fg-faint)}
.fq:focus{outline:none;border-color:var(--seal)}
.fsel{min-width:0;padding:5px 6px;border:1px solid var(--line);border-radius:2px;font-size:11px;
  color:var(--fg-mid);background:var(--panel);font-family:inherit;appearance:none;text-align:center}
.fsel:focus{outline:none;border-color:var(--seal);color:var(--fg)}
.chips::-webkit-scrollbar{display:none}
.chip{flex:none;padding:5px 11px;border:1px solid var(--line);border-radius:2px;font-size:11.5px;color:var(--fg-mid);white-space:nowrap}
.chip:hover{color:var(--fg)}
.chip.on{background:var(--seal-deep);border-color:var(--seal);color:#f3e4e1}
/* 잠긴 칩 — 명운 엮기에서 남의 종파 (v204). **지우지 않고 눌리지만 않게 한다** —
   자리가 사라지면 왜 못 고르는지가 안 보인다 */
.chip.off{opacity:.3;pointer-events:none;text-decoration:line-through}
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.gcard{position:relative;cursor:pointer}
/* 찾기 줄에 바짝 붙어 있으면 어디까지가 거르개고 어디부터가 카드인지 안 갈린다 */
.poolgrid{margin-top:9px;gap:11px}
#plBody{gap:9px}
.tally{display:flex;justify-content:flex-end;font-family:var(--mono);font-size:11px;color:var(--fg-mid);font-variant-numeric:tabular-nums}
.legacy{border:1px solid #5c4a22;background:#231c10;border-radius:var(--r-s);padding:9px 11px;font-size:11px;color:var(--chungi);line-height:1.7}

/* 명운(덱) */
.preset{display:flex;align-items:center;gap:11px;width:100%;text-align:left;padding:12px 13px;
  border:1px solid var(--line);border-radius:var(--r-s);background:var(--panel)}
.preset:hover{border-color:var(--seal)}
.preset.empty,.preset.locked{border-style:dashed;background:none}
.preset.locked{opacity:.62}
.p-no{font-family:var(--mono);font-size:11px;color:var(--fg-faint);width:14px;flex:none;text-align:center}
.p-body{flex:1;min-width:0}
.p-name{font-family:var(--serif);font-size:14.5px;font-weight:700;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.p-meta{font-size:11px;color:var(--fg-mid);margin-top:2px;display:block;font-family:var(--mono);font-variant-numeric:tabular-nums}
.p-meta.bad{color:var(--warn)}
.dots{display:flex;gap:3px;flex:none}
.dot{width:7px;height:7px;border-radius:50%}

#s-edit,#s-battle{padding:var(--top-gap) 0 0;gap:0}
/* ⚠ 머리말은 **짧을수록 좋다** (2026-10-07 기획자) — 여기서 아낀 세로가 그대로
   아래 카드 목록으로 간다. 이름과 장수는 한 번 보고 마는 것이지 내내 읽는 것이 아니다 */
.ed-head{flex:none;padding:7px 12px 6px;border-bottom:1px solid var(--line-soft);background:var(--panel);display:flex;flex-direction:column;gap:6px}
.ed-row{display:flex;gap:10px;align-items:center}
/* 이름칸은 좁게, 장수는 크게 — 엮는 동안 내내 보는 것은 이름이 아니라 장수다 */
.ed-name{flex:0 1 58%;min-width:0;background:var(--ink-2);border:1px solid var(--line);border-radius:var(--r-s);
  padding:6px 9px;font-family:var(--mjo);font-size:12px;font-weight:700}   /* 명운 이름 — 명조 (v0.226) */
.ed-cnt{margin-left:auto;font-family:var(--mono);font-size:16.5px;font-weight:800;font-variant-numeric:tabular-nums;
  flex:none;color:var(--fg);letter-spacing:.01em;line-height:1}
.ed-cnt.full{color:var(--ok)} .ed-cnt.over{color:var(--danger)}
/* 코스트 분포는 가로 막대로 눕힌다 — 칸이 다섯뿐이라 세로로 세우면 오히려 안 읽힌다 */
/* ⚠ 엮은 카드가 **왼쪽**, 내공 분포가 **오른쪽**이다 (2026-10-07 기획자).
   ⚠ 키를 여기서 못 박는다 — 양쪽이 **같은 키를 꽉 채워** 쓴다. 전에는 목록만 125px 이고
     분포가 짧아 오른쪽 아래가 비었다. 넉 줄이 보이는 키가 125px 다(아래 `.dklist` 메모) */
/* ⚠ **키 셈** — 넉 줄(125) + 머리글(22) + 아래 여백(6) + 테 둘(2) = 155.
   목록만 125 로 두었더니 머리글이 그만큼 먹어 **석 줄 반**밖에 안 보였다 */
/* ⚠ **위 줄과 세로 열을 맞춘다** (2026-10-07 기획자) — 엮은 카드는 **명운 이름칸**과 같은 폭,
   내공 분포는 **문양 단추가 서는 자리**부터다. 그래서 `gap` 과 폭을 `.ed-row` 와 똑같이 쓴다
   (`.ed-name{flex:0 1 58%}` · `.ed-row{gap:10px}`). 한쪽만 고치면 열이 어긋난다 */
.ed-mid{display:flex;gap:10px;align-items:stretch;height:155px}
/* ⚠ **분포도 엮은 카드와 같은 틀(`.dkwrap`)을 쓴다** (2026-10-07 기획자) — 머리글이 붙어야
   무엇을 보는 칸인지 한눈에 읽힌다. 둘이 같은 꼴이라 나란히 서도 따로 놀지 않는다 */
/* ⚠ `.cvwrap` 은 `.dkwrap` 과 **같은 틀을 쓰므로 class 가 둘이다**(`class="dkwrap cvwrap"`).
   그래서 `.dkwrap` 의 `flex` 를 이기려면 **둘을 겹쳐 적어야** 한다 — `.cvwrap` 한 짝으로는
   뒤에 선 `.dkwrap` 에 져서 **둘 다 같은 폭**이 된다 (2026-10-07 에 그래서 열이 안 맞았다) */
.dkwrap.cvwrap{flex:1;min-width:0}
/* ⚠ **세로 막대다.** 여섯이 한 줄에 서서 폭만 쓴다 — 가로로 눕히면 세로를 길게 먹는다.
   ⚠ 칸이 여섯이다(0~5내공) — 사이를 좁게 잡아야 막대가 너무 가늘어지지 않는다 */
.curve{flex:1;min-height:0;display:flex;align-items:stretch;gap:3px;padding:0 6px 6px}
.cv{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;gap:3px}
.cv-n{flex:none;font-family:var(--mono);font-size:9.5px;font-weight:700;
  color:var(--fg-mid);line-height:1;font-variant-numeric:tabular-nums}
/* 막대가 서는 통 — 남는 키를 다 먹고, 막대는 **아래에서** 자란다 */
.cv-t{flex:1;min-height:0;width:100%;border-radius:2px;background:#ffffff0d;overflow:hidden;
  display:flex;align-items:flex-end}
/* ⚠ **많을수록 진하다** (2026-10-07 기획자). `--w` 는 0~1 — 가장 많은 칸이 1 이다.
   바닥을 .28 로 깔아 둔다. 0 에서 시작하면 한 장짜리 칸이 아예 안 보인다.
   ⚠ 늘고 주는 것이 눈에 보이게 `height` 에 참을 건다 — 결은 뒤로 갈수록 느긋한 쪽이다.
     색도 함께 따라가야 키만 변하고 색은 툭 바뀌는 어긋남이 없다 */
.cv-b{display:block;width:100%;border-radius:2px;--w:0;
  background:color-mix(in srgb,var(--seal) calc((.28 + .72*var(--w))*100%),#2a2733);
  transition:height .34s cubic-bezier(.32,.72,.3,1),background-color .34s ease-out}
.cv-b.z{background:transparent}
.cv-c{flex:none;height:11px;font-family:var(--mono);font-size:9.5px;color:var(--fg-faint);
  line-height:11px;font-variant-numeric:tabular-nums}
.ed-body{flex:1;min-height:0;overflow-y:auto;padding:11px 14px 16px;display:flex;flex-direction:column;gap:11px}
/* 엮은 카드 — 위에 목록으로 둔다 */
.dkwrap{flex:0 1 58%;min-width:0;display:flex;flex-direction:column;
  border:1px solid var(--line-soft);border-radius:var(--r-s);background:var(--ink-2);overflow:hidden}
.dkhead{flex:none;display:flex;justify-content:space-between;align-items:center;padding:5px 8px 3px;
  font-size:9.5px;letter-spacing:.14em;color:var(--fg-faint)}
.dkn{font-variant-numeric:tabular-nums;letter-spacing:.04em;color:var(--fg-mid)}
/* ⚠ **키는 틀(`.ed-mid`)이 쥔다** — 여기서는 남는 키를 다 먹기만 한다.
   넉 줄이 보이는 키가 125px 다: 한 줄 29px(알맹이 19 + 안쪽 4·4 + 테 1·1)에 사이 3px —
   29*4 + 3*3 = 125. 줄 수를 바꾸려거든 `.ed-mid` 의 `height` 를 이 셈으로 고친다 */
.dklist{flex:1;min-height:0;overflow-y:auto;padding:0 6px 6px;display:flex;flex-direction:column;gap:3px;
  scrollbar-width:none}
.dklist::-webkit-scrollbar{display:none}
.dkrow{display:flex;align-items:center;gap:5px;width:100%;padding:4px 5px;border-radius:2px;
  background:var(--panel);border:1px solid transparent;text-align:left}
.dkrow:hover{border-color:var(--seal);background:var(--panel-2)}
.dkrow.miss{background:#221513;border-color:#5a3630}
/* ⚠ **카드와 같은 내공 딱지를 쓴다** (2026-10-07 기획자) — 목록과 카드가 같은 그림이라야
   눈이 옮겨 다닐 때 한 번 더 읽지 않는다. 그림은 `.c-cost` 가 쓰는 것과 같은 것이다.
   ⚠ 19px 은 원본(그림이 쥔 꼴)보다 작으므로 `contain` 으로 줄여 담는다 —
     `cover` 로 두면 테두리가 잘려 다른 딱지로 보인다 */
.dkc{flex:none;width:19px;height:19px;display:flex;align-items:center;justify-content:center;
  background:url(assets/ui/badge_cost.png?v=3) center/contain no-repeat;
  font-size:10px;font-weight:700;color:#f4f2ec;font-variant-numeric:tabular-nums;
  text-shadow:0 1px 2px #000}
.dkbar{flex:none;width:3px;align-self:stretch;border-radius:1px}
.dkn2{flex:1;min-width:0;font-family:var(--mjo);font-size:10.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dkq{flex:none;font-size:11px;font-weight:700;color:var(--fg-mid);font-variant-numeric:tabular-nums}
/* ⚠ 「각」 한 글자로 줄여 적던 것을 **「각연자」로 푼다** (2026-10-07 기획자) — 한 글자로는 못 읽는다 */
.dkq.e{font-family:var(--mjo);font-size:9.5px;letter-spacing:-.01em;color:var(--chungi)}
/* 고르는 격자 */
/* ⚠ **누르면 살짝 커졌다 돌아온다** (2026-10-12 기획자 — 「터치감」).
   담기는 그 순간 손끝에 눌린 것이 보여야 한다. 지금은 목록이 소리 없이 다시 그려질 뿐이라
   **눌렸는지 안 눌렸는지가 손에 안 남는다.**
   ⚠⚠ **`paintEdit()` 이 `#edBody` 를 통째로 다시 그린다** — 누른 그 요소는 같은 틱에 사라진다.
     그래서 누른 자리에 거는 것이 아니라, **다시 그린 뒤 같은 카드를 찾아** 건다(`ui.js` 의 `눌림표`).
   ⚠ `transform-origin` 을 가운데에 두어야 칸 밖으로 비어져 나가지 않는다.
   ⚠ 바깥 칸(`.gcard`)이 아니라 **안쪽 카드(`.card`)만** 키운다 — 칸을 키우면 격자가 흔들린다 */
/* ⚠⚠ **`transform` 이 아니라 `scale` 로 키운다.** 누르는 것 가운데에는 제 `transform` 을 이미
   쓰는 것이 많다(가운데 맞추는 `translate(-50%,-50%)`, 마름모의 `rotate(45deg)` 따위).
   `transform` 으로 키우면 그것들을 **통째로 덮어써** 자리가 튄다. `scale` 은 따로 겹쳐 올라간다 */
@keyframes 눌림{0%{scale:1}38%{scale:1.07}100%{scale:1}}
.gcard.tap .card{animation:눌림 190ms cubic-bezier(.3,1.3,.6,1)}
/* ⚠ 연출을 줄여 달라고 한 기기에서는 키우지 않는다 */
@media (prefers-reduced-motion:reduce){.gcard.tap .card,.tapped{animation:none}}

/* ═══ 누르는 것 모두에 **눌린 느낌**을 준다 (2026-10-12 기획자 — 「웬만한 버튼들에 모두」) ═══
   손잡이마다 손으로 붙이지 않는다. **몸(`document`)에서 한 번만 받아** 누른 것에 표를 달고,
   표가 달린 동안만 키운다 (`ui.js` 의 「눌린 느낌」).
   ⚠ 카드는 바깥 칸이 아니라 **안쪽 카드**를 키우므로 위의 `.gcard.tap` 이 따로 맡는다.
   ⚠ 작은 것은 덜 키운다 — 1.07 배는 큰 단추에서 알맞고 작은 칩에서는 들썩여 보인다 */
.tapped{animation:눌림 190ms cubic-bezier(.3,1.3,.6,1)}
.chip.tapped,.coin.tapped,.gq.tapped,.mmi.tapped,.mic.tapped,.pkdot.tapped,.varr.tapped,.parr.tapped{
  animation-name:눌림작게}
@keyframes 눌림작게{0%{scale:1}38%{scale:1.13}100%{scale:1}}
.gcard.pickable{cursor:pointer}
.gcard.pickable:hover .card{box-shadow:0 0 0 1px var(--seal)}
/* ═══ 카드 세 모습 — **채도가 말을 가른다** (2026-10-07 기획자) ═══════════════════
     ① 아직 더 담을 수 있다 — 제빛 그대로
     ② **가진 것을 다 담았다**(`used`) — 채도 절반, 칩도 회색
     ③ **아직 없다**(`.card.locked`) — 흑백
   ⚠⚠ 셋이 **한 눈금씩 다른 채도**라 나란히 놓여도 갈린다. 예전에는 ②와 ③이 둘 다
     흑백이라 구분이 없었고, ②에는 투명(.3)까지 걸려 뒤 배경이 비쳤다.
   ⚠ 흐리게 하는 것은 **카드뿐**이다 — 위에 얹힌 빼기 단추는 늘 또렷해야 한다 (v0.227).
   ⚠ **`used` 는 상한이 아니라 보유 장수로 가른다** — 두 장까지 담을 수 있어도
     한 장만 가졌으면 그 한 장을 담은 순간 다 쓴 것이다. 더 담으려면 연진을 치러야 한다 */
.gcard.used .card{filter:saturate(.5) brightness(.82)}
/* ⚠ **다 쓴 표는 촘촘한 빗금이다** (2026-10-07 기획자). 채도만으로는 작은 칸에서 덜 갈린다.
   **오른쪽 위에서 왼쪽 아래로** 검은 실선을 여러 줄 촘촘히 긋는다 — 한 줄짜리 사선은
   「그어 지운 것」으로 보였고, 여러 줄이면 **가려 둔 것**으로 읽힌다.
   ⚠ **줄은 가장 얇게(.5px), 사이는 2.5px, 짙기는 .27**(`#00000045`) — 굵거나 성기면
     그림 위에서 글씨처럼 읽혀 카드 문구와 다툰다. **카드 테두리만큼 촘촘해야**(기획자)
     줄이 하나하나 보이지 않고 **천을 덮어 둔 결**로 읽힌다.
   ⚠ **줄만 반투명이다.** 칸(`.gcard`)이나 카드에 `opacity` 를 걸면 뒤 배경이 관통한다 —
     그것을 걷어 내려고 오늘 온종일 손본 자리다.
   ⚠ `z-index` 는 `.card::before`(6) 아래, 수치 칩(3) 위에 둔다 — 칩은 읽혀야 한다.
   ⚠ 각연자는 `.card` 에 `filter` 를 안 걸므로 이 줄도 제빛이다. 얇아 금테는 안 가린다.
   ⚠⚠ **기울기는 `45deg` 다.** `repeating-linear-gradient` 의 각은 **줄이 아니라 줄에 수직인 축**을
     가리킨다 — `135deg` 로 적으면 줄은 그 반대인 왼쪽 아래→오른쪽 위로 눕는다. 한 번 헛디딘 자리다 */
.gcard.used .card::after{content:"";position:absolute;inset:0;z-index:4;pointer-events:none;
  background-image:repeating-linear-gradient(135deg,#00000045 0 .5px,#0000 .5px 2.5px);
  /* ⚠ **빗금 아래에 옅은 검은 막을 한 겹 더 깐다** (2026-10-12 기획자 — 「살짝 어둡게」).
     빗금만으로는 「가려 둔 것」까지만 읽히고 **담을 수 없다**가 덜 읽힌다.
     ⚠ 막은 **이 덮개에만** 건다. `.gcard` 나 `.card` 에 `opacity` 를 걸면 뒤 배경이 관통한다 —
       위 머리말이 말하는 그 자리다 */
  background-color:#00000040}
/* ⚠⚠ **다 쓴 카드에는 정마름모 금지 표를 얹는다** (2026-10-12 기획자, 레퍼런스 지정).
   빗금과 어둠은 「가려 둔 것」까지를 말하고, **「더 못 담는다」**는 이 표가 말한다.
   ⚠ **`.card` 가 아니라 `.gcard` 의 가짜 요소다.** `.card` 는 `filter` 때문에 쌓임 바탕을 만들어
     그 안에 넣으면 빗금·카드틀과 z 를 다투게 된다. 밖에 두면 늘 맨 위다.
   ⚠ **`::before` 가 마름모판, `::after` 가 금지 동그라미**다. 하나로는 둘 다 못 그린다.
   ⚠ 크기는 카드 폭의 비율(%)로 잡는다 — 연보와 명운 엮기의 칸 크기가 서로 다르다.
   ⚠ `pointer-events:none` 을 빼지 마라. 빼면 카드를 눌러도 이 표가 먼저 먹는다 */
/* ⚠ 마름모판은 **살짝 비친다** (2026-10-12 기획자 — 「투명도 조금만」). 밑그림이 어렴풋이 보여야
   가려 둔 것이지 지워 버린 것이 아니게 읽힌다. ⚠ 판에만 건다 — 금지 표는 또렷해야 한다 */
.gcard.used::before{content:"";position:absolute;left:50%;top:50%;z-index:7;pointer-events:none;
  width:34%;aspect-ratio:1;transform:translate(-50%,-50%) rotate(45deg);
  background:#0b090894;border:1px solid #ffffff24;border-radius:3px;
  box-shadow:0 1px 6px #0000005c}
/* 금지 동그라미 — 테두리로 원을 그리고 **빗금 하나를 결로 깔아** 가운데를 가른다.
   ⚠⚠ **기울기는 `135deg` 라야 왼쪽 위 → 오른쪽 아래로 눕는다**(표준 금지 표시의 방향).
     `45deg` 로 적으면 줄이 그 반대인 왼쪽 아래 → 오른쪽 위로 서 버린다 — 2026-10-12 에 한 번 밟았다.
     까닭은 위 빗금 머리말과 같다. 각은 **줄이 아니라 줄에 수직인 축**을 가리킨다 */
.gcard.used::after{content:"";position:absolute;left:50%;top:50%;z-index:8;pointer-events:none;
  width:15%;aspect-ratio:1;transform:translate(-50%,-50%);border-radius:50%;
  /* ⚠ **빨강이다** (2026-10-12 기획자, 레퍼런스 지정). 흰 동그라미는 카드 글씨와 같은 빛이라
     「막은 것」이 아니라 꾸밈으로 읽혔다. 도(道) 색이 아닌 `--danger` 를 써서 **어느 도에서나
     같은 뜻**으로 서게 한다. 비치는 마름모판 위라 조금 짙게 깐다 */
  border:2px solid var(--danger);
  background:linear-gradient(135deg,#0000 calc(50% - 1px),var(--danger) calc(50% - 1px),
    var(--danger) calc(50% + 1px),#0000 calc(50% + 1px));
  filter:drop-shadow(0 0 2px #00000096)}
.gcard.used .card.eng{filter:none}
.gcard.used .card.eng>*{filter:saturate(.5) brightness(.82)}
/* ⚠ 미보유는 **흑백 그대로** — 위 줄보다 세게 눌러 쓴다. 값은 `.card.locked` 와 같아야 한다.
   저쪽을 고치거든 **여기도 같이** 고쳐라. 안 그러면 두 자리가 다른 농도로 뜬다 */
.gcard.used .card.locked{filter:grayscale(1) brightness(.42) contrast(.95)}
.gcard.used .card.eng.locked{filter:none}
.gcard.used .card.eng.locked>*{filter:grayscale(1) brightness(.42) contrast(.95)}
/* 아래 가운데 칩 — **「아직 안 쓴 장수 / 가진 장수」** (2026-10-07 기획자).
   ⚠ **앞의 수가 남은 장수다.** `0/1` 이면 가진 한 장을 이미 엮은 것이다.
   ⚠ **남은 것이 있으면 초록, 다 썼으면 회색** — 색이 「지금 더 담을 수 있는가」를 말한다.
   ⚠ 명운 엮기(`#edBody`)에서만 그렇게 칠한다. 연보에서는 같은 칩이 그냥 보유 수량이다.
   ⚠ 칩을 새로 달지 않는다. 왼쪽 위는 **내공 값**이, 오른쪽 위는 **빼기 단추**가 쓴다 */
#edBody .c-own{border-color:var(--ok);color:var(--ok);background:#0b0908ee;font-weight:800}
#edBody .c-own.z{border-color:#ffffff1f;color:var(--fg-faint);font-weight:700}
/* ⚠⚠ **이 블록을 지우지 마라** (2026-10-07 에 한 번 지웠다). 빼기 단추는 글씨가 없고
   `background` 그림과 크기만으로 서 있어, 이 줄이 사라지면 **단추가 그려지는데 안 보인다** —
   눌러서 빼는 길이 통째로 막힌다. 위 카드 꾸밈을 손볼 때 함께 쓸려 가기 쉽다 */
/* 명운 엮기의 오른쪽 위 — **담은 장수 대신 「빼기」 단추**다 (v0.227). 누르면 명운에서 한 장 뺀다 */
.gq.gminus{width:26px;min-width:26px;height:26px;padding:0;border:0;border-radius:50%;font-size:0;line-height:1;cursor:pointer;
  color:transparent;background:transparent url(assets/ui/icon_deck_remove.webp?v=1) center/contain no-repeat;
  box-shadow:0 2px 6px #000a}
.gq.gminus:active{transform:scale(.9)}
.gq{position:absolute;top:3px;right:3px;z-index:5;
  min-width:24px;height:19px;padding:0 6px;border-radius:10px;
  display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:800;
  background:#0b0908ee;border:1px solid var(--ok);color:var(--ok);font-variant-numeric:tabular-nums}
.gcard.indeck .c-eng{display:none}
/* ⚠⚠ **각연자(`.eng`)의 테는 건드리지 않는다** (2026-10-07 기획자 제보 — 「왜 점멸이 되지」).
   `.card.eng` 는 `engb` 로 **2.4초에 한 번 숨쉬는** 금테다. 그 애니메이션은 50% 만 적어 두고
   0%·100% 는 **그때 계산된 `box-shadow`** 를 쓴다 — 여기서 초록이나 회색으로 덮으면
   **초록 ↔ 금빛 사이를 오가며 깜빡인다.** 숨쉬기가 점멸이 되는 자리다.
   ⚠ 그래서 둘 다 `:not(.eng)` 로 비켜 둔다. 각연자는 금테 하나로 충분하고,
     담았는지는 오른쪽 위 빼기 단추와 아래 칩이 말한다 */
.gcard.indeck .card:not(.eng){box-shadow:0 0 0 1px var(--ok)}
/* 다 쓴 카드는 테두리도 눌러 둔다 — 초록은 「더 담을 수 있다」는 말이다 */
.gcard.indeck.used .card:not(.eng){box-shadow:0 0 0 1px var(--line)}
/* ⚠ **목록에는 연진 값을 띄우지 않는다** (2026-10-07 기획자) — 사는 것은 카드를 펼쳐 보는
   자리에서 한다. 칸마다 값이 붙으면 그림을 가리고, 고르는 동안 읽을 것이 하나 더 는다.
   ⚠ `.gcard.craftable` 은 **꾸밈을 걷었다.** 투명(.82)까지 섞이면 채도로 가른 세 모습이
     네 모습이 된다 — 그 셋만으로 말한다(`.gcard.used` 메모) */
.ed-foot{flex:none;display:flex;gap:8px;padding:10px 14px calc(10px + env(safe-area-inset-bottom));
  border-top:1px solid var(--line-soft);background:var(--panel)}
.result .fbtn{flex:none;width:min(220px,72%)}
/* flex:1 은 단추를 가로로 나눠 갖자는 뜻이다. 화면에 바로 놓이면 세로로 늘어나 버린다 */
.screen > .fbtn{flex:none}
.fbtn{flex:1;padding:11px;border:1px solid var(--line);border-radius:var(--r-s);font-size:13px;text-align:center;transition:.16s}
.fbtn:hover{border-color:var(--seal)}
.fbtn.pri{background:var(--seal-deep);border-color:var(--seal);color:#f3e4e1;font-weight:600}
.fbtn[disabled]{opacity:.4;cursor:default;background:var(--panel-2);border-color:var(--line);color:var(--fg-mid);font-weight:400}
/* ⚠⚠ 이 `.warn` 은 **알림 상자** 전용이다. 시계는 20초부터 `.warn` 을 달기 때문에
   가려 두지 않으면 시계에 테두리와 바탕이 함께 붙는다 — 갑자기 상자가 쳐진 것처럼 보였다 (v148).
   ⚠⚠ **시계를 새로 만들거든 그 이름을 여기 `:not()` 에 더한다.** 같은 덫을 두 번 밟았다 —
      차례 시계(`.tbar`, v148) 다음에 **멀리건 시계(`.mclk`, v0.342)** 가 또 걸렸다.
      노랑이 되는 순간에만 상자가 생기므로 **평소 보기로는 안 잡힌다** (2026-10-06 기획자 제보) */
.warn:not(.tbar):not(.mclk){border:1px solid #5c4220;background:#231a0f;border-radius:var(--r-s);padding:9px 11px;font-size:11.5px;color:var(--warn);line-height:1.7}

/* ===== 수라 ===== */
.battle-shell{flex:1;min-height:0;display:grid;grid-template-columns:minmax(430px,560px);grid-template-areas:"arena";justify-content:center;background:transparent;overflow:hidden}   /* 바탕은 #s-battle 이 진다 */
/* 수라 화면의 바탕 — 세로로 긴 그림 한 장이 위아래 끝까지 이어진다.
   수라장 칸에만 깔면 본체·패 칸에서 그림이 토막 나 화면이 여러 조각으로 보인다 */
.battle-arena{grid-area:arena;min-width:0;min-height:0;display:flex;flex-direction:column;
  box-shadow:0 0 36px #0009;position:relative;z-index:2;
  background:transparent}
/* 바탕은 수라 화면 전체가 진다 — 위쪽 카메라 여백(.screen 의 padding)까지 같은 그림이라야
   거기만 색이 달라 보이지 않는다. 그늘은 수라장(가운데)에서 멀어질수록 짙어진다 */
/* 바탕을 아주 약간만 눌러 둔다 — 카드와 글자가 흙바닥 위에서 더 또렷해진다.
   맨 앞의 평평한 한 겹(#0000001f)이 그 구실을 한다 */
#s-battle{background-color:#15120f;
  background-image:linear-gradient(#0000001f,#0000001f),
    linear-gradient(180deg,
    #070709ed 0%,#070709b0 9%,#0707095c 20%,#0707091f 33%,
    #07070900 50%,
    #0707091f 67%,#0707095c 80%,#070709b0 91%,#070709ed 100%),
    url(assets/ui/bg_battle_ground.webp?v=3);
  background-size:100% 100%,100% 100%,cover;background-position:center,center,center;background-repeat:no-repeat}
.battle-side{min-width:0;padding:14px 12px;background:linear-gradient(180deg,#0a0a0bb3,#07070ad9);position:relative;z-index:1}   /* 보랏빛을 빼고 중성으로 */
.battle-side.clock-side{grid-area:clock;display:flex;flex-direction:column;align-items:flex-end}
.hud-label{width:100%;font-size:9px;line-height:1;letter-spacing:.2em;color:var(--fg-faint);text-align:left;margin-bottom:7px}
.clock-side .hud-label{text-align:right}
.battle-side .clock{width:86px;min-height:52px;flex-direction:column;gap:1px;padding:6px 10px;background:#0b0b0dd9}
.clock::before{content:"남은 시간";font-size:8px;letter-spacing:.12em;color:var(--fg-faint)}
.battle-side .ck-n{font-size:24px;line-height:1.1}
/* ⚠ **수라장도 다른 화면과 같은 폭을 쓴다** (v0.247).
   예전에는 넓은 화면에서만 판을 1100px 로 벌렸다. 그런데 이 게임은 **세로로 긴 게임**이라,
   벌려 놓으면 수라장이 좌우로 늘어져 흙바닥만 넓어지고 멀리건의 카드가 사방으로 흩어졌다.
   폭은 `--app-w` 하나로 고정하고, 남는 좌우는 강호의 산 그림이 받는다.
   ⚠ 그래서 아래 배치는 **화면 너비와 상관없이 늘 같다** — 예전의 `max-width:759px` 묶음을 풀었다.
      판 너비가 늘 같으니 화면 크기로 가를 까닭이 없다 */
.battle-shell{grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(0,1fr);grid-template-areas:"arena"}
.battle-side{padding:5px 8px;border-bottom:1px solid var(--line-soft)}
.battle-side.clock-side{align-items:flex-start;justify-content:center}
.hud-label{display:none}
.battle-side .clock{width:66px;min-height:31px;padding:2px 7px;flex-direction:row;gap:5px}
.clock::before{content:"시간";font-size:7px}
.battle-side .ck-n{font-size:16px}
.battle-arena{border-inline:0}
@media (max-width:360px){
  .tray{gap:5px;padding-inline:6px}
}
.cmdr{flex:none;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:9px;
  padding:6px 12px;background:transparent;border-bottom:0}
/* 이름은 본체에 붙인다 — 상대는 머리 위, 나는 발밑 */
.cm-c{grid-area:1/2;justify-self:center;display:flex;flex-direction:column;align-items:center;gap:3px}
.cmdr.mine{border:0}
.por{width:44px;height:44px;flex:none;border-radius:3px;
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  -webkit-user-select:none;user-select:none;-webkit-touch-callout:none;
  border:2px solid var(--line);position:relative;font-size:17px;font-weight:800;
  transition:box-shadow .16s,transform .1s}
.por:hover{transform:translateY(-1px)}
.pips{grid-area:1/3;justify-self:end}
/* 본체는 위폐(位牌) 그림으로. 그림이 제 테두리를 갖고 있어 네모 테두리와 바탕은 걷는다 */
/* 그림이 정사각 안의 정원이라 겨눔 테도 원형이어야 한다 — 네모 테를 두르면 그림 밖 빈 구석이 같이 빛난다 */
.por.foe,.por.me{border:0;border-radius:50%;background-repeat:no-repeat;background-position:center;
  background-size:contain;width:50px;height:50px}
.por.foe{background-image:url(assets/ui/battle_core_enemy.webp?v=7);color:#f7dcd4;
  text-shadow:0 1px 3px #000,0 0 7px #0009}
.por.me{background-image:url(assets/ui/battle_core_player.webp?v=7);color:#dff3ea;
  text-shadow:0 1px 3px #000,0 0 7px #0009}
.por.hit{animation:shake .3s}
/* 본체가 맞으면 **각연권속처럼 붉게 물든다** (v0.227) — 같은 빛(`.bleed`)을 방패 둘레에 맞춰 둥글게 깐다.
   숫자(명)는 그 위에 남는다 */
.por.hit::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;border-radius:50%;
  background:radial-gradient(closest-side,#ff5242 0%,#c4271b 62%,#7a110900 100%);
  animation:bleedp .34s ease-out forwards}
@keyframes bleedp{0%{opacity:0}18%{opacity:.62}100%{opacity:0}}
.por>span{position:relative;z-index:2}
/* 본체 파괴 (v0.225) — 다섯 장을 겹쳐 두고 한 장씩 켠다 (`coreBreak`) */
.corebreak{position:fixed;z-index:18;pointer-events:none;transform:translate(-50%,-50%)}
.corebreak img{position:absolute;inset:0;width:100%;height:100%;opacity:0}
.corebreak img.on{opacity:1}
.cbflash{position:fixed;inset:0;z-index:18;pointer-events:none;
  background:radial-gradient(circle at var(--x) var(--y),#ffffffb0 0,#ffe7c466 9%,#ffffff00 34%)}
/* 본체가 다 깨진 뒤 남는 작은 파편. 큰 좌우 조각은 만들지 않는다. */
.cbdebris{position:fixed;z-index:19;pointer-events:none;transform:translate(-50%,-50%);overflow:visible}
.cbshard,.cbspark,.cbshock{position:absolute;display:block;pointer-events:none}
/* ⚠ **그 자리에서만 터진다** (2026-10-03) — 화면 전체를 덮던 옛 섬광과 다르다.
   전체를 덮으면 그 위에 설 승패 글이 안 읽힌다 */
/* ⚠⚠ **여섯 할로 옅다** (2026-10-03 기획자가 정함) — 방패가 터지는 그 자리에는 곧
   승패 글이 선다. 진하면 그 글을 태워 먹는다.
   ⚠ **그 값은 여기가 아니라 `ui.js` 의 키프레임에 있다.** 이 둘은 `animate()` 가
      `opacity` 를 **직접 몰기** 때문에, 여기에 `opacity` 를 적어도 동작이 덮어쓴다 —
      적어 두면 고친 줄 알고 넘어가게 된다. `coreDebris` 의 머리말을 본다 */
.cbboom{position:absolute;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,#fff 0%,#ffeec4 22%,#ffb45a66 46%,transparent 72%)}
.cbwave{position:absolute;border-radius:50%;pointer-events:none;
  border:2.5px solid #ffe3ae;box-shadow:0 0 16px #ffc67a99}
.cbshard{clip-path:polygon(12% 0,100% 24%,72% 100%,0 68%);
  box-shadow:0 0 2px #f5dcaa99,0 2px 4px #000c}
.cbshard:nth-child(3n){clip-path:polygon(48% 0,100% 100%,0 72%)}
.cbshard:nth-child(4n){clip-path:polygon(0 15%,86% 0,100% 72%,28% 100%)}
.cbspark{width:3px;height:3px;border-radius:50%;background:var(--spark);
  box-shadow:0 0 5px var(--spark),0 0 9px #fff5}
.cbshock{left:50%;top:50%;width:72%;height:72%;border-radius:50%;
  border:2px solid #ead39a99;box-shadow:0 0 8px #dcc07988,inset 0 0 7px #fff4}
/* ===== 각성한 본체 (v188 — 불을 걷고 후광으로) =====
   각성하면 본체 뒤에 **후광**(`battle_core_awakening_backplate_spin.png`)이 뜨고
   **판이 끝날 때까지 남는다.** v187 까지는 불이 잠깐 붙었다 꺼졌는데,
   각성은 **한 번 일어나면 되돌릴 수 없는 상태**다 — 스쳐 가는 연출로는 그 말이 안 된다.

   ⚠ **수라장 배경 바로 위**에 깔린다. 본체(위패)와 명(明)은 그 위에 얹히고 이름도 위에 선다 —
   그래서 후광을 `.por` 안에 넣지 않는다. 안에 넣으면 위패 그림 위로 올라와 얼굴을 가린다.
   `.porwrap` 이 본체를 감싸고, 후광은 그 안의 **형제**로 앉아 z-index 로 뒤에 깔린다.

   그림은 가운데가 뚫린 고리다. **도는 것을 전제로 그린 것**이라(`_spin`) 위아래가 없다 —
   v188 의 첫 판은 용 뿔이 위를 향해 있어 돌리면 어색했다.
   ⚠ **구멍이 폭의 48%** 다(첫 판은 55%였다). 본체 50px 이 그 구멍 안에 여유 있게 들어앉으려면
   구멍이 64px 쯤이라야 하므로 후광은 64 ÷ 0.48 ≈ **134px** 이다.
   그림을 갈면 이 셈을 다시 한다 — 구멍 지름부터 재고, 거기에 본체를 넣는다 */
/* ⚠ **후광은 가장 아래 칸에 둔다.** `.porwrap` 이 자리를 잡은(positioned) 상자라,
   z-index 를 안 주면 자리 안 잡은 형제들(이름·시계 줄) **위로** 올라가 글씨를 덮는다.
   `z-index:0` 으로 눌러 두고, 그 위에 올라야 할 것들에 `z-index:1` 을 준다 —
   본체·명은 이 상자 안에서, 이름과 시계 줄은 바깥에서 */
.porwrap{position:relative;z-index:0;flex:none;display:flex;align-items:center;justify-content:center}
.porwrap .por{position:relative;z-index:1}
.cm-halo{position:absolute;left:50%;top:50%;z-index:0;pointer-events:none;
  width:var(--halo,clamp(104px,calc(var(--app-w) * .32),134px));aspect-ratio:1;
  transform:translate(-50%,-50%) scale(.4);opacity:0;
  background:url(assets/ui/battle_core_awakening_backplate_spin.png?v=1) center/contain no-repeat;
  transition:opacity .5s ease,transform .5s cubic-bezier(.2,1.2,.35,1)}
/* 피어나는 순간 — 작게 시작해 부풀며 돈다. 그 뒤로는 아주 느리게 계속 돈다 */
.porwrap.awoke .cm-halo{opacity:.92;transform:translate(-50%,-50%) scale(1);
  animation:halospin 26s linear infinite}
@keyframes halospin{
  from{transform:translate(-50%,-50%) rotate(0deg)}
  to  {transform:translate(-50%,-50%) rotate(360deg)}}
@media (prefers-reduced-motion:reduce){ .porwrap.awoke .cm-halo{animation:none} }
.por span{transition:color .2s}
.lowhp{color:var(--danger)!important}
.rolling{display:inline-block;animation:rollp .44s cubic-bezier(.2,1.4,.4,1)}
@keyframes rollp{0%{transform:scale(1)}32%{transform:scale(1.26)}100%{transform:scale(1)}}
.dmgf{position:absolute;left:50%;top:-2px;transform:translate(-50%,0);pointer-events:none;z-index:6;
  font-size:17px;font-weight:800;color:var(--danger);text-shadow:0 2px 7px #000,0 0 14px #c9524a88;white-space:nowrap}
.dmgf.up{color:var(--ok);text-shadow:0 2px 7px #000,0 0 14px #5da16b88}
.dmgf.down{top:auto;bottom:-2px}
@keyframes shake{25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}
/* 이름은 **후광 위에 겹쳐** 선다 (v188) — 후광이 이름 자리까지 뻗으므로 글씨를 위로 올린다 */
/* ⚠ **이름을 자르지 않는다** (v0.282). 가운데 기둥은 방패 너비(50px)로 찌부러지는데,
   예전에는 이름칸을 그 안에 가두어 「무명자」가 **「무…」로 잘렸다.**
   기둥을 넓히면 내공 칸이 찌그러지므로, **이름만 좌우로 넘쳐 나가게** 둔다 —
   방패를 축으로 가운데 정렬이라 양쪽으로 고르게 퍼진다. 이름은 열 자까지라 넘쳐도 자리를 침범하지 않는다 */
.cm-n{position:relative;z-index:1;
  font-family:var(--serif);font-size:12.5px;font-weight:700;white-space:nowrap;
  max-width:none;overflow:visible;text-align:center;
  text-shadow:0 1px 4px #000,0 0 10px #000b}
/* 본체 오른쪽 기둥 — 위에서부터 (상대만)포기 · 각성 딱지 · 내공이다.
   셋 다 `flex:none` 이라 **어느 하나가 비어도 나머지가 밀리지 않는다** (v161) */
.cm-r{grid-area:1/3;justify-self:end;display:flex;flex-direction:column;align-items:flex-end;gap:5px}
.cm-r > *{flex:none}
/* 포기 — 상대 내공 **위**에 선다 (v155). 하단 바에서 올라온 것이다.
   판을 뜨는 단추가 차례 넘김 옆에 있으면 넘기려다 나간다. 여기는 엄지가 쉬는 자리에서 가장 먼 구석이다.
   **눈에 띄면 안 된다** — 흐린 글씨 한 조각으로 두고, 눌러야 비로소 묻는다 */
.givebtn{flex:none;padding:3px 9px;border-radius:9px;border:1px solid var(--line);
  background:#0d0b10a8;font-family:var(--serif);font-size:10.5px;font-weight:700;
  letter-spacing:.1em;text-indent:.1em;color:var(--fg-faint);line-height:1.5;white-space:nowrap}
.givebtn:hover,.givebtn:active{color:var(--danger);border-color:#5c2620}
.givebtn[hidden]{display:none}
/* 남은 시간 — **내 본체 바로 위에 가로로 눕는 한 줄** (v129).
   예전에는 내공 위에 네모 시계로 앉아 있었다. 지금 두는 쪽의 시간이 흐르므로
   상대 차례에도 같은 줄을 본다 — 누구의 시간인지는 색으로 가른다.
   굵을 까닭이 없다. 손패 아래에서 걷어낸 스크롤막대와 같은 두께다 */
/* 시계 줄도 후광 위다 — 내 본체 바로 위라 후광의 윗자락이 여기까지 온다 */
.tbar{position:relative;z-index:1;
  flex:none;display:flex;flex-direction:column;align-items:stretch;gap:2px;
  padding:3px 10px 2px;transition:opacity .2s}
.tb-n{align-self:flex-end;font-family:var(--mono);font-size:11px;font-weight:700;
  font-variant-numeric:tabular-nums;line-height:1;letter-spacing:.04em;
  /* **색 전환을 걸지 않는다.** color 에 transition 을 걸어 두면 값이 var() 에서 올 때
     크로미움이 처음 값을 물고 놓지 않는다 — 게이지는 바뀌는데 숫자만 그대로였다 (v139) */
  color:var(--tc)}
.tb-g{height:3px;border-radius:2px;background:#ffffff14;overflow:hidden}
.tb-g > i{display:block;height:100%;width:100%;border-radius:2px;
  background:linear-gradient(90deg,color-mix(in srgb,var(--tc) 55%,#000),var(--tc));
  transition:width .22s linear,background .25s}
/* 색은 변수 하나로 묶는다 (v139) — 게이지와 숫자가 따로 놀지 않는다.
   내 시간은 초록, 상대 시간은 파랑, 20초부터 노랑, 10초부터 빨강.
   촉박한 색은 누구 차례든 같다 — 급한 것은 급한 것이다 */
.tbar{--tc:#7fdca0}
.tbar.foe{--tc:#8fb6f0}
.tbar.warn,.tbar.foe.warn{--tc:#f0d67e}
.tbar.hot,.tbar.foe.hot{--tc:#e8695f}
.tbar.hot .tb-n{animation:ckp 1s ease-in-out infinite}
.tbar.idle{opacity:.3}
@keyframes ckp{0%,100%{opacity:1}50%{opacity:.45}}
/* 기록 — 내 본체 왼쪽에 최근 넉 줄만 흘린다. 누르면 전체가 열린다 */
.logfeed{grid-area:1/1;justify-self:start;min-width:0;max-width:100%;display:flex;flex-direction:column;
  gap:1px;overflow:hidden;text-align:left;padding:2px 4px;border-radius:var(--r-s);cursor:pointer}
.logfeed:hover{background:#ffffff08}
.lf{font-size:8.5px;line-height:1.5;color:var(--fg-faint);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;max-width:100%}
.lf.me{color:#9ad3b4} .lf.foe{color:#e0a59b} .lf.sys{color:var(--fg-faint)}
.lf:nth-last-child(1){opacity:1} .lf:nth-last-child(2){opacity:.7}
.lf:nth-last-child(3){opacity:.46} .lf:nth-last-child(n+4){opacity:.28}
/* 각성 딱지가 앉는 칸 — **비어 있어도 자리를 잡아 둔다** (v161).
   높이를 안 잡아 두면 각성이 터지고 꺼질 때마다 그 아래 내공 구슬이 위아래로 튄다.
   딱지는 한 판에 한 번뿐이라 각성 전에는 빈 칸이지만, **빈 칸도 같은 자리를 차지해야**
   본체·딱지·내공 셋이 판 내내 한자리에 붙어 있는다.
   ⚠ 딱지 높이(.simg 22px)와 같은 값이다. 글꼴이나 여백을 고치면 이 값도 같이 고친다 */
.cm-s{display:flex;gap:9px;height:22px;flex:none;justify-content:flex-end;align-items:center;
  font-family:var(--mono);font-size:10px;color:var(--fg-mid);font-variant-numeric:tabular-nums}
/* 각성 딱지 — **본체와 내공 사이**다 (v160). 본체에 난 일이니 본체 옆에 선다.
   한 판에 한 번뿐이므로 한 번 서면 **판이 끝날 때까지 남는다** (v169).
   **눌러서 다시 읽는 단추다** — 손가락 기기에는 `title` 이 없다 */
.simg{font-family:var(--serif);font-size:10.5px;padding:2px 7px;border-radius:2px;font-weight:700;
  border:1px solid;white-space:nowrap;animation:awkin .3s cubic-bezier(.2,1.3,.4,1);
  cursor:pointer;-webkit-tap-highlight-color:transparent;transition:filter .14s}
.simg:active{filter:brightness(1.35)}
@media (hover:hover) and (pointer:fine){ .simg:hover{filter:brightness(1.2)} }
@keyframes awkin{0%{opacity:0;transform:scale(.7)}100%{opacity:1;transform:scale(1)}}
.simg.심마{background:#33150f;color:var(--simma);border-color:#5c2620}
.simg.명경지수{background:#131f33;color:var(--myeong);border-color:#22375c}
.simg.축기{background:#0f2a22;color:var(--chukgi);border-color:#1e4d3e}
.simg.무아지경{background:#2a2333;color:#c3a9e8;border-color:#463a5c}
.simg.결의{background:#2e2410;color:var(--chungi);border-color:#5c4a1e}
.pips{display:flex;gap:3px;align-items:center;flex:none}
.pip{width:9px;height:9px;border-radius:50%;background:var(--line)}
.pip.x{background:#ffffff0d;box-shadow:inset 0 0 0 1px #ffffff12}
/* 찬 것 = 지금 쓸 수 있는 내공 — 초록. 얹힌 것 = 이번 차례만 더 쓰는 내공 — 노랑 */
.pip.f{background:linear-gradient(145deg,#8fe0a8,#2f7f4e);box-shadow:0 0 5px #2f7f4e99}
.pip.b{background:linear-gradient(145deg,#eccb7a,#b8892f);box-shadow:0 0 5px #b8892f99}
/* **상대의 내공은 붉다** (v0.225) — 내 것(초록)과 한눈에 갈려야 누구 구슬인지 안 헷갈린다 */
#foePips .pip.f{background:linear-gradient(145deg,#f09a8f,#9e3b33);box-shadow:0 0 5px #9e3b3399}
/* 내공은 한꺼번에 딸깍 켜지지 않는다 — 한 알씩 차례로 부풀어 오른다 */
@keyframes pipin{0%{transform:scale(0);opacity:0}
  58%{transform:scale(1.55);opacity:1}
  100%{transform:scale(1);opacity:1}}
.pip.new{animation:pipin .34s cubic-bezier(.3,1.5,.5,1) backwards}
/* 패에서 고른 카드가 실제로 쓸 내공만 숨을 쉬듯 흐려진다. 카드를 놓기 전의 예고이며 값은 아직 빠지지 않는다. */
@keyframes pipspend{0%,100%{opacity:1;transform:scale(1);filter:brightness(1)}
  50%{opacity:.28;transform:scale(.72);filter:brightness(.72) saturate(.55)}}
#myPips .pip.spend{animation:pipspend .68s ease-in-out infinite;outline:1px solid #ead99a66;outline-offset:1px}

/* `overflow-y` 만 정하면 가로축은 `visible` 이 `auto` 로 바뀐다 —
   카드 그림이 들어오는 동안 가로 스크롤막대가 떴고, 그게 시계 게이지 바로 위라
   게이지가 둘로 보였다. 가로는 아예 잠그고 세로 막대도 숨긴다 (v148) */
/* ⚠⚠ **`safe center` 다 — 그냥 `center` 로 되돌리지 마라** (2026-10-14 기획자 제보).
   `justify-content:center` 는 속이 넘칠 때 **위아래로 똑같이 흘려 보낸다.** 그런데 위로 흘러간
   것은 **스크롤로 닿지 않는다**(`scrollTop` 의 아래끝이 0 이라 음수로 못 간다) — 그래서
   판이 낮으면 **상대 수라장이 위로 잘려 나간 채 영영 안 보였다.** 재어 둔다 (연 다섯씩):
     판 560 — 넘침 1px, 멀쩡하다 ·  판 520 — 상대 줄이 판 위 **42px 바깥**, `scrollTop` 은 0
     판 480 — 상대 줄이 판 위 **88px 바깥**, 역시 0
   `safe` 를 붙이면 **넘치는 순간에만 `flex-start` 로 물러선다** — 안 넘칠 때는 전과 똑같이
   가운데다. 넘치면 위부터 보이고 내 줄은 굴려서 본다. 잘리는 쪽이 **상대**가 되면 안 된다. */
.board{flex:1;min-height:0;position:relative;display:flex;flex-direction:column;justify-content:safe center;gap:5px;padding:6px 8px;overflow-y:auto;overflow-x:hidden;scrollbar-width:none;
  /* 아무것도 깔지 않는다. 여기에 그늘이나 테를 두면 바탕 그림 한가운데에 네모난 상자가 떠올라
     스크롤 칸처럼 보인다. 화면 전체의 그늘은 .battle-arena 가 한 번에 맡는다 */
  background:transparent}
.board::-webkit-scrollbar{display:none}
.frow{display:flex;gap:4px;justify-content:center;min-height:72px;align-items:center;position:relative;z-index:1}
.board .rule{display:none}   /* 가운데 가름선 — 흙바닥을 반으로 잘라 놓아 걷었다 */
/* 연이 설 자리는 늘 옅은 테로 그어 둔다 — 수라장이 몇 칸인지 보이지 않으면 어디에 놓을지 가늠이 안 된다 */
.slot{flex:1;max-width:62px;aspect-ratio:63/88;border-radius:2px;background:transparent;
  border:1px solid #d8c9a81f;box-shadow:inset 0 0 12px #0000003d}
/* 놓을 수 있는 빈 칸 — 판 위에서 **곁눈에도 걸리게** 짙게 깜빡인다 */
.slot.open{opacity:1;border:1.5px dashed var(--ok);background:#6fcf972e;
  box-shadow:inset 0 0 12px #6fcf9733,0 0 6px #6fcf9740;animation:sp 1.1s ease-in-out infinite}
.slot.open::after{content:"＋";display:flex;align-items:center;justify-content:center;height:100%;color:var(--ok);font-size:19px;opacity:.95}
@keyframes sp{50%{background:#6fcf9759;border-color:#b6f5cf;box-shadow:inset 0 0 18px #6fcf9766,0 0 14px #6fcf9780}}
/* 수라장의 연 — 손패 카드를 그대로 옮긴다. 테두리·효과만 겉에 두른다 */
.unit{flex:1;max-width:62px;position:relative;cursor:pointer;transition:transform .12s;border-radius:3px}
/* ⚠⚠ **`body` 로 나간 연출 카드는 상한도 배율을 따른다** (2026-10-14).
   `ui.js` 가 연출 카드를 `document.body` 에 `position:fixed` 로 붙이는데, 거기도 `.unit` 이라
   **위의 `max-width:62px` 이 그대로 걸린다.** 그래서 `width:86px` 이라 적어 둔 자리도 실제로는
   62px 으로 잘려 왔다 — 폰에서도 그랬으므로 **그 62px 이 곧 모바일의 본디 모습**이다.
   판 바깥이라 `zoom` 을 못 받으니 상한에 `--fxk` 를 곱해 **판이 커진 만큼 같이 커지게** 한다.
   ⚠ 폰은 `--fxk` 가 1 이라 62px 그대로 — 한 화소도 안 바뀐다.
   ⚠ 소환 카드는 뺀다. `.summon-ghost.unit` 이 상한을 **일부러 풀어 둔** 자리라(크게 보여 주는
     연출이다) 여기서 다시 씌우면 그 뜻이 죽는다.
   ⚠⚠ **`"position:fixed"` 로 찾으면 안 걸린다.** `cssText` 로 넣어도 브라우저가 `style` 속성을
     다시 적으면서 **`position: fixed` 처럼 빈칸을 끼워 넣는다** — 그래서 `fixed` 한 낱말로 찾는다.
     2026-10-14 에 빈칸 없는 꼴로 적었다가 한 자리도 안 걸려 상한이 그대로 62px 이었다. */
.unit[style*="fixed"]:not(.summon-ghost){max-width:calc(62px * var(--fxk))}
.unit .card{transition:box-shadow .18s}
/* 각연자는 어느 화면에서 작게 보든 금빛이 돈다 — 한 벌에 한 장뿐인 카드는 한눈에 갈려야 한다 */
.card.eng{box-shadow:0 0 0 1.5px #e8cf8fb0,0 0 9px 1px #d4a84366,inset 0 0 12px #d4a8431a;
  animation:engb 2.4s ease-in-out infinite}
@keyframes engb{50%{box-shadow:0 0 0 2px #f4e4b4,0 0 15px 3px #d4a84399,inset 0 0 16px #d4a8432e}}
/* ⚠ **목록에서는 여섯이 한꺼번에 깜빡이면 안 된다** (v213).
   v212 에 연보·명운 엮기의 기본 나열을 **고코스트 순**으로 바꿨더니,
   코스트 5인 **각연자 여섯 장이 목록 맨 앞에 나란히** 서게 됐다.
   여섯이 같은 순간에 애니메이션을 시작하므로 **2.4초마다 한 덩어리로 번쩍인다** —
   카드 하나가 빛나는 것이 아니라 **화면 윗부분이 깜빡이는 것**으로 보인다.

   카드 하나의 빛은 그대로 두고(한 벌에 한 장뿐인 카드는 크게 빛나야 한다),
   **시작점만 흩어** 서로 어긋나게 돈다. 감싸개(`.gcard`)의 차례로 여섯 갈래를 준다 —
   카드 자신은 늘 감싸개의 첫째 자식이라 `.card:nth-child()` 로는 갈리지 않는다.
   ⚠ 늦춤이 **음수**다. 0 에서 시작해 기다리는 것이 아니라 **이미 돌고 있던 것처럼** 시작한다 */
.gcard:nth-child(6n+1) .card.eng{animation-delay:0s}
.gcard:nth-child(6n+2) .card.eng{animation-delay:-.41s}
.gcard:nth-child(6n+3) .card.eng{animation-delay:-1.53s}
.gcard:nth-child(6n+4) .card.eng{animation-delay:-.92s}
.gcard:nth-child(6n+5) .card.eng{animation-delay:-2.07s}
.gcard:nth-child(6n+6) .card.eng{animation-delay:-1.24s}
/* ⚠ **수라장에서는 금테를 얇게 쓴다** (v180). 칸 사이가 4px 뿐이라(`.frow{gap:4px}`)
   테가 2px + 흐림 3px 로 뻗으면 **옆 각연권속 자리를 침범한다** — 누구의 빛인지 안 갈린다.
   여기서만 하드 테를 1px 로 줄이고 흐림도 반으로 죈다. 연보·결연처럼 자리가 넉넉한 화면은
   위 값을 그대로 쓴다 — **한 벌에 한 장뿐인 카드는 크게 보이는 자리에서 크게 빛나야 한다** */
.unit .card.eng{box-shadow:0 0 0 1px #e8cf8fc4,0 0 6px 0 #d4a8435c,inset 0 0 10px #d4a8431a;
  animation:engbu 2.4s ease-in-out infinite}
@keyframes engbu{50%{box-shadow:0 0 0 1.4px #f4e4b4,0 0 10px 1px #d4a84388,inset 0 0 13px #d4a8432e}}
/* 고르는 중이거나 겨눠진 연은 제 색이 우선이다 — 금빛이 그 위를 덮으면 무엇을 고른 건지 안 보인다.
   ⚠ **각연자도 겨눠지면 깜빡여야 한다** (v155). 여기서 `animation:none` 하나로 덮어 두었더니
   `.unit.tgt .card` 보다 이쪽이 더 촘촘해(0,3,1) 이겨서, 각연자만 붉게 굳은 채 서 있었다.
   금빛(engb)만 끄고 겨눔의 맥(plr·plg)은 그대로 돌려준다 */
.unit.sel .card.eng,.unit.ready .card.eng{animation:none}
.unit.tgt .card.eng{animation:plr .62s ease-in-out infinite}
.unit.tgt.good .card.eng{animation:plg .62s ease-in-out infinite}
/* ⚠⚠ **겨눌 수 있는 연에 적는 말** (2026-10-03 기획자가 정함) — 테두리는 「여기다」까지만
   말한다. 무엇을 하라는 것인지는 글이 말해야 한다.
   ⚠ **카드 한가운데**다(`inset:0` + `flex`). `left:50%`+`transform` 은 폭을 화면 절반으로
      잡아 글자가 접힌다 — §11 이 못 박은 그 함정이다.
   ⚠ 붉은 것이 기본이고 **이로운 것만 초록**이다. 효과는 해로운 쪽이 더 흔하다 */
.tgtlab{position:absolute;inset:0;z-index:5;display:flex;align-items:center;justify-content:center;
  pointer-events:none;
  font-family:var(--serif);font-size:clamp(9px,round(calc(var(--app-w) * .027), 1px),11.5px);font-weight:800;letter-spacing:.02em;
  word-break:keep-all;text-align:center;color:#fff}
.tgtlab::before{content:"";position:absolute;left:8%;right:8%;top:38%;bottom:38%;border-radius:3px;
  background:#2a0d0ddd;border:1.5px solid #e2574e;
  box-shadow:0 0 10px #e2574e77,inset 0 0 8px #e2574e33}
.tgtlab.good::before{background:#07241add;border-color:#4fd08a;
  box-shadow:0 0 10px #4fd08a77,inset 0 0 8px #4fd08a33}
/* ═══ ⚠⚠ **머무는 나쁜 것은 「당함」과 「풀림」 한 짝으로 말한다** (2026-10-03 기획자가 정함) ═══
   한쪽만 글이 서면 **짝이 안 맞아** 무엇이 일어난 것인지 읽는 결이 갈린다.
   그래서 **같은 상자, 같은 글꼴**이고 **빛깔만** 갈린다 — 걸리면 붉은빛, 풀리면 맑은 빛.
   ⚠ 글귀는 `ui.js` 의 `머묾이름` 한 표가 짓는다. 새 상태가 생기거든 거기 한 줄만 더하면
      이 두 꼴이 그대로 따라온다 — 여기 빛깔을 더 늘릴 일이 없다 */
.fxpop.free,.fxpop.bind{border-radius:3px;padding:2px 7px;border:1.5px solid}
.fxpop.free{color:#eafff3;background:#07241ae0;border-color:#5fd8a0;
  box-shadow:0 0 10px #4fd08a66}
.fxpop.bind{color:#ffe6e2;background:#2a0d0de0;border-color:#e2574e;
  box-shadow:0 0 10px #e2574e66}
.tgtlab{animation:tgtlab 1.2s ease-in-out infinite}
@keyframes tgtlab{0%,100%{opacity:.86}50%{opacity:1}}
@media (prefers-reduced-motion:reduce){ .tgtlab{animation:none} }
/* 이번 차례에 칠 수 있는 연·각연자는 한눈에 보여야 한다 — 눌러 봐야 아는 것은 화면이 일을 안 한 것이다.
   고르는 중인 대상(맥박이 뛴다)과 달리 이쪽은 가만히 있는 테두리라 헷갈리지 않는다 */
/* ===== 금강 =====
   그림을 걷었다. **카드 안쪽 가장자리에 흰 테와 흰 빛**이 서고, 가운데로 올수록 스러져
   카드 그림은 그대로 보인다. 칸 밖으로는 한 픽셀도 나가지 않는다(옆 칸이 4px 뿐이다) */
/* ⚠ **그늘 층(`.c-veil`) 위에 깐다** (v0.225) — 코스트·이름·딱지·공력·기력 같은 UI 밑이되, 그늘보다는 위다.
   예전에는 그림 층(`.c-art`) 안에 깔아 **그늘이 흰 빛을 덮었다** — 그늘은 카드 아래 4할을 거의 까맣게 칠하므로
   흰 테의 아래 절반이 통째로 죽어 「금강이 눈에 안 들어온다」는 말이 나왔다 */
/* ⚠⚠ **흰 점멸은 걷었다** (2026-10-02 기획자가 정함) — 그 자리를 금강 연출이 대신한다.
   둘을 같이 두면 흰 테가 연출을 덮어 무엇이 걸렸는지 안 읽힌다.
   되돌릴 거면 아래 `display:none` 한 줄만 지우면 된다 */
.unit.gang .c-veil::after{display:none;content:"";position:absolute;inset:0;pointer-events:none;
  /* v0.225 — 흰 기운이 안쪽으로 **한 뼘 더** 번지고(7→10px · 14→20px, 투명 시작 66→58%),
     빛은 **아주 조금** 짙어졌다. 판 위에서 곁눈에 안 걸린다는 말이 있었다 */
  box-shadow:inset 0 0 0 1.5px #ffffffd6,inset 0 0 10px 2px #ffffffa6,inset 0 0 20px 5px #dff3ff42;
  background:radial-gradient(ellipse 75% 68% at 50% 50%,transparent 58%,#ffffff17 80%,#ffffff33 100%);
  animation:gangb 2.1s ease-in-out infinite}
@keyframes gangb{50%{box-shadow:inset 0 0 0 1.5px #fffffff0,inset 0 0 13px 3px #ffffffc4,inset 0 0 26px 7px #dff3ff59}}
/* ═══ 전투 연출 — 스프라이트 시트를 steps() 로 흘린다 (2026-10-02) ═══════
   기획자가 512px 낱장으로 준 것을 `docs/_표식굽기.py` 가 **가로로 이어 붙인 한 장**으로 굽는다.
   낱장 그대로면 한 연출에 요청이 열두 번이고 `hit_fire` 하나가 2.5MB 다 —
   전투 중 첫 재생에서 눈에 띄게 끊긴다. 시트는 요청 1번 · 용량 1/9 이다.

   ⚠⚠ **%로 밀면 칸이 어긋나 미끄러진다** (2026-10-02 에 제보받아 잡았다).
      `steps(n)` 은 0~100% 를 **n 등분**해 0, 1/n, … (n−1)/n 을 내놓는데,
      `background-position` 의 칸 경계는 **(n−1) 등분** 자리(0, 1/(n−1), …)다.
      그래서 칸마다 조금씩 밀려 **그림이 옆으로 흐르는 것처럼 보인다** —
      세로로 긴 그림(내공 상승)에서 특히 또렷했다.
      **px 로 민다.** 한 칸이 정확히 `--w` 만큼이라 어긋날 길이 없다 —
      `fxPlay` 가 요소 크기를 `--w` 로 넣어 준다.
   ⚠ **`pointer-events:none`** — 연출이 카드 위에 서므로 안 끄면 카드를 못 누른다.
   ⚠ 움직임을 줄인 사람에게는 아예 안 띄운다 (`fxPlay` 가 `RED` 를 먼저 본다) */
.fxplay{position:fixed;z-index:16;pointer-events:none;
  transform:translate(-50%,-50%);
  background-repeat:no-repeat;
  background-size:calc(var(--n) * var(--w)) var(--w);
  animation:fxrun var(--ms) steps(var(--n)) 1 forwards}
@keyframes fxrun{ from{background-position-x:0} to{background-position-x:calc(var(--n) * var(--w) * -1)} }
/* 금강은 **머무는 연출**이다 — 켜져 있는 동안 되풀이한다 */
.fxplay.loop{animation:fxrun var(--ms) steps(var(--n)) infinite}
/* ⚠ **방패 뒤에 서는 연출**(내공 상승)은 `.porwrap` 안에 들어간다 — 후광(`.cm-halo`)과 같은 법이다.
   `position:fixed` 로 몸에 붙이면 **반드시 방패 앞**에 선다(쌓임 순서를 비집고 들어갈 수가 없다).
   ⚠ `.porwrap` 이 `z-index:0` 으로 쌓임 바탕을 열어 두었고 방패가 그 안의 1 이다 */
.fxplay.behind{position:absolute;left:50%;top:50%;z-index:0}

/* ═══ 손으로 그린 연출 (2026-10-03) ═══════════════════════════════════
   ⚠⚠ **시트가 아니라 꼴로 그린다.** 낱장 원화를 구운 시트는 「무엇이 일어났나」는 말해 주는데
      **센 맛**이 없었다(기획자: 「공력 상승이 없어 보인다 · 극독에 타격감이 전혀 없다」).
      시트는 칸 수만큼만 움직이고 크기도 못 바꾼다 — 꼴로 그리면 **카드 크기에 맞춰 늘고**
      빛무리와 흐림이 겹겹이 돈다.
   ⚠ 빛깔은 **원화에서 그대로 가져왔다** — 상승은 연한 민트, 극독은 자주 핵에 황록 덩굴이다.
      그림을 새로 그리거든 여기 `--c1~--c3` 세 줄만 갈아 끼운다.
   ⚠ **자리와 크기는 `fxPlay` 가 준다**(카드 네모 그대로). 여기서 px 을 적지 않는다 —
      적으면 화면 폭이 바뀔 때 어긋난다. 안쪽 길이는 모두 %다.
   ⚠ `--ms` 는 그 갈래의 참이다. 낱낱의 박자는 그 안에서 비로 잡는다 */
/* ═══ ⚠⚠ 쌓임의 띠 — **이 표를 지킨다** (2026-10-03 전수조사) ═══════════════════
   2026-10-03 에 **전투 연출이 모든 창을 뚫고 올라오는** 것이 드러났다 — 승리 화면 위로
   호법 보호막이 떠 있었다. 호법만의 탈이 아니라 **연출 띠가 통째로 창 띠보다 위**였다
   (연출 56~63 · 창 20~30). 띠를 다시 나눈다.

     1~14    판 위의 것 — 카드·칸·기록·수라장 글 · **치는 연14 · 맞는 연13**
     **15~19 전투 연출** — 파동15 · 시트와 꼴16 · 검선과 불꽃17 · 끌기와 숫자18 ·
                            파편19 · **날아가는 패19**
     20~30   창과 결과 — 장막20 · 무르기25 · 카드상세28 · 승패30
     40~45   말풍선 — 토스트40 · 길잡이45
     70~96   알림과 가르침 — 차례알림70 · 튜토리얼95·96

   ⚠⚠ **이 표는 `style.css` 만의 것이 아니다.** `ui.js` 가 `style.cssText` 로 **몸에 직접
      박는** 쌓임도 같은 표를 지킨다 — 날아가는 패(소환·초식·버림·뽑기·장비·스러짐·지침·유언)와
      치고 맞는 연이 그렇다. 2026-10-03 에 CSS 띠만 손보고 **박힌 값 열한 자리를 빼먹어**
      날아가는 패가 56~58 에 남아 창과 말풍선을 통째로 뚫고 있었다.
      → `fx-check` 의 「몸에 박은 쌓임이 띠를 넘지 않는다」가 이것을 지킨다.

   ⚠⚠ **연출은 창보다 아래다.** 창이 떴다는 것은 **판에서 손을 뗀다**는 뜻이라,
      그 위로 수라장의 일이 비치면 안 된다.
   ⚠ 새 연출을 더하거든 **15~19 안에서** 고른다. 20 을 넘기면 창을 뚫는다.
   ⚠ 끌기 유령(`dragghost`)과 숫자(`fxpopw`)는 **연출보다 위**(18)다 — 손이 쥔 것과
      읽어야 하는 수는 그림에 가리면 안 된다.
   ═══════════════════════════════════════════════════════════════════════ */
.fxcss{position:fixed;z-index:16;pointer-events:none;transform:translate(-50%,-50%);overflow:visible}
.fxcss i,.fxcss b{position:absolute;display:block}

/* ── 공력·기력 오르내림 ──────────────────────────────────────
   밑동에서 기운이 피어 **솟아오르고**(상승) 혹은 **가라앉는다**(감소).
   줄기 여섯이 저마다 다른 때에 올라 흔들리고, 그 사이로 입자가 튄다 */
.fx-statup{--c1:#e8fbf0;--c2:#8fe0b0;--c3:#4fd08a;--dir:-1}
.fx-statdn{--c1:#efe6f5;--c2:#a893bd;--c3:#6b5f7d;--dir:1}
.fxcss .glow{left:50%;width:92%;height:38%;transform:translateX(-50%);
  background:radial-gradient(60% 80% at 50% 100%,var(--c2) 0%,color-mix(in srgb,var(--c3) 55%,transparent) 44%,transparent 74%);
  filter:blur(2px);opacity:0;animation:fxglow var(--ms) ease-out forwards}
.fx-statup .glow{bottom:-12%}   /* 더 아래에서 피어오른다 (2026-10-03) */
.fx-statdn .glow{top:-4%;transform:translateX(-50%) scaleY(-1)}
@keyframes fxglow{0%{opacity:0}16%{opacity:.95}100%{opacity:0}}
.fxcss .wisp{left:calc(50% + var(--x));width:var(--w);height:78%;margin-left:calc(var(--w) / -2);
  background:linear-gradient(to top,transparent 2%,var(--c3) 16%,var(--c2) 42%,var(--c1) 66%,transparent 100%);
  border-radius:48% 52% 44% 56%/62% 58% 42% 38%;
  filter:blur(1.6px);opacity:0;
  animation:fxwisp var(--ms) cubic-bezier(.26,.66,.36,1) var(--d) forwards}
.fx-statup .wisp{bottom:-7%}    /* 카드 밑동보다 조금 아래에서 올라온다 */
/* ⚠ 가라앉는 쪽은 **빛깔 띠를 뒤집는다.** `transform:scaleY(-1)` 로 뒤집으면
   아래 `@keyframes fxwisp` 의 `transform` 이 그것을 덮어써 아무 일도 안 일어난다 —
   움직임을 쥔 쪽이 이기므로, 모양은 **움직임이 안 건드리는 자리**에서 뒤집는다 */
.fx-statdn .wisp{top:0;
  background:linear-gradient(to bottom,transparent 2%,var(--c3) 16%,var(--c2) 42%,var(--c1) 66%,transparent 100%)}
@keyframes fxwisp{
  0%  {opacity:0;   transform:translateY(calc(var(--dir) * -4%))  scaleY(.3)  scaleX(.7)  skewX(0deg)}
  20% {opacity:.98}
  58% {              transform:translateY(calc(var(--dir) * 36%)) scaleY(1)   scaleX(1.06) skewX(5deg)}
  100%{opacity:0;   transform:translateY(calc(var(--dir) * 86%)) scaleY(1.18) scaleX(.62) skewX(-6deg)}}
.fxcss .mote{left:calc(50% + var(--x));width:var(--s);height:var(--s);border-radius:50%;
  background:radial-gradient(circle,#fff 0%,var(--c1) 40%,transparent 72%);
  opacity:0;animation:fxmote var(--ms) ease-out var(--d) forwards}
.fx-statup .mote{bottom:1%}
.fx-statdn .mote{top:8%}
@keyframes fxmote{
  0%  {opacity:0;transform:translate(0,0) scale(.5)}
  22% {opacity:1}
  100%{opacity:0;transform:translate(var(--sx),var(--fy)) scale(.25)}}

/* ── 극독 피격 ──────────────────────────────────────────────
   ⚠⚠ **앞머리가 세야 타격감이 난다.** 터지는 것은 처음 1/5 안에 다 일어나고
      나머지는 **스러지는 시간**이다. 고르게 퍼지면 「맞았다」가 아니라 「켜졌다」로 읽힌다 */
.fx-venom{--c1:#f2e9f7;--c2:#a21caf;--c3:#5d1160;--c4:#c3d98a}
/* ⚠⚠ **%여백으로 가운데를 맞추지 마라** (2026-10-03 제보 — 「극독이 세로 정중앙이 아니다」).
   `margin-top:-38%` 는 **세로인데도 가로를 기준**으로 셈한다(CSS 규칙이다). 카드는 세로로 길어
   가로와 세로가 다르니, 그렇게 맞추면 **아래로 밀린다.**
   그래서 여백을 안 쓰고 **네 변을 직접 적어** 가운데를 잡는다 — 폭 30%면 왼쪽·위가 35%다 */
.fxcss .vring{left:35%;top:35%;width:30%;height:30%;border-radius:50%;
  border:2px solid var(--c1);opacity:0;
  animation:fxvring calc(var(--ms) * .46) cubic-bezier(.12,.8,.3,1) forwards}
@keyframes fxvring{0%{opacity:.95;transform:scale(.3)}100%{opacity:0;transform:scale(3.1)}}
.fxcss .vcore{left:12%;top:12%;width:76%;height:76%;border-radius:50%;
  background:radial-gradient(circle,#fff 0%,var(--c2) 22%,var(--c3) 48%,transparent 72%);
  filter:blur(1.4px);opacity:0;
  animation:fxvcore var(--ms) cubic-bezier(.1,.9,.3,1) forwards}
@keyframes fxvcore{
  0%{opacity:0;transform:scale(.2)} 8%{opacity:1;transform:scale(1.14)}
  22%{transform:scale(.92)} 100%{opacity:0;transform:scale(1.05)}}
/* 덩굴 — 핵에서 세 갈래로 뻗어 나가며 끝이 말린다 */
.fxcss .varm{left:45%;top:4%;width:10%;height:46%;transform-origin:50% 100%;
  background:linear-gradient(to top,transparent 0%,var(--c3) 12%,var(--c4) 46%,transparent 94%);
  border-radius:50% 50% 40% 40%/70% 70% 30% 30%;
  filter:blur(1.2px);opacity:0;
  animation:fxvarm calc(var(--ms) * .8) cubic-bezier(.1,.75,.3,1) var(--d) forwards}
@keyframes fxvarm{
  0%  {opacity:0;  transform:rotate(var(--a)) translateY(28%) scale(.22)}
  12% {opacity:.98}
  55% {             transform:rotate(calc(var(--a) + 9deg)) translateY(-16%) scale(1)}
  100%{opacity:0;  transform:rotate(calc(var(--a) + 16deg)) translateY(-30%) scale(1.12)}}
.fxcss .vdrop{left:50%;top:50%;width:var(--s);height:var(--s);border-radius:50%;
  margin-left:calc(var(--s) / -2);margin-top:calc(var(--s) / -2);   /* px 이라 가로세로 탈이 없다 */
  background:radial-gradient(circle,var(--c1) 0%,var(--c2) 48%,transparent 74%);
  opacity:0;animation:fxvdrop calc(var(--ms) * .72) cubic-bezier(.1,.8,.4,1) var(--d) forwards}
@keyframes fxvdrop{
  0%  {opacity:0;transform:translate(0,0) scale(.4)}
  10% {opacity:1}
  100%{opacity:0;transform:translate(var(--sx),var(--sy)) scale(.2)}}

/* ── 본체 방패 — 내공 상승 · 명 회복 ────────────────────────
   ⚠ 방패는 **둥글다.** 카드처럼 밑동에서 솟는 꼴이 아니라 **테두리를 감아 도는** 꼴이다.
      고리 둘이 밖으로 번지고, 그 위로 알갱이가 떠오른다 — 원화의 화환이 그 뜻이었다 */
.fx-ki{--c1:#fff6dd;--c2:#f0c868;--c3:#c98f2a}
.fx-healCore{--c1:#eafff3;--c2:#7fe0b8;--c3:#2fae7a}
.fxcss .ring{left:50%;top:50%;width:100%;height:100%;margin-left:-50%;margin-top:-50%;
  border-radius:50%;border:2px solid var(--c2);opacity:0;
  box-shadow:0 0 10px var(--c3),inset 0 0 10px color-mix(in srgb,var(--c2) 60%,transparent);
  animation:fxring calc(var(--ms) * .8) cubic-bezier(.2,.7,.3,1) var(--d) forwards}
@keyframes fxring{0%{opacity:0;transform:scale(.62)}22%{opacity:.95}100%{opacity:0;transform:scale(1.42)}}
.fxcss .halo{left:-12%;top:-12%;width:124%;height:124%;border-radius:50%;opacity:0;
  background:radial-gradient(circle,transparent 42%,color-mix(in srgb,var(--c2) 55%,transparent) 58%,transparent 76%);
  filter:blur(2px);animation:fxhalo var(--ms) ease-out forwards}
@keyframes fxhalo{0%{opacity:0;transform:scale(.8)}24%{opacity:1}100%{opacity:0;transform:scale(1.2)}}

/* ── 효과·초식 피해 (불) ────────────────────────────────────
   ⚠ 극독과 **같은 뼈대**다 — 터지고, 핵이 솟았다 줄고, 혀가 뻗고, 불똥이 난다.
      다른 것은 빛깔과 **혀가 위로 쏠린다**는 것뿐이다. 불은 올라가는 것이다 */
/* ⚠ **일곱 할로 옅다** (2026-10-03 기획자가 정함). 불은 밝은 빛깔 셋이 겹쳐 타오르는 꼴이라
   한 할도 안 내리면 **카드 그림과 숫자를 태워 먹는다** — 무엇이 맞았는지가 안 읽힌다.
   ⚠ 틀에 걸어 둔다. 안쪽 낱낱에 거는 것이 아니라 **한 벌 전체**가 옅어야 겹친 데가 균일하다 */
.fx-fire{--c1:#fff3d6;--c2:#ff9b3d;--c3:#e03b14;--c4:#7a1a06;opacity:.7}
.fxcss .fring{left:35%;top:35%;width:30%;height:30%;border-radius:50%;
  border:2px solid var(--c1);opacity:0;
  animation:fxvring calc(var(--ms) * .42) cubic-bezier(.12,.8,.3,1) forwards}
.fxcss .fcore{left:14%;top:14%;width:72%;height:72%;border-radius:50%;
  background:radial-gradient(circle,#fff 0%,var(--c1) 14%,var(--c2) 36%,var(--c3) 58%,transparent 76%);
  filter:blur(1.3px);opacity:0;
  animation:fxvcore var(--ms) cubic-bezier(.1,.9,.3,1) forwards}
.fxcss .ftongue{left:44%;top:2%;width:12%;height:48%;transform-origin:50% 100%;
  background:linear-gradient(to top,transparent 0%,var(--c4) 10%,var(--c3) 34%,var(--c2) 62%,var(--c1) 84%,transparent 100%);
  border-radius:50% 50% 36% 36%/72% 72% 28% 28%;
  filter:blur(1px);opacity:0;
  animation:fxftongue calc(var(--ms) * .78) cubic-bezier(.12,.76,.3,1) var(--d) forwards}
@keyframes fxftongue{
  0%  {opacity:0;  transform:rotate(var(--a)) translateY(30%) scale(.2)}
  14% {opacity:1}
  56% {             transform:rotate(calc(var(--a) * .74)) translateY(-14%) scale(1)}
  100%{opacity:0;  transform:rotate(calc(var(--a) * .5))  translateY(-34%) scale(1.14)}}
.fxcss .ember{left:50%;top:50%;width:var(--s);height:var(--s);border-radius:50%;
  margin-left:calc(var(--s) / -2);margin-top:calc(var(--s) / -2);
  background:radial-gradient(circle,#fff 0%,var(--c2) 46%,transparent 74%);
  opacity:0;animation:fxvdrop calc(var(--ms) * .76) cubic-bezier(.1,.8,.4,1) var(--d) forwards}

/* ── 점혈 ───────────────────────────────────────────────────
   ⚠ 원화는 **몸의 혈 자리에 붉은 점이 찍히고 흰 테가 번지는** 그림이다.
      그 뜻만 가져온다 — 점 다섯이 차례로 찍히고 저마다 흰 고리가 퍼진다 */
/* ⚠ **채도를 낮춘다** (2026-10-03 기획자가 정함) — 새빨가면 어두운 판에서 혼자 튄다.
   혈 자리라는 뜻은 남기되 **묵은 주사(朱砂)빛**으로 가라앉힌다 */
.fx-seal{--c1:#f3e6e4;--c2:#a85a52;--c3:#6e332e}
.fxcss .pt{width:var(--s);height:var(--s);border-radius:50%;
  left:calc(var(--px) - var(--s) / 2);top:calc(var(--py) - var(--s) / 2);
  background:radial-gradient(circle,#fff 0%,var(--c2) 38%,var(--c3) 70%,transparent 86%);
  opacity:0;animation:fxpt var(--ms) ease-out var(--d) forwards}
@keyframes fxpt{0%{opacity:0;transform:scale(.2)}16%{opacity:1;transform:scale(1.25)}
  34%{transform:scale(1)}100%{opacity:0;transform:scale(.9)}}
.fxcss .ptring{width:var(--r);height:var(--r);border-radius:50%;
  left:calc(var(--px) - var(--r) / 2);top:calc(var(--py) - var(--r) / 2);
  border:1.5px solid var(--c1);opacity:0;
  animation:fxptring calc(var(--ms) * .55) cubic-bezier(.15,.8,.3,1) var(--d) forwards}
@keyframes fxptring{0%{opacity:.9;transform:scale(.25)}100%{opacity:0;transform:scale(1.5)}}

/* ── 호법 — 옛 「내려찍히는 방패」 꼴은 **통째로 걷었다** (2026-10-03) ──
   ⚠ `.ward`·`.wave`·`.crack`·`.puff` 와 옛 빛깔 네 줄(`--c4` 포함)이 여기 남아 있었다.
      호법이 **붉은 외침**으로 바뀐 뒤로 **아무도 안 세우는 꼴**이었다.
      안 쓰는 꼴을 남겨 두면 빛깔 변수가 뒤 규칙으로 새어 들고(`--c4` 가 그랬다),
      다음 사람이 「이게 아직 도는가」를 눈으로 확인해야 한다.
   ⚠ 그 외침도 2026-10-04 에 걷었다 — 호법은 **시트로 간다**(`FX.hobeop`). 아래 자리에 적어 두었다 */
/* ── 주화입마 — 방패 위 흑적 균열 ───────────────────────────
   ⚠ 제 수에 제 명을 치르는 자리다. **밖에서 맞은 것이 아니라 안에서 갈라지는** 꼴이라
      터져 퍼지지 않고 **금이 가며 붉은 기운이 새어 나온다** */
.fx-juhwaipma{--c1:#ffd9d9;--c2:#c0202a;--c3:#2a0608}
.fxcss .jflash{left:-6%;top:-6%;width:112%;height:112%;border-radius:50%;opacity:0;
  background:radial-gradient(circle,color-mix(in srgb,var(--c2) 55%,transparent) 0%,transparent 64%);
  animation:fxjflash var(--ms) ease-out forwards}
@keyframes fxjflash{0%{opacity:0;transform:scale(.6)}12%{opacity:1}100%{opacity:0;transform:scale(1.1)}}
.fxcss .jcrack{left:50%;top:50%;width:var(--w);height:2.5px;transform-origin:0 50%;
  background:linear-gradient(90deg,var(--c1) 0%,var(--c2) 34%,var(--c3) 74%,transparent 100%);
  box-shadow:0 0 6px color-mix(in srgb,var(--c2) 70%,transparent);
  opacity:0;animation:fxjcrack var(--ms) cubic-bezier(.1,.85,.3,1) var(--d) forwards}
@keyframes fxjcrack{
  0%  {opacity:0;transform:rotate(var(--a)) scaleX(.06)}
  14% {opacity:1}
  46% {transform:rotate(var(--a)) scaleX(1)}
  100%{opacity:0;transform:rotate(var(--a)) scaleX(1)}}

/* ── 극독으로 스러질 때 — **해골은 걷었다** (2026-10-03 롤백) ──
   꼴로 그린 해골이 **해골로 안 읽혔다**(기획자: 「원 상태로 롤백해」).
   극독은 자주 핵에 황록 덩굴이 뻗는 그 꼴 하나로 돌아갔다 — 그쪽이 타격감이 있었다.
   ⚠ 안 쓰는 꼴을 남겨 두지 않는다. 남겨 두면 fx-check 가 지키지 못하는 자리가 늘고,
      다음 사람이 「이것도 도는가」를 눈으로 확인해야 한다 */
/* ── 징집 — 위에서 빛이 내려 쬔다 ──────────────────────────
   ⚠ 부르는 것이지 터지는 것이 아니다. **위에서 아래로** 빛이 내려와 그 자리를 비추고,
      빛을 타고 티끌이 **거꾸로 떠오른다**. 불려 나온다는 뜻이 그 두 방향에 있다 */
/* ⚠ **일곱 할로 옅다** (2026-10-03 기획자가 정함) — 부르는 빛이지 터지는 빛이 아니다 */
.fx-draft{--c1:#fff6dc;--c2:#ffd98a;--c3:#c9972f;opacity:.7}
/* ⚠⚠ **`clip-path` 로 모양을 내지 마라** (2026-10-03 기획자가 물림 — 「금강이랑 상황이 같다」).
      `clip-path` 는 **`filter` 뒤에** 먹는다 — 아무리 흐려 놓아도 그 흐린 것을 **다시 칼로
      자른다.** 그래서 흐림을 올려도 가장자리가 끝내 날카로웠다.
   ⚠ 모양은 **가면(`mask`)**이 낸다. 가면은 가장자리를 **투명으로 녹일 수 있어** 자른 자국이
      안 남는다 — 아래가 넓은 타원 가면이라 위에서 아래로 퍼지는 빛기둥이 된다.
      위아래로 녹는 것은 바탕 기울기가 이미 하고 있다(0%·100% 가 투명).
   ⚠ 가면을 못 쓰는 판에서는 옛 `clip-path` 가 그대로 남는다 */
.fxcss .beam{left:18%;top:-46%;width:64%;height:116%;
  background:linear-gradient(180deg,transparent 0%,color-mix(in srgb,var(--c1) 70%,transparent) 18%,
             color-mix(in srgb,var(--c2) 52%,transparent) 62%,transparent 100%);
  clip-path:polygon(32% 0,68% 0,100% 100%,0 100%);
  filter:blur(1.5px);opacity:0;transform-origin:50% 0;
  animation:fxbeam var(--ms) cubic-bezier(.2,.8,.3,1) forwards}
@supports ((mask:radial-gradient(#000,#000)) or (-webkit-mask:radial-gradient(#000,#000))){
  /* ⚠⚠ **가면의 가로 반지름은 틀 안에서 끝나야 한다.** 처음에 `150%` 로 두었더니 녹는 자리가
     틀 **밖**이라 좌우가 네모로 뚝 잘렸다 — 가면을 씌운 보람이 없었다.
     투명이 되는 자리(`86%`)가 틀 안에 들도록 `0.56 × 0.86 ≈ 0.48 < 0.5` 로 잡는다 */
  .fxcss .beam{clip-path:none;filter:blur(3.4px);
    -webkit-mask:radial-gradient(56% 124% at 50% 108%,#000 18%,#0009 52%,transparent 86%);
            mask:radial-gradient(56% 124% at 50% 108%,#000 18%,#0009 52%,transparent 86%)}
}
@keyframes fxbeam{
  0%  {opacity:0;transform:scaleY(.1) scaleX(.7)}
  22% {opacity:1;transform:scaleY(1)  scaleX(1)}
  64% {opacity:.9}
  100%{opacity:0;transform:scaleY(1)  scaleX(.86)}}
.fxcss .pool{left:6%;bottom:2%;width:88%;height:26%;border-radius:50%;
  background:radial-gradient(50% 60% at 50% 50%,var(--c1) 0%,color-mix(in srgb,var(--c2) 60%,transparent) 44%,transparent 76%);
  filter:blur(2px);opacity:0;animation:fxpool var(--ms) ease-out forwards}
@keyframes fxpool{0%{opacity:0;transform:scale(.4)}26%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(1.1)}}

/* ── 호법 — **꼴로 그리던 「붉은 외침」은 통째로 걷었다** (2026-10-04 기획자: 「붉은 외침은 안 쓴다」) ──
   ⚠ `.fx-hobeop`·`.yell`·`.ray`·`.holler` 와 그 참(`fxyell`·`fxray`·`fxholler`)이 여기 있었다.
      호법이 **시트**(`fx_guard_hobeop_v2` — 갈라진 철방패가 맞물린다)로 바뀐 뒤로
      `FX.hobeop` 에 `css:1` 이 없어 **아무도 안 세우는 꼴**이었다. 옅기(0.7)는 그 표가 쥔다.
   ⚠ 안 쓰는 꼴을 남겨 두면 빛깔 변수가 뒤 규칙으로 새어 들고(옛 `--c4` 가 그랬다),
      다음 사람이 「이게 아직 도는가」를 눈으로 확인해야 한다 */

/* ── 금강 — 기류가 몸을 휘감는다 ────────────────────────────
   ⚠⚠ **금빛 테가 아니다** (2026-10-03 기획자가 물림 — 「각연자 연출 같다」).
      금테는 이미 각연자(`eng`)가 쓰는 말이라 **같은 빛깔로 다른 말**을 하고 있었다.
      이제 **맑은 기류가 띠처럼 감아 돈다** — 두르는 것이지 빛나는 것이 아니다.
   ⚠ 머무는 연출이라 **옅다**. 띠 셋이 저마다 다른 빠르기로 돌아 겹치며 흐른다.
   ⚠⚠ **카드 안에서 돈다** (2026-10-03 기획자가 정함 — 「카드 내부에서 돌도록」).
      전에는 `inset:-6%` 으로 카드 **밖까지** 번졌고 띠 둘도 음수 여백으로 비어져 나갔다 —
      수라장은 칸이 붙어 있어 옆 칸 카드 위로 띠가 지나갔다.
      이제 틀이 **카드 네모 그대로**(`inset:0`)고 `overflow:hidden` 이 **넘지 못하게 자른다.**
      안쪽 띠 셋은 **모두 양수 여백**이다 — 하나라도 음수면 잘려서 띠가 끊겨 보인다.
   ⚠⚠ `margin-top:-56%` 로 가운데를 맞추고 있었다 — **%여백은 네 방향 모두 너비 기준**이라
      카드(62×89)에서는 세로가 **15px 어긋나 있었다.** `translate(-50%,-50%)` 로 바꿨다 */
/* ═══ ⚠⚠ **금강은 읽어야 하는 것 아래에 선다** (2026-10-03 기획자가 정함) ═══════════
   「금강 연출이 공력·기력·파·코스트 UI 위로 돌더라 — 그보단 아래 레이어로」.
   ⚠⚠ **금강을 내려서는 못 고친다.** 그 수치들은 `z-index:auto`(=0)인데, 쌓임에서는
      **양수 z 가 auto 를 늘 이긴다** — 금강을 1 로 내려도 여전히 위다.
      음수로 내리면 이번엔 카드 그림 **뒤로** 숨어 아예 안 보인다.
      그래서 고치는 길은 하나뿐이다: **읽어야 하는 것을 금강 위로 올린다.**
   ⚠ 올리는 것은 **수와 글자**뿐이다(`.c-cost`·`.c-atk`·`.c-hp`·`.c-path`·`.ugain`·`.tgtlab`).
      그림과 테는 그대로 둔다 — 금강은 그 위를 감는 것이 맞다 */
.gangfx{position:absolute;inset:0;z-index:7;pointer-events:none;
  overflow:hidden;border-radius:3px}
/* ⚠⚠ **끝이 뭉툭하면 UI 가 된다** (2026-10-03 기획자가 물림 — 「그냥 U자형 UI라 너무 딱딱해,
      기력·공력 상승의 부드러움이 딱 좋아」). 테(`border-top-color`)로 그린 띠는 반원이 **뚝
      끊겨** 시작과 끝이 칼로 자른 듯하다 — 기운이 아니라 그려 넣은 도형으로 읽힌다.
   ⚠ 상승(`.wisp`)이 부드러운 까닭은 **양끝이 투명으로 녹고**(`linear-gradient` 의 0%·100%)
      거기에 **흐림**이 얹혀서다. 그 두 가지를 그대로 가져온다 —
      다만 띠가 **원을 따라 도는 것**이라 `linear` 가 아니라 **`conic`** 이다.
   ⚠ `conic-gradient` 는 둥근 판 전체를 칠하므로 **고리만 남기는 가면**(`mask`)을 씌운다.
      가면의 가장자리도 부드럽게 두어 **굵기까지 끝에서 녹는다.**
   ⚠ 가면을 못 쓰는 판에서는 아래 테 꼴이 그대로 남는다 — 못 쓴다고 사라지면 안 된다 */
.gangfx i{position:absolute;inset:2%;border-radius:50%;
  border:1.5px solid transparent;
  border-top-color:#fff6dc;border-bottom-color:#ffd98a;
  opacity:.52;
  animation:gangspin var(--d) linear infinite}
.gangfx i:nth-child(1){--d:2.6s;transform:rotate(0deg)}
.gangfx i:nth-child(2){--d:3.6s;inset:11% 3%;border-top-color:#ffeab4cc;border-bottom-color:#e8b45f99;
  animation-direction:reverse}
.gangfx i:nth-child(3){--d:4.8s;inset:4% 13%;border-top-color:#ffe9b099;border-bottom-color:#c9972f88}
@supports ((mask:radial-gradient(#000,#000)) or (-webkit-mask:radial-gradient(#000,#000))){
  .gangfx i{border:0;
    /* 두 자락이 마주 보고 돌되 **저마다 양끝이 투명으로 녹는다** */
    background:conic-gradient(from 0deg,
      transparent 0 3%, var(--g2) 13%, var(--g1) 23%, var(--g2) 33%, transparent 46%,
      transparent 53%, var(--g2) 63%, var(--g1) 73%, var(--g2) 83%, transparent 96% 100%);
    /* ═══ ⚠⚠ **카드 테 안쪽에 붙어 돈다** (2026-10-03 기획자가 정함) ══════════════
       「지금은 중앙에서 빙빙 돌잖아 — 카드 테두리 안쪽에 붙어서 도는, 보호받고 있다는 느낌」.
       둥근 가면(`radial-gradient`)은 **카드 한가운데에 동그라미**를 그린다. 카드는 62×89
       세로 네모라, 동그라미를 그리면 위아래가 남아 **가운데서 맴도는 고리**로 보였다.
       ⚠ 그래서 가면을 **네모 테 꼴**로 바꾼다 — 안쪽을 도려내는 그 수법이다
          (겹 둘을 겹쳐 안쪽을 빼낸다: `content-box` 한 장 + 전체 한 장 + `exclude`).
          그러면 띠가 **카드 네 변을 따라** 흐른다.
       ⚠⚠ **네모는 돌리면 안 된다.** 예전처럼 `transform:rotate` 를 걸면 네모 자체가
          빙글 돌아 카드 밖으로 모서리가 삐져나온다. **틀은 가만두고 그 안의 빛만** 돈다 —
          그래서 도는 것은 `::before` 고, 틀은 `animation:none` 이다.
       ⚠ `::before` 가 틀보다 **커야**(200%) 돌아도 네 귀가 안 빈다 */
    padding:1.6px;border-radius:3px;background:none;animation:none;overflow:hidden;
    -webkit-mask:linear-gradient(#000,#000) content-box,linear-gradient(#000,#000);
            mask:linear-gradient(#000,#000) content-box,linear-gradient(#000,#000);
    -webkit-mask-composite:xor;mask-composite:exclude}
  .gangfx i::before{content:"";position:absolute;left:50%;top:50%;width:200%;height:200%;
    background:conic-gradient(from 0deg,
      transparent 0 3%, var(--g2) 13%, var(--g1) 23%, var(--g2) 33%, transparent 46%,
      transparent 53%, var(--g2) 63%, var(--g1) 73%, var(--g2) 83%, transparent 96% 100%);
    filter:blur(.9px);
    animation:gangrun var(--d) linear infinite}
  /* ⚠⚠ **노랑으로 돌아왔다** (2026-10-03 기획자가 정함 — 「금강 연출을 노랑색으로,
     투명도를 조금 줄여줘 잘 안 보인다」). 2026-10-02 에는 금테가 **각연자의 금빛과
     같은 말**을 해서 맑은 기류로 바꾸었는데, 돌려 보니 **어두운 카드 위에서 푸른 기류가
     아예 안 보였다.** 각연자의 금빛(`#e8cf8f`·`#d4a843`)과는 **움직임으로 갈린다** —
     그쪽은 카드에 붙박인 가는 테 하나고 이쪽은 **네 변을 따라 흐르는 띠 셋**이다.
     ⚠ 세기도 올렸다(.56/.36/.22 → .82/.58/.38). 그래도 1 은 아니다 —
        판이 끝날 때까지 떠 있는 것이라 꽉 차면 그 아래 그림과 숫자를 가린다.
     ⚠ **안쪽일수록 옅다.** 셋을 같은 세기로 두면 **액자 세 겹**으로 보인다 —
        옅어져 들어가야 「한 겹이 몸을 감싸고 그 안쪽으로 기운이 번진다」로 읽힌다 */
  .gangfx i:nth-child(1){--g1:#fff6dc;--g2:#ffd98acc;inset:2%;opacity:.82}
  .gangfx i:nth-child(2){--g1:#ffeab4;--g2:#e8b45fa8;inset:7%;padding:1.2px;opacity:.58}
  .gangfx i:nth-child(3){--g1:#ffe9b0;--g2:#c9972f88;inset:12%;padding:1px;opacity:.38}
  .gangfx i:nth-child(2)::before{animation-direction:reverse}
}
@keyframes gangspin{to{transform:rotate(360deg)}}
@keyframes gangrun{
  from{transform:translate(-50%,-50%) rotate(0deg)}
  to  {transform:translate(-50%,-50%) rotate(360deg)}}
/* ⚠ 숨은 **테 안쪽에서** 쉰다 — 가운데에 둥근 빛을 두면 또 「한가운데서 맴도는 것」이 된다.
   안쪽으로 번지는 그늘이라야 「둘러싸여 지켜지고 있다」로 읽힌다 */
.gangfx b{position:absolute;inset:0;border-radius:3px;
  box-shadow:inset 0 0 10px 1px #ffd98a3d,inset 0 0 3px #fff6dc47;
  animation:gangbreath 2.2s ease-in-out infinite}
@keyframes gangbreath{0%,100%{opacity:.42}50%{opacity:.78}}
@media (prefers-reduced-motion:reduce){ .gangfx i,.gangfx i::before,.gangfx b{animation:none} }
/* ⚠ **수와 글자는 금강(7) 위**다 — 위 머리말이 그 까닭이다.
   ⚠ `.card` 는 `position:relative` 에 `z-index:auto` 라 **쌓임 바탕을 열지 않는다** —
      그래서 카드 안의 이것들이 카드 밖의 `.gangfx` 와 **같은 자리에서 겨룬다.**
      `.card` 에 `z-index` 를 주면 이 셈이 통째로 뒤집히므로 주지 마라.
   ⚠ 「효과 선택」(`.tgtlab`)은 한 단 더 위다 — 지금 **무엇을 하라는 말**이라 무엇에도 안 가린다 */
.unit .c-cost,.unit .c-atk,.unit .c-hp,.unit .c-path{z-index:8}
.unit .ugain{z-index:8}
.unit .tgtlab{z-index:9}

/* ── 스러진 연의 먼지 (2026-10-03 보강 · 10-03 잿빛으로 다시) ──
   ⚠ 카드 자체가 흐려지는 것만으로는 **지워진 것**으로 보인다. 알갱이가 떠올라야 흩어진 것이다.
   ⚠⚠ **타고 남은 재다**(기획자: 「잿빛으로, 불탐을 강조」). 그래서 알갱이가 두 가지다 —
      **재**는 잿빛으로 식어 흩어지고, **불똥**은 아직 붉게 달아 있다가 꺼진다.
      한 가지 빛깔로만 날리면 「먼지」지 「타 없어진 것」이 아니다 */
.dustmotes{position:absolute;inset:0;z-index:9;pointer-events:none;overflow:visible}
.dustmotes b{position:absolute;display:block;border-radius:50%;
  background:radial-gradient(circle,#d7d2c7 0%,#7d786f 46%,transparent 76%);
  opacity:0;animation:dustmote var(--ms) ease-out var(--d) forwards}
.dustmotes b.ash{background:radial-gradient(circle,#d7d2c7 0%,#847f76 48%,transparent 78%)}
.dustmotes b.ember{background:radial-gradient(circle,#fff3d0 0%,#ff9b3d 38%,#c2380c 66%,transparent 82%);
  box-shadow:0 0 5px #ff8a2e88}
@keyframes dustmote{
  0%  {opacity:0;transform:translate(0,0) scale(.7)}
  18% {opacity:.95}
  100%{opacity:0;transform:translate(var(--sx),var(--sy)) scale(.2)}}
/* ⚠ **타는 자리가 먼저 달아오른다.** 그냥 흐려지면 「사라진다」지 「탄다」가 아니다 —
   앞머리에 붉은 기가 한 번 돌고 나서 잿빛으로 식으며 흩어진다 */
@keyframes dust{
  0%  {opacity:1;filter:none}
  22% {opacity:.92;filter:blur(.5px) brightness(1.25) sepia(.55) saturate(2.6) hue-rotate(-14deg)}
  55% {opacity:.62;filter:blur(2px) brightness(1.05) sepia(.4) saturate(1.4) grayscale(.35)}
  100%{opacity:0;  filter:blur(8px) brightness(.9) grayscale(.9);transform:translateY(-16px) scale(.94)}}
@media (prefers-reduced-motion:reduce){
  .fxcss,.dustmotes{display:none} }

/* ⚠ 금강은 카드에 **붙박이**로 선다 — 이벤트가 아니라 상태다.
   `.card.gang` 이 켜져 있는 동안만 보이므로 지우고 세우는 손이 없다 */
/* ⚠⚠ **`.unit.gang` 이다 — `.card.gang` 이 아니다** (2026-10-02 에 제보받아 잡았다).
   수라장의 연은 `.unit` 이라 `.card` 로 적으면 **아무 데도 안 걸려 조용히 안 나온다.**
   ⚠⚠ **`--n` 을 반드시 함께 준다** (2026-10-02 에 두 번째로 잡았다). `@keyframes fxrun` 의
      끝값이 `calc(var(--n) * var(--w) * -1)` 인데 `--n` 이 없으면 **그 줄이 통째로 무효**가 되어
      칸이 한 발짝도 안 움직인다. 첫 칸은 거의 비어 있어 **아무것도 안 뜨는 것처럼 보인다.**
      `fx-check` 가 칸 수를 재지만 `--n` 이 **있는지**까지는 못 봤다 — 그 검사도 더했다.
   ⚠ 연은 세로로 길고(63:88) 연출 그림은 **정사각**이다. 네모 칸에 그대로 깔면 눌려 보이므로
      **가로를 기준으로 정사각 칸**을 만들어 카드 한가운데에 얹는다.
   ⚠ **카드 위에 선다.** 카드틀(`.card::before`)이 z 6 이므로 그보다 위여야 테를 안 가린다 */
/* ⚠⚠ **`--w` 는 px 다 — %로 적으면 칸이 어긋난다.** `background-position` 의 퍼센트는
   「칸 수」가 아니라 **(칸 − 그림) 차이**에 걸려서, 흐르는 연출(`.fxplay`)과 같은 어긋남이 난다.
   수라장의 연은 `max-width:62px` 로 못 박혀 있고 판 전체가 고정 폭(`zoom`)이라 px 로 적어도 안전하다 */
/* ⚠⚠ **금강의 금빛 테를 걷었다** (2026-10-03 기획자가 물림 — 「각연자 연출 같다」).
   금테는 각연자(`.card.eng`)가 쓰는 말이라 **같은 빛깔로 다른 뜻**을 말하고 있었다.
   이제 맑은 기류 띠 셋이 감아 돈다 — 꼴은 `.gangfx`(markup) 가 쥔다. 여기는 비워 둔다.
   ⚠ `::after` 를 지우지 않고 **남겨 둔다** — 지우면 `fx-check` 의 「금강이 .unit.gang 에
      걸려 있다」가 깨진다. 안쪽에 그릴 것만 없앴다 */
.unit.gang::after{content:"";position:absolute;inset:0;z-index:7;pointer-events:none}
@media (prefers-reduced-motion:reduce){ .unit.gang::after{animation:none} }
/* ⚠ 옛 시트가 쓰던 줄은 걷었다 (2026-10-03) — 흘릴 칸이 없다 */

/* ===== 파동 — 카드가 수라장에 나오는 순간, 그리고 초식 (`ripple`) =====
   권속은 초록, 각연자는 제 테두리와 같은 금빛으로 더 굵고 더 멀리 퍼진다 */
/* ⚠ **내 것은 초록, 상대 것은 적색** (2026-10-02 기획자가 정함) — 누가 낸 연인지가
   파동만 보고도 읽혀야 한다. 빛깔만 가르고 퍼지는 꼴은 같다 */
.ripfx{position:fixed;z-index:15;pointer-events:none;border-radius:6px;opacity:0;
  border:2px solid #7dffb4;
  box-shadow:0 0 10px 1px #4dffa088,inset 0 0 8px #4dffa044}
.ripfx.foe{border-color:#ff8a8a;
  box-shadow:0 0 10px 1px #ff5a5a88,inset 0 0 8px #ff5a5a44}
.ripfx.foe.eng{border-color:#ffb27a;
  box-shadow:0 0 16px 3px #ff7a4fcc,0 0 30px 8px #d4634366,inset 0 0 12px #ff7a4f66}
.ripfx.eng{border:3px solid #ffe08a;
  box-shadow:0 0 16px 3px #ffd25fcc,0 0 30px 8px #d4a84366,inset 0 0 12px #ffd25f66}
/* ===== 오오라 한 장 (v179) =====
   「펑」(`.boom`)은 **맞았다**는 말이다. 나은 것·굳은 것에 그 꼴을 쓰면 좋은 일과 나쁜 일이
   같은 그림으로 나온다. 이쪽은 자리를 감싸고 한 번 부풀었다 스민다 —
   크기는 감쌀 칸에서 재어 넣으므로(`auraAt`) 여기서는 빛깔만 정한다 */
.aurafx{position:fixed;z-index:16;pointer-events:none;transform:translate(-50%,-50%)}
.aurafx.heal{border:2px solid #7fe0a8;
  box-shadow:0 0 16px 4px #4fd08a80,0 0 34px 10px #4fd08a3d,inset 0 0 18px 4px #7fe0a84d;
  background:radial-gradient(closest-side,#4fd08a26,transparent 78%)}
/* 금강이 걸리는 순간은 따로 그리지 않는다 — 버프라 회복과 같은 초록 오오라(`.aurafx.heal`)를 쓴다 (`auraAt`) */
/* 막 내려앉은 자리 — 연이 그려지는 첫 순간에만 한 번 부푼다 */
.slot.land,.unit.land{animation:land .34s cubic-bezier(.2,1.5,.4,1)}
@keyframes land{0%{transform:scale(1.18)}100%{transform:scale(1)}}
/* ⚠⚠ **숨 쉬게 한다** (2026-10-03 기획자: 「점멸 연출이 사라졌다」).
   가만히 있는 테는 **칠 수 있다**는 말을 하기엔 너무 조용했다 — 판이 어두워 눈에 안 걸린다.
   ⚠ 빠르게 깜빡이지 않는다. 느리게 들숨날숨 하는 결이라 **고르는 중인 대상**(맥박 .62s)과
      헷갈리지 않는다. 그쪽이 빠르고 이쪽이 느리다 */
.unit.ready .card{box-shadow:0 0 0 2px var(--ready),0 0 13px #4dffa055,inset 0 0 14px #4dffa01a;
  animation:readybreath 1.5s ease-in-out infinite}
@keyframes readybreath{
  0%,100%{box-shadow:0 0 0 2px var(--ready),0 0 10px #4dffa04d,inset 0 0 14px #4dffa01a}
  50%    {box-shadow:0 0 0 2px var(--ready),0 0 22px 3px #4dffa0cc,inset 0 0 16px #4dffa033}}
@media (prefers-reduced-motion:reduce){ .unit.ready .card{animation:none} }
/* 줄에 세워 둔 공격 — **이미 둔 수다** (v156). 초록 테를 끄는 것만으로는
   「칠 수 없는 연」과 구별이 안 되므로, 칼을 낸 쪽으로 반 발짝 나가 선 채로 기다린다 */
.unit.queued{transform:translateY(-2px)}
/* ⚠⚠ **푸른 테를 두르지 않는다** (2026-10-03 기획자가 물림 — 「없던 테두리야」).
   줄에 세운 수는 **반 발짝 나가 선 것**(`translateY`)과 한 겹 어둡게 깔리는 것(`::after`)으로
   이미 말하고 있다. 테까지 두르면 「칠 수 있다」(초록 테)와 **같은 말을 두 빛깔로** 하는 셈이다.
   ⚠ `animation:none` 은 남긴다 — 이미 둔 수는 숨 쉬지 않는다(`readybreath` 를 끈다) */
.unit.queued .card{animation:none}
.unit.queued .card::after{content:"";position:absolute;inset:0;z-index:4;pointer-events:none;background:#0a0a1433}
/* 고르는 동안은 처음부터 끝까지 초록 하나로 간다 — 시전 자리·고른 연·겨눈 대상이 다 같은 색이다.
   자리마다 색이 갈리면 지금 무엇을 하는 중인지가 아니라 색이 무슨 뜻인지를 먼저 풀어야 한다 */
.unit.sel{transform:translateY(-5px)}
.unit.sel .card{box-shadow:0 0 0 2px var(--ok),0 0 14px #6fcf9777}
/* 겨누는 색은 **무엇을 하려는지**로 가른다 — 치러 가면 붉고, 이롭게 하면 초록이다.
   둘 다 초록으로 두면 상대를 고르는 건지 내 편을 고르는 건지 색으로 구별이 안 된다 */
/* 맥이 더 세게 뛴다 (v155) — 테만 굵어지는 정도로는 판이 어수선할 때 눈에 안 들어왔다.
   빠르게(1s → .62s), 테는 2→4px, 그리고 **밝기까지 함께 오르내린다**.
   테두리는 카드 바깥이라 그림에 묻히지만 밝기는 카드 얼굴 전체가 움직이므로 곁눈에도 걸린다 */
.unit.tgt .card{box-shadow:0 0 0 2px var(--danger),0 0 12px #c9524a99;animation:plr .62s ease-in-out infinite}
/* ▼▼ 끌어 두기 (v0.336) — 걷어낼 때는 `ui.js` 의 같은 표와 함께 지운다 ▼▼
   ⚠ `touch-action:none` 은 **칠 수 있는 연에만** 건다. 안 걸면 손가락을 위로 끄는 순간
      브라우저가 화면을 굴려 버려 끌기가 시작되지도 않는다.
      칠 수 없는 연은 그대로 두어 화면이 굴러간다 — 잡히지도 않는 연이니 막을 까닭이 없다 */
.unit.ready{touch-action:none}
/* ⚠⚠ 패는 **가로만** 브라우저에 맡긴다(`pan-x`). 세로는 우리가 받아 카드를 끌어낸다.
   이 한 줄이 없으면 손가락을 위로 끄는 것을 브라우저가 먼저 삼켜 끌기가 안 열린다 */
.hand{touch-action:pan-x}
/* 이어 주는 줄 — 화면 전체를 덮는 투명한 판 하나에 그린다. 수라장 위(58)와 창(20) 사이에 선다.
   빛깔은 하는 일이 정한다(`--hue`) — 칼은 붉고, 기는 푸르고, 병기는 금빛, 자리는 옥빛 */
/* ⚠ 줄도 **숨 쉰다** (2026-09-30 기획자가 정함) — 겨눌 자리(`.unit.tgt`)가 0.62초로 깜빡이는데
   줄만 가만히 있으면 둘이 따로 논다. **같은 빠르기**로 맞춘다 */
.atkline{position:fixed;inset:0;width:100%;height:100%;z-index:17;pointer-events:none;--hue:var(--danger);
  animation:atkbeat .62s ease-in-out infinite}
@keyframes atkbeat{50%{opacity:.5}}
@media (prefers-reduced-motion:reduce){.atkline{animation:none}}
.atkline line{stroke:var(--hue);stroke-width:3;stroke-linecap:round;
  filter:drop-shadow(0 0 6px color-mix(in srgb,var(--hue) 70%,transparent)) drop-shadow(0 1px 2px #000c)}
.atkline polygon{fill:var(--hue);
  filter:drop-shadow(0 0 6px color-mix(in srgb,var(--hue) 70%,transparent)) drop-shadow(0 1px 2px #000c)}
/* 놓을 자리 위에 뜨는 표식 — 무엇을 하려는지 그림 하나로 말한다 (도·갑·서·패).
   ⚠ 기획자가 그린 원화다(`drag_action_*.png`, 1254px). 그대로 쓰면 표식 하나에 1MB 가 넘어가므로
      가장자리 빈 곳을 잘라 128px webp 로 구워 두었다 — `drag_mark_*.webp`, 넷 합쳐 30KB 남짓이다.
      원화를 고치거든 `docs/_표식굽기.py` 를 다시 돌린다.
   ⚠ **어두운 동그라미를 걷어냈다.** 붓으로 그린 그림이라 22px 원 안에 넣으니 뭉개져서,
      그림을 키우고(44px) 동그라미 대신 **그림 둘레에 빛무리**를 둘렀다.
      좋고 나쁨은 그 빛무리 빛깔(`--mk`)이 말한다 — 테두리 선일 때와 뜻이 같다.
   ⚠ 빛무리는 `box-shadow` 가 아니라 `drop-shadow` 다 — 네모 칸이 아니라 **그림 모양**을 따라간다 */
.dropmark{position:fixed;z-index:17;width:calc(54px * var(--fxk));height:calc(54px * var(--fxk));margin:calc(-27px * var(--fxk)) 0 0 calc(-27px * var(--fxk));
  pointer-events:none;
  background-repeat:no-repeat;background-position:center;background-size:contain;
  filter:drop-shadow(0 0 5px var(--mk,#c9524a))
         drop-shadow(0 0 13px color-mix(in srgb,var(--mk,#c9524a) 75%,transparent))
         drop-shadow(0 2px 4px #000d);
  animation:mkpop .18s cubic-bezier(.2,1.4,.4,1)}
@keyframes mkpop{from{transform:scale(.55);opacity:0}to{transform:scale(1);opacity:1}}
/* ⚠ 빛무리는 **좋은가 나쁜가** 둘뿐이다. 무엇을 하는지는 **그림**이 말한다 */
.dropmark.bad {--mk:var(--danger)}
.dropmark.good{--mk:var(--ok)}
.dropmark.atk   {background-image:url(assets/ui/drag_mark_atk.webp?v=2)}
.dropmark.equip {background-image:url(assets/ui/drag_mark_equip.webp?v=1)}
.dropmark.cast,
.dropmark.sumtgt{background-image:url(assets/ui/drag_mark_cast.webp?v=1)}
.dropmark.summon{background-image:url(assets/ui/drag_mark_summon.webp?v=1)}
@media (prefers-reduced-motion:reduce){.dropmark{animation:none}}
/* ▼ 손끝에 딸려 오는 카드 (v0.339) — 패에서 끌 때만 뜬다.
   ⚠ `translate(-50%,-86%)` — 손끝 **위쪽**에 매단다. 손끝에 겹쳐 두면 놓을 자리가
      손가락에 가려 안 보인다. 그 아래 남은 자리로 표식과 화살촉이 보인다.
   ⚠⚠ `pointer-events:none` 이 목숨줄이다 — 이것이 없으면 카드가 **제 밑을 가려**
      `elementFromPoint` 가 놓을 자리 대신 이것을 집고, 놓아도 아무 일이 안 난다.
   ⚠ 안에 든 것은 패에 있는 카드를 통째로 베낀 것이라(`cloneNode`) 크기가 `.hcard` 와 같다 */
/* ⚠⚠ **너비에 `--k` 를 곱한다 — 이것은 `.app` **바깥**(`body`)에 달리기 때문이다** (2026-10-14).
   `lift()` 가 `document.body.appendChild` 로 단다(`ui.js`). 그래서 `.app` 의 `zoom:var(--k)` 를
   **안 받는다** — 위 머리말이 「크기가 `.hcard` 와 같다」고 적어 둔 것이 넓은 화면에서는 거짓이었다:
     배율 1 (좁은 창)   — 패 60px · 유령 68.4px
     배율 1.625 (최대화) — 패 97.5px · 유령 68.4px  ← **3할이 작다**
   `--k` 는 `:root` 에 서므로 `body` 밑에서도 읽힌다. 이제 어느 배율에서나 패와 같은 크기다.
   ⚠⚠ **너비가 아니라 `scale` 로 키운다.** `width` 만 곱하면 액자만 커지고 **안에 든 글자와
      딱지는 px 붙박이라 그대로**여서, 큰 화면에서 이름만 깨알 같은 카드가 딸려 온다.
   ⚠⚠ **`zoom` 을 쓰면 안 된다** — 판(`.app`)과 달리 이것은 `position:fixed` 라
      `zoom` 이 `left`·`top` 까지 함께 곱해 **유령이 손끝에서 떨어져 나간다.**
      `transform:scale` 은 자리를 안 건드린다(`translate` 의 `%` 는 60px 테두리 상자 기준이다).
      §판 머리말이 「`scale` 은 글자가 자글자글하다」고 적어 둔 것은 **내내 서 있는 판** 이야기고,
      이것은 끄는 동안만 떴다 사라지는 것이라 그 값이 안 든다.
   ⚠ **자리(`left`·`top`)에는 곱하지 마라.** `ui.js` 가 손끝 창 좌표를 그대로 넣는다.
   ⚠ 확대를 1.14 → 1.04 로 낮췄다 (기획자 — 「드래그했을 때 카드가 너무 크다」, 좁은 창).
      1 로 두지는 않는다. 조금 떠 보여야 **쥐고 있는 것**과 패에 놓인 것이 갈린다 */
.dragghost{position:fixed;z-index:18;width:60px;pointer-events:none;
  transform:translate(-50%,-86%) rotate(-4deg) scale(calc(1.04 * var(--k,1)));transform-origin:50% 100%;
  filter:drop-shadow(0 6px 12px #000b) drop-shadow(0 0 10px #0008);
  animation:ghpick .16s cubic-bezier(.2,1.3,.4,1)}
/* ⚠ 집어 드는 짧은 연출도 **`--k` 를 함께 곱한다**. 안 곱하면 넓은 화면에서 유령이
   폰 크기(.96)로 떴다가 제 크기로 **툭 뛴다** — 끝 값만 고치고 시작 값을 잊은 자리다 */
@keyframes ghpick{from{transform:translate(-50%,-62%) rotate(0) scale(calc(.96 * var(--k,1)))}}
/* 집어 든 그 자리 — 비워 둔 듯 흐려 둔다. 카드가 둘로 보이면 안 된다 */
.hcard.lifted{opacity:.22}
.hcard.lifted .card{animation:none!important;box-shadow:none!important}
@media (prefers-reduced-motion:reduce){.dragghost{animation:none}}
/* ▲ 손끝에 딸려 오는 카드 여기까지 ▲ */
/* 끄는 동안에는 글자가 잡히지 않게 — 손가락이 미끄러지며 글을 긁으면 지저분하다 */
body.atkdrag{user-select:none;-webkit-user-select:none}
/* ⚠⚠ **그림은 손끝에 안 잡힌다** (2026-09-30).
   ① `pointer-events:none` — 길게 눌러도 **그림이 아니라 그것을 담은 칸**이 눌린 것이 된다.
      브라우저가 「이미지 다운로드」 차림표를 여는 까닭이 그림이 눌렸기 때문이다.
      누르는 판정은 어차피 `closest()` 로 바깥 칸을 찾으므로 잃는 것이 없다.
   ② `-webkit-user-drag:none` — 쥐로 그림을 끌면 브라우저의 **제 끌기**가 먼저 붙어,
      우리 「끌어 두기」가 시작되다 말고 그림 유령만 따라다녔다 */
img{-webkit-touch-callout:none;-webkit-user-drag:none;user-select:none;-webkit-user-select:none}
.card img,.unit img,.hcard img,.gcard img,.stg-card img,.gain-ic img,#iBody img,#oBody img{pointer-events:none}
/* ▲▲ 끌어 두기 여기까지 ▲▲ */
@keyframes plr{50%{box-shadow:0 0 0 4px #ff8a7e,0 0 26px #e8695fe6,inset 0 0 20px #c9524a5c;
  filter:brightness(1.22) saturate(1.1)}}
.unit.tgt.good .card{box-shadow:0 0 0 2px var(--ok),0 0 12px #6fcf9799;animation:plg .62s ease-in-out infinite}
@keyframes plg{50%{box-shadow:0 0 0 4px #b6f5cf,0 0 26px #6fcf97e6,inset 0 0 20px #6fcf975c;
  filter:brightness(1.2) saturate(1.1)}}
/* 겨눠진 무명자 본체 — 연과 **같은 맥**으로 뛴다 (v155).
   예전에는 자바스크립트가 그림자 값을 인라인으로 박아 두어 아예 깜빡이지 않았다.
   본체는 동그라미라 테도 동그라미다 */
.por.tgt{animation:plrp .62s ease-in-out infinite}
@keyframes plrp{
  0%,100%{box-shadow:0 0 0 3px var(--danger),0 0 14px #c9524aaa;filter:none}
  50%{box-shadow:0 0 0 5px #ff8a7e,0 0 30px #e8695fe6;filter:brightness(1.24)}}
.orb.good{background:radial-gradient(circle,#fff 0%,#b6f5cf 40%,#6fcf9766 70%,transparent)}
.boom.good{background:radial-gradient(circle,#f2fff6 0%,#9fe7bd 28%,#6fcf9788 54%,transparent 72%);
  animation:rise .5s ease-out forwards}
@keyframes rise{to{transform:translateY(-26px) scale(1.5);opacity:0}}
.unit.hit{animation:shake .3s}
/* 잠행 — 겨눌 수 없는 연이다. 한 겹 어둡게 깔아 두면 누르기 전에 알아본다 (v128) */
.unit.hid .card{filter:brightness(.6) saturate(.72)}
.unit.hid .card::after{content:"";position:absolute;inset:0;z-index:4;pointer-events:none;
  background:#0a0712a1;mix-blend-mode:multiply}
/* 수라장에서는 효과 문구만 뺀다 — 62px 에서 문장은 읽히지 않는다. 나머지는 손패와 같다 */
.unit .c-text{display:none}
/* ── 키워드 상자 ───────────────────────────────────────────
   **작게 볼 때는 이름 밑줄 바로 아래**, 그 밑이 효과 문구다 (v157).
   줄이 하나 더 끼는 만큼 이름이 위로 올라간다 — 그래야 상자가 제 자리를 갖는다.
   꼴은 유형 표식(.c-type)과 같다. 카드 위에서 「상자에 담긴 낱말」은 한 가지 뜻이어야 한다 */
.c-kw{display:flex;justify-content:center;gap:2px;flex-wrap:wrap;z-index:2}
/* ⚠ **테두리가 있어야 상자로 읽힌다.** 검은 바탕만 깔면 어두운 일러스트 위에서 그냥 글씨가 된다 */
.kb{font-family:var(--mono);font-size:clamp(5px,4.1cqw,7px);line-height:1.5;
  letter-spacing:.04em;text-indent:.04em;padding:0 4px;border-radius:7px;
  background:#0b0908d4;border:1px solid #ffffff33;
  color:#efe6d6;text-shadow:0 1px 2px #000;white-space:nowrap}
.kb.g{color:#96dfa0} .kb.s{color:#9fd6ff} .kb.y{color:#e0c98a}
/* ⚠ `.kb.more` (말줄임 딱지)는 **v166 에 걷었다.** 그것도 딱지라 「둘까지」가 셋이 되어
   하서진에서 줄이 접히고 카드명이 얼굴 위로 올라왔다. 넘친 딱지는 그냥 안 보인다 → core.js `kbHTML()` */
/* 새로 얻은 키워드 — 카드 **밖**에 세로로 선다. 내 것은 아래, 상대 것은 위 (`gainedTags`).
   카드 안 딱지와 같은 꼴이되, 얻은 것이라 테를 초록으로 하고 「+」를 붙인다 */
/* 딱지 한 줄 높이 13px(글 7px × 1.55 + 테 2px) + 사이 2px — **세 줄까지 보이고 넘치면 구른다** */
.ugain{--gh:13px;position:absolute;left:50%;transform:translateX(-50%);z-index:4;
  display:flex;flex-direction:column;align-items:center;gap:2px;width:max-content;max-width:calc(100% + 4px);
  max-height:calc(var(--gh) * 3 + 4px);overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;
  scrollbar-width:none;-webkit-overflow-scrolling:touch;touch-action:pan-y}
.ugain::-webkit-scrollbar{display:none}
.unit[data-side="0"] .ugain{top:calc(100% + 3px)}
.unit[data-side="1"] .ugain{bottom:calc(100% + 3px);flex-direction:column-reverse}
.ugain .kb{flex:none;height:var(--gh);box-sizing:border-box;display:flex;align-items:center;
  font-size:7px;line-height:1;padding:0 5px;border-color:#6fcf9799;background:#0b0908eb;
  max-width:100%;overflow:hidden;text-overflow:ellipsis}
/* 당한 것(−점혈·−혼절)은 붉게 (v0.225) */
.kb.d{color:#ff8f80;border-color:#7d3c39}
/* 넘칠 때 — 먼 끝을 흐려 「더 있다」를 알린다. 내 것은 아래 끝, 상대 것은 위 끝이 먼 끝이다 */
.unit[data-side="0"] .ugain.more{-webkit-mask-image:linear-gradient(180deg,#000 72%,transparent);mask-image:linear-gradient(180deg,#000 72%,transparent)}
.unit[data-side="1"] .ugain.more{-webkit-mask-image:linear-gradient(0deg,#000 72%,transparent);mask-image:linear-gradient(0deg,#000 72%,transparent)}
.unit.sel .ugain{transform:translateX(-50%) translateY(5px)}   /* 고른 연이 5px 떠도 딱지는 제자리 */
/* 누를 수 있는 딱지 (상세보기) — 단추라도 꼴은 그대로다 */
button.kb{cursor:pointer;-webkit-tap-highlight-color:transparent;transition:.14s}
button.kb:hover{background:#1a1613ee;border-color:#ffffff59}
button.kb.on{background:var(--seal-deep);border-color:var(--seal);color:#f3e4e1}
/* 키워드는 없지만 효과 문구를 가진 연 — 수라장에서는 문구를 지우므로 가진 줄도 모르고 지나간다 */
.kb.e{color:#cbb6ff}
/* 카드에 적힌 값과 다른 수 — 오르면 초록, 깎이면 붉다 (v128).
   코스트는 뜻이 반대라(싼 쪽이 좋다) 위쪽 .c-cost 규칙을 그대로 둔다 */
.c-atk.up,.c-hp.up{color:#7dffb4;text-shadow:0 0 7px #4dffa08c,0 1px 2px #000}
.c-atk.dn,.c-hp.dn{color:#ff9a8e;text-shadow:0 0 7px #e8695f8c,0 1px 2px #000}
.c-hp.hurt{color:#ff6b5e;text-shadow:0 0 6px #00000099}
/* 새로 맺은 연 — 코스트 구슬 **바로 아래**에 노랑 NEW.
   붉은 점은 무슨 뜻인지 배워야 알지만 글자는 그냥 읽힌다 */
.c-new{position:absolute;left:4%;top:calc(4% + clamp(16px,19cqw,27px) + 1.2cqw);z-index:7;
  width:clamp(16px,19cqw,27px);text-align:center;
  font-family:var(--mono);font-weight:800;line-height:1.1;
  font-size:clamp(5.5px,4.8cqw,8.5px);letter-spacing:.04em;
  color:var(--chungi);text-shadow:0 1px 3px #000,0 0 8px #d4a84388;
  animation:newpulse 1.6s ease-in-out infinite}
@keyframes newpulse{50%{opacity:.5}}
.c-ar{position:absolute;bottom:3.5%;left:50%;transform:translateX(-50%);z-index:2;
  font-size:clamp(7px,7cqw,10px);font-weight:700;color:#9fd6ff;text-shadow:0 1px 3px #000}

/* 명운(왼쪽) — 패 — 황천(오른쪽) */
/* 판때기는 비운다 — 바탕 그림이 위아래 끝까지 이어져야 한다.
   덱·황천·패·본체는 제 배경을 갖고 있고, 최하단 줄만 불투명하게 남긴다 */
/* 판때기도 선도 두지 않는다 — 화면 전체에 깔린 그라데이션 그늘이 글자를 지킨다 */
/* 각성 후광은 **배경 바로 위**다 — 패·명운 더미·황천은 그 위에 선다 (v194).
   후광이 본체보다 훨씬 커서 위아래 줄까지 뻗는데, 자리 안 잡은 줄은 후광(positioned) 밑으로 깔린다 */
.tray{position:relative;z-index:1;
  flex:none;display:flex;gap:7px;padding:4px 8px;background:transparent;align-items:flex-end}
/* 상대 패는 본체와 같은 3칸 격자에 얹는다 — 가운데 칸에 놓아야 머리 바로 아래에 든 것처럼 보인다 */
.tray.foe{display:grid;grid-template-columns:1fr auto 1fr;align-items:start}
.tray.foe .pile.deck{grid-area:1/1;justify-self:start}
.tray.foe .ohand{grid-area:1/2;justify-self:center}
.tray.foe .pile.grave{grid-area:1/3;justify-self:end}
.tray.foe{border-bottom:1px solid var(--line-soft);align-items:flex-start;padding:3px 8px}
.tray.mine{border:0}
/* 더미는 장수만 읽히면 된다 — 작게 둘수록 수라장이 넓어진다.
   화면이 짧으면 연이 더미 줄과 겹쳐 버리므로 여기서 아낀 높이가 그대로 수라장으로 간다 */
.pile{flex:none;width:30px;aspect-ratio:63/88;border-radius:3px;position:relative;overflow:hidden;
  border:1px solid var(--line);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0}
.tray.foe .pile{width:26px}
.pile::before{display:none}
.pile.deck{background-color:#11151b;background-image:linear-gradient(#080a0b24,#080a0b52),url(assets/ui/pile_deck_back.webp?v=1);
  background-position:center;background-size:cover;background-repeat:no-repeat;border-color:#5d5548;
  box-shadow:2px 1px 0 #17191d,4px 2px 0 #0b0c0e,0 2px 7px #000b}
/* 황천은 죽은 자리다 — 검은 막을 한 겹 더 씌워 명운 더미와 한눈에 갈린다 (v148) */
.pile.grave{background-color:#08080a;background-image:linear-gradient(#000000a8,#000000cc),url(assets/ui/pile_grave_back.webp?v=1);
  background-position:center;background-size:cover;background-repeat:no-repeat;border-color:#413c3f;
  box-shadow:2px 1px 0 #101012,4px 2px 0 #080809,0 2px 7px #000c}
.pile.empty{opacity:.42}
.pile.grave{cursor:pointer} .pile.grave:hover{border-color:var(--seal)}
.pl-n{position:relative;z-index:1;font-size:12px;font-weight:800;line-height:1;font-variant-numeric:tabular-nums;
  text-shadow:0 1px 4px #000}
.tray.foe .pl-n{font-size:11px}
.pl-l{position:relative;z-index:1;font-size:6.5px;letter-spacing:.1em;color:var(--fg-faint);text-indent:.1em}
.tray.foe .pl-l{font-size:6px}
/* 상대 패 — 뒷면만 겹쳐 놓는다. 몇 장인지가 곧 정보다 */
/* 상대 패도 더미와 같은 높이로 낮춘다 — 이 줄이 높으면 더미만 줄여 봐야 수라장이 넓어지지 않는다 */
.ohand{min-width:0;max-width:100%;display:flex;justify-content:center;align-items:flex-start;padding-top:1px;height:37px}
.oc{flex:none;width:22px;aspect-ratio:63/88;border-radius:2px;border:1px solid #2d2740;margin-left:-9px;
  background-color:#11151b;
  background-image:linear-gradient(#080a0b1f,#080a0b47),url(assets/ui/pile_deck_back.webp?v=1);
  background-size:cover;background-position:center;
  box-shadow:0 1px 4px #0008}
.oc:first-child{margin-left:0}
/* 드러난 상대 패 — 뒷면 사이에서 혼자 앞면으로 선다. 겹치지 않게 조금 넓다 */
.oc.shown{width:31px;margin-left:-3px;border-color:#6b5a3a;background-image:none;cursor:pointer;
  box-shadow:0 0 0 1px #d4a84366,0 1px 5px #000a}
.oc.shown .card{width:100%;border-radius:1px}
.oc.shown .c-path,.oc.shown .c-type,.oc.shown .c-foot,.oc.shown .c-atk,.oc.shown .c-hp{display:none}
/* 손패도 같은 까닭으로 금빛 테가 위아래로 잘렸다 — 안쪽에 자리를 두고 바깥으로 되돌린다 */
.hand{flex:1;min-width:0;display:flex;gap:5px;overflow-x:auto;padding:7px 6px 5px;
  margin:-7px -6px -3px;
  scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;cursor:grab}
/* 패가 열 장 — **더 뽑으면 그대로 황천이다.** 한 장 쓰라는 말을 테로 한다 (2026-09-29).
   ⚠ `outline` 을 쓴다 — 이 상자는 가로로 굴러가는 자리(`overflow-x:auto`)라,
      `box-shadow: inset` 으로 두르면 브라우저에 따라 **테가 카드를 따라 흘러간다.**
      `outline` 은 굴러도 제자리에 선다.
   ⚠ 켜고 끄는 것은 `paintHandFull` 이 쥔다 — 뽑기 연출이 끝난 자리에서만 켜고,
      한 장이라도 내서 열 장 아래로 내려가면 그리면서 끈다 */
.hand.full{outline:2px solid #e2564d;outline-offset:-1px;border-radius:3px;
  animation:handfull 1s ease-in-out infinite}
@keyframes handfull{
  50%{outline-color:#ff9a90;background:#e2564d1f;box-shadow:0 0 14px #e2564d5c}}
@media (prefers-reduced-motion:reduce){
  .hand.full{animation:none;background:#e2564d1a}}
.hand.grabbing{cursor:grabbing;scroll-snap-type:none}
.hand.grabbing .hcard{pointer-events:none}
/* 스크롤막대는 어디에도 안 보인다 (v128) — 손패 아래에 떠 있던 7px 짜리 막대가
   게이지처럼 읽혔다. 밀어서 넘기는 자리는 카드가 잘려 보이는 것으로 이미 알 수 있다 */
.hand::-webkit-scrollbar{display:none}
.hcard{flex:none;width:60px;cursor:pointer;transition:transform .12s;position:relative;scroll-snap-align:center}
/* 양 끝 카드는 **끝에 붙어** 선다 (v0.229) — 가운데로 붙이면 첫 장이 명운 더미 쪽으로 반쯤 밀려 잘렸다 */
.hcard:first-child{scroll-snap-align:start}
.hcard:last-child{scroll-snap-align:end}
.hcard.sel{transform:translateY(-8px)}
.hcard.sel .card{box-shadow:0 0 0 2px var(--seal),0 0 16px #c4453a66}
/* 지금 낼 수 없는 카드 — 일러스트가 원래 어두워서 약하게 누르면 낼 수 있는 카드와 구별이 안 된다.
   색을 완전히 빼고 더 눌러 앉힌 뒤, 위에 어둠을 한 겹 덮어 확실히 갈라 놓는다 */
/* 지금 내공으로 낼 수 있는 패 — 초록으로 숨 쉰다. 무엇을 낼 수 있는지 세어 보지 않아도 보인다 */
.hcard.can .card{box-shadow:0 0 0 1.5px #6fcf97b0,0 0 10px #6fcf9755;animation:hcb 1.5s ease-in-out infinite}
@keyframes hcb{50%{box-shadow:0 0 0 2px var(--ok),0 0 15px #6fcf97a0}}
.hcard.sel.can .card{animation:none}
/* 내공이 모자라 못 내는 카드 — 예전에는 거의 검정이라 무슨 카드인지도 안 보였다 (v128).
   회색으로 물리되 그림과 글씨는 읽히게 둔다 */
.hcard.no .card{filter:grayscale(.92) brightness(.72) contrast(.94);opacity:.9}
.hcard.no .card::after{content:"";position:absolute;inset:0;z-index:5;pointer-events:none;background:#1a17204d}
.actbar{flex:none;display:flex;gap:8px;align-items:center;padding:11px 12px calc(11px + var(--bot-gap));
  background:var(--panel);border-top:1px solid var(--line-soft)}
.hint{flex:1;min-width:0;font-size:11px;color:var(--fg-mid);line-height:1.4}
.hint b{color:var(--seal)}
/* 하단 바의 오른쪽 끝. 전체보기가 그 왼쪽에 붙는다.
   ⚠ `margin-left:auto` 로 **제 손으로 오른쪽 끝까지 민다** (v162).
   수라에서는 재화도 뒤로가기도 이름표도 다 숨으므로, 밀어 줄 것이 아무것도 없다 —
   6px 만 두었더니 전체보기 옆에 붙어 왼쪽으로 쏠렸다. 엄지가 닿는 자리는 오른쪽이다 */
.endbtn{flex:none;margin-left:auto;margin-right:-4px;padding:9px 15px;min-height:38px;
  border:1px solid var(--seal);border-radius:var(--r-s);background:var(--seal-deep);
  color:#f3e4e1;font-size:12.5px;font-weight:600}
.endbtn[hidden]{display:none}
/* 눌러 뒀지만 아직 연출이 남았다 */
.endbtn.wait{opacity:.6}
.endbtn[disabled]{opacity:.42;background:var(--panel-2);border-color:var(--line);color:var(--fg-mid)}
.cbtn{flex:none;padding:9px 12px;border:1px solid var(--line);border-radius:var(--r-s);font-size:12.5px;color:var(--fg-mid)}
.logpane{position:absolute;left:0;right:0;bottom:0;max-height:52%;background:#100d0bf7;border-top:1px solid var(--line);z-index:12;display:none;flex-direction:column}
.logpane.on{display:flex}
.lh{display:flex;align-items:center;padding:8px 12px;border-bottom:1px solid var(--line-soft)}
.lh span{font-family:var(--mono);font-size:10px;letter-spacing:.18em;color:var(--fg-faint)}
.loglist{flex:1;overflow-y:auto;padding:8px 12px 14px;display:flex;flex-direction:column;gap:3px}
.lg{font-size:10px;line-height:1.55;color:var(--fg-mid)}
.lg.me{color:#bfe0d2} .lg.foe{color:#e8c4bb} .lg.sys{color:var(--fg-faint)}

.fieldmsg{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) scale(.95);z-index:14;
  padding:11px 20px;border-radius:var(--r-s);background:#1c1713f5;border:1px solid var(--line);
  font-size:13px;color:var(--fg);text-align:center;max-width:82%;line-height:1.5;pointer-events:none;
  opacity:0;transition:opacity .16s,transform .16s;box-shadow:0 10px 26px -10px #000}
.fieldmsg.on{opacity:1;transform:translate(-50%,-50%) scale(1)}
.fieldmsg b{color:var(--seal)}
.fieldmsg.w{border-color:#5c4220;color:var(--warn)}
/* 규칙 풀이는 아래에 한 칸 띄워 흐리게 — 왜 막혔는지 바로 읽히게 한다 */
.nsub{display:block;margin-top:7px;padding-top:7px;border-top:1px solid var(--line-soft);
  font-size:11px;line-height:1.6;color:var(--fg-mid);font-weight:400}
/* 차례가 넘어가면 수라장 한가운데에 한 번 크게 적는다 */
/* ⚠⚠ **차례 알림은 연출보다 위에 선다** (2026-10-03 제보 — 「혼절이 차례 위로 올라온다」).
   알림은 **판이 바뀌었다**는 말이라 무엇에도 가려지면 안 된다 —
   연출은 수라장의 일이고 알림은 그 위에서 하는 말이다.
   ⚠⚠ **번호만으로는 세 번 고쳐도 안 고쳐졌다.** `#tban` 이 `.battle-arena`(z:2)
      **안에 갇혀** 있었고 그 위의 `.screens` 가 z:1 이라, 뿌리에서 알림은 **1** 로 섰다.
      연출은 몸에 붙는 `fixed` 라 뿌리에서 16~19 다 — 70 을 줘도 질 수밖에 없었다.
      그래서 `ui.js` 의 `tbAnchor` 가 이것을 **몸(`body`)으로 내보낸다.**
   ⚠ 그래서 `fixed` 다. `absolute` 로 되돌리면 몸에 붙은 채 글 흐름을 따라가 자리가 틀어진다.
      선 자리(`top`)는 `tbAnchor` 가 수라장 네모를 **재서** 넣는다 — 여기 `top` 은 그 전의 밑값이다 */
/* ⚠⚠ **판 너비만큼만 차지한다 — `left:0;right:0` 으로 창을 가로지르지 않는다** (2026-10-14).
   `tbAnchor` 가 이것을 `body` 로 내보내므로 **판 바깥**이고, `zoom` 도 안 받는다.
   창을 가로지르게 두면 넓은 화면에서 **판이 아니라 창 한가운데**에 서고, 판이 창 가운데가
   아닌 때(사이드바·분할 화면) 띠만 혼자 엇나간다. 판 폭에 배율을 곱해 **판 위에 포갠다.** */
.turnban{position:fixed;left:50%;width:calc(var(--app-w) * var(--k));top:50%;z-index:70;
  display:flex;justify-content:center;
  pointer-events:none;opacity:0;transform:translate(-50%,-50%)}
/* ===== 차례 알림 — 귀면기와 명패 =====
   `turn_banner_{mine|foe}.webp` 는 768×256 다. 짧은 차례 문구에 맞춰 폭을 줄이고,
   단청 장식 대신 귀면기와의 눈·송곳니와 검은 기와 지붕을 한 덩어리로 쓴다.
   ⚠ 내 차례는 **청록**, 상대 차례는 **붉은빛** — 테두리 색으로 갈린다.
      글자를 그림에 그려 넣지 않았으므로 여기서 얹는다.
   ⚠ 아래 %값은 그림에서 잰 것이다. 그림을 갈면 이 값도 같이 잰다 */
/* ⚠ 띠가 `body` 로 나가 `zoom` 을 못 받으므로 **제 손으로 `--fxk` 를 곱한다** — 안 곱하면
   폰에서는 판의 70% 인 띠가 넓은 화면에서는 절반밖에 안 되어 혼자 쪼그라든다 */
.tbbx{position:relative;display:block;width:calc(min(var(--app-w) * .7,300px) * var(--fxk));aspect-ratio:3/1;
  background:url(assets/ui/turn_banner_mine.webp?v=2) center/100% 100% no-repeat;
  filter:drop-shadow(0 10px 26px #000a)}
.turnban.foe .tbbx{background-image:url(assets/ui/turn_banner_foe.webp?v=2)}
/* 귀면의 눈과 송곳니를 피해 가운데 검은 판에만 앉힌다 */
.tb-t{position:absolute;left:18%;right:18%;top:35%;bottom:24%;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--mjo);font-weight:800;
  /* 글자 크기는 **액자 폭**을 따라간다 — 좁은 화면에서 액자만 줄면 글자가 판 밖으로 넘친다 */
  font-size:clamp(14px,round(calc(var(--app-w) * .05), 1px),21px);letter-spacing:.16em;text-indent:.16em;line-height:1;
  color:#e9f2ef;text-shadow:0 2px 9px #000,0 0 14px #000}
.turnban.foe .tb-t{color:#f3ddd6}
/* 각성 — 차례 넘김과 **같은 자리**다. 다만 그림 액자를 쓴다 (v170).
   `dialog_awakening.webp` 는 2097×750 이고 글자를 얹을 판이 셋이다.
   ⚠ 아래 %값은 **그 그림에서 직접 잰 것**이다(어둡고 불투명한 칸을 줄마다 훑어서).
   그림을 갈아 끼우면 이 값도 다시 잰다 — 안 그러면 글자가 무늬 위로 올라앉는다 */
.turnban.awk{padding:0}
.awkbx{position:relative;display:block;
  /* 글자 크기를 **액자 폭**에 맞춘다(`cqw`) — 좁은 화면에서 액자만 줄고 글자가 그대로면 판 밖으로 넘친다 */
  container-type:inline-size;
  /* ⚠ 폭은 **%** 다. `96vw` 로 두었더니 창이 넓고 낮은 자리에서(앱 틀이 화면보다 훨씬 좁아진다)
     액자만 혼자 540px 로 서서 **틀 밖으로 삐져나갔다** — 인수인계 §8 의 그 덫이다 (v186) */
  width:min(96%,540px);aspect-ratio:2097/750;
  background:url(assets/ui/dialog_awakening.webp?v=1) center/100% 100% no-repeat;
  filter:drop-shadow(0 14px 34px #000c)}
/* ⚠ `.awkbx > span` 은 (0,1,1) 이라 `.aw-sub` (0,1,0) 보다 **촘촘하다.**
   여기에 `left/right` 를 두면 아래 개별 규칙이 못 이긴다 — 가로 자리는 낱낱이 정한다 */
.awkbx > span{position:absolute;display:flex;align-items:center;justify-content:center;
  text-align:center;white-space:nowrap}
/* 맨 위 작은 현판 — **다시 쟀다** (v186). 어두운 판의 속은 x 41.6~58.6% · **y 19.5~30.1%** 다.
   17.3~28.8% 에 얹어 두었더니 **위로 2%가 삐져나가** 용 머리 장식을 밟고,
   글자 상자(15px + 줄높이)가 판 속 높이(20px)보다 커서 아래로도 넘쳤다.
   ⚠ 판이 얕으므로 `line-height:1` 로 못을 박는다 — 줄높이가 기본이면 글자보다 상자가 먼저 넘친다.
   글꼴은 **100년체**(`--serif`)다. `--han` 은 붓글씨인데 그 글꼴에는 **한자밖에 없어서**
   「각성」 두 글자가 뒤의 명조로 떨어지고 있었다 — 액자 안에서만 결이 달라 보인 까닭이다 */
.aw-cap{left:0;right:0;top:19.8%;height:10.3%;font-family:var(--serif);
  font-size:clamp(8.5px,2.6cqw,12.5px);line-height:1;
  letter-spacing:.34em;text-indent:.34em;
  color:#f5e0ab;text-shadow:0 1px 4px #000,0 0 10px #d4a84366}
/* 가운데 넓은 판 — x 31~68%, y 35~55% */
.aw-name{left:0;right:0;top:33%;height:22%;font-family:var(--serif);font-weight:800;
  font-size:clamp(17px,5.6cqw,27px);letter-spacing:.14em;text-indent:.14em;
  color:#f8efdb;text-shadow:0 2px 10px #000,0 0 22px #d4a84366}
/* 아래 긴 판 — x 11~89%, y 61~85%. 여기만 두 줄까지 간다 */
.aw-sub{left:12%;right:12%;top:60%;height:26%;
  font-size:clamp(9.5px,3.1cqw,13.5px);line-height:1.42;white-space:normal;
  color:#dccfb6;text-shadow:0 1px 5px #000}
/* 상대 것은 붉은 쪽으로 반 발짝. 액자는 그대로 두고 **글자만** 기운다 —
   그림을 물들이면 금박까지 같이 죽는다 */
.turnban.awk.foe .aw-cap{color:#e8b2a6}
.turnban.awk.foe .aw-name{color:#f6ded6;text-shadow:0 2px 10px #000,0 0 22px #a8524466}
/* 효과가 터진 자리에 무엇이 걸렸는지 띄운다 — 점혈·산공·내공 같은 것들 */
/* 같은 자리에 여러 개가 뜨면 먼저 뜬 것이 한 칸씩 위로 밀려 올라간다(--row).
   그래야 효과 표기와 피해 표기가 서로를 덮지 않는다. 두 줄까지만 세우고 그 위는 걷는다 */
/* ⚠⚠ **이것도 `body` 에 붙는 `position:fixed` 라 `zoom` 을 못 받는다** (2026-10-14).
   그래서 `scale(var(--fxk))` 를 제 손으로 건다 — 기획자 제보 「호법·내공 상승·피해·피격
   이런 태그 박스가 대응이 안 된다」가 이 자리다. 안 걸면 판만 커지고 딱지는 폰 크기로 남는다.
   ⚠ 겹칠 때 한 칸씩 밀어 올리는 `--row` 의 27px 도 **같이 곱한다** — 안 곱하면 딱지는
     커졌는데 밀리는 폭은 그대로라 두 줄이 서로를 깔고 앉는다.
   ⚠ `scale` 은 `translate` **뒤**에 둔다. 앞에 두면 미는 폭까지 한 번 더 곱해진다 */
.fxpopw{position:fixed;z-index:18;pointer-events:none;
  transform:translate(-50%,calc(-50% - var(--row,0) * 27px * var(--fxk))) scale(var(--fxk));
  transition:transform .2s cubic-bezier(.2,.8,.3,1)}
.fxpopw.out{transition:transform .2s,opacity .2s;opacity:0}
.fxpop{font-size:12.5px;font-weight:800;white-space:nowrap;letter-spacing:.02em;
  padding:3px 10px;border-radius:11px;background:#0c0a09f0;border:1px solid var(--line);
  color:var(--fg);text-shadow:0 1px 3px #000;box-shadow:0 5px 16px -6px #000}
.fxpop.bad{color:#ff8f80;border-color:#5f2c26}
.fxpop.good{color:#8fe0a8;border-color:#2c5a3c}
/* 회복은 좋은 일 가운데서도 **가장 초록**이다 — 같은 자리에 초록 오오라가 함께 돈다 (v179) */
.fxpop.heal{color:#7fe0a8;border-color:#2c5a3c;text-shadow:0 0 10px #4fd08a66}
.fxpop.ki{color:#eccb7a;border-color:#5f4a1f}
/* 「1차례 남음」 — 값이 아니라 남은 횟수라 눈에 덜 띄어야 한다 */
.fxpop.dim{color:#b6ada0;border-color:#3b3731;font-weight:700;font-size:11px}
.boom{position:fixed;z-index:17;pointer-events:none;width:calc(74px * var(--fxk));height:calc(74px * var(--fxk));margin:calc(-37px * var(--fxk)) 0 0 calc(-37px * var(--fxk));border-radius:50%;
  background:radial-gradient(circle,#fff2e0 0%,#f0b070 26%,#c4453a88 52%,transparent 72%)}
/* 검선 — 벤 자리에 남는 한 줄. 카드 밖으로 조금 삐져나가야 「그었다」로 읽힌다 */
/* **한가운데를 지난다** (v155). v147 에 좌상단으로 7·9px 밀어 두었던 것을 걷었다 —
   숫자와 겹치는 것보다 줄이 카드 복판에서 벗어나 보이는 쪽이 더 어색했다 */
.slashfx{position:fixed;z-index:17;pointer-events:none;overflow:visible}
/* 막대의 **오른쪽 끝**을 카드 우상단 꼭지점에 두고 그 점을 축으로 돌린다.
   각도는 카드마다 다르다(대각선) — 자바스크립트가 잰다.
   ⚠ `margin-top` 은 막대 두께의 **절반을 음수로** 적는다 — 회전축(`transform-origin:100% 50%`)의
   세로를 카드 위쪽 모서리(y=0)에 정확히 올려놓기 위한 값이다. 이게 어긋나면 줄이 아래로 처진다.
   두께를 고치면 이 값도 같이 고친다 (지금 10px → −5px).
   **가운데가 두껍고 양끝이 얇다** — clip-path 로 방추형으로 깎는다. 칼자국은 균일한 막대가 아니다 */
.slashfx > i{position:absolute;right:0;top:0;height:10px;margin-top:-5px;display:block;
  transform-origin:100% 50%;
  background:linear-gradient(90deg,transparent 0,#cfe8ff 8%,#fff 50%,#cfe8ff 92%,transparent 100%);
  filter:drop-shadow(0 0 6px #ffffffee) drop-shadow(0 0 16px #bfe0ffcc) drop-shadow(0 0 30px #7fb4ee77);
  clip-path:polygon(0 50%,14% 30%,38% 6%,62% 6%,86% 30%,100% 50%,86% 70%,62% 94%,38% 94%,14% 70%)}
/* 본선과 길이·각도가 같은 얇은 잔광. 선을 하나 더 긋지 않고 칼날의 속도층으로 읽히게 한다. */
.slash-echo{position:absolute;right:0;top:0;height:4px;margin-top:-2px;display:block;
  transform-origin:100% 50%;
  background:linear-gradient(90deg,transparent,#e8f5ff 13%,#fff 48%,#a9d4ff 86%,transparent);
  filter:drop-shadow(0 0 3px #fff) drop-shadow(0 0 10px #8ec8ffcc);
  clip-path:polygon(0 50%,20% 18%,78% 18%,100% 50%,78% 82%,20% 82%)}
/* 파편은 작은 칼가루처럼 흩어진다. 검선의 길이나 각도에는 손대지 않는다. */
.slash-chip{position:absolute;left:50%;top:50%;width:8px;height:2px;margin:-1px 0 0 -4px;
  background:linear-gradient(90deg,#fff,#a9d4ff88,transparent);filter:drop-shadow(0 0 3px #d8edff);
  animation:slashChip .42s var(--delay) cubic-bezier(.12,.7,.25,1) both}
@keyframes slashChip{0%{opacity:0;transform:translate(0,0) scaleX(.25) rotate(var(--rot))}
  18%{opacity:.9}100%{opacity:0;transform:translate(var(--dx),var(--dy)) scaleX(.75) rotate(var(--rot))}}
.slash-bloodmist{position:absolute;left:50%;top:50%;width:52px;height:34px;transform:translate(-50%,-50%) rotate(-18deg);
  border-radius:48% 56% 42% 61%;background:radial-gradient(ellipse,#a51f1c80 0 18%,#76110e52 38%,transparent 70%);
  filter:blur(1.2px);animation:slashBloodMist .48s ease-out forwards}
@keyframes slashBloodMist{0%,13%{opacity:0;transform:translate(-50%,-50%) rotate(-18deg) scale(.35)}
  28%{opacity:.75;transform:translate(-50%,-50%) rotate(-18deg) scale(1)}100%{opacity:0;transform:translate(-50%,-50%) rotate(-18deg) scale(1.3)}}
.slash-bloodcut{position:absolute;left:50%;top:50%;height:5px;margin:-2.5px 0 0 0;display:block;
  transform-origin:50% 50%;transform:translate(-50%,-50%) rotate(var(--slash-deg));text-decoration:none;
  background:linear-gradient(90deg,transparent,#65100d 10%,#bd352b 42%,#7f1712 70%,transparent);
  filter:drop-shadow(0 1px 1px #260403);clip-path:polygon(0 52%,13% 28%,42% 8%,72% 26%,100% 48%,72% 72%,38% 94%,12% 72%);
  animation:slashBloodCut .52s ease-out forwards}
@keyframes slashBloodCut{0%,14%{opacity:0;transform:translate(-50%,-50%) rotate(var(--slash-deg)) scaleX(.35)}
  28%{opacity:.9;transform:translate(-50%,-50%) rotate(var(--slash-deg)) scaleX(1)}
  70%{opacity:.62}100%{opacity:0;transform:translate(-50%,-50%) rotate(var(--slash-deg)) scaleX(1.05)}}
.slash-blood{position:absolute;left:50%;top:50%;width:7px;height:3px;margin:-1.5px 0 0 -3.5px;border-radius:70% 25% 65% 30%;
  background:#b92e25;box-shadow:0 0 2px #4d0908;animation:slashBlood .43s var(--bdelay) cubic-bezier(.12,.68,.28,1) both}
.slash-blood:nth-of-type(even){width:4px;height:4px;border-radius:50%;background:#851713}
@keyframes slashBlood{0%{opacity:0;transform:translate(0,0) scale(.35) rotate(var(--brot))}
  20%{opacity:.92}100%{opacity:0;transform:translate(var(--bdx),var(--bdy)) scale(.72) rotate(var(--brot))}}
/* 베인 자리 — 붉은 딤드가 한 겹 얹혔다 걷힌다.
   **그림이 비쳐야 한다** — 통째로 덮으면 무엇이 맞았는지가 안 보인다 */
.bleed::after{content:"";position:absolute;inset:0;z-index:8;pointer-events:none;border-radius:3px;
  /* multiply 로 깔면 어두운 카드에서는 그냥 어두워지기만 한다 — 그대로 덮어 붉은 기를 준다 */
  background:radial-gradient(130% 95% at 50% 45%,#ff5242 0%,#c4271b 58%,#7a1109 100%);
  animation:bleedf .52s ease-out forwards}
@keyframes bleedf{0%{opacity:0}16%{opacity:.46}100%{opacity:0}}
.orb{position:fixed;z-index:17;pointer-events:none;width:calc(20px * var(--fxk));height:calc(20px * var(--fxk));margin:calc(-10px * var(--fxk)) 0 0 calc(-10px * var(--fxk));border-radius:50%;
  background:radial-gradient(circle,#fff 0%,#9fd6ff 40%,#4e9cc466 70%,transparent)}
/* 터진 진(陣) — 수라장 한가운데에 선 동안 테를 두르고 숨을 쉰다.
   **누구의 진인지를 색으로 가른다** (v140) — 내 것은 초록, 상대 것은 붉다.
   금빛은 각연자 몫으로 비워 둔다. 한 색이 두 가지를 뜻하면 둘 다 안 읽힌다 */
.formfx .card{box-shadow:0 0 0 2px var(--fc),0 0 22px 3px var(--fg2),0 10px 30px -10px #000;
  animation:formb 1.1s ease-in-out infinite}
.formfx.mine{--fc:#7fdca0c4;--fg2:#3f9e6366;--fc2:#bff3d4;--fg3:#3f9e6388}
.formfx.foe {--fc:#e8918ac4;--fg2:#a8342c66;--fc2:#f6c5c0;--fg3:#a8342c88}
@keyframes formb{50%{box-shadow:0 0 0 2px var(--fc2),0 0 30px 5px var(--fg3),0 10px 30px -10px #000}}
/* 이름과 효과 — 카드 **밑에** 붙인다 (2026-09-30 기획자가 정함).
   ⚠ 카드 그림만으로는 92px 짜리가 1.2 배로 서 봐야 글씨가 안 읽힌다. 무엇이 무슨 일을
      했는지가 이 연출의 요점인데 그것을 못 읽으면 설 까닭이 없다.
   ⚠ 카드가 `scale` 로 커지므로 이 글씨도 같이 커진다 — 그만큼 작게 잡아 둔다.
   ⚠ 너비는 카드(92px)보다 넓게 잡고 가운데를 맞춘다. 좁으면 두 자씩 끊어져 읽힌다 */
.formcap{position:absolute;left:50%;top:100%;transform:translateX(-50%);
  width:150px;margin-top:5px;text-align:center;pointer-events:none;
  display:flex;flex-direction:column;gap:2px}
.formcap b{font-family:var(--serif);font-size:8.5px;font-weight:800;letter-spacing:.02em;
  color:var(--fc2,#e8dcc6);text-shadow:0 1px 3px #000,0 0 8px #000}
.formcap span{font-size:7px;line-height:1.45;color:#ddd3c2;
  text-shadow:0 1px 3px #000,0 0 8px #000}
/* 카드가 떠 있는 동안 빈 자리가 어디였는지 남겨 둔다 — 되돌아갈 자리가 보여야 눈이 따라간다 */
.unit.firing .card{opacity:.22;filter:grayscale(.6)}
.unit.firing{box-shadow:inset 0 0 0 1px #ffffff2e}

.result{position:absolute;inset:0;z-index:30;background:#100d0bf7;display:flex;flex-direction:column;align-items:center;
  justify-content:safe center;gap:15px;padding:26px;text-align:center}
/* 길흉 동전 */
/* ===== 심안녀 — 첫 접속 안내 =====
   강제 진행이라 화면 전체를 덮는다. 아무 데나 누르면 다음 말로 넘어간다 */
.tuto{position:fixed;inset:0;z-index:95;background:#05040788;
  cursor:pointer;-webkit-tap-highlight-color:transparent;overflow:hidden;
  /* 발 높이와 말칸 너비 — 말칸은 이 둘로 자기 자리를 잡는다 */
  /* --tu-bar 는 하단바 높이 — tutoStart() 가 재서 넣는다.
     말칸은 바 바로 위에 서고, 심안녀는 그 위에 선다 */
  --tu-bot:calc(var(--tu-bar,0px) + 6px); --tu-bw:min(var(--app-w),520px);
  /* 말칸은 **진행 중 튜토리얼과 같은 한 벌**(`.tg-bubble`)이다 (v0.238).
     그 한 벌이 하단바 높이를 `--tg-bar` 로 받으므로 여기서 이어 준다 */
  --tg-bar:var(--tu-bar,0px)}
.tuto[hidden]{display:none}
/* ===== 전신 심안녀 — **실루엣** (v0.238) =====
   말은 말칸의 상반신이 한다. 전신은 뒤에 그림자처럼 서서 자리를 채운다.
   까맣게 죽이되 테두리에 인장빛을 옅게 둘러, 어둠 속에 잠긴 사람으로 읽히게 한다 */
.tu-face{position:absolute;left:50%;transform:translateX(-50%);
  bottom:calc(var(--tu-bot) + var(--tu-bw) * 0.30);
  width:min(calc(var(--app-w) * .86),400px);max-height:calc(var(--app-h) * .6);object-fit:contain;object-position:bottom;
  filter:brightness(.44) saturate(.6) contrast(1.04)
         drop-shadow(0 0 30px #7c86b63d) drop-shadow(0 14px 38px #000d);
  pointer-events:none}
/* 말칸 — 하단바 바로 위. 나머지 꼴은 `.tg-bubble` 이 그대로 맡는다 */
.tu-bub{bottom:calc(var(--tu-bot) + 2px)}
.tg-text>span{display:block;width:100%}
.tu-next{position:absolute;right:5%;bottom:12%;z-index:4;font-size:12px;color:#d8c9a8;
  animation:tunext 1.2s ease-in-out infinite}
@keyframes tunext{50%{transform:translateY(4px);opacity:.45}}
@media (max-width:380px){ .tu-face{width:calc(var(--app-w) * .8)} }
/* ===== 진행 중 튜토리얼 말풍선 =====
   시작 대화창보다 작게 떠서 게임 화면을 남기고, 손끝과 빛테가 클릭할 한 자리만 가리킨다. */
.tguide{position:fixed;inset:0;z-index:96;pointer-events:none;--tg-bar:0px}
.tguide[hidden]{display:none}
.tg-shade{position:absolute;inset:0;z-index:0;background:transparent;pointer-events:auto}
/* 짚는 자리가 없을 때만 판 전체를 덮는다 — 있을 때는 빛테의 그림자가 **그 바깥만** 어둡게 한다 (v0.229) */
.tguide.bare .tg-shade{background:#050407a8}
/* 길게 누르기를 가르치는 동안에는 덮개를 뚫는다 (v0.238) — 손이 진짜로 카드에 닿아야 한다.
   엉뚱한 곳을 눌러도 엔진이 튜토리얼 줄과 맞지 않는 수를 물리므로 판이 어긋나지 않는다 */
.tguide.hold .tg-shade{pointer-events:none}
.tg-focus,.tg-hit{position:fixed;border-radius:12px}
/* 옮겨 앉을 때만 미끄러진다 (`tgGlide` 가 0.36초만 걸어 준다).
   ⚠ `box-shadow` 는 섞지 않는다 — 9999px 짜리 그림자라 무겁고, 숨쉬기(`tgfocus`)와도 부딪힌다 */
.tg-focus.glide,.tg-hand.glide{transition:left .3s cubic-bezier(.3,.8,.3,1),top .3s cubic-bezier(.3,.8,.3,1),
  width .3s cubic-bezier(.3,.8,.3,1),height .3s cubic-bezier(.3,.8,.3,1),opacity .22s ease-out .08s}
/* 겹쳐 넘어가는 옛 얼굴 — 새 얼굴 위에 잠깐 겹쳐 섰다 스민다 (`tuImg`).
   ⚠ **자리는 건드리지 않는다.** 복제는 원본의 class 를 그대로 물려받아
      (`.tg-bust` 의 left·bottom·크기·clip-path) 정확히 같은 자리에 선다 —
      여기서 left/top/width 를 다시 적으면 그 자리를 망가뜨린다.
   ⚠ `tuImg` 는 **자리를 띄운 그림(absolute·fixed)만** 겹친다. 흐름 속에 선 그림을
      복제하면 한 칸을 더 차지해 화면이 밀린다 */
/* ⚠ 참(`transition-duration`)은 `tuImg` 가 그림마다 따로 넣는다 — 상반신은 짧게,
   전신은 길게. 여기 적힌 .17s 는 안 넣었을 때의 기본값이다.
   ⚠ 결은 `ease-in-out` 이다 — `ease-out` 은 옛 그림이 앞머리에서 훅 사라져, 긴 참을 주어도
   「겹쳐 넘어간다」가 아니라 「끊고 바뀐다」로 보인다 */
.tu-fade{pointer-events:none;opacity:1;transition:opacity .17s ease-in-out;z-index:3}
.tg-focus{z-index:2;border:2px solid #d7b465;
  box-shadow:0 0 0 9999px #050407b0,0 0 0 5px #d7b46528,0 0 24px 7px #d7b46578;
  animation:tgfocus 1.25s ease-in-out infinite;pointer-events:none}
.tg-hit{z-index:4;margin:0;padding:0;border:0;background:transparent;pointer-events:auto;
  -webkit-tap-highlight-color:transparent;cursor:pointer}
@keyframes tgfocus{50%{box-shadow:0 0 0 9999px #050407b0,0 0 0 8px #d7b46518,0 0 34px 10px #d7b465a0}}
.tg-hand{position:fixed;z-index:5;height:auto;pointer-events:none;
  filter:drop-shadow(0 8px 15px #000c) drop-shadow(0 0 8px #7966d999);
  animation:tghand .86s ease-in-out infinite}
@keyframes tghand{50%{transform:translate(-4px,6px)}}
/* 화면 꼭대기에 붙은 것을 짚을 때 — **뒤집어 아래에서 위로** (v0.247).
   `rotate` 는 `transform` 과 따로 도는 성질이라, 위의 까딱임이 살아 있는 채로 돌아간다.
   까딱임도 함께 뒤집는다 — 목표 쪽으로 다가갔다 물러나야 짚는 시늉이 된다 */
.tg-hand.up{rotate:180deg;animation-name:tghandup}
@keyframes tghandup{50%{transform:translate(4px,-6px)}}
.tg-bubble{position:absolute;z-index:3;left:50%;bottom:calc(var(--tg-bar) + 8px);transform:translateX(-50%);
  width:var(--tg-bw);aspect-ratio:1400/467;padding:0;
  background:url(assets/ui/dialog_simannyeo.webp?v=1) center/100% 100% no-repeat;
  filter:drop-shadow(0 15px 22px #000d);pointer-events:none;
  /* ⚠ 대화창 그림(1400×467)은 **밑에 83px 이 투명 여백**이라, 그려진 액자의 밑선은
     칸 밑에서 높이의 17.8% 위다. 상반신을 그 선에서 자르려고 그 여백 높이를 재어 둔다.
     (83/467 × 467/1400 = 너비의 0.0593배) */
  --tg-bw:min(var(--app-w),520px); --tg-foot:calc(var(--tg-bw) * .0593)}
.tg-bubble::before{display:none}
/* 전신 대화창과 같은 한지·금속 액자 위에 상반신이 걸친다.
   위로는 그대로 솟되, **액자 밑선 아래는 잘라 낸다** — 상반신 그림에는 여백이 없어
   그냥 두면 액자를 넘어 수라장 위로 흘러내린다 */
.tg-bust{position:absolute;z-index:2;left:-12px;--tg-lift:8px;bottom:var(--tg-lift);
  width:150px;height:202px;object-fit:contain;object-position:bottom;
  clip-path:inset(0 0 calc(var(--tg-foot) - var(--tg-lift)) 0);
  filter:drop-shadow(0 9px 18px #000d)}
.tg-copy{position:absolute;z-index:3;left:29%;right:8%;top:20%;bottom:14%}
.tg-name{position:absolute;left:8%;top:-13%;display:flex;align-items:center;justify-content:center;min-width:86px;height:27px;padding:0 17px;
  border:1px solid #796544;clip-path:polygon(7px 0,calc(100% - 7px) 0,100% 7px,100% calc(100% - 7px),calc(100% - 7px) 100%,7px 100%,0 calc(100% - 7px),0 7px);
  background:linear-gradient(180deg,#211f22f8,#0d0d10f8);box-shadow:inset 0 0 0 1px #c2a9771f,0 3px 8px #000b;
  font-family:var(--serif);font-size:clamp(10px,round(calc(var(--app-w) * .027), 1px),13px);font-weight:800;letter-spacing:.08em;color:#e7d4a8;text-shadow:0 2px 6px #000}
/* 전신 대화창(`.tu-text`)과 **같은 글꼴·같은 정렬**이다 — 한 사람이 하는 말이 자리마다
   다르게 보이면 안 된다. 까닭은 `.tu-text` 에 적어 두었다 */
.tg-text{position:absolute;left:8%;right:0;top:20%;bottom:0;margin:0;display:flex;align-items:flex-start;padding-top:1px;
  font-family:var(--mjo);
  font-size:clamp(10px,round(calc(var(--app-w) * .027), 1px),13px);line-height:1.6;color:#eee7de;text-shadow:0 2px 6px #000}
/* 말만 하는 단계 — 어디를 눌러도 넘어간다. 짚는 자리는 빛테로만 (v0.229) */
.tguide.say .tg-shade{cursor:pointer}
/* ===== 뜰 때 한 박자 (2026-09-30) =====
   말풍선과 심안녀가 **툭 나타나던 것**을 걷었다. 아래에서 살짝 올라오며 스민다.
   ⚠⚠ **안 보이는 것을 기본값으로 두지 않는다.** 처음에는 `opacity:0` 으로 두고
      `.in` 이 붙을 때만 보이게 했는데, `.in` 은 `requestAnimationFrame` 이 건다 —
      **창이 뒤에 있거나 화면이 바쁘면 그 프레임이 안 돌아** 말풍선도 빛테도
      영영 안 보였다(§5-6). 서막과 수라 한복판에서 대화가 통째로 사라진 것이 이것이다.
      그래서 **기본은 보이는 것**이고, `.in` 은 **들어오는 시늉만** 얹는다.
      시늉이 빠져도 잃는 것은 연출뿐이다 */
.tguide.in .tg-bubble{animation:tgbin .24s cubic-bezier(.2,.9,.3,1) both}
@keyframes tgbin{from{opacity:0;transform:translateX(-50%) translateY(10px)}
                 to  {opacity:1;transform:translateX(-50%) translateY(0)}}
/* ⚠ **빛테와 손가락에는 손대지 않는다.** 저마다 제 숨쉬기(`tgfocus`·`tghand`)를 돌리고 있어,
   스미는 연출을 얹으려면 두 애니메이션을 합쳐 적어야 한다 — 한 자만 어긋나도
   **금빛 테가 깜빡이지 않는 자리가 생긴다.** 실제로 그렇게 났다(2026-09-30 제보).
   들이는 품에 비해 얻는 것이 없다. 말풍선 하나만 스미면 족하다 */
@media (prefers-reduced-motion:reduce){
  .tguide.in .tg-bubble{animation:none}}
.tg-focus[hidden],.tg-hit[hidden],.tg-hand[hidden]{display:none}
/* 짚는 자리가 화면 아래쪽이면 대화창이 위로 선다 — 누를 곳을 가리지 않게.
   ⚠ 심안녀 상반신은 기본 대화 액자 위로 솟는다. 맨 위에 붙이면 머리가 잘리므로 그만큼 내려 잡는다. */
.tg-bubble.top{top:calc(var(--top-gap) + 64px);bottom:auto}
.tg-bubble.top::before{display:none}
/* 튜토리얼 잠금판 — 짚어 주는 자리가 안 떠 있는 동안만 판을 덮는다 (v0.230).
   덮개(#tfocus 75)보다 아래, 그 밖의 모든 것보다 위다 */
#tblock{position:fixed;inset:0;z-index:74;background:transparent;
  -webkit-tap-highlight-color:transparent;touch-action:none}
#tblock[hidden]{display:none}
/* 수라 안의 한마디 — 덮개(#tfocus) 위에 얹는다. 눌리지 않는다 */
#tfocus .tf-bub{position:fixed;z-index:2}
#tfocus .tf-bub[hidden]{display:none}
@media (max-width:380px){
  .tg-bust{width:122px;height:164px;left:-8px;--tg-lift:5px}
  .tg-copy{left:30%;right:7%;top:19%}
  .tg-name{left:7%;top:-10%;min-width:76px;height:24px;padding:0 13px}
  .tg-text{top:20%}
}
/* ===== 대화 (v0.229) =====
   밑에서 올라오는 창. **화면을 다 덮지 않는다** — 혈투 칸 절반쯤까지(65dvh)만 올라와
   뒤에 강호가 남아 있는 것이 보인다. 자판이 오르면 dvh 가 줄어 창도 같이 줄어든다 */
.cveil{position:fixed;inset:0;z-index:87;background:#05040766;
  opacity:0;transition:opacity .24s;-webkit-tap-highlight-color:transparent}
.cveil[hidden]{display:none}
.cveil.in{opacity:1}
.cpane{position:fixed;z-index:88;left:0;right:0;bottom:0;
  height:min(calc(var(--app-h) * .65),620px);min-height:300px;
  display:flex;flex-direction:column;overflow:hidden;
  border:1px solid var(--line);border-bottom:0;border-radius:17px 17px 0 0;
  background:var(--panel);box-shadow:0 -18px 44px #000d;
  padding-bottom:var(--bot-gap);
  transform:translateY(100%);transition:transform .26s cubic-bezier(.2,.9,.3,1)}
.cpane[hidden]{display:none}
.cpane.in{transform:none}
/* 손잡이 — 밑에서 올라온 창이라는 표시. 끌지는 않는다 */
.cgrip{flex:none;width:38px;height:4px;margin:7px auto 0;border-radius:2px;background:#ffffff26}
.ch{flex:none;display:flex;align-items:center;gap:8px;padding:9px 14px 8px}
.ch h3{margin:0;flex:1;font-family:var(--serif);font-size:15px;font-weight:800;letter-spacing:.06em;color:var(--fg)}
.ch-x{flex:none;width:30px;height:30px;display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line);border-radius:var(--r-s);background:#0d0b11a6;color:var(--fg-mid);
  font-size:13px;-webkit-tap-highlight-color:transparent}
.ch-x:active{border-color:var(--seal);color:var(--fg)}
.clog{flex:1;min-height:0;overflow-y:auto;padding:4px 14px 10px;
  display:flex;flex-direction:column;gap:12px}
.cnone{margin:auto;font-size:12px;color:var(--fg-faint)}
.cmsg{display:flex;gap:9px}
/* 초상화는 명호에서 쓰는 그 얼굴이다 — 여기서는 동그랗게 */
.clog .face{flex:none;width:32px;height:32px;border-radius:50%;border:1px solid var(--line)}
.cm-b{flex:1;min-width:0}
.cm-h{display:flex;align-items:baseline;gap:5px}
/* ⚠ **`.cmsg` 안으로 가둔다** (v0.282). 그냥 `.cm-n` 으로 두었더니 **대전의 무명자 이름**과
   한 이름을 다투었다 — 이 규칙이 뒤에 있어 이겼고, 수라장에서 「무명자」가 「무…」로 잘렸다.
   채팅 말칸 안의 이름만 줄인다 */
.cmsg .cm-n{font-size:12.5px;font-weight:700;color:var(--fg);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;max-width:46%}
.cm-g{font-family:var(--mono);font-size:10px;color:var(--fg-faint)}
/* 년월일과 시각 — 오른쪽 끝에 옅게 */
.cm-t{margin-left:auto;flex:none;font-family:var(--mono);font-size:9.5px;color:var(--fg-faint);white-space:nowrap}
.cm-x{margin:3px 0 0;font-size:13px;line-height:1.65;color:var(--fg-mid);
  white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere}
.cmsg.me .cm-n{color:var(--seal)}
/* 알림 — 누가 한 말이 아니다. 가운데에 옅게 한 줄 */
.cmsg.sys{justify-content:center;text-align:center;font-size:11px;line-height:1.6;color:var(--fg-faint)}
.cbar{flex:none;display:flex;align-items:flex-end;gap:8px;padding:9px 12px 10px;
  border-top:1px solid var(--line-soft)}
.cin{flex:1;min-width:0;max-height:76px;padding:9px 11px;resize:none;overflow-y:auto;
  border:1px solid var(--line);border-radius:12px;background:#0d0b11;color:var(--fg);
  font-family:inherit;font-size:13px;line-height:1.5}
.cin:focus{outline:none;border-color:var(--seal)}
.cin:disabled{opacity:.5}
.csend{flex:none;height:37px;padding:0 14px;border-radius:12px;border:1px solid var(--seal);
  background:#1a1119;color:#f0dcc8;font-size:12.5px;font-weight:700;
  -webkit-tap-highlight-color:transparent;transition:opacity .14s}
.csend:disabled{opacity:.38;border-color:var(--line);color:var(--fg-faint)}
.csend:not(:disabled):active{transform:scale(.96)}
/* 막힌 동안 남은 때 — 입력칸 바로 위 */
.cnote{flex:none;margin:0;padding:0 14px 7px;text-align:center;
  font-size:10.5px;line-height:1.5;color:var(--warn)}
.cnote:empty{display:none}
/* 패에서 꺼내 보이는 카드 — 앞면으로 크게, 아래에 무엇이 걸렸는지 */
/* ⚠ 이것도 `body` 에 붙는 `position:fixed` 라 `zoom` 을 못 받는다 — `--fxk` 를 제 손으로 건다.
   ⚠ 카드와 밑의 글딱지를 **한 덩이로** 키운다. 따로 키우면 둘 사이 틈(`gap`)만 안 늘어
     넓은 화면에서 글딱지가 카드에 달라붙는다 */
.revwrap{position:fixed;z-index:16;pointer-events:none;
  transform:translate(-50%,-50%) scale(var(--fxk));
  display:flex;flex-direction:column;align-items:center;gap:9px}
.rev-card{width:96px}
.rev-lab{font-family:var(--serif);font-size:15px;font-weight:800;letter-spacing:.2em;text-indent:.2em;
  padding:4px 13px;border-radius:2px;background:#0c0a10e8;border:1px solid var(--line);
  text-shadow:0 2px 7px #000}
.rev-lab.bad{color:#f0a89f;border-color:#7d3c39}
.rev-lab.good{color:#9fe0b6;border-color:#2f5c42}
/* 시전 자리에 선 카드 밑의 상자 — 연끊기·연부름 (v0.225) */
.castlab{display:block;width:max-content;margin:6px auto 0}
.castlab.top{margin:0 auto 6px}
/* 상대가 뽑고 버리는 카드 — 뒷면만 보인다 */
/* ⚠ 판 바깥(`body`)이라 `--fxk` 를 제 손으로 곱한다 — §`--fxk` 머리말 */
.backfly{position:fixed;z-index:15;pointer-events:none;width:calc(38px * var(--fxk));aspect-ratio:63/88;border-radius:2px;
  border:1px solid #2d2740;background-color:#11151b;
  background-image:linear-gradient(#080a0b1f,#080a0b47),url(assets/ui/pile_deck_back.webp?v=1);
  background-size:cover;background-position:center;box-shadow:0 3px 10px #000a}
.coinfly{position:fixed;z-index:16;pointer-events:none;display:flex;flex-direction:column;align-items:center;gap:4px;
  opacity:0;transform:translate(-50%,-46%) scale(.94);transition:opacity .18s ease,transform .22s ease}
.coinfly.entered{opacity:1;transform:translate(-50%,-50%) scale(1)}
.coinfly.leaving{opacity:0;transform:translate(-50%,-58%) scale(.96)}
.cf-wheel{display:flex;align-items:center;gap:clamp(8px,calc(var(--app-w) * .025),14px)}
.cf-choice{position:relative;width:clamp(82px,calc(var(--app-w) * .23),108px);aspect-ratio:1;opacity:.55;transform:scale(.91);
  filter:saturate(.58) brightness(.66);transition:opacity .07s linear,transform .07s ease,filter .07s linear}
.cf-choice img{display:block;width:100%;height:100%;object-fit:contain;filter:drop-shadow(0 7px 8px #000b)}
.cf-choice.is-focus{opacity:1;transform:scale(1.045);filter:saturate(1.12) brightness(1.1)}
.cf-choice-good.is-focus{filter:saturate(1.15) brightness(1.12) drop-shadow(0 0 8px #d6bd68aa)}
.cf-choice-bad.is-focus{filter:saturate(1.12) brightness(1.08) drop-shadow(0 0 8px #a84d49aa)}
.cf-choice.is-final{transform:scale(1.09)}
.cf-result-ring{position:absolute;left:50%;top:50%;width:88%;height:88%;border:2px solid #dfc56a;border-radius:50%;
  opacity:0;transform:translate(-50%,-50%) scale(.72);box-shadow:0 0 13px #dfc56aaa,inset 0 0 10px #dfc56a55}
.cf-choice-bad .cf-result-ring{border-color:#b85a50;box-shadow:0 0 13px #b85a50aa,inset 0 0 10px #b85a5055}
.cf-choice.is-final .cf-result-ring{animation:cfresult .58s cubic-bezier(.14,.72,.24,1) .15s both}
@keyframes cfresult{0%{opacity:0;transform:translate(-50%,-50%) scale(.72)}35%{opacity:.95}100%{opacity:0;transform:translate(-50%,-50%) scale(1.48)}}
.cf-particle{position:absolute;left:50%;top:50%;width:3px;height:11px;border-radius:3px;background:#ead78a;
  box-shadow:0 0 6px currentColor;opacity:0;transform:translate(-50%,-50%) rotate(var(--a)) translateY(-18px);
  animation:cfparticle .52s cubic-bezier(.15,.72,.25,1) both}
.cf-choice-bad .cf-particle{background:#c36b61}
@keyframes cfparticle{0%{opacity:0;transform:translate(-50%,-50%) rotate(var(--a)) translateY(-18px) scaleY(.45)}25%{opacity:.9}100%{opacity:0;transform:translate(-50%,-50%) rotate(var(--a)) translateY(calc(-1 * var(--d))) scaleY(.16)}}
.cf-lab{min-height:22px;font-family:var(--serif);font-size:14px;font-weight:800;letter-spacing:.06em;
  color:#f2e7d2;text-shadow:0 2px 8px #000;opacity:0;transform:translateY(4px)}
.coinfly.revealed .cf-lab{animation:cflabel .28s ease-out both}
@keyframes cflabel{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}
.coinfly.bad .cf-lab{color:#e5b7af}
.rwd{display:flex;align-items:center;gap:11px}
.coinbig{width:46px;height:46px;object-fit:contain;filter:drop-shadow(0 0 9px #d4a84366)}
.rwd-n{font-size:27px;font-weight:800;color:var(--chungi);font-variant-numeric:tabular-nums;letter-spacing:.02em}
.rwd-l{margin:0;font-size:11.5px;color:var(--fg-faint);letter-spacing:.06em}

/* 승패 — **조선100년체로 굵게** 찍는다 (v155). 한자 붓글씨(勝利·敗北)에서 한글로 바꿨다.
   ⚠ 100년체에는 굵은 판이 아예 없어서 여기만은 **브라우저가 만드는 굵기를 그대로 쓴다.**
   본문에서 그것을 금한 까닭은 작은 글자에서 획이 뭉개지기 때문인데, 여기는 38px 한 낱말이라 상하지 않는다.
   그래서 `--sans`(700 자리가 굵은명조로 넘어간다)가 아니라 **`--story` 를 직접 집는다** */
.result h2{margin:0;font-family:var(--story);font-size:38px;font-weight:700;letter-spacing:.14em;text-indent:.14em;
  text-shadow:0 4px 22px #000c}
.result.w h2{color:var(--ok)} .result.l h2{color:var(--danger)} .result.d h2{color:var(--fg-mid)}
/* 한자로 되돌릴 자리 — 붓글씨는 획이 굵어 가짜 굵기를 얹지 않는다 */
.result h2.han{font-family:var(--han);font-weight:400;letter-spacing:-.02em;text-indent:-.02em}
.result p{margin:0;font-size:12px;color:var(--fg-mid);font-family:var(--mono)}
/* 아래 .result p 보다 뒤에 와야 한다 — 거기서 색과 고정폭 글꼴이 덮어씌워진다 */
.result p.rsay{margin:-4px 0 2px;font-size:12px;line-height:1.85;color:var(--fg-faint);font-family:var(--sans);letter-spacing:.03em;text-align:center}

/* 멀리건 */
/* 멀리건은 **세로 가운데**에 선다 (v128). 위로 붙여 두었더니 여섯 장 아래가 통째로 비어
   화면이 반만 쓰인 것처럼 보였다. 카드가 많아 넘치면 그때만 위에서부터 흐른다 */
.mull{position:absolute;inset:0;z-index:25;background:#100d0bf7;display:flex;flex-direction:column;
  justify-content:center;
  padding:calc(10px + var(--top-gap)) 14px calc(16px + var(--bot-gap));gap:13px}
.mull h3{margin:0;font-family:var(--serif);font-size:19px;font-weight:700;letter-spacing:.08em;text-align:center}
/* 멀리건 시계 (v0.342) — 선공·후공 바로 밑. 아래 줄의 차례 시계는 장막 뒤라 안 보인다.
   ⚠ 빛깔 규칙은 `.tbar` 와 **같은 것**을 쓴다(20초 노랑·10초 빨강) — 두 시계가 따로 놀면 안 된다.
   ⚠ 숫자에 `transition` 을 걸지 않는다. `color` 가 `var()` 에서 올 때 크로미움이
      처음 값을 물고 놓지 않는다 — 게이지만 바뀌고 숫자가 그대로였던 그 버릇이다 (v139) */
.mclk{--tc:#7fdca0;flex:none;width:min(210px,62%);margin:-4px auto 0;
  display:flex;flex-direction:column;align-items:stretch;gap:3px}
.mclk.warn{--tc:var(--warn)}
.mclk.hot {--tc:var(--danger)}
.mclk-n{align-self:center;font-family:var(--mono);font-size:12px;font-weight:700;
  font-variant-numeric:tabular-nums;line-height:1;letter-spacing:.06em;color:var(--tc)}
.mclk-g{height:3px;border-radius:2px;background:#ffffff1a;overflow:hidden}
.mclk-g > i{display:block;height:100%;width:100%;border-radius:2px;
  background:linear-gradient(90deg,color-mix(in srgb,var(--tc) 55%,#000),var(--tc));
  transition:width .22s linear,background .25s}
.mturn{font-size:27px!important;font-weight:900!important;letter-spacing:.26em!important;text-indent:.26em;
  color:var(--fg);text-shadow:0 2px 20px #0009}
/* **각연자의 금빛 테가 잘리지 않게 안쪽에 자리를 둔다** (v134).
   그 테는 카드 바깥으로 퍼지는 box-shadow 라, overflow 를 가진 그릇이 그대로 잘라 먹었다.
   테두리가 세 변만 이어지고 한 변이 없어 보이던 것이 이 때문이다.
   padding 으로 벌리고 같은 만큼 margin 으로 되돌려 자리는 그대로 둔다 */
.mgrid{flex:0 1 auto;min-height:0;overflow-y:auto;scrollbar-width:none;
  display:grid;grid-template-columns:repeat(3,1fr);gap:8px;align-content:center;
  padding:9px;margin:-9px}
.mgrid::-webkit-scrollbar{display:none}
.mcard{position:relative;cursor:pointer;transition:transform .12s,opacity .15s}
/* 물릴 수 없는 카드 — 후공에게 주는 주과. 눌러도 아무 일 없다.
   ⚠ **눌리지 않는다는 것을 눌러 보기 전에 알려 준다** (v186).
   전에는 아무 표도 없어, 눌러 보고 나서야 「이건 안 되는구나」를 알았다.
   고른 카드(`.x`)와 **같은 꼴**로 덮되 글씨만 다르다 — 같은 자리에 두 가지 모양을 만들지 않는다.
   다만 빛깔은 도장 빛이 아니라 흐린 회색이다. 이것은 **내가 고른 것이 아니라 못 고르는 것**이다 */
/* 고른 카드는 **내보낼 것**이라 깊이 죽이고, 못 고르는 카드는 **그냥 못 고를 뿐**이라 덜 죽인다 (v193).
   둘을 같은 .4 로 두었더니 주과가 너무 어두워 무슨 카드인지 읽히지 않았다.
   ⚠ 주과는 **눌러서 펼쳐 볼 수는 있다** — 손이 닿는 자리이므로 커서도 손가락이다 */
.mcard.fixed{cursor:pointer;opacity:.74}
.mcard.x{opacity:.4;transform:scale(.94)}
.mcard.fixed:active{transform:scale(.97)}
.mcard.fresh{animation:fresh 1s cubic-bezier(.2,1.5,.4,1) both}
@keyframes fresh{from{transform:translateY(18px) scale(.8);opacity:0}to{transform:none;opacity:1}}
.mcard.x::after,.mcard.fixed::after{content:"교체";position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--serif);font-size:13px;font-weight:700;color:var(--seal);
  background:#000000a8;border:1px solid var(--seal);border-radius:3px}
/* 덮개도 밝힌다 — 글씨는 잠긴 아이콘(`.fc-lk`)과 같은 빛깔, 바탕은 카드가 비칠 만큼만 */
.mcard.fixed::after{content:"교체 불가";font-size:11.5px;letter-spacing:.02em;font-weight:700;
  color:#cfc4b4;border-color:#4d4657;background:#0000007a;
  text-shadow:0 1px 3px #000}

/* 수진(手盡) — 명운이 비어 뽑을 것이 없다. 뽑기와 같은 길로 오되 **뒷면**이다 (v128).
   명운 더미(.pile)와 같은 등가죽을 써서 「저기서 온 것」으로 읽히게 한다 */
.tireback{border-radius:4px;border:1px solid #4a4130;
  background:url(assets/ui/pile_deck_back.webp?v=1) center/cover no-repeat,#151119;
  box-shadow:0 10px 26px #000c,0 0 0 1px #00000080;
  filter:grayscale(.45) brightness(.72)}

/* 교서 — 갈래 단추. 한 줄로 흐르고 넘치면 옆으로 민다 (v132) */
.hptabs{display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;padding:0 0 2px;margin:0 0 4px}
.hptabs::-webkit-scrollbar{display:none}
.hptab{flex:none;padding:6px 12px;border:1px solid var(--line);border-radius:2px;
  font-size:11.5px;color:var(--fg-mid);white-space:nowrap;background:var(--panel);
  -webkit-tap-highlight-color:transparent}
.hptab:hover{color:var(--fg)}
.hptab.on{background:var(--seal-deep);border-color:var(--seal);color:#f3e4e1}

/* 덮개 */
/* ⚠ 카드 상세(`#vInfo`)는 **멀리건(`.mull`, z 25) 위**에 떠야 한다 (v193).
   멀리건에서 주과를 눌러 펼치는 길이 생겼는데, 20 으로는 멀리건 뒤에 깔려 아무것도 안 보였다 */
#vInfo{z-index:28}
.veil{position:absolute;inset:0;z-index:20;background:#100d0bf7;display:none;flex-direction:column;
  padding:calc(10px + var(--top-gap)) 16px calc(20px + var(--bot-gap))}
.veil.on{display:flex;animation:fade .2s ease}
.vh{position:relative;z-index:2;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:10px;margin-bottom:13px;flex:none}
.vh h3{grid-area:1/2;justify-self:center;text-align:center;margin:0;font-family:var(--serif);
  font-size:16px;font-weight:700;letter-spacing:.06em;
  max-width:calc(var(--app-w) * .52);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 상세 창은 아래에 바를 하나 두고 닫기를 뒤로가기 자리(왼쪽 끝)에 앉힌다 — 화면의 뒤로가기와 같은 손놀림이 된다 */
.veil.vfooted{padding-bottom:0}
.vfoot{flex:none;display:flex;align-items:center;gap:8px;margin:13px -16px 0;
  padding:15px 16px calc(15px + var(--bot-gap));
  background:var(--panel);border-top:1px solid var(--line-soft)}
/* 닫기는 바 전체를 차지한다 — 왼손이든 오른손이든 엄지가 닿는 곳에 있다 */
.vclose{flex:1;min-height:38px;display:flex;align-items:center;justify-content:center;
  font-size:13.5px;letter-spacing:.2em;text-indent:.2em;color:var(--fg-mid)}   /* 38px 은 하단 바의 뒤로가기와 같은 키 */
.vclose:hover{color:var(--fg)}
.vx{grid-area:1/3;justify-self:end;color:var(--fg-mid);font-size:13px;padding:5px 9px;border:1px solid var(--line);border-radius:var(--r-s)}
.vx:hover{color:var(--fg);border-color:var(--seal)}
/* ⚠ **가로는 잠근다** (v192). `overflow-y` 만 정하면 가로축은 `visible` 이 `auto` 로 바뀐다.
   10봉을 열면 각연자의 금빛 테(`.engaura::after{inset:-5px}`)가 칸 밖으로 5px 뻗어
   **가로 스크롤막대가 떠올랐고, 그것이 하단의 게이지처럼 보였다.**
   수라장에서 v148 에 같은 덫을 밟았다(`.board`) — 이번에는 창 쪽이다.
   테가 잘리지 않게 좌우로 7px 을 벌리고 같은 만큼 되돌린다(`.mgrid` 와 같은 수법) */
/* ⚠⚠ **세로도 똑같이 벌린다** (2026-10-05 기획자 제보 — 「결연에서 각연자 획득하고
   최종 결과 보는 화면에서도 위에가 잘려, 빛이」). 위의 가로 막음과 **같은 덫의 다른 축**이다.
   `overflow-y:auto` 는 **제 안쪽 테에서 그대로 잘라낸다** — 맨 윗줄 각연자의 금빛이
   위로 뻗다가 직선으로 끊겼다. 멀리건(`.mgrid`)은 진작 네 방향을 다 벌려 두었는데
   (`padding:9px;margin:-9px`) 이 창만 가로뿐이었다.
   ⚠ **얼마나 벌리나** — 금테가 가장 밝을 때 `0 0 15px 3px`(`engb` 50%)이라 18px 까지 뻗는다.
     다만 그만큼 당기면 머리글(`.vh{margin-bottom:13px}`)과 바닥 바를 파고든다.
     그래서 **10px** 이다 — 눈에 보이는 속심을 다 담고 자리는 안 건드린다.
     빛의 맨 끝 옅은 자락은 남지만 그것은 직선으로 끊겨 보이지 않는다.
   ⚠ `padding` 은 자르는 테 **안쪽**이라 그만큼 빛이 설 자리가 되고, 같은 만큼의 음수 여백이
     그 벌어진 몫을 되돌려 **글과 카드의 자리는 그대로**다 (`.mgrid` 와 같은 수법).
   ⚠ 굴려 내리면 가운뎃줄은 자르는 테에 닿으므로 그 자리에서는 잘린다 — 굴리는 틀의 숙명이고,
     가로축도 그렇게 두었다. 처음 보이는 **맨 윗줄**이 안 잘리는 것이 이 자리의 할 일이다 */
.vb{position:relative;flex:1;min-height:0;
  overflow-y:auto;overflow-x:hidden;scrollbar-width:none;
  padding-inline:7px;margin-inline:-7px;
  padding-block:10px;margin-block:-10px;
  display:flex;flex-direction:column;gap:13px}
.vb::-webkit-scrollbar{display:none}
/* ===== 세로 가운데에 서는 창 (v187) =====
   버릴 카드 고르기는 **멀리건과 같은 일**이다 — 패를 펼쳐 놓고 고른다.
   그런데 멀리건은 가운데에 서고 이쪽만 위에 붙어 있었다. 같은 손놀림은 같은 자리에서 한다.
   `flex:0 1 auto` 라 **카드가 적으면 가운데에 모이고, 넘치면 그 자리에서 스크롤**한다
   (멀리건 `.mgrid` 와 같은 얼개다). 스크롤 막대는 숨긴다 — 검은 화면에 흰 막대가 튄다.
   ⚠ **각연자의 금빛 테가 잘리지 않게** 안쪽에 자리를 두고 같은 만큼 되돌린다(`.mgrid` §1773 과 같은 까닭) */
.veil.mid{justify-content:center}
.veil.mid .vb{flex:0 1 auto;scrollbar-width:none;padding:9px;margin:-9px}
.veil.mid .vb::-webkit-scrollbar{display:none}
.veil.mid .vb > .grid{align-content:center}
/* 창 본문은 세로 flex 인데 안이 넘치면 형제들이 밀려 줄어든다 — 찾기 줄이 0px 로 짜부라져
   입력칸이 카드 위로 삐져나오고 종수 글자와 겹쳤다. 스크롤되는 칸에서는 아무도 줄어들면 안 된다 */
.vb > *{flex:none}
/* 세로만 브라우저에 넘기고 가로 제스처는 우리가 받는다 — 이게 없으면 모바일에서 넘김이 죽는다 */
#iBody{touch-action:pan-y}
#iBody img{-webkit-user-drag:none;user-select:none;-webkit-touch-callout:none}
/* 연보에서는 좌우로 넘긴다 */
.varr{position:absolute;top:50%;transform:translateY(-50%);z-index:3;width:34px;height:52px;
  display:flex;align-items:center;justify-content:center;font-size:13px;color:var(--fg-mid);
  background:#0b0908cc;border:1px solid var(--line);border-radius:var(--r-s);backdrop-filter:blur(2px)}
.varr:hover{color:var(--fg);border-color:var(--seal)}
.varr.l{left:4px} .varr.r{right:4px}
.varr[hidden]{display:none}
@media (max-width:420px){.varr{width:28px;height:46px;opacity:.82}}
.rstage{flex:1;min-height:0;display:flex;flex-direction:column;align-items:center;justify-content:safe center;gap:15px}
.rone{width:min(208px,calc(var(--app-w) * .62));position:relative}
/* 첫 장을 덮는 패 뒷면 (v0.309) — 수라에서 쓰는 그 그림을 카드 자리에 그대로 얹는다.
   ⚠ `center/100% 100%` 로 **꽉 채운다** — `cover` 로 두면 카드 비율과 어긋나 테두리가 잘린다.
   ⚠ `.engaura` 가 함께 붙으면 젖히기 전에 금빛이 샌다 — 각연자가 나왔다는 귀띔이다 */
/* ⚠ `pointer-events:none` 를 빼지 말 것 — 뒷면이 `.tapz`(젖히는 손) 위에 서 있어
   그냥 두면 **손가락을 삼켜 아무리 눌러도 안 젖혀진다**
   ⚠⚠ `.rone` 을 앞에 붙여 **무게를 올려 둔다.** 뒤에 오는 `.engaura` 가 같은 무게로
      `position:relative` 와 제 애니메이션을 얹어, 그냥 `.rback` 으로 두면
      **각연자일 때만 뒷면이 사라지고 내려가지도 않는다.** 실제로 그렇게 났다 */
/* ⚠ `z-index` 는 카드 얼굴의 「NEW」 딱지보다 높아야 한다 — 낮으면 젖히기도 전에
   딱지가 뒷면 위로 비쳐 **새 연인지 아닌지가 먼저 새어 나간다** */
.rone .rback{position:absolute;inset:0;z-index:9;border-radius:3px;pointer-events:none;
  background:url(assets/ui/pile_deck_back.webp?v=1) center/100% 100% no-repeat,#151119;
  box-shadow:0 6px 22px #000000a6}
.rone .rback.engaura{box-shadow:0 0 0 2px #ffe9a8,0 0 13px 2px #ffd25fcc,0 0 30px 6px #fff3c866,0 6px 22px #000000a6}
/* 스르륵 내려간다 — 밑으로 빠지면서 옅어진다 */
.rone .rback.go{animation:rbackdown .56s cubic-bezier(.36,.02,.2,1) forwards}
@keyframes rbackdown{
  18%{transform:translateY(-5%) rotate(-.6deg)}
  100%{transform:translateY(124%) rotate(1.2deg);opacity:0}}
@media (prefers-reduced-motion:reduce){
  .rone .rback.go{animation-duration:.2s}
  @keyframes rbackdown{100%{transform:translateY(124%);opacity:0}}}
.pop{animation:pop .42s cubic-bezier(.2,1.5,.4,1)}
@keyframes pop{from{transform:scale(.74) rotateY(20deg);opacity:0}to{transform:none;opacity:1}}
.eburst{animation:eb 1.1s ease-out}
@keyframes eb{0%{box-shadow:0 0 0 0 #d4a843cc}70%{box-shadow:0 0 42px 12px #d4a84300}100%{box-shadow:0 0 0 0 #d4a84300}}
/* 연진 전환 — 카드샵 §3.2 */
.dust{animation:dust 1.1s ease-in forwards}
/* 수라장에서 쓰는 짧은 판 — 결연은 한 장을 천천히 보여 주지만, 판에서는 다음 수가 기다린다 */
.dust.q{animation-duration:.6s}
/* ⚠ `@keyframes dust` 는 **아래 「스러진 연의 먼지」 자리 한 곳**에만 둔다 (2026-10-03).
   여기 있던 옛 벌을 걷었다 — 두 벌이면 나중 것이 이겨서, 고쳤는데 안 바뀌는 자리가 된다 */
.rcount{font-family:var(--mono);font-size:11px;letter-spacing:.18em;color:var(--fg-faint)}
.rhint{font-size:11.5px;color:var(--fg-mid);text-align:center;line-height:1.6}
.rhint.jin{color:var(--jin)}
/* 누르라는 말은 **덮였을 때나 젖힌 뒤나 한 가지 얼굴**이다 — 같은 말, 같은 깜빡임.
   자리마다 다르게 굴면 같은 손짓인 줄을 모른다 */
.rhint.tap{animation:revtap 1.5s ease-in-out infinite}
@keyframes revtap{50%{opacity:.34}}
@media (prefers-reduced-motion:reduce){.rhint.tap{animation:none}}
.trow.tap{width:100%;text-align:left;cursor:pointer}
.trow.tap:hover{background:#ffffff0a}
/* 확률표의 각연자 — 이름만으로는 누구인지 모른다. 얼굴을 붙이고 누르면 그 카드가 펼쳐진다.
   카드 그림은 위쪽에 얼굴이 오도록 그려져 있어 top 을 물린다 */
.trow.ofa{align-items:center;gap:10px}
.trow.ofa .n{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.oface{flex:none;width:34px;height:34px;border-radius:var(--r-s);
  background:center 18%/150% no-repeat;border:1px solid var(--line-soft);
  background-color:#14111a}
.oface[data-none]{background-image:linear-gradient(150deg,#2a2233,#171320)}
/* 각연자는 금빛과 흰빛이 함께 돈다 — 한 장씩 보는 화면과 건너뛴 화면에서 같은 표를 쓴다 */
.engaura{position:relative;border-radius:3px;
  box-shadow:0 0 0 2px #ffe9a8,0 0 13px 2px #ffd25fcc,0 0 30px 6px #fff3c866;
  animation:engglow 1.9s ease-in-out infinite}
@keyframes engglow{
  50%{box-shadow:0 0 0 2px #fffdf2,0 0 19px 4px #ffdf86,0 0 44px 10px #fff6d688}}
.engaura::after{content:"";position:absolute;inset:-5px;border-radius:5px;pointer-events:none;
  background:radial-gradient(60% 50% at 50% 50%,#fff2c02e,transparent 72%)}
.gstamp{position:relative}
.tapz{position:absolute;inset:0;z-index:1}
/* 한 봉에서 나오는 장수(PACK)에 맞춰 칸을 나눈다.
   다섯 칸으로 못 박아 두면 세 장을 뽑았을 때 오른쪽 두 칸이 빈 채 남아 카드가 쭈그러든다.
   칸 수는 그리는 쪽이 `--g` 로 알려 준다 */
/* ⚠ **`minmax(0,1fr)` 이라야 한다** (v192). `1fr` 만 적으면 칸은 **카드의 최소 너비 아래로 못 줄어든다** —
   다섯 칸이 21px 넘쳐 가로 스크롤막대가 떠올랐고, 그것이 하단의 게이지처럼 보였다.
   `minmax(0,…)` 이 그 바닥을 풀어 준다. 격자를 새로 짤 때마다 이 한 줄을 본다 */
.g5{display:grid;grid-template-columns:repeat(var(--g,5),minmax(0,1fr));gap:6px}
@media (max-width:380px){.g5{grid-template-columns:repeat(min(var(--g,5),4),minmax(0,1fr))}}
.jinbox{border:1px solid #4a4133;border-radius:var(--r-s);padding:10px 12px;background:#1f1a14}
.jinbox h4{margin:0 0 6px;font-family:var(--mono);font-size:10px;letter-spacing:.16em;color:var(--jin);text-transform:uppercase}
.jinbox ul{margin:0;padding-left:16px;font-size:11.5px;color:var(--fg-mid);line-height:1.8}
.jinbox b{color:var(--jin);font-family:var(--mono)}

.detail{display:flex;flex-direction:column;gap:13px;align-items:center}
.dfull{width:100%;max-width:300px;aspect-ratio:63/88;border-radius:3px;overflow:hidden;
  border:1px solid var(--line);position:relative;cursor:pointer;align-self:center}
/* 원본 일러 — 받는 동안은 숨고 밑에 깔린 작은 판이 보인다 (v0.228) */
.dimg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .22s}
.dimg.on{opacity:1}
/* 큰 그림 위에 얹는 표기. 작게 볼 때와 같은 배지를 쓰되 크기는 큰 화면에 맞춰 따로 잡는다 */
.dover{position:absolute;inset:0;pointer-events:none;container-type:inline-size;
  transition:opacity .18s}
.dfull.bare .dover{opacity:0}
/* 그림만 보는 자리 — 그림 밖은 전부 검다. **어디를 눌러도 닫힌다** (v158에도 그대로다).
   세로로 셋을 쌓는다: 위 여백(타이틀이 얹힌다) · 그림 · 닫기 단추.
   그림은 `flex:1` 인 가운데 칸의 한가운데에 서므로, 단추가 아래를 먹는 만큼 저절로 위로 올라간다 */
.artfull{position:fixed;inset:0;z-index:90;background:#000;cursor:zoom-out;
  display:flex;flex-direction:column;align-items:stretch;
  padding:calc(var(--top-gap) + 8px) 12px calc(12px + var(--bot-gap))}
.af-stage{flex:1;min-height:0;display:flex;align-items:center;justify-content:center}
.artfull img{max-width:100%;max-height:100%;object-fit:contain;display:block}
.artfull .af-none{width:min(calc(var(--app-w) * .92),520px);max-height:100%;aspect-ratio:63/88;border-radius:3px}
/* 전체 보기 낙관은 **강호의 실제 로고**(`#mHan`)를 따른다.
   강호는 가운데 놓인 `.app` 안에서 `zoom:var(--k)` 으로 커지지만, 전체 보기 창은
   `body` 에 붙는 고정 화면이다. 그래서 판의 왼쪽 여백과 배율을 함께 셈해야 같은 자리에 선다.
   누르면 그림과 똑같이 닫힌다(겉틀이 받는다). */
.af-mark{align-self:flex-start;display:block;
  width:calc(clamp(72px,calc(var(--app-w) * .22),100px) * var(--k));height:auto;
  margin:calc((var(--top-gap) + 18px) * var(--k) - var(--top-gap) - 8px) 0 0
    calc((var(--view-w) - var(--app-w) * var(--k)) / 2 + 17px * var(--k) - 12px);
  opacity:.82;filter:brightness(0) invert(1)
    drop-shadow(0 1px 7px #000) drop-shadow(0 0 16px #a97cff22);
  pointer-events:none;user-select:none}
/* 닫기 — **다른 창과 같은 꼴**이다 (v187). 여기만 알약 단추라 혼자 달라 보였다.
   바 전체를 차지한다(`.vfoot` + `.vclose` 와 같은 치수) — 왼손이든 오른손이든 엄지가 닿는다 */
.af-x{flex:none;align-self:stretch;margin:12px -12px calc(-12px - var(--bot-gap)) -12px;
  min-height:38px;padding:15px 16px calc(15px + var(--bot-gap));
  display:flex;align-items:center;justify-content:center;
  background:var(--panel);border:0;border-top:1px solid var(--line-soft);
  font-size:13.5px;letter-spacing:.2em;text-indent:.2em;color:var(--fg-mid);transition:color .14s}
.af-x:hover,.af-x:active{color:var(--fg)}
/* 아래쪽 딤 — **작은 카드보다 옅게 깐다** (v158).
   작은 카드(.c-veil)의 값을 그대로 가져왔더니 큰 화면에서는 그림 아래 절반이 통째로 검게 죽었다.
   글씨가 큰 만큼 덜 깔아도 읽힌다. 다 걷으면 밝은 그림에서 이름이 묻히므로 없애지는 않는다 */
.dover::before{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,#00000047 0 10%,transparent 22% 46%,#0000008c 72%,#000000bf 100%)}
.dover .c-cost,.dover .c-atk,.dover .c-hp{width:clamp(26px,10.5cqw,36px);font-size:clamp(14px,5.8cqw,20px)}
.dover .c-path{width:clamp(27px,11cqw,38px);top:3.2%;right:3.2%}
.dover .c-eng{left:4%;top:calc(4% + clamp(26px,10.5cqw,36px) + 1.2cqw);
  width:clamp(26px,10.5cqw,36px);font-size:clamp(11px,4.4cqw,15px)}
/* 큰 그림 위의 이름과 효과 문구 — 작은 카드와 같은 자리, 큰 글씨 */
.dover .c-foot{left:7%;right:7%;bottom:calc(3.4cqw + clamp(26px,10.5cqw,36px) + 6px);gap:4px}
.dover .c-name{font-size:clamp(15px,5.4cqw,22px);line-height:1.25}
.dover .c-name::after{margin-top:4px}
.dover .c-text{font-size:clamp(11px,3.6cqw,14px);line-height:1.6;min-height:1.6em;-webkit-line-clamp:7}
/* 유형(권속·각연자·초식…)은 **작은 카드와 같은 자리** — 코스트와 도 문양 사이, 위 가운데다 (v157).
   v126~v156 에는 혼자 아래 가운데에 앉아 있어 큰 카드와 작은 카드의 배치가 갈렸다 */
.dover .c-type{top:3.4%;max-width:44%;padding:2px 12px;border-radius:11px;
  font-family:var(--mjo);font-weight:800;font-size:clamp(10px,3.2cqw,13px);
  letter-spacing:.14em;text-indent:.14em;line-height:1.5;
  color:#e7dfd1;background:#0b0908d9;border:1px solid var(--line);text-shadow:0 1px 3px #000}
/* 딱지는 작은 카드와 **같은 자리** — 이름 밑줄 바로 아래다 (v158).
   다만 여기서는 눌러서 풀이를 편다. `.c-foot` 이 pointer-events:none 이라 이 줄만 되살린다 */
.dover .c-kw{gap:5px;pointer-events:auto}
.dover .kb{font-size:clamp(10px,3.1cqw,12.5px);padding:1px 10px;border-radius:11px;
  border-color:var(--line);background:#0b0908ee}
.craftb{display:flex;align-items:center;justify-content:center;gap:10px;padding:12px;
  border:1px solid var(--jin);border-radius:var(--r-s);background:#1c1a2699;color:var(--fg);transition:.16s}
.craftb:hover{background:#232735;box-shadow:0 0 16px #7c86b633}
.craftb.no{opacity:.45}
.cr-l{font-size:13px;font-weight:700;letter-spacing:.04em}
.cr-v{font-size:12.5px;font-weight:700;color:var(--jin);font-variant-numeric:tabular-nums}
.craftn{margin:0;text-align:center;font-size:11px;color:var(--fg-faint)}
/* 맺기 창은 하단 재화 바를 덮는다 — 가진 연진을 여기 한 번 더 적는다 */
.crhave{display:flex;align-items:center;justify-content:center;gap:5px;position:relative;
  font-size:11.5px;color:var(--fg-mid)}
/* 보유액은 무엇으로 치르는지에 따라 색이 다르다 — 연진은 초록, 천기는 금빛 */
.crhave b{font-family:var(--mono);color:var(--jin);font-weight:700}
.crhave b.gold{color:var(--chungi)}
.craftn.short{color:var(--warn)}
.fbtn.no{opacity:.45}
.fout{position:absolute;left:50%;top:-2px;transform:translate(-50%,0);pointer-events:none;z-index:8;
  font-family:var(--mono);font-size:13px;font-weight:800;white-space:nowrap;
  color:var(--danger);text-shadow:0 2px 6px #000}
.fout.jin{color:var(--jin)}
.fout.up{color:var(--ok)}
.dkws{display:flex;flex-wrap:wrap;gap:6px;justify-content:center}
/* 눌러서 풀이를 펴는 단추다 — 손가락이 닿게 36px 을 확보한다 */
.dkw{font-size:12.5px;font-weight:700;letter-spacing:.06em;padding:0 14px;min-height:36px;border-radius:var(--r-s);
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--seal);background:#c4453a18;border:1px solid #c4453a55;transition:.14s}
/* 추가 효과(대전에서 붙은 것) — 오른 것은 초록, 깎인 것은 붉다 */
.dkw.up{border-color:#2f5c42;color:#9fe0b6;background:#12241a}
.dkw.dn{border-color:#5c3230;color:#e6a9a2;background:#241615}
.dbase{display:block;font-family:var(--sans);font-size:10px;color:var(--fg-faint);letter-spacing:.02em;margin-top:1px}
/* 명호의 계정 자리 */
.linkbox{display:flex;flex-direction:column;gap:9px}
.social-links{display:flex;flex-direction:column;gap:8px}
.social-row{min-height:52px;display:flex;align-items:center;gap:10px;padding:8px 10px;
  border:1px solid var(--line);border-radius:var(--r-s);background:var(--panel)}
.social-brand{min-width:0;display:flex;align-items:center;gap:10px;font-size:13px;color:var(--fg)}
.social-brand b{font-weight:600}
.social-row[data-provider="facebook"] .sns-icon{width:22px;height:22px}
.social-row[data-provider="x"] .sns-icon{width:20px;height:20px;margin:2px}
.social-link{flex:none;margin-left:auto;min-width:66px;padding:8px 12px;font-size:12px}
.social-linked{margin-left:auto;font-size:11px;line-height:1.35;text-align:right;color:var(--fg-mid)}
.dkw[data-kw]{cursor:pointer} .dkw[data-kw]:hover{background:#c4453a30}
.dkw.on{background:var(--seal-deep);color:#f3e4e1}
.dkw.flat{opacity:.75;cursor:default}
.dkw.sm{font-size:12px;padding:0 12px;min-height:34px;margin:0 6px 6px 0}
.kwl{display:flex;flex-wrap:wrap}
/* 목록 줄의 딱지는 풀이가 **위**에 선다 (v156) — 여백도 위가 아니라 아래에 둔다 */
.kwtip{margin:0 0 7px;padding:9px 11px;border-left:2px solid var(--seal);background:#c4453a12;
  border-radius:0 2px 2px 0;font-size:11.5px;line-height:1.75;color:var(--fg-mid);animation:fade .16s ease;
  white-space:pre-line}
/* 카드 맨 아랫줄의 딱지는 카드 **바로 밑**에 편다 (v157) — 단추 바로 아래다 */
.kwtip.under{margin:7px 0 0}
/* 풀이를 여는 낱말 — 밑줄만 그어 둔다. 단추처럼 보이면 목록이 단추밭이 된다 */
.tword{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;
  text-decoration:underline;text-decoration-style:dotted;text-underline-offset:3px;
  text-decoration-color:var(--fg-faint)}
.tword:hover,.tword.on{color:var(--seal);text-decoration-color:var(--seal)}
/* `.dmain` 은 걷어냈다 (v157) — 카드 밖에 효과 문단을 따로 두던 자리다. 글은 그림 위에만 있다 */
/* \ud6a8\uacfc \ubb38\uad6c\u00b7\uce74\ub4dc \uc124\uba85\u00b7\ud6a8\uacfc \ud0dc\uadf8\ub97c \uac00\uc6b4\ub370\ub85c \ubaa8\uc740\ub2e4 \u2014 \uce74\ub4dc \uadf8\ub9bc\uc774 \uac00\uc6b4\ub370 \uc11c \uc788\uc5b4 \uae00\ub3c4 \uac19\uc740 \ucd95\uc744 \ub530\ub978\ub2e4 */
/* 카드가 저 혼자 하는 이야기. 규칙이 아니라 세계관이라 글꼴부터 갈라 둔다 */
/* ⚠ 이야기 안에서 **굵게 선 대목**은 그 사람이 무명자께 품은 마음이다 (2026-10-08 기획자).
   굵기만으로는 밤빛 바탕에서 잘 안 읽혀 글빛도 한 단 올린다. 엑셀에 `**…**` 로 적는다 */
.dcon b{font-weight:700;color:#efe4cf}
.dcon{margin:0;padding:10px 13px;text-align:center;background:#ffffff04;
  font-family:var(--story);font-size:12px;line-height:1.9;color:var(--fg-faint)}
.dwarn{display:block;margin-top:6px;font-size:10.5px;color:var(--warn)}
/* 태그 줄에 섞여 서는 자리 — 줄을 새로 잡지 않고 옆에 붙는다 */
.dkws .dwarn{display:inline-flex;align-items:center;margin:0 0 0 2px}
.dl{width:100%;display:flex;flex-direction:column;border:1px solid var(--line-soft);border-radius:var(--r-s);overflow:hidden}
.dl div{display:flex;gap:12px;padding:8px 12px;font-size:12px;border-bottom:1px solid var(--line-soft)}
.dl div:last-child{border-bottom:none}
.dl dt{flex:none;width:68px;color:var(--fg-faint);font-size:11px}
.dl dd{margin:0;flex:1}
.dl dd.m{font-family:var(--mono);font-variant-numeric:tabular-nums}
.concept{font-family:var(--serif);font-size:13px;line-height:1.9;color:var(--fg-mid);text-align:center;max-width:32ch}
.codebox{width:100%;background:var(--ink);border:1px solid var(--line);border-radius:var(--r-s);padding:10px 11px;
  font-family:var(--mono);font-size:11.5px;line-height:1.7;color:var(--fg);resize:vertical;min-height:84px;word-break:break-all}
.btnrow{display:flex;gap:8px}
/* 되돌릴 수 없는 쪽은 붉게 — 눌러도 되는 것과 눈으로 갈린다 */
.fbtn.dg{border-color:#7d3c39;color:#e6a9a2}
.fbtn.dg:hover{background:#2a1716;border-color:var(--danger);color:#ffd9d3}
.veil.ask{align-items:center;justify-content:center;padding:24px}
/* 재화 사용 확인 (v0.226) — 영석처럼 **돈으로 사는 재화**를 쓰기 전에 한 번 묻는다 */
.spend-h{margin:0;text-align:center;font-family:var(--mjo);font-size:15px;font-weight:800;letter-spacing:.06em}
.spend-q{margin:0;text-align:center;font-size:13px;line-height:1.6;color:var(--fg-mid)}
.spend-go{display:inline-flex;align-items:center;justify-content:center;gap:5px}
.spend-go .mini-token{width:15px;height:15px}
.spend-go.yeong{color:var(--yeong)} .spend-go.chungi{color:var(--chungi)}
.askbox{width:min(340px,100%);display:flex;flex-direction:column;gap:18px;
  padding:22px 20px;border:1px solid var(--line);border-radius:var(--r-s);background:var(--panel)}
/* ===== 획득 창 =====
   ⚠⚠ **이제 그림틀이 하나도 없다** (2026-10-13 에 마지막 하나를 걷었다).
      아래 세 줄은 **옛 꼴의 기록**이다 — 되돌릴 일이 생기면 무엇이 어디에 쓰였는지 여기서 찾는다.
      지금은 네 갈래 모두 **같은 겹테 없는 창**이고, 가르는 것은 **줄 세우는 법**뿐이다.
        · 이레 출석                        → 격자 (`.att7`) — 그림틀 `popup_att7day.webp` 를 2026-10-13 에 걷었다
        · 여러 줄 · 굴려야 하는 것          → **한국 대문 틀** `popup_rewardlist_gate.webp` (`.lg`)
          (순례 0~5관문의 카드 보상처럼 **줄이 길어 굴리는** 자리다)
        · 하나·둘·빈손                     → **기와집 틀** `popup_reward_small.webp` (`.one`·`.compact`·`.sm`)
          (천기 하나처럼 **짧은 내역**이다)
   ⚠⚠ **이레 출석 그림을 다른 틀에 쓰지 마라.** 2026-10-02 에 그 그림이 `popup_rewardlist.webp`
      **자리에 들어앉아**, 「최초 클리어 보상」이 7일 출석 그림을 뒤집어쓰고 떴다 —
      같은 제보를 여러 번 받고 2026-10-04 에 갈라 두었다. 7일 출석 틀은 **이 한 줄만** 쓴다.
      ⚠ 그림이 같은지는 `fx-check` 의 「창 틀 그림이 서로 같은 그림이 아니다」가 지킨다 —
        **이름이 달라도 알맹이가 같으면 걸린다**(그때 걸린 것이 바로 그 꼴이었다).
      받는 몫이 클수록 판도 커야 한다. 이레치 출석을 얇은 판에 담으면 잔돈처럼 보인다.
   ⚠ **단추는 틀 밖 아래에 선다.** 안에 넣으면 기와 그림에 먹혀 누를 곳으로 안 보인다 (v0.304).
      그래서 `.gainwrap` 이 세로 묶음이고, **이 묶음이 화면 세로 한가운데**다 */
.gainwrap{display:flex;flex-direction:column;align-items:center;gap:clamp(12px,calc(var(--app-w) * .034),18px);
  width:min(460px,100%)}
.gain-act{width:min(300px,86%)}
/* ⚠ `hidden` 은 `display:flex` 에 지고 만다 — `.btnrow` 가 flex 라 그대로 두면
   단추가 사라져도 **빈 자리가 남아** 틀이 화면 가운데에서 밀린다 */
.gain-act[hidden]{display:none}
.gain-act .fbtn{width:100%;padding:13px}
/* ⚠⚠ **그림틀 둘을 걷었다** (2026-10-12 기획자가 정함 — 「괜히 UI로 만들었더니 위치 잡기 힘들다」).
   `popup_rewardlist_gate.webp`(대문)·`popup_reward_small.webp`(기와집)를 더 안 쓴다.
   까닭 — 지붕과 기둥이 **그림에 그려져 있어** 안쪽 여백을 너비 비율(%)로 잡아야 했고,
   가로세로비를 못 박아야 그 %가 맞았다. 글이 조금만 길어지면 지붕을 파고들었고,
   틀을 고르는 셈(`sm`/`one`/`compact`/`lg`)과 「남의 틀 그림을 뒤집어쓰는」 사고가 거기서 났다.
   이제 **공통 겹테 하나**를 쓰고 여백은 px 다. 글이 늘면 상자가 늘어난다.
   ⚠ 두 그림 파일은 **지우지 않았다** — 되돌릴 자리를 남긴다. 아무도 안 쓸 뿐이다.
   ⚠ `.lg`/`.one`/`.compact`/`.sm` 은 **줄 세우는 법**(2열·큰 그림 하나)으로만 남는다. 틀 그림은 없다 */
/* ⚠⚠ **테도 바탕도 없다 — 딤드 위에 그냥 뜬다** (2026-10-12 저녁 기획자, 레퍼런스 지정).
   `.askbox` 가 쥔 바탕·테·모서리를 여기서 통째로 걷는다. 겹테에서 빼기만 하면
   `.askbox` 의 기본 1px 테를 도로 물려받는다 — 이레 출석에서 한 번 밟은 자리다(아래) */
#vGain .gainbox{box-sizing:border-box;width:100%;text-align:center;display:flex;flex-direction:column;
  gap:clamp(7px,calc(var(--app-w) * .02),10px);overflow:hidden;padding:20px 18px;
  border:0;border-radius:0;box-shadow:none;background:none}
/* ⚠⚠ **어두운 띠는 `#vGain`(가림막)이 깐다 — 상자가 아니다** (2026-10-12 기획자 —
   「왜 주변 테두리는 딤드가 별로 없냐 · 밖으로 나갈수록 투명도 더 줘서 구분 안 가게 해 놨잖아」).
   처음에는 `.gainbox` 에 깔았는데, 상자가 `overflow:hidden` 에 폭이 460px 로 못 박혀 있어
   **사라지기 전에 상자 모서리에서 잘렸다** — 그래서 어두운 네모가 그대로 보였다.
   가림막은 화면을 통째로 덮으므로 **잘릴 가장자리가 없다.** 가운데가 가장 짙고
   밖으로 가며 옅어져 **어디까지가 창인지 눈에 안 잡힌다**(레퍼런스가 그렇다).
   ⚠ 상자에 다시 깔지 마라 — 그 자리에서 또 네모가 된다 */
/* 펼친 두루마리 — **그림이 아니라 CSS 다**(다 쓴 카드의 마름모 금지표와 같은 길).
   가운데 종이 한 장(`::before`)에 양 끝 말린 축 둘(`::after` 의 그라데이션 두 장)이다.
   ⚠ **안은 비워 둔다** (2026-10-12 기획자가 정함). 레퍼런스의 물음표는 「무엇이 나올지 모른다」는
      뜻인데, 우리 창은 바로 아래에 받은 것을 적어 두므로 말이 엇갈린다 */
/* ═══ 마름모 두루마리 표 (2026-10-12 기획자, 레퍼런스 지정) ════════════════════
   ⚠⚠ **다 쓴 카드의 금지 표(`.gcard.used`)와 같은 마름모다.** 한 게임 안에서
      「마름모 = 무엇인가를 다는 자리」로 읽히게 맞춘다 — 저쪽을 고치거든 결을 여기도 맞춰라.
   ⚠ **판은 돌리고 알맹이는 되돌린다.** 판(`.gain-mark`)을 45도 돌리고 안의 svg 를
     −45도로 되돌려 세운다. 하나로 하면 두루마리가 비스듬히 눕는다.
   ⚠ 좌우로 뻗는 가는 줄은 `::before`·`::after` 다 — 레퍼런스의 그 줄이고,
     머리글 덩이와 받은 것 덩이를 가른다. **마름모가 그 줄 위에 앉는다** */
/* ⚠⚠ **`display:block` 을 빼지 마라** (2026-10-13 에 밟았다). 이것은 `<span>` 이다.
   획득 창에서는 부모가 `display:flex` 라 저절로 덩이가 되지만, 관문 창의 머리글은
   그냥 덩이 칸이라 **인라인으로 남는다** — 그러면 너비·높이·`margin:auto` 가 다 먹히지 않고
   돌리기만 걸려 **작은 평행사변형**이 된다. 실제로 그렇게 나왔다 */
/* ⚠⚠ **크기는 `--mk` 하나로 잰다** (2026-10-13). 좌우로 뻗는 줄이 마름모 모서리에서
   시작해야 하는데, 그 모서리까지의 거리는 **한 변이 아니라 대각선의 절반**이다(`--mk-in`,
   `--mk` × 0.707). 둘을 따로 적어 두면 크기를 바꿀 때 한쪽만 고쳐 줄이 마름모를 파고들거나
   허공에서 뜬다. ⚠ CSS 에는 제곱근이 없어 `--mk-in` 은 손으로 셈해 적는다 */
.gain-mark,.stg-mark{--mk:38px;--mk-in:26px;
  display:block;position:relative;flex:none;width:var(--mk);height:var(--mk);margin:2px auto 8px;
  transform:rotate(45deg);border-radius:5px;
  background:linear-gradient(135deg,#2b2535,#171320);
  border:1px solid var(--og,#6b5d8c);
  box-shadow:0 0 0 1px #0008,inset 0 1px 0 #ffffff1f,0 3px 10px #000a}
/* ⚠⚠ **좌우로 뻗는 줄은 돌아간 판 안에 있다** — 먼저 `rotate(-45deg)` 로 **되돌려 눕히고**,
   그 다음 `translateX` 로 좌우로 민다. 차례가 중요하다: 돌리기를 먼저 적어야 미는 축이
   진짜 가로가 된다. `scaleX(-1)` 로 뒤집으려 들지 마라 — 2026-10-12 에 한쪽 줄이 사라졌다.
   ⚠ 둘 다 `left:50%` 에서 시작하고 **왼쪽 줄은 제 너비만큼 더 밀어** 반대쪽으로 보낸다 */
.gain-mark::before,.gain-mark::after,.stg-mark::before,.stg-mark::after{content:"";position:absolute;left:50%;top:50%;
  height:1px;width:92px;transform-origin:0 50%}
.gain-mark::before,.stg-mark::before{transform:rotate(-45deg) translateX(calc(-92px - var(--mk-in)));
  background:linear-gradient(90deg,#0000,var(--og,#6b5d8c))}
.gain-mark::after,.stg-mark::after{transform:rotate(-45deg) translateX(var(--mk-in));
  background:linear-gradient(90deg,var(--og,#6b5d8c),#0000)}
.gain-mark svg,.stg-mark svg{position:absolute;left:50%;top:50%;
  width:calc(var(--mk) * 23 / 38);height:calc(var(--mk) * 23 / 38);
  transform:translate(-50%,-50%) rotate(-45deg)}
/* ⚠ **순례 표식은 보상 창과 같은 크기다** (2026-10-13 기획자 — 「마름모 크기도 공통 보상
   팝업이랑 맞추고 왜 이렇게 여긴 크지?」). 한때 66px 로 키웠는데, 그때는 그림이 돌길 **풍경**이라
   38px 에서 뭉갰기 때문이다. 지금 것은 칼 하나라 그 자리에 들어간다 — 덧쓸 것이 없다.
   ⚠ 다시 키울 일이 생기거든 `--mk` 와 `--mk-in`(= `--mk` × 0.707) 을 **함께** 고친다 */
.gm-pg{fill:#6a6080;stroke:#15111f;stroke-width:.8}
.gm-rl{fill:var(--og-hi,#9b8fbb);stroke:#15111f;stroke-width:.7}
/* ⚠ 물음표는 **교서 단추(`.mic-pic.help`)와 같은 그림**이다 (2026-10-13 기획자).
   손으로 그린 획(`.gm-qm`·`.gm-qd`)을 쓰다가 갈았다 — 두 자리가 같은 모양이라야
   「펼쳐 보면 알 수 있다」가 한 뜻으로 읽힌다.
   ⚠⚠ **빛깔을 파랑에서 보라로 돌린다** (2026-10-13 기획자). 교서 아이콘은 푸른 유리빛인데
     이 창은 통째로 보랏빛이라, 그대로 얹으면 물음표만 딴 데서 온 것처럼 뜬다.
     ⚠ **그림 파일을 새로 만들지 않는다.** 교서 단추와 **같은 한 장**을 쓰는 것이 이 바꿈의 뜻이다 —
       파일을 가르면 다음에 한쪽만 갈려 두 자리가 또 달라진다. 화면에서만 돌린다.
     ⚠ 각도는 눈대중이 아니라 **재서 잡았다.** 아이콘은 색상 214°(채도 37%), 이 창의 보라는
       `--og` 258°·종이 259° 다. `hue-rotate` 는 참 색상 회전이 아니라 **근사 행렬**이라
       214+44 가 258 이 되지 않는다 — 실제로 넣어 셈해 보니 **44° 에서 중간 톤이 258.4°** 로 앉는다.
     ⚠ 채도는 따로 안 만진다. 돌리면서 37% → 29.5% 로 내려가 `--og`(34%)와 종이(25%) 사이에 든다.
     ⚠ **`hue-rotate` 를 그림자보다 앞에 둔다.** 뒤에 두면 그림자 빛깔까지 같이 돌아간다 */
.gm-qi{filter:hue-rotate(44deg) drop-shadow(0 .5px .6px #0b0814b8)}
/* 아무 데나 눌러 닫는 창에서만 뜬다 — `gain2`·`attShow` 가 `hidden` 으로 끈다 */
.gain-hint{flex:none;margin:0;font-size:11px;line-height:1.4;
  color:var(--fg-faint);letter-spacing:.01em}
.gain-hint[hidden]{display:none}
.gain-seal{position:relative;flex:none;width:58px;height:32px;margin:2px auto 0;
  filter:drop-shadow(0 2px 5px #000a)}
/* 가운데 **종이** — 테 안쪽 면보다 밝아야 「펼쳐 놓은 종이」로 읽힌다.
   ⚠ 너무 어둡게 두면 양 끝 축만 남아 **아령처럼** 보인다. 2026-10-12 에 한 번 그리 나왔다.
   가로줄 둘은 적어 놓은 글의 결이다 — 글자를 그리지 않고 결만 남긴다 */
.gain-seal::before{content:"";position:absolute;left:7px;right:7px;top:3px;bottom:3px;
  background:
    linear-gradient(#0000 6px,#ffffff1f 6px,#ffffff1f 7px,#0000 7px),
    linear-gradient(#0000 12px,#ffffff17 12px,#ffffff17 13px,#0000 13px),
    linear-gradient(180deg,#6a6080,#413a56);
  border:1px solid #1a1626;box-shadow:inset 0 1px 0 #ffffff1c}
/* 양 끝 **말린 축** — 위가 밝고 아래가 어두워 둥글게 말린 것으로 보인다 */
.gain-seal::after{content:"";position:absolute;inset:0;
  background:
    linear-gradient(180deg,var(--og-hi,#9b8fbb),var(--og,#6b5d8c) 44%,var(--og-lo,#2e2744)) left center/8px 100% no-repeat,
    linear-gradient(180deg,var(--og-hi,#9b8fbb),var(--og,#6b5d8c) 44%,var(--og-lo,#2e2744)) right center/8px 100% no-repeat;
  border-radius:3px}
/* 어디서 받은 것인가 — 머리글 아래 한 줄. 예전에는 이 말이 **머리글 자리**에 들어갔다
   (「혈투 보상」·「최초 클리어 보상」). 머리글은 「보상 획득」으로 못 박고 이 말을 여기로 내렸다 —
   부르는 쪽(`gain2(…, head)`)은 한 줄도 안 고쳤다 */
.gain-d{margin:0;font-size:12px;line-height:1.5;color:var(--fg-mid);letter-spacing:.01em}
.gain-d:empty{display:none}
/* ⚠⚠ **이레 출석도 이제 머리글·마름모·한 줄을 그대로 쓴다** (2026-10-13).
   예전에는 그 셋이 **그림에 붓으로 적혀 있어서** 여기서 걷었는데,
   그림을 걷었으니 걷을 것이 없다 — 걷으면 머리가 없는 창이 된다.
   ⚠ `.gain-seal`(펼친 두루마리)은 **아무도 안 쓰는 옛 자리**라 그대로 둔다 */
#vGain .gainbox.att7 .gain-seal{display:none}
/* ⚠⚠ **이레 출석 틀은 테를 쓰지 않는다.** 겹테에서 비켜 두었더니(`:not(.att7)`) 이번에는
   `.askbox` 의 기본 1px 테와 모서리를 도로 물려받아, 그림틀 둘레에 없던 선이 생겼다
   (2026-10-12 에 띄워 보고 잡았다). 예전에는 `#vGain .gainbox` 가 통째로 걷고 있었다 —
   그 자리가 사라졌으니 여기서 걷는다 */
#vGain .gainbox.att7{border:0;border-radius:0;box-shadow:none}
/* ⚠ 안쪽 여백은 **너비 비율(%)로** 잡는다. 기와지붕과 기둥이 그림에 그려져 있어,
   px 로 잡으면 화면 폭이 바뀔 때 글이 지붕 위로 올라타거나 기둥을 파고든다.
   ⚠⚠ **%는 네 방향 모두 너비를 기준으로 잰다.** 위아래에 큰 값을 주면 안쪽이 통째로 눌린다 */
/* ⚠ 머리글을 조금 내렸다 (2026-09-30) — 17% 는 지붕 바로 밑에 붙어 있었다 */
/* ⚠⚠ **한국 대문 틀** — 굴려야 하는 긴 내역이 선다 (2026-10-04 기획자가 정함).
   옛 `popup_rewardlist.webp` 에는 **7일 출석 그림이 들어앉아 있었다** — 그래서 최초 클리어
   보상이 출석 그림을 뒤집어쓰고 떴다. 그 이름은 **버린다**(옛 꼴을 쥔 기기는 그 주소에
   옛 그림을 그대로 본다). 새 그림은 **새 이름**으로 간다 — `?v=` 로는 모자라다(§11).
   ⚠⚠ **글이 들어갈 자리는 기획자가 그림에 그어 주었다** (2026-10-04 — 빨간 상자).
      1380×957 에서 **x 190..1195 · y 270..802** 다. **머리글도 그 안**이어야 한다 —
      밖으로 나가면 지붕 위에 글이 뜬다. %여백은 네 방향 모두 **너비 기준**이므로
      가로세로비를 못 박아야 뜻대로 떨어진다.
        왼 190/1380 = 13.8%   ·   오 185/1380 = 13.4%   ·   위 270/1380 = 19.6%   ·   아래 155/1380 = 11.2% */
/* ⚠ **`justify-content:center` 가 빠져 있었다** (2026-10-05). 얇은 틀(`.one`·`.compact`·`.sm`)에만
   있고 이 큰 틀에는 없어, 머리글과 내역이 **상자 위쪽에 붙고** 아래만 비었다.
   목록이 이제 자라지 않으므로(`flex:0 1 auto`) 이 한 줄이 둘을 **한 덩이로 상자 한가운데**에 세운다 */
/* ⚠ 기와집 틀과 나란히 **5px 내렸다** (2026-10-06 기획자) — 두 틀이 같은
   「보상 획득」 창이라 한쪽만 내리면 받는 것에 따라 글이 위아래로 뛰는 것처럼 보인다 */
/* ⚠ 대문 그림틀을 걷었다 (2026-10-12, 위 「그림틀 둘을 걷었다」). 남은 일은 **굴릴 높이를 재는 것**뿐이다 */
#vGain .gainbox.lg{max-height:min(calc(var(--app-h) * .62),420px)}
/* ⚠ 이레 출석 칸은 **이 아래 `#vGain` 바탕 다음**에 있다 (2026-10-13 에 격자로 갈았다).
   예전 이 자리에는 「칸은 그림에 그려져 있다」는 머리말이 있었다 — 그 그림을 걷었다 */
/* ⚠⚠ **뒤가 비쳐야 한다** (2026-10-02 기획자가 정함). 보통 가림막은 거의 먹빛이라
   (`.veil` 의 `#100d0bf7`) 강호가 통째로 사라져 **어디에 서 있는지**가 끊긴다.
   받는 창은 잠깐 서는 것이라 뒤가 비치는 편이 맞다 — 다만 글이 읽혀야 하므로
   **흐림(blur)을 같이 건다.** 투명도만 올리면 뒤의 그림과 글자가 서로 먹는다 */
/* ⚠ 가운데가 짙고 밖으로 가며 옅어진다 — 받은 것이 앉는 자리는 글이 읽히게 덮고,
   가장자리는 강호가 비쳐 **어디에 서 있는지**가 끊기지 않는다. 두 켜를 겹쳐 깐다 */
#vGain{background:
    radial-gradient(118% 40% at 50% 50%,#050408e8 0%,#050408c4 38%,#05040866 72%,#05040800 100%),
    #0a080ca6;
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px)}
/* ⚠⚠ **출석 창에서는 어두운 띠를 넓힌다** (2026-10-13 에 띄워 보고 잡았다).
   위 띠는 세로로 **40% 밖에 안 덮는다** — 받은 것 한두 줄짜리 보상 창은 그 복판에 쏙 들어가지만,
   이레를 두 줄로 펴는 출석 창은 **띠 밖까지 자란다.** 그러면 칸 뒤로 강호의 그림이 쨍하게
   비쳐 글도 칸도 안 읽힌다 — 받은 칸(`.got`)은 가라앉아 있어 아예 사라져 보였다.
   ⚠ **보상 창의 띠는 건드리지 않는다.** 「밖으로 갈수록 옅어져 어디까지가 창인지 눈에 안
      잡히게」가 그 창에 대해 기획자가 정한 것이다. 넓혀야 하는 것은 **키가 큰 이 창뿐**이다.
   ⚠ `#vGain` 에 딱지를 거는 것은 `attShow` 이고, `gain2` 가 **반드시 걷는다** —
      안 걷으면 다음에 열리는 보통 보상 창이 넓은 띠를 쓴다(`att7` 딱지와 같은 짝이다) */
#vGain.attv{background:
    radial-gradient(124% 66% at 50% 50%,#050408f4 0%,#050408e4 40%,#05040894 72%,#05040800 100%),
    #0a080cc9}
/* ═══ 이레 출석 — **공통 보상 칸을 격자로 편다** (2026-10-13 기획자) ═════
   「7일 출석 보상의 나열은 기존과 유지하고 형식은 순례 스테이지 팝업 참고해서
    검은색 딤드를 활용한 깔끔한 디자인으로」.
   ⚠⚠ **그림틀(`popup_att7day.webp`)을 걷었다.** 그 그림에는 칸 일곱과 머리글이
      붓으로 그려져 있어, 칸마다 그림에서 잰 백분율(`ATT_BOX`)로 **위에 얹어야** 했다.
      그래서 보상을 한 가지 바꾸려면 **그림을 다시 그리고 일곱 줄을 다시 재야** 했다.
      이벤트로 돌릴 자리에 그것은 매번 치르는 일이라, 기획자가 꼴을 바꾸라 했다.
      ⚠ `popup_att7day.webp` 는 **지우지 않았다** — 되돌릴 자리를 남긴다(그림틀 둘과 같다).
   ⚠ **나열은 그대로다** — 1·2·3 윗줄, 4·5·6 아랫줄, 7일차가 오른쪽에서 두 줄을 통째로.
     네 칸짜리 격자에서 마지막 칸이 1.32배인 까닭은 그림에서 재던 예전 비율(23.35/14.97=1.56)을
     칸 사이 여백까지 세어 옮긴 값이다 — 일곱째가 연(카드)이라 세로로 길고,
     가로까지 넓으면 옆 세 칸을 까먹는다.
   ⚠⚠ **칸 꼴을 여기서 새로 적지 않는다.** 칸은 `.gain-item` 그대로고, 여기는
      **자리만** 정한다. 옛 `.a7c`·`.a7d`·`.a7-ic`·`.a7-n`·`.a7-nm` 은 다 걷었다 —
      그것들이 있어서 공통 보상 칸을 고칠 때마다 출석만 옛 모습으로 남았다 */
/* ⚠ 이 틀만 **옆 여백을 줄인다**(18 → 10). 네 칸이 한 줄에 서는 자리라
   여백 16px 이 곧 칸 하나의 4px 이다 — 밑줄 한마디가 들어가고 말고가 거기서 갈린다 */
#vGain .gainbox.att7{width:100%;padding-left:10px;padding-right:10px}
#vGain .gainbox.att7 .gain-h{display:block}
/* ⚠⚠ **`1fr` 이 아니라 `minmax(0,1fr)` 이다.** `1fr` 은 속으로 `minmax(auto,1fr)` 이라
   **칸 안 글자보다 좁아지지 않는다** — 줄바꿈을 막아 둔 글이 들어 있으면 그 글자 너비가
   그대로 칸의 바닥이 되어, 글이 긴 칸만 넓어지고 짧은 칸이 눌린다(2026-10-13 에 재어 보고
   잡았다: 61.2 · 61.2 · 58.5). 바닥을 0 으로 풀어야 넷이 뜻대로 나뉜다.
   ⚠⚠ **이레째가 2.2배다** (2026-10-13 기획자 — 「7일 출석 보상이 제일 중요하잖아,
      1~6일차 가로폭 좀 줄여서 7일차 가로폭 더 늘려봐」). 1~6일차는 여섯 칸이 다 같은
      영석 무더기라 작아도 읽히고, 이레째만 **무엇을 주는지가 얼굴로 읽혀야 하는 칸**이다.
      칸을 고르게 두면 가장 중요한 것이 가장 안 보인다 */
#vGain .gainbox.att7 .gain-list{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr)) minmax(0,2.2fr);
  grid-template-rows:auto auto;
  gap:clamp(7px,calc(var(--app-w) * .02),10px);align-items:stretch;overflow:visible;padding-bottom:clamp(10px,calc(var(--app-w) * .026),14px)}

/* ═══ 출석 칸 — **공통 보상 칸과 다른 양식이다** (2026-10-13 기획자가 갈라 둠) ═══════
   「7일 출석은 공통 보상 팝업과는 다른 양식으로 구현해줘, 공통 사용하지 말고」.
   ⚠⚠ **`.gain-item` 을 쓰지 않는다.** 2026-10-13 낮에 한 번 공통 칸으로 묶었다가 물렸다 —
      출석은 **이레를 한눈에 펴 보이는 표**이고 보상 창은 **방금 받은 것을 알리는 쪽지**라,
      같은 칸을 쓰면 한쪽을 손볼 때마다 다른 쪽이 따라 움직인다.
      ⚠ 그러니 여기 값을 공통 칸에서 가져다 쓰지도, 저쪽에 넘기지도 마라. **두 벌이 맞다.**
   ⚠ 꼴이 다른 자리는 셋이다 — ① 며칠째인지가 **칸 위**에 선다(보상 창은 이름 밑)
     ② 수가 그림 위가 아니라 **이름 옆**에 붙는다 ③ 받은 칸에 **표가 찍힌다**.
   ⚠ 창틀(어두운 딤드·마름모·머리글·한마디)은 `#vGain` 것을 그대로 쓴다 — 그것은
     「받는 창」의 꼴이지 칸의 꼴이 아니다. 기획자가 가른 것은 **칸**이다 */
.a7c{display:flex;flex-direction:column;align-items:center;gap:5px;min-width:0}
/* 며칠째인가 — 칸 위에 작게. 옛 그림의 비단 이름패가 서 있던 자리다 */
.a7-d{flex:none;font-family:var(--serif);font-size:clamp(9.5px,round(calc(var(--app-w) * .026), 1px),11px);font-weight:700;
  line-height:1.2;letter-spacing:.02em;color:var(--fg-faint);white-space:nowrap}
.a7c.now .a7-d{color:var(--warn)}
/* 그림 상자 — 네모 하나. 테와 바탕은 보상 창과 **닮았으나 제 값이다**(위 머리말) */
.a7-ic{position:relative;flex:none;width:100%;aspect-ratio:1;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  border-radius:6px;background:linear-gradient(160deg,#1e1a27,#110e17);
  border:1px solid var(--line-soft);box-shadow:inset 0 0 12px #0009}
.a7-ic img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center 28%}
/* 이레째 — 연의 낯짝이라 칸이 세로로 길다. 두 줄을 통째로 쓰고 상자가 남는 키를 다 먹는다 */
.a7c.big{grid-column:4;grid-row:1/3}
.a7c.big .a7-ic{flex:1 1 auto;aspect-ratio:auto;min-height:0;width:100%}
/* ══ 수·이름은 **상자 안 아래**에 박스를 쳐 앉힌다 (2026-10-14 기획자) ══
   「인과 윤회의 보답처럼 이미지 안에 박스 쳐서 수량 작성」 · 「카드쪽도 마찬가지」.
   ⚠⚠ **상자 밑의 줄(예전 `.a7-n`)은 걷었다.** 그래서 1~6일차 칸이 한 줄만큼 낮아졌고,
      남는 세로 자리를 **1~3일차 밑 실선**이 받는다(아래).
   ⚠ 꼴은 보상 창의 `.gain-q` 와 **닮았으나 제 값이다** — 칸을 갈라 둔 기획자의 뜻은
     그대로다(위 머리말). 저쪽 값을 가져다 쓰지도, 저쪽에 넘기지도 마라.
   ⚠ 갈무리 딱지(`.a7-got`)보다 **위에** 선다 — 깔리면 수가 안 읽힌다 */
.a7-q{position:absolute;left:3px;right:3px;bottom:3px;z-index:2;
  font-family:var(--mono);font-size:clamp(10.5px,round(calc(var(--app-w) * .03), 1px),12.5px);font-weight:800;
  font-variant-numeric:tabular-nums;color:var(--yeong);line-height:1.5;
  background:#0b0812c7;border-radius:4px;text-align:center;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  text-shadow:0 1px 2px #000}
/* 연 이름 — 수가 아니라 말이라 제 글꼴이다. 칸이 넓어(2.2배) 한 줄에 들어간다 */
.a7-q.nm{font-family:var(--serif);font-weight:700;color:var(--fg);
  font-size:clamp(11px,round(calc(var(--app-w) * .03), 1px),13px)}
/* ⚠ 다음에 받을 칸만 밝다 — 나머지는 **아직 안 받았을 뿐** 놓친 것이 아니다.
   그래서 가라앉히는 것은 **받은 칸뿐**이다(`.got`). 안 받은 칸은 제 빛으로 선다 */
.a7c.now .a7-ic{border-color:var(--warn);box-shadow:inset 0 0 12px #0009,0 0 13px 2px #e8b45f55}
.a7c.got .a7-ic{opacity:.46;filter:grayscale(.7)}
.a7c.got .a7-q{opacity:.46}
/* ══ 윗줄(1~3일차) 밑에 **실선 한 줄** (2026-10-14 기획자) ═════════
   수를 상자 안으로 넣어 칸이 낮아지면서 윗줄과 아랫줄 사이에 자리가 남았다 —
   비워 두면 여섯 칸이 두 덩어리가 아니라 한 덩어리로 흘러 보인다.
   ⚠ **앞에서 셋째까지만**이다(`-n+3`) — 넷째는 두 줄을 통째로 쓰는 이레째 칸이라
     그 밑에 줄을 그으면 **칸 한가운데를 가로질러** 연의 낯짝을 베어 문다.
   ⚠ 칸 사이 틈(`gap`)이 그대로 있으므로 줄은 칸에 붙여 그어 두 줄을 가른다 */
.a7c:nth-child(-n+3){padding-bottom:clamp(6px,calc(var(--app-w) * .018),9px);
  border-bottom:1px solid #ffffff2b}
/* 받은 표 — 상자 위에 얹는 **갈무리 표(✓)**. 글자는 안 적는다(칸이 좁다).
   ⚠⚠ **가위표(✕)로 그리지 마라** (2026-10-13 에 한 번 그렇게 나왔다). 빗금 둘을 엇갈리게
      그렸더니 **「못 받는다」로 읽혔다** — 받은 칸은 가라앉아 있어서 더 그랬다.
      출석에서 가위표가 뜻할 것은 아무것도 없다. 놓치는 날이 없기 때문이다.
   ⚠ 체크는 **왼쪽 짧은 획 + 아래 긴 획을 −45도로 돌린 것**이다. 네모의 두 변만 남겨 그린다 */
.a7-got{position:absolute;inset:0;display:block;background:#0b0812a8}
.a7-got::after{content:"";position:absolute;left:50%;top:46%;
  width:32%;height:17%;box-sizing:border-box;
  border-left:2px solid #ecdfc2;border-bottom:2px solid #ecdfc2;
  transform:translate(-50%,-50%) rotate(-45deg);
  filter:drop-shadow(0 1px 2px #000)}

/* 하나·둘·빈손 — **기와집 틀** (1380×720) */
/* ⚠⚠ **안쪽 자리는 그림에서 쟀다** (2026-10-02 제보 — 「상하 중앙이 하나도 안 맞는다」).
   눈대중으로 여백을 적으면 폭이 바뀔 때마다 다시 어긋난다. 금 테 안쪽을 재어 %로 적는다.
   틀 1380×720 의 금 테 안쪽은 **x 115..1264 · y 182..608** 이다. 곧—
     왼 115/1380 = 8.3%   ·   오 116/1380 = 8.4%   ·   위 182/1380 = 13.2%   ·   아래 112/1380 = 8.1%
   ⚠⚠ **위와 아래가 다르다**(기와지붕이 위를 먹는다). 같은 값을 주면 내용이 지붕을 파고든다.
   ⚠ 가로세로비를 박아야 이 %가 맞는다. %여백은 네 방향 모두 **너비 기준**이라,
      비가 고정되어야 위아래 값이 뜻대로 떨어진다.
   ⚠ 안쪽에서 다시 **세로 한가운데**로 모은다(`justify-content:center`) — 머리글 하나에
      줄 하나뿐이라 위에서부터 쌓으면 아래가 빈다.
   ⚠ 옛 `popup_reward_common.webp`(1428×668)는 이제 **아무도 안 쓴다** — 짧은 내역은
      기와집 틀로 간다(2026-10-04 기획자가 정함) */
#vGain .gainbox.one,#vGain .gainbox.compact,#vGain .gainbox.sm{
  /* ⚠ 가로세로비를 걷었다 (2026-10-12) — 그림틀이 없으니 **글이 정하는 높이**가 맞다.
     비를 박아 두면 한 줄짜리에도 빈 자리가 크게 남는다 */
  justify-content:center;
  /* ⚠⚠ **대문 틀의 빨간 상자와 같은 결로 잡았다** (2026-10-04). 기와집 틀은 안쪽 판이
     낮으므로(1380×720 의 y 182..608) 대문 틀에서 재어 둔 안쪽 들임을 **판 높이에 비례해** 옮겼다.
     ⚠ **머리글도 이 상자 안**이다. 넘칠 때는 목록이 굴러야지 머리글이 밀려 나가면 안 된다.
     ⚠⚠ **위아래를 다시 셈해 판 한가운데에 맞췄다** (2026-10-05 기획자: 「박스 이미지 중앙에」).
        옛 값(위 17.5% · 아래 8.8%)은 안쪽 상자의 한가운데가 **그려진 판보다 6px 아래**였다.
        %는 네 방향 모두 **너비 기준**이라 셈이 한 번 꺾인다 — 가로세로비가 1380:720 이므로
        높이로 환산하려면 1.9167 을 곱한다.
          상자 한가운데(높이 비) = 0.5 + (위 − 아래) × 1.9167 ÷ 2
          판 한가운데            = (182/720 + 608/720) ÷ 2 = 0.5486
        둘을 같게 두면 **위 − 아래 = 0.0507** 이다. 안쪽 높이를 그대로 두려고 합(0.263)은
        건드리지 않았다 → 위 15.7% · 아래 10.6%.
        ⚠ 그림을 새로 받아 판의 자리가 바뀌거든 **이 셈을 다시 한다** — 눈대중으로 옮기면 또 어긋난다 */
  /* ⚠ **머리글과 내역을 다두 5px 내렸다** (2026-10-06 기획자).
     둘은 `justify-content:center` 로 한 덧이가 되어 있으므로, 위를 5px 늘리고
     아래를 5px 줄이면 **덧이가 딱 5px 내려앉는다**(안쪽 높이는 그대로다).
     ⚠ px 로 더했는데 나머지는 %다 — 눈으로 보고 더 옮길 때는 **위와 아래를 같은 값으로**
       여닫는다. 한쪽만 고치면 위에서 재어 둔 안쪽 높이가 틀어진다 */
  /* ⚠ 기와집 그림틀을 걷었다 (2026-10-12, 위 「그림틀 둘을 걷었다」).
     위에 재어 둔 %셈(판 한가운데 맞추기)은 **그 그림이 있을 때의 이야기**다 — 되살릴 일이
     생기거든 그 셈을 그대로 쓴다. 지금은 여백이 px 라 셈할 것이 없다 */
  padding:20px 18px}
/* `#vGain` 으로 비단 테마의 기본 `.askbox` 배경보다 우선한다. */
/* ═══ 로그인 처리 중 (v0.305) ═══
   누르는 그 순간 단추를 걷는다. 제목만 남아 가운데로 가고, 그 자리에서 기다린다 —
   단추가 남은 채 창이 열렸다 닫히면 어설퍼 보인다 */
#s-title .signin{transition:opacity .26s ease}
#s-title.waiting .signin{opacity:0;pointer-events:none}
/* 빈 안내와 보상 두 줄까지는 내용 높이, 그보다 많을 때만 고정 높이로 굴린다. */
/* ⚠ 머리글은 **다른 창과 같은 결**이다 (v0.277) — 회원 탈퇴·혈투 결과·알림의 `.quit-h`,
   관문의 `.stg-t`·`.stg-ph` 가 모두 명조에 기본 글자색이다.
   여기만 금빛(`--chungi`)에 자간 .28em 이라 혼자 튀었다. 금빛은 **재화 그 자체**를 가리키는
   색이라(천기·`.gain-q`) 머리글에까지 쓰면 그 뜻이 묽어진다 — 받은 수에만 남긴다.
   ⚠ 자간도 좁혔다. .28em 은 「획득」 두 자에 맞춘 값이라
      「최초 클리어 보상」처럼 긴 이름이 오면 낱자가 흩어져 읽힌다 */
/* ⚠ **머리글 밑줄을 걷었다** (2026-10-04 기획자). 기와집 틀이 이미 제 테두리를 쥐고 있어
   그 안에 줄을 한 겹 더 그으면 칸이 둘로 쪼개져 보인다. 줄이 빠진 만큼 머리글이 숨을 쉰다 */
.gain-h{flex:none;margin:0;text-align:center;font-family:var(--serif);
  font-size:clamp(15px,round(calc(var(--app-w) * .042), 1px),19px);font-weight:800;letter-spacing:.04em;color:var(--fg);
  padding:2px 0 8px}
/* 얇은 틀에서는 머리글도 얇게 — 안 그러면 아래 테두리에 잘린다 */
/* ⚠⚠ **기와집 틀의 안쪽 판은 너비의 30.9% 뿐이다** (2026-10-04). 머리글과 줄이 그 안에
   들어가야 한다 — 넘치면 `justify-content:center` 가 **위아래로 똑같이 밀어내** 머리글은
   지붕 위로, 마지막 줄은 바닥 아래로 삐져나간다(둘 다 잘린다).
   그래서 이 틀에서는 머리글을 더 얇게, 줄 사이를 더 좁게 잡는다.
   ⚠ 손말틀(375px)에서 먼저 재고 올린다 — 좁은 쪽이 먼저 넘친다 */
#vGain .gainbox.one .gain-h,#vGain .gainbox.compact .gain-h,#vGain .gainbox.sm .gain-h{
  font-size:clamp(12.5px,round(calc(var(--app-w) * .033), 1px),15px);padding:0 0 3px}
#vGain .gainbox.one,#vGain .gainbox.compact,#vGain .gainbox.sm{gap:clamp(5px,calc(var(--app-w) * .016),8px)}
/* ⚠ **`grid` 다** (v0.320) — 받을 것이 다섯을 넘으면 두 칸으로 접어 **한눈에 다 들어온다.**
   예전에는 한 줄씩만 쌓여 관문 보상 여섯 장 가운데 **셋만 보이고 넷째가 반쯤 잘렸다.**
   ⚠ `align-content:center` — 적게 받았을 때 목록이 위에 붙지 않고 판 한가운데 선다.
      한 줄만 받았는데 위에 치우쳐 있으면 머리글과 따로 노는 것으로 보인다 */
/* ⚠ **한 칸이다.** 좌우로 가르지 않는다 — 받은 것은 위에서 아래로 한 줄씩 읽는 것이다.
   ⚠ `align-content:center` — 적게 받았을 때 목록이 위에 붙지 않고 판 한가운데 선다.
      한 줄만 받았는데 위에 치우쳐 있으면 머리글과 따로 노는 것으로 보인다 */
/* ⚠⚠ **가로로 늘어서고 넘치면 접힌다** (2026-10-12). 세로로 쌓던 것을 뒤집었다 —
   레퍼런스가 그렇고, 받은 것이 둘이든 여섯이든 **같은 꼴**이라 갈래마다 따로 적을 일이 없다.
   ⚠ 위아래 가는 줄이 받은 것 덩이를 머리글·한마디와 가른다(마름모의 줄과 한 결이다) */
.gain-list{flex:0 1 auto;min-height:0;
  /* ⚠ **`stretch` 다.** `flex-start` 로 두면 한마디가 붙은 칸만 키가 커져 **이름 줄이 어긋난다** */
  display:flex;flex-wrap:wrap;justify-content:center;align-items:stretch;
  /* ⚠⚠ **가르는 줄은 둘 다 걷었다** (2026-10-12 기획자 — 윗줄 「없애도 될 것 같아」 →
     아랫줄 「영석 아래 아랫줄 뭐야」). 마름모가 이미 제 좌우로 줄을 뻗어 머리글을 이고 있어,
     아래에 줄을 또 그으면 받은 것이 **칸에 갇힌 것**처럼 보인다.
     가르는 일은 **여백이 한다** — 줄을 다시 긋지 마라.
   ⚠ 아래 여백이 위보다 넉넉하다. 이름이 상자 밑에 붙어 있어 **글 쪽에 숨 쉴 자리**가 더 든다 */
  gap:clamp(8px,calc(var(--app-w) * .024),12px);padding:clamp(10px,calc(var(--app-w) * .026),14px) 2px clamp(16px,calc(var(--app-w) * .042),22px);
  overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;
  /* ⚠ 굴림대는 **숨긴다.** 판이 좁아 금빛 막대가 수 바로 옆에 붙어 글자를 가렸다 */
  scrollbar-width:none}
/* ⚠⚠ **첫 칸·끝 칸의 `margin:auto` 를 걷었다** (2026-10-12 기획자가 물림 —
   「왜 재화 보상과 카드 보상의 열 정렬이 달라야 하는 거냐」).
   세로로 쌓던 시절에 **목록을 판 한가운데 세우려고** 걸어 둔 것인데, 가로줄이 된 지금은
   **첫 칸에 `margin-top:auto` 가 걸려 그 칸만 늘어나지 않고 아래로 밀렸다**
   (`align-items:stretch` 는 `auto` 여백에 진다). 그래서 천기 칸만 키가 95, 나머지는 108 이었고
   이름 줄이 한 칸만 내려앉았다. **가운데 세우기는 이제 `justify-content:center` 가 한다** */
.gain-list::-webkit-scrollbar{display:none}
/* 예외 안내와 보상 1~2개는 굴리지 않는다. */
/* ⚠⚠ **틀 안에서 굴린다** (2026-10-04 기획자: 「헤더가 자꾸 벗어난다」).
   예전에는 얇은 틀의 목록이 `flex:0 0 auto` 에 `overflow:visible` 이라 **제 키를 고집**했다.
   그러면 머리글+줄이 안쪽 판보다 높을 때 `justify-content:center` 가 위아래로 똑같이 밀어내
   **머리글이 지붕 위로 올라가고** 마지막 줄이 바닥 밑으로 내려갔다 — 그림이 바뀌면 또 난다.
   이제 목록이 **남는 높이만 쓰고** 모자라면 저 혼자 굴린다. 머리글은 어떤 경우에도 상자 안이다 */
#vGain .gainbox.sm .gain-list,#vGain .gainbox.one .gain-list,
#vGain .gainbox.compact .gain-list{flex:1 1 auto;min-height:0;overflow-y:auto}
/* ⚠⚠ **갈래마다 여백·크기를 따로 적던 줄 넷을 걷었다** (2026-10-12 기획자 —
   「왜 이렇게 딱 붙여서 만들지」). 기와집 그림틀 시절에 **낮은 판에 욱여넣느라** 적어 둔 값들인데
   (`padding:0 2px` · `gap:4px` · 그림 24px), 그림틀이 없어진 지금은 **여백만 깎아 먹는다.**
   실제로 `padding:0 2px` 가 받은 것 아래 여백을 통째로 0 으로 만들어 이름이 한마디에 달라붙었다.
   ⚠ **갈래마다 따로 적지 마라.** 꼴은 하나다 — 고칠 곳도 하나여야 한다 */
#vGain .gainbox.sm .gain-none{font-size:clamp(11.5px,round(calc(var(--app-w) * .031), 1px),13px);line-height:1.5}
/* ═══ 받은 것은 **칸(박스)으로** 선다 (2026-10-12 기획자, 레퍼런스 지정) ════════════
   「보상 내역들은 박스쳐서 표기하고」. 한 칸 = **그림 상자 + 그 안 아래의 수 + 상자 밑의 이름**이다.
   ⚠⚠ **줄(`.gain-row`)은 통째로 걷었다.** 예전에는 「그림 · 이름 · 오른쪽 끝에 수」를 한 줄로
      세우고, 받은 수에 따라 `.one`/`.compact`/`.lg` 가 **저마다 다른 줄 꼴**을 쓰게 갈라 두었다.
      그 갈래마다 여백·차례·이름 감추기를 따로 적다 보니 한 곳을 고치면 다른 곳이 어긋났다
      (2026-10-04~10-06 에 되풀이해 터진 자리다).
      이제 꼴이 **하나**다 — 몇 개를 받든 같은 칸이 가로로 늘어서고, 넘치면 다음 줄로 접힌다.
   ⚠ 그래서 `.one`/`.compact`/`.lg`/`.sm` 은 이제 **굴릴지 말지와 단추를 세울지**만 가른다.
     줄 꼴을 다시 갈래별로 적지 마라 — 그것이 지난 사고의 뿌리다 */
/* ⚠ 상자와 이름 사이를 **벌렸다** (2026-10-12 기획자 — 「왜 이렇게 딱 붙여서 만들지」).
   5px 이면 이름이 상자에 달라붙어 상자의 일부처럼 읽힌다 */
.gain-item{flex:none;display:flex;flex-direction:column;align-items:center;gap:9px;
  width:clamp(62px,calc(var(--app-w) * .19),76px)}
/* 그림 상자 — 수가 **이 안 아래쪽**에 앉는다(레퍼런스) */
.gain-ic{position:relative;flex:none;width:100%;aspect-ratio:1;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  border-radius:7px;background:linear-gradient(160deg,#211c2b,#120f18);
  border:1px solid var(--line-soft);
  box-shadow:inset 0 1px 0 #ffffff14,inset 0 0 14px #000a,0 2px 6px #0007}
/* ⚠⚠ **재화든 연이든 **같은 자**로 담는다** (2026-10-12 기획자가 물림 —
   「왜 재화 보상과 카드 보상의 열 정렬이 달라야 하는 거냐」).
   처음에는 연만 따로 떼어 상자를 꽉 채우게 했는데, 그래서 **상자 크기도 칸 높이도 글자색도**
   둘이 갈렸다(105 대 103 · 134 대 146). 한 줄에 나란히 서는 칸이 서로 다른 자를 쓰면
   이름이 어긋나 읽기가 불편하다. **갈래마다 따로 적지 마라** — 그것이 옛 줄 꼴의 그 탈이다.
   ⚠ `object-fit:contain` 이라 세로로 긴 연 그림도 제 비율 그대로 상자 안에 들어앉는다 */
/* ⚠⚠ **상자를 꽉 채운다** (2026-10-12 기획자 — 「천기는 저렇게 꽉 채워놓고 카드는 왜」).
   `contain` 이면 세로로 긴 연 그림이 좌우에 흰 자리를 남겨 **재화보다 작아 보인다.**
   `cover` 로 채우고 **위쪽을 살려** 자른다(`28%`) — 연 그림은 얼굴이 위에 있다 */
/* ⚠⚠ **그림은 자리를 안 차지한다**(`absolute`). 흐름 안에 두면 세로로 긴 연 그림이
   제 키로 상자를 **밀어 올려** `aspect-ratio:1` 을 이긴다 — 재화 76×76, 연 76×106 으로
   갈렸다(2026-10-12 에 밟았다). 떼어 두면 상자는 언제나 정사각이다 */
.gain-ic img{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center 28%}
/* 수 — 상자 **안 아래**. 바탕을 깔아 그림 위에서도 읽힌다 */
.gain-q{position:absolute;left:3px;right:3px;bottom:3px;
  font-family:var(--mono);font-size:clamp(11px,round(calc(var(--app-w) * .031), 1px),13px);font-weight:800;
  font-variant-numeric:tabular-nums;color:var(--chungi);line-height:1.5;
  background:#0b0812c7;border-radius:4px;
  text-shadow:0 1px 2px #000}
.gain-q.jin{color:var(--jin)}
/* 이름 — 상자 **밑. 한 줄이다** (2026-10-12 기획자).
   ⚠⚠ **접지 않는다.** 한국말 카드 이름은 길고 띄어쓰기가 여럿이라, 접게 두면
      띄어쓰기마다 꺾여 **「청성문 / 입문제자」처럼 두 줄, 세 줄**이 된다 —
      칸마다 높이가 달라져 줄이 들쭉날쭉해진다.
   ⚠ 그래서 **글자를 줄여 넣어 보고**(`gainFit`), 그래도 넘치면 **말줄임(…)**으로 끝낸다 */
/* ⚠⚠ **높이를 못 박는다.** 글자를 줄이면(`gainFit`) 줄 높이도 함께 줄어 **칸마다 키가
   달라지고** 이름 줄이 어긋난다 — 실제로 134 대 146 으로 갈렸다. 한 줄 자리를 미리 비워 둔다.
   ⚠ 글자색도 하나다 — 연이라고 더 밝게 두면 그것도 「다른 양식」이 된다 */
.gain-n{width:100%;min-width:0;font-size:clamp(10.5px,round(calc(var(--app-w) * .029), 1px),12px);
  line-height:14px;height:14px;
  color:var(--fg);text-align:center;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 「승단」·「오늘」 같은 한마디 — 이름 아래 한 줄 더. ⚠ 여기도 높이를 못 박는다 */
.gain-sub{display:block;font-size:10px;line-height:13px;height:13px;color:var(--fg-faint);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* ⚠ 한마디가 붙은 칸은 이름 칸이 두 줄 자리를 쓴다 — 그 칸만 커지지 않게 **줄에 맞춰 늘린다**.
   한 줄짜리 칸도 같은 키가 되도록 목록이 칸을 늘려 세운다(`align-items:stretch`) */
.gain-item .gain-n:has(.gain-sub){height:27px}
/* 연진이 된 연·아직 못 받은 줄은 **흐리게 둔다** — 받은 것과 한눈에 갈려야 한다 */
.gain-item.tojin .gain-ic img,.gain-item.dim .gain-ic img{filter:grayscale(.85) brightness(.7)}
.gain-item.dim{opacity:.55}
/* 오늘 몫은 한 겹 밝게 — 출석처럼 여러 날을 한 자리에 펼 때 쓴다 */
.gain-item.now .gain-ic{border-color:var(--og,#6b5d8c);box-shadow:inset 0 1px 0 #ffffff1f,0 0 10px #6b5d8c55}

/* ═══ ⚠⚠ **머리글과 내역은 한 덩이로 판 한가운데에 선다** (2026-10-05 기획자가 물림) ═══
   「헤더가 왜 이렇게 위에 있어 · 헤더와 보상 내역의 줄간이 너무 넓어 · 팝업 영역 박스 이미지
    중앙에 오게끔」. **최초 클리어 보상(`.lg`)도 같은 탈이었다.**

   ⚠⚠ **까닭은 목록이 남는 높이를 다 먹은 것이다.** `.gain-list` 가 `flex:1 1 auto` 로
      자라서 판을 꽉 채우고, 그 안에서 `margin:auto`(또는 `align-content:center`)로 줄만
      가운데에 섰다. 그래서 **머리글은 판 맨 위에 붙박이고** 줄은 저 아래 가운데에 떠서
      둘 사이가 훅 벌어졌다. 틀의 `justify-content:center` 는 아무 일도 못 했다 —
      자리가 남지 않으니 가운데로 밀 것이 없었다.

   ⚠ 그래서 **자라지는 않고 줄어들기만** 하게 한다(`flex:0 1 auto`).
       · 내역이 짧으면 — 목록이 제 키만 쓰고, 틀이 **머리글 + 목록을 한 덩이로** 가운데 세운다
       · 내역이 길면 — 목록만 줄어들어(`min-height:0`) 제 안에서 굴린다.
         **머리글은 어떤 경우에도 판 안이다** — 2026-10-04 에 「헤더가 자꾸 벗어난다」로
         한 번 터진 자리라, 그 막음은 그대로 지킨다.
   ⚠ 자라지 않으므로 `margin:auto` 로 가운데 세우던 것은 **할 일이 없어졌다.** 남겨 두면
     목록이 줄어드는 자리에서 위아래로 헛여백을 만든다 — 걷는다 */
#vGain .gainbox.one .gain-list,#vGain .gainbox.compact .gain-list,
#vGain .gainbox.sm .gain-list,#vGain .gainbox.lg .gain-list{flex:0 1 auto}
/* ⚠ 위 `margin:auto` 를 되돌리던 줄 넷은 **함께 걷었다** — 되돌릴 것이 없어졌다 */
/* ⚠ 머리글과 내역 사이를 **확 좁힌다**(기획자). 머리글의 아래 여백과 틀의 `gap` 이
   둘 다 벌어져 있어 합이 15~18px 이었다 — 이제 합이 6px 안쪽이다 */
#vGain .gainbox.lg,#vGain .gainbox.one,
#vGain .gainbox.compact,#vGain .gainbox.sm{gap:clamp(3px,.calc(var(--app-w) * .09),5px)}
#vGain .gainbox.lg .gain-h{padding:0 0 1px}
#vGain .gainbox.one .gain-h,#vGain .gainbox.compact .gain-h,
#vGain .gainbox.sm .gain-h{padding:0 0 1px}


/* ⚠ **「×3,500」이 아니라 「+3,500」이다** (v212). 곱셈표는 「세 벌을 산다」처럼 읽히는데
   여기는 **받아서 늘어나는 자리**다. 수를 만드는 곳은 `gain2()` 한 군데다 */

/* 받은 것이 차례로 자리를 잡고 작게 되튄다. 배율 폭과 지연을 줄여
   여러 보상이 한꺼번에 나올 때도 화면이 덜 들썩이게 한다. */
.gain-ic,.gain-q{animation:gainslam .4s cubic-bezier(.2,.85,.3,1) backwards;
  animation-delay:calc(var(--i,0) * .07s)}
@keyframes gainslam{
  0%  {opacity:0; transform:translateY(9px) scale(1.18)}
  60% {opacity:1; transform:translateY(0) scale(.97)}
  82% {           transform:scale(1.025)}
  100%{opacity:1; transform:scale(1)}
}
/* 박히는 순간의 파문. 그림 칸에만 걸어 둔다 — 숫자에까지 걸면 지저분하다.
   ⚠ `.gain-ic` 는 `overflow` 가 없어야 파문이 테 밖으로 퍼진다 */
.gain-ic{position:relative}
.gain-ic::after{content:"";position:absolute;inset:0;border-radius:7px;
  pointer-events:none;
  animation:gainring .52s ease-out backwards;
  animation-delay:calc(var(--i,0) * .11s + .16s)}
@keyframes gainring{
  from{box-shadow:0 0 0 0 #d4a843bb,0 0 18px 4px #d4a84366}
  to  {box-shadow:0 0 0 16px #d4a84300,0 0 0 0 #d4a84300}
}
@media (prefers-reduced-motion:reduce){
  .gain-ic,.gain-q{animation:none}
  .gain-ic::after{animation:none}
}

/* ===== 출석 보상 (v0.230) =====
   **1·2·3 / 4·5·6 두 줄, 7일차는 오른쪽 한 칸이 두 줄을 통째로 쓴다.**
   이레째만 크게 서야 「저기까지 가면 저것을 준다」가 한눈에 읽힌다 */
/* 출석 창은 **가운데로 모은다** — 제목도 칸도 한 축에 선다 */
/* ⚠ **틀 밖으로 넘치게 두지 않는다** (v0.284). 틀은 그림이라 높이가 못박혀 있는데(1380:1260)
   안의 것들은 제 크기를 고집해, 375px 손말틀에서 108px 이 넘쳐 **굴러 내려갔다.**
   틀을 세로 칸으로 세우고 **격자가 남은 높이를 나눠 쓰게** 한다 — 굴릴 일이 없어진다 */
/* ⚠⚠ **이 아래 한 덩이는 이제 아무도 안 세운다** (2026-10-04 확인 — `ui.js`·`index.html` 어디에도
   `.attbox`·`.attgrid` 가 없다). 출석 창은 `#vGain` 의 `.att7` 틀로 옮겨 갔다.
   ⚠ 그래서 여기 적힌 `popup_attendance_7day.webp` 도 **쓰이지 않는다** — 7일 출석 그림의
     살아 있는 자리는 `popup_att7day.webp` 하나뿐이다. 되살릴 일이 있거든 가로세로비부터
     그림에 맞춰라(1380/1260 은 옛 그림의 비다. 지금 그 파일은 1122×1402 다) */
.attbox{width:min(460px,100%);max-width:460px;aspect-ratio:1380/1260;text-align:center;
  border:0;border-radius:0;padding:clamp(44px,calc(var(--app-w) * .115),62px) clamp(30px,calc(var(--app-w) * .08),42px) clamp(16px,calc(var(--app-w) * .045),28px);
  background:transparent url(assets/ui/popup_attendance_7day.webp?v=3) center/100% 100% no-repeat;
  box-shadow:none;
  display:flex;flex-direction:column;overflow:hidden}
.attbox .stg-t{text-align:center;flex:none;font-size:clamp(15px,round(calc(var(--app-w) * .044), 1px),21px)}
/* 엿새 칸은 **좁게 못 박고**(54px), 남는 자리는 전부 이레째가 가져간다.
   격자를 창보다 좁게 잡아 가운데로 모으면 좌우가 비어 숨통이 트인다 (v0.230) */
/* ⚠ 남은 높이를 **격자가 전부 가져간다**(`flex:1`). `minmax(0,…)` 이 없으면 칸이
   제 내용만큼 버텨 다시 넘친다 — 격자에서 넘침을 막는 것은 늘 이 0 이다 */
.attgrid{flex:1 1 auto;min-height:0;
  display:grid;gap:clamp(4px,calc(var(--app-w) * .014),7px);margin:clamp(7px,calc(var(--app-w) * .024),14px) auto 0;width:min(304px,100%);
  grid-template-columns:repeat(3,minmax(0,1fr)) 1.24fr;grid-template-rows:repeat(2,minmax(0,1fr))}
.attc{position:relative;min-width:0;min-height:0;overflow:hidden;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:clamp(2px,calc(var(--app-w) * .01),5px);
  padding:clamp(4px,calc(var(--app-w) * .016),9px) 4px;border:1px solid var(--line);border-radius:var(--r-s);background:#12101a;
  color:var(--fg-mid);-webkit-tap-highlight-color:transparent;transition:border-color .14s,opacity .14s}
.attc.big{grid-column:4;grid-row:1 / 3;gap:clamp(3px,calc(var(--app-w) * .014),8px);padding:clamp(6px,calc(var(--app-w) * .02),12px) 6px;
  background:#171122;border-color:#5c4a22}
.at-d{flex:none;font-family:var(--serif);font-size:clamp(8.5px,round(calc(var(--app-w) * .025), 1px),10.5px);font-weight:700;
  letter-spacing:.04em;color:var(--fg-faint)}
.attc.big .at-d{font-size:clamp(10px,round(calc(var(--app-w) * .031), 1px),13px);color:var(--chungi)}
.at-ic{flex:0 1 auto;min-height:0;width:auto;display:flex;align-items:center;justify-content:center}
.attc.big .at-ic{width:100%}
.at-ic img{width:auto;height:100%;max-height:clamp(18px,calc(var(--app-w) * .064),26px);aspect-ratio:1;object-fit:contain;
  filter:drop-shadow(0 1px 2px #000b)}
/* 카드 보상은 카드 낯짝 그대로 — 재화 아이콘과 한눈에 갈린다 */
.at-ic.card{width:auto;height:auto}
.at-ic.card img{width:auto;height:100%;max-height:none;aspect-ratio:63/88;object-fit:cover;border-radius:2px;
  border:1px solid var(--line)}
.attc.big .at-ic.card img{width:auto;height:100%;max-width:100%;border-color:#6b5a3a;
  box-shadow:0 3px 12px #000a,0 0 14px #d4a84333}
.at-n{flex:none;font-size:clamp(8px,round(calc(var(--app-w) * .024), 1px),9.5px);line-height:1.3;text-align:center;color:var(--fg-mid);
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* ⚠ `keep-all` — 한글은 낱말 가운데서도 줄이 갈린다. 「만권루주 서하란」이
   「만권루주 서 / 하란」으로 끊겨 이름이 아닌 것처럼 읽혔다 (v0.298) */
.attc.big .at-n{font-size:clamp(9px,round(calc(var(--app-w) * .029), 1px),11.5px);white-space:normal;word-break:keep-all;font-weight:700;color:var(--fg);line-height:1.3}
.at-s{flex:none;font-family:var(--mono);font-size:clamp(7px,round(calc(var(--app-w) * .021), 1px),8.5px);letter-spacing:.06em;color:var(--fg-faint)}
/* 받은 날 · 놓친 날 · 아직 오지 않은 날 */
.attc.got{opacity:.5}
.attc.got .at-s{color:var(--jin)}
.attc.miss{opacity:.34;border-style:dashed}
.attc.soon{opacity:.62}
/* 오늘 — **깜빡인다.** 누를 곳이 어디인지 말로 적지 않아도 눈이 먼저 간다 */
.attc.now{cursor:pointer;border-color:var(--seal);color:var(--fg);
  animation:attblink 1.15s ease-in-out infinite}
.attc.now .at-s{color:var(--seal)}
.attc.now:active{transform:scale(.97)}
@keyframes attblink{
  0%,100%{box-shadow:0 0 0 1px var(--seal),0 0 13px #c4453a3d}
  50%    {box-shadow:0 0 0 2px var(--seal),0 0 24px #c4453a9e}}
@media (prefers-reduced-motion:reduce){ .attc.now{animation:none;box-shadow:0 0 0 2px var(--seal)} }
/* ⚠⚠ **여기 있던 넉 줄을 걷었다** (2026-10-12). 줄 꼴 시절의 잔재인데 **파일 뒤쪽이라
   위에 새로 적은 칸 규칙을 덮고 있었다** — 보고도 한참 못 찾은 자리다.
     · `.gain-ic.card img{width:30px…}`   — `.card` 는 이제 안 붙인다(위 `gain2` 머리말)
     · 연진 줄의 `.gain-n{white-space:normal}` — 이름을 **한 줄로** 두기로 한 것을 깨뜨렸다
     · `.gain-sub{…}` 가 **두 번째로 선언**되어 못 박아 둔 높이를 통째로 덮었다
   ⚠ 획득 창 규칙은 **위 한 덩이**에만 적는다. 여기 뒤쪽에 더 적지 마라 */
/* 연진이 된 줄 — **카드를 받은 것이 아니다** (v0.271).
   그림은 남기되 흐리게 두어 「들어오다 말았다」는 것을 보이고, 수량 자리는 연진 빛깔로 바꾼다 */
/* ⚠ **꺼진 칸**이다 — 사라지지 않고 그 자리에 남아 「이 연이 연진이 되었다」를 말한다.
   그림을 흑백으로 눌러 두고 상자도 함께 가라앉힌다. 수 자리의 연진 그림이 무엇이 되었는지 말한다 */
.gain-item.tojin .gain-ic img{filter:grayscale(1) brightness(.5);opacity:.55}
.gain-item.tojin .gain-ic{background:linear-gradient(160deg,#17141d,#0d0b12);border-color:#2a2533}
.gain-item.tojin .gain-n{color:var(--fg-faint)}
/* 수 옆의 연진 그림 — 글자와 같은 키로 선다 */
.gain-q .gq-ic{width:1.05em;height:1.05em;object-fit:contain;vertical-align:-.16em;margin-right:2px}
/* 출석처럼 **이미 받은 날과 지난날**을 함께 펼 때 — 흐리게 두어 오늘 것이 먼저 눈에 든다 (v0.320) */
.gain-item.dim{opacity:.42}
.gain-item.now .gain-sub{color:var(--chungi)}
/* ⚠ .gain-q.jin 은 위 한 덩이에만 적는다 — 여기 있던 두 번째 선언을 걷었다 (2026-10-12) */
/* 받은 것이 없을 때 — 까닭 한 줄만 세운다 (v0.297). 왜 못 받았는지 모르면 버그로 읽힌다 */
.gain-none{margin:0;font-size:13.5px;line-height:1.75;color:var(--fg-mid);text-align:center;
  word-break:keep-all;white-space:pre-line}

/* ===== 제보 (v195) ===== */
#s-report .hptabs{gap:6px;flex-wrap:wrap}
#s-report .hptab{flex:1 1 auto;min-width:78px;text-align:center;padding:8px 10px;font-size:12px}
/* ⚠ `.fq` 는 **가로줄에 놓으라고 만든 것**이라 `flex:1 1 0%` 다 (찾기 줄·이름 칸).
   세로로 쌓는 이 화면에서는 그대로 두면 **제목 칸이 본문만큼 부푼다** — 195px 이 됐다.
   여기서는 셋 다 제 키를 지킨다 */
#s-report .fq,#s-report .fbtn{flex:none}
#s-report #rpTitle{padding:11px 12px;font-size:13px}
.rp-body{flex:none;resize:none;height:168px;padding:11px 12px;font-size:13px;line-height:1.7}
.rp-note{margin:0;font-size:10.5px;line-height:1.6;color:var(--fg-faint)}
.rp-status{margin:0;min-height:1.4em;text-align:center;font-size:12px;font-weight:700;color:var(--warn)}
/* ⚠ `white-space:pre-line` — 묻는 말이 길어지면 줄을 나눠야 읽힌다 (2026-10-01).
   `#askQ` 는 `textContent` 로 적으므로 이것이 없으면 줄바꿈이 통째로 뭉개진다 */
.ask-q{margin:0;text-align:center;font-size:14.5px;line-height:1.6;color:var(--fg);
  white-space:pre-line;word-break:keep-all}
.btnrow.one{justify-content:center}
/* ===== 머리글이 있는 알림 (v0.255) =====
   까닭을 먼저 밝히고 그다음에 무엇을 하면 되는지 이른다.
   머리글은 가운데로 모은다 — 목록이 없어 눈이 훑을 일이 없고, 한마디 알림은 가운데가 읽기 좋다 */
.notebox{gap:11px;text-align:center}
.notebox .quit-h{text-align:center}
.note-t{margin:0;font-size:13.5px;line-height:1.7;color:var(--fg-mid);white-space:pre-line}
/* ===== 혈투 결과 (v0.267) =====
   받은 천기는 **나가기 바로 위**에 세운다 — 마지막에 눈이 닿는 자리다.
   획득 창(`.gain-q`)과 같은 금빛으로 적는다 — 화면 어디서나 「받았다」는 같은 색이다 */
.drbox{gap:9px;text-align:center}
.drbox .quit-h{text-align:center;font-size:17px}
.dr-sub{margin:0;font-size:13px;color:var(--fg-mid);letter-spacing:.02em}
.dr-sub:empty{display:none}
.dr-get{margin:5px 0 2px;font-size:14px;line-height:1.6}
.dr-get:empty{display:none}
.dr-get .dr-get{display:contents}
.dr-get b.dr-get,b.dr-get{font-family:var(--serif);font-size:19px;font-weight:800;color:var(--chungi);
  text-shadow:0 0 12px rgba(212,175,95,.35)}
.dr-full{font-size:12.5px;line-height:1.6;color:var(--fg-mid)}
/* 재화 풀이 맨 아래의 하루 몫 — 위 글과 줄 하나로 갈라 둔다 */
.tip-day{margin-top:8px!important;padding-top:7px;border-top:1px solid var(--line);
  font-size:12px;color:var(--fg-faint)}
.tip-day b{color:var(--chungi);font-weight:700}
/* ===== 회원 탈퇴 (v0.242) =====
   무엇이 사라지는지 **먼저 읽히고** 나서 동의가 온다. 그래서 가운데 정렬을 쓰지 않는다 —
   목록은 왼쪽에서 시작해야 눈이 훑는다 */
.quitbox{gap:13px;text-align:left}
.quit-h{margin:0;font-family:var(--serif);font-size:15px;font-weight:800;letter-spacing:.04em;color:var(--fg)}
.quit-lead{margin:0;font-size:13px;line-height:1.6;color:var(--fg-mid)}
.quit-warn{margin:0;font-size:12.5px;line-height:1.65;color:var(--danger)}
.quit-list{margin:0;padding-left:17px;display:flex;flex-direction:column;gap:5px;
  font-size:12.5px;line-height:1.6;color:var(--fg-mid)}
/* 동의는 **글까지 눌러서** 짚을 수 있다 — 작은 네모만 노리게 하면 손이 헛돈다 */
.quit-ok{display:flex;gap:9px;align-items:flex-start;cursor:pointer;
  padding:11px 12px;border:1px solid var(--line);border-radius:var(--r-s);background:#00000038;
  font-size:12px;line-height:1.55;color:var(--fg-mid)}
.quit-ok input{flex:0 0 auto;width:17px;height:17px;margin:1px 0 0;accent-color:var(--danger);cursor:pointer}
.quit-ok:has(input:checked){border-color:#7d3c39;color:var(--fg)}
/* 짚기 전에는 눌리지 않는다는 것이 **눈에 보여야** 한다 */
#quitGo[disabled]{opacity:.38;cursor:default}
/* 탈퇴 자리 — 로그아웃 단추와 눈으로 갈린다. 붉게 두지 않는다(누르라고 부르는 꼴이 된다) */
/* 문서 셋 — 한 줄에 나란히 (v0.313). 각각 한 줄씩 세우면 세 줄이 되어
   고객센터와 로그아웃 사이가 벌어지고, 그 사이에 낀 로그아웃이 안 보인다.
   ⚠ 좁은 화면에서는 저절로 접힌다(`flex-wrap`) — 세 낱말이 375px 에 겨우 든다 */
.docrow{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
  gap:2px 4px;margin-top:34px;padding-bottom:4px}
/* 회원 탈퇴와 같은 얼굴이라 밑줄은 걷는다 — 낮춰 둔 자리는 다 같은 결이어야 한다 */
.docrow .linkb{margin:0;padding:6px 4px;text-decoration:none}
/* 사이에 가운뎃점 — 셋이 한 덩어리로 읽히지 않게 */
.docrow .linkb + .linkb::before{content:"·";margin-right:8px;color:var(--line)}
.docrow .linkb:hover{color:var(--seal)}
.linkb.quit{margin-top:10px;color:var(--fg-faint)}
.linkb.quit:hover{color:var(--danger)}
.btnrow.one .fbtn{flex:none;min-width:min(220px,64%)}
/* 안내는 화면 한가운데에 띄운다. 아래 구석에 뜨면 손이 가려 못 보고 지나간다.
   수라장에서만 아래로 내린다 — 가운데는 차례 배너와 연이 쓰는 자리다 */
/* ═══ 동양풍 액자 — **그림 파일을 쓰지 않는다** (v0.508 기획자가 정함) ═══════════
   창이 「그냥 네모 상자」라 밋밋했다. 눌러 둔 보랏빛 겹테를 둘러 무협 액자로 보이게 한다.
   ⚠⚠ **UI 그림을 뽑지 않은 까닭이 있다.** 글 길이가 제각각이라(한 줄짜리부터 세 줄짜리까지)
      그림으로 두르면 **늘어난 자리에서 테가 뭉개진다.** 테두리와 그라데이션으로 그리면
      폭이 얼마가 되든 선 굵기가 같다. 글꼴 크기를 키워도 따라온다.
   ⚠ 쓰려면 `class="... ornate"` 를 더한다. **클래스를 통째로 갈아 끼우는 자리**
      (`el.className=…`)에서는 `ornate` 를 같이 적어야 한다 — 안 적으면 테가 벗겨진다.
      공통 창(`.askbox`·`.stgbox`)은 **선택자로 걸어** 두어 손으로 더할 것이 없다.

   ⚠⚠ **겹테와 꺾쇠는 `::before`·`::after` 가 아니라 「배경 층」이다** (2026-10-12).
      처음에는 가상 요소로 그렸는데, **스크롤이 있는 창**(`.stgbox` — 관문 이야기·시즌 보상·
      명운 고르기)에서는 그것이 **안쪽 글과 함께 굴러가** 테가 밀려 올라갔다.
      배경은 기본값(`background-attachment:scroll`)이 **칸에 붙어 있고 글만 구르므로**
      어떤 창에서도 제자리를 지킨다. **가상 요소로 되돌리지 마라** — 스크롤 창에서 깨진다 */
/* ⚠ **획득 창도 이 테를 쓴다** (2026-10-12). 예전에는 틀마다 **그림**을 깔아 비켜 갔는데,
   그 그림에 지붕과 기둥이 그려져 있어 안쪽 여백을 **너비 비율(%)**로 잡아야 했고,
   글이 길어지면 지붕에 올라탔다. 그림을 걷고 이 테로 모았다 (아래 「획득 창」 머리말).
   ⚠ **이레 출석(`.att7`)만 그대로 그림틀이다** — 칸 일곱이 그림에 그려져 있어 걷을 수 없다 */
/* ⚠⚠ **획득 창은 2026-10-12 저녁에 이 테에서 다시 빠졌다** (기획자, 레퍼런스 지정 —
   「딤드를 활용한 보상 안내 팝업 · 기존 툴팁 팝업과는 전혀 다른 현대적인 팝업」).
   레퍼런스에는 **테가 아예 없다** — 어둡게 깐 막 위에 마름모·머리글·칸만 뜬다.
   테를 두르면 「창 안에 담긴 것」이 되고, 레퍼런스는 **화면 위에 떠오른 것**이다.
   ⚠ 되돌리려거든 아래 `:not(.gainbox)` 하나만 걷으면 된다. 그러면 `#vGain .gainbox` 의
     `border:0` 줄도 함께 걷어야 한다 — 안 그러면 테만 지워진 빈 판이 남는다 */
/* ⚠⚠ **관문 창도 2026-10-13 에 이 테에서 빠졌다** (기획자 — 「딤드 검은 투명도를 활용한
   보상 획득 팝업 식으로」). 획득 창과 같은 까닭이다 — 테를 두르면 「창 안에 담긴 것」이 되고,
   이 꼴은 **화면 위에 떠오른 것**이다.
   ⚠ 다만 **선택자에서 빼지 않고 테만 걷는다**(아래 `.stgbox{border:0…}`). 여기 적힌
     `--og` 세 빛깔을 **마름모(`.stg-mark`)가 물려받아** 쓰기 때문이다 — 선택자에서 빼면
     마름모가 빛깔을 잃고 기본값으로 떨어진다 */
.ornate,
.veil.ask .askbox:not(.att7):not(.gainbox),
.stgbox{
  /* ⚠⚠ **보랏빛이다. 금빛이 아니다** (2026-10-12 기획자가 정함 — 「기존 우리 게임 톤의
     보라색 느낌이 좋을 듯」). 처음에 천기 금빛으로 뽑았더니 게임 전체의 먹보랏빛과 따로 놀았다.
     ⚠ **한 번 더 눌렀다** (기획자: 「톤 좀 더 낮춰봐」). 쨍한 보라는 창이 글보다 먼저 눈에 들어온다 —
        테는 글을 담는 그릇이지 볼거리가 아니다.
     ⚠ **영석(`--yeong` `#a97cff`)과는 갈라 둔다** — 그쪽은 쨍한 보라이고 이것은 눌러 둔 보라다.
        테가 재화와 같은 빛이면 어느 쪽이 값인지 흐려진다 */
  --og:#6b5d8c;                /* 보랏빛 바탕 */
  --og-hi:#9b8fbb;             /* 빛 받는 쪽 — 위 */
  --og-lo:#2e2744;             /* 그늘 — 아래 */
  --ct:1px;                    /* 꺾쇠 굵기 */
  --cl:9px;                    /* 꺾쇠 길이 */
  --ci:6px;                    /* 꺾쇠를 안쪽으로 들인 거리 */
  position:relative;
  border:3px solid transparent;
  /* 층 차례 — 위에 적은 것이 앞에 선다.
     ① 네 귀 꺾쇠 여덟 장 ② 면 ③ 테.
     ⚠ 꺾쇠가 **「동양 액자」로 읽히게 하는 핵심**이다. 빼면 그냥 보라 테 상자가 된다.
     ⚠ 면은 **거의 검정**이어야 한다 — 밝으면 테가 묻히고 글자도 흐려진다.
     ⚠ 면도 **먹보라**다(265도) — 바탕 그림과 색상이 같아야 붙여 놓아도 겉돌지 않는다 */
  background:
    linear-gradient(var(--og-hi),var(--og-hi)) left  var(--ci) top    var(--ci)/var(--cl) var(--ct) no-repeat padding-box,
    linear-gradient(var(--og-hi),var(--og-hi)) left  var(--ci) top    var(--ci)/var(--ct) var(--cl) no-repeat padding-box,
    linear-gradient(var(--og-hi),var(--og-hi)) right var(--ci) top    var(--ci)/var(--cl) var(--ct) no-repeat padding-box,
    linear-gradient(var(--og-hi),var(--og-hi)) right var(--ci) top    var(--ci)/var(--ct) var(--cl) no-repeat padding-box,
    linear-gradient(var(--og-hi),var(--og-hi)) left  var(--ci) bottom var(--ci)/var(--cl) var(--ct) no-repeat padding-box,
    linear-gradient(var(--og-hi),var(--og-hi)) left  var(--ci) bottom var(--ci)/var(--ct) var(--cl) no-repeat padding-box,
    linear-gradient(var(--og-hi),var(--og-hi)) right var(--ci) bottom var(--ci)/var(--cl) var(--ct) no-repeat padding-box,
    linear-gradient(var(--og-hi),var(--og-hi)) right var(--ci) bottom var(--ci)/var(--ct) var(--cl) no-repeat padding-box,
    radial-gradient(120% 150% at 50% 0%,#1d1927f5,#0e0c13f8 72%) padding-box,
    linear-gradient(180deg,var(--og-hi),var(--og) 38%,var(--og-lo)) border-box;
  box-shadow:
    inset 0 0 0 1px #000c,                  /* 테 바로 안쪽의 어두운 선 — 테를 도드라지게 한다 */
    inset 0 1px 0 #ffffff0d,
    inset 0 -16px 28px -14px #000d,         /* 아래가 가라앉아 면이 평평해 보이지 않는다 */
    0 0 0 1px #0b0910,                      /* 테 **바깥**의 어두운 선 — 배경으로 번지지 않는다 */
    0 8px 30px #000b;
}
.toast{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) scale(.94);z-index:40;
  padding:14px 22px;border-radius:3px;
  /* ⚠ 글꼴과 글자색은 **손대지 않는다** (기획자: 「폰트는 우리거 유지」) — 본문 글꼴(`--sans`)을
     그대로 물려받는다. 바뀐 것은 상자와 테두리뿐이다. 그림자는 금테 옆에서 글자가 묻히지 않을
     만큼만 둔다 */
  font-size:13px;line-height:1.5;color:var(--fg);pointer-events:none;opacity:0;
  text-shadow:0 1px 2px #0009;
  transition:opacity .2s,transform .2s;text-align:center;
  /* ⚠⚠ **좁았던 진짜 까닭은 `max-width` 가 아니었다** (2026-09-30 제보).
     `position:absolute` + `left:50%` 만 두면 브라우저가 쓸 수 있다고 보는 폭이
     **왼쪽 절반부터 오른쪽 끝까지**, 곧 화면의 **절반뿐**이다. 가운데로 옮기는 것은
     `transform` 이라 자리를 잡은 **뒤의** 일이라, 폭을 셀 때는 아직 왼쪽 끝에 있다.
     360px 화면에서 180px 밖에 못 쓰니 열일곱 자짜리 한 문장이 두 줄로 접혔다.
     `width:max-content` 로 **한 줄 폭을 먼저 잡고**, 그 위를 `max-width` 로 막는다.
     ⚠ 그래서 이것은 이 안내 하나가 아니라 **게임의 모든 쪽지**가 함께 넓어지는 고침이다.
     ⚠ `keep-all` — 한글은 이것이 없으면 **낱글자 단위로 끊긴다.** 「해금됩니」/「다」 같은 꼴이 난다 */
  width:max-content;max-width:min(90%,420px);word-break:keep-all}
.toast.on{opacity:1;transform:translate(-50%,-50%) scale(1)}
.app.battle-wide .toast{top:auto;bottom:96px;transform:translate(-50%,6px) scale(.96)}
.app.battle-wide .toast.on{transform:translate(-50%,0) scale(1)}
.devbox{border:1px dashed var(--line);border-radius:var(--r-s);padding:11px 12px;display:flex;flex-direction:column;gap:9px}
.mini{padding:6px 11px;border:1px solid var(--line);border-radius:var(--r-s);font-size:11.5px;color:var(--fg-mid)}
.mini:hover{border-color:var(--seal);color:var(--fg)}
.mini.dg:hover{border-color:var(--danger);color:var(--danger)}
/* 출전 화면도 **같은 격자**다 — 칸 수와 폭이 어긋나면 같은 명운이 다르게 보인다 */
.pick{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px 10px}
@media (min-width:400px){ .pick{grid-template-columns:repeat(4,minmax(0,1fr))} }
/* ===== 혈투 로비 (v151 · 혈투 기획 §9) =====
   가운데가 지금 경지, 왼쪽이 내려앉을 자리, 오른쪽이 올라설 자리.
   `1fr auto 1fr` 이라 한쪽이 비어도 **가운데는 가운데에 선다** */
/* 혈투 로비 — **혈투 단추를 바닥에 붙인다** (v171). 아래에 아무 글도 두지 않으므로 하단 바 바로 위에 온다.
   ⚠ `.screen.on` 이 이미 세로 flex 다. 여기에 `#s-pvp{display:flex}` 를 또 쓰면 **화면이 안 감춰진다** —
   `.screen{display:none}`(0,1,0) 보다 아이디(1,0,0)가 이겨 늘 떠 있게 된다. v172 에 그렇게 당했다 */
#s-pvp > #pvGo{margin-top:auto}
/* 24칸을 다 깔고 옆으로 민다 (v152). 좌우 여백은 첫 칸·끝 칸도 가운데까지 올 수 있게 넉넉히.
   ⚠ 위 여백은 **경지 문양이 들어올 자리**를 미리 비워 둔 것이다 (v171) — 문양이 붙으면 다시 잰다 */
.pvrail{display:flex;align-items:center;gap:clamp(3px,calc(var(--app-w) * .012),8px);
  /* 칸 너비를 **큰 문양에 맞춰 고정**한다 (v181). 가운데 칸이 커질 때 줄 전체가 밀리면
     스크롤이 손에서 미끄러진다 — 너비가 늘 같으면 커지는 것은 문양뿐이고 줄은 가만히 있다.
     칸이 넓어진 만큼 **사이(gap)는 좁힌다** — 안 그러면 한 화면에 세 칸도 안 들어온다 */
  --pvw:clamp(78px,calc(var(--app-w) * .23),100px);
  /* ⚠ **위아래로 자리를 벌린다** (v192). `overflow-x:auto` 는 세로축도 `auto` 로 바꾸므로
     1단의 금빛 빛무리(`.pv-em.art.d1::before` 의 `box-shadow`, 밖으로 26px)가 **잘려 나갔다.**
     줄 안쪽에 14px 을 벌리고 바깥 여백에서 같은 만큼 되돌린다 — 자리는 그대로고 잘림만 없어진다.
     세로 막대도 숨긴다. 이 줄은 옆으로만 미는 자리다 */
  /* ⚠ 1단 금빛이 깜빡일 때는 밖으로 38px 까지 번진다 — 위아래 36px 을 벌린다.
     출전 명운의 「30/30 · 출전 가능」 줄을 걷은 만큼 전체가 아래로 내려앉는다 */
  margin:calc(26px + var(--top-gap) - 14px) -16px 2px;padding:36px 44%;
  /* **`scroll-behavior:smooth` 를 걸지 않는다.** 걸어 두면 `scrollLeft=…` 이 부드러운 이동으로 바뀌는데,
     화면이 가려져 있거나 방금 켜진 참이면 그 이동이 끝나지 못해 **아예 안 움직인다** (v152) */
  overflow-x:auto;overflow-y:hidden;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
.pvrail::-webkit-scrollbar{display:none}
.pvcell{flex:none;width:var(--pvw);display:flex;flex-direction:column;align-items:center;gap:3px;
  opacity:.34;transition:opacity .2s}
.pvcell.past{opacity:.2}            /* 이미 지나온 칸은 한 겹 더 물린다 */
.pvcell.now{opacity:1}
/* ===== 줄 한가운데에 온 칸 (v181) =====
   밀어서 가운데에 온 경지는 **지금 칸과 같은 크기**로 선다 — 문양도 이름도.
   작은 문양 46px 로는 여덟 경지가 서로 안 갈렸다. 가운데만 크면 **미는 대로 하나씩 읽힌다.**
   ⚠ 다만 **켜지지는 않는다.** 크기만 같고 밝기는 중간이며, 「지금」 딱지도 금빛 깜빡임도 없다 —
   커진 것이 곧 내 경지로 읽히면 몇 단인지 헷갈린다. 지금 칸은 여전히 저 혼자 또렷하다 */
.pvcell.mid:not(.now){opacity:.62}
.pvcell.mid:not(.now) .pv-em{--em:clamp(74px,calc(var(--app-w) * .22),96px)}
.pvcell.mid:not(.now) .pv-ko{font-size:clamp(15px,round(calc(var(--app-w) * .044), 1px),18px);letter-spacing:.04em;color:#e6dccb}
.pvcell.mid:not(.now) .pv-dan{font-size:10px}
.pvcell:not(.now) .pv-cap:empty{min-height:1em}   /* 딱지가 없어도 높이는 같게 — 줄이 들쭉날쭉하지 않는다 */
.pv-cap{font-family:var(--mono);font-size:8.5px;letter-spacing:.2em;text-indent:.2em;color:var(--fg-faint)}
.pv-cap.dn{color:#e0928a} .pv-cap.up{color:#8fe0a8}
/* 문양이 아직 없다 — 한자를 새긴 원패로 대신한다. `assets/ui/rank_*.webp` 가 오면 갈아 끼운다 */
.pv-em{position:relative;display:flex;align-items:center;justify-content:center;
  width:var(--em,46px);height:var(--em,46px);border-radius:50%;
  transition:width .18s ease,height .18s ease;
  font-family:var(--han);font-size:calc(var(--em,46px) * .34);line-height:1;color:#efe4cf;
  border:1px solid #5b5040;background:radial-gradient(70% 70% at 50% 34%,#2b2536,#15121c);
  box-shadow:inset 0 0 14px #0009,0 3px 10px #0008;
  text-align:center;padding:2px;word-break:keep-all}
.pv-em.big{--em:clamp(74px,calc(var(--app-w) * .22),96px);border-color:var(--seal);color:#f6ecd8;
  box-shadow:inset 0 0 18px #0009,0 0 0 1px #00000080,0 6px 20px #000a,0 0 22px #a97cff1f}
/* ── 경지 문양 (v173) ─────────────────────────────────────────
   그림은 둘레가 투명한 256×256 이다. 원패 바탕과 테는 걷고 **그림만** 세운다 —
   바탕을 깔면 그림의 빛무리가 네모난 판 위에 얹힌 것처럼 보인다 */
.pv-em.art{border:0;background:none;box-shadow:none;padding:0;overflow:visible}
.pv-emi{width:100%;height:100%;object-fit:contain;display:block;
  filter:drop-shadow(0 2px 6px #000a)}
/* 단(段)마다 테가 다르다. **3 → 2 → 1 로 갈수록 밝아진다** — 경지 안에서 어디까지 왔는지가 한눈에 읽힌다.
   테는 그림 뒤에 원으로 깐다(`::before`) — 그림 자체에 테를 두르면 빛무리까지 잘린다 */
.pv-em.art::before{content:"";position:absolute;inset:6%;border-radius:50%;pointer-events:none}
/* 3단 — **채도만 낮춘다** (v177). 흑백으로 돌렸더니 여덟 경지의 3단이 다 똑같아 보였다.
   빛깔이 남아 있어야 절정 3단은 보랏빛, 이류 3단은 풀빛으로 서로 갈린다.
   ⚠ **어둡게(brightness) 하지 않는다.** 이 문양은 나중에 맞대결 화면에도 그대로 쓴다 —
   딤드를 문양에 박아 두면 거기서도 죽은 채로 나온다. 흐리게 할 일이 있으면 **칸 쪽**에서 한다 */
.pv-em.art.d3 .pv-emi{filter:saturate(.38) drop-shadow(0 2px 6px #000a)}
.pv-em.art.d3::before{border:1px solid #7a7480aa}
/* 2단 — 빛깔이 거의 돌아오고 은색 테가 붙는다 */
.pv-em.art.d2 .pv-emi{filter:saturate(.82) drop-shadow(0 2px 6px #000a)}
.pv-em.art.d2::before{border:1px solid #cdd6e0;
  box-shadow:0 0 7px #aab7c480,inset 0 0 9px #cdd6e024}
/* 1단 — 각연자와 **같은 금빛**이다 (`.engaura` 와 한 몸). 경지를 넘기 직전이라는 표다 */
.pv-em.art.d1::before{border:2px solid #ffe9a8;
  box-shadow:0 0 12px 2px #ffd25fb0,0 0 26px 5px #fff3c855,inset 0 0 12px #ffdf8630;
  animation:engglow2 1.9s ease-in-out infinite}
@keyframes engglow2{
  50%{box-shadow:0 0 17px 4px #ffdf86,0 0 38px 9px #fff6d677,inset 0 0 16px #ffdf8644}}
/* 지나온 칸은 흐리게 두되(`.pvcell.past`) **금빛까지 깜빡이면 눈이 아프다** — 지금 칸에서만 돈다 */
.pvcell:not(.now) .pv-em.art.d1::before{animation:none}
/* 「지금」 칸에만 도는 빛무리 (v181) — 가운데 칸도 같은 크기로 서게 되면서
   **크기만으로는 둘이 안 갈린다.** `.pv-em.big` 의 테·빛은 `.art` 가 걷어 버려(문양은 바탕이 없다)
   그림 문양에는 아무 표가 남지 않았다. 여기서 도장 빛(`--seal`)으로 한 겹 두른다.
   ⚠ **문양 자체는 건드리지 않는다** — 칸 쪽에서 두르는 것이라 맞대결 화면에 그대로 옮겨도 된다 */
.pvcell.now .pv-em.art::after{content:"";position:absolute;inset:-7%;border-radius:50%;pointer-events:none;
  box-shadow:0 0 20px 5px #a97cff38,inset 0 0 26px #a97cff24}
.pv-ko{font-family:var(--serif);font-size:11px;font-weight:700;color:#ddd3c2;white-space:nowrap;
  transition:font-size .18s ease,color .18s ease}
.pvcell.now .pv-ko{font-size:clamp(15px,round(calc(var(--app-w) * .044), 1px),18px);color:#f2ebdf;letter-spacing:.04em}
.pv-dan{font-family:var(--mono);font-size:8.5px;color:var(--fg-faint);letter-spacing:.06em}
.pvcell.now .pv-dan{font-size:10px}
/* 공 막대 — 100이면 한 단 오른다 */
.pvbarw{margin-bottom:16px;position:relative}
.pvbar{height:7px;border-radius:4px;background:#ffffff12;overflow:hidden;
  border:1px solid #2a2530}
/* 막대는 스크립트가 한 틱씩 민다(`pvGauge`) — CSS 전이를 겹치면 뒤처져 따라온다 */
.pvbar > i{display:block;height:100%;width:0;border-radius:4px;
  background:linear-gradient(90deg,#6f5ba8,#b79bff)}
/* 판에서 얻은·잃은 경지 — 막대 오른쪽 위에 잠깐 뜬다 */
.pvd{position:absolute;right:0;bottom:calc(100% + 1px);opacity:0;pointer-events:none;
  font-family:var(--mono);font-size:12px;font-weight:700}
.pvd.up{color:#c9b6ff}
.pvd.dn{color:var(--warn)}
/* 직전 판에서 **오르내린 몫**만 따로 칠한다 (v0.507 기획자가 정함).
   막대 빛깔 하나로는 「이번 판에 얼마나 움직였나」가 안 읽혔다 — 오른 몫은 초록, 잃은 몫은 적색이다.
   ⚠ **직전 기록이 없으면 칠하지 않는다**(`on` 이 안 붙는다) — 로그아웃하고 다시 들어오거나
      판을 아직 안 둔 자리에서는 기본 빛깔 그대로다. 그것이 「이번 판」이라는 뜻을 지킨다.
   ⚠ `#pvFill` 보다 **뒤에 놓인다** — 오른 몫은 찬 막대 위에 겹쳐 보여야 하고,
      잃은 몫은 찬 막대 바깥의 빈 자리에 남아야 한다 */
.pvbar{position:relative}
.pvbar > .pvgain{position:absolute;top:0;height:100%;width:0;border-radius:4px;
  opacity:0;transition:opacity .22s linear}
.pvbar > .pvgain.on{opacity:1}
.pvbar > .pvgain.up{background:linear-gradient(90deg,#2f7d4f,#5fd196)}
.pvbar > .pvgain.dn{background:linear-gradient(90deg,#7d2f33,#d4615a)}
/* 승단·강등 알림 — 토스트 한 줄로는 가장 큰 사건이 그냥 지나갔다 (v0.507).
   줄이 옆 칸으로 밀리고 나서 가운데에 떠올라 무슨 일이 일어났는지 말한다.
   ⚠ `position:fixed` 다 — 경지 줄(`.pvrail`)은 옆으로 구르는 자리라 그 안에 넣으면 같이 밀린다 */
/* ⚠ **경지 줄 위에 겹치지 않는다.** 38% 에 두었더니 문양과 글자가 서로를 먹었다 —
   줄과 막대 아래의 **빈 자리**에 선다. 무엇이 바뀌었는지는 줄이 보여 주고, 이 판은 말을 맡는다 */
.pvban{position:fixed;left:50%;top:58%;transform:translate(-50%,-50%);z-index:19;
  max-width:min(calc(var(--app-w) * .86),420px);padding:13px 20px;border-radius:10px;text-align:center;
  font-size:14px;line-height:1.5;letter-spacing:-.01em;pointer-events:none;
  background:linear-gradient(180deg,#1a1620f2,#120f18f2);
  border:1px solid var(--pb,#6f5ba8);
  box-shadow:0 0 18px color-mix(in srgb,var(--pb,#6f5ba8) 45%,transparent),0 6px 22px #000a}
.pvban.up{--pb:#d8b25a;color:#f3e6c4}
.pvban.dn{--pb:#8d3a38;color:#e4c9c7}
.pvmeta{display:flex;justify-content:space-between;gap:10px;margin-top:5px;
  font-family:var(--mono);font-size:10px;color:var(--fg-faint)}
.pvmeta > span:last-child{text-align:right}
.pvmeta > span.bad{color:var(--warn)}
/* 출전 명운 한 칸 — 명운 화면과 같은 타일을 단추 속에 넣는다 */
/* 출전 명운 — 타일 하나와 그 **아래 한 줄**. 혈투 단추는 아래에서 밀어 하단 바에 붙는다 */
.pvdeckw{display:flex;flex-direction:column;align-items:center;gap:9px;margin:8px 0 18px}
.pvpick{margin:0;font-size:11.5px;line-height:1.6;color:var(--fg-faint);text-align:center;max-width:86%}
.pvpick:empty{display:none}
.pvdeck{width:clamp(96px,calc(var(--app-w) * .3),118px);padding:0;background:none;border:0;
  -webkit-tap-highlight-color:transparent;transition:transform .12s}
.pvdeck:active{transform:scale(.96)}
/* 시즌 종료 보상 단추 — 혈투 화면 좌측 상단에 붙는다 */
.pvtop{position:absolute;z-index:2;top:calc(var(--top-gap) + 6px);left:16px;right:16px;
  display:flex;align-items:center;justify-content:space-between;gap:8px}
.pvleft{display:flex;align-items:center;gap:9px;min-width:0}
.pvsea{font-size:11.5px;color:var(--fg-mid);white-space:nowrap}
.pvrank{flex:none;height:32px;padding:0 13px;border:1px solid var(--seal);
  border-radius:var(--r-s);background:#0d0b11c0;color:var(--fg);font-family:var(--serif);
  font-size:12px;font-weight:700;-webkit-tap-highlight-color:transparent}
.pvrank:active{transform:scale(.95)}
.pvrwd{
  display:flex;align-items:center;gap:5px;height:32px;padding:0 10px 0 7px;
  border:1px solid #5c4a22;border-radius:var(--r-s);background:#0d0b11c0;
  font-family:var(--serif);font-size:12px;font-weight:700;color:var(--chungi);
  -webkit-tap-highlight-color:transparent;transition:transform .12s,border-color .14s}
.pvrwd img{width:18px;height:18px;object-fit:contain}
.pvrwd:active{transform:scale(.95);border-color:var(--chungi)}
/* 순위는 로비를 밀지 않고 별도 창에서 본다. 긴 명호는 줄 안에서만 접힌다. */
.pbbox{display:flex;flex-direction:column;gap:11px;width:min(100%,420px);max-height:94%;overflow:hidden}
.pbtabs{display:grid;grid-template-columns:1fr 1fr;gap:6px;flex:none}
.pbtab{height:36px;border:1px solid var(--line-soft);border-radius:var(--r-s);
  background:#ffffff08;color:var(--fg-mid);font-family:var(--mjo);font-size:13px;font-weight:700}
.pbtab.on{border-color:var(--seal);background:#7c86b62b;color:var(--fg)}
.pbscroll{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin}
.pbnear{flex:none;max-height:calc(var(--app-h) * .38);overflow-y:auto;padding-top:10px;border-top:1px solid var(--line-soft)}
.pbnear .pbsec{margin-top:0}
.pbsec{margin:0 0 8px;font-family:var(--mjo);font-size:13px;color:var(--fg-mid)}
.pbsec:not(:first-child){margin-top:20px}
.pbsec-icon{width:20px;height:20px;object-fit:contain;vertical-align:middle;margin-right:5px}
.pbrow{display:grid;grid-template-columns:28px 38px minmax(0,1fr) auto;align-items:center;gap:8px;
  width:100%;min-height:56px;margin:0 0 5px;padding:7px 9px;text-align:left;
  background:#ffffff08;border:1px solid var(--line-soft);border-radius:var(--r-s);color:var(--fg)}
.pbrow.me{border-color:var(--seal);background:#7c86b62b;box-shadow:inset 3px 0 var(--seal)}
.pbrow:active{transform:scale(.985)}
.pbplace{font-family:var(--mono);font-size:13px;font-weight:800;text-align:center;color:var(--chungi)}
.pbmine{display:block;font-family:var(--mjo);font-size:10px;line-height:1;color:var(--fg)}
.pbrow .face{width:38px;height:38px}
.pbnear .pbrow{grid-template-columns:28px 32px minmax(0,1fr) auto;min-height:46px;padding:4px 9px}
.pbnear .pbrow .face{width:32px;height:32px}
.pbwho{min-width:0;display:flex;flex-direction:column;line-height:1.3}
.pbname{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--mjo);font-weight:700}
.pbtag{font-size:10px;color:var(--fg-mid)}
.pbtier{display:inline-flex;align-items:center;gap:4px;font-family:var(--mjo);font-size:11px;white-space:nowrap;color:var(--fg-mid)}
.pbtier-icon{width:21px;height:21px;object-fit:contain;flex:none}
.pbnear .pbtier-icon{width:18px;height:18px}
.pbnone{margin:16px 0;color:var(--fg-mid);font-size:12px;text-align:center}
/* ⚠ 순위를 기다리는 자리 — 예전의 「화면 예시」(`.pbpreview`) 를 2026-10-17 에 걷고
   그 자리에 돌림개를 세웠다. 빈 순위 틀을 세우면 「순위가 없다」로 읽힌다 */
.pbwait{display:flex;align-items:center;justify-content:center;gap:9px;
  margin:28px 0;color:var(--fg-mid);font-size:12px}
.pbspin{width:17px;height:17px;flex:none;border-radius:50%;
  border:2px solid var(--seal);border-top-color:transparent;
  animation:pbspin .8s linear infinite}
@keyframes pbspin{to{transform:rotate(360deg)}}
/* ⚠ 어지럼을 줄이는 설정에서는 돌리지 않고 **깜박임**으로 바꾼다 */
@media (prefers-reduced-motion:reduce){
  .pbspin{animation:pbfade 1.2s ease-in-out infinite}
  @keyframes pbfade{0%,100%{opacity:1}50%{opacity:.35}}
}
.pbprof{padding:20px 13px}
.pbprof .avatar{display:block}
/* 시즌 종료 보상 창 — 머리와 닫기는 서 있고 목록만 구른다 */
.ssbox{display:flex;flex-direction:column;max-height:84%;overflow:hidden}
.ss-d{margin:8px 0 12px;font-size:12px;line-height:1.7;color:var(--fg-mid)}
.sslist{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;
  display:flex;flex-direction:column;gap:4px;margin:0 -6px 14px;padding:0 6px}
.ssrow{flex:none;display:grid;grid-template-columns:34px 76px 1fr auto;align-items:center;gap:8px;
  padding:5px 8px;border:1px solid transparent;border-radius:var(--r-s);background:#ffffff06}
.ssrow.now{border-color:#a97cff66;background:#a97cff14}
.ssrow .pv-em{--em:34px;font-size:11px}
.ssrow .pv-em.art.d1::before{animation:none;box-shadow:0 0 6px 1px #ffd25f90}
.ss-n{font-family:var(--serif);font-size:12.5px;font-weight:700;color:#e6dccb;white-space:nowrap}
.ss-n i{margin-left:5px;font-style:normal;font-family:var(--mono);font-size:8.5px;letter-spacing:.12em;color:#b79bff}
.ss-g{height:6px;border-radius:3px;background:#ffffff10;overflow:hidden}
.ss-g > i{display:block;height:100%;border-radius:3px;background:linear-gradient(90deg,#8a6f3a,var(--chungi))}
.ss-p{display:flex;align-items:center;gap:3px;justify-content:flex-end;min-width:62px;
  font-family:var(--num);font-size:12px;font-weight:700;color:var(--chungi);font-variant-numeric:tabular-nums}
/* 맞수를 찾는 동안 */
.veil.match{align-items:center;justify-content:center;background:#07060ae8}
.mbox{display:flex;flex-direction:column;align-items:center;gap:18px;max-width:390px;width:100%;padding:0 18px}
/* ⚠ 크기를 줄였다 (2026-10-06 기획자). 230px 은 손말틀에서 화면의 절반을 먹어
   아래 글이 밀려 내려갔다 — 기다리는 동안 읽을 것은 글이지 그림이 아니다 */
/* ⚠⚠ **그림은 틀 안에 띄워 세운다** (2026-10-07) — `tuImg` 가 겹쳐 넘기려면 복제가 원본과
   **같은 자리에 절대 위치**로 서야 한다. 흐름 속에 둔 채로 두면 겹침이 아예 안 돌고
   예전처럼 툭 갈아 끼워진다. 크기는 이제 **틀이 쥔다** — 그림은 틀을 가득 채운다.
   ⚠ 숨쉬기는 **틀에** 건다. 그림에 걸면 복제가 제 박자로 따로 흔들려 겹치는 동안 떤다 */
/* ⚠ 심안녀는 **맞수를 기다리는 동안 곁에 선 사람**이라 화면을 차지하면 안 된다
   (2026-10-07 기획자 — 「더 작게」). `min(46vw,168px)` 에서 한 단 내렸다 */
.mcharw{position:relative;flex:none;width:min(calc(var(--app-w) * .36),132px);height:min(calc(var(--app-w) * .36),132px);
  animation:mchar-breathe 3s ease-in-out infinite}
.mchar{position:absolute;left:0;top:0;width:100%;height:100%;object-fit:contain;
  filter:drop-shadow(0 12px 18px #0009)}
@keyframes mchar-breathe{50%{transform:translateY(-6px)}}
@media (prefers-reduced-motion:reduce){.mcharw{animation:none}}
/* ⚠⚠ **줄은 글이 가른다** (2026-10-06) — `MATCH_SCENES` 가 둘로 나눠 `\n` 으로 넘긴다.
   `pre-line` 이라야 그 `\n` 이 줄바꿈으로 선다. 폭이 더 좁으면 그 안에서 한 번 더 접힌다.
   ⚠ 낱말 가운데는 자르지 않는다 — 한국말이다 */
.mtx{margin:0;text-align:center;font-family:var(--serif);font-size:13.5px;line-height:1.7;color:#ddd3c2;
  white-space:pre-line;word-break:keep-all;overflow-wrap:break-word;
  min-height:3.4em;display:flex;flex-direction:column;align-items:center;justify-content:center}
/* 말도 겹쳐 넘긴다 — 지는 동안 `.fade` 가 서고, 새 말을 적은 뒤에 걷는다 (`sceneTx`).
   ⚠ 키(`min-height`)를 그대로 두는 까닭 — 두 줄과 한 줄이 번갈아 서면 아래 단추가 들썩인다 */
.mtx{transition:opacity .24s ease-in-out}
.mtx.fade{opacity:0}
.mbox .fbtn{flex:none;min-width:130px}
/* 통신 대기 창의 아랫줄 — 무슨 일인지 한 줄로만 말한다 (2026-10-06).
   심안녀의 말(`.mtx`)은 **기다리는 동안의 결**이고, 이 줄은 **까닭**이다. 둘을 섞지 않는다 */
.msub{margin:0;text-align:center;font-size:11.5px;line-height:1.6;color:var(--fg-faint);
  letter-spacing:.02em}

/* ═══ 맞수 소개 — 매칭이 되고 멀리건에 들기 전 2초 (2026-10-05 기획자가 정함) ═══════
   「좌에서 내가 우에서 상대가 가운데로 들어오면서 vs 나오고나서 2초 유지되다가 멀리건」.
   ⚠ **배경은 맞수 찾기와 같은 창(`.veil.match`)을 그대로 쓴다** — 대기 연출(`#mBox`)만 걷고
      이것을 세운다. 창을 새로 띄우면 배경이 한 번 깜빡여 「딴 화면으로 갔다」로 읽힌다.
   ⚠ 보이는 것은 **초상화 · 명호 · 경지** 셋뿐이다. 태그(#0000)는 적지 않는다(기획자).
   ⚠⚠ **양쪽을 한 꼴로 그린다.** 맞수 쪽만 빈 칸이 뜨면 그것이 봇이라는 표가 된다 (혈투 §5.2).
   ⚠ 가로로 셋이 서므로 좁은 기기에서 가운데 VS 가 눌리지 않게 **양옆만 줄어든다**(minmax) */
.vsbox{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:clamp(6px,calc(var(--app-w) * .025),12px);
  width:100%;max-width:320px;padding:0 8px}
.vsbox[hidden]{display:none}
.vs-side{display:flex;flex-direction:column;align-items:center;gap:7px;min-width:0}
/* 들어오는 길 — 내 쪽은 왼쪽에서, 맞수는 오른쪽에서. 멈춘 자리에서 더 움직이지 않는다 */
.vs-me{animation:vsin-l .52s cubic-bezier(.17,.84,.44,1) both}
.vs-foe{animation:vsin-r .52s cubic-bezier(.17,.84,.44,1) both}
@keyframes vsin-l{from{opacity:0;transform:translateX(-46%)}to{opacity:1;transform:none}}
@keyframes vsin-r{from{opacity:0;transform:translateX(46%)}to{opacity:1;transform:none}}
/* 초상화 — `.face` 한 벌을 그대로 쓰고 **크기와 테만** 이 자리에 맞춘다.
   ⚠⚠ **`background` 축약을 쓰지 마라** (2026-10-05 에 밟았다). `.face` 가
      `background:#1a1622 center 22% / cover no-repeat` 로 **자리와 배율까지** 잡아 두는데,
      여기서 축약을 한 번 더 쓰면 그 둘이 기본값(`auto`·`0 0`)으로 되돌아가 **큰 그림의
      왼쪽 위 귀퉁이만** 보인다 — 화면에는 「빈 동그라미」로만 보여 까닭을 찾기 어렵다.
      바탕색을 바꿀 일이 있으면 `background-color` 한 줄로 적는다.
   ⚠ `.face` 가 `height:100%` 라 그대로 두면 비율이 안 선다 — `auto` 로 되돌린다 */
.vs-face{flex:none;width:clamp(62px,calc(var(--app-w) * .19),84px);height:auto;aspect-ratio:1;
  border:1px solid var(--line);box-shadow:0 6px 18px #000a}
/* 명호 — 길면 줄인다. **두 줄로 접지 않는다**(한 줄에 서야 양쪽 키가 같다) */
.vs-n{font-family:var(--mjo);font-size:clamp(12px,round(calc(var(--app-w) * .036), 1px),15px);font-weight:800;letter-spacing:.04em;
  color:#f6f0e4;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  text-shadow:0 1px 3px #000,0 2px 8px #000c}
/* 경지 — 「삼류 3단」 명칭만. 공(功)이나 칸 수는 적지 않는다 */
.vs-g{font-family:var(--serif);font-size:clamp(9.5px,round(calc(var(--app-w) * .028), 1px),11.5px);font-weight:700;letter-spacing:.08em;
  color:#c7b68f;white-space:nowrap;text-shadow:0 1px 3px #000}
/* VS — ⚠ **지금은 글씨다.** 그림이 오거든 이 칸의 속만 갈아 끼운다(바깥 자리는 그대로 쓴다) */
.vs-mark{flex:none;font-family:var(--serif);font-weight:800;letter-spacing:.04em;
  font-size:clamp(26px,round(calc(var(--app-w) * .09), 1px),40px);line-height:1;color:#f0e2c0;
  text-shadow:0 2px 6px #000,0 0 18px #e8b45f66,0 0 34px #e8b45f33;
  animation:vsmark .42s .34s cubic-bezier(.2,1.5,.4,1) both}
@keyframes vsmark{from{opacity:0;transform:scale(.42)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .vs-me,.vs-foe,.vs-mark{animation:none} }

/* ===== 명운 타일 (v145) =====
   뒷면 그림 · 그 한가운데 도 문양 · 아래에 이름과 장수.
   명운 화면과 출전 화면이 이 한 벌을 나눠 쓴다 */
.dtile{display:flex;flex-direction:column;align-items:center;gap:6px;padding:0;min-width:0;
  background:none;border:0;text-align:center;-webkit-tap-highlight-color:transparent;
  transition:transform .12s}
.dtile:active{transform:scale(.96)}
.dt-back{position:relative;width:100%;aspect-ratio:63/88;border-radius:4px;
  background:url(assets/ui/pile_deck_back.webp?v=1) center/cover no-repeat,#151119;
  border:1px solid #4a4130;box-shadow:0 6px 16px #0009,inset 0 0 22px #00000066;
  display:flex;align-items:center;justify-content:center;overflow:hidden}
/* 문양은 뒷면 한가운데. 도 색으로 은은한 빛을 깔아 뒤에서 떠오르게 한다 */
.dt-back::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(58% 42% at 50% 50%,color-mix(in srgb,var(--pc,#8a7c5a) 42%,transparent),transparent 72%)}
.dt-sig{position:relative;z-index:1;width:56%;display:flex;align-items:center;justify-content:center}
.dt-sig-img{width:100%;height:auto;object-fit:contain;
  filter:drop-shadow(0 2px 6px #000c) drop-shadow(0 0 10px #0008)}
.dt-ok{position:absolute;right:4px;top:3px;z-index:2;font-size:11px;font-weight:800;color:var(--ok);
  text-shadow:0 1px 3px #000,0 0 8px #3f9e6388}
.dt-n{font-family:var(--mjo);font-size:12px;font-weight:700;line-height:1.25;
  width:100%;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 칸 열기의 값은 **영석 아이콘과 영석 빛깔**로 — 만보각·결연의 영석 값과 같은 꼴 (v0.225) */
.dt-m.yv{display:inline-flex;align-items:center;justify-content:center;gap:3px;color:var(--yeong)}
.dt-m.yv .mini-token{width:12px;height:12px}
.dt-m{font-family:var(--mono);font-size:9.5px;font-variant-numeric:tabular-nums;color:var(--fg-faint);
  line-height:1.2;width:100%;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 「2/30 · 미완성」은 **붉게** 쓴다 (v0.280) — 나갈 수 없다는 말이라 노란 주의색으로는 약하다 */
.dt-m.bad{color:var(--danger)}
/* 30장이 안 찬 명운 — 뒷면을 죽여 둔다. 출전 화면에서는 아예 못 고른다.
   ⚠ **`filter` 를 상자에 걸지 않는다** (v0.280). 걸면 자식까지 물들어 붉은 붓질이 잿빛이 된다.
      덮개 하나를 깔아 **그 아래만** 죽인다 — 붓질은 z-index 1 이라 덮개 위에 남는다 */
.dtile.no .dt-back{filter:none}
.dtile.no .dt-back::after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  -webkit-backdrop-filter:grayscale(.7) brightness(.62);backdrop-filter:grayscale(.7) brightness(.62)}
/* 붓질은 붉은 기운을 머금게 — 문양의 금빛 그림자와 다른 결이어야 한다 */
.dt-sig-img.dt-x{filter:drop-shadow(0 2px 6px #000c) drop-shadow(0 0 12px #c4453a66)}
.dtile[disabled]{opacity:.45;cursor:default}
.dtile[disabled]:active{transform:none}
/* 뒷면에 손을 올리거나 누르면 다른 단추들과 같은 빛이 돈다 (v150).
   `filter` 가 아니라 `box-shadow` 로 두른다 — 30장이 안 찬 명운은 filter 로 죽여 두었다 */
@media (hover:hover) and (pointer:fine){
  .dtile:not([disabled]):not(.empty):not(.lock):hover .dt-back{
    border-color:#4dffa055;box-shadow:0 0 0 1px #4dffa055,0 0 14px #4dffa04d,0 6px 16px #0009}
}
.dtile:not([disabled]):not(.empty):not(.lock):active .dt-back{
  border-color:var(--ready);box-shadow:0 0 0 2px var(--ready),0 0 18px #4dffa0aa,0 6px 16px #0009}
.dtile.on .dt-back{border-color:var(--seal);box-shadow:0 0 0 2px var(--seal),0 6px 18px #0009}
.dtile.on .dt-n{color:#f3e4e1}
/* 빈 칸·잠긴 칸 */
.dtile.empty .dt-back,.dtile.lock .dt-back{background:none;border-style:dashed;border-color:var(--line);box-shadow:none}
.dtile.empty .dt-back::before,.dtile.lock .dt-back::before{display:none}
/* 빈 명운 — 점선 안을 **기본 강조색**으로 옅게 채워 「여기에 엮는다」가 읽히게 (v0.227) */
.dtile.empty .dt-back{background:color-mix(in srgb,var(--seal) 13%,transparent);border-color:color-mix(in srgb,var(--seal) 55%,var(--line))}
.dtile.empty .dt-lock{color:var(--seal)}
/* 명운 공간 추가 — 자물쇠 + 검은 딤드. 빈 명운과 한눈에 갈린다 */
.dtile.lock .dt-back{background:#000000b3}
.dtile.lock{opacity:.85}
.dt-lock{font-size:22px;color:var(--fg-faint);line-height:1;display:flex;align-items:center;justify-content:center}
/* 자물쇠는 그림이다 (v0.235). 빈 명운의 「＋」는 글자 그대로라 위의 `.dt-lock` 을 함께 쓴다 —
   그림이 들어가는 쪽만 이 줄이 크기를 정한다 */
.dt-lock.lockpic{width:34px;height:34px;
  background:url(assets/ui/icon_deck_slot_lock.webp?v=1) center/contain no-repeat}
@media (hover:hover) and (pointer:fine){
  .dtile:not([disabled]):hover .dt-back{border-color:var(--seal)}
}

/* 도 문양 고르기 */
.edsig{flex:none;display:flex;align-items:center;gap:5px;padding:6px 9px;
  border:1px solid var(--line);border-radius:var(--r-s);background:var(--ink-2);
  font-size:11px;letter-spacing:.06em;color:var(--fg-mid);-webkit-tap-highlight-color:transparent}
.edsig:active{border-color:var(--seal);color:var(--fg)}
.edsig-i{width:20px;height:20px;display:flex;align-items:center;justify-content:center}
.edsig-i .dt-sig-img{width:20px;height:20px}
.sigpick{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:14px 0 18px}   /* 아래 단추와 한 뼘 띄운다 (v0.226) */
#vIcon .btnrow{gap:10px}
.sigb{display:flex;flex-direction:column;align-items:center;gap:5px;padding:10px 4px;
  border:1px solid var(--line);border-radius:var(--r-s);background:var(--panel);
  font-size:11px;color:var(--fg-mid);-webkit-tap-highlight-color:transparent}
.sigb .dt-sig-img{width:34px;height:34px}
.sigb.on{border-color:var(--seal);background:var(--seal-deep);color:#f3e4e1}
.sigb.on .dt-sig-img{filter:drop-shadow(0 0 8px #c4453a88)}
/* 잠긴 문양 — 이 명운의 종파가 아닌 것 (v204). 제 종파와 무도만 고를 수 있다 */
.sigb.off{opacity:.26;pointer-events:none}
.sigb.off .dt-sig-img{filter:grayscale(1)}

.prow{display:flex;align-items:center;gap:10px;padding:11px 12px;border:1px solid var(--line);border-radius:var(--r-s);
  background:var(--panel);text-align:left;width:100%}
.prow:hover{border-color:var(--seal)}
.prow[disabled]{opacity:.38;cursor:default}
.prow.on{border-color:var(--seal);background:var(--panel-2)}
.prow b{font-family:var(--serif);font-size:14px;font-weight:700;display:block}
.prow span{font-size:11px;color:var(--fg-mid);display:block;margin-top:2px}

/* ===== 튜토리얼 강제 포커싱 (v0.226) — docs/KWCCG_튜토리얼.md §5 =====
   구멍 둘레의 네 판(`.tf-p`)이 검게 덮고 눌림을 받아 버린다. 구멍은 비어 있어 그 아래 카드·칸이 눌린다.
   말풍선과 손가락 그림은 나중에 이 위에 얹는다 */
#tfocus{position:fixed;inset:0;z-index:75;pointer-events:none}
#tfocus[hidden]{display:none}
#tfocus .tf-p{position:fixed;background:#000000c2;pointer-events:auto;transition:opacity .16s}
#tfocus .tf-ring{position:fixed;pointer-events:none;border-radius:6px;
  box-shadow:0 0 0 2px #f2e6c9cc,0 0 18px 4px #f2e6c966;animation:tfring 1.2s ease-in-out infinite}
@keyframes tfring{50%{box-shadow:0 0 0 3px #fff3d6,0 0 26px 7px #f2e6c999}}

/* 소리 채널별 조작 및 확정 승패 붓글씨 */
.mic-pic.sound-bgm{background-image:url(assets/ui/icon_sound_bgm.webp?v=1)}
.mic-pic.sound-sfx{background-image:url(assets/ui/icon_sound_sfx.webp?v=4)}
.result .rstamp:has(img){text-indent:0;line-height:1.2}
.rstamp img{display:block;width:4em;height:1.57em;object-fit:contain}
.summon-ghost.unit{max-width:none;transition:none}

/* ═══ 인과(因果) — 계정 레벨 (v0.524 · docs/KWCCG_인과.md §5) ═══════════════
   ⚠⚠ **한 덩이에만 적는다.** 파일 뒤쪽에 `.ig-*` 를 또 적지 마라 —
      2026-10-13 에 획득 창이 네 번 걸린 까닭이 「한 꼴을 여러 곳에 나눠 적은 것」이었다.
   ⚠⚠ **출석 창·보상 획득 창의 칸을 가져다 쓰지 않는다.** 그 둘을 한 번 묶었다가
      기획자가 갈라내라 해서 떼어 냈다 — 쓰임이 다른 칸을 묶으면 한쪽을 손볼 때마다
      다른 쪽이 따라 움직인다. **순례 관문 창의 칸을 본으로 삼되 제 벌을 쓴다.**
   ⚠ 겁 상자 줄은 **혈투 경지 줄(`.pvrail`)과 같은 버릇**이다 — 좌우 여백으로 첫 칸·끝 칸도
      가운데까지 오고, 가로로만 구른다. 두 자리가 다르게 움직이면 손이 헷갈린다 */

/* ── 메인 좌상단 프로필 (§5.1) ──
   초상화·이름·인과를 한 단추로 묶어 튜토리얼의 강조 범위도 실제 터치 범위와 같게 한다. */
.mhanb{position:relative;display:flex;align-items:center;gap:7px;min-width:0;width:min(100%,210px);
  min-height:43px;padding:4px 0;border:1px solid transparent;border-radius:var(--r-s);
  background:none;color:var(--fg);cursor:pointer;-webkit-tap-highlight-color:transparent}
.mhanb:focus-visible{outline:1px solid var(--seal);outline-offset:2px}
.mhanb:active{transform:scale(.97)}
.mprof-face{position:relative;display:block;flex:none;width:32px;height:32px;font-size:14px}
.mprof-face .nudot{--nx:-2px;--ny:-2px}
.mprof-copy{display:flex;flex:1;min-width:0;flex-direction:column;align-items:stretch;gap:2px}
.mprof-name{display:flex;align-items:baseline;gap:3px;max-width:100%;white-space:nowrap;
  font-family:var(--mjo);font-size:12px;font-weight:800;line-height:1.2;text-align:left}
.mprof-name #mProfName{min-width:0;overflow:hidden;text-overflow:ellipsis}
.mprof-tag{flex:none;color:var(--fg-faint);font-family:var(--mono);font-size:10px;font-weight:500}
/* 「2겁」과 띠가 한 줄에 선다 — 수가 왼쪽, 띠가 오른쪽(기획자) */
.mig-row{display:flex;align-items:center;gap:5px;width:100%}
.mig-k{flex:none;
  font-family:var(--mono);font-size:10.5px;font-weight:800;font-variant-numeric:tabular-nums;
  color:var(--chungi);letter-spacing:.01em;text-shadow:0 1px 3px #000}
/* 띠 — 혈투 막대(`.pvbar`)와 같은 치수다. 3px 로 두었더니 테를 빼고 1.4px 만 남아 안 보였다 */
.mig-bar{flex:1;min-width:0;display:block;height:5px;border-radius:3px;overflow:hidden;
  background:#ffffff1f;border:1px solid #2a2530;box-sizing:border-box}
/* ⚠ **노랑이다** (2026-10-13 기획자 — 「메인화면에 인과 게이지도 노랑톤으로」).
   왼쪽의 겁 수(`.mig-k`)가 이미 천기 금빛(`--chungi`)이라, 띠만 보랏빛이면 한 덩이로 안 읽혔다.
   ⚠ 인과 화면의 띠(`#igFill`)와는 **일부러 다르다** — 저쪽은 그 화면의 주인공이라 제 빛깔을 쓴다 */
.mig-bar > i{display:block;height:100%;width:0;border-radius:3px;
  background:linear-gradient(90deg,#8a6a2a,var(--chungi,#d4a843))}
/* 보상 금점은 단추 오른쪽 위, 새 초상화 점은 초상화 자체에 붙인다.
   둘 다 우편·무훈이 쓰는 `.nudot` 한 벌을 공유한다. */
.mhanb > .nudot{--nx:-3px;--ny:-3px}

/* ── 무명자 화면의 인과 탭 (§5.2) ── */
/* ⚠⚠ **`display` 를 여기서 적지 마라.** `.screen` 은 `display:none`, `.screen.on` 은 `flex` 인데
   **아이디 선택자가 그 둘을 다 이긴다** — 화면을 나가도 안 사라져 메인 위에 겹쳐 선다.
   2026-10-13 에 실제로 그렇게 떴다. `#s-camp` 가 `padding`·`gap` 만 적어 둔 까닭이 이것이다 */
.ightop{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:7px}
.igk{font-family:var(--serif);font-size:clamp(17px,round(calc(var(--app-w) * .05), 1px),21px);font-weight:700;letter-spacing:.04em;
  color:#f2ebdf}
.igamt{font-family:var(--mono);font-size:12px;font-variant-numeric:tabular-nums;color:var(--fg-mid)}
/* 띠 — 메인 프로필의 인과 게이지와 같은 금빛이다. */
.igbar{height:7px;border-radius:4px;background:#ffffff12;overflow:hidden;border:1px solid #2a2530;
  margin-bottom:11px}
.igbar > i{display:block;height:100%;width:0;border-radius:4px;
  background:linear-gradient(90deg,#8a6a2a,var(--chungi,#d4a843));transition:width .3s ease}

/* ── 겁마다의 한마디 (§8 · 기획자가 쓴 여든 줄) ──
   띠 아래에 **한 줄 띄워 가운데로** 선다(기획자). 고른 겁을 따라 바뀐다 */
.igsay{margin:0 0 10px;min-height:2.2em;display:flex;align-items:center;justify-content:center;
  padding:0 6px;text-align:center;
  font-family:var(--serif);font-size:12.5px;line-height:1.5;letter-spacing:.01em;
  color:var(--fg-mid);text-shadow:0 1px 6px #000}

/* ── 겁 상자 줄 — 마름모가 선으로 이어진 사다리 ──
   ⚠⚠ **띄엄띄엄 둔다** (2026-10-13 기획자 — 「지금 너무 다닥다닥」). 칸 너비가 마름모보다
      훨씬 넓고, 남는 자리를 **잇는 선**이 채운다. 좁히려거든 `--igw` 하나만 줄인다.
   ⚠ 가로로만 구른다. 좌우 여백이 첫 칸·끝 칸도 가운데까지 데려온다 */
/* ⚠⚠ **크기는 `--mk` 하나로 잰다.** 잇는 선이 마름모 **모서리**에서 시작해야 하는데,
   그 모서리까지의 거리는 한 변이 아니라 **대각선의 절반**이다(`--mk-in` = `--mk` × 0.707).
   둘을 따로 적어 두면 크기를 바꿀 때 한쪽만 고쳐 선이 마름모를 파고들거나 허공에서 뜬다.
   CSS 에는 제곱근이 없어 `--mk-in` 은 손으로 셈해 적는다(보상 창의 마름모와 같은 길).
   ⚠ 칸(`--igw`·높이)은 **마름모의 대각선(`--mk` × 1.414)보다 넉넉해야** 한다 — 안 그러면
     커진 마름모가 이웃을 파고든다. 지금은 대각선 76px 에 칸 94px 이다 */
.igrail{--igw:116px;--mk:66px;--mk-in:47px;
  display:flex;align-items:center;gap:0;
  overflow-x:auto;overflow-y:hidden;scrollbar-width:none;
  padding:2px calc(50% - var(--igw) / 2);margin-bottom:10px;
  overscroll-behavior-x:contain}
.igrail::-webkit-scrollbar{display:none}
.igcell{position:relative;flex:none;width:var(--igw);height:104px;padding:0;
  display:flex;align-items:center;justify-content:center;
  border:0;background:none;cursor:pointer;-webkit-tap-highlight-color:transparent;
  /* ⚠ **크기는 스크립트가 쓴다**(`ingMid`). 여기에 `transition` 을 걸면 손끝을 뒤따라오며 늘어진다 */
  transform:scale(0.62)}
/* 잇는 선 — 마름모의 **모서리**에서 칸 끝까지. 모서리까지는 한 변이 아니라 대각선의 절반(`--mk-in`)이다.
   ⚠ 첫 칸의 왼쪽과 끝 칸의 오른쪽은 걷는다 — 허공으로 뻗으면 길이 더 있는 것처럼 읽힌다 */
.igcell::before,.igcell::after{content:"";position:absolute;top:50%;height:1px;pointer-events:none}
.igcell::before{left:0;right:calc(50% + var(--mk-in));
  background:linear-gradient(90deg,#0000,var(--og,#6b5d8c))}
.igcell::after{left:calc(50% + var(--mk-in));right:0;
  background:linear-gradient(90deg,var(--og,#6b5d8c),#0000)}
.igcell:first-child::before,.igcell:last-child::after{display:none}
/* 마름모 — 보상 창·관문 창의 그 마름모다(`.gain-mark`·`.stg-mark`). 한 게임 안에서 결을 맞춘다.
   ⚠ **판은 돌리고 알맹이는 되돌린다** — 안의 초상화와 수가 비스듬히 눕지 않게 */
/* ⚠⚠ **겁이 오를수록 짙어진다** (2026-10-13 기획자 — 「1일때는 저채도, 80일때는 진하게」).
   `--g` 는 스크립트가 칸마다 실어 보내는 0~1 자리값이다(`ingCell`). 여기서 그 값으로 빛깔을 섞는다 —
   1겁은 잿빛에 가깝고 영겁은 보랏빛이 가득 찬다.
   ⚠ `.now`·`.pick` 이 테 빛깔을 덮는다. 그 둘은 「지금」과 「고른 것」을 가리는 표라 채도보다 앞선다 */
.ig-dia{position:relative;display:flex;align-items:center;justify-content:center;
  width:var(--mk);height:var(--mk);transform:rotate(45deg);border-radius:6px;
  background:linear-gradient(135deg,
    color-mix(in srgb,#6b5d8c calc(var(--g,0) * 46%),#272231),
    color-mix(in srgb,#2a2238 calc(var(--g,0) * 55%),#171320));
  border:1px solid color-mix(in srgb,var(--og-hi,#9b8fbb) calc(18% + var(--g,0) * 82%),#3b3548);
  box-shadow:0 0 0 1px #0008,inset 0 1px 0 #ffffff1f,0 3px 10px #000a}
/* ⚠⚠ **알맹이가 들어갈 자리는 마름모의 내접 정사각형**이라 한 변이 `--mk` 가 아니라
   `--mk` × 0.707 이다. 그보다 크게 담으면 모서리 밖으로 삐져나간다 —
   54px 마름모의 속은 38px 이고, 초상화 22px 와 수 한 줄이 그 안에 든다 */
/* ⚠ 초상과 수 사이를 **띄운다** (기획자 — 「너무 붙어있어」). 마름모 속에서 가운데로 모인다 */
.ig-in{transform:rotate(-45deg);display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:5px;width:var(--mk-in);pointer-events:none}
/* 무명자 초상화 — 명호·하단 바가 쓰는 그 한 장이다(`profile_nameless_default`).
   ⚠ 새 그림을 만들지 않는다. 같은 한 장이라야 「이것이 나다」가 한 뜻으로 읽힌다 */
/* ⚠ 초상화는 **어두운 두건 그림**이라 어두운 마름모 위에 그대로 얹으면 까만 덩이로 묻힌다
   (2026-10-13 에 그렇게 떴다). 밝기를 올리고 **옅은 테를 한 겹** 둘러 윤곽을 세운다 */
.ig-face{width:26px;height:26px;border-radius:50%;object-fit:cover;display:block;
  filter:brightness(1.75) contrast(1.06);
  box-shadow:0 0 0 1px #ffffff2e,0 1px 4px #000}
/* 수는 **키운다**(기획자). 마름모가 커진 만큼 자리가 남는다 */
.igc-k{font-family:var(--mono);font-size:15px;font-weight:800;font-variant-numeric:tabular-nums;
  color:#ddd3c2;line-height:1;text-shadow:0 1px 3px #000}
/* 지나온 겁은 가라앉히고, 지금 겁과 고른 겁에만 표가 선다.
   ⚠ **투명도로 멀고 가까움을 말하지 않는다**(순례가 그렇게 정했다) — 그것은 크기가 맡는다.
      여기 투명도는 「지나왔는가」만 가른다 */
.igcell.past .ig-dia{opacity:.5}
.igcell.now .ig-dia{border-color:var(--chungi);box-shadow:0 0 0 1px #0008,inset 0 1px 0 #ffffff2a,0 0 12px #d4a84355}
.igcell.now .igc-k{color:#f2ebdf}
/* 고른 칸 — 「지금 겁」과 「보고 있는 겁」은 다를 수 있어 표가 둘이다 */
.igcell.pick .ig-dia{border-color:var(--og-hi,#9b8fbb);box-shadow:0 0 0 1px #0008,inset 0 1px 0 #ffffff2a,0 0 14px #9b8fbb66}
.igcell.mid .igc-k{color:#f2ebdf}
/* ══ 받은 겁은 **마름모까지 흑백이다** (2026-10-14 기획자 — 「보상 받았으면 겁 레벨
   숫자 쪽 박스도 흑백처리 비활성화」) ══════════════════════════════
   아래 보답 칸(`.igpane.done`)은 이미 가라앉는데 위의 마름모만 제 빛깔로 남아,
   이미 받은 겁인지가 **갈무리 표 하나로만** 읽혔다. 위아래가 같은 결이라야 한눈에 갈린다.
   ⚠ 갈무리 표(`.igc-chk`)는 **빼놓는다** — 마름모 밖에 붙어 있고, 「받았다」고
     말하는 유일한 표라 그것까지 흑백이면 아무 말도 남지 않는다.
   ⚠ `.now`·`.pick` 의 테 빛깔도 함께 가라앉는다. 그래도 된다 — 테는 「어디에 서 있는가」이고
     흑백은 「이미 받았다」라, 뒤의 것이 더 굳은 사실이다.
   ⚠ 초상화(`.ig-face`)는 마름모 안이라 이 한 줄에 함께 딸려 온다 */
.igcell.done .ig-dia{filter:grayscale(1) brightness(.62)}
.igcell.done .igc-k{color:#9a948c}
/* 받은 겁 — 갈무리 표. 출석 창과 같은 표다. 마름모 **밖**에 붙어 돌아가지 않는다 */
.igc-chk{position:absolute;right:21px;bottom:19px;font-size:12px;color:var(--ok);line-height:1;
  text-shadow:0 1px 3px #000}
.igcell .nudot{--nx:22px;--ny:18px}

/* ── 그 겁의 보답 (§5.2) — 순례 관문 창의 칸을 본으로 삼은 **제 벌**이다 ── */
/* ═══ 겁을 얻는 길 — 하단바 **바로 위**에 세 줄 (2026-10-13 기획자) ═══════════
   ⚠ **`margin-top:auto`** 가 이것을 바닥으로 민다 — `.prof-pane.ingwa` 가 세로 묶음이다.
     자리를 못 박으면(`position:absolute`) 겁 상자가 길어질 때 그 위를 덮는다.
   ⚠⚠ **톤을 한 겹 더 눌렀다** (기획자 — 「살짝 톤 어둡게」). 겁마다의 한마디(`.igsay`)보다
     **더 희미해야** 한다 — 저쪽은 그 겁의 이야기이고 이쪽은 **늘 같은 안내**다.
     늘 같은 글이 또렷하면 눈이 매번 거기에 걸린다. `--fg-faint` 에서 한 번 더 내린다 */
.ighow{margin:auto 0 0;padding:17px 8px 0;
  border-top:1px solid #ffffff0d;
  display:flex;flex-direction:column;gap:6px;text-align:center}
/* ⚠ 글이 길어 **한 줄에 안 들어간다.** 손말틀(375px)에서 한 줄에 넣으려면 8px 아래로
   내려가야 하는데 그러면 읽을 수가 없다 — 기획자가 「너무 길면 크기 줄여도 된다」 했으므로
   **읽히는 선까지만** 줄이고 나머지는 접는다. 세 마디는 줄 사이(`gap`)로 가른다.
   ⚠ `balance` 로 접어 두 줄의 길이를 고르게 한다 — 한 줄만 길면 토막처럼 보인다 */
/* ⚠⚠ **`word-break:keep-all`** — 한국어는 그냥 두면 **낱말 한가운데서 끊긴다**
   (「사투를 벌 / 이는」·「상한이 있으 / 나,」). 어절째로 넘기게 못 박는다.
   ⚠ 그래서 한 어절이 칸보다 길면 비어져 나갈 수 있는데, 여기 글에는 그런 어절이 없다 */
.ighow p{margin:0;font-family:var(--serif);font-size:clamp(9.5px,round(calc(var(--app-w) * .027), 1px),10.5px);line-height:1.5;
  letter-spacing:-.012em;color:#565a70;word-break:keep-all;text-wrap:balance}
.igpane{display:flex;flex-direction:column;align-items:center;gap:11px}
.ig-h{font-family:var(--serif);font-size:12px;font-weight:700;letter-spacing:.06em;
  color:var(--fg-mid);text-align:center}
/* 받은 겁은 **흑백**이다 (2026-10-13 기획자).
   ⚠ **글로 한 번 더 말하지 않는다** — 흑백이고 받기 단추가 없으면 이미 받은 것이 그대로 읽힌다.
      그래서 머리글의 「획득 완료」도, 그것을 칠하던 초록도 걷었다(기획자) */
.igpane.done .ig-list{opacity:.6}
.igpane.done .ig-ic img{filter:grayscale(1) brightness(.62)}
.igpane.done .ig-q{color:var(--fg-faint)}
/* **2행 3열** (2026-10-13 기획자 — 「순례 스테이지 팝업 양식 그대로」).
   ⚠ 접어서 세 칸이 되기를 바라지 않는다 — 폭이 좁아지면 넷+둘로 꺾인다(2026-10-13 에 밟았다).
      **세 칸으로 못 박는다.** 천기 한 줄뿐인 21겁부터는 그 한 칸이 가운데 선다(`.one`) */
.ig-list{display:grid;grid-template-columns:repeat(3,clamp(60px,calc(var(--app-w) * .18),76px));
  justify-content:center;align-items:start;gap:12px 13px}
.ig-list.one{grid-template-columns:clamp(60px,calc(var(--app-w) * .18),76px)}
.ig-item{display:flex;flex-direction:column;align-items:center;gap:9px;min-width:0;
  /* 눌러서 펼치는 칸은 단추라 — 단추의 기본 꾸밈을 걷는다 */
  padding:0;border:0;background:none;color:inherit;font:inherit;text-align:center}
.ig-item[data-pay]{cursor:pointer}
.ig-item[data-pay]:active{transform:scale(.96)}
.ig-ic{position:relative;flex:none;width:100%;aspect-ratio:1;
  display:flex;align-items:center;justify-content:center;
  border-radius:7px;background:linear-gradient(160deg,#211c2b,#120f18);
  border:1px solid var(--line-soft);
  box-shadow:inset 0 1px 0 #ffffff14,inset 0 0 14px #000a,0 2px 6px #0007}
/* ⚠ 그림은 테 안에서만 — 칸은 `overflow` 가 없어야 아래 파문이 테 밖으로 퍼진다.
   그래서 **그림에만** 둥근 모서리를 따로 물린다 */
.ig-ic img{position:absolute;inset:0;width:100%;height:100%;border-radius:6px;
  object-fit:cover;object-position:center 28%}
.ig-q{position:absolute;left:3px;right:3px;bottom:3px;
  font-family:var(--mono);font-size:clamp(11px,round(calc(var(--app-w) * .031), 1px),13px);font-weight:800;
  font-variant-numeric:tabular-nums;color:var(--chungi);line-height:1.5;
  background:#0b0812c7;border-radius:4px;text-shadow:0 1px 2px #000}
/* 이름은 **한 줄이다** — 접게 두면 한국말 카드 이름이 띄어쓰기마다 꺾여 칸마다 키가 달라진다 */
.ig-n{display:block;width:100%;font-size:10.5px;line-height:1.3;color:#ddd3c2;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ig-none{margin:0;font-size:11.5px;color:var(--fg-faint)}
.igpane .fbtn{margin-top:4px;min-width:150px}
/* 받은 것이 보상 창과 **같은 결**(`gainslam`·`gainring`)로 나타난다 (기획자: 「생동감있게」).
   ⚠⚠ **칸(`.gain-item`)을 가져다 쓰지는 않는다.** 2026-10-13 에 그 둘을 한 번 묶었다가
      기획자가 갈라내라 해서 떼어 냈다 — 쓰임이 다른 칸을 묶으면 한쪽을 손볼 때마다 다른 쪽이 따라 움직인다.
      **움직임(@keyframes)만** 함께 쓴다. 그것까지 두 벌로 만들면 두 자리가 다른 결로 튄다 */
.igpane.ig-enter .ig-ic,.igpane.ig-enter .ig-q{animation:gainslam .4s cubic-bezier(.2,.85,.3,1) backwards;
  animation-delay:calc(var(--i,0) * .07s)}
.igpane.ig-enter .ig-ic::after{content:"";position:absolute;inset:0;border-radius:7px;pointer-events:none;
  animation:gainring .52s ease-out backwards;
  animation-delay:calc(var(--i,0) * .07s + .16s)}
@media (prefers-reduced-motion:reduce){
  .igpane.ig-enter .ig-ic,.igpane.ig-enter .ig-q{animation:none}
  .igpane.ig-enter .ig-ic::after{animation:none}
}

/* ── 결과 화면의 인과 한 줄 (§5.3) ──
   ⚠ **도겁은 알림일 뿐 보상이 아니다.** 여기서 보상 창을 띄우지 않는다 —
      판 보상과 겁 보상이 섞인다 */
/* ⚠⚠ **승패 두 줄(`.rsay`)에 바로 잇대어 붙는 셋째 줄이다** (2026-10-13 기획자가 정함).
   그래서 글꼴·크기·줄간·자간을 **`.rsay` 와 똑같이** 적는다 — 한 숨으로 읽혀야 한다.
   ⚠ `.rsay` 를 고치는 날 **여기도 같이 고친다.** 한쪽만 바꾸면 셋째 줄만 튄다.
   ⚠ 예전에는 「인과 +150」을 17px 로 혼자 크게 세웠다. 기획자가 물렸다 —
     결과 화면의 주인공은 붓글씨 한 글자지 수가 아니다 */
/* ⚠⚠ **`.result p` 로 적는다 — `.rig` 만으로는 안 먹는다.** 위의 `.result p{color:var(--fg-mid)}`
   가 **더 또렷한 겨눔**(갈래+딱지)이라 홑 딱지로는 빛깔을 못 덮는다. `.rsay` 도 같은 까닭으로
   `.result p.rsay` 다. 2026-10-13 에 홑으로 적었다가 셋째 줄만 밝게 떴다 */
.result p.rig{margin:0 0 2px;display:block;text-align:center;
  font-family:var(--sans);font-size:12px;line-height:1.85;letter-spacing:.03em;color:var(--fg-faint)}
/* 수만 빛깔을 받는다 — 글줄은 가라앉고 그 자리만 떠오른다 */
.rig-n{font-family:var(--mono);font-weight:800;font-variant-numeric:tabular-nums;
  color:#c9b6ff;text-shadow:0 1px 6px #000;white-space:nowrap}
/* ⚠⚠ **글줄을 넘기지 않는다**(기획자) — 높이를 `1em` 으로 묶어 글자 키를 따라간다.
   `px` 로 박으면 글자 크기를 고치는 날 알만 혼자 남는다.
   ⚠ `vertical-align` 으로 글줄 가운데에 맞춘다. 안 맞추면 밑줄에 걸려 한 줄이 두꺼워진다 */
.rig-i{height:1em;width:auto;vertical-align:-.17em;margin-right:1px}
/* 도겁 한마디는 **제 줄**에 선다 — 인과 줄 끝에 붙이면 둘 다 안 읽힌다 */
.rig-up{display:block;font-family:var(--serif);font-size:11.5px;letter-spacing:.04em;color:var(--chungi)}

/* ═══ 효과 태그 거르개 (2026-10-14 기획자 — 「내공 우측에 효과 필터」) ═══════════════
   ⚠ 담는 것은 **카드에 적힌 효과 태그**뿐이다 — 무맥·계는 안 담는다(`ui.js` 의 `kwAll` 머리말).
   ⚠ 칸은 `.fsels` 아래 **한 줄을 더 쓴다.** 옆에 끼워 넣으면 네 칸이 되어 손말틀에서 다 눌린다 */
/* ⚠⚠ **글은 가운데다** (2026-10-14 기획자 — 「효과 전체는 왜 가운데 정렬 아니냐」).
   옆의 셋(`select`)이 다 가운데라 이 칸만 왼쪽이면 줄이 어긋나 보인다.
   ⚠ 화살표를 **글 흐름에서 빼낸다**(`position:absolute`). 흐름에 두면 그만큼 글이
     왼쪽으로 밀려 **가운데가 가운데가 아니게** 된다 — 눈에 안 띄게 어긋나는 자리다. */
.fkwtog{position:relative;display:flex;align-items:center;justify-content:center;
  width:100%;min-width:0;padding-inline:13px;text-align:center}
.fkwsum{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fkwtog.on .fkwsum{color:var(--chungi)}
.fkwi{position:absolute;right:5px;top:50%;transform:translateY(-50%);
  flex:none;font-size:9px;opacity:.7;pointer-events:none}
/* 펼친 칸 — **거르개 줄 아래로 흐른다.** 떠 있게 하면 옆 칸 셋이나 아래 카드 격자를 덮어
   무엇이 걸러졌는지 보이지 않는다. 거르개 자체가 접히는 칸이라 자리를 더 써도 된다 */
.fkwbox{display:flex;flex-wrap:wrap;align-items:center;gap:5px;margin:6px 0 0;padding:7px;
  border:1px solid var(--line-soft);border-radius:6px;background:#17131fb8}
.fkwopt{display:inline-flex;align-items:center;gap:4px;
  padding:3px 8px;border:1px solid var(--line-soft);border-radius:999px;
  font-size:11.5px;color:var(--fg-faint);cursor:pointer;user-select:none}
.fkwopt.on{color:var(--fg);border-color:var(--og-hi,#9b8fbb);background:#2a2338}
.fkwopt.off{opacity:.38;cursor:not-allowed}
/* 네모 자체는 숨긴다 — 칩이 켜지고 꺼지는 것으로 이미 다 말한다 */
.fkwopt input{position:absolute;opacity:0;width:0;height:0}
.fkwclr{flex:none;margin-left:auto;padding:3px 8px;font-size:11px;
  color:var(--fg-faint);text-decoration:underline;text-underline-offset:2px}

/* 인과 화면 머리의 알 — 결과 화면(`.rig-i`)과 **같은 그림, 제 꼴**이다 (2026-10-14) */
.igamt-i{height:1em;width:auto;vertical-align:-.16em;margin-right:3px}
