/* ===== 잿불 — 프로토타입 스타일 =====
   단일 비주얼 월드(어두운 탑)로 커밋. 테마 전환 없음. */

:root {
  --bg:        #0C0A08;
  --panel:     #16120E;
  --panel-2:   #1E1813;
  --line:      #2C241D;
  --ink:       #EDE3D4;
  --ink-soft:  #B5A897;
  --muted:     #7A6F63;
  --ember:     #E9954A;
  --ember-dim: #A05F27;
  --blood:     #C0483A;
  --cold:      #7C90A6;
  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: "IBM Plex Sans KR", "Malgun Gothic", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
  height: 100%;
  overscroll-behavior: none;
  word-break: keep-all;
}

/* 100% 만으로는 부모 높이가 정해지지 않은 환경(아티팩트 iframe 등)에서
   높이가 0으로 무너진다. 뷰포트 단위로 못박아 둔다. */
#app {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
}

.screen, .overlay {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  flex-direction: column;
}
.hidden { display: none !important; }

/* ---------- 타이틀 ---------- */

#title-screen {
  background:
    radial-gradient(ellipse at 50% 34%, rgba(233,149,74,.14) 0%, transparent 60%),
    var(--bg);
}
.title-inner { text-align: center; padding: 20px; }

/* 제목은 한 색으로 둔다.
   두 글자를 색으로 가르면 서로 다른 단어처럼 읽히고,
   주황은 게임 안에서 이미 "불씨"라는 뜻으로 쓰고 있어서
   제목에까지 쓰면 그 뜻이 흐려진다. 불빛은 글자 뒤에만 깐다. */
.game-title {
  font-family: "Cinzel", "Gowun Batang", serif;
  font-size: clamp(40px, 9vw, 66px);
  font-weight: 600;
  letter-spacing: .22em;
  text-indent: .22em;              /* 자간 때문에 오른쪽으로 밀리는 것을 되돌린다 */
  text-transform: uppercase;
  margin: 0 0 6px;
  color: var(--ink);
  text-shadow: 0 0 46px rgba(233,149,74,.38);
}

/* 한글 이름은 영문 아래에 작게. 둘 다 이름이므로 크기로만 서열을 준다. */
.game-name {
  font-family: "Gowun Batang", "Nanum Myeongjo", serif;
  font-size: clamp(15px, 3.6vw, 19px);
  letter-spacing: .42em;
  text-indent: .42em;
  color: var(--muted);
  margin: 0 0 20px;
}

.game-sub {
  font-family: "Gowun Batang", serif;
  font-size: clamp(13px, 3.2vw, 16px);
  line-height: 1.85;
  color: var(--ink-soft);
  margin: 0 0 26px;
  text-wrap: balance;
}

/* 마지막 두 줄만 한 칸 띄우고 조금 어둡게.
   앞은 상황이고 뒤는 망설임이라, 붙여 두면 같은 호흡으로 읽혀 버린다. */
.game-sub .turn {
  display: block;
  margin-top: .85em;
  color: var(--muted);
}

/* 버튼은 눌리는 입체 테두리로. 그라데이션 대신 단색 두 겹을 쓴다 —
   도트 그림 옆에서 부드러운 계조는 혼자 떠 보인다. */
