/* ============================================================
   铜锈纪元 · BRASS RUST
   视觉基调：黄铜 + 锈 + 永冬的冷光
   依据：暗色终端可读性（底 #0e0f0d 不纯黑，字 #d8d2c4 不纯白，
        正文对比度守 AA，颜色只给有意义的东西）
   ============================================================ */

@font-face {
  font-family: 'BrassMono';
  src: local('Cascadia Mono'), local('CascadiaMono'), local('Consolas');
}

:root {
  /* 背景层 */
  --bg:            #0c0d0b;
  --bg-raise:      #14150f;
  --bg-card:       #191a12;
  --bg-card-hi:    #1f2016;

  /* 描边 */
  --line:          #2e2c1e;
  --line-hi:       #4a4326;
  --brass-dim:     #6b5a2c;
  --brass:         #b8942f;
  --brass-hi:      #e0b94e;
  --brass-glow:    rgba(224, 185, 78, 0.14);

  /* 锈 */
  --rust:          #a8442a;
  --rust-dim:      #6b2c1c;
  --rust-glow:     rgba(168, 68, 42, 0.18);
  /* 亮锈：给「这个字正在烂」和账的段标用。
     一直只在 var(--rust-hi, #b85a33) 里当兜底活着，从没被正式声明过——
     这种变量一旦有人写了 var(--rust-hi) 不带兜底，就会静默失效成透明。 */
  --rust-hi:       #b85a33;

  /* 字 */
  --ink:           #d8d2c4;
  --ink-soft:      #a8a294;
  --ink-dim:       #6f6a5c;
  --ink-faint:     #4a4740;

  /* 功能色（克制使用） */
  --ok:            #7fa650;
  --warn:          #d4913c;
  --bad:           #b4432f;
  --cool:          #6a9aa8;

  --mono: 'BrassMono', 'Cascadia Mono', 'Consolas', 'Menlo', monospace;
  --sans: 'Noto Sans SC', 'Source Han Sans SC', 'Microsoft YaHei', 'PingFang SC', sans-serif;
  --serif: 'Source Han Serif SC', 'Songti SC', 'SimSun', serif;

  --shadow: 0 1px 0 rgba(0,0,0,.6), 0 8px 24px rgba(0,0,0,.5);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* 关键：让 hidden 生效，即使该元素在某处被设成了 display:flex */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}

body {
  /* 极淡的纸纹 + 顶部冷光，制造"在雾里"的感觉 */
  background-image:
    radial-gradient(120% 60% at 50% -10%, rgba(184,148,47,.07), transparent 60%),
    radial-gradient(80% 50% at 50% 110%, rgba(168,68,42,.05), transparent 70%);
  background-attachment: fixed;
}

/* 噪点层 */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  opacity: .035;
  z-index: 9999;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
}

#app {
  max-width: 480px;
  margin: 0 auto;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  position: relative;
}

/* ============================================================ 通用文本 */

.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

.brass   { color: var(--brass-hi); }
.rust    { color: var(--rust); }
.soft    { color: var(--ink-soft); }
.dim     { color: var(--ink-dim); }

/* 波浪分隔线 —— 原作标志元素 */
.wave {
  color: var(--brass-dim);
  font-family: var(--mono);
  letter-spacing: 2px;
  opacity: .55;
  font-size: 11px;
  user-select: none;
  overflow: hidden;
  white-space: nowrap;
}

/* ============================================================ 标题屏 */

#title {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 40px 28px 100px;
  gap: 0;
  animation: fadein 1.2s ease both;
}

@keyframes fadein { from { opacity: 0 } to { opacity: 1 } }

.title-era {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .5em;
  color: var(--brass-dim);
  margin-bottom: 26px;
}

.title-main {
  font-size: 46px;
  font-weight: 900;
  letter-spacing: .16em;
  line-height: 1.15;
  color: var(--ink);
  text-shadow: 0 0 40px var(--brass-glow);
  margin-bottom: 6px;
}

.title-main em {
  font-style: normal;
  color: var(--brass-hi);
}

.title-en {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .55em;
  color: var(--brass-dim);
  margin-bottom: 34px;
}

.title-lines {
  border-left: 2px solid var(--rust-dim);
  padding-left: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 38px;
}

.title-lines p {
  font-size: 14.5px;
  line-height: 1.85;
  color: var(--ink-soft);
  letter-spacing: .04em;
}

.title-hook {
  font-size: 13px;
  color: var(--brass);
  letter-spacing: .3em;
  margin-bottom: 44px;
}

/* ============================================================ 按钮 */

.btn-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.btn {
  appearance: none;
  border: 1px solid var(--line-hi);
  background: linear-gradient(180deg, var(--bg-card-hi), var(--bg-card));
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14px;
  letter-spacing: .12em;
  padding: 13px 20px;
  cursor: pointer;
  transition: all .16s ease;
  border-radius: 2px;
  position: relative;
}

.btn:hover:not(:disabled) {
  border-color: var(--brass);
  color: var(--brass-hi);
  box-shadow: 0 0 0 1px var(--brass-glow), inset 0 0 20px var(--brass-glow);
}

.btn:active:not(:disabled) { transform: translateY(1px); }

.btn:disabled { opacity: .35; cursor: not-allowed; }

.btn-primary {
  border-color: var(--brass-dim);
  background: linear-gradient(180deg, #2a2415, #1d1a10);
  color: var(--brass-hi);
  font-weight: 600;
}

.btn-primary:hover:not(:disabled) {
  border-color: var(--brass-hi);
  box-shadow: 0 0 0 1px var(--brass), 0 0 24px var(--brass-glow);
}

.btn-ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--ink-dim);
}

.btn-ghost:hover:not(:disabled) { color: var(--ink-soft); border-color: var(--line-hi); }

.btn-wide { width: 100%; justify-content: center; text-align: center; }

/* 原作按钮样式：【确认建档】 */
.btn-bracket {
  background: transparent;
  border: none;
  color: var(--rust);
  font-size: 14px;
  letter-spacing: .1em;
  padding: 10px 4px;
}
.btn-bracket:hover:not(:disabled) { color: var(--ink); box-shadow: none; }

/* ============================================================ 建档流程 */

#create, #awaken, #faction {
  flex: 1;
  padding: 22px 20px 90px;
  animation: fadein .6s ease both;
}

/* 把 .opt 当按钮用时的重置 */
button.opt {
  appearance: none;
  background: transparent;
  border: none;
  border-left: 1px solid transparent;
  font-family: var(--sans);
  text-align: left;
  padding-left: 2px;
  border-radius: 0;
}
button.opt:hover { border-left-color: var(--brass-dim); padding-left: 8px; }
button.opt.on { border-left-color: var(--rust); padding-left: 8px; }

.card-frame {
  border: 1px solid var(--rust-dim);
  background: linear-gradient(180deg, rgba(168,68,42,.045), rgba(0,0,0,.25));
  padding: 22px 18px;
  position: relative;
  box-shadow: inset 0 0 60px rgba(0,0,0,.5);
}

/* 四角铆钉 */
.card-frame::before,
.card-frame::after {
  content: '';
  position: absolute;
  width: 5px; height: 5px;
  background: var(--brass-dim);
  opacity: .6;
}
.card-frame::before { top: 7px; left: 7px; box-shadow: calc(100% + 0px) 0 0 var(--brass-dim); }
.card-frame::after  { bottom: 7px; right: 7px; }

.card-head {
  text-align: center;
  margin-bottom: 4px;
}

.card-head h2 {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: .35em;
  color: var(--rust);
  display: inline;
}

.card-head .en {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .4em;
  color: var(--rust-dim);
  margin-left: 10px;
}

.card-sub {
  text-align: center;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: .3em;
  color: var(--ink-faint);
  margin: 8px 0 18px;
}

/* 提示行 */
.hint {
  font-size: 13px;
  color: var(--warn);
  margin: 16px 0 14px;
  line-height: 1.7;
  letter-spacing: .02em;
}
.hint .ico { margin-right: 6px; }

.hint-plain {
  font-size: 13px;
  color: var(--ink-soft);
  margin: 14px 0;
  line-height: 1.75;
}

/* 局与局之间的一句话提点。
 * 它只在「你已经玩过至少一局」的时候出现，所以可以写得像有人在跟你说话——
 * 第一次打开游戏的人看到的应该是干净的建档屏，不是一个熟门熟路的老兵建议。 */
.tip-line {
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.85;
  color: var(--brass);
  opacity: .9;
  margin: 12px 0 10px;
  padding-left: 10px;
  border-left: 2px solid var(--brass-dim);
}

/* 当过的出身 / 站过的势力：圆点是实心的，右边缀一个小点标记。
 * 刻意做得极轻——这是记忆，不是成就。看第二眼才发现才最好。 */
.opt.been .circle {
  color: var(--brass);
}

.opt.been .been-dot {
  margin-left: 5px;
  color: var(--brass);
  opacity: .75;
}

/* 劝你去的那一家：右边一个「劝」标签。
 * 只是建议，不锁按钮——玩家爱选哪家选哪家。 */
.opt.suggest {
  border-color: var(--brass-dim);
}

.opt.suggest .tag {
  margin-left: 6px;
}

/* 分组标题【基础信息】 */
.sec {
  font-size: 14px;
  color: var(--rust);
  letter-spacing: .14em;
  margin: 20px 0 10px;
  font-weight: 600;
}

/* 字段行 */
.field {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 12px;
}

.field label {
  font-size: 14px;
  color: var(--ink);
  white-space: nowrap;
  min-width: 4.5em;
  letter-spacing: .06em;
}

.field .line-in {
  flex: 1;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--line-hi);
  color: var(--brass-hi);
  font-family: var(--sans);
  font-size: 14px;
  padding: 4px 2px 6px;
  outline: none;
  letter-spacing: .05em;
}

.field .line-in:focus { border-bottom-color: var(--brass); box-shadow: 0 1px 0 var(--brass-glow); }
.field .line-in::placeholder { color: var(--ink-faint); }

.line-static {
  flex: 1;
  border-bottom: 1px solid var(--line);
  height: 1.4em;
}

/* 单选圈 ○ 列表 */
.opts {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 0;
}

.opt {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: var(--ink);
  cursor: pointer;
  padding: 5px 12px 5px 0;
  letter-spacing: .04em;
  transition: color .12s;
  user-select: none;
  width: 50%;
}

.opt.wide { width: 100%; }
.opt.wide3 { width: 100%; }

/* 宽选项右边那句小字（出身的技能 / 势力的类型与人数）。
 * 推到右边缘：中文名称长短差得远，「前军人」和「自然觉醒者」差三个字，
 * 不推右的话下面那行小字会参差不齐，看着像没对齐的表格。 */
.opt.wide .dim {
  margin-left: auto;
  text-align: right;
  white-space: nowrap;
  opacity: .72;
  font-size: 11.5px;
}

.opt .circle {
  font-family: var(--mono);
  color: var(--rust);
  font-size: 13px;
  transition: all .12s;
}

.opt:hover { color: var(--brass-hi); }
.opt.on { color: var(--rust); }
.opt.on .circle { color: var(--rust); text-shadow: 0 0 10px var(--rust-glow); }
.opt.on .circle::before { content: '●'; }
.opt.on .circle { font-size: 0; }
.opt.on .circle::before { font-size: 13px; }

