/* ==========================================================================
   games.zzxcd.cn · 单人纸牌
   --------------------------------------------------------------------------
   世界：绿绒牌桌 + 扑克牌本体。
   桌面是一块纯色绒面（用墨色混出来的深底，不用渐变），牌是真牌：
   白面、墨边、左上右下的角标、中间按点数铺花色。牌背是强调色底上的斜格密纹。
   牌的位置全部由 JS 算出并写 transform，所以这里只管牌的尺寸、牌面与状态色。
   ========================================================================== */

/* ---------- 牌尺寸令牌 ----------
   ⚠️ 必须声明在 :root，不能声明在 .table 上。
   脚本 layout() 量的是**列宽**（#columns > .column 的 getBoundingClientRect().width），
   再把量到的值写回 documentElement 的 --cw / --ch（inline style）。
   若 .table 自己再声明一次 --cw，就会**遮蔽** :root 上的值 —— 这张牌桌里所有
   后代（.pcard / .col-empty / .table 的 min-height）都拿不到脚本实测的尺寸，
   桌面 1280 下实测：列宽 140.5px 而牌只有 94.7px（clamp 的上限 96px），
   牌比列窄三分之一、脚本按 140.5 算的废牌扇形与桌面高度全部对不上。
   这里给的是脚本跑之前的兜底值（首帧 var() 无效会让槽位塌陷）。 */
:root {
  --cw: clamp(46px, 7.4vw, 96px);
  --ch: calc(var(--cw) * 1.4);
}

/* ---------- 对局容器 ---------- */
#gameView {
  display: grid;
  justify-items: center;
  gap: 0.7rem;
}

.status-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  min-width: 0;
}

.stat-box {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  min-width: 4.4rem;
  padding: 0.24rem 0.55rem 0.32rem;
  border: var(--rule);
  background: var(--sheet);
}

/* ---------- 工具条 ---------- */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  width: 100%;
  min-width: 0;
}

.tbtn {
  flex: 1 1 6rem;
  min-height: 2.2rem;
  padding: 0.35rem 0.5rem;
  border: var(--rule);
  background: var(--sheet);
  font-size: calc(0.8rem * var(--font-scale, 1));
  transition: background-color var(--dur) var(--ease), transform var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
}

.tbtn:hover {
  background: color-mix(in srgb, var(--accent) 12%, var(--sheet));
}

.tbtn:active {
  transform: translate(2px, 2px);
}

/* 四个动作各自留一点点区别：撤销最中性、提示偏辅色、自动完成与重新发牌更重 */
.tb-undo {
  background: var(--sheet);
}

.tb-hint {
  background: color-mix(in srgb, var(--accent-2) 18%, var(--sheet));
}

.tb-auto {
  background: color-mix(in srgb, var(--accent) 18%, var(--sheet));
}

.tb-new {
  background: var(--ink);
  color: var(--sheet);
}

/* ---------- 牌桌 ---------- */
/* 绒面用主题令牌 --c-table-bg（四套主题都给的是深绿径向渐变）。
   用 color-mix(ink, paper) 混出来是**灰色**：默认主题量到 #9d9ea0，
   暗色主题的 --ink 是浅色（#e0e0e0）、混出来反而比页面底色更亮 —— 绿绒牌桌
   这个身份在四套主题里全都不成立，牌面白底贴在灰底上也没有对比。 */
.table {
  position: relative;
  width: 100%;
  min-height: calc(var(--ch) * 3.6);
  padding: 0.85rem;
  isolation: isolate;
  border: var(--rule);
  background: var(--c-table-bg, color-mix(in srgb, var(--ink) 42%, var(--paper)));
  box-shadow: var(--shadow);
}

/* ⚠️ 不要在这里再声明 --cw：脚本会把实测值写到 :root 的 --cw 上，
   牌桌自己声明一次就会**遮蔽**它 —— 实测牌宽比列宽小三成、发牌堆和列对不上。 */