.btn-main {
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .04em;
  color: #1A1209;
  background: var(--ember);
  border: 2px solid #F4B978;
  border-right-color: #8C4E18;
  border-bottom-color: #8C4E18;
  padding: 12px 38px;
  cursor: pointer;
  image-rendering: pixelated;
}
.btn-main:hover { background: #F0A257; }
.btn-main:active {
  transform: translate(1px, 1px);
  border-color: #8C4E18;
  border-right-color: #F4B978;
  border-bottom-color: #F4B978;
}

.btn-ghost {
  font-family: inherit;
  font-size: 12.5px;
  color: var(--ink-soft);
  background: var(--panel-2);
  border: 2px solid var(--line);
  border-right-color: #100D0A;
  border-bottom-color: #100D0A;
  padding: 7px 16px;
  cursor: pointer;
}
.btn-ghost:hover { border-color: var(--ember-dim); border-right-color: #100D0A; border-bottom-color: #100D0A; color: var(--ember); }
.btn-ghost:active { transform: translate(1px, 1px); }

/* ---------- 캐릭터 선택 ---------- */

/* 다섯 장은 항상 한 줄이어야 한다. 폭을 픽셀로 못박으면 기기마다 접히므로,
   남는 공간을 나눠 갖고 좁아지면 같이 줄어들게 둔다. */
.hero-pick {
  display: flex; justify-content: center; flex-wrap: nowrap;
  gap: clamp(4px, 1.2vw, 8px);
  margin: 0 0 14px;
  width: 100%; max-width: 500px;
}
.hero {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  flex: 1 1 0; min-width: 0; max-width: 92px;
  padding: 10px 2px 8px;
  overflow: hidden;
  font-family: inherit;
  background: var(--panel);
  border: 2px solid var(--line);
  border-right-color: #100D0A; border-bottom-color: #100D0A;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.hero:hover { border-color: var(--ember-dim); }
.hero.on {
  border-color: var(--ember);
  background: var(--panel-2);
  box-shadow: 0 0 24px -6px rgba(233,149,74,.45);
}
.hero-img {
  width: 34px; height: 56px;
  object-fit: contain; object-position: bottom;
  image-rendering: pixelated;
  display: block;
}
.hero-name {
  font-family: "Gowun Batang", serif;
  font-size: clamp(11px, 2.9vw, 14px);
  color: var(--ink-soft);
  white-space: nowrap;
}
.hero.on .hero-name { color: var(--ember); font-weight: 700; }
.hero-stat {
  font-family: "IBM Plex Mono", monospace; font-size: 9.5px;
  color: var(--muted); letter-spacing: -.02em;
}
.hero-stat em { font-style: normal; color: var(--cold); }

.hero-say {
  min-height: 58px; margin-bottom: 24px;
  font-family: "Gowun Batang", serif;
}
.hero-say b {
  display: block; font-size: 14px; font-weight: 400;
  color: var(--ink-soft); margin-bottom: 4px;
}
.hero-say span { font-size: 12px; color: var(--muted); }
.hero-say .hero-nums {
  display: none;
  font-family: "IBM Plex Mono", monospace; font-size: 11px;
  margin-top: 6px; color: var(--muted);
}
.hero-say .hero-nums em { font-style: normal; color: var(--cold); }

/* 좁은 화면에서는 다섯 장이 한 줄에 안 들어간다.
   카드에서 수치를 빼 아래로 내리고 폭을 줄여 한 줄을 지킨다 —
   두 줄로 접히면 무엇을 고르는 화면인지 한눈에 안 읽힌다. */
@media (max-width: 560px) {
  .hero { padding: 8px 1px 6px; gap: 2px; }
  .hero-img { width: 26px; height: 42px; }
  .hero-stat { display: none; }
  .hero-say .hero-nums { display: block; }
}

.record {
  margin-top: 26px;
  font-size: 12.5px;
  color: var(--muted);
  letter-spacing: .04em;
  min-height: 18px;
}
.title-links { margin-top: 22px; }

/* ---------- 게임 화면 ---------- */

#game-screen {
  justify-content: center;
  padding: 10px;
  gap: 8px;
  --game-w: 792px;
}

.hud {
  width: 100%;
  max-width: var(--game-w);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  font-size: 12.5px;
}
.hud-left { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; }

/* 체력은 하트로. 막대보다 로그라이크답고, 칸이 몇 개 남았는지가 숫자보다 빨리 읽힌다. */
.hearts { display: flex; gap: 2px; flex-wrap: wrap; }
.heart {
  width: 18px; height: 17px;
  image-rendering: pixelated;
  display: block;
}
#hp-text { color: var(--muted); font-size: 11.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }

.hud-right { display: flex; gap: 16px; }

/* 장비·물약 아이콘. 전부 16px 도트라 확대할 때 뭉개지면 안 된다.
   object-fit 이 없으면 기본값 fill 이라 정사각 칸에 늘려 채운다. 직접 그린
   아이콘은 16x16 이라 멀쩡하지만, 무기는 팩에서 오는 것이라 세로로 길다
   (긴 창 6x30, 짧은 검 10x21). 그대로 두면 창이 뭉툭한 막대가 된다. */
.g-ico, .shop-ico, .gear-icon {
  image-rendering: pixelated;
  object-fit: contain;
  vertical-align: middle;
}
.g-ico { width: 16px; height: 16px; margin-right: 3px; }
.shop-ico { width: 26px; height: 26px; flex: none; }
.gear-icon { width: 40px; height: 40px; display: block; margin: 0 auto 4px; }
/* display:block 이 hidden 속성을 덮어써서, 그림이 없을 때 깨진 이미지가 떴다.
   (그림이 없는 장비, 그리고 정체불명처럼 일부러 안 보여주는 것) */
.gear-icon[hidden] { display: none; }

/* 레벨 — 체력 옆에 둔다. 레벨이 곧 체력이 늘어나는 일이므로 같이 읽힌다. */
.lv { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.lv i { font-style: normal; color: var(--muted); font-size: 11px; }
.lv b { color: var(--ember); font-weight: 600; font-variant-numeric: tabular-nums; }
.xp-bar {
  width: 46px; height: 4px; border-radius: 2px;
  background: var(--line); overflow: hidden;
}
.xp-fill {
  display: block; height: 100%; width: 0;
  background: var(--ember-dim);
  transition: width .18s ease-out;
}
.lv.up b { animation: lvpop .5s ease-out; }
@keyframes lvpop {
  0%   { transform: scale(1);   text-shadow: none; }
  35%  { transform: scale(1.5); text-shadow: 0 0 10px var(--ember); }
  100% { transform: scale(1);   text-shadow: none; }
}
@media (prefers-reduced-motion: reduce) {
  .xp-fill { transition: none; }
  .lv.up b { animation: none; }
}
.stat { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.stat i { font-style: normal; color: var(--muted); font-size: 11px; }
.stat b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
/* 물약·골드 아이콘도 게임 화면과 같은 그림에서 가져온다 */
.stat .ico {
  width: 16px; height: 16px;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  image-rendering: pixelated;
}

/* 보스 체력 — 마주친 뒤에만 나타난다 */
.boss-bar {
  width: 100%;
  max-width: var(--game-w);
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: "Gowun Batang", serif;
  font-size: 13px;
  color: var(--ember);
}
.boss-track {
  flex: 1;
  height: 6px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 0;
  overflow: hidden;
}
#boss-fill {
  height: 100%; width: 100%;
  background: linear-gradient(90deg, var(--ember-dim), var(--ember));
  transition: width .25s ease-out;
}

/* 장착 중인 장비 — 캔버스 바로 위 한 줄 */
.gear-strip {
  width: 100%;
  max-width: var(--game-w);
  display: flex;
  gap: 14px;
  font-size: 11.5px;
  color: var(--muted);
  min-height: 16px;
  flex-wrap: wrap;
}
.gear-strip .g-slot { display: inline-flex; align-items: baseline; gap: 5px; }
.gear-strip .g-slot i { font-style: normal; opacity: .65; }
.gear-strip .g-slot b { font-weight: 500; }
.gear-strip .g-empty { color: #4E463D; }

/* 좁은 화면에서는 이 줄이 넘쳐 능력치가 혼자 다음 줄로 밀린다.
   폰(가용 폭 약 382px)에서 재보면 장비 357 + 간격 14 + 능력치 110 = 481 이다.
   아이콘 셋은 52px 뿐이라 그것만 줄여선 모자라고, 슬롯 이름 셋이 92px 로 더 크다.
   그림이 붙은 슬롯은 이름을 지워도 무엇인지 읽히므로 그쪽을 접는다.
   (등급 접두가 붙은 긴 이름이 셋 다 겹치면 그래도 넘칠 수 있다 — 그때는 접힌다) */
@media (max-width: 560px) {
  .gear-strip { gap: 8px; }
  .gear-strip .g-lab { display: none; }
}

canvas#view {
  display: block;
  width: 100%;
  max-width: var(--game-w);
  height: auto;
  background: #080705;
  border: 1px solid var(--line);
  border-radius: 0;
  image-rendering: pixelated;
  touch-action: none;
}

.log {
  width: 100%;
  max-width: var(--game-w);
  height: 74px;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 8px 12px;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--ink-soft);
  scrollbar-width: thin;
}
.log div { opacity: .55; }
.log div:last-child { opacity: 1; color: var(--ink); }
.log .hit  { color: var(--ember); }
.log .hurt { color: var(--blood); }
.log .good { color: #8FBF7F; }
.log .sys  { color: var(--muted); }

/* 터치 조작 — 키보드에만 있던 기능을 전부 버튼으로 꺼낸다 */
.touch-row {
  display: none; align-items: flex-end; justify-content: center;
  gap: 10px; margin-top: 8px; width: 100%;
}
/* 칸 크기를 픽셀로 박아 두면 좁은 기기에서 좌우 여백이 사라져 다닥다닥 붙는다.
   화면 폭을 따라가되 위아래로 한계를 둔다 — 작은 폰에서는 넘치지 않고,
   큰 폰에서는 쓸데없이 커지지 않는다. */
.touch-acts {
  display: grid;
  grid-template-columns: repeat(2, clamp(64px, 18vw, 96px));
  gap: 8px;
}
.touch-acts button {
  font-family: inherit; font-size: 12px;
  color: var(--ink-soft);
  background: var(--panel-2);
  border: 2px solid var(--line);
  border-right-color: #100D0A; border-bottom-color: #100D0A;
  padding: 10px 4px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.touch-acts button b { color: var(--ink); font-weight: 600; }
.touch-acts button:active { transform: translate(1px, 1px); }
.touch-acts button.on { color: #1A1209; background: var(--ember); border-color: #F4B978; }
.touch-acts button.locked { opacity: .35; }

/* 흔적 — 할 수 있는 순간에만 나타난다. 한 칸에 끼우면 홀로 남은 칸처럼 보여서
   두 칸을 다 쓴다. 나타났다는 것 자체가 「지금 여기서 된다」는 신호다. */
.touch-acts button[data-act="mark"] {
  grid-column: 1 / -1;
  padding: 8px 4px;
  color: #E8D9B8;
  border-color: #5A4A32; border-right-color: #100D0A; border-bottom-color: #100D0A;
}

/* 터치 조작 */
.touch-pad {
  display: none;
  /* 방향키도 같은 규칙으로. 엄지가 닿는 자리라 조금 크게 잡는다 */
  grid-template-columns: repeat(3, clamp(52px, 17vw, 74px));
  grid-template-rows: repeat(3, clamp(46px, 14.5vw, 64px));
  gap: 8px;
}
.touch-pad button {
  font-size: 22px;
  color: var(--ink-soft);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.touch-pad button:active { background: var(--line); color: var(--ember); }
.touch-pad button[data-dir="up"]    { grid-area: 1 / 2; }
.touch-pad button[data-dir="left"]  { grid-area: 2 / 1; }
.touch-pad button[data-dir="wait"]  { grid-area: 2 / 2; font-size: 16px; color: var(--muted); }
.touch-pad button[data-dir="right"] { grid-area: 2 / 3; }
.touch-pad button[data-dir="down"]  { grid-area: 3 / 2; }

@media (hover: none) and (pointer: coarse) {
  .touch-row { display: flex; }
  .touch-pad { display: grid; }
  .log { height: 52px; }
}

/* ---------- 층 진입 연출 ---------- */

#floor-intro {
  background: radial-gradient(ellipse at 50% 60%, #140D06 0%, #070504 70%);
  z-index: 40;
  transition: opacity .5s ease;
}
#floor-intro.fading { opacity: 0; }

.intro-inner { text-align: center; padding: 24px; max-width: 480px; }
.intro-floor {
  font-family: "Gowun Batang", serif;
  font-size: clamp(40px, 10vw, 62px);
  font-weight: 700;
  color: var(--ember);
  letter-spacing: .08em;
  margin-bottom: 24px;
  text-shadow: 0 0 40px rgba(233,149,74,.4);
}
/* 기억 이름처럼 긴 제목은 층수보다 작게 */
.intro-floor.long { font-size: clamp(28px, 7vw, 44px); }

.intro-line {
  font-family: "Gowun Batang", serif;
  font-size: clamp(14px, 3.6vw, 16.5px);
  line-height: 2.1;
  color: var(--ink-soft);
  min-height: 3.2em;
}
.intro-line .caret {
  color: var(--ember);
  animation: blink .7s step-end infinite;
}
@keyframes blink { 50% { opacity: 0; } }

.intro-hint {
  margin-top: 20px;
  font-size: 12.5px;
  color: var(--muted);
  font-style: italic;
  opacity: 0;
  transition: opacity .6s ease .2s;
}
.intro-hint.show { opacity: 1; }

/* ---------- 장비 비교 ---------- */

#gear-modal { background: rgba(7,5,4,.90); z-index: 45; }
.gear-inner {
  width: calc(100% - 40px); max-width: 400px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 24px 26px;
}
.gear-head { margin-bottom: 18px; }
.gear-slot {
  display: block;
  font-family: "IBM Plex Mono", monospace;
  font-size: 10.5px; letter-spacing: .16em;
  color: var(--muted); margin-bottom: 6px;
}
.gear-name {
  font-family: "Gowun Batang", serif;
  font-size: 22px; font-weight: 700; color: var(--ink);
}
.gear-name.r-fine    { color: var(--cold); }
.gear-name.r-ancient { color: var(--ember); }

.gear-table { width: 100%; border-collapse: collapse; font-size: 13.5px; margin-bottom: 14px; }
.gear-table th {
  font-family: "IBM Plex Mono", monospace;
  font-size: 10px; letter-spacing: .1em; font-weight: 500;
  color: var(--muted); text-align: right; padding-bottom: 7px;
  border-bottom: 1px solid var(--line);
}
.gear-table th:first-child { text-align: left; }
.gear-table td {
  padding: 7px 0; text-align: right; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; border-bottom: 1px solid var(--line-soft, #221C16);
}
.gear-table td:first-child { text-align: left; color: var(--muted); }
.gear-table td.up   { color: #8FBF7F; }
.gear-table td.down { color: var(--blood); }
.gear-table td.same { color: var(--muted); }

.gear-old { font-size: 12px; color: var(--muted); margin-bottom: 20px; line-height: 1.6; }
.gear-actions { display: flex; gap: 10px; }
.gear-actions .btn-main, .gear-actions .btn-ghost { flex: 1; padding-left: 0; padding-right: 0; }
.k {
  display: inline-block; margin-left: 6px; opacity: .6;
  font-family: "IBM Plex Mono", monospace; font-size: 11px;
}

/* ---------- 상점 ---------- */

#shop-modal { background: rgba(7,5,4,.93); z-index: 45; }
.shop-inner {
  width: calc(100% - 40px); max-width: 460px;
  max-height: 86vh; overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 24px 26px;
}
.shop-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.shop-head h2 { font-family: "Gowun Batang", serif; font-size: 20px; margin: 0; color: var(--ember); }
.shop-gold { font-size: 12.5px; color: var(--muted); }
.shop-gold b { color: var(--gold, #D9B04E); font-variant-numeric: tabular-nums; }
.shop-say {
  font-family: "Gowun Batang", serif; font-size: 13px; line-height: 1.8;
  color: var(--muted); margin: 0 0 18px;
}

.shop-list { display: grid; gap: 8px; margin-bottom: 20px; }
.shop-row {
  display: grid; grid-template-columns: 20px 26px minmax(0,1fr) auto;
  gap: 12px; align-items: center;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 11px 14px;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  transition: border-color .15s, background .15s;
}
.shop-row:hover:not(:disabled) { border-color: var(--ember-dim); }
.shop-row:disabled { opacity: .42; cursor: default; }
.shop-row .num { font-family: "IBM Plex Mono", monospace; font-size: 11px; color: var(--muted); }
.shop-row .nm { font-size: 13.5px; color: var(--ink); }
.shop-row .nm.r-fine    { color: var(--cold); }
.shop-row .nm.r-ancient { color: var(--ember); }
.shop-row .sub { display: block; font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.shop-row .sub .up   { color: #8FBF7F; }
.shop-row .sub .down { color: var(--blood); }
.shop-row .price {
  font-size: 12.5px; color: #D9B04E; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.shop-row.sold .price { color: var(--muted); }

/* ---------- 결말 ---------- */

/* 결말 화면은 완전히 덮지 않는다.
   여기까지 온 사람이 서 있는 곳은 옥상이고, 그게 뒤로 계속 보여야
   "탑 꼭대기에서 고르는 중"이 유지된다. */
#ending-screen {
  background: radial-gradient(ellipse at 50% 40%, rgba(20,16,10,.82) 0%, rgba(6,5,4,.93) 70%);
  z-index: 55;
}
.ending-inner { width: calc(100% - 40px); max-width: 520px; text-align: center; }
.ending-title {
  font-family: "Gowun Batang", serif;
  font-size: clamp(26px, 6vw, 34px); font-weight: 700;
  color: var(--ember); margin-bottom: 22px;
  text-shadow: 0 0 46px rgba(233,149,74,.4);
}
.ending-body {
  font-family: "Gowun Batang", serif;
  font-size: 14.5px; line-height: 2.1; color: var(--ink-soft);
  margin: 0 0 34px;
}
.ending-choices { display: grid; gap: 12px; }
.ending-pick {
  font: inherit; text-align: left; cursor: pointer;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 0; padding: 18px 20px;
  transition: border-color .18s, background .18s;
}
.ending-pick:hover { border-color: var(--ember); background: var(--panel-2); }
.ending-pick b {
  display: block; font-family: "Gowun Batang", serif;
  font-size: 17px; color: var(--ink); margin-bottom: 7px;
}
.ending-pick span { font-size: 12.5px; line-height: 1.75; color: var(--muted); }
.ending-pick .k {
  font-family: "IBM Plex Mono", monospace; font-size: 11px;
  color: var(--muted); border: 1px solid var(--line); padding: 1px 6px; margin-left: 6px;
}
/* 고를 수 없는 것 — 숨기지 않는다. 다음 판에 무기를 들고 오면 열린다는 걸 알려야 한다 */
.ending-pick.locked { opacity: .42; cursor: default; }
.ending-pick.locked:hover { border-color: var(--line); background: var(--panel); }

/* 모닥불 — 결말과 같은 틀을 쓰되 불빛이 더 가깝다 */
#camp-modal {
  background: radial-gradient(ellipse at 50% 55%, rgba(48,28,12,.86) 0%, rgba(6,5,4,.94) 70%);
  z-index: 54;
}
.camp-inner .ending-title { margin-bottom: 14px; }
.camp-inner .ending-body { margin-bottom: 22px; }

/* 짧은 것이 여럿일 때 — 쪽지 낱말 열둘, 틀 여섯.
   세로로 쌓으면 화면 밖으로 넘쳐 아래가 잘린다. 고르는 창은 한눈에 다 보여야 한다. */
.ending-choices.camp-grid {
  grid-template-columns: repeat(auto-fit, minmax(108px, 1fr));
  gap: 8px;
}
.camp-grid .ending-pick { padding: 13px 10px; text-align: center; }
.camp-grid .ending-pick b {
  margin-bottom: 0; font-size: 15px; white-space: nowrap;
}
/* 문장이 들어오는 격자 — 칸을 넓히고, 그래도 모자라면 줄을 바꾼다.
   잘린 문장은 무엇을 고르는지 알 수 없으므로 잘리는 것만은 막는다. */
.ending-choices.camp-grid.wide { grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); }
.camp-grid.wide .ending-pick b { white-space: normal; line-height: 1.5; }
/* 아무리 좁은 화면이라도 창이 화면을 넘지 않게 — 넘치면 창 안에서 구른다 */
.camp-inner { max-height: 88vh; overflow-y: auto; }

/* 내가 남긴 말이 읽힌 횟수. 기록 줄 아래에 조용히 붙는다 —
   자랑하는 자리가 아니라 「혼자가 아니다」를 알리는 자리다. */
.record-nods {
  margin-top: 6px;
  font-size: 11.5px;
  color: var(--ember);
  opacity: .7;
}

/* ---------- 되짚기 ----------
   삽화가 아니라 표식이다. 불 하나, 계단 하나, 이름 한 줄.
   그림이 위, 글이 아래 — 무성영화의 자막과 같은 자리다. */
#story-screen {
  background: radial-gradient(ellipse at 50% 42%, #0e0a07 0%, #050403 72%);
  z-index: 68;
  display: flex; flex-direction: column;
}
.story-inner {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 26px; padding: 24px; width: 100%;
}
.story-canvas {
  width: min(420px, 78vw);
  height: min(300px, 40vh);
  display: block;
}
.story-text { width: min(560px, 88vw); text-align: center; }
.story-title {
  font-family: "Gowun Batang", serif;
  font-size: 13px; letter-spacing: .28em; color: var(--ember);
  margin-bottom: 18px; opacity: .85;
}
.story-lines {
  font-family: "Gowun Batang", serif;
  font-size: clamp(15px, 3.6vw, 18px); line-height: 2.15; color: var(--ink);
  min-height: 7.4em;                 /* 줄이 늘어도 그림이 흔들리지 않게 */
}
/* 아직 안 찍힌 글자. 자리는 지키고 보이지만 않는다 —
   빼 버리면 줄 길이가 바뀌면서 글이 좌우로 떨린다. */
.story-lines .ghost { visibility: hidden; }

@media (max-height: 700px) {
  .story-canvas { height: 30vh; }
  .story-lines { line-height: 1.95; }
}

/* ---------- 크레딧 ----------
   결말 뒤에 흐른다.

   뒤를 비치게 해 봤더니 타이틀 화면의 글자와 크레딧이 겹쳐 둘 다 안 읽혔다.
   여기서는 이름 말고 읽을 것이 없어야 한다 — 완전히 덮되, 가운데만
   아주 옅게 밝혀 불빛 앞에서 흐르는 것처럼 둔다. */
#credits-screen {
  background: radial-gradient(ellipse at 50% 45%, #0d0a08 0%, #060504 70%);
  z-index: 70;
  display: flex; flex-direction: column;
}
.credits-view {
  flex: 1; width: 100%; overflow: hidden; position: relative;
  /* 위아래 끝에서 글자가 스며들 듯 사라진다 */
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 12%, #000 88%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0, #000 12%, #000 88%, transparent 100%);
}
/* 흐르는 것은 JS 가 직접 옮긴다 (UI.showCredits) — 누르고 있는 동안 빨라져야 하는데
   CSS 애니메이션은 도중에 속도를 바꾸면 진행한 만큼을 잃고 처음부터 다시 흐른다. */
.credits-roll {
  position: absolute; left: 0; right: 0; top: 100%;
  text-align: center; padding: 0 24px;
  will-change: transform;
}

.cr-big {
  font-family: "Cinzel", "Gowun Batang", serif;
  font-size: clamp(30px, 8vw, 44px); font-weight: 600;
  color: var(--ember); letter-spacing: .16em;
  text-shadow: 0 0 50px rgba(233,149,74,.45);
}
.cr-sub {
  font-family: "Gowun Batang", serif;
  font-size: 15px; color: var(--muted); letter-spacing: .5em;
  margin-top: 6px;
}
.cr-head {
  font-family: "Cinzel", serif; font-size: 12px; letter-spacing: .3em;
  color: var(--ember); text-transform: uppercase; margin-bottom: 14px;
}
/* 직함과 이름을 위아래로 둔다. 좌우로 놓으면 좁은 화면에서 줄이 접혀
   같은 이름이 열 번 나온다는 농담이 안 읽힌다. */
.cr-row { margin-bottom: 20px; }
.cr-row b {
  display: block; font-family: "IBM Plex Mono", monospace;
  font-size: 11px; font-weight: 400; letter-spacing: .22em;
  color: var(--muted); text-transform: uppercase; margin-bottom: 4px;
}
.cr-row span {
  font-family: "Gowun Batang", serif; font-size: 17px; color: var(--ink);
}
.cr-line {
  font-size: 12.5px; line-height: 1.9; color: var(--ink-soft);
}
.cr-note {
  font-family: "Gowun Batang", serif;
  font-size: 14px; line-height: 2; color: var(--muted); font-style: italic;
}

.credits-foot {
  flex: none; padding: 14px 0 26px; text-align: center; min-height: 58px;
}
.credits-hint {
  font-size: 11px; color: var(--muted); opacity: .55; letter-spacing: .06em;
}

/* 손이 닿는 화면에서는 글자가 더 빨리 지나가도 읽히도록 조금 키운다 */
@media (max-width: 760px) {
  .cr-row span { font-size: 16px; }
  .cr-line { font-size: 12px; }
}

/* ---------- 결과 ---------- */

/* 같은 이유로 결과 화면도 조금 비친다 — 불을 붙였다면 뒤에서 새벽이 온다 */
#result-screen { background: rgba(7,5,4,.88); z-index: 50; }
.result-inner { text-align: center; padding: 30px; max-width: 420px; }
.result-title {
  font-family: "Gowun Batang", serif;
  font-size: 30px; font-weight: 700;
  color: var(--ember);
  margin-bottom: 14px;
}
.result-line {
  font-family: "Gowun Batang", serif;
  font-size: 14.5px; line-height: 1.9;
  color: var(--ink-soft);
  margin-bottom: 30px;
}
.result-stats {
  display: grid;
  grid-template-columns: auto auto;
  gap: 9px 26px;
  justify-content: center;
  margin: 0 0 32px;
  font-size: 13.5px;
}
.result-stats dt { color: var(--muted); text-align: right; }
.result-stats dd { margin: 0; color: var(--ink); font-variant-numeric: tabular-nums; text-align: left; }

/* ---------- 도감 ----------
   조작법 · 몬스터 · 아이템 · 내 기억 · 업적을 탭 하나로 묶은 창 */

#codex-screen { background: rgba(7,5,4,.95); z-index: 60; }
.codex-inner {
  width: calc(100% - 32px); max-width: 640px;
  height: min(86vh, 660px);
  display: flex; flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 0;
  overflow: hidden;
}

.codex-tabs {
  display: flex; gap: 2px;
  padding: 10px 10px 0;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.codex-tabs button {
  font: inherit; font-size: 12.5px;
  color: var(--muted);
  background: transparent;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 0;
  padding: 8px 13px;
  cursor: pointer;
  margin-bottom: -1px;
  white-space: nowrap;
}
.codex-tabs button:hover { color: var(--ink-soft); }
.codex-tabs button.on {
  color: var(--ember);
  background: var(--panel-2);
  border-color: var(--line);
  border-bottom: 1px solid var(--panel-2);
}
.codex-tabs .codex-x {
  margin-left: auto; margin-bottom: 0;
  color: var(--muted); font-size: 14px; padding: 6px 10px;
}
.codex-tabs .codex-x:hover { color: var(--ember); }

.codex-body {
  flex: 1; overflow-y: auto;
  padding: 20px 24px 26px;
  scrollbar-width: thin;
}
.codex-say {
  font-family: "Gowun Batang", serif; font-size: 12.5px; line-height: 1.9;
  color: var(--muted); margin: 0 0 18px;
}

.codex-table { width: 100%; border-collapse: collapse; font-size: 12.5px; font-variant-numeric: tabular-nums; }
.codex-table th {
  font-family: "IBM Plex Mono", monospace; font-weight: 500;
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint, #6E6259); text-align: right;
  padding: 0 8px 8px 0; border-bottom: 1px solid var(--line); white-space: nowrap;
}
.codex-table th:nth-child(-n+2) { text-align: left; }
.codex-table td {
  padding: 7px 8px 7px 0; text-align: right;
  color: var(--ink-soft); border-bottom: 1px solid #221C16;
}
.codex-table td:nth-child(-n+2) { text-align: left; }
.codex-table td.cx-name { color: var(--ink); }
.codex-table td.cx-mod { color: var(--muted); font-size: 11.5px; }
.codex-table td.hi { color: var(--ink); font-weight: 600; }
.codex-table td.hi.mag { color: var(--cold); }
.codex-table tr.locked td { color: #453E36; font-style: italic; }
.cx-thumb {
  display: block; width: 26px; height: 26px;
  object-fit: contain; object-position: bottom;
  image-rendering: pixelated;
}
.cx-tag {
  font-size: 10px; color: var(--cold);
  border: 1px solid color-mix(in srgb, var(--cold) 40%, transparent);
  border-radius: 0; padding: 0 4px; margin-left: 4px; vertical-align: 1px;
}

/* 업적 */
.ach-list { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 0; }
.ach-row {
  display: grid; grid-template-columns: 20px 130px minmax(0,1fr);
  gap: 10px; align-items: baseline;
  background: var(--panel-2); padding: 11px 14px; font-size: 13px;
}
.ach-row .ach-mark { color: #443D35; text-align: center; }
.ach-row .ach-name { color: #4E463D; font-family: "Gowun Batang", serif; }
.ach-row .ach-desc { color: #3E3830; font-size: 12px; }
.ach-row.got .ach-mark { color: var(--ember); }
.ach-row.got .ach-name { color: var(--ember); font-weight: 700; }
.ach-row.got .ach-desc { color: var(--muted); }
@media (max-width: 520px) {
  .ach-row { grid-template-columns: 18px minmax(0,1fr); }
  .ach-row .ach-desc { grid-column: 2; }
}

/* 업적 알림 */
#toasts {
  position: absolute; right: 16px; bottom: 16px;
  display: flex; flex-direction: column; gap: 8px;
  z-index: 70; pointer-events: none;
}
.toast {
  background: var(--panel); border: 1px solid var(--ember-dim);
  border-left-width: 3px; border-radius: 0;
  padding: 11px 16px; max-width: 260px;
  box-shadow: 0 8px 26px -10px rgba(0,0,0,.8);
  animation: toastIn .32s ease-out;
}
.toast b {
  display: block; font-family: "Gowun Batang", serif;
  font-size: 14px; color: var(--ember); margin-bottom: 3px;
}
.toast span { font-size: 11.5px; color: var(--muted); line-height: 1.5; }
.toast.out { opacity: 0; transform: translateX(12px); transition: opacity .6s, transform .6s; }
@keyframes toastIn { from { opacity: 0; transform: translateX(20px); } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }

.memory-list { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 0; margin-bottom: 20px; }
.mem-row { background: var(--panel-2); padding: 13px 16px; }
.mem-row .mem-name {
  font-family: "Gowun Batang", serif; font-size: 14.5px;
  color: #4E463D;
}
.mem-row .mem-line { display: none; }
.mem-row.got .mem-name { color: var(--ember); font-weight: 700; }
.mem-row.got .mem-line {
  display: block;
  font-family: "Gowun Batang", serif; font-size: 12.5px;
  color: var(--ink-soft); margin-top: 5px; line-height: 1.7;
}
.mem-row.got .mem-eff {
  font-size: 11.5px; color: var(--muted); margin-top: 6px;
  font-family: "IBM Plex Mono", monospace;
}
.mem-row:not(.got) .mem-eff { display: none; }

/* ---------- 도움말 ---------- */




.help-table { width: 100%; border-collapse: collapse; font-size: 13px; margin-bottom: 20px; }
.help-table td { padding: 7px 10px 7px 0; border-bottom: 1px solid var(--line); color: var(--ink-soft); vertical-align: middle; }
.help-table td:first-child { white-space: nowrap; width: 44%; }
kbd {
  display: inline-block;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 11.5px;
  color: var(--ink);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 0;
  padding: 2px 6px;
}
.or { color: var(--muted); font-size: 11px; margin: 0 2px; }
.help-note { font-size: 12.5px; line-height: 1.85; color: var(--muted); margin: 0 0 16px; }
.help-note b { color: var(--ink-soft); }
.gl-stair { color: var(--ember); font-weight: 700; }
.gl-camp  { color: #E86A3A; font-weight: 700; }
.gl-shop  { color: #C9A227; font-weight: 700; }
.gl-gear  { color: var(--ink-soft); font-weight: 700; font-family: "IBM Plex Mono", monospace; }

button:focus-visible, canvas:focus-visible {
  outline: 2px solid var(--ember);
  outline-offset: 2px;
}

/* ---------- 도트 문법 마무리 ----------
   폰트는 그대로 두되 형태만 픽셀 쪽으로 맞춘다.
   한글 픽셀 폰트는 12px 아래로 내려가면 읽히지 않아서,
   가독성을 지키면서 통일감을 얻는 절충이다. */

/* 창은 각지게, 테두리는 두껍게 */
.codex-inner, .gear-inner, .shop-inner, .result-inner, .ending-pick, .memory-list, .ach-list {
  border-width: 2px;
}

/* 게이지도 칸 단위로 — 매끄럽게 차오르지 않고 뚝뚝 끊긴다 */
.boss-track { height: 10px; border-width: 2px; }
#boss-fill {
  transition: width .12s steps(6, end);
  background: repeating-linear-gradient(
    90deg, var(--ember) 0 6px, #C97B33 6px 8px);
}

/* 목록의 점도 네모로 */
ul li::before, .chip::before { border-radius: 0 !important; }

/* 픽셀 그림은 어떤 크기로 늘려도 뭉개지지 않게 */
img.cx-thumb, img.heart { image-rendering: pixelated; }

/* ===== 확성기 =====
   던전 위에 떠 있되 화면을 막지 않는다 — 채팅을 열어 둔 채로 계속 오를 수 있어야
   확성기다. 그래서 모달이 아니라 구석에 붙는 판이고, 창 크기의 절반을 넘지 않는다. */

.chat-tab {
  position: absolute; right: 12px; bottom: 12px; z-index: 40;
  padding: 7px 12px;
  background: var(--panel); color: var(--ink-soft);
  border: 2px solid var(--line); border-radius: 0;
  font: inherit; font-size: 12.5px; cursor: pointer;
}
.chat-tab:hover { color: var(--ink); border-color: var(--ember-dim); }

.chat-badge {
  display: inline-block; min-width: 16px; margin-left: 6px; padding: 0 4px;
  background: var(--ember); color: #1A1109;
  font-size: 11px; font-weight: 700; text-align: center;
}

.chat {
  position: absolute; right: 12px; bottom: 12px; z-index: 41;
  display: flex; flex-direction: column;
  width: 300px; max-width: calc(100% - 24px);
  max-height: min(52%, 380px);
  background: var(--panel); border: 2px solid var(--line);
}

.chat-head {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px;
  background: var(--panel-2); border-bottom: 2px solid var(--line);
  font-size: 12px; color: var(--muted);
}
.chat-where { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 붙어 있는지 한 눈에. 글자를 읽지 않아도 색으로 안다. */
.chat-dot { width: 8px; height: 8px; background: var(--muted); flex: none; }
.chat-dot.on   { background: #8FBF7F; }
.chat-dot.wait { background: var(--ember); animation: chat-blink 1s steps(2, end) infinite; }
@keyframes chat-blink { 50% { opacity: .25; } }

.chat-x {
  background: none; border: none; color: var(--muted);
  font: inherit; font-size: 13px; cursor: pointer; padding: 0 2px;
}
.chat-x:hover { color: var(--ink); }

/* ---------- 들어가기 전 ---------- */
.chat-join { padding: 12px; display: flex; flex-direction: column; gap: 9px; }
.chat-join label {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--muted);
}
.chat-row { display: flex; gap: 8px; }
.chat-note { margin: 2px 0 0; font-size: 11.5px; line-height: 1.6; color: var(--muted); }

.chat input {
  flex: 1; min-width: 0;
  padding: 6px 8px;
  background: var(--bg); color: var(--ink);
  border: 2px solid var(--line); border-radius: 0;
  font: inherit; font-size: 12.5px;
}
.chat input:focus { outline: none; border-color: var(--ember-dim); }

.chat button:not(.chat-x) {
  padding: 6px 12px;
  background: var(--ember-dim); color: #1A1109;
  border: 2px solid var(--ember-dim); border-radius: 0;
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.chat button:not(.chat-x):hover { background: var(--ember); border-color: var(--ember); }
.chat button.ghost {
  background: none; color: var(--muted); border-color: var(--line);
  font-weight: 400;
}
.chat button.ghost:hover { background: none; color: var(--ink); border-color: var(--ember-dim); }

/* ---------- 들어간 뒤 ---------- */
.chat-live { display: flex; flex-direction: column; min-height: 0; }

.chat-lines {
  flex: 1; min-height: 90px;
  overflow-y: auto; scrollbar-width: thin;
  padding: 8px 10px;
  font-size: 12.5px; line-height: 1.65;
}

.chat-line { margin-bottom: 3px; color: var(--ink-soft); word-break: break-word; }
.chat-line b { color: var(--muted); font-weight: 600; margin-right: 6px; }
.chat-line b::after { content: ''; }
.chat-line.mine { color: var(--ink); }
.chat-line.mine b { color: var(--ember-dim); }
.chat-line.sys { color: var(--muted); font-size: 11.5px; }

.chat-form { display: flex; gap: 6px; padding: 8px; border-top: 2px solid var(--line); }

.chat-foot { padding: 0 8px 8px; }
/* 한 번 되물을 때만 붉게. 되돌릴 수 없는 것임을 색으로도 말한다 */
.chat button.ghost.warn { color: var(--blood); border-color: var(--blood); }
.chat-foot button { padding: 4px 8px !important; font-size: 11.5px !important; }

/* 클립보드가 막힌 곳(비-https 등)에서 직접 골라 복사하라고 내주는 칸 */
.chat-link {
  margin: 0 8px 6px; width: calc(100% - 16px);
  font-size: 11.5px !important; color: var(--muted) !important;
}

/* 좁은 화면에서는 아래에 붙는 판으로. 폭을 다 쓴다 —
   폰에서 300px 짜리 판은 던전과 겹쳐서 둘 다 못 읽는다. */
@media (max-width: 560px) {
  .chat {
    right: 0; left: 0; bottom: 0;
    width: auto; max-width: none;
    max-height: 58%;
    border-width: 2px 0 0;
  }
  .chat-tab { right: 8px; bottom: 8px; }
}

/* ===== 관전 띠 =====
   남의 판을 보고 있다는 것이 한눈에 보여야 한다 — 내 판인 줄 알고
   키를 누르다가 "왜 안 움직이지"로 헤매면 그게 제일 나쁘다. */
.cast-bar {
  position: absolute; top: 0; left: 0; right: 0; z-index: 42;
  display: flex; align-items: center; gap: 10px;
  padding: 7px 12px;
  background: var(--panel-2); border-bottom: 2px solid var(--ember-dim);
  font-size: 12.5px; color: var(--ink-soft);
}
/* 띠가 뜬 만큼 화면 안쪽을 내린다 */
#app.has-cast .screen, #app.has-cast .overlay { padding-top: 36px; }

.cast-bar span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cast-bar button {
  padding: 4px 10px;
  background: var(--ember-dim); color: #1A1109;
  border: 2px solid var(--ember-dim); border-radius: 0;
  font: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer;
}
.cast-bar button:hover { background: var(--ember); border-color: var(--ember); }