.opt .tag {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--ink-faint);
  margin-left: 2px;
}

/* 长文本输入（外貌/性格） */
.blanks {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 6px;
}
.blank-row {
  border-bottom: 1px solid var(--line-hi);
  padding-bottom: 10px;
}
.blank-row input,
.blank-row textarea {
  width: 100%;
  background: transparent;
  border: none;
  color: var(--brass-hi);
  font-family: var(--sans);
  font-size: 13.5px;
  line-height: 1.7;
  outline: none;
  resize: none;
  letter-spacing: .04em;
}
.blank-row input::placeholder,
.blank-row textarea::placeholder { color: var(--ink-faint); }

/* 底部操作条（固定） */
.action-bar {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 0;
  width: 100%;
  max-width: 480px;
  padding: 14px 20px calc(14px + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, transparent, var(--bg) 32%);
  display: flex;
  gap: 16px;
  justify-content: center;
  align-items: center;
  z-index: 50;
}

/* ============================================================ 游戏主界面 */

#game {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  padding-bottom: 0;
}

/* 顶部状态条 */
/* hud 与腔状态条合成一个 sticky 容器，实在挡一层；
   单独 sticky 两个元素会因为 top 计算相互推挤，滚起来就散了 */
.hud-wrap {
  position: sticky;
  top: 0;
  z-index: 40;
  background: #0c0d0b;                /* 必须不透明：正文会滚到它下面 */
  border-bottom: 1px solid var(--line);
  box-shadow: 0 6px 16px rgba(0,0,0,.55);
}

.hud {
  background: #0c0d0b;
  padding: 10px 16px 0;
}

.hud-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .16em;
  color: var(--ink-faint);
  margin-bottom: 8px;
}

.hud-chapter { color: var(--brass-dim); }

/* 场面条：此刻在哪儿、身边站着谁。
   群戏规则要求「三个人以上必须两人出声」，玩家得能自己看见这个人数，
   否则只能靠 NPC 忽然冒出来提醒他。地点 + 时辰用极淡色，人名用黄铜色。 */
.hud-scene {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 8px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .06em;
  color: var(--ink-dim);
  padding: 0 0 8px;
  line-height: 1.5;
}

.hud-scene .hs-place {
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 60%;
}

.hud-scene .hs-hour { color: var(--ink-faint); }

.hud-scene .hs-sep {
  color: var(--ink-faint);
  opacity: .5;
}

.hud-scene .hs-who { color: var(--brass); }

.hud-scene .hs-who + .hs-who::before {
  content: '·';
  margin-right: 8px;
  color: var(--ink-faint);
}

/* 三人以上：这回合至少要有两个人开口，给个安静但明确的提示 */
.hud-scene.crowd .hs-count { color: var(--warn); }

.hud-scene .hs-count { color: var(--ink-faint); }

.hud-bars {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px 10px;
  padding-bottom: 10px;
}

.bar-item { display: flex; flex-direction: column; gap: 3px; }

.bar-label {
  display: flex;
  justify-content: space-between;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: .1em;
  color: var(--ink-dim);
}
.bar-label .v { color: var(--ink-soft); }

.bar-track {
  height: 2px;
  background: var(--line);
  position: relative;
  overflow: hidden;
}
.bar-fill {
  position: absolute; inset: 0 auto 0 0;
  background: var(--brass);
  transition: width .5s cubic-bezier(.2,.8,.2,1);
}
.bar-fill.low  { background: var(--bad); }
.bar-fill.mid  { background: var(--warn); }
.bar-fill.cool { background: var(--cool); }

/* raw number variant (cores) */
.bar-num {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--brass-hi);
  letter-spacing: .05em;
  line-height: 1;
}
/* 只占位、不画进度（晶核这类无限额数值） */
.bar-track-ghost { opacity: 0; }

/* HUD 折叠详细 */
.hud-toggle {
  font-family: var(--mono);
  font-size: 9px;
  color: var(--ink-faint);
  cursor: pointer;
  letter-spacing: .2em;
  padding: 2px 0 8px;
  display: inline-block;
}
.hud-toggle:hover { color: var(--brass-dim); }

/* HUD 上的小方按钮（行囊 / 地图） */
.hud-acts { display: inline-flex; align-items: center; gap: 6px; margin-left: auto; }
.hud-btn {
  appearance: none;
  -webkit-appearance: none;
  font-family: var(--mono);
  font-size: 10px;
  line-height: 1;
  color: var(--ink-soft);
  background: none;
  border: 1px solid var(--line-hi);
  border-radius: 2px;
  padding: 3px 5px;
  cursor: pointer;
  letter-spacing: 0;
  transition: color .12s, border-color .12s;
}
.hud-btn:hover { color: var(--brass-hi); border-color: var(--brass-dim); }
.hud-btn.on { color: var(--brass-hi); border-color: var(--brass); }
.hud-acts .hud-toggle { padding: 0; }

/* 正文区 */
/* 注意：不要给 flex:1 —— 那会把正文撑满视口、把选项推到屏幕外一大截。
   正文应该自然生长，底部只留刚好不挡输入框的距离。 */
.log {
  padding: 22px 20px 20px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.block { animation: rise .5s cubic-bezier(.2,.8,.2,1) both; }

@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* 玩家行动回显 */
.echo {
  border-left: 2px solid var(--rust-dim);
  padding: 2px 0 2px 12px;
  font-size: 13.5px;
  color: var(--ink-dim);
  letter-spacing: .03em;
  line-height: 1.7;
}
.echo::before {
  content: '你';
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: .2em;
  color: var(--rust-dim);
  display: block;
  margin-bottom: 4px;
}

/* 正文段落 */
.prose {
  font-size: 16px;
  line-height: 1.95;
  color: var(--ink);
  letter-spacing: .03em;
  text-align: justify;
}
.prose p { margin-bottom: 1.05em; }
.prose p:last-child { margin-bottom: 0; }

/* 对话行 */
.prose .said {
  color: var(--brass-hi);
}

/* 打字机光标 */
.caret {
  display: inline-block;
  width: .5em;
  height: 1em;
  background: var(--brass);
  vertical-align: -.12em;
  animation: blink 1s step-end infinite;
  margin-left: 1px;
}
@keyframes blink { 50% { opacity: 0 } }

/* 数值变化浮标 */
.deltas {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: -8px;
}

.delta {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .08em;
  padding: 3px 8px;
  border: 1px solid var(--line);
  color: var(--ink-dim);
  background: rgba(0,0,0,.3);
  border-radius: 2px;
}
.delta.up   { color: var(--ok);   border-color: rgba(127,166,80,.3); }
.delta.down { color: var(--bad);  border-color: rgba(180,67,47,.3); }
.delta.warn { color: var(--warn); border-color: rgba(212,145,60,.3); }

/* 选项区 */
#options {
  padding: 0 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 104px;   /* 给固定输入框让出位置，不是 140px 那么夸张 */
}

.choice {
  text-align: left;
  width: 100%;
  padding: 14px 16px;
  background: linear-gradient(90deg, rgba(184,148,47,.045), transparent);
  border: 1px solid var(--line);
  border-left: 2px solid var(--brass-dim);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14.5px;
  letter-spacing: .04em;
  line-height: 1.6;
  cursor: pointer;
  transition: all .18s ease;
  position: relative;
  border-radius: 2px;
}
/* 交战中的动作按钮：想走是风险动作，边框换成锈色，
   跟出手/守住那种「继续打」的选项在视觉上分开 */
#options .choice.risky {
  border-left-color: var(--rust);
  background: linear-gradient(90deg, rgba(168, 68, 42, .06), transparent);
}
#options .choice.risky:hover:not(:disabled) {
  border-left-color: var(--rust);
  background: linear-gradient(90deg, rgba(168, 68, 42, .13), transparent);
}

/* 超载：这一回合唯一一个「拿命换一口气」的选项。
   比「想走」更重——锈色底 + 虚线边，读起来像炉子自己在提议。 */
#options .choice.overload {
  border-left-color: var(--rust);
  border-left-width: 3px;
  border-top: 1px dashed rgba(168, 68, 42, .45);
  border-bottom: 1px dashed rgba(168, 68, 42, .45);
  background: linear-gradient(90deg, rgba(168, 68, 42, .11), transparent 65%);
  color: #e2b9a4;
}
#options .choice.overload .idx {
  color: var(--rust);
}
#options .choice.overload:hover:not(:disabled) {
  border-left-color: var(--warn);
  background: linear-gradient(90deg, rgba(212, 145, 60, .17), transparent 65%);
  color: var(--brass-hi);
}
/* 差一点够得着的时候是禁用态：读起来要像「还差一口气」，不是坏了 */
#options .choice:disabled {
  opacity: .42;
  cursor: default;
  border-left-color: var(--line-hi);
}
/* 被前情那行字挡住的路线（阶段 16.4）。它不是按钮，是一句话——
   故意做成不可交互的注释块，免得玩家去戳它。 */
.route-blocked {
  font-size: 12.5px;
  line-height: 1.85;
  color: #7d7360;
  padding: 9px 12px;
  margin-top: 6px;
  border-left: 2px dashed #42351f;
  background: rgba(60, 48, 28, .18);
  font-family: var(--serif);
  letter-spacing: .02em;
}
.route-blocked::before {
  content: '';
  display: inline-block;
  width: 0;
}

/* ---------------------------------------------------------------- 熄火 EMBER
   炉压归零之后的三班缓冲。这一屏的视觉要压过其他所有面板——
   它不是「还有别的事可以做」，它是「你现在只能做这一件事」。 */
.ember-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 8px;
}
.ember-title {
  font-family: var(--serif);
  font-size: 20px;
  letter-spacing: .16em;
  color: var(--rust);
  text-shadow: 0 0 14px rgba(168, 68, 42, .5);
}
.ember-left {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .1em;
  color: var(--ink-dim);
}
.ember-left.urgent {
  color: var(--bad);
  animation: emberPulse 1.6s ease-in-out infinite;
}
@keyframes emberPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .38; }
}
.ember-pips {
  display: flex;
  gap: 6px;
  padding: 2px 0 10px;
}
.ember-pip {
  flex: 1;
  height: 3px;
  background: var(--line-hi);
}
.ember-pip.on {
  background: linear-gradient(90deg, var(--rust), var(--warn));
  box-shadow: 0 0 8px rgba(168, 68, 42, .5);
}

.ember-opt {
  border: 1px solid var(--line);
  border-left: 2px solid var(--rust-dim);
  padding: 10px 12px;
  margin-bottom: 8px;
  cursor: pointer;
  transition: border-color .16s, background .16s;
}
.ember-opt:hover:not(.disabled) {
  border-left-color: var(--rust);
  background: linear-gradient(90deg, rgba(168, 68, 42, .12), transparent 70%);
}
.ember-opt.disabled {
  opacity: .4;
  cursor: default;
}
.ember-opt.bad {
  border-left-color: var(--line-hi);
}
.ember-opt.bad:hover {
  border-left-color: var(--ink-dim);
  background: none;
}
.eo-top {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}
.eo-idx {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--rust);
}
.eo-label {
  font-size: 15px;
  color: var(--ink);
  letter-spacing: .06em;
}
.eo-desc {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--brass);
  margin-left: auto;
}
.eo-hint {
  font-size: 13px;
  color: var(--ink-soft);
  line-height: 1.7;
  padding-top: 2px;
}
.eo-lack {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--bad);
  padding-top: 3px;
}
/* 锈换命：烧锈这一项会多攒一口气时的提示。
 * 用 brass 而不是 rust——rust 在这一屏是「危险」的颜色（接受熄灭用了它），
 * 而这一行是**好消息**：你正把一条命攥在手里。 */
