/* 设计语言取自 Claude Design 出的《生死时速》原型稿：
   暖近黑底 + 米色文字 + 琥珀金强调，小偷珊瑚红 / 警察青，
   直角无圆角、1px 低透明琥珀描边、菱形项目符号。 */
:root {
  --bg:       #0e0906;   /* 页面底：暖近黑，不是纯黑 */
  --chrome:   #140d08;   /* 面板/条带 */
  --chrome-2: #1b1109;
  --edge:     #0a0705;
  --ink:      #f5ead6;   /* 米色正文 */
  --muted:    rgba(245,234,214,.45);
  --muted-2:  rgba(245,234,214,.72);
  --accent:   #f0b429;   /* 琥珀金（沿用原有强调色） */
  --accent-hi:#ffd166;
  --accent-lo:#b87514;
  --line:     rgba(240,180,41,.22);
  --line-2:   rgba(240,180,41,.35);
  --thief:    #ff5d73;   /* 小偷：珊瑚红 */
  --police:   #3ee0d0;   /* 警察：青 */
  --ok:       #3ee0d0;
  --bad:      #ff5d73;
  /* 中文用系统字体，不加载 web 字体。Noto Sans SC 是 CJK 字体，
     unicode-range 分片上千个 —— Cloudflare 的字体优化把它内联进 HTML 后，
     每个页面凭空多出 377KB 阻塞渲染的 CSS，绝大部分是页面用不到的字符范围。
     而 PingFang SC / 微软雅黑 / Noto Sans CJK 各平台都自带，观感没有损失。 */
  --font: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", sans-serif;
  --latin: "Chakra Petch", var(--font);
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

button:focus-visible, a:focus-visible, input:focus-visible,
select:focus-visible, summary:focus-visible {
  outline: 2px solid var(--police);
  outline-offset: 3px;
}

html, body {
  margin: 0;
  /* 不再锁 height:100% + overflow:hidden —— 游戏占满首屏，
     正文接在下面，页面整体可以向下滚。 */
  min-height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
}

.cabinet {
  height: 100vh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  /* 列轨道必须写成 minmax(0, 1fr)。
     grid 轨道默认按内容的 max-content 定尺寸，子项设 min-width: 0 也没用 ——
     顶部状态条的 min-content 有 452px，于是整条轨道被撑到 422，
     页面横向滚动、静音按钮跑到屏幕外。375px 的手机上实测过。
     写死 minmax(0, …) 之后轨道才允许比内容窄，
     .stats 那条"横向可滚"的设计（下面窄屏断点里）也才真正生效。 */
  grid-template-columns: minmax(0, 1fr);
  max-width: 1240px;
  margin: 0 auto;
  border-left: 1px solid var(--edge);
  border-right: 1px solid var(--edge);
}

/* ── 顶栏 ───────────────────────────────────────────── */
.bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 18px;
  background: linear-gradient(180deg, var(--chrome-2), var(--chrome));
  border-bottom: 1px solid var(--line);
}

.title {
  font-size: 20px; font-weight: 900; letter-spacing: 3px; white-space: nowrap;
  background: linear-gradient(180deg, #fff3cf, var(--accent) 52%, var(--accent-lo));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.title .sub {
  font-family: var(--latin); font-size: 11px; font-weight: 600; letter-spacing: 4px;
  color: var(--muted); margin-left: 10px;
  background: none; -webkit-text-fill-color: var(--muted);
}

.stats { display: flex; gap: 6px; flex-wrap: wrap; }

.stat {
  min-width: 62px; padding: 5px 11px; text-align: center;
  background: rgba(240,180,41,.05);
  border: 1px solid var(--line);
  border-radius: 0;
}
.stat i { display: block; font-style: normal; font-size: 9px; letter-spacing: 2px; color: var(--muted); }
.stat b { font-family: var(--latin); font-weight: 700; font-size: 17px; color: var(--accent-hi); }
.stat b s { text-decoration: none; font-size: 9px; color: var(--muted); }
.stat.tier b { color: var(--accent); font-family: var(--font); font-weight: 700; font-size: 13px; }

/* ── 画面 ───────────────────────────────────────────── */
/* 原版是 800×600 视口，这里等比缩放居中，保持像素对齐 */
/* 画布是固定 800x600，比容器矮，上下必然留白。设计稿里 HUD 是浮在满幅
   街景上的，所以留白区用同一张底图模糊压暗填充 —— 而不是一片死黑。 */
.screen {
  position: relative; overflow: hidden; display: block;
  background: var(--edge);
}
.screen::before {
  content: ""; position: absolute; inset: -30px; z-index: 0;
  background: var(--menu-bg) center/cover no-repeat;
  filter: blur(26px) brightness(.34) saturate(.9);
}
.screen::after {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(180deg, rgba(14,9,6,.55), rgba(14,9,6,.2) 30%, rgba(14,9,6,.2) 70%, rgba(14,9,6,.72));
}
.stage, .overlay, .chase, .kickoff { z-index: 1; }
#view {
  box-shadow: 0 0 0 1px var(--line), 0 24px 70px rgba(0,0,0,.6);
  /* CSS 兜底，不能只靠 JS 的 _resize()。
     竞速页的 Race 实例是点「开始竞速」才创建的，在那之前 _resize() 一次
     都没跑过，canvas 保持 HTML 里写死的 800x600 —— 手机竖屏（视口 483px）
     下直接把设置面板顶出屏幕，右侧的角色按钮和下拉框全被切掉。
     （追逐模式没这个问题：它的 Game 实例在页面加载时就创建了。）
     max-width 让它在任何情况下都不会超出父容器。 */
  max-width: 100%;
  height: auto;
}

/* 追逐距离条 */
.chase {
  position: absolute;
  top: 40px; left: 50%;
  transform: translateX(-50%);
  display: flex; align-items: center; gap: 8px;
  padding: 6px 12px;
  background: rgba(12,15,20,.72);
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 999px;
  backdrop-filter: blur(4px);
  font-size: 12px;
}
.chase-label { color: var(--muted); }
.chase-track {
  width: 240px; height: 8px; border-radius: 999px; overflow: hidden;
  background: rgba(240,180,41,.14);
  box-shadow: inset 0 0 0 1px var(--line);
}
.chase-track i { display: block; height: 100%; width: 50%; background: var(--ok); transition: width .12s linear, background .2s; }
.chase-num { font-family: var(--latin); font-weight: 700; min-width: 40px; text-align: right; color: var(--accent-hi); }

/* ── 遮罩面板 ────────────────────────────────────────── */
.overlay {
  position: absolute; inset: 0; z-index: 5;
  display: grid; place-items: center; padding: 10px;
  background:
    linear-gradient(180deg, rgba(14,9,6,.86), rgba(14,9,6,.94)),
    radial-gradient(120% 80% at 18% 30%, rgba(240,180,41,.12), transparent 60%),
    var(--menu-bg) center/cover no-repeat;
}
.overlay.hidden { display: none; }

