/* ==========================================================================
   games.zzxcd.cn · 棋 · 智弈（五子棋 / 中国象棋 / 国际象棋 / 中国跳棋）
   --------------------------------------------------------------------------
   世界：漆木棋枰。
   四种棋共用一个骨架 —— 标题条、两块计时牌、枰、回合提示、三个动作键 ——
   但枰本身各按各的规矩画：五子棋与跳棋是 canvas 的线格与星位，
   中国象棋是九路十行的交叉点（子落在交点上，不是格里），
   国际象棋是八八六十四格（子落在格里）。计时牌做成"号码牌"，
   轮到谁，谁的牌翻成墨底白字 —— 不用闪，一眼就知道该谁走。
   ========================================================================== */

/* ---------- 首页 ---------- */
#app {
  position: relative;
  z-index: 1;
}

.card .card-icon svg,
.card .card-side svg {
  width: 1.7rem;
  height: 1.7rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
}

.card .card-side svg {
  width: 1rem;
  height: 1rem;
  stroke-width: 2.4;
}

/* ---------- 对局：标题条 ---------- */
.nav-bar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding-bottom: 0.6rem;
  border-bottom: var(--rule);
  min-width: 0;
}

.nav-title {
  font-size: calc(1.02rem * var(--font-scale, 1));
  font-weight: 800;
  letter-spacing: 0.04em;
}

/* 四个玩法的共用列 */
.gomoku,
.xq,
.ch,
.ck {
  display: grid;
  justify-items: center;
  gap: 0.6rem;
  width: 100%;
  padding-top: 0.7rem;
  min-width: 0;
}

/* ---------- 回合状态 ---------- */
.status {
  width: 100%;
  padding: 0.42rem 0.7rem;
  border: var(--rule);
  border-left-width: 8px;
  background: var(--sheet);
  font-size: calc(0.86rem * var(--font-scale, 1));
  font-weight: 700;
  text-align: center;
}

.status.win {
  border-left-color: var(--accent-ink);
  background: color-mix(in srgb, var(--accent) 14%, var(--sheet));
}

.status.lose {
  border-left-color: var(--ink);
  background: color-mix(in srgb, var(--ink) 12%, var(--sheet));
}

.status.draw,
.status.thinking {
  border-left-color: var(--accent-2);
}

/* ---------- 计时牌 ---------- */
.clocks {
  display: flex;
  gap: 0.5rem;
  width: 100%;
  min-width: 0;
}

.clock {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.32rem 0.6rem;
  border: var(--rule);
  background: var(--sheet);
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
  min-width: 0;
}

.clock-label {
  font-family: var(--font-mono);
  font-size: calc(0.68rem * var(--font-scale, 1));
  letter-spacing: 0.08em;
  opacity: 0.8;
}