.eo-arm {
  font-size: 12px;
  line-height: 1.75;
  color: var(--brass-hi);
  padding-top: 5px;
  border-top: 1px dashed var(--line);
  margin-top: 6px;
}
.eo-arm.dim {
  color: var(--ink-faint);
  font-family: var(--mono);
  font-size: 11px;
}
.eo-note {
  font-size: 12px;
  color: var(--ink-faint);
  line-height: 1.65;
  padding-top: 3px;
  font-style: italic;
}

/* HUD 下的熄火条。和 .chamber-bar / .duel-bar 同一个位置，同时只该有一条。 */
.ember-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 16px 6px;
  border-top: 1px solid var(--rust-dim);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .08em;
  background: rgba(107, 44, 28, .18);
}
.ember-bar .eb-name {
  color: var(--rust);
}
.ember-bar .eb-left {
  color: var(--ink-soft);
  margin-left: auto;
}
.ember-bar.urgent {
  background: rgba(168, 68, 42, .3);
}
.ember-bar.urgent .eb-left {
  color: var(--bad);
  animation: emberPulse 1.6s ease-in-out infinite;
}

/* ---------------------------------------------------------------- 信 LETTER
   不要长得像系统通知。它像一个真的东西被人放在你面前：
   衬线、宽行距、左右留白多。 */
.letter-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding-bottom: 10px;
  border-bottom: 1px dashed var(--line);
}
.letter-kind {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .18em;
  color: var(--ink-faint);
}
.letter-from {
  font-size: 13px;
  color: var(--brass);
  letter-spacing: .06em;
}
.letter-body {
  padding: 12px 2px 4px;
}
.letter-body p {
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.95;
  color: var(--ink);
  margin: 0 0 10px;
  letter-spacing: .02em;
}
.letter-body p:last-child {
  margin-bottom: 0;
}
.letter-replies {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding-top: 6px;
}
.letter-reply {
  appearance: none;
  background: transparent;
  border: 1px solid var(--line-hi);
  color: var(--ink-soft);
  font-family: var(--sans);
  font-size: 13px;
  padding: 6px 14px;
  cursor: pointer;
  transition: border-color .16s, color .16s, background .16s;
}
.letter-reply:hover {
  border-color: var(--brass);
  color: var(--brass-hi);
  background: rgba(184, 148, 47, .08);
}

/* 收信箱抽屉里的行。未读的左边有一道锈色竖线，
   读过之后变回普通边——这是那种「一眼就能扫出哪封还没看」的便宜设计。 */
.mail-row {
  border-left: 2px solid transparent;
  padding: 10px 12px;
  margin-bottom: 8px;
  cursor: default;
  transition: border-color .16s, background .16s;
}
.mail-row.unread {
  border-left-color: var(--rust);
  background: rgba(168, 68, 42, .07);
  cursor: pointer;
}
.mail-row.unread:hover {
  background: rgba(168, 68, 42, .14);
}
.mail-top {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}
.mail-kind {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  color: var(--ink-faint);
}
.mail-from {
  font-size: 13px;
  color: var(--brass);
}
.mail-at {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--ink-faint);
  margin-left: auto;
}
.mail-text {
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.9;
  color: var(--ink-soft);
  padding-top: 6px;
}
.mail-row.unread .mail-text {
  color: var(--ink);
}
.mail-replies {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding-top: 8px;
}
.mail-reply {
  appearance: none;
  background: transparent;
  border: 1px solid var(--line-hi);
  color: var(--ink-soft);
  font-family: var(--sans);
  font-size: 12px;
  padding: 5px 12px;
  cursor: pointer;
  transition: border-color .16s, color .16s;
}
.mail-reply:hover {
  border-color: var(--brass);
  color: var(--brass-hi);
}
.mail-echo {
  font-family: var(--serif);
  font-size: 13px;
  line-height: 1.85;
  color: var(--ink-dim);
  padding: 8px 0 0 10px;
  border-left: 1px dashed var(--line-hi);
  margin-top: 8px;
}

/* HUD 上的未读红点 */
.hud-btn {
  position: relative;
}
.hud-dot {
  position: absolute;
  top: 1px;
  right: 2px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--rust);
  box-shadow: 0 0 6px rgba(168, 68, 42, .9);
}

.choice:hover:not(:disabled) {
  border-left-color: var(--brass-hi);
  background: linear-gradient(90deg, rgba(184,148,47,.13), transparent 70%);
  color: var(--brass-hi);
  padding-left: 20px;
}
.choice:disabled { opacity: .3; cursor: default; }
.choice .idx {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--brass-dim);
  margin-right: 9px;
}

/* 自由输入条 */
.input-bar {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 0;
  width: 100%;
  max-width: 480px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, transparent, var(--bg) 30%);
  z-index: 50;
}

.input-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--line-hi);
  background: rgba(25,26,18,.95);
  padding: 2px 2px 2px 14px;
  border-radius: 2px;
  transition: border-color .16s;
}
.input-wrap:focus-within {
  border-color: var(--brass-dim);
  box-shadow: 0 0 0 1px var(--brass-glow);
}

.input-wrap input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14px;
  padding: 12px 0;
  letter-spacing: .03em;
}
.input-wrap input::placeholder { color: var(--ink-faint); }

.send-btn {
  border: none;
  background: var(--brass-dim);
  color: #0c0d0b;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .15em;
  padding: 11px 16px;
  cursor: pointer;
  border-radius: 1px;
  transition: background .15s;
  font-weight: 700;
}
.send-btn:hover:not(:disabled) { background: var(--brass-hi); }
.send-btn:disabled { opacity: .3; cursor: default; }

/* 思考中 */
.thinking {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--brass-dim);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .22em;
  padding: 4px 0;
}
.thinking .dots span {
  animation: dotpulse 1.3s infinite;
  opacity: .2;
}
.thinking .dots span:nth-child(2) { animation-delay: .22s; }
.thinking .dots span:nth-child(3) { animation-delay: .44s; }
@keyframes dotpulse { 0%,60%,100% { opacity: .2 } 30% { opacity: 1 } }

/* 齿轮转动 */
.gear {
  display: inline-block;
  animation: spin 3.4s linear infinite;
  color: var(--brass-dim);
}
@keyframes spin { to { transform: rotate(360deg) } }

/* ============================================================ 面板卡（核心视觉） */

.panel {
  border: 1px solid var(--rust-dim);
  background: linear-gradient(180deg, rgba(168,68,42,.05), rgba(0,0,0,.32));
  padding: 20px 16px 16px;
  box-shadow: inset 0 0 70px rgba(0,0,0,.55), 0 2px 14px rgba(0,0,0,.4);
  position: relative;
  animation: panelin .55s cubic-bezier(.2,.9,.25,1) both;
}

@keyframes panelin {
  from { opacity: 0; transform: translateY(16px) scale(.985); }
  to   { opacity: 1; transform: none; }
}

.panel::before,
.panel::after {
  content: '';
  position: absolute;
  width: 4px; height: 4px;
  background: var(--brass-dim);
  opacity: .55;
}
.panel::before { top: 6px; left: 6px; box-shadow: calc(100% + 0px) 0 0 var(--brass-dim); }
.panel::after  { bottom: 6px; right: 6px; }

.panel-head {
  text-align: center;
  margin-bottom: 3px;
}
.panel-head h3 {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: .28em;
  color: var(--rust);
  display: inline;
}
.panel-head .en {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: .34em;
  color: var(--rust-dim);
  margin-left: 9px;
}

.panel-rule {
  text-align: center;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .2em;
  color: var(--ink-faint);
  margin: 7px 0 15px;
  overflow: hidden;
  white-space: nowrap;
  opacity: .7;
}

.panel-body { display: flex; flex-direction: column; gap: 2px; }

/* 面板里的行 */
.p-line {
  font-size: 14px;
  line-height: 1.95;
  color: var(--ink);
  letter-spacing: .03em;
}
.p-line .k { color: var(--rust); }
.p-line .v { color: var(--ink); }

.p-item {
  font-size: 14px;
  line-height: 1.9;
  color: var(--ink);
  letter-spacing: .03em;
  padding-left: 2px;
}
.p-item::before {
  content: '▸ ';
  color: var(--rust);
  font-size: 11px;
}

.p-sec {
  font-size: 14px;
  color: var(--rust);
  letter-spacing: .12em;
  font-weight: 600;
  margin: 14px 0 7px;
}

.p-note {
  font-size: 13px;
  color: var(--ink-soft);
  line-height: 1.8;
  margin: 3px 0;
}

/* 事实表：见过 / 做过 / 知道
 * 它是账本，不是日记——所以用等宽字、单行、右侧挂班次。
 * 玩家一眼能扫出「我这局活成什么样了」，而不是要读完一段回忆。 */
.facts-block {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed var(--line-hi);
}
.fact-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 12.5px;
  line-height: 1.85;
  color: var(--ink-soft);
  padding-left: 10px;
  border-left: 1px solid var(--line-hi);
}
.fact-at {
  margin-left: auto;
  flex: 0 0 auto;
  font-family: var(--mono);
  font-size: 10px;
  color: var(--ink-faint);
  letter-spacing: .04em;
}

.p-warn {
  font-size: 13px;
  color: var(--warn);
  line-height: 1.8;
  margin: 12px 0 14px;
}

.p-foot {
  text-align: center;
  margin-top: 16px;
  font-size: 12.5px;
  color: var(--brass-dim);
  letter-spacing: .1em;
}

/* 好感度行 */
.aff-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  font-size: 13px;
  color: var(--ink);
}
.aff-heart { color: var(--rust); font-size: 14px; }
.aff-track {
  flex: 1;
  height: 3px;
  background: var(--line);
  position: relative;
}
.aff-fill { position: absolute; inset: 0 auto 0 0; background: var(--rust); }
.aff-val { font-family: var(--mono); font-size: 12px; color: var(--ink-soft); }
.locked { color: var(--ink-faint); font-size: 12px; letter-spacing: .1em; }

/* 战斗面板 */
.threat-badge {
  display: inline-block;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .2em;
  padding: 2px 8px;
  border: 1px solid currentColor;
  margin-left: 6px;
}
.threat-low  { color: var(--ok); }
.threat-mid  { color: var(--warn); }
.threat-high { color: var(--bad); }
.threat-dead { color: var(--rust); }

/* ---------------------------------------------------------------- 交战 */