.panel {
  width: min(560px, 92vw);
  padding: 30px 32px 26px;
  background: linear-gradient(165deg, rgba(27,17,9,.97), rgba(14,9,6,.98));
  border: 1px solid var(--line-2);
  border-radius: 0;
  box-shadow: 0 28px 80px rgba(0,0,0,.72), 0 0 60px rgba(240,180,41,.06);
  /* 高度要按【容器】算而不是视口：面板装在 .screen 里，而 .screen 上下
     还有顶栏和待打文本条。用 92vh 会比容器高，短屏上标题被切掉、
     底部按钮看不见（1440x900 实测如此）。 */
  max-height: calc(100% - 20px); overflow-y: auto;
}

/* 主按钮吸在面板底部。
   面板里的选项会越加越多 —— 竞速这边加了角色、难度、圈数、房间码之后
   内容 972px 而可视区只有 820px，主按钮被推到滚动区最底下，
   第一次进来的人看不到怎么开始，得先滚一下才发现。
   sticky 让它无论内容多长都留在视野里；背景必须不透明，否则会透出下面的内容。 */
/* 只有【面板里最后一个可见块】才吸底。
 *
 * 原来写的是 .panel .go —— 对竞速页成立（那里 .go 就是最后一个元素），
 * 但首页的开始按钮下面还有「多人对战大厅」「竞速模式」两个链接和一行说明，
 * sticky 让按钮浮起来，把它们整个盖住了（实测：两个入口被压在按钮下面看不见）。
 *
 * :last-child 不行：.go 后面还有兄弟节点时就不该吸底，而首页正是这种情况。
 * 用 :last-of-type 也不行 —— 那只看同类型标签。所以直接用 :last-child，
 * 让"按钮是不是最后一项"这件事自己决定要不要吸底。 */
.panel .go:last-child {
  position: sticky;
  bottom: -26px;                 /* 抵掉 .panel 的下内边距 */
  margin-bottom: -26px;
  padding-bottom: 26px;
  z-index: 2;
}
.panel .go:last-child::after {
  /* 按钮上方拉一道渐变，滚动时内容不会硬邦邦地被切断 */
  content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 18px;
  background: linear-gradient(to top, rgba(14,9,6,.98), rgba(14,9,6,0));
  pointer-events: none;
}
/* sticky 的按钮浮在滚动内容之上，它上方还没滚到的内容会被压住 ——
   实测房间码那两个输入框被盖了半截。
   解法是给按钮本身留出上边距：sticky 元素的 margin-top 会实际占据
   文档流空间，所以滚到底时前一项能完整露出来。 */
.panel .go {
  margin-top: 16px;
}
.panel h1 {
  margin: 0; font-size: 42px; font-weight: 900; letter-spacing: 7px; line-height: 1.1;
  background: linear-gradient(180deg, #fff3cf, var(--accent) 52%, var(--accent-lo));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* 次要设置与成长信息使用原生 details：键盘、读屏和无 JS 状态都有现成语义。
   复古金属面板不换视觉语言，只把任务层级从“所有东西同时出现”改成按需展开。 */
.setup-more, .progress-hub, .result-more {
  margin: 12px 0;
  border: 1px solid rgba(240,180,41,.25);
  background: rgba(240,180,41,.035);
}
.setup-more > summary, .progress-hub > summary, .result-more > summary {
  min-height: 46px; padding: 10px 13px;
  display: flex; align-items: center; gap: 10px;
  cursor: pointer; list-style: none; color: var(--accent-hi);
  font-size: 13px; font-weight: 800; letter-spacing: 1px;
}
.setup-more > summary::-webkit-details-marker,
.progress-hub > summary::-webkit-details-marker,
.result-more > summary::-webkit-details-marker { display: none; }
.setup-more > summary small, .progress-hub > summary small, .result-more > summary small {
  margin-left: auto; color: var(--muted); font-size: 10px; font-weight: 500; letter-spacing: 0;
}
.setup-more > summary::after, .progress-hub > summary::after, .result-more > summary::after {
  content: "+"; width: 20px; text-align: center;
  color: var(--accent); font: 700 18px/1 var(--latin);
}
.setup-more[open] > summary::after,
.progress-hub[open] > summary::after,
.result-more[open] > summary::after { content: "−"; }
.details-body { padding: 2px 13px 13px; border-top: 1px solid rgba(240,180,41,.14); }
.details-body > .field:first-child,
.details-body > .loop-profile:first-child { margin-top: 12px; }
.progress-hub .loop-card:last-child { margin-bottom: 0; }
.result-actions { display: grid; grid-template-columns: 1.25fr 1fr; gap: 9px; margin-top: 14px; }
.result-actions .go, .result-actions .ghost { margin: 0; min-height: 48px; }
.personal-best.hidden, .friend-result.hidden { display: none; }
.panel .latin {
  font-family: var(--latin); font-size: 12px; font-weight: 600; letter-spacing: 7px;
  color: var(--muted); margin: 6px 0 14px;
}
.lead { margin: 0 0 18px; color: var(--muted); font-size: 13px; line-height: 1.6; }

/* ── 长期成长 / 每日挑战 ─────────────────────────────── */
.loop-profile {
  display: grid;
  grid-template-columns: minmax(120px, auto) minmax(110px, 1fr) auto auto;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  padding: 10px 12px;
  border: 1px solid rgba(240,180,41,.28);
  background: linear-gradient(105deg, rgba(240,180,41,.12), rgba(240,180,41,.025));
}
.loop-rank {
  min-width: 0; padding: 0; text-align: left; cursor: pointer;
  border: 0; background: none; color: var(--ink); font-family: inherit;
}
.loop-rank span { display: block; font-size: 13px; font-weight: 800; }
.loop-rank b { display: block; margin-top: 2px; color: var(--accent); font-family: var(--latin); font-size: 11px; }
.loop-rank:hover span { color: var(--accent-hi); }
.loop-grow { min-width: 0; }
.loop-xp { height: 5px; overflow: hidden; background: rgba(245,234,214,.1); }
.loop-xp i { display: block; width: 0; height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-hi)); transition: width .25s ease; }
.loop-grow small { display: block; margin-top: 4px; color: var(--muted); font-family: var(--latin); font-size: 9px; }
.loop-wallet, .loop-streak { min-width: 46px; text-align: center; }
.loop-wallet b, .loop-streak b { display: block; color: var(--accent-hi); font-family: var(--latin); font-size: 16px; }
.loop-wallet span, .loop-streak span { display: block; color: var(--muted); font-size: 9px; }

