:root {
  --bg: #0a0d12;
  --panel: rgba(19, 25, 34, 0.92);
  --line: rgba(216, 180, 106, 0.18);
  --line-strong: rgba(216, 180, 106, 0.38);
  --gold: #d8b46a;
  --gold-2: #f0d59b;
  --ink: #e9e4d8;
  --muted: #95a0ae;
  --red: #e66060;
  --blue: #63b3ed;
  --red-deep: #a82020;
  --blue-deep: #174a7c;

  --cell-size: clamp(16px, 4.2vw, 44px);
  --board-cols: 17;
  --board-rows: 11;
  --board-width: calc(var(--board-cols) * var(--cell-size));
  /* 棋盘外的行列标签、间隙和边框都随格子大小缩放，保证棋盘始终按比例占满可用空间。 */
  --label-w: clamp(15px, calc(var(--cell-size) * 0.55), 24px);
  --label-row: clamp(14px, calc(var(--cell-size) * 0.5), 22px);
  /* 棋盘与棋盘容器贴合：边框内外都不留额外间隙。 */
  --frame-pad: 0px;
  --frame-gap: 0px;
  --frame-extra: calc(var(--label-w) + var(--frame-gap) + var(--frame-pad) * 2 + 2px);
  --frame-width: calc(var(--board-width) + var(--frame-extra));
  --frame-height: calc(var(--board-rows) * var(--cell-size) + var(--label-row) + var(--frame-gap) + var(--frame-pad) * 2 + 2px);
  --rotate-deg: 0deg;
  --rotate-w: var(--frame-width);
  --rotate-h: var(--frame-height);
  --status-width: calc(var(--rotate-w) - 8px);

  /* 统一字号/控件：小 16px / 24px，中 24px / 32px，大 32px / 40px。 */
  --ui-scale: 1;
  --font-base: 16px;
  --font-sm: 16px;
  --font-xs: 16px;
  --font-2xs: 16px;
  --font-md: 24px;
  --font-lg: 32px;
  --control-h: 32px;
  --control-h-sm: 24px;
  --control-sm: 24px;
  --control-md: 32px;
  --control-lg: 40px;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --panel-pad: 0px;
  --ui-2xs: 16px;
  --ui-xs: 16px;
  --ui-sm: 16px;
  --ui-md: 24px;
  --ui-lg: 32px;
  --ui-gap: var(--space-2);
  --ui-pad: var(--space-3);
  /* 状态栏开头几个字（等待开始 / 匹配中 / 红方胜 / 和棋 …）统一字号。 */
  --status-lead-size: 24px;

  /* 随机配色会覆盖这些变量；这里只是兜底值 */
  --enh-color: #d4ff3f;
  --move-dot: #f0d59b;
  --capture-ring: #ff5a5a;
  --swap-ring: #c084fc;
  --merge-ring: #5eead4;

  --cell-normal: #302116;
  --cell-palace: #40301b;
  --last-from: #ff9f1c;

  --piece-blue-normal: #d6e4f2;
  --piece-blue-enhanced: #f1f8ff;
  --piece-red-normal: #f0dcc9;
  --piece-red-enhanced: #fff2e6;

  --board-a: #2b1c12;
  --board-b: #1a100a;
  --shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  --serif: "Microsoft YaHei", "PingFang SC", "Noto Sans SC", system-ui, sans-serif;
  --sans: "Microsoft YaHei", "PingFang SC", "Noto Sans SC", system-ui, sans-serif;
  --mono: "Microsoft YaHei", "PingFang SC", "Noto Sans SC", system-ui, sans-serif;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--font-base);
  background:
    radial-gradient(1100px 700px at 15% -10%, rgba(70, 94, 130, 0.22), transparent 60%),
    radial-gradient(900px 600px at 100% 10%, rgba(120, 70, 40, 0.16), transparent 55%),
    linear-gradient(180deg, #0b1017 0%, #080a0e 100%);
  min-height: 100vh;
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* ---------------------------------------------------------------- 顶部 */

.topbar {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: none;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  gap: 12px;
  flex: 0 0 auto;
}

/* 左上角：萌图标 / 标题 / 版本号 / 连接状态，四个元素靠顶靠左排成一行。 */
.brand {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 8px;
  min-width: 0;
  margin: 0;
  padding: 0;
}
.brand-mark {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  flex: 0 0 36px;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background:
    radial-gradient(circle at 35% 25%, rgba(255, 255, 255, 0.35), transparent 55%),
    linear-gradient(150deg, rgba(216, 180, 106, 0.28), rgba(20, 16, 12, 0.9));
  color: var(--gold-2);
  font-family: var(--serif);
  font-size: 16px;
  font-weight: 700;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
}
.brand h1 {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(17px, 1.6vw, 22px);
  letter-spacing: 0.1em;
  line-height: 1.1;
}
.brand h1 .latin {
  margin-left: 8px;
  font-family: var(--mono);
  font-size: 16px;
  letter-spacing: 0.3em;
  color: var(--gold);
  vertical-align: middle;
}
.brand p {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 16px;
  letter-spacing: 0.08em;
}
.brand .app-version {
  display: inline-block;
  margin-top: 0;
  padding: 0 4px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 999px;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 16px;
  letter-spacing: 0.06em;
}

.engine-badge {
  display: inline-flex;
  align-items: center;
  height: 20px;
  margin-top: 0;
  padding: 0 7px;
  border: 1px solid rgba(104, 211, 145, 0.45);
  border-radius: 999px;
  background: rgba(104, 211, 145, 0.1);
  color: #8be3ad;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.engine-badge[hidden] { display: none; }

.conn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 96px;
  height: 18px;
  padding: 0 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--muted);
  font-size: 16px;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
}
.conn i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 8px currentColor;
}
.conn.ok { color: #68d391; border-color: rgba(104, 211, 145, 0.4); }
.conn.warn { color: var(--gold-2); }
.conn.down { color: #ff8a8a; border-color: rgba(255, 138, 138, 0.35); }

/* ---------------------------------------------------------------- 舞台 */

.stage {
  position: relative;
  z-index: 2;
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
  padding: 0 12px 8px;
  display: flex;
  align-items: stretch;
  overflow: hidden;
}

.board-panel {
  flex: 1 1 auto;
  width: 100%;
  max-width: none;
  min-height: 0;
  border: 1px solid var(--line);
  border-radius: 16px;
  background:
    linear-gradient(180deg, rgba(28, 24, 19, 0.72), rgba(10, 13, 18, 0.9)),
    var(--panel);
  box-shadow: var(--shadow);
  padding: var(--panel-pad);
  display: flex;
  flex-direction: row;
  align-items: stretch;
  justify-content: flex-start;
  gap: var(--space-2);
}
/* 棋盘在左，操作按钮在右：右侧竖排固定 9 行，每行一个控件。
   棋盘与按钮列作为一个整体居中；旋转时棋盘变窄，按钮列仍紧贴棋盘右边。 */
.board-main {
  flex: 0 0 auto;
  width: var(--rotate-w);
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.game-rail {
  flex: 0 0 104px;
  width: 104px;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.game-rail .game-bar {
  width: 100%;
  padding: 0;
  flex: 0 0 auto;
}
.game-rail .bar-right {
  flex-direction: column;
  flex-wrap: nowrap;
  align-items: stretch;
  justify-content: flex-start;
  gap: 4px;
  width: 100%;
}
.game-rail .bar-right > * { width: 100%; }

.game-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  padding: 4px 4px 0;
  min-height: 0;
  flex: 0 0 auto;
  flex-wrap: wrap;
}
.turn-dot {
  flex: 0 0 8px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--red);
  box-shadow: 0 0 0 4px rgba(230, 96, 96, 0.12), 0 0 16px rgba(230, 96, 96, 0.5);
  transition: 0.2s;
}
.turn-dot.blue { background: var(--blue); box-shadow: 0 0 0 4px rgba(99, 179, 237, 0.12), 0 0 16px rgba(99, 179, 237, 0.5); }
.turn-dot.idle { background: var(--muted); box-shadow: 0 0 0 4px rgba(149, 160, 174, 0.1); }
.turn-name {
  flex: 0 0 76px;
  width: 76px;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 16px;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.turn-sub {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--muted);
  font-size: 16px;
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bar-right {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  flex-wrap: wrap;
}
.bar-right > * { flex: 0 0 auto; }
.room-code {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  column-gap: 0;
  width: 78px;
  height: var(--control-h);
  box-sizing: border-box;
  padding: 0 4px;
  border: 1px solid rgba(149, 160, 174, 0.24);
  border-radius: 999px;
  background: rgba(149, 160, 174, 0.06);
  color: var(--muted);
  font-size: 16px;
  white-space: nowrap;
}
.room-code > span { margin: 0; padding: 0; }
.room-code-input {
  width: auto;
  min-width: 0;
  margin: 0;
  height: var(--control-h);
  box-sizing: border-box;
  border: 0;
  background: transparent;
  color: var(--gold-2);
  font-family: var(--mono);
  font-size: 16px;
  letter-spacing: 0;
  text-align: left;
  padding: 0;
}
.room-code-input::placeholder {
  color: rgba(149, 160, 174, 0.55);
  letter-spacing: 0;
}
.room-code-input:focus { outline: none; }
.room-code-input:read-only { cursor: default; }
.invite {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: var(--control-h);
  box-sizing: border-box;
  border: 1px solid rgba(99, 179, 237, 0.3);
  border-radius: 999px;
  background: rgba(99, 179, 237, 0.07);
  color: #bfe3ff;
  font-family: var(--sans);
  font-size: 16px;
  padding: 0;
  text-align: center;
  cursor: pointer;
}
.invite:hover { background: rgba(99, 179, 237, 0.16); }
.score {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 62px;
  height: var(--control-h);
  box-sizing: border-box;
  padding: 0 4px;
  border: 1px solid rgba(216, 180, 106, 0.3);
  border-radius: 999px;
  background: rgba(216, 180, 106, 0.07);
  color: var(--gold-2);
  font-size: 16px;
  letter-spacing: 0;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.score[hidden] { display: none; }
.score b {
  font-family: var(--mono);
  font-size: 16px;
  color: #fff3cf;
  margin-left: 0;
}
.rank {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: var(--control-h);
  box-sizing: border-box;
  padding: 0 4px;
  border: 1px solid rgba(99, 179, 237, 0.3);
  border-radius: 999px;
  background: rgba(99, 179, 237, 0.07);
  color: #bfe3ff;
  font-size: 16px;
  letter-spacing: 0;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rank b {
  font-family: var(--mono);
  font-size: 16px;
  color: #e7f6ff;
  margin-left: 0;
}
.rule-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  width: 68px;
  height: var(--control-h);
  box-sizing: border-box;
  padding: 0 4px;
  border: 1px solid rgba(104, 211, 145, 0.3);
  border-radius: 999px;
  background: rgba(104, 211, 145, 0.06);
  color: #b7f0ce;
  font-size: 16px;
  white-space: nowrap;
}
.rule-number input {
  width: auto;
  min-width: 0;
  height: var(--control-h);
  box-sizing: border-box;
  border: 0;
  background: transparent;
  color: #d9ffe9;
  font-family: var(--mono);
  font-size: 16px;
  text-align: left;
  padding: 0;
}
.rule-number input::placeholder { color: rgba(183, 240, 206, 0.55); letter-spacing: 0; }
.rule-number input:focus { outline: none; }
.rule-number input:disabled { opacity: 0.55; cursor: default; }
.start {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: var(--control-h);
  box-sizing: border-box;
  border: 1px solid rgba(216, 180, 106, 0.42);
  border-radius: 999px;
  background: rgba(216, 180, 106, 0.1);
  color: var(--gold-2);
  font-family: var(--sans);
  font-size: 16px;
  letter-spacing: 0.04em;
  padding: 0;
  text-align: center;
  cursor: pointer;
  transition: 0.15s ease;
}
.start:hover:not(:disabled) {
  background: rgba(216, 180, 106, 0.2);
  border-color: rgba(216, 180, 106, 0.68);
}
.start:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.role {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 66px;
  height: var(--control-h);
  box-sizing: border-box;
  padding: 0 4px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--gold-2);
  font-size: 16px;
  letter-spacing: 0.02em;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pass {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: var(--control-h);
  box-sizing: border-box;
  border: 1px solid rgba(94, 234, 212, 0.4);
  border-radius: 999px;
  background: rgba(94, 234, 212, 0.08);
  color: #9ff5e5;
  font-family: var(--mono);
  font-size: 16px;
  letter-spacing: 0.04em;
  padding: 0;
  text-align: center;
  cursor: pointer;
  transition: 0.15s ease;
}
.pass:hover:not(:disabled) { background: rgba(94, 234, 212, 0.18); }
.pass:disabled { opacity: 0.35; cursor: not-allowed; }

/* ---------------------------------------------------------------- 棋盘 */

.board-frame {
  display: grid;
  width: var(--frame-width);
  max-width: 100%;
  grid-template-columns: var(--label-w) calc(var(--board-cols) * var(--cell-size));
  grid-template-rows: var(--label-row) calc(var(--board-rows) * var(--cell-size));
  gap: var(--frame-gap);
  padding: var(--frame-pad);
  border-radius: 16px;
  background: linear-gradient(180deg, rgba(32, 22, 14, 0.75), rgba(12, 9, 7, 0.9));
  border: 1px solid rgba(216, 180, 106, 0.24);
  box-shadow: inset 0 0 60px rgba(0, 0, 0, 0.45);
  min-width: 0;
  box-sizing: border-box;
}

/* 双指缩放：外层裁切，内层只做 transform，不改变棋盘占用的布局高度。 */
.board-zoom {
  position: relative;
  flex: 0 0 auto;
  height: var(--rotate-h);
  min-height: 0;
  width: 100%;
  max-width: none;
  margin: 0 auto;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow: hidden;
  border-radius: 16px;
  touch-action: pan-y;
}
/* 旋转 90°/270° 时宽高互换；整块棋盘（含棋子文字和坐标标记）一起转。 */
:root[data-board-rotation="1"],
:root[data-board-rotation="3"] {
  --rotate-w: var(--frame-height);
  --rotate-h: var(--frame-width);
}
.board-rotate-frame {
  position: relative;
  width: var(--rotate-w);
  height: var(--rotate-h);
  margin: 0 auto;
}
.board-zoom-layer {
  transform-origin: 0 0;
  will-change: transform;
}
.board-zoom .board-frame {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--frame-width);
  max-width: none;
  margin: 0;
  transform: translate(-50%, -50%) rotate(var(--rotate-deg));
  transform-origin: center center;
}
.board-rotate {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 50px;
  height: var(--control-h);
  box-sizing: border-box;
  border: 1px solid rgba(216, 180, 106, 0.32);
  border-radius: 999px;
  background: rgba(216, 180, 106, 0.07);
  color: var(--gold-2);
  font-family: var(--sans);
  font-size: 16px;
  letter-spacing: 0;
  padding: 0;
  text-align: center;
  cursor: pointer;
  transition: 0.15s ease;
  white-space: nowrap;
}
.board-rotate:hover { background: rgba(216, 180, 106, 0.16); border-color: rgba(216, 180, 106, 0.55); }
.board-rotate:active { transform: translateY(1px); }
.board-zoom-reset {
  position: absolute;
  top: 7px;
  right: 7px;
  z-index: 30;
  appearance: none;
  border: 1px solid rgba(216, 180, 106, 0.55);
  border-radius: 999px;
  padding: 4px 8px;
  background: rgba(10, 13, 18, 0.86);
  color: var(--gold-2);
  font-family: var(--mono);
  font-size: 16px;
  letter-spacing: 0.04em;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.42);
  touch-action: manipulation;
}
.board-zoom-reset[hidden] { display: none; }
.board-zoom-reset:active { transform: translateY(1px); }

.corner { grid-column: 1; grid-row: 1; }
.file-labels {
  grid-column: 2;
  grid-row: 1;
  display: grid;
  grid-template-columns: repeat(var(--board-cols), var(--cell-size));
  align-items: center;
  width: calc(var(--board-cols) * var(--cell-size));
  overflow: hidden;
  color: rgba(216, 180, 106, 0.55);
  font-family: var(--mono);
  font-size: clamp(7px, calc(var(--cell-size) * 0.26), 10px);
  text-align: center;
  letter-spacing: 0.05em;
}
.rank-labels {
  grid-column: 1;
  grid-row: 2;
  display: grid;
  grid-template-rows: repeat(var(--board-rows), var(--cell-size));
  align-items: center;
  height: calc(var(--board-rows) * var(--cell-size));
  overflow: hidden;
  color: rgba(216, 180, 106, 0.55);
  font-family: var(--mono);
  font-size: clamp(7px, calc(var(--cell-size) * 0.26), 10px);
  text-align: center;
}
.board-wrap {
  grid-column: 2;
  grid-row: 2;
  position: relative;
  width: calc(var(--board-cols) * var(--cell-size));
  height: calc(var(--board-rows) * var(--cell-size));
  min-width: 0;
}
.board {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(var(--board-cols), var(--cell-size));
  grid-template-rows: repeat(var(--board-rows), var(--cell-size));
  border: 1px solid rgba(216, 180, 106, 0.45);
  border-radius: 6px;
  overflow: hidden;
  background:
    radial-gradient(ellipse at 50% 48%, rgba(118, 72, 35, 0.18), transparent 62%),
    linear-gradient(135deg, var(--board-a), var(--board-b) 55%, #22150d);
  box-shadow:
    inset 0 0 0 4px rgba(0, 0, 0, 0.25),
    inset 0 0 80px rgba(0, 0, 0, 0.5),
    0 24px 60px rgba(0, 0, 0, 0.35);
  /* 长按棋子不选中文字、不弹系统菜单。 */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

.cell {
  position: relative;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  border: 0;
  border-right: 1px solid rgba(232, 198, 132, 0.2);
  border-bottom: 1px solid rgba(232, 198, 132, 0.2);
  background-color: var(--cell-normal);
  background-image: linear-gradient(160deg, rgba(255, 255, 255, 0.026), rgba(0, 0, 0, 0.09));
  padding: 0;
  margin: 0;
  cursor: pointer;
  display: grid;
  place-items: center;
  color: inherit;
  -webkit-tap-highlight-color: transparent;
  isolation: isolate;
  transition: filter 0.15s ease;
}
.cell.edge-right { border-right: 0; }
.cell.edge-bottom { border-bottom: 0; }
.cell.inactive { visibility: hidden; pointer-events: none; }
.cell:hover { filter: brightness(1.1); }
.cell:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; z-index: 5; }

.cell.palace {
  background-color: var(--cell-palace);
  box-shadow: inset 0 0 0 1px rgba(232, 198, 132, 0.16);
}
.cell.river-mid { background-color: var(--cell-palace); }

.cell.red.has-piece {
  --piece-fill: var(--piece-red-normal);
  --piece-fill-hi: var(--piece-red-enhanced);
}
.cell.blue.has-piece {
  --piece-fill: var(--piece-blue-normal);
  --piece-fill-hi: var(--piece-blue-enhanced);
}

.cell.has-piece::before {
  content: "";
  position: absolute;
  inset: 7%;
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 24%, rgba(255, 255, 255, 0.62), rgba(255, 255, 255, 0) 58%),
    radial-gradient(circle at 50% 52%, var(--piece-fill) 0%, var(--piece-fill) 62%, rgba(0, 0, 0, 0.16) 100%);
  box-shadow:
    0 3px 6px rgba(0, 0, 0, 0.55),
    inset 0 0 0 2px rgba(63, 42, 18, 0.38),
    inset 0 0 0 4px rgba(255, 255, 255, 0.4),
    inset 0 -5px 8px rgba(0, 0, 0, 0.16);
  z-index: 1;
  transition: transform 0.14s ease, box-shadow 0.14s ease;
}
.cell.has-piece:hover::before {
  transform: translateY(-1px);
  box-shadow:
    0 5px 10px rgba(0, 0, 0, 0.6),
    inset 0 0 0 2px rgba(63, 42, 18, 0.52),
    inset 0 0 0 4px rgba(255, 255, 255, 0.5),
    inset 0 -5px 8px rgba(0, 0, 0, 0.16);
}

.cell .glyph {
  position: relative;
  z-index: 2;
  font-family: var(--serif);
  font-size: calc(var(--cell-size) * 0.54);
  font-weight: 700;
  line-height: 1;
  transform: translateY(-1px);
  pointer-events: none;
  user-select: none;
}
.cell.red .glyph { color: var(--red-deep); text-shadow: 0 1px 0 rgba(255, 225, 200, 0.55); }
.cell.blue .glyph { color: var(--blue-deep); text-shadow: 0 1px 0 rgba(220, 240, 255, 0.5); }

.cell .star {
  position: absolute;
  top: 2%;
  right: 3%;
  z-index: 4;
  width: clamp(8px, calc(var(--cell-size) * 0.34), 17px);
  height: clamp(8px, calc(var(--cell-size) * 0.34), 17px);
  display: none;
  place-items: center;
  border-radius: 50%;
  background: var(--enh-color);
  color: #11140a;
  font-family: var(--sans);
  font-size: clamp(5px, calc(var(--cell-size) * 0.2), 10px);
  font-weight: 900;
  line-height: 1;
  border: 1px solid rgba(0, 0, 0, 0.65);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.25), 0 0 10px var(--enh-color);
  text-shadow: none;
}
.cell.enhanced .star { display: grid; }
.cell.enhanced::before {
  background:
    radial-gradient(circle at 34% 24%, rgba(255, 255, 255, 0.78), rgba(255, 255, 255, 0) 60%),
    radial-gradient(circle at 50% 52%, var(--piece-fill-hi) 0%, var(--piece-fill-hi) 62%, rgba(0, 0, 0, 0.14) 100%);
  box-shadow:
    0 0 0 3px var(--enh-color),
    0 0 20px var(--enh-color),
    0 3px 7px rgba(0, 0, 0, 0.55),
    inset 0 0 0 2px rgba(63, 42, 18, 0.32),
    inset 0 0 0 4px rgba(255, 255, 255, 0.55);
}

.cell .transform-mark {
  position: absolute;
  left: 5%;
  bottom: 4%;
  z-index: 4;
  display: none;
  font-size: clamp(5px, calc(var(--cell-size) * 0.2), 11px);
  font-weight: 800;
  color: #1b1207;
  background: linear-gradient(180deg, #f4d99d, #cda65a);
  border-radius: 50%;
  width: 1.55em;
  height: 1.55em;
  place-items: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
}
.cell.transform-available .transform-mark { display: grid; }

.cell .stack-mark {
  position: absolute;
  right: 4%;
  bottom: 3%;
  z-index: 5;
  display: none;
  min-width: 1.55em;
  height: 1.55em;
  padding: 0 0.18em;
  place-items: center;
  border-radius: 999px;
  background: linear-gradient(180deg, #ffeab0, #d3a84e);
  color: #201306;
  font-family: var(--mono);
  font-size: clamp(5px, calc(var(--cell-size) * 0.2), 11px);
  font-weight: 900;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  border: 1px solid rgba(0, 0, 0, 0.65);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.55), inset 0 0 0 1px rgba(255, 255, 255, 0.35);
}
.cell.stacked .stack-mark { display: grid; }
.cell.stacked.stack-wide .stack-mark { font-size: clamp(4px, calc(var(--cell-size) * 0.17), 9px); padding: 0 0.28em; }
.cell.stacked.stack-xwide .stack-mark { font-size: clamp(3px, calc(var(--cell-size) * 0.14), 8px); padding: 0 0.3em; }

.cell .hidden-mark {
  position: absolute;
  left: 4%;
  top: 3%;
  z-index: 5;
  display: none;
  min-width: 1.55em;
  height: 1.55em;
  padding: 0 0.18em;
  place-items: center;
  border-radius: 999px;
  background: rgba(15, 23, 42, 0.92);
  color: #b8c7d9;
  font-family: var(--mono);
  font-size: clamp(4px, calc(var(--cell-size) * 0.17), 9px);
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  border: 1px solid rgba(184, 199, 217, 0.45);
  box-shadow: 0 0 8px rgba(148, 163, 184, 0.35);
}
.cell.has-hidden .hidden-mark { display: grid; }
.cell.has-hidden.hidden-wide .hidden-mark { font-size: clamp(3px, calc(var(--cell-size) * 0.15), 8px); padding: 0 0.26em; }
.cell.has-hidden.hidden-xwide .hidden-mark { font-size: clamp(3px, calc(var(--cell-size) * 0.13), 7px); padding: 0 0.3em; }

.cell.selected {
  box-shadow: inset 0 0 0 3px var(--gold), inset 0 0 22px rgba(216, 180, 106, 0.22);
  z-index: 4;
}
.cell.last-from:not(.selected),
.cell.last-to:not(.selected) {
  box-shadow:
    inset 0 0 0 999px var(--last-from),
    inset 0 0 0 2px rgba(255, 255, 255, 0.35);
}

.cell.legal-empty::after {
  content: "";
  position: absolute;
  width: 15%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--move-dot);
  opacity: 0.9;
  z-index: 3;
  box-shadow: 0 0 10px var(--move-dot);
  pointer-events: none;
}
.cell.legal-capture::after,
.cell.legal-swap::after,
.cell.legal-merge::after {
  content: "";
  position: absolute;
  inset: 8%;
  border-radius: 50%;
  border: max(1px, calc(var(--cell-size) * 0.06)) solid var(--capture-ring);
  z-index: 3;
  pointer-events: none;
  box-shadow: 0 0 14px var(--capture-ring);
}
.cell.legal-swap::after { border-color: var(--swap-ring); box-shadow: 0 0 14px var(--swap-ring); }
.cell.legal-merge::after { border-color: var(--merge-ring); box-shadow: 0 0 14px var(--merge-ring); }

/* ---------------------------------------------------------------- 底部状态 / 结算行 */

.board-status,
.result-line {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  max-width: 100%;
  height: 26px;
  min-height: 26px;
  box-sizing: border-box;
  margin: 0 auto;
  padding: 0 4px;
  border-top: 1px solid rgba(216, 180, 106, 0.18);
  white-space: nowrap;
  overflow: hidden;
  flex: 0 0 auto;
}
.board-status[hidden],
.result-line[hidden] { display: none; }
.board-status.overtime .turn-name { color: #ffcf9a; }
.board-status.overtime .turn-sub {
  color: #ffb27a;
  font-weight: 600;
  letter-spacing: 0.05em;
}
.result-line {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  justify-content: flex-start;
  gap: 4px;
  height: 32px;
  min-height: 32px;
  padding: 0 8px;
}
.result-summary,
.result-next {
  width: auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.result-summary {
  color: var(--ink);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: 0.02em;
  flex: 0 0 auto;
}
.result-separator {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 16px;
}
.result-next {
  flex: 1 1 auto;
  color: var(--muted);
  font-size: 16px;
  letter-spacing: 0.01em;
}

/* ---------------------------------------------------------------- 提示 */

.notice {
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  margin: 4px auto 0;
  padding: 4px 8px;
  border: 1px solid var(--line-strong);
  border-left: 3px solid var(--gold);
  border-radius: 8px;
  background: linear-gradient(90deg, rgba(216, 180, 106, 0.12), rgba(10, 13, 18, 0.88));
  color: var(--ink);
  font-size: 16px;
  letter-spacing: 0.02em;
  animation: notice-in 0.2s ease;
  flex: 0 0 auto;
}
.notice[hidden] { display: none; }
@keyframes notice-in { from { opacity: 0; transform: translateY(-4px); } }

/* ---------------------------------------------------------------- 窄屏 / 动态缩放 */

@media (max-width: 760px) {
  :root {
    /* JS 会按当前布局的列数/行数写入精确像素值；这里只是脚本加载前的兜底。 */
    --cell-size: clamp(16px, 4.6vw, 40px);
    --label-w: clamp(11px, calc(var(--cell-size) * 0.45), 18px);
    --label-row: clamp(11px, calc(var(--cell-size) * 0.4), 16px);
    --frame-pad: 0px;
    --frame-gap: 0px;
    --ui-scale: 0.95;
  }

  .stage { padding: 0 0 16px; }
  .topbar {
    width: 100%;
    padding: 0;
    gap: 8px;
  }
  .brand { gap: 6px; min-width: 0; }
  .brand-mark { width: 30px; height: 30px; flex-basis: 30px; font-size: 16px; }
  .brand h1 {
    font-size: calc(17px * var(--ui-scale));
    letter-spacing: 0.04em;
    white-space: nowrap;
  }
  .brand h1 .latin { display: none; }
  .brand .app-version { margin-top: 0; padding: 0 4px; font-size: var(--ui-2xs); }
  .conn { min-width: 0; padding: 4px 8px; gap: 4px; font-size: var(--ui-xs); }
  .conn i { width: 7px; height: 7px; }

  .board-panel { padding: 0; border-radius: 12px; }
  .game-bar {
    width: var(--rotate-w);
    padding: 4px 0 0;
    gap: var(--space-1);
    min-height: 0;
    justify-content: center;
  }
  .bar-right { justify-content: center; gap: var(--space-1); flex-wrap: wrap; width: 100%; }
  .room-code { width: calc(96px * var(--ui-scale)); gap: 0; padding: 0 4px; font-size: var(--ui-xs); }
  .room-code-input { width: calc(52px * var(--ui-scale)); font-size: var(--ui-xs); }
  .invite { width: calc(42px * var(--ui-scale)); padding: 0; font-size: var(--ui-xs); }
  .rule-number { width: calc(80px * var(--ui-scale)); padding: 0 4px; font-size: var(--ui-2xs); }
  .rule-number input { width: calc(44px * var(--ui-scale)); font-size: var(--ui-xs); }
  .score { width: calc(72px * var(--ui-scale)); padding: 0 4px; font-size: var(--ui-xs); }
  .score b { font-size: var(--ui-sm); }
  .rank { width: calc(70px * var(--ui-scale)); padding: 0 4px; font-size: var(--ui-2xs); }
  .rank b { font-size: var(--ui-xs); }
  .board-rotate { width: calc(62px * var(--ui-scale)); padding: 0; font-size: var(--ui-2xs); }
  .role { width: calc(66px * var(--ui-scale)); padding: 0 4px; font-size: var(--ui-xs); }
  .start { width: calc(52px * var(--ui-scale)); padding: 0; font-size: var(--ui-xs); }
  .board-frame { border-radius: 12px; }

  /* 棋盘下方状态/结算文字：允许换行，不再单行截掉一半。 */
  .board-status {
    width: var(--rotate-w);
    height: auto;
    min-height: 34px;
    margin-top: 0;
    padding: 4px 4px 0;
    gap: 4px;
    flex-wrap: wrap;
    align-items: flex-start;
    white-space: normal;
  }
  .turn-dot { flex: 0 0 9px; width: 9px; height: 9px; margin-top: 4px; }
  .turn-name { flex: 0 0 auto; width: auto; font-size: calc(14px * var(--ui-scale)); line-height: 1.2; }
  .turn-sub {
    flex: 1 1 120px;
    white-space: normal;
    overflow: visible;
    font-size: var(--ui-xs);
    line-height: 1.4;
  }
  .result-line {
    width: var(--rotate-w);
    height: auto;
    min-height: 40px;
    margin-top: 0;
    white-space: normal;
  }
  .result-summary, .result-next { white-space: normal; overflow: visible; }
  .result-summary { font-size: var(--ui-xs); }
  .result-next { font-size: var(--ui-2xs); }
  .notice {
    width: var(--rotate-w);
    margin-top: 8px;
    padding: 8px 8px;
    max-height: 30vh;
    overflow: auto;
    font-size: var(--ui-xs);
    line-height: 1.45;
  }
}


/* ---------------------------------------------------------------- 手机 / 矮屏：恢复纵向滚动 */
@media (max-width: 760px), (max-height: 560px) {
  html, body { height: auto; min-height: 100vh; overflow: auto; }
  body { display: block; height: auto; }
  .topbar { width: 100%; padding: 0; }
  .stage {
    display: block;
    flex: none;
    min-height: 0;
    padding: 0 4px 8px;
    overflow: visible;
  }
  .board-panel {
    display: block;
    height: auto;
    min-height: 0;
    padding: 0;
    border-radius: 12px;
  }
  /* 手机/矮屏：右侧竖排按钮改为棋盘下方竖排，仍是 9 行、每行一个控件。 */
  .board-main { width: 100%; flex: 1 1 auto; }
  .game-rail { width: 100%; max-width: 280px; margin: 4px auto 0; }
  .game-bar { justify-content: center; width: 100%; padding: 4px 0 0; }
  .bar-right { justify-content: center; width: 100%; gap: 4px; }
  .board-zoom {
    display: block;
    flex: none;
    width: var(--rotate-w);
    max-width: 100%;
    height: auto;
    margin: 0 auto;
  }
  .board-status, .result-line {
    width: 100%;
    height: auto;
    min-height: 26px;
    margin-top: 0;
  }
  .notice { width: 100%; }
  .room-code { width: 84px; padding: 0 4px; }
  .room-code-input { width: 46px; }
  .invite { width: 34px; }
  .rule-number { width: 70px; padding: 0 4px; }
  .rule-number input { width: 40px; }
  .score { width: 56px; padding: 0 4px; }
  .rank { width: 64px; padding: 0 4px; }
  .board-rotate { width: 44px; }
  .role { width: 58px; padding: 0 4px; }
  .pass { width: 40px; }
  .start { width: 40px; }
}

/* ---------------------------------------------------------------- 统一字号与控件 */
.brand h1 { font-size: 32px; }
.brand-mark { width: 48px; height: 48px; flex-basis: 48px; font-size: 24px; }
.brand p, .brand .app-version { font-size: 16px; }
.topbar { gap: 16px; }

/* 面板内边距统一 0：棋盘与容器贴合 */
.board-panel { padding: 0; }

/* 按钮自适应宽度：不再写死宽高 */
.room-code,
.invite,
.rule-number,
.score,
.rank,
.role,
.pass,
.board-rotate,
.start {
  width: auto;
  min-width: 0;
}
.room-code,
.rule-number,
.score,
.rank,
.role,
.conn {
  height: 32px;
  min-height: 32px;
  padding: 0 8px;
}
.room-code-input,
.rule-number input {
  width: auto;
  height: 24px;
  min-width: 0;
  font-size: 16px;
  field-sizing: content;
}
.invite,
.board-rotate,
.pass,
.start {
  height: 32px;
  min-height: 32px;
  padding: 0 12px;
  font-size: 16px;
}
.start { padding: 0 16px; }
.board-zoom-reset {
  height: 24px;
  min-height: 24px;
  padding: 0 8px;
  font-size: 16px;
}
.conn { font-size: 16px; }

.turn-name { font-size: 24px; flex: 0 0 auto; width: auto; }
.turn-sub { font-size: 16px; }
.turn-dot { width: 12px; height: 12px; flex-basis: 12px; }
.board-status,
.result-line {
  width: 100%;
  height: auto;
  min-height: 40px;
  padding: 4px 8px;
}
/* 状态行紧贴棋盘：单行高度，不再留两行空白。 */
.board-status {
  height: 32px;
  min-height: 32px;
  padding: 0 8px;
}
/* 棋盘和状态行贴合，不再保留额外间距。 */
.board-main > .board-status,
.board-main > .result-line {
  margin-top: 0;
}
.result-summary,
.result-next,
.notice {
  font-size: 16px;
}
.notice { padding: 8px 8px; }

.game-bar { padding: 4px 0 0; gap: 8px; }
.bar-right { gap: 8px; }

@media (max-width: 760px) {
  .room-code,
  .rule-number,
  .score,
  .rank,
  .role,
  .conn { height: 32px; padding: 0 8px; }
  .room-code-input,
  .rule-number input { height: 24px; font-size: 16px; }
  .invite,
  .board-rotate,
  .pass { height: 32px; padding: 0 8px; font-size: 16px; }
  .start { height: 32px; padding: 0 12px; font-size: 16px; }
  .board-panel { padding: 0; }
}

/* 标题与版本号同一行 */
.brand-title-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.brand .app-version {
  margin-top: 0;
  height: 24px;
  display: inline-flex;
  align-items: center;
  padding: 0 8px;
}

/* 每局 seed（日期+时间，精确到秒） */
.seed-line {
  margin-left: 8px;
  color: var(--muted, #9aa4b2);
  font-family: var(--mono, monospace);
  font-size: 10px;
  opacity: 0.85;
  white-space: nowrap;
}

/* 棋盘底部状态栏 / 结算行：永远单行，不换行、不撑高。 */
.board-status {
  flex-wrap: nowrap;
  white-space: nowrap;
  overflow: hidden;
}
.board-status .turn-sub {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.board-main > .result-line {
  height: 32px;
  min-height: 32px;
  padding: 0 8px;
  flex-direction: row;
  flex-wrap: nowrap;
  white-space: nowrap;
  overflow: hidden;
}
/* “等待开始/匹配中/红方胜/和棋”等状态栏开头文字统一字号。 */
#turn-name,
#result-summary { font-size: var(--status-lead-size); }
.result-line .result-separator,
.result-line .result-next { font-size: 16px; }
@media (max-width: 760px) {
  .brand { gap: 6px; }
  .brand-mark { width: 30px; height: 30px; flex-basis: 30px; font-size: 16px; }
  .brand h1 {
    font-size: calc(17px * var(--ui-scale));
    letter-spacing: 0.04em;
    white-space: nowrap;
  }
  .brand .app-version { height: 22px; padding: 0 4px; font-size: 12px; }
  .conn {
    flex: 0 0 auto;
    height: 24px;
    min-height: 24px;
    padding: 0 6px;
    font-size: 12px;
  }
}