.duel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.duel-name {
  font-size: 17px;
  color: var(--ink);
  letter-spacing: .04em;
}
.duel-hp {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}
.duel-hp-track {
  flex: 1;
  height: 6px;
  background: var(--line);
  position: relative;
  overflow: hidden;
}
.duel-hp-fill {
  height: 100%;
  background: var(--brass);
  transition: width .28s ease-out;
}
.duel-hp-fill.hurt { background: var(--warn); }
.duel-hp-fill.crit { background: var(--bad); }
.duel-hp-num {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-soft);
  min-width: 52px;
  text-align: right;
  letter-spacing: .08em;
}
.duel-round {
  margin-top: 12px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .22em;
  color: var(--ink-faint);
  text-align: right;
}
.duel-logbox {
  margin-top: 10px;
  padding: 8px 10px;
  border-left: 1px solid var(--rust-dim);
  background: rgba(168, 68, 42, .06);
}
.duel-log {
  font-size: 12px;
  line-height: 1.65;
  color: var(--ink-dim);
  padding: 1px 0;
}

/* 交战中的画面压迫：把边框推成锈色，不换底色（底色一换整页会跳） */
body.in-combat .panel:has(.duel-head) {
  border-color: var(--rust);
  box-shadow: 0 0 0 1px rgba(168, 68, 42, .28), 0 8px 26px rgba(168, 68, 42, .12);
}

/* 掉落面板 */
.loot-item {
  border-left: 1px solid var(--brass-dim);
  padding: 5px 0 5px 12px;
  margin: 8px 0;
}
.loot-name { font-size: 14px; color: var(--brass-hi); letter-spacing: .05em; }
.loot-desc { font-size: 12.5px; color: var(--ink-dim); line-height: 1.7; margin-top: 2px; }

/* 搜尸三选一
 * 这不是抽卡结算，是蹲在一具还温着的身体旁边做决定。
 * 所以它不庆祝、不加光效，三个选项按危险度从锈到灰排下去。 */
.loot-seen {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-soft);
  letter-spacing: .05em;
  padding-bottom: 10px;
  border-bottom: 1px dashed var(--line-hi);
  margin-bottom: 12px;
}
.loot-choices { display: flex; flex-direction: column; gap: 2px; }
.loot-opt {
  display: grid;
  grid-template-columns: 22px 1fr;
  grid-template-areas: 'idx t' 'idx d';
  gap: 0 10px;
  padding: 11px 12px;
  border-left: 2px solid var(--line-hi);
  cursor: pointer;
  transition: background .18s, border-color .18s;
}
.loot-opt:hover { background: rgba(184, 148, 47, .06); border-left-color: var(--brass); }
.loot-opt.warn { border-left-color: var(--rust-dim); }
.loot-opt.warn:hover { background: rgba(168, 68, 42, .1); border-left-color: var(--rust); }
.loot-opt[data-busy] { cursor: default; opacity: .55; }
.lo-idx { grid-area: idx; font-family: var(--mono); font-size: 11px; color: var(--brass-dim); line-height: 1.8; }
.lo-t { grid-area: t; font-size: 14px; color: var(--ink); letter-spacing: .04em; }
.loot-opt.warn .lo-t { color: #e2b9a4; }
.lo-d { grid-area: d; font-size: 12px; color: var(--ink-dim); line-height: 1.7; }
.loot-pick.done { opacity: .45; pointer-events: none; }

/* 日志/文档面板 */
.doc-line {
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 2;
  color: var(--ink-soft);
  letter-spacing: .02em;
}

/* 结算面板 */
.settle-row {
  display: flex;
  justify-content: space-between;
  font-family: var(--mono);
  font-size: 12.5px;
  padding: 5px 0;
  border-bottom: 1px dashed var(--line);
  color: var(--ink-soft);
  letter-spacing: .05em;
}
.settle-row:last-child { border-bottom: none; }
.settle-row .n.up { color: var(--ok); }
.settle-row .n.down { color: var(--bad); }

/* ============================================================ 结局 */

/* 锈换命：刚才那一下够死一次。
 * 视觉上要「像一次事故」，但不能像结局——
 * 结局是安静的（.ending 居中、60px 上下留白、淡入 1.6 秒），
 * 这个是突然砸下来的：左右锈色竖线，不等宽数字，没有淡入。 */
.burn-save {
  margin: 22px 0;
  padding: 14px 0 12px 16px;
  border-left: 3px solid var(--rust);
  background: linear-gradient(90deg, rgba(168, 68, 42, .12), rgba(168, 68, 42, 0));
}

.burn-save .bs-head {
  font-family: var(--serif);
  font-size: 17px;
  letter-spacing: .22em;
  color: var(--rust);
  margin-bottom: 10px;
}

.burn-save .bs-note {
  font-size: 14px;
  line-height: 1.85;
  color: var(--ink);
}

.burn-save .bs-foot {
  margin-top: 10px;
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.8;
  color: var(--ink-dim);
}

.ending {
  padding: 60px 28px;
  text-align: center;
  animation: fadein 1.6s ease both;
}
.ending h2 {
  font-size: 26px;
  letter-spacing: .3em;
  color: var(--rust);
  margin-bottom: 20px;
}
.ending p {
  font-size: 15px;
  line-height: 2.1;
  color: var(--ink-soft);
  margin-bottom: 14px;
  text-align: left;
}

/* ============================================================ 滚动条 */

::-webkit-scrollbar { width: 3px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--line-hi); }

/* ============================================================ 余压腔 */

/* —— 腔状态条（在 HUD 下方，进场才出现） */
.chamber-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 20px;
  border-top: 1px solid #2a2118;
  background: #0a0b09;
  font-size: 12px;
  letter-spacing: .04em;
}
.chamber-bar[hidden] { display: none; }
.chamber-bar .cb-id { color: var(--brass); }
.chamber-bar .cb-name { color: var(--ink-dim); }
.chamber-bar .cb-spacer { flex: 1; }
.chamber-bar .cb-residual {
  font-family: var(--mono);
  color: var(--brass-hi);
  padding: 2px 8px;
  border: 1px solid #3a2f1c;
}
.chamber-bar.low .cb-residual {
  color: #e0522c;
  border-color: #6b2c1c;
  animation: pulse 1.4s ease-in-out infinite;
}

/* ---------------------------------------------------------------- 交战条 */

/* 战斗时正文几百字一直往上滚，敌人血量不能只活在面板里，
   否则玩家每回合都要往回翻才能知道还要打几下。 */
.duel-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 20px;
  border-top: 1px solid #2a2118;
  background: #0a0b09;
  font-size: 12px;
  letter-spacing: .04em;
}
.duel-bar[hidden] { display: none; }
.duel-bar .db-name {
  color: var(--rust);
  font-weight: 600;
  max-width: 34%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.duel-bar .db-hp { flex: 1; display: flex; align-items: center; }
.duel-bar .db-track {
  flex: 1;
  height: 4px;
  background: #241f15;
  border: 1px solid #332a1b;
  overflow: hidden;
}
.duel-bar .db-fill {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--rust);
  transition: width .35s ease;
}
.duel-bar .db-fill.hurt { background: var(--warn); }
.duel-bar .db-fill.crit { background: #e0522c; animation: pulse 1.2s ease-in-out infinite; }
.duel-bar .db-round {
  font-family: var(--mono);
  color: var(--ink-dim);
  white-space: nowrap;
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .45; }
}