.clock-time {
  font-family: var(--font-mono);
  font-size: calc(1.06rem * var(--font-scale, 1));
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* 轮到谁，谁的牌翻面 */
.clock.active {
  background: var(--ink);
  color: var(--sheet);
  box-shadow: var(--shadow-sm);
}

/* ---------- 枰 ---------- */
.board-wrap {
  width: 100%;
  display: grid;
  place-items: center;
  min-width: 0;
}

.gomoku .board-wrap {
  max-width: min(100%, calc(100vh - 12rem), 560px);
}

.ck .board-wrap {
  max-width: min(100%, calc(100vh - 12rem), 560px);
}

.gomoku .board,
.ck .board {
  width: 100%;
  aspect-ratio: 1;
  border: var(--rule);
  background: var(--sheet);
  box-shadow: var(--shadow);
  touch-action: manipulation;
}

/* 漆木枰：交叉点棋盘，宽高比 9:10 */
.xq .board {
  position: relative;
  width: min(100%, calc(100vh - 12rem), 520px);
  aspect-ratio: 9 / 10;
  border: var(--rule);
  background: var(--sheet);
  box-shadow: var(--shadow);
  touch-action: manipulation;
}

/* 网格要退进枰框里：九路十行的最外两条线是"边线"，
   子落在交点上，边线上的子有一半在枰外 —— inset:0 时边子会越出枰框，
   压到上面的计时牌、下面的回合提示/按钮上（390 下还会把整页顶出 9px 横向滚动）。
   左右 5.55% / 上下 5% 同时让格子回到正方（53.34 × 53.38）。 */
.xq .grid {
  position: absolute;
  inset: 5% 5.55%;
}

/* 横线：10 条，从 0% 到 100% */
.xq .hline {
  position: absolute;
  left: 0;
  width: 100%;
  height: 1px;
  background: color-mix(in srgb, var(--ink) 62%, transparent);
}

/* 竖线：被河界截断，所以由 JS 给 top/height */
.xq .vline {
  position: absolute;
  width: 1px;
  background: color-mix(in srgb, var(--ink) 62%, transparent);
}

/* 「楚河 汉界」写在河界那一条空档里。字距不能拉太开：
   letter-spacing 会把每个字后面垫出一段空白，48px 的枰上就会顶到边卒的圈里。 */
.xq .river {
  position: absolute;
  left: 0;
  top: 44.4445%;
  width: 100%;
  height: 11.111%;
  display: flex;
  align-items: center;
  justify-content: space-around;
  font-size: clamp(calc(0.6rem * var(--font-scale, 1)), 2.2vw, calc(0.8rem * var(--font-scale, 1)));
  letter-spacing: 0.16em;
  text-indent: 0.16em;
  color: color-mix(in srgb, var(--ink) 52%, transparent);
}

/* 九宫斜线：从宫的一角拉到对角，两条交叉成「米」字。
   用两个对角方向的 linear-gradient 画 1px 斜线（角关键字保证正好落在宫角上）。 */
.xq .palace {
  position: absolute;
  border: 1px solid color-mix(in srgb, var(--ink) 30%, transparent);
  background:
    linear-gradient(to top right,
      transparent calc(50% - 0.5px),
      color-mix(in srgb, var(--ink) 30%, transparent) calc(50% - 0.5px),
      color-mix(in srgb, var(--ink) 30%, transparent) calc(50% + 0.5px),
      transparent calc(50% + 0.5px)),
    linear-gradient(to bottom right,
      transparent calc(50% - 0.5px),
      color-mix(in srgb, var(--ink) 30%, transparent) calc(50% - 0.5px),
      color-mix(in srgb, var(--ink) 30%, transparent) calc(50% + 0.5px),
      transparent calc(50% + 0.5px));
  pointer-events: none;
}

/* 交叉点上的落子：圆心必须在交点上 */
.xq .piece {
  position: absolute;
  width: 9.2%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  border: var(--rule);
  border-radius: 50%;
  background: var(--sheet);
  box-shadow: var(--shadow-sm);
  font-size: clamp(calc(0.6rem * var(--font-scale, 1)), 2.6vw, calc(0.9rem * var(--font-scale, 1)));
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  /* 两个图层都铺满整个枰，若让它们接管命中测试，
     上面的 dot-layer 会把每一次点击都吃掉 → 棋子永远选不中。
     图层放行、只有子和点自己接收点击。 */
  pointer-events: auto;
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.xq .piece.red {
  color: var(--accent-ink);
  border-color: var(--accent-ink);
}

.xq .piece.black {
  color: var(--ink);
}

.xq .piece.sel {
  box-shadow: var(--shadow-sm), 0 0 0 3px var(--accent);
  z-index: 3;
}

.xq .piece.from {
  opacity: 0.55;
}

.xq .piece.last {
  border-width: 3px;
}

/* 可落点：空点是实心圆点，吃子是可吃的圈 */
.xq .dot-layer,
.xq .piece-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.xq .piece-layer {
  z-index: 2;
}

.xq .dot-layer {
  z-index: 3;
}

.xq .dot {
  position: absolute;
  width: 2.6%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: var(--accent);
  border-radius: 50%;
  pointer-events: auto;
}

.xq .dot.cap {
  width: 8.4%;
  background: none;
  border: 3px solid var(--accent);
}

/* 最后一手：起点空心、落点实心 */
.xq .last-mark {
  position: absolute;
  width: 8.4%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border: 2px solid var(--accent-2);
  border-radius: 50%;
}

.xq .last-mark.to {
  border-style: solid;
  border-color: var(--accent-ink);
}

/* 国际象棋：64 格 */
.ch .board {
  width: min(100%, calc(100vh - 12rem), 580px);
  aspect-ratio: 1;
  display: grid;
  grid-template-rows: repeat(8, 1fr);
  border: var(--rule);
  background: var(--sheet);
  box-shadow: var(--shadow);
  touch-action: manipulation;
  transition: transform var(--dur-slow) var(--ease-out);
}

.ch .board.flipped {
  transform: rotate(180deg);
}

.ch .rank {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
}

.ch .sq {
  position: relative;
  display: grid;
  place-items: center;
}

.ch .sq.light {
  background: color-mix(in srgb, var(--ink) 7%, var(--sheet));
}

.ch .sq.dark {
  background: color-mix(in srgb, var(--ink) 32%, var(--sheet));
}

/* 棋子跟着枰一起转，字形才不会倒过来 */
.ch .board.flipped .pc {
  transform: rotate(180deg);
}

.ch .pc {
  font-size: clamp(calc(1.1rem * var(--font-scale, 1)), 5.4vw, calc(2rem * var(--font-scale, 1)));
  line-height: 1;
  user-select: none;
}

.ch .pc.w {
  color: var(--sheet);
  text-shadow: 0 0 1px var(--ink), 1px 0 0 var(--ink), -1px 0 0 var(--ink), 0 1px 0 var(--ink),
    0 -1px 0 var(--ink);
}

.ch .pc.b {
  color: var(--ink);
  text-shadow: 0 0 1px var(--sheet);
}

.ch .sq.sel {
  box-shadow: inset 0 0 0 3px var(--accent);
}

.ch .sq.last {
  box-shadow: inset 0 0 0 3px color-mix(in srgb, var(--accent-2) 80%, transparent);
}

.ch .sq.chk {
  background: var(--accent);
}

.ch .sq.chk .pc {
  color: var(--on-accent);
  text-shadow: none;
}

.ch .mdot {
  position: absolute;
  width: 26%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 78%, transparent);
}

.ch .mring {
  position: absolute;
  width: 84%;
  aspect-ratio: 1;
  border: 3px solid var(--accent);
  border-radius: 50%;
}

/* 升变选择 */
.promo-mask {
  position: fixed;
  inset: 0;
  z-index: 140;
  display: grid;
  place-items: center;
  padding: 1rem;
  background: var(--scrim);
  min-width: 0;
}

.promo-card {
  padding: 1.1rem 1.2rem 1.2rem;
  border: var(--rule);
  background: var(--sheet);
  box-shadow: var(--shadow-lg);
  text-align: center;
}

.promo-title {
  font-size: calc(0.92rem * var(--font-scale, 1));
  font-weight: 700;
}

.promo-opts {
  display: flex;
  gap: 0.45rem;
  margin-top: 0.8rem;
  min-width: 0;
}

.promo-btn {
  width: 3rem;
  height: 3rem;
  display: grid;
  place-items: center;
  border: var(--rule);
  background: var(--sheet);
  font-size: calc(1.6rem * var(--font-scale, 1));
  line-height: 1;
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
  min-width: 0;
}

.promo-btn:hover {
  background: var(--accent);
  color: var(--on-accent);
}

.promo-btn:active {
  transform: translate(3px, 3px);
  box-shadow: 0 0 0 var(--ink);
}

/* ---------- 吃子 / 手数 / 记谱 ---------- */
/* ⚠️ .hidden 只写 display:none 会被窄屏断点里的 display:flex 压回去
   （同优先级、后来者胜），于是"这一步还没吃子/还没记谱"时页面上会多出一条
   空横条 —— 实测五子棋、象棋、华容道、国象都顶出来了。这里让隐藏态一律优先。 */
.captured-row.hidden,
.move-record.hidden {
  display: none;
}

/* 内容为空时整行不占位。
   五子棋与象棋的「第 N 手」是装在一个 .captured-row 里的（那是给"吃子"设计的容器），
   只改 .movenum 不够 —— 容器自己是 width:100%，于是页面上横着一条通栏的窄框，
   里面只有小小的三个字（用户报「那条还是那么宽」就是这个）。
   容器上没有钩子可加，就用 :empty —— 空容器直接收起来，有内容时才出现。 */
.captured-row:empty,
.move-record:empty {
  display: none;
}

/* 手数 / 吃子这一类"薄信息行"收成内容宽度并**居中对齐**。
   ⚠️ 不能写 margin-left:auto ——那在 grid 子项上是"贴到内容列最右边"，
   实测这条标签会从棋盘下方一路飘到页面右缘（用户报「你这都跑哪里去了」）。
   居中的短标签落在棋盘正下方：棋盘是这一区最宽的元素，居中即对齐（实测偏差 0px）。
   ⚠️ 这里**只能**用 width:fit-content，不能顺手加 display:flex ——
   `display` 会让 :empty 失效（空文本节点也算内容），空横条会立刻回来。 */
#gk-moveinfo,
#ck-moveinfo {
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
  /* 只装手数（没有吃子列表）时不套独立的框：无框的轻量读数，紧贴棋盘下沿 */
  padding: 0;
  border: 0;
  background: none;
}