/* 顶排七列：发牌堆(1) · 废牌区(2-3) · 四个收牌位(4-7)。
   ⚠️ 不能用 auto 排布：markup 里只有 5 个子元素，auto 会把它们挤到前五列，
   收牌位就跑到发牌堆下面去了（实测就是这样）。所以逐个写死列位。
   ⚠️⚠️ .table-top / .columns 都**不能**写 position:relative ——
   脚本的 slotPos() 用的是 el.offsetLeft/offsetTop，参考系是 offsetParent 的
   padding 边缘。这两个容器一旦成为 offsetParent，脚本拿到的就不是「相对 .table」
   的坐标了（实测：发牌堆/收牌位的牌整体偏 (-13.6,-13.6)，七列的 28 张牌偏
   (-13.6,-224.6)，整叠牌画到了顶排上面、盖住发牌堆与四个 A 槽）。
   它们也不再需要 z-index：卡片层是定位元素（z-index:5），天然压在流内内容之上。 */
.table-top {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  align-items: start;
  min-width: 0;
}

.drawpile {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1.4;
  display: grid;
  place-items: center;
  border: var(--rule);
  background: color-mix(in srgb, var(--on-accent) 22%, transparent);
  color: color-mix(in srgb, var(--on-accent) 72%, transparent);
  cursor: pointer;
  min-width: 0;
}

.drawpile .slot-label {
  font-size: calc(1.4rem * var(--font-scale, 1));
  line-height: 1;
}

.drawpile-count {
  position: absolute;
  right: 0.25rem;
  bottom: 0.15rem;
  font-family: var(--font-mono);
  font-size: calc(0.66rem * var(--font-scale, 1));
  font-weight: 700;
}

/* 这个空档只是 markup 里的占位，列位已经写死，不需要它占格子 */
.top-spacer {
  display: none;
}

.foundation {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1.4;
  display: grid;
  place-items: center;
  border: 2px dashed color-mix(in srgb, var(--on-accent) 45%, transparent);
  color: color-mix(in srgb, var(--on-accent) 60%, transparent);
  font-family: var(--font-mono);
  font-size: calc(1.1rem * var(--font-scale, 1));
  min-width: 0;
}

/* 用 id 写死列位，不用 :nth-of-type —— 后者数的是"同标签兄弟的序号"，
   而 .top-spacer 也是 div，序号会被它带偏（实测 found0 落到了第 5 列）。
   收牌位占 4-7 列、废牌区占 2-3 列：脚本 layout() 里废牌扇形的右边界就是
   f0.offsetLeft，3 张牌（1.08 牌宽起、每张错开 0.42 牌宽）需要 2.92 牌宽，
   放在 2-3 列刚好放下；写成 3-6 列时预算只剩 1 牌宽，第三张废牌会压到 A 槽上。 */
#drawpile {
  grid-column: 1;
}

#found0 {
  grid-column: 4;
}

#found1 {
  grid-column: 5;
}

#found2 {
  grid-column: 6;
}

#found3 {
  grid-column: 7;
}

/* Spider 没有收牌位，发牌堆独占顶排；十列也必须在同一行里（脚本发 10 列牌，
   7 列网格会把后 3 列折到第二行，桌面实测第二行落到 y=704、牌桌高 1143px）。 */
.table-top.spider {
  grid-template-columns: repeat(10, minmax(0, 1fr));
}

.table-top.spider #found0,
.table-top.spider #found1,
.table-top.spider #found2,
.table-top.spider #found3 {
  display: none;
}

/* 列：JS 逐列写 minHeight，这里只给定位基准（同样不能 position:relative） */
.columns {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  align-items: start;
  margin-top: 0.9rem;
  min-width: 0;
}

/* 蜘蛛是十列（.spider 类由脚本挂在 .table-top 上，与 #columns 是兄弟节点） */
.table-top.spider ~ .columns {
  grid-template-columns: repeat(10, minmax(0, 1fr));
}

/* 空列的虚线槽位：脚本会给空列加 .empty（render 里 toggle），只有空列才画它。
   常显的话，虚线框的**上边与左边**会在每叠牌的顶边/左边露出 0.4px 的发丝线
   （脚本的 offsetLeft 取整：列在 15.6px、牌落在 16px，牌盖不住槽位的 2px 虚线），
   截图放大后是一条条脏虚线、1:1 下也能看出牌顶有一道毛边。 */
.col-empty {
  display: none;
  border: 2px dashed color-mix(in srgb, var(--on-accent) 40%, transparent);
  height: var(--ch);
}

.column.empty .col-empty {
  display: block;
}