/* —— 勘测结果（观察，不下结论） */
.survey-list { margin: 2px 0; }
.survey-row {
  display: flex;
  gap: 7px;
  align-items: baseline;
  padding: 5px 0;
  line-height: 1.55;
}
.survey-row .sq {
  font-family: var(--mono);
  color: #6b6152;
  font-size: 12px;
  min-width: 14px;
}
.survey-row .sv { flex: 1; color: var(--ink); }
.survey-row.dim .sv { color: #8d8475; }
.survey-deny {
  padding: 8px 10px;
  margin-bottom: 8px;
  border-left: 2px solid #6b2c1c;
  background: #16100d;
  color: #c08070;
  font-size: 13px;
  line-height: 1.6;
}

/* —— 五感标签配色 */
.tag {
  font-size: 11px;
  letter-spacing: .06em;
  white-space: nowrap;
  padding: 0 2px;
}
.tag-sight { color: #7fb0c8; }
.tag-hear  { color: #8fc9a8; }
.tag-smell { color: #c9a86b; }
.tag-touch { color: #c98fa8; }
.tag-press { color: #b8a0d8; }
.tag-doubt { color: #d8856b; }
.tag-move  { color: #9fb87f; }

/* —— 气压表 */
.scan-dial { text-align: center; padding: 6px 0 12px; }
.scan-num {
  font-family: var(--mono);
  font-size: 40px;
  line-height: 1;
  color: var(--brass-hi);
  letter-spacing: -.02em;
}
.scan-dial.low .scan-num { color: #e0522c; }
.scan-unit {
  font-size: 11px;
  color: #7a7162;
  letter-spacing: .18em;
  margin-top: 4px;
}
.scan-track {
  height: 4px;
  background: #1e1a13;
  margin: 10px auto 0;
  max-width: 240px;
  overflow: hidden;
}
.scan-fill {
  height: 100%;
  background: linear-gradient(90deg, #6b2c1c, var(--brass-hi));
  transition: width .4s ease;
}
.scan-dial.low .scan-fill { background: linear-gradient(90deg, #6b2c1c, #e0522c); }
.scan-rows { margin-top: 6px; }
.scan-row {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  padding: 4px 0;
  border-bottom: 1px dashed #241f18;
}
.scan-row .k { color: #8d8475; }
.scan-row .v { font-family: var(--mono); color: var(--ink); }
.scan-note {
  margin-top: 8px;
  font-size: 12px;
  color: #a09684;
  font-style: italic;
}
.scan-alarm {
  margin-top: 10px;
  padding: 7px 10px;
  border: 1px solid #6b2c1c;
  color: #e0522c;
  font-size: 12px;
  text-align: center;
  letter-spacing: .08em;
}

/* —— 腔况总览 */
.premise {
  font-size: 13px;
  line-height: 1.75;
  color: #b3a996;
  padding: 8px 10px;
  border-left: 2px solid #3a2f1c;
  background: #100f0c;
  margin: 4px 0 10px;
}
/* 前情背面那行字（阶段 16.4）。它默认是藏着的，玩家点过按钮才出现。
   视觉上要比前情**更旧**：前情是「别人讲给你听的」，这一行是
   「你自己想起来的」，所以用更低的对比度和一道虚线边界——
   读的时候有点像在辨认一层被刮掉的字。 */
.premise-clue {
  font-family: var(--serif);
  font-size: 13px;
  line-height: 1.85;
  color: #9a8f7c;
  letter-spacing: .04em;
  padding: 10px 12px;
  margin: -4px 0 12px;
  border-left: 2px dashed #4a3a22;
  background: repeating-linear-gradient(
    180deg,
    rgba(168, 68, 42, .045) 0px,
    rgba(168, 68, 42, .045) 1px,
    transparent 1px,
    transparent 5px
  );
  animation: clueIn 620ms ease-out both;
}
.premise-clue.on::before {
  content: '那行字：';
  display: block;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .18em;
  color: #6b5c42;
  margin-bottom: 5px;
}
@keyframes clueIn {
  from { opacity: 0; transform: translateY(-3px); }
  to { opacity: 1; transform: none; }
}
.premise-ask { margin: -4px 0 12px; }
.btn-mini {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .1em;
  color: var(--brass);
  background: none;
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 5px 10px;
  cursor: pointer;
  transition: border-color .18s, color .18s;
}
.btn-mini:hover:not(:disabled) { border-color: var(--brass-dim); color: var(--brass-hi); }
.btn-mini:disabled { color: var(--ink-dim); cursor: default; opacity: .7; }

.rule-line {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--brass-hi);
  padding: 5px 0 5px 10px;
  border-left: 1px solid #6b5520;
  margin: 3px 0;
  letter-spacing: .02em;
}
.note-sm {
  font-size: 12.5px;
  color: #8d8475;
  line-height: 1.6;
  padding: 3px 0 6px;
}
.route-block {
  margin: 9px 0;
  padding: 9px 10px;
  border: 1px solid #2a2118;
  background: #0e0d0a;
}
.route-head {
  font-size: 13px;
  color: var(--brass);
  letter-spacing: .06em;
  margin-bottom: 5px;
}
.route-desc { font-size: 12.5px; color: #9c9280; line-height: 1.6; margin-bottom: 6px; }
.route-need {
  font-size: 12px;
  color: #7d7466;
  font-family: var(--mono);
  padding: 1px 0 1px 10px;
}

/* —— 结算 */
.settle { border-top: 1px solid #2a2118; }
.settle-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  padding: 7px 0;
  border-bottom: 1px dashed #1e1a13;
}
.settle-row .sk { color: #8d8475; white-space: nowrap; }
.settle-row .sv { color: var(--ink); text-align: right; }
.settle-row.down .sv { color: #d8705a; }
.settle.ok .settle-row:first-child .sv { color: var(--brass-hi); }
.grant-line {
  margin-top: 12px;
  padding: 9px 10px;
  border: 1px solid #6b5520;
  color: var(--brass-hi);
  font-size: 12.5px;
  text-align: center;
  letter-spacing: .05em;
}

/* —— 进场选择屏（携带道具） */
#chamber-enter {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 22px 20px 90px;
  overflow-y: auto;
}
#chamber-enter[hidden] { display: none; }
.carry-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin: 12px 0;
}
.carry-item {
  border: 1px solid #2a2118;
  padding: 9px 10px;
  cursor: pointer;
  background: #0c0d0b;
  transition: border-color .18s, background .18s;
}
.carry-item:active { background: #14120d; }
.carry-item.on {
  border-color: var(--brass-hi);
  background: #16130c;
}
.carry-item .ci-name { font-size: 13px; color: var(--ink); }
.carry-item.on .ci-name { color: var(--brass-hi); }
.carry-item .ci-eff {
  font-size: 11.5px;
  color: #7d7466;
  line-height: 1.5;
  margin-top: 4px;
}
.carry-item .ci-uses {
  font-family: var(--mono);
  font-size: 11px;
  color: #6b6152;
  margin-top: 3px;
}
.carry-count {
  font-size: 12px;
  color: #8d8475;
  letter-spacing: .06em;
  margin-bottom: 6px;
}
.carry-count b { color: var(--brass-hi); font-weight: 400; }

/* —— 炉压崩坏的 UI 效果（从 IAPA 的 SAN 机制借来的思路，
      但绑在炉压上——我们已有炉压，不再加血条） */
body.critical #game .log {
  animation: flicker 3.2s infinite;
}
@keyframes flicker {
  0%, 96%, 100% { opacity: 1; filter: none; }
  97% { opacity: .82; filter: blur(.4px); }
  98% { opacity: 1; filter: none; }
  99% { opacity: .9; }
}
body.critical .hud { border-bottom-color: #6b2c1c; }

/* ============================================================ 背包抽屉 */

.drawer { position: fixed; inset: 0; z-index: 90; }
.drawer-mask {
  position: absolute; inset: 0;
  background: rgba(4, 5, 4, .72);
  animation: fadeIn .16s ease both;
}
@keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }

.drawer-body {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  /* 宽屏上收窄成一条竖栏，否则每个物品右边空出一大片 */
  max-width: 560px;
  margin: 0 auto;
  max-height: 82vh;
  display: flex;
  flex-direction: column;
  background: #0e100d;
  border-top: 1px solid var(--line-hi);
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
  box-shadow: 0 -10px 32px rgba(0, 0, 0, .7);
  animation: drawerUp .22s cubic-bezier(.2, .7, .3, 1) both;
}
@keyframes drawerUp { from { transform: translateY(100%) } to { transform: translateY(0) } }

.drawer-head {
  display: flex; align-items: baseline; gap: 10px;
  padding: 12px 16px 8px;
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}
.drawer-title { font-size: 15px; color: var(--brass-hi); letter-spacing: .08em; }
.drawer-title .en {
  font-family: var(--mono); font-size: 9px; color: var(--ink-faint);
  letter-spacing: .22em; margin-left: 8px;
}
.drawer-meta {
  font-family: var(--mono); font-size: 11px; color: var(--ink-dim);
  display: flex; align-items: baseline; gap: 6px;
}
.drawer-meta .sep { color: var(--ink-faint); }
.drawer-meta .stat-ico { color: var(--brass); margin-right: 2px; }
.drawer-meta b { color: var(--brass-hi); font-weight: 400; }
.drawer-x {
  appearance: none; background: none; border: none;
  color: var(--ink-dim); font-size: 15px; cursor: pointer;
  margin-left: auto; padding: 0 2px; line-height: 1;
}
.drawer-x:hover { color: var(--rust); }

.drawer-tabs {
  display: flex; gap: 0; overflow-x: auto;
  padding: 0 8px;
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
  scrollbar-width: none;
}
.drawer-tabs::-webkit-scrollbar { display: none; }
.dtab {
  appearance: none; background: none; border: none;
  border-bottom: 2px solid transparent;
  color: var(--ink-dim);
  font-family: var(--sans); font-size: 12px;
  padding: 9px 10px 8px;
  cursor: pointer; white-space: nowrap;
  transition: color .12s, border-color .12s;
}
.dtab:hover { color: var(--ink-soft); }
.dtab.on { color: var(--brass-hi); border-bottom-color: var(--brass); }

.drawer-list {
  flex: 1 1 auto; overflow-y: auto;
  /* 底部多留一截：滚到最底下时让渐隐吃掉这截空白，别吃掉最后一行字 */
  padding: 12px 12px 24px;
  -webkit-overflow-scrolling: touch;
}
/* 列表比抽屉高时才渐隐底边，滚到底就收起来——不然最后一行永远糊着 */
.drawer-list.has-more {
  mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent 100%);
}
.drawer-foot {
  flex: 0 0 auto;
  padding: 8px 16px calc(10px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 11px;
  color: var(--ink-dim); min-height: 14px;
}
.drawer-foot .warn { color: var(--warn); }

/* 分类小标题 */
.bag-cat {
  display: flex; align-items: baseline; gap: 8px;
  margin: 4px 4px 6px;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: .18em; color: var(--brass-dim);
  text-transform: none;
}
.bag-cat .cat-desc { color: var(--ink-faint); letter-spacing: 0; font-size: 10px; }

/* 单件物品 */
.bag-item {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 10px;
  padding: 9px 10px;
  margin-bottom: 6px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--line-hi);
  border-radius: 2px;
  background: rgba(255, 255, 255, .012);
  cursor: pointer;
  transition: border-color .12s, background .12s;
}
.bag-item:hover { border-color: var(--line-hi); border-left-color: var(--brass-dim); }
.bag-item.open { border-left-color: var(--brass); background: rgba(184, 148, 47, .05); }
.bag-item.sel { border-left-color: var(--brass-hi); }
.bag-item.dim { opacity: .45; }

.bi-name { font-size: 13px; color: var(--ink); }
.bi-name .bi-n {
  font-family: var(--mono); font-size: 10px; color: var(--ink-dim);
  margin-left: 6px;
}
.bi-uses { font-family: var(--mono); font-size: 10px; color: var(--ink-faint); margin-left: 6px; }
.bi-uses.low { color: var(--warn); }
.bi-right { text-align: right; font-family: var(--mono); font-size: 11px; white-space: nowrap; }
.bi-price { color: var(--brass); }
.bi-price .stat-ico { font-size: 9px; margin-right: 1px; opacity: .8; }
.bi-price.no { color: var(--ink-faint); font-size: 10px; }
/* 通缉加价：划掉的原价 + 一句解释。
 * 只写「贵了」玩家会以为这家店黑；得让他知道是自己被认出来了。 */
.bi-was {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--ink-faint);
  text-decoration: line-through;
  margin-right: 5px;
}
.price-mark {
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.7;
  color: var(--rust);
  letter-spacing: .04em;
  padding: 0 2px 10px;
}
.bi-desc {
  grid-column: 1 / -1;
  font-size: 11.5px; line-height: 1.6;
  color: var(--ink-dim);
  margin-top: 3px;
}
.bi-use {
  grid-column: 1 / -1;
  font-size: 11.5px; line-height: 1.6;
  color: var(--ink-faint);
  border-left: 1px solid var(--line-hi);
  padding-left: 8px;
  margin-top: 5px;
  display: none;
}
.bag-item.open .bi-use { display: block; }

.bi-acts {
  grid-column: 1 / -1;
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-top: 7px;
  display: none;
}
.bag-item.open .bi-acts { display: flex; }
.bi-btn {
  appearance: none; background: none;
  border: 1px solid var(--line-hi);
  border-radius: 2px;
  color: var(--ink-soft);
  font-family: var(--sans); font-size: 11.5px;
  padding: 4px 10px; cursor: pointer;
  transition: color .12s, border-color .12s;
}
.bi-btn:hover { color: var(--brass-hi); border-color: var(--brass-dim); }
.bi-btn.buy { border-color: var(--brass-dim); color: var(--brass); }
.bi-btn.buy:hover { border-color: var(--brass); color: var(--brass-hi); }
.bi-btn:disabled { opacity: .35; cursor: not-allowed; }
.bi-btn:disabled:hover { color: var(--ink-soft); border-color: var(--line-hi); }

/* 空背包 */
.bag-empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--ink-faint);
  font-size: 13px;
  line-height: 2;
}

/* ============================================================ 地形图 */

.map-canvas {
  position: relative;
  height: 340px;
  margin: 4px 0 2px;
  border: 1px solid var(--line);
  background:
    /* 雾。越往外越淡，像真的看不清远处。 */
    radial-gradient(ellipse 70% 60% at 50% 55%, rgba(184,148,47,.055), transparent 70%),
    repeating-linear-gradient(0deg, rgba(216,210,196,.018) 0 1px, transparent 1px 26px),
    repeating-linear-gradient(90deg, rgba(216,210,196,.018) 0 1px, transparent 1px 26px),
    #0a0b09;
  overflow: hidden;
}
.map-canvas svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.mc-line { stroke: var(--line-hi); stroke-width: 1; stroke-dasharray: 3 4; }
.mc-line.reach { stroke: var(--brass-dim); stroke-dasharray: none; }

.map-node {
  position: absolute;
  transform: translate(-50%, -50%);
  display: flex; flex-direction: column;
  align-items: center; gap: 2px;
  cursor: default;
  z-index: 2;
}
.map-node .mn-dot {
  width: 9px; height: 9px;
  border: 1px solid var(--ink-dim);
  background: #0a0b09;
  transform: rotate(45deg);
}
.map-node .mn-name {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .04em;
  color: var(--ink-dim);
  white-space: nowrap;
  text-shadow: 0 0 6px #0a0b09, 0 0 6px #0a0b09;
}
.map-node.here .mn-dot {
  width: 12px; height: 12px;
  border-color: var(--brass-hi);
  background: var(--brass);
  box-shadow: 0 0 10px rgba(224,185,78,.6);
  animation: herePulse 2.4s ease-in-out infinite;
}
.map-node.here .mn-name { color: var(--brass-hi); }
@keyframes herePulse {
  0%, 100% { box-shadow: 0 0 8px rgba(224,185,78,.45); }
  50%      { box-shadow: 0 0 16px rgba(224,185,78,.85); }
}
.map-node.visited .mn-dot { border-color: var(--ink-soft); }
.map-node.visited .mn-name { color: var(--ink-soft); }

/* 已探明但没去过的：虚线框，明显弱一档 */
.map-node.reach { cursor: pointer; }
.map-node.reach .mn-dot {
  border-color: var(--brass-dim);
  border-style: dashed;
}
.map-node.reach .mn-name { color: var(--ink-soft); }
.map-node.reach:hover .mn-dot { border-color: var(--brass-hi); background: rgba(184,148,47,.35); }
.map-node.reach:hover .mn-name { color: var(--brass-hi); }

/* 威胁等级只改点的颜色，不改大小——大小代表「去过」，别混 */
.map-node.t-mid  .mn-dot { border-color: var(--warn); }
.map-node.t-high .mn-dot { border-color: var(--bad); }
.map-node.t-dead .mn-dot { border-color: var(--bad); background: rgba(180,67,47,.4); }

.map-node .mn-badge {
  font-family: var(--mono);
  font-size: 8px;
  color: var(--ink-faint);
  letter-spacing: .06em;
}

/* 这一格站着谁。名字用黄铜，没见过的写「有人」用暗色 */
.map-node .mn-npc {
  display: flex;
  gap: 4px;
  margin-top: 1px;
}
.map-node .mn-npc span {
  font-family: var(--mono);
  font-size: 8px;
  letter-spacing: .06em;
  color: var(--brass);
  text-shadow: 0 1px 3px #000, 0 0 6px #000;
}
.map-node .mn-npc span:only-child {
  font-size: 9px;
}

/* —— 扫描页 */
.scan-head {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 12px 0 8px;
  border-bottom: 1px dashed var(--line);
  margin-bottom: 10px;
}
.scan-at { font-size: 14px; color: var(--ink); }
.scan-at .en { font-family: var(--mono); font-size: 9px; color: var(--ink-faint); letter-spacing: .18em; margin-left: 6px; }
.scan-worst {
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
  padding: 2px 6px; border: 1px solid currentColor;
}
.scan-worst.w-safe { color: var(--ok); }
.scan-worst.w-low  { color: var(--cool); }
.scan-worst.w-mid  { color: var(--warn); }
.scan-worst.w-high, .scan-worst.w-dead { color: var(--bad); }

.scan-ring {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 2px 8px;
  align-items: baseline;
  padding: 7px 0;
  border-bottom: 1px solid rgba(46,44,30,.5);
}
.scan-ring .sr-dir {
  font-family: var(--mono); font-size: 10px; color: var(--ink-dim); letter-spacing: .04em;
}
.scan-ring .sr-name { font-size: 13px; color: var(--ink-soft); }
.scan-ring .sr-name .sr-sub { font-size: 10px; color: var(--ink-faint); margin-left: 6px; }
.scan-ring .sr-name .sr-npc {
  font-size: 10px; color: var(--brass); margin-left: 6px; letter-spacing: .04em;
}
.scan-here-npc {
  font-family: var(--mono); font-size: 10px; letter-spacing: .06em;
  color: var(--brass); padding: 6px 0 10px;
  border-bottom: 1px dashed var(--line);
  margin-bottom: 10px;
}
.scan-ring .sr-threat {
  font-family: var(--mono); font-size: 9px; letter-spacing: .1em;
  padding: 1px 5px; border: 1px solid currentColor;
}
.scan-ring.t-safe .sr-threat { color: var(--ok); }
.scan-ring.t-low  .sr-threat { color: var(--cool); }
.scan-ring.t-mid  .sr-threat { color: var(--warn); }
.scan-ring.t-high .sr-threat,
.scan-ring.t-dead .sr-threat { color: var(--bad); }
.scan-ring.t-high .sr-name,
.scan-ring.t-dead .sr-name { color: var(--bad); }

.scan-ambient {
  margin-top: 14px; padding-top: 12px;
  border-top: 1px dashed var(--line);
  display: grid; grid-template-columns: auto 1fr; gap: 5px 12px;
  font-size: 12px;
}
.scan-ambient dt { font-family: var(--mono); font-size: 10px; color: var(--ink-faint); letter-spacing: .1em; }
.scan-ambient dd { color: var(--ink-soft); }
.scan-ambient dd.bad { color: var(--bad); }
.scan-ambient dd.warn { color: var(--warn); }

/* ============================================================ 终局 */
/* 一局最后看到的画面。它不该像一条日志，该像一块碑。 */

#ending { flex: 1; display: flex; padding: 44px 22px 60px; overflow-y: auto; }
.ending-wrap { width: 100%; max-width: 620px; margin: 0 auto; }

.ending-kicker {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .34em;
  color: var(--rust);
  text-align: center;
  margin-bottom: 14px;
}
.ending-kicker::before { content: '【'; }
.ending-kicker::after { content: '】'; }

.ending-title {
  font-family: var(--serif);
  font-size: 34px;
  font-weight: 800;
  letter-spacing: .1em;
  color: var(--brass-hi);
  text-align: center;
  margin: 0 0 6px;
  line-height: 1.24;
  text-shadow: 0 0 26px rgba(224, 185, 78, .18);
}

.ending-title-en {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .28em;
  color: var(--ink-faint);
  text-align: center;
  text-transform: uppercase;
  margin-bottom: 20px;
}

.ending-wrap .wave { text-align: center; margin: 0 0 22px; opacity: .5; }

.ending-body p {
  font-size: 16px;
  line-height: 1.92;
  color: var(--ink);
  margin: 0 0 16px;
  text-indent: 2em;
}
/* 结局第一段不缩进——它是一句话，不是一段叙述 */
.ending-body p:first-child { text-indent: 0; }
.ending-body p:first-child::first-letter {
  font-size: 30px;
  color: var(--brass-hi);
  font-family: var(--serif);
}
/* 死亡结局临场那段单独着色：它是玩家亲眼看见的，不是旁白总结 */
.ending-body .played {
  color: var(--bad);
  font-style: normal;
  border-left: 2px solid var(--rust-dim);
  padding-left: 14px;
  text-indent: 0;
  font-size: 17px;
}

/* 判词：你走过来的样子。
 * 十种结局 × 四种活法 = 四十种终局文本，引擎按痕迹权重算出来的一小段话。
 * 排版上要跟「发生了什么」（正文）分开：正文是衬线、有首行缩进；
 * 判词是等宽、居中偏左、带一点锈色——它像一行刻在炉壁内侧的字，
 * 不是故事的一部分，是故事之后留下的东西。 */
.ending-verdict {
  margin: 30px 0 0;
  padding: 18px 0 0;
  border-top: 1px dashed var(--line);
  text-align: left;
}

.ending-verdict .ev-line {
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.95;
  letter-spacing: .06em;
  color: var(--brass-hi);
}

.ending-verdict .ev-foot {
  margin-top: 8px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.9;
  color: var(--ink-dim);
  opacity: .85;
}

.ending-foot {
  margin: 26px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.9;
  color: var(--ink-dim);
  text-align: center;
}

/* —— 账本：这一局你做过的事 —— */
/* 结局值不值得截屏，几乎全看这一块。数值谁都有，故事只有这一局有。 */
/* ---------------------------------------------------------------- 账 CHRONICLE
   阶段 18。一页纸，排在「判词」与「流水账本」之间。
   视觉上要比结局正文更冷、更干——它是记录，不是故事：
   无衬线、等宽的数字、很细的分隔线、没有装饰。 */
.chronicle {
  margin: 34px 0 0;
  padding: 22px 0 0;
  border-top: 1px solid var(--line);
}
.chronicle[hidden] { display: none; }

.chron-head { margin-bottom: 20px; }
.chron-title {
  font-family: var(--serif);
  font-size: 19px;
  letter-spacing: .12em;
  color: var(--brass-hi);
}
.chron-sub {
  margin-top: 6px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .1em;
  color: var(--ink-dim);
}

.chron-sec {
  display: grid;
  grid-template-columns: 84px 1fr;
  gap: 6px 14px;
  padding: 11px 0;
  border-bottom: 1px dotted rgba(120, 100, 70, .18);
}
.chron-sec:last-child { border-bottom: none; }

.chron-k {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .1em;
  color: var(--brass);
  padding-top: 1px;
  white-space: nowrap;
}
.chron-ico {
  display: inline-block;
  width: 14px;
  color: var(--rust-hi);
  opacity: .8;
}

.chron-lines { min-width: 0; }
.chron-line {
  font-size: 13.5px;
  line-height: 1.95;
  color: #b6ad9a;
  /* 数字用 tabular-nums，让上下几行的数位对齐——
     这一页有一半是数字，歪着读起来像报表没做完。 */
  font-variant-numeric: tabular-nums;
}
.chron-line + .chron-line { margin-top: 1px; }

@media (prefers-reduced-motion: no-preference) {
  .chronicle { animation: chronIn 700ms ease-out both; }
  @keyframes chronIn {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
  }
}

.ending-ledger { margin: 32px 0 0; }
.ledger-head {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .22em;
  color: var(--ink-faint);
  margin-bottom: 12px;
}
.ledger-head::before { content: '▸ '; color: var(--brass-dim); }

.ledger-list { display: flex; flex-direction: column; gap: 1px; }

.ledger-row {
  display: grid;
  grid-template-columns: 46px 1fr;
  gap: 10px;
  align-items: baseline;
  padding: 9px 0;
  border-bottom: 1px dashed rgba(74, 67, 38, .34);
}
.ledger-row:last-child { border-bottom: none; }

.lr-turn {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--ink-faint);
  letter-spacing: .04em;
}
.lr-text {
  font-size: 14px;
  line-height: 1.72;
  color: var(--ink-soft);
}
/* 那些不可撤销的：锈色竖线，一眼看出「这一步改不回来了」 */
.ledger-row.perm .lr-text { color: var(--ink); }
.ledger-row.perm { border-left: 2px solid var(--rust); padding-left: 10px; }
.ledger-row.perm .lr-turn { color: var(--rust); }

/* —— 结算数值 —— */
.ending-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  justify-content: center;
  margin: 28px 0 0;
  padding: 16px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-dim);
}
.ending-stats b {
  color: var(--ink-soft);
  font-weight: 600;
  margin-left: 4px;
}

.ending-acts {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 34px;
}

/* —— 图鉴 —— */
.gal-row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 12px;
  padding: 13px 0;
  border-bottom: 1px dashed rgba(74, 67, 38, .3);
}
.gal-row:last-child { border-bottom: none; }

.gal-mark {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink-faint);
  grid-row: span 2;
  padding-top: 2px;
}
.gal-row.on .gal-mark { color: var(--brass-hi); }

.gal-title {
  font-size: 15px;
  color: var(--ink-dim);
  letter-spacing: .05em;
}
.gal-row.on .gal-title { color: var(--brass-hi); }
.gal-row.locked .gal-title { color: var(--ink-faint); }

.gal-kind {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: .16em;
  color: var(--ink-faint);
  margin-left: 8px;
}
.gal-row.on .gal-kind { color: var(--rust); }

.gal-hint {
  font-size: 12px;
  line-height: 1.7;
  color: var(--ink-faint);
}
.gal-row.close .gal-hint { color: var(--warn); }
.gal-row.on .gal-hint { color: var(--ink-dim); }
.gal-excerpt {
  grid-column: 2;
  font-size: 13px;
  line-height: 1.78;
  color: var(--ink-soft);
  margin-top: 6px;
  padding-left: 12px;
  border-left: 1px solid var(--line-hi);
}

/* ============================================================ 锈长在界面上（阶段 15） */

/*
  四档：清 / 起锈 / 及骨 / 将变。

  这里是**唯一**允许让正文看起来"不太对"的地方。
  三条 CSS 层面的硬约束，改的时候别忘：
  1. 只用 filter / opacity / text-shadow / 极小位移，**绝不改 font-size 或 letter-spacing**
     —— 一改字形度量，整段会重排，那是排版事故不是演出。
  2. 动效周期全部 ≥ 3s 且振幅 ≤ .35px。快抖 = 电视雪花 = 玩家以为卡了。
  3. 全部包在 @media (prefers-reduced-motion: no-preference) 里。
     开了减弱动效的人只会看到静态的锈色，不会看到抖。
*/

/* 档 1 · 起锈：字还在，只是有点旧 */
.prose.veil-1 {
  color: #cfc7b4;
  text-shadow: 0 0 .6px rgba(168, 68, 42, .35);
}

/* 档 2 · 及骨：字开始站不太住 */
.prose.veil-2 {
  color: #c6bda8;
  text-shadow:
    0 0 1px rgba(168, 68, 42, .5),
    .3px .25px 0 rgba(107, 44, 28, .35);
}
.prose.veil-2 .said {
  color: #d8c9a6;
  text-shadow: 0 0 1.4px rgba(168, 68, 42, .55);
}

/* 档 3 · 将变：行距不再完全均匀 */
.prose.veil-3 {
  color: #bdb49e;
  text-shadow:
    0 0 1.4px rgba(168, 68, 42, .62),
    .42px .35px 0 rgba(107, 44, 28, .45);
}
.prose.veil-3 .said {
  color: #cdbb94;
  text-shadow: 0 0 2px rgba(196, 84, 50, .55);
}

/* 单段级的轻微错位（renderProse 给档 ≥2 的段落加的 class） */
.p-tremor {
  animation: pTremor 7s ease-in-out infinite;
}
@keyframes pTremor {
  0%, 100% { transform: translate3d(0, 0, 0); }
  28% { transform: translate3d(.22px, -.18px, 0); }
  61% { transform: translate3d(-.18px, .22px, 0); }
  84% { transform: translate3d(.12px, .1px, 0); }
}

/*
  单个字的锈：把那个字染成锈色。

  ⚠ 为什么不用 Unicode 组合符（U+0336 长横线之类）：
  实测在 16px 宋体下，带组合符的那一行宽出 11 像素。
  组合符的 advance width 在多数中文字体里不是 0，
  中文正文一行三十来字，每行都往右偏一点，就是排版事故。

  ⚠ 为什么不用「换成一个形状差不多的怪符号」：
  试过，那个字会跟周围字不是一套字形，读起来像编码错误。

  ⚠ 为什么最后没有用"在字上盖一道斜裂"（我最初的设计）：
  宽度验证完美——四档 getBoundingClientRect().height 全等 258.375。
  但在 1280×800 真机截图里，1px 宽的对角线穿过 17px 的中文字，
  肉眼几乎看不见；我放大到 2.1 倍才勉强认出来，而玩家不会放大。
  又试了四种盖法：screen（被背景吃掉）、multiply（变脏但不明显）、
  近背景色啃掉（像字被咬了一块，读起来像渲染错误）、
  横贯锈带（像被人用红笔划了一道）。都不对。

  染色的好处是它说的是同一件事，而且一眼就懂：
  **不是这个字变了，是你读它的方式变了**——那个字确实在你眼里开始发锈了。
  代价最小：color 和 text-shadow 都不参与排版，宽度一个像素都不动。
*/
.rust-bit {
  /* 不改任何字形度量：字号、行高、字距、盒模型全都继承。
     这里连 display 都不改——inline 才是零影响的，
     inline-block 会让基线对齐规则变化，中文行里偶发顶起 1px。 */
  color: var(--rust-hi, #b85a33);
  /* 一点点渗光——锈在往外洇，不是在往下掉 */
  text-shadow: 0 0 4px rgba(168, 68, 42, .45);
}

/*
 * 三档的差别不是"裂得多宽"，是"锈得多深"。
 *
 * 档 1 只染色不渗光——看起来像这个字本来就印得比旁边旧一点，
 *      玩家会怀疑自己看错了。这正是要的：起锈的第一阶段，
 *      连你自己都不确定是不是眼睛出了问题。
 * 档 2 加渗光——开始往外洇，承认了。
 * 档 3 深锈 + 更重的光晕——那个字已经在你眼里烂进骨了。
 */
.prose.veil-1 .rust-bit {
  color: #a9754a;
  text-shadow: none;
}
.prose.veil-2 .rust-bit {
  color: var(--rust-hi, #b85a33);
  text-shadow: 0 0 4px rgba(168, 68, 42, .45);
}
.prose.veil-3 .rust-bit {
  color: #9e4426;
  text-shadow:
    0 0 5px rgba(168, 68, 42, .6),
    0 0 11px rgba(107, 44, 28, .35);
}

/* 那半句"没人说过的话" */
.ghost-line {
  color: #a8442a;
  opacity: .82;
  margin-top: .9em;
  padding-left: 1.1em;
  border-left: 1px solid rgba(168, 68, 42, .45);
  font-style: normal;
  letter-spacing: .04em;
  transition: opacity .9s ease;
}
.ghost-line.fading { opacity: 0; }

/* HUD 的把柄条：只染颜色，不动数值（硬约束之二） */
.bar-item.veil-pulse .bar-fill.low,
.bar-item.veil-pulse .bar-fill.mid {
  animation: steelPulse 4.4s ease-in-out infinite;
}
.bar-item.veil-urgent .bar-fill.low,
.bar-item.veil-urgent .bar-fill.mid {
  animation: steelPulse 2.2s ease-in-out infinite;
}
@keyframes steelPulse {
  0%, 100% { filter: brightness(1); }
  50% { filter: brightness(1.28) saturate(1.15); }
}
.bar-item[data-k="corrosion"].veil-pulse .bar-label > span:first-child {
  color: var(--rust-hi);
}

/* 把柄档位压到根节点上，给"墙"那个字符画用 */
:root[data-veil="2"] .veil-tint,
:root[data-veil="3"] .veil-tint { opacity: .9; }

@media (prefers-reduced-motion: reduce) {
  .p-tremor { animation: none !important; }
  .bar-item.veil-pulse .bar-fill,
  .bar-item.veil-urgent .bar-fill { animation: none !important; }
}

/* ============================================================ 心炉内壁 */

/* 这面墙的每一条样式都在服务同一件事：让人相信他正在看自己胸腔里的东西。
   所以它不能像 UI。没有圆角、没有卡片、没有留白呼吸感——
   只有一块被烧过、被刻过、正在锈的铁。 */

.wall-body {
  /* 比别的抽屉宽一点：40 格字符画需要地方。 */
  max-width: 620px;
}

.wall-list {
  /* 字符画不许折行。宁可横向滚，也不能让「⛰岩学徒级」被切成两行——
     切了就不是铭文了，是 tab 坏了。 */
  overflow-x: auto;
  overflow-y: auto;
  padding: 18px 20px 6px;
  /* 让 inline-block 的那块字符画居中 */
  text-align: center;
}

.wall-remark {
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.9;
  color: var(--ink-dim);
  letter-spacing: .03em;
  margin-bottom: 14px;
  padding-left: .9em;
  border-left: 2px solid rgba(184, 148, 47, .3);
  /* 抬头这句是说明文字，不能跟着字符画一起居中——
     .wall-list 的 text-align:center 是给那块 <pre> 用的。 */
  text-align: left;
}

.furnace-wall {
  margin: 0;
  /* 整块字符画作为一个整体居中：inline-block 让 pre 的宽度跟着内容走，
     父容器的 text-align:center 就能把它居中。行内仍然左对齐——
     这样「岩 / 学徒级 / 代价」三层缩进才保得住。
     不能给 pre 自己设 text-align:center：这套字体里汉字是拉丁字符的
     1.705 倍宽而不是 2 倍，逐行居中会让每行的左边缘各偏一段，字就散了。 */
  display: inline-block;
  text-align: left;
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.62;
  letter-spacing: 0;
  color: #b9ae95;
  white-space: pre;
  /* 墙的底色不是纯黑：铁在火里烧久了会泛出一点暖。
     但没有格子、没有边框——它不是容器，它是一面墙。 */
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(184, 148, 47, .045), transparent 62%),
    radial-gradient(90% 70% at 50% 100%, rgba(168, 68, 42, .05), transparent 60%);
  padding: 20px 14px;
  text-shadow: 0 0 3px rgba(184, 148, 47, .12);
}

/* 三档的温度差。注意：只动颜色与光，绝不动字号与字距——
   那些一改，40 格的对齐就全散了，字符画立刻变成乱码。 */
.furnace-wall.lv-1 { color: #b3a892; }
.furnace-wall.lv-2 {
  color: #ab9f88;
  text-shadow: 0 0 4px rgba(168, 68, 42, .16);
}
.furnace-wall.lv-3 {
  color: #a0947c;
  text-shadow:
    0 0 5px rgba(168, 68, 42, .24),
    0 0 14px rgba(107, 44, 28, .12);
}

/* 底部三条账。它们是这面墙上唯一的数字，
   因为「占了多少容积」是玩家真正需要核对的那件事。 */
.wall-foot {
  display: flex;
  gap: 26px;
  flex-wrap: wrap;
  align-items: baseline;
}

.wall-acc {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}

.wa-k {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: .16em;
  color: var(--ink-dim);
  opacity: .8;
}

.wa-v {
  font-family: var(--mono);
  font-size: 14px;
  color: var(--brass-hi);
  font-variant-numeric: tabular-nums;
}

.wa-h {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--ink-dim);
  opacity: .6;
}

/* 抽屉标题旁那个档名 */
.wall-lv {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .18em;
  padding: 2px 8px;
  border: 1px solid rgba(184, 148, 47, .28);
}
.wall-lv.lv-1 { color: #a9754a; border-color: rgba(169, 117, 74, .32); }
.wall-lv.lv-2 { color: var(--rust-hi); border-color: rgba(184, 90, 51, .38); }
.wall-lv.lv-3 {
  color: #c4683c;
  border-color: rgba(184, 90, 51, .5);
  text-shadow: 0 0 5px rgba(168, 68, 42, .4);
}

/* ============================================================ 模型设置
   这一屏的读者不是开发者，是拿到这个游戏的人。
   所以它不能长得像配置文件编辑器：不要满屏等宽字、不要技术名词、
   不要「必填」这种语气。要像一张说明卡，让他知道现在该做什么。
   ============================================================ */

.title-setup {
  margin-top: 14px;
}

/* 「没接上模型」时让设置按钮亮起来——整屏就这一个出口，
   这时候还让它灰扑扑的，玩家会以为连出口都没有。 */
.btn-mini.urge {
  border-color: var(--rust);
  color: var(--rust-hi);
  animation: urgePulse 2s ease-in-out infinite;
}

@keyframes urgePulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(168, 68, 42, 0); }
  50%      { box-shadow: 0 0 0 3px rgba(168, 68, 42, 0.18); }
}

#setup {
  flex: 1;
  padding: 22px 20px 90px;
  overflow-y: auto;
}

.setup-wrap {
  max-width: 520px;
  margin: 0 auto;
}

.setup-kicker {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .28em;
  color: var(--rust-hi);
  margin-bottom: 22px;
}

.setup-title {
  font-family: var(--serif);
  font-size: 25px;
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: .04em;
  color: var(--brass-hi);
  margin: 0 0 16px;
}

.setup-lede {
  font-family: var(--serif);
  font-size: 14px;
  line-height: 1.95;
  color: var(--ink-soft);
  margin: 0 0 22px;
}

.setup-lede.dim {
  font-size: 13px;
  color: var(--ink-dim);
}

/* 两个 tab：在线 / 本机。
   做成「两个字的开关」而不是下拉——这里只有两种选择，
   用下拉会让第一次打开的人还要多点一次才知道还有另一个。 */
.setup-tabs {
  display: flex;
  gap: 2px;
  margin-bottom: 24px;
  border-bottom: 1px solid var(--line);
}

.stab {
  flex: 1;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .16em;
  color: var(--ink-dim);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 11px 8px;
  cursor: pointer;
  transition: color .18s, border-color .18s;
}

.stab:hover { color: var(--ink-soft); }

.stab.on {
  color: var(--brass-hi);
  border-bottom-color: var(--brass);
}

.setup-row {
  display: grid;
  grid-template-columns: 62px 1fr;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}

.setup-label {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .12em;
  color: var(--ink-dim);
}

.setup-input,
.setup-select {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink);
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 9px 11px;
  width: 100%;
  min-width: 0;
  transition: border-color .18s;
}

.setup-input:focus,
.setup-select:focus {
  outline: none;
  border-color: var(--brass-dim);
}

.setup-input::placeholder { color: var(--ink-dim); opacity: .75; }

.setup-note {
  font-family: var(--serif);
  font-size: 12.5px;
  line-height: 1.8;
  color: var(--brass-dim);
  margin: -4px 0 16px 74px;
}

.setup-note.dim { color: var(--ink-dim); }

.setup-result {
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.85;
  padding: 11px 13px;
  border-left: 2px solid var(--line);
  border-radius: 2px;
  margin: 18px 0;
  word-break: break-word;
}

.setup-result.ok {
  border-left-color: var(--brass);
  color: var(--brass-hi);
  background: rgba(184, 148, 47, 0.06);
}

.setup-result.bad {
  border-left-color: var(--rust);
  color: var(--rust-hi);
  background: rgba(168, 68, 42, 0.07);
}

.setup-acts {
  display: flex;
  gap: 10px;
  margin-top: 26px;
  flex-wrap: wrap;
}

.setup-acts .btn {
  flex: 1;
  min-width: 110px;
  justify-content: center;
}

/* ============================================================ 小屏适配 */

@media (max-height: 700px) {
  .title-main { font-size: 38px; }
  .title-lines { margin-bottom: 26px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}


/* 架势条：战斗里的第二根缓冲。破了才扣炉压。 */
.duel-bar .db-poise { width: 92px; flex: none; display: flex; align-items: center; }
.duel-bar .dp-track {
  flex: 1;
  height: 4px;
  background: #241f15;
  border: 1px solid #332a1b;
  overflow: hidden;
}
.duel-bar .dp-fill {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--brass);
  transition: width .35s ease;
}
.duel-bar .dp-fill.broken { background: #e0522c; animation: pulse 1.2s ease-in-out infinite; }


/* 歇班三选一：停下来这一班拿来干什么 */
.rest-list { display: flex; flex-direction: column; gap: 10px; }
.rest-card {
  text-align: left;
  appearance: none;
  -webkit-appearance: none;
  background: #17130d;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 12px 14px;
  cursor: pointer;
  color: var(--ink-soft);
  transition: border-color .15s, background .15s;
}
.rest-card:hover { border-color: var(--brass-dim); background: #1b1610; }
.rest-card.off { opacity: .45; cursor: not-allowed; }
.rc-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px; }
.rc-title { font-size: 15px; color: var(--brass-hi); letter-spacing: .06em; }
.rc-sub { font-size: 11px; color: var(--ink-dim); }
.rc-desc { font-size: 12px; line-height: 1.7; color: var(--ink-soft); margin-bottom: 8px; }
.rc-cost { font-family: var(--mono); font-size: 11px; color: var(--brass); }


/* ══════════════════════════════════════════════════════════════════
   邀请码屏
   ══════════════════════════════════════════════════════════════════
   这一屏是公网上别人看到的第一眼，所以它只做一件事：
   让人知道「这里需要一把钥匙」，并且把那把钥匙的输入框放在最显眼处。

   刻意没有做「申请入口」「联系管理员」这类东西——
   这个游戏是发给认识的人玩的，链接之外的信息一概不提供。
   门关着就是关着，不该假装还有别的路。
   ────────────────────────────────────────────────────────────────── */

#gate {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 32px 24px;
  box-sizing: border-box;
  text-align: center;
}

.gate-body { width: 100%; max-width: 340px; }

/* ── 页签 ──
   三格等宽，靠下划线亮起来表示当前在哪一页。
   不用 tab 组件（项目里没有），也不用 border 包盒子——
   这一屏已经很窄了，再画框会把输入位置挤没。 */
.gate-tabs {
  display: flex;
  gap: 0;
  margin-bottom: 26px;
  border-bottom: 1px solid rgba(184, 148, 47, .18);
}

/* hidden 在 author 样式里打不过 display:flex ——
   浏览器自带的 [hidden]{display:none} 优先级比类选择器低，
   所以「隐藏页签」这件事必须显式再写一条。
   踩过：建完号展示找回码时页签没退下去，玩家还能点「注册」再建一个。 */
.gate-tabs[hidden] { display: none; }

.gate-tab {
  flex: 1;
  padding: 10px 0 12px;
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: .3em;
  color: var(--ink-dim);
  background: none;
  border: none;
  border-bottom: 1px solid transparent;
  margin-bottom: -1px;
  cursor: pointer;
  transition: color .18s, border-color .18s;
}

.gate-tab:hover { color: var(--ink-soft); }
.gate-tab.on {
  color: var(--brass-hi);
  border-bottom-color: var(--brass);
}

.gate-pane[hidden] { display: none; }

.gate-line {
  font-size: 14px;
  line-height: 1.9;
  color: var(--ink-soft);
  margin: 0 0 6px;
}

.gate-line.dim { font-size: 12px; color: var(--ink-dim); margin-bottom: 30px; }

.gate-form { display: flex; flex-direction: column; gap: 12px; }

.gate-input {
  width: 100%;
  box-sizing: border-box;
  padding: 14px 16px;
  font-family: var(--mono);
  font-size: 15px;
  letter-spacing: .1em;
  text-align: center;
  color: var(--brass-hi);
  background: #0c0d0b;
  border: 1px solid rgba(184, 148, 47, .34);
  border-radius: 3px;
  outline: none;
}

/* 只有邀请码那一格需要全大写（码本身就是大写的）。
   名字和口令若是也强制大写，玩家输入时看到的和他实际输的会不一致，
   而口令里大小写是有意义的——这一条能让人对着键盘输十遍输不对。 */
#gate-code, #reg-code {
  letter-spacing: .26em;
  text-transform: uppercase;
}

#gate-name, #reg-name, #gate-pass, #reg-pass, #reg-pass2 {
  letter-spacing: .06em;
  font-size: 15px;
}