#gk-moveinfo .movenum,
#ck-moveinfo .movenum {
  padding: 0;
  border: 0;
  background: none;
}

/* 象棋那条是「吃子 + 手数」合用一行，保留框与底，同样收成内容宽度居中 */
#xq-captured,
#ck-captured {
  width: fit-content;
  max-width: 100%;
  margin-inline: auto;
  padding: 0.2rem 0.5rem;
}

/* 记谱行（炮二平五 马8进7…）该和**棋盘同宽**，不是通栏。
   ⚠️ 上一轮只改了吃子行，把 `#xq-moverec` / `#ck-moverec` 漏了 ——
   实测 736px = 内容列宽的 100%（用户报「其他的棋都没变」就是这个）。
   与棋盘同宽：文字超过一行就换行，不用横向滚动，居中的短行也不显得空。 */
.xq .move-record {
  max-width: min(100%, calc(100vh - 12rem), 520px);
  margin-inline: auto;
  max-height: 5.5rem;
}

.ch .move-record {
  max-width: min(100%, calc(100vh - 12rem), 580px);
  margin-inline: auto;
  max-height: 5.5rem;
}

.xq .move-record {
  max-width: min(100%, calc(100vh - 12rem), 520px);
}

.ch .move-record {
  max-width: min(100%, calc(100vh - 12rem), 580px);
}