/* 收牌动画的容器：牌绝对定位在这里。
   ⚠️ 必须铺满整个 .table 的 padding box（inset:0）：脚本 slotPos() 拿到的
   offsetLeft/offsetTop 就是「相对 .table 的 padding 边缘」，两者必须同一个原点；
   卡片层再内缩 0.85rem 就会整体偏 13.6px（实测发牌堆里 24 张牌全部画到左上角）。 */
.cards-layer {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}

/* ---------- 牌 ---------- */
.pcard {
  position: absolute;
  width: var(--cw);
  height: var(--ch);
  perspective: 700px;
  will-change: transform;
  transition: transform 180ms var(--ease-out);
  pointer-events: auto;
  touch-action: none;
}

.pcard.no-anim {
  transition: none;
}

/* 拖拽幽灵：脚本 buildGhost() 建的是一个 class="drag-ghost" 的**容器**（不是牌），
   里面克隆若干 .pcard，并给容器写 inline left/top（视口坐标）——所以容器必须
   position:fixed。原来这里写成 `.pcard.drag-ghost`：容器身上永远没有 .pcard，
   这条规则一次都没命中过（幽灵既没有定位、也没有 pointer-events:none），
   于是拖拽时原牌被 visibility:hidden 藏起来、幽灵却按静态块流排到 body 末尾，
   手指下面空空如也。 */
.drag-ghost {
  position: fixed;
  z-index: 3000;
  pointer-events: none;
}

.drag-ghost .pcard {
  position: absolute;
  left: 0;
  top: 0;
}

.drag-ghost .pcard .face {
  box-shadow: 4px 4px 0 rgb(0 0 0 / 28%);
}

.pcard-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 200ms var(--ease-out);
}

.pcard.down .pcard-inner {
  transform: rotateY(180deg);
}

.face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  border: var(--rule);
  border-radius: 2px;
  overflow: hidden;
}

/* 牌面 */
.face.front {
  background: #fbf8f2;
  color: #1b1b1b;
}

/* 牌背：纸色外框 + 墨色内框 + 框内斜纹（真实纸牌的背面就是这个结构）。
   ⚠️ 不能整张铺满斜纹 —— 级联时背面牌只露出 ~25px 高的一条，
   满铺的话那一条就是"一块红绒布"，看不出是张牌（用户圈出来指出的问题）。
   留出外框后，露出的窄条里至少能看到「纸色沿 + 墨线 + 一条纹样」。 */
.face.back {
  background-color: #fbf8f2;
  background-image: repeating-linear-gradient(
    45deg,
    color-mix(in srgb, var(--accent) 88%, var(--ink)) 0 3px,
    color-mix(in srgb, var(--accent) 62%, var(--sheet)) 3px 6px
  );
  background-repeat: no-repeat;
  background-origin: content-box;
  background-clip: content-box;
  border: var(--rule);
  box-shadow:
    inset 0 0 0 2px #fbf8f2,
    inset 0 0 0 4px color-mix(in srgb, var(--ink) 70%, var(--accent));
  transform: rotateY(180deg);
}

.pcard.drag,
.pcard.pop {
  z-index: 40 !important;
}

.pcard.sel .face.front {
  box-shadow: inset 0 0 0 3px var(--accent);
}

.pcard.hint-src .face.front {
  box-shadow: inset 0 0 0 3px var(--accent-2);
}

.pcard.hint-dst .face.front {
  box-shadow: inset 0 0 0 3px var(--accent);
}

.slot-hint {
  box-shadow: inset 0 0 0 3px var(--accent-2);
}

/* 角标：左上正立，右下倒置（真牌就是这样印的） */
.corner {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: calc(var(--cw) * 0.24);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  text-align: center;
  min-width: 0;
}

.corner.tl {
  top: 0.22em;
  left: 0.3em;
}

.corner.br {
  right: 0.3em;
  bottom: 0.22em;
  transform: rotate(180deg);
}

.pcard.red .corner,
.pcard.red .pips {
  color: #b3271f;
}

.pcard.black .corner,
.pcard.black .pips {
  color: #16181c;
}

/* 中间花色：点数越多越密，透明度压低，别盖住角标 */
.pips {
  position: absolute;
  inset: 22% 16%;
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  justify-content: center;
  gap: 1px;
  font-size: calc(var(--cw) * 0.19);
  line-height: 1;
  opacity: 0.66;
  min-width: 0;
}

.pips .big {
  font-size: calc(var(--cw) * 0.62);
  opacity: 0.9;
}