.gate-input::placeholder { color: var(--ink-dim); letter-spacing: .12em; text-transform: none; }
.gate-input:focus { border-color: var(--brass); }

/* 次要入口：「用码进」那一栏。
   放在主表单下面，语气比主表单低一档——它是给老玩家的后门，
   不是给新人看的第二个选择。 */
.gate-alt {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px dashed rgba(184, 148, 47, .16);
}

.gate-alt > p {
  font-size: 11px;
  line-height: 1.8;
  color: var(--ink-dim);
  margin: 0 0 12px;
}

.gate-msg {
  min-height: 20px;
  margin-top: 14px;
  font-size: 12px;
  line-height: 1.7;
  color: var(--bad);
}

.gate-foot {
  margin-top: 26px;
  font-size: 11px;
  line-height: 1.8;
  color: var(--ink-dim);
}

/* 「换人」：挂在用户名后面的一行小字。
   不做成按钮是因为它是一年点一次的操作，
   做得越显眼，越容易在误触时把正在玩的一局关掉。 */
.whoami-out {
  margin-left: 10px;
  font-size: 10px;
  letter-spacing: .1em;
  color: var(--ink-dim);
  text-decoration: none;
  border-bottom: 1px dotted rgba(168, 162, 148, .45);
}

.whoami-out:hover { color: var(--brass); border-bottom-color: var(--brass); }