.loop-card {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  margin-bottom: 10px; padding: 11px 12px;
  border: 1px solid rgba(240,180,41,.22);
  background: rgba(16,11,7,.72);
}
.loop-card.friend { border-color: rgba(62,224,208,.36); background: rgba(62,224,208,.055); }
.loop-card.league { border-color: rgba(255,93,115,.32); background: rgba(255,93,115,.045); }
.loop-card.hidden, .loop-reward.hidden { display: none; }
.loop-card > div { min-width: 0; }
.loop-kicker { display: block; color: var(--accent); font-family: var(--latin); font-size: 9px; font-weight: 700; letter-spacing: 2px; }
.loop-card b { display: block; margin-top: 3px; color: var(--ink); font-size: 13px; }
.loop-card small { display: block; margin-top: 3px; color: var(--muted); font-size: 10px; line-height: 1.45; }
.loop-action {
  flex: none; padding: 8px 11px; cursor: pointer;
  border: 1px solid var(--line-2); background: rgba(240,180,41,.08);
  color: var(--accent); font-family: inherit; font-size: 11px; font-weight: 800;
}
.loop-action:hover { background: rgba(240,180,41,.18); }
.loop-action:disabled { cursor: default; color: var(--ok); border-color: rgba(86,194,106,.35); background: rgba(86,194,106,.06); }
.league-progress, .league-big {
  height: 5px; margin-top: 7px; overflow: hidden; background: rgba(245,234,214,.1);
}
.league-progress i, .league-big i {
  display: block; width: 0; height: 100%;
  background: linear-gradient(90deg, var(--thief), var(--accent-hi));
  transition: width .25s ease;
}
.league-big { height: 9px; margin: -8px 0 16px; }
.league-me { color: var(--accent-hi); }

.loop-reward {
  margin: 0 0 14px; padding: 11px 13px;
  border-left: 3px solid var(--accent);
  background: rgba(240,180,41,.08);
}
.loop-reward b { display: block; color: var(--accent-hi); font-size: 14px; }
.loop-reward span { display: block; margin-top: 4px; color: var(--muted-2); font-size: 11px; }
.loop-earn { color: var(--muted-2); }
.loop-earn b { color: var(--accent-hi); }
.challenge-share { width: 100%; margin-bottom: 8px; }
.share-note { margin-bottom: 8px; text-align: center; color: var(--ok); }
.share-link {
  width: 100%; margin: 0 0 10px; padding: 9px 11px;
  border: 1px solid var(--line-2); background: var(--edge); color: var(--muted-2);
  font-family: var(--mono); font-size: 10px;
}