.captured-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  width: 100%;
  padding: 0.3rem 0.6rem;
  border: var(--rule);
  background: color-mix(in srgb, var(--ink) 6%, var(--sheet));
  font-size: calc(1.05rem * var(--font-scale, 1));
  line-height: 1.2;
  max-height: 8.5rem;
  overflow-y: auto;
  min-width: 0;
}

.captured-label {
  font-family: var(--font-mono);
  font-size: calc(0.64rem * var(--font-scale, 1));
  letter-spacing: 0.1em;
  color: var(--ink-soft);
}

.captured-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.1rem;
  min-width: 0;
}

.cap-you {
  font-size: calc(0.72rem * var(--font-scale, 1));
  color: var(--accent-ink);
}

.cap-ai {
  font-size: calc(0.72rem * var(--font-scale, 1));
  color: var(--ink-soft);
}

.movenum {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: calc(0.7rem * var(--font-scale, 1));
  color: var(--ink-soft);
}

.move-record {
  width: 100%;
  max-height: 6.5rem;
  overflow-y: auto;
  border: var(--rule-thin);
  padding: 0.3rem 0.55rem;
  font-family: var(--font-mono);
  font-size: calc(0.7rem * var(--font-scale, 1));
  line-height: 1.75;
  color: var(--ink-soft);
}

/* ---------- 回合提示 + 动作 ---------- */
.turn-hint {
  min-height: 1.2em;
  font-family: var(--font-mono);
  font-size: calc(0.74rem * var(--font-scale, 1));
  color: var(--ink-soft);
  text-align: center;
}

.controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  width: 100%;
  max-width: 34rem;
  min-width: 0;
}