/* ── 找回码展示（建号成功后的必经一屏）──
   做成一块「单独的东西」而不是普通提示条：
   边框用实线并且比别处亮一档，因为它要拦人一秒。
   玩家的眼睛得先落在这串码上，才看得见下面那个按钮。
   不加过渡动画——淡入会让人觉得「等一下会消失」，而它不会。 */
.recover-show {
  margin-top: 8px;
  padding: 20px 18px;
  text-align: center;
  border: 1px solid rgba(184, 148, 47, .34);
  background: rgba(184, 148, 47, .035);
}

.recover-head {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .42em;
  text-indent: .42em;
  color: var(--ink-dim);
  margin-bottom: 14px;
}

/* 找回码本体：字号明显大于正文、字距拉开、可选中。
   等宽字体加宽字距，是为了让「抄」这件事在视觉上成立——
   密排的 8 位字符抄错一位，等于这串码不存在。 */
.recover-code {
  font-family: var(--mono);
  font-size: 22px;
  letter-spacing: .18em;
  text-indent: .18em;
  color: var(--brass-hi, var(--brass));
  margin-bottom: 18px;
  cursor: text;
  user-select: all;
  -webkit-user-select: all;
}

.recover-warn {
  color: var(--warn, #c98a3c) !important;
}

/* 降级提示：平时不出现，掉到第二档以后才亮一下。
   为什么要有：玩家不会知道「模型」是什么，但他能感觉到文笔突然变糙。
   与其让他以为游戏坏了，不如直接告诉他「今晚烧的是备用的炭」。 */
.chain-note {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  color: var(--warn, #c98b2a);
  margin-top: 6px;
  opacity: .82;
}