.garage-panel { width: min(480px, 92vw); }
.garage-balance { margin-bottom: 12px; color: var(--muted-2); font-size: 12px; }
.garage-balance b { color: var(--accent-hi); font-family: var(--latin); font-size: 22px; }
.garage-list { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.garage-item {
  min-width: 0; padding: 12px; cursor: pointer; text-align: left;
  border: 1px solid rgba(245,234,214,.12); background: rgba(245,234,214,.025);
  color: var(--muted-2); font-family: inherit;
}
.garage-item:hover { border-color: var(--line-2); }
.garage-item.on { border-color: var(--accent); background: rgba(240,180,41,.12); color: var(--ink); }
.garage-item strong { display: block; font-size: 13px; }
.garage-item span { display: block; margin-top: 4px; color: var(--muted); font-size: 10px; }
.garage-note { min-height: 21px; margin: 10px 0 4px; color: var(--accent); text-align: center; }

.field { margin-bottom: 16px; }
.field label {
  display: flex; align-items: center; gap: 9px;
  font-size: 11px; font-weight: 700; letter-spacing: 3px; color: var(--muted);
  margin-bottom: 9px;
}
.field label::before {
  content: ""; width: 8px; height: 8px; background: var(--accent);
  transform: rotate(45deg); flex: none;
}
.choices { display: flex; gap: 8px; flex-wrap: wrap; }

.choice {
  flex: 1; min-width: 0; padding: 12px 14px; text-align: left; cursor: pointer;
  background: rgba(240,180,41,.03);
  color: var(--muted-2);
  border: 1px solid rgba(245,234,214,.12);
  border-radius: 0;
  font-family: inherit; font-size: 14px; font-weight: 700;
  transition: border-color .14s, background .14s, color .14s;
}
.choice:hover { border-color: var(--line-2); color: var(--ink); }
.choice em { display: block; font-style: normal; font-weight: 400; font-size: 11px; color: var(--muted); margin-top: 5px; line-height: 1.5; }
.choice .rl { font-family: var(--latin); font-size: 10px; font-weight: 600; letter-spacing: 3px; color: var(--muted); margin-left: 8px; }
.choice:hover { background: #313846; }
.choice.on {
  background: linear-gradient(150deg, rgba(240,180,41,.2), rgba(240,180,41,.05));
  border-color: var(--accent);
  color: var(--ink);
  box-shadow: 0 0 26px rgba(240,180,41,.14);
}
.choice.on em { color: rgba(240,180,41,.85); }
/* 立场卡按阵营上色：和 HUD、场景里的标记同色 */
.choice.role-thief.on  { border-color: var(--thief);  background: linear-gradient(150deg, rgba(255,93,115,.2), rgba(255,93,115,.04)); box-shadow: 0 0 26px rgba(255,93,115,.14); }
.choice.role-thief.on  em, .choice.role-thief.on .rl { color: rgba(255,93,115,.9); }
.choice.role-police.on { border-color: var(--police); background: linear-gradient(150deg, rgba(62,224,208,.18), rgba(62,224,208,.04)); box-shadow: 0 0 26px rgba(62,224,208,.12); }
.choice.role-police.on em, .choice.role-police.on .rl { color: rgba(62,224,208,.9); }
.choice.on em { color: #d7c391; }

.go {
  display: block; width: 100%; margin-top: 20px; padding: 15px; cursor: pointer;
  background: linear-gradient(100deg, var(--accent), var(--accent-hi));
  color: #1a1005;
  border: 0; border-radius: 0;
  clip-path: polygon(13px 0, 100% 0, calc(100% - 13px) 100%, 0 100%);
  font-family: inherit; font-size: 16px; font-weight: 900; letter-spacing: 5px;
  box-shadow: 0 8px 32px rgba(240,180,41,.3);
  transition: filter .14s;
}
.go:hover { filter: brightness(1.08); }
.go:hover { filter: brightness(1.08); }

.hint { margin: 12px 0 0; font-size: 11px; color: #6d7789; text-align: center; }

.grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 16px; }
.grid > div {
  padding: 13px 10px; text-align: center;
  background: rgba(240,180,41,.04);
  border: 1px solid var(--line);
  border-radius: 0;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%);
}
.grid i { display: block; font-style: normal; font-size: 9px; letter-spacing: 2px; color: var(--muted); }
.grid b { font-family: var(--latin); font-weight: 700; font-size: 26px; color: var(--accent-hi); }

.submit { display: flex; gap: 8px; margin-bottom: 14px; }
.submit input {
  flex: 1; padding: 11px 13px;
  background: var(--edge); color: var(--ink);
  border: 1px solid rgba(245,234,214,.14); border-radius: 0;
  font-family: inherit; font-size: 13px;
}
.submit input:focus { outline: none; border-color: var(--line-2); }
.submit button {
  padding: 9px 14px; background: var(--chrome-2); color: var(--ink);
  border: 1px solid #000; border-radius: 6px; cursor: pointer; font-family: inherit; font-size: 13px;
}

/* 榜单：名次用拉丁数字字体，行间用细分隔线 —— 和设计稿的行式布局一致 */
.board {
  margin: 0 0 18px; padding: 0; list-style: none;
  counter-reset: rank;
  font-size: 13px; color: var(--muted-2);
}
.board li {
  counter-increment: rank;
  display: flex; align-items: center; gap: 12px;
  padding: 9px 12px;
  border: 1px solid rgba(245,234,214,.08);
  border-bottom: 0;
  background: rgba(240,180,41,.02);
}
.board li:last-child { border-bottom: 1px solid rgba(245,234,214,.08); }
.board li::before {
  content: counter(rank);
  font-family: var(--latin); font-weight: 700; font-size: 15px;
  color: var(--muted); width: 18px; flex: none;
}
.board li b { font-family: var(--latin); font-size: 15px; color: var(--accent-hi); }
/* 前三名描金 */
.board li:nth-child(-n+3)::before { color: var(--accent); }
.board b { color: var(--ink); font-family: var(--mono); }

/* ── 底部输入条（对齐原版那道横条） ────────────────────── */
.typebar {
  padding: 16px 22px 14px;
  background: linear-gradient(180deg, rgba(20,13,8,.5), var(--chrome) 34%);
  border-top: 1px solid var(--line-2);
}

.line {
  font-family: var(--mono);
  font-size: clamp(15px, 2.1vw, 21px);
  line-height: 1.55;
  letter-spacing: .4px;
  padding: 10px 14px 9px;
  background: var(--edge);
  border: 1px solid #000;
  border-radius: 6px;
  min-height: 78px;
  white-space: pre-wrap;
  word-break: break-word;
  overflow: hidden;
}
.typing-current, .nextline { display: block; white-space: pre; overflow: hidden; }
.typing-current { scrollbar-width: none; }
.typing-current::-webkit-scrollbar { display: none; }
.line .placeholder { color: #5a6478; font-family: var(--font); font-size: 14px; }
.line .done { color: var(--ok); }
.line .cur {
  display: inline-block;
  background: var(--accent);
  color: #23190a;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(255,209,102,.22);
  animation: cursorPulse 1.15s ease-in-out infinite;
}
.line .cur.err {
  background: var(--bad); color: #fff;
  animation: missPulse .16s ease-out;
}
.line .todo { color: #6f7a8d; }
.line .nextline {
  margin-top: 3px;
  color: rgba(245,234,214,.34);
  font-size: .62em;
  line-height: 1.45;
  letter-spacing: .2px;
}
.line .next-label {
  display: inline-block;
  width: 58px;
  color: rgba(240,180,41,.62);
  font-family: var(--latin);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 2px;
}
.line .nextline.continued .next-label { color: rgba(255,209,102,.86); }
.line .next-cont {
  color: rgba(245,234,214,.72);
  font-weight: 600;
  text-shadow: 0 0 10px rgba(240,180,41,.12);
}
.line .nextline.finish {
  color: rgba(245,234,214,.24);
  font-family: var(--font);
  letter-spacing: 0;
}

@keyframes cursorPulse {
  50% { background: var(--accent-hi); box-shadow: 0 0 0 3px rgba(240,180,41,.12); }
}
@keyframes missPulse {
  0% { transform: translateX(-2px); box-shadow: 0 0 0 3px rgba(255,93,115,.22); }
  45% { transform: translateX(2px); }
  100% { transform: translateX(0); box-shadow: 0 0 0 1px rgba(255,93,115,.12); }
}

@media (prefers-reduced-motion: reduce) {
  .line .cur, .line .cur.err { animation: none; }
}

.progress { margin-top: 8px; height: 6px; background: #0a0c10; border-radius: 3px; overflow: hidden; }
.progress i { display: block; height: 100%; width: 0; background: var(--accent); transition: width .1s linear; }

@media (max-width: 720px) {
  .stats { gap: 4px; }
  .stat { min-width: 52px; padding: 3px 7px; }
  .grid { grid-template-columns: repeat(2, 1fr); }
}

/* ── 追加：素材版专用 ─────────────────────────────────── */
.mute {
  width: 34px; height: 34px; margin-left: 4px;
  background: var(--edge); color: var(--ink);
  border: 1px solid #000; border-radius: 4px;
  cursor: pointer; font-size: 15px; line-height: 1;
}
.mute:hover { background: var(--chrome-2); }

.panel select {
  width: 100%; padding: 9px 11px;
  background: var(--edge); color: var(--ink);
  border: 1px solid #000; border-radius: 6px;
  font-family: inherit; font-size: 13px;
}

/* 结算页使用与重制街区、HQ 角色一致的胜负画面。 */
.verdict {
  display: block; width: 100%; max-height: 190px;
  object-fit: cover; object-position: center 38%;
  border-radius: 6px; border: 1px solid #000;
  margin-bottom: 14px; background: #000;
}
.verdict:not([src]), .verdict[src=""] { display: none; }

/* 载入进度条复用底部那根 */
#loading .progress { margin-top: 14px; }

/* ── 追加：暂停 / 开局提示 ────────────────────────────── */
.panel.narrow { width: min(360px, calc(100% - 40px)); text-align: center; }

.ghost {
  display: block; width: 100%; margin-top: 9px; padding: 11px; cursor: pointer;
  background: rgba(240,180,41,.04); color: var(--muted-2);
  border: 1px solid rgba(245,234,214,.12); border-radius: 0;
  font-family: inherit; font-size: 13px; font-weight: 700;
  transition: border-color .14s, color .14s;
}
.ghost:hover { border-color: var(--line-2); color: var(--ink); }
.ghost:hover { background: var(--chrome-2); color: var(--ink); }

.kickoff {
  position: absolute;
  left: 50%; top: calc(50% + 30px);
  transform: translate(-50%, -50%);
  padding: 10px 22px;
  background: rgba(12,15,20,.8);
  border: 1px solid rgba(255,255,255,.16);
  border-radius: 999px;
  font-size: 15px;
  letter-spacing: 1px;
  pointer-events: none;
  animation: pulse 1.4s ease-in-out infinite;
}
.kickoff.hidden { display: none; }
@keyframes pulse { 50% { opacity: .45; } }

.weak-keys { margin-top: 6px; }
.weak-keys kbd { margin: 0 2px; }
.result-actions .advice { border-color: var(--police); }
kbd {
  padding: 1px 5px;
  background: var(--edge);
  border: 1px solid #000;
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 11px;
}

/* canvas 由 JS 按 DPR 定尺寸，这里只负责居中 */
.stage { position: absolute; inset: 0; display: grid; place-items: center; }
#view { display: block; }

.choices.wrap { flex-wrap: wrap; }
.choices.wrap .choice { flex: 1 1 46%; min-width: 0; }

/* 换档进度。速度分档是核心机制，但 HUD 原来只显示当前档位名，
   玩家看不出离上车还差多少，只能靠反复试 —— 这条细线补上那个信息。 */
.stat.tier { position: relative; }
.tierbar {
  display: block; height: 2px; margin-top: 3px;
  background: rgba(255,255,255,.14); border-radius: 1px; overflow: hidden;
}
.tierbar > span {
  display: block; height: 100%; width: 0;
  background: currentColor; transition: width .08s linear;
}

/* ── 模式互跳 ────────────────────────────────────────
   race.html 一直在用 .modelink 但样式表里没有这条规则，
   所以它此前是浏览器默认的蓝色下划线链接。 */
.modelink {
  display: inline-block; margin-left: 14px; vertical-align: middle;
  padding: 5px 12px;
  font-family: var(--font); font-size: 11px; font-weight: 700; letter-spacing: 2px;
  color: var(--muted-2); text-decoration: none;
  background: rgba(240,180,41,.05);
  border: 1px solid var(--line);
  -webkit-text-fill-color: var(--muted-2);   /* 抵消 .title 的渐变裁切 */
  transition: border-color .14s, color .14s;
}
.modelink:hover {
  border-color: var(--accent); color: var(--accent);
  -webkit-text-fill-color: var(--accent);
}

/* 长得像次级按钮的链接 */
.ghost.as-link { text-align: center; text-decoration: none; }

/* ── 竞速模式的场上组件 ──────────────────────────────
   .rcboard / .rctip 此前在 race.html 里用了但样式表里没有对应规则，
   于是名次板是一块浏览器默认底色的裸 div。 */
.rcboard {
  position: absolute; top: 44px; right: 14px; min-width: 190px;
  display: flex; flex-direction: column; gap: 3px;
  padding: 11px 13px;
  background: rgba(14,9,6,.86);
  border: 1px solid var(--line-2);
  backdrop-filter: blur(5px);
  font-size: 12px; color: var(--muted-2);
}
.rcrow {
  display: flex; align-items: center; gap: 9px;
  padding: 4px 1px; color: var(--muted-2);
}
.rcrow.me { color: var(--accent); font-weight: 700; }
.rcpos {
  width: 15px; text-align: right; flex: none;
  font-family: var(--latin); font-weight: 700; color: var(--muted);
}
.rcrow.me .rcpos { color: var(--accent); }
.rcname { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rclap { font-family: var(--latin); font-variant-numeric: tabular-nums; color: var(--muted); }
.rcrow.me .rclap { color: var(--accent-hi); }

/* #tip 是一行较长的近道提示，.game-countdown 是大号倒计时 —— 两者共用这个类，
   基准按提示条做（小号横幅），倒计时用单独类放大。
   一度按倒计时来定基准，40px 让提示那行宽过屏幕，居中后两头都被裁掉。 */
.rctip {
  position: absolute; left: 50%; top: 44px; transform: translateX(-50%);
  max-width: calc(100% - 28px);
  padding: 8px 16px;
  background: rgba(14,9,6,.88);
  border: 1px solid var(--line);
  backdrop-filter: blur(5px);
  font-size: 12px; line-height: 1.5; color: var(--muted-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rctip b { color: var(--accent-hi); font-weight: 700; }
.game-countdown {
  left: 50%; top: calc(40% + 30px); transform: translate(-50%,-50%);
  padding: 14px 26px; font-size: 34px;
  font-family: var(--latin); font-weight: 700; letter-spacing: 4px;
  color: var(--accent-hi); text-shadow: 0 0 30px rgba(240,180,41,.5);
  border-color: var(--line-2); white-space: normal;
}
.rctip[hidden] { display: none; }

/* ══ 多人对战大厅 ═══════════════════════════════════════
   1:1 照 Claude Design 的 02 画板做。稿子是 1920 宽，这里按
   同比例缩到常见的 1280~1440 视口：栏宽 540→420，留白 64→44。
   列宽比例、字号层级、间距节奏保持不变。 */
.lobby-body {
  margin: 0; height: 100%; overflow: hidden;
  background: linear-gradient(180deg, #221309 0%, #191009 55%, #140d08 100%);
  color: var(--ink); font-family: var(--font);
}
.lb-shell { position: relative; height: 100vh; display: flex; flex-direction: column; }
/* 稿子里那层极淡的横向扫描线，给暗场加质感 */
.lb-scan {
  position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background: repeating-linear-gradient(0deg, rgba(240,180,41,.022) 0 2px, transparent 2px 6px);
}
.lb-shell > * { position: relative; z-index: 1; }

.lb-bar {
  flex: none; height: 72px; display: flex; align-items: center; gap: 18px;
  padding: 0 44px;
  background: rgba(16,11,7,.88);
  border-bottom: 1px solid var(--line);
}
.lb-h1 { font-size: 21px; font-weight: 900; letter-spacing: 4px; }
.lb-h1-en { font-family: var(--latin); font-size: 11px; font-weight: 600; letter-spacing: 4px; color: rgba(245,234,214,.35); }
.lb-back {
  font-size: 11px; font-weight: 600; color: rgba(245,234,214,.6); text-decoration: none;
  border: 1px solid rgba(245,234,214,.2); padding: 6px 12px;
}
.lb-back:hover { color: var(--accent); border-color: var(--line-2); }
.lb-spacer { flex: 1; }

.lb-me {
  display: flex; align-items: center; gap: 11px;
  background: rgba(24,17,12,.9); border: 1px solid rgba(240,180,41,.25);
  padding: 8px 15px;
}
.lb-avatar {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  background: linear-gradient(135deg, var(--accent), #7a4a0c);
  border: 1px solid rgba(240,180,41,.6);
}
.lb-me-name { font-size: 13px; font-weight: 700; }
.lb-me-wpm { font-family: var(--latin); font-size: 10px; font-weight: 500; color: var(--accent); }

.lb-quick {
  cursor: pointer; border: 0; text-align: left;
  padding: 10px 22px;
  background: linear-gradient(100deg, var(--accent), var(--accent-hi));
  color: #1a1005;
  clip-path: polygon(11px 0, 100% 0, calc(100% - 11px) 100%, 0 100%);
  box-shadow: 0 6px 26px rgba(240,180,41,.28);
  font-family: var(--font);
  transition: filter .14s;
}
.lb-quick:hover { filter: brightness(1.08); }
.lb-quick-t { display: block; font-size: 15px; font-weight: 900; letter-spacing: 3px; }
.lb-quick-s { display: block; font-family: var(--latin); font-size: 10px; font-weight: 600; opacity: .7; }

.lb-main {
  flex: 1; min-height: 0;
  display: grid; grid-template-columns: minmax(0, 1fr) 420px; gap: 24px;
  padding: 22px 44px 30px;
}
.lb-left, .lb-right { display: flex; flex-direction: column; gap: 12px; min-height: 0; }

.lb-sec { display: flex; align-items: center; gap: 12px; flex: none; }
.lb-sec-t { font-size: 15px; font-weight: 700; letter-spacing: 3px; }
.lb-sec-n { font-family: var(--latin); font-size: 11px; font-weight: 500; color: rgba(245,234,214,.4); }
/* 玩法选择。两种玩法的房间在列表里混排，建房时必须先选 —— 选错了
   进去的是规则完全不同的一局，不是"设置略有不同"。 */
.lb-mode { display:flex; gap:0; border:1px solid var(--line) }
.lb-mode-b {
  padding:7px 12px; border:0; background:none; cursor:pointer;
  color:rgba(245,234,214,.5); font:600 11px/1 inherit; letter-spacing:1px;
}
.lb-mode-b.on { background:rgba(240,180,41,.14); color:var(--accent) }
.lb-rmode { font-size:11px; color:rgba(245,234,214,.55) }

.lb-create {
  cursor: pointer; padding: 8px 18px;
  border: 1.5px solid var(--accent); background: none; color: var(--accent);
  font-family: var(--font); font-size: 13px; font-weight: 700; letter-spacing: 2px;
  clip-path: polygon(9px 0, 100% 0, calc(100% - 9px) 100%, 0 100%);
  transition: background .14s;
}
.lb-create:hover { background: rgba(240,180,41,.14); }

.lb-table {
  flex: 1; min-height: 0; display: flex; flex-direction: column;
  background: rgba(16,11,7,.9); border: 1px solid rgba(240,180,41,.2);
}
/* 列宽照搬稿子的 52 / 1fr / 260 / 150 / 100 / 110 / 110（等比缩） */
.lb-thead, .lb-row {
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) 56px 190px 108px 70px 78px 82px;
  align-items: center; gap: 10px;
}
.lb-thead {
  flex: none; padding: 11px 18px;
  border-bottom: 1px solid var(--line);
  font-size: 10px; font-weight: 600; letter-spacing: 2px; color: rgba(245,234,214,.45);
}
.lb-tbody { flex: 1; overflow-y: auto; }
.lb-row {
  width: 100%; margin: 0; text-align: left; font: inherit; color: inherit; appearance: none;
  padding: 11px 18px; cursor: pointer;
  background: transparent; border: 0;
  border-bottom: 1px solid rgba(245,234,214,.05);
  transition: background .12s;
}
.lb-row:hover { background: rgba(240,180,41,.06); }
.lb-row.racing, .lb-row:disabled { opacity: .55; cursor: default; }
.lb-row.racing:hover { background: none; }
.lb-lock { text-align: center; color: var(--accent); }
.lb-lock.open { color: rgba(245,234,214,.18); }
.lb-rname { font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-rles { font-size: 12px; color: rgba(245,234,214,.6); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-rwpm { font-family: var(--latin); font-size: 13px; font-weight: 600; color: var(--accent); }
.lb-rcnt { font-family: var(--latin); font-size: 13px; font-weight: 600; color: rgba(245,234,214,.7); }
.lb-st { font-size: 11px; font-weight: 700; text-align: center; padding: 4px 0; border: 1px solid; }
.lb-st.wait { color: var(--police); border-color: rgba(62,224,208,.4); background: rgba(62,224,208,.1); }
.lb-st.race { color: var(--thief); border-color: rgba(255,93,115,.4); background: rgba(255,93,115,.1); }
.lb-st.full { color: var(--muted); border-color: rgba(245,234,214,.14); }
.lb-btn {
  font-size: 11px; font-weight: 700; text-align: center; padding: 6px 0;
  border: 1px solid var(--line-2); color: var(--accent);
}
.lb-row.racing .lb-btn { border-color: rgba(245,234,214,.12); color: var(--muted); }
.lb-empty {
  padding: 40px 16px; text-align: center; font-size: 12px; color: var(--muted);
  display: flex; flex-direction: column; align-items: center; gap: 14px;
}
.lb-empty-action {
  min-height: 42px; padding: 9px 20px; cursor: pointer;
  border: 1px solid var(--line-2); background: rgba(240,180,41,.08);
  color: var(--accent); font: 700 12px/1 var(--font); letter-spacing: 1px;
}
.lb-empty-action:hover { background: rgba(240,180,41,.16); }

.lb-card {
  flex: none;
  background: linear-gradient(180deg, rgba(36,23,12,.96), rgba(20,14,9,.96));
  border: 1px solid var(--line-2);
  box-shadow: 0 20px 50px rgba(0,0,0,.5);
  padding: 20px 22px;
  display: flex; flex-direction: column; gap: 16px;
}
.lb-card-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; }
.lb-code-lab { font-size: 10px; letter-spacing: 3px; color: rgba(245,234,214,.45); }
.lb-code-row { display: flex; align-items: center; gap: 11px; margin-top: 5px; }
.lb-code {
  font-family: var(--latin); font-size: 31px; font-weight: 700; line-height: 1;
  letter-spacing: 8px; color: var(--accent);
  text-shadow: 0 0 26px rgba(240,180,41,.45);
}
.lb-reroll {
  cursor: pointer; padding: 4px 10px; background: none;
  border: 1px solid rgba(240,180,41,.4); color: var(--accent);
  font-family: var(--font); font-size: 10px; font-weight: 600;
}
.lb-reroll:hover { background: rgba(240,180,41,.14); }

.lb-priv {
  display: flex; flex-direction: column; align-items: flex-end; gap: 6px; cursor: pointer; flex: none;
  padding: 0; background: none; border: 0; color: inherit; font: inherit;
}
.lb-priv-lab { font-size: 10px; color: rgba(245,234,214,.45); }
.lb-priv-track {
  width: 42px; height: 21px; border-radius: 999px; position: relative;
  background: rgba(245,234,214,.1); border: 1px solid rgba(245,234,214,.16);
  transition: background .16s, border-color .16s;
}
.lb-priv-knob {
  position: absolute; top: 2px; left: 2px; width: 15px; height: 15px; border-radius: 50%;
  background: rgba(245,234,214,.5); transition: transform .16s, background .16s;
}
.lb-priv.on .lb-priv-track { background: rgba(240,180,41,.28); border-color: var(--accent); }
.lb-priv.on .lb-priv-knob { transform: translateX(21px); background: var(--accent); }
.lb-priv-hint { font-size: 10px; color: var(--muted); }
.lb-priv.on .lb-priv-hint { color: var(--accent); }

.lb-rule { height: 1px; background: linear-gradient(90deg, rgba(240,180,41,.45), transparent); }

.lb-players { display: flex; flex-direction: column; gap: 8px; }
.lb-prow {
  display: flex; align-items: center; gap: 11px;
  padding: 11px 13px;
  background: rgba(245,234,214,.03);
  border: 1px solid rgba(245,234,214,.1);
}
.lb-prow.ready { background: linear-gradient(150deg, rgba(62,224,208,.12), rgba(62,224,208,.03)); border-color: rgba(62,224,208,.42); }
.lb-prow.me { border-color: var(--line-2); }
.lb-pav { width: 26px; height: 26px; border-radius: 50%; flex: none; background: linear-gradient(135deg, var(--accent), #7a4a0c); }
.lb-prow.ready .lb-pav { background: linear-gradient(135deg, var(--police), #16564f); }
.lb-pname { font-size: 13px; font-weight: 600; }
.lb-psub { font-family: var(--latin); font-size: 10px; color: rgba(245,234,214,.45); }
.lb-pready { margin-left: auto; font-size: 11px; font-weight: 700; color: var(--muted); }
.lb-prow.ready .lb-pready { color: var(--police); }
.lb-slot {
  padding: 16px 13px; text-align: center;
  border: 1px dashed rgba(245,234,214,.14);
  font-size: 11px; color: rgba(245,234,214,.35);
}

.lb-start {
  cursor: pointer; padding: 13px; border: 0;
  background: linear-gradient(100deg, var(--accent), var(--accent-hi));
  color: #1a1005;
  clip-path: polygon(11px 0, 100% 0, calc(100% - 11px) 100%, 0 100%);
  font-family: var(--font); font-size: 14px; font-weight: 900; letter-spacing: 4px;
  box-shadow: 0 8px 28px rgba(240,180,41,.3);
  transition: filter .14s;
}
.lb-start:hover:not(:disabled) { filter: brightness(1.08); }
.lb-start:disabled {
  background: rgba(245,234,214,.06); color: var(--muted); cursor: default;
  box-shadow: none; letter-spacing: 2px; font-weight: 700;
}

.lb-tips {
  flex: none; padding: 12px 15px;
  background: rgba(16,11,7,.7); border: 1px solid rgba(240,180,41,.14);
  display: flex; flex-direction: column; gap: 6px;
}
.lb-tip { font-size: 11px; line-height: 1.6; color: rgba(245,234,214,.5); }
.lb-tip b { color: var(--accent); font-weight: 700; }

.lb-join {
  flex: none; display: grid; gap: 8px;
  grid-template-columns: 92px minmax(0, 1fr) auto;
}
.lb-join input {
  min-width: 0; padding: 10px 12px;
  background: var(--edge); color: var(--ink);
  border: 1px solid rgba(245,234,214,.14);
  font-family: var(--font); font-size: 13px;
}
.lb-join #join-code {
  width: 92px; flex: none;
  font-family: var(--latin); font-weight: 700; letter-spacing: 4px; text-transform: uppercase;
}
.lb-join #join-name { flex: 1; }
.lb-join #login-note { grid-column: 1 / -1; margin: 0; }
.lb-join input:focus { outline: none; border-color: var(--line-2); }
.lb-join button {
  grid-column: 1 / -1;
  cursor: pointer; padding: 10px 20px; flex: none;
  background: rgba(240,180,41,.08); color: var(--accent);
  border: 1px solid var(--line-2);
  font-family: var(--font); font-size: 13px; font-weight: 700;
}
.lb-join button:hover { background: rgba(240,180,41,.18); }

/* ── 大厅的窄屏布局 ──────────────────────────────────────
   右栏装着「创建房间」「房间码」「加入」—— 窄屏把它 display:none
   等于让用户进了大厅什么都做不了，而空列表还在提示他去点一个
   被隐藏的按钮。1080px 这个断点很宽，笔记本分屏、平板、横屏手机全中。
   正确做法是折到列表上方：没有房间时"创建/加入"本来就是首要动作。 */
@media (max-width: 1080px) {
  .lb-main {
    grid-template-columns: minmax(0, 1fr);
    grid-auto-rows: min-content;
    overflow-y: auto;
  }
  .lb-right { order: -1; }          /* 折到列表上方，不是隐藏 */
  .lb-left  { min-height: 320px; }
  .lb-tips  { display: none; }      /* 说明文字可以让位，操作入口不行 */
}

/* 六个固定列加起来 566px，700px 视口里表头会被挤成竖排。
   窄屏按重要性逐级丢列：课文和房主水平是参考信息，
   房间名/人数/状态/加入按钮是决策必需的。 */
@media (max-width: 900px) {
  .lb-thead, .lb-row { grid-template-columns: 32px minmax(0, 1fr) 62px 70px 74px; }
  .lb-thead > :nth-child(3), .lb-row > :nth-child(3),   /* 课文 */
  .lb-thead > :nth-child(4), .lb-row > :nth-child(4) {  /* 房主水平 */
    display: none;
  }
  /* 课文并进房间名下方，信息不丢 */
  .lb-rname { display: flex; flex-direction: column; gap: 2px; }
}
@media (max-width: 720px) {
  .lb-bar { height: auto; flex-wrap: wrap; padding: 10px 16px; gap: 10px; }
  .lb-h1 { font-size: 17px; letter-spacing: 2px; }
  .lb-h1-en, .lb-me { display: none; }
  /* 顶栏在 375px 下会堆到 167px（812 屏的 20%）。返回键收成图标、
     快速匹配去掉副标，压到一行半。列表才是这一屏的主体。 */
  .lb-quick { flex: 1; padding: 9px 14px; }
  .lb-quick-t { font-size: 14px; letter-spacing: 2px; }
  .lb-quick-s { display: none; }
  .lb-back { padding: 5px 9px; font-size: 10px; }
  .lb-main { padding: 14px 16px 20px; }
  .lb-code { font-size: 25px; letter-spacing: 5px; }
  .lb-card { padding: 16px; }
  /* 加入区原来仍是一行 flex。登录提示显示后，两个输入框会被挤到
     几个像素宽，手机上既看不见内容也点不中。两格放输入，提示和
     提交按钮各占整行，375px 下仍有可用的触控宽度。 */
  .lb-join {
    grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  }
  .lb-join #join-code { width: auto; }
  .lb-join #login-note,
  .lb-join button { grid-column: 1 / -1; }
  .lb-join #login-note { margin: 0; }
  .lb-thead, .lb-row { grid-template-columns: 26px minmax(0, 1fr) 54px 64px; }
  /* 加入按钮列隐藏 —— 行本身就绑了点击（lobby.js 里 row.addEventListener），
     所以功能不丢。加个箭头提示可点，否则变成"看得见进不去"。 */
  .lb-thead > :nth-child(7), .lb-row > :nth-child(7) { display: none; }
  .lb-row:not(.racing) .lb-rname::after {
    content: "　加入 ›"; color: var(--accent); font-size: 11px; font-weight: 700;
  }
}

/* ══ 页面正文（SEO + 真给人看的说明）════════════════════════
   canvas 游戏对搜索引擎是一片空白，没有可索引文字就排不上。
   但正文必须【真实可见可滚动】—— 用 display:none / 移出视口
   / 零号字这类手法藏关键词是作弊，被判定了会整站掉权重。
   所以：游戏区占满首屏，正文接在下面，向下滚就能读到。 */
.seo {
  max-width: 760px;
  margin: 0 auto;
  padding: 56px 24px 96px;
  color: var(--muted-2);
  font-size: 15px;
  line-height: 1.9;
}
.seo h1 {
  margin: 0 0 20px;
  font-size: 27px; font-weight: 900; letter-spacing: 2px; line-height: 1.4;
  background: linear-gradient(180deg, #fff3cf, var(--accent) 52%, var(--accent-lo));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.seo h2 {
  display: flex; align-items: center; gap: 10px;
  margin: 40px 0 12px;
  font-size: 17px; font-weight: 700; letter-spacing: 2px; color: var(--ink);
}
.seo h2::before {
  content: ""; width: 8px; height: 8px; flex: none;
  background: var(--accent); transform: rotate(45deg);
}
.seo h3 { margin: 22px 0 6px; font-size: 14px; font-weight: 700; color: var(--ink); }
.seo p  { margin: 0 0 14px; }
.seo ul, .seo ol { margin: 0 0 14px; padding-left: 22px; }
.seo li { margin-bottom: 8px; }
.seo strong { color: var(--accent-hi); font-weight: 700; }
.seo a { color: var(--accent); border-bottom: 1px solid rgba(240,180,41,.35); }
.seo a:hover { color: var(--accent-hi); }
.seo kbd {
  padding: 1px 6px; border: 1px solid var(--line-2); border-radius: 2px;
  font-family: var(--mono); font-size: 12px; color: var(--accent);
}

/* ══ 手机端 ═══════════════════════════════════════════════
   国内怀旧流量绝大多数来自手机，搜过来打不开等于 SEO 白做。
   实测 375px 下：顶栏 559px 宽（比容器还宽）、351px 高 ——
   六个状态格换行堆成一坨，吃掉 43% 的屏幕。 */
@media (max-width: 720px) {
  /* 4:3 画布在竖屏上下各留约 175px。桌面用的重压暗参数在手机上会把
     这 350px 变成两块死黑；提高同一张街区图的可读性，让它像舞台延展。
     只动伪背景，不拉伸 canvas，也不改变任何交互坐标。 */
  .screen::before {
    inset: -20px;
    filter: blur(20px) brightness(.62) saturate(1.08);
    transform: scale(1.06);
  }
  .screen::after {
    background:
      radial-gradient(ellipse at center, transparent 28%, rgba(14,9,6,.22) 100%),
      linear-gradient(180deg, rgba(14,9,6,.32), rgba(14,9,6,.08) 30%, rgba(14,9,6,.08) 70%, rgba(14,9,6,.38));
  }
  .bar { flex-wrap: wrap; gap: 8px; padding: 8px 12px; }
  .title { font-size: 16px; letter-spacing: 2px; }
  .title .sub { display: none; }          /* 拉丁副标在窄屏只是占地方 */
  .modelink { margin-left: 8px; padding: 4px 9px; font-size: 10px; letter-spacing: 1px; }

  /* 状态格改成横向可滚的一条，不再换行堆高 */
  .stats {
    width: 100%; flex-wrap: nowrap; overflow-x: auto; gap: 6px;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
  }
  .stats::-webkit-scrollbar { display: none; }
  /* 静音钮在这条可滚的状态条里，不吸边的话要横向拖到底才找得到 ——
     手机上等于没有静音按钮。sticky 让它始终贴在右缘可见。 */
  .mute { position: sticky; right: 0; z-index: 2; }
  .stat { flex: none; min-width: 54px; padding: 4px 8px; }
  .stat b { font-size: 15px; }

  .chase-track { width: 130px; }
  .panel { padding: 20px 18px 18px; }
  .panel h1 { font-size: 30px; letter-spacing: 4px; }
  .loop-profile {
    grid-template-columns: minmax(0, 1fr) minmax(100px, 1fr) auto;
    gap: 8px;
  }
  .loop-streak { display: none; }
  .loop-card { align-items: flex-start; }
  .garage-list { grid-template-columns: 1fr; }
  .choices { flex-wrap: wrap; }
  .choice { min-width: calc(50% - 4px); font-size: 13px; padding: 10px 11px; }
  .typebar { padding: 10px 12px 9px; }
  .line { min-height: 72px; font-size: 15px; }
  .seo { padding: 36px 18px 72px; font-size: 14px; }
  .seo h1 { font-size: 21px; }
}

/* 触屏提示：手机没有物理键盘，不给入口的话游戏就是死的 */
.tapkbd {
  position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%);
  z-index: 6; display: none; align-items: center; gap: 8px;
  padding: 11px 20px;
  background: linear-gradient(100deg, var(--accent), var(--accent-hi));
  color: #1a1005; border: 0;
  clip-path: polygon(10px 0, 100% 0, calc(100% - 10px) 100%, 0 100%);
  font-family: var(--font); font-size: 13px; font-weight: 900; letter-spacing: 2px;
  box-shadow: 0 6px 24px rgba(240,180,41,.34);
}
body.touch .tapkbd { display: inline-flex; }
body.touch.kbd-on .tapkbd { display: none; }
/* 真正接收输入的框：必须留在视口内且有尺寸，否则 iOS 不弹键盘、
   也不会把输入事件发给它。所以是"透明贴在角落"而不是 display:none。 */
#kbd-sink {
  position: absolute; left: 0; bottom: 0; z-index: -1;
  width: 1px; height: 1px; padding: 0; border: 0;
  opacity: 0; background: transparent; color: transparent;
  font-size: 16px;            /* < 16px 会让 iOS 自动放大整个页面 */
}

/* ── 联机追逐面板 ──────────────────────────────────────────────────
   只在带 ?room= 进来时显示。它【取代】单机那套设置而不是并排放：
   身份由服务端分配，也没有可单独配置的电脑对手；难度和课文仍由房间共用。 */
.chase-room { margin:14px 0; padding:14px 16px; border:1px solid rgba(240,180,41,.42); background:rgba(240,180,41,.06); text-align:left }
.chase-room.hidden { display:none }
body.online-chase .online-hidden { display:none }
.cr-head { display:flex; align-items:baseline; gap:10px; margin-bottom:8px }
.cr-tag { font:600 10px/1 ui-monospace,SFMono-Regular,Menlo,monospace; letter-spacing:2px; color:var(--accent) }
.cr-code { font:700 20px/1 ui-monospace,SFMono-Regular,Menlo,monospace; letter-spacing:6px }
.cr-side { margin-bottom:8px; font-size:13px; color:var(--fg) }
.cr-players { margin:0 0 10px; padding:0; list-style:none; font-size:12px; color:rgba(245,234,214,.7) }
.cr-players li { display:flex; justify-content:space-between; padding:3px 0; border-bottom:1px solid rgba(245,234,214,.06) }
.cr-players li b { font-weight:600; color:var(--fg) }
.cr-note { margin:8px 0 0; font-size:11px; color:rgba(245,234,214,.5) }