/* 收牌 / 胜利时弹一下。
   ⚠️ 不能用会改 transform 的 keyframes：牌的位置是 JS 写在 style.transform 上的，
   动画一跑就会被盖掉、跑到左上角去。所以只动 filter 和 z-index。 */
@keyframes sol-pop {
  0% {
    filter: none;
  }
  45% {
    filter: drop-shadow(0 0 6px color-mix(in srgb, var(--accent) 85%, transparent));
  }
  100% {
    filter: none;
  }
}

.pcard.pop {
  animation: sol-pop 400ms var(--ease);
}

/* ---------- 开局选模式 ---------- */
.overlay-mask {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: none;
}

.overlay-mask.open {
  display: grid;
  place-items: center;
  padding: 1rem;
  background: var(--scrim);
  min-width: 0;
}

.overlay-card {
  width: min(100%, 420px);
  padding: 1.3rem 1.2rem 1.2rem;
  border: var(--rule);
  background: var(--sheet);
  box-shadow: var(--shadow-lg);
  animation: sol-deal var(--dur-slow) var(--ease-out);
}

@keyframes sol-deal {
  from {
    transform: translateY(14px);
    opacity: 0;
  }
}

.overlay-title {
  font-size: calc(1.22rem * var(--font-scale, 1));
  font-weight: 800;
  text-align: center;
}

.overlay-sub {
  margin-top: 0.3rem;
  font-family: var(--font-mono);
  font-size: calc(0.74rem * var(--font-scale, 1));
  color: var(--ink-soft);
  text-align: center;
}

.diff-grid {
  display: grid;
  gap: 0.5rem;
  margin-top: 1rem;
  min-width: 0;
}

.dopt {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0.2rem 0.8rem;
  padding: 0.7rem 0.85rem;
  border: var(--rule);
  background: var(--sheet);
  text-align: left;
  transition: background-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
  min-width: 0;
}

.dopt .dname {
  font-size: calc(1rem * var(--font-scale, 1));
  font-weight: 700;
}

.dopt .ddesc {
  grid-column: 1;
  font-family: var(--font-mono);
  font-size: calc(0.72rem * var(--font-scale, 1));
  color: var(--ink-soft);
}

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

.dopt.on .ddesc {
  color: color-mix(in srgb, var(--on-accent) 82%, var(--accent));
}

.result-card {
  text-align: center;
}

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

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

.result-text {
  margin-top: 0.45rem;
  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.6rem;
  margin-top: 1.1rem;
  min-width: 0;
}

.btn {
  padding: 0.52rem 0.8rem;
  border: var(--rule);
  background: var(--sheet);
  box-shadow: var(--shadow-sm);
  font-size: calc(0.86rem * var(--font-scale, 1));
  font-weight: 700;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
    background-color var(--dur) var(--ease);
}

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

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

.start-btn {
  width: 100%;
  margin-top: 0.9rem;
}

/* ---------- 断点 ---------- */
@media (max-width: 640px) {
  /* 窄屏：七列必须都在屏内（横向滚动会把最后一列推出屏幕、牌局残缺 —— 实测被否掉）。
     所以策略是"抠宽度"而不是"加滚动"：
       · 牌桌内距 0.85rem → 0.2rem（给每列多让 ~3px）
       · 列间 0 间隙
       390 宽 → 牌宽 50.6px、末列右缘 372/390 在屏内、无横向滚动。
     牌宽被七列锁死在 ~50px，所以**可读性靠角标**：见下面那条。
     ⚠️ 这条 .table 必须留在**本段（640px 断点）** —— 曾写进上面的断点段里，
     被这条按源码顺序盖掉，改了不生效。 */
  .table {
    padding: 0.2rem;
  }

  .columns,
  .table-top {
    column-gap: 0;
    row-gap: 0;
  }

  .stat-box {
    min-width: 0;
  }
}

/* 牌宽被锁在 ~50px，读得清的关键是角标而不是牌面本身：0.24 → 0.30 倍牌宽
   （390 宽下 11.9 → 15.2px，+28%）。
   ⚠️ 只放大**左上角那一个**：.corner.br 是右下角旋转 180° 的副本，
   一起放大会在右下角冒出一个大号倒置数字。 */
.corner.tl {
  font-size: calc(var(--cw) * 0.3);
}