.btn {
  flex: 1 1 0;
  min-width: 0;
  padding: 0.5rem 0.5rem;
  border: var(--rule);
  background: var(--sheet);
  box-shadow: var(--shadow-sm);
  font-size: calc(0.84rem * var(--font-scale, 1));
  font-weight: 700;
  white-space: nowrap;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
    background-color var(--dur) var(--ease);
}

.btn:disabled {
  opacity: 0.4;
  pointer-events: none;
}

.btn:active {
  transform: translate(3px, 3px);
  box-shadow: 0 0 0 var(--ink);
}

.btn.primary {
  background: var(--accent);
  color: var(--on-accent);
}

.btn.danger {
  background: var(--ink);
  color: var(--sheet);
}

.btn.ghost {
  background: var(--sheet);
}

/* ---------- 对局设置 ---------- */
.setup-mask {
  position: fixed;
  inset: 0;
  z-index: 85;
  display: grid;
  place-items: center;
  padding: 1rem;
  background: var(--scrim);
  overflow-y: auto;
  min-width: 0;
}

.setup-card {
  width: min(100%, 460px);
  max-height: 92vh;
  overflow-y: auto;
  padding: 1.2rem 1.15rem 1.3rem;
  border: var(--rule);
  background: var(--sheet);
  box-shadow: var(--shadow-lg);
}

.setup-title {
  font-size: calc(1.18rem * var(--font-scale, 1));
  font-weight: 800;
  text-align: center;
  padding-bottom: 0.55rem;
  border-bottom: var(--rule);
}

.setup-sub {
  margin: 0.85rem 0 0.45rem;
  font-family: var(--font-mono);
  font-size: calc(0.66rem * var(--font-scale, 1));
  letter-spacing: 0.12em;
  color: var(--ink-soft);
}

.setup-options {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.45rem;
  min-width: 0;
}

.setup-options.difficulty {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.setup-options .opt {
  padding: 0.5rem 0.6rem;
  border: var(--rule);
  background: var(--sheet);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}

.setup-options .opt-name {
  font-size: calc(0.88rem * var(--font-scale, 1));
  font-weight: 700;
}

.setup-options .opt-desc {
  font-family: var(--font-mono);
  font-size: calc(0.66rem * var(--font-scale, 1));
  color: var(--ink-soft);
  line-height: 1.4;
}

.setup-options .opt.on {
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: var(--shadow-sm);
}

.setup-options .opt.on .opt-desc {
  color: color-mix(in srgb, var(--on-accent) 84%, var(--accent));
}

.setup-start {
  width: 100%;
  margin-top: 1.1rem;
  flex: none;
}

/* ---------- 结算 ---------- */
.result-mask {
  position: fixed;
  inset: 0;
  z-index: 86;
  display: grid;
  place-items: center;
  padding: 1rem;
  background: var(--scrim);
  min-width: 0;
}

.result-card {
  width: min(100%, 380px);
  padding: 1.3rem 1.2rem 1.2rem;
  border: var(--rule);
  background: var(--sheet);
  box-shadow: var(--shadow-lg);
  text-align: center;
}

.result-card.win {
  border-top-width: 8px;
  border-top-color: var(--accent-ink);
}

.result-card.lose {
  border-top-width: 8px;
  border-top-color: var(--ink);
}

.result-emoji {
  font-size: calc(2.1rem * var(--font-scale, 1));
  line-height: 1;
}

.result-title {
  margin-top: 0.3rem;
  font-size: calc(1.35rem * var(--font-scale, 1));
  font-weight: 800;
}

.result-text {
  margin-top: 0.4rem;
  font-family: var(--font-mono);
  font-size: calc(0.78rem * var(--font-scale, 1));
  line-height: 1.7;
  color: var(--ink-soft);
}

.result-btns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.55rem;
  margin-top: 1.1rem;
  min-width: 0;
}

.result-btns .btn {
  padding: 0.52rem 0.6rem;
}

/* ---------- 断点 ---------- */
@media (max-width: 620px) {
  .captured-row,
  .move-record {
    display: none;
  }

  .captured-row.hidden,
  .move-record.hidden {
    display: none;
  }

  .xq .board {
    width: 100%;
    max-width: 420px;
  }

  .ch .board {
    width: 100%;
    max-width: 420px;
  }
}
