/* ==========================================================
   争上游（Struggle Upstream）—— 页面私有样式
   颜色全部取自 common.css 的主题变量，深浅色自动适配；
   所有自定义类加 .zsy- 前缀，绝不覆盖其他工具页的样式。
   ========================================================== */

.container{max-width:1120px;padding:24px 40px 48px;}
header{margin-bottom:22px;}

/* ---------- 游戏主区 ---------- */

.zsy-game{display:flex;flex-direction:column;gap:14px;}

/* ---------- 三家桌面 ---------- */

.zsy-table{
  display:grid;
  grid-template-columns:1fr auto 1fr;
  gap:18px;
  background:var(--bg-2);
  border:1px solid var(--border);
  border-radius:16px;
  padding:18px;
  min-height:230px;
}

.zsy-seat{display:flex;flex-direction:column;gap:10px;min-width:0;}
.zsy-seat-head{display:flex;align-items:center;gap:8px;}
.zsy-seat:last-child .zsy-seat-head{justify-content:flex-end;}

.zsy-avatar{
  width:30px;height:30px;border-radius:9px;flex-shrink:0;
  display:grid;place-items:center;
  background:var(--bg-4);border:1px solid var(--border-light);
  color:var(--fg-2);
  font-family:'JetBrains Mono',monospace;font-size:12px;font-weight:700;
  transition:all .2s ease;
}
.zsy-avatar-me{background:var(--accent-alpha-15);border-color:var(--accent-alpha-35);color:var(--accent);}
.zsy-seat.zsy-active .zsy-avatar{
  border-color:var(--accent);color:var(--accent);
  box-shadow:0 0 0 2px var(--accent-alpha-15);
}
.zsy-seat.zsy-active .zsy-seat-name{color:var(--accent);}
.zsy-me.zsy-active .zsy-avatar-me{box-shadow:0 0 0 2px var(--accent-alpha-15);}
.zsy-seat-name{font-size:13px;color:var(--fg);font-weight:500;}
.zsy-seat-count{
  font-family:'JetBrains Mono',monospace;font-size:11px;
  padding:3px 8px;border-radius:6px;
  background:var(--bg-3);border:1px solid var(--border);color:var(--fg-3);
}

.zsy-seat-play{
  display:flex;flex-wrap:wrap;gap:5px;
  align-items:flex-start;align-content:flex-start;
  min-height:84px;
}
.zsy-seat:last-child .zsy-seat-play{justify-content:flex-end;}

/* ---------- 中央状态 ---------- */

.zsy-center{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:10px;min-width:250px;padding:0 10px;text-align:center;
}
.zsy-status{
  font-size:14px;font-weight:500;color:var(--fg);
  display:flex;align-items:center;gap:8px;
}
.zsy-status .zsy-status-dot{
  width:6px;height:6px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 8px var(--accent);
}
.zsy-status.zsy-waiting .zsy-status-dot{animation:zsyPulse 1.4s ease-in-out infinite;}
@keyframes zsyPulse{0%,100%{opacity:1}50%{opacity:.25}}

.zsy-basis{
  font-family:'JetBrains Mono',monospace;font-size:12px;
  color:var(--fg-2);line-height:1.7;
  padding:7px 14px;border-radius:9px;
  background:var(--bg-3);border:1px solid var(--border);
  max-width:280px;
}
.zsy-basis b{color:var(--accent);font-weight:600;}
.zsy-basis.zsy-invisible{visibility:hidden;}

/* ---------- 扑克牌 ---------- */

.zsy-card{
  position:relative;flex:0 0 auto;
  width:calc(56px * var(--zsy-cs,1));
  height:calc(78px * var(--zsy-cs,1));
  border-radius:calc(7px * var(--zsy-cs,1));
  background:var(--bg-3);
  border:1px solid var(--border-light);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:calc(2px * var(--zsy-cs,1));
  font-family:'JetBrains Mono',monospace;
  color:var(--fg);
  user-select:none;
  transition:transform .14s ease,border-color .14s ease,box-shadow .14s ease;
}
.zsy-card .zsy-rank{font-size:calc(19px * var(--zsy-cs,1));font-weight:700;line-height:1;}
.zsy-card .zsy-suit{font-size:calc(15px * var(--zsy-cs,1));line-height:1;}
.zsy-card.zsy-red{color:var(--danger);}
.zsy-card.zsy-joker .zsy-rank{font-size:calc(13px * var(--zsy-cs,1));letter-spacing:.02em;}

.zsy-card.zsy-back{
  background:
    repeating-linear-gradient(45deg,var(--accent-alpha-10) 0 4px,transparent 4px 8px),
    var(--bg-4);
  border-color:var(--border);
}

/* 桌面出牌区 / 我的最近一手：与手牌同尺寸，看得清才敢记牌 */
.zsy-seat-play,.zsy-me-played,.zsy-basis-cards{--zsy-cs:1;}

.zsy-play-tag{
  font-family:'JetBrains Mono',monospace;font-size:12px;
  color:var(--fg-3);padding:calc(30px * var(--zsy-cs,1)) 0;
}

/* ---------- 我的手牌 ---------- */

.zsy-me{
  background:var(--bg-2);
  border:1px solid var(--border);
  border-radius:16px;
  padding:14px 18px 10px;
  transition:border-color .2s ease;
}
.zsy-me.zsy-active{border-color:var(--accent-alpha-35);}

.zsy-me-head{display:flex;align-items:center;gap:8px;margin-bottom:2px;}
.zsy-me-played{display:flex;gap:4px;align-items:center;margin-left:auto;min-height:24px;}

/* 手牌区整体跟着 --zsy-cs 缩放：叠牌形态下牌会被放大（见 ui.js 的 layoutHand），
   容器高度与内边距必须一起长，否则大牌会贴着边框甚至被裁。
   --zsy-cs 由 JS 按「容器宽度 ÷ 张数」算出来，展开形态恒为 1。 */
.zsy-hand{
  display:flex;justify-content:center;align-items:flex-end;
  min-height:calc(104px * var(--zsy-cs,1));
  padding:calc(20px * var(--zsy-cs,1)) 0 calc(4px * var(--zsy-cs,1));
  /* 窄屏兜底：手牌按最小可读重叠仍放不下时，宁可让它横向滚，也不要把两头的牌切掉。
     用 justify-content:center 的 flex 行一旦溢出会**两头同时**被裁，
     所以溢出时必须切到 flex-start，否则第一张牌会被压掉半张。 */
  overflow-x:auto;
  overflow-y:hidden;
  scrollbar-width:thin;
}
.zsy-hand.zsy-hand-overflow{justify-content:flex-start;}
.zsy-hand .zsy-card{cursor:pointer;}
.zsy-hand.zsy-locked .zsy-card{cursor:default;opacity:.7;}
.zsy-hand.zsy-locked .zsy-card:hover{transform:none;}

/* 展开形态：相邻牌隔开 --zsy-gap（张数多时可为负，自适应重叠） */
.zsy-hand.zsy-spread .zsy-card + .zsy-card{margin-left:var(--zsy-gap,-14px);}
.zsy-hand.zsy-spread .zsy-card:not(.zsy-sel):hover{transform:translateY(-9px);}

/* 叠牌形态：右边的牌压住左边那张，只露出左上角的点数与花色。
   牌尺寸与重叠量都由 JS 算（--zsy-cs / --zsy-overlap）：**先把牌放大到上限，
   再用剩余宽度定间距**，所以 18 张也能把横向空间刚好铺满，不浪费。
   ⚠️ 间距（= 卡宽 + overlap）必须 ≥ 角标右边缘，否则点数会被右边那张盖住。 */
.zsy-hand.zsy-stack .zsy-card + .zsy-card{margin-left:var(--zsy-overlap,-28px);}
.zsy-hand.zsy-stack .zsy-card:not(.zsy-sel):hover{transform:translateY(calc(-5px * var(--zsy-cs,1)));}

/* 叠牌形态下，点数与花色**移到左上角**并缩小。
   原因是重叠时右侧会被下一张盖住，居中的大字会被切成半个字；
   挪到左上角后，无论怎么叠，左上那一小块永远是完整的。
   这里只改位置与字号，不动 .zsy-card 的 flex 布局——展开形态完全不受影响。 */
.zsy-hand.zsy-stack .zsy-card{
  display:block;
  overflow:hidden;
}
/* 角标靠左贴齐，而不是撑满整张牌居中——它只需要占「露出来」的那一小条。
   所有尺寸都乘 --zsy-cs：基准下左缘 3px + 宽 19px ⇒ 右边缘到 22px。
   JS 保证相邻牌的间距 ≥ 22px × 缩放，所以角标永远不会被下一张盖住。 */
.zsy-hand.zsy-stack .zsy-card .zsy-rank,
.zsy-hand.zsy-stack .zsy-card .zsy-suit{
  position:absolute;
  left:calc(3px * var(--zsy-cs,1));
  width:calc(19px * var(--zsy-cs,1));
  text-align:center;
}
.zsy-hand.zsy-stack .zsy-card .zsy-rank{
  top:calc(5px * var(--zsy-cs,1));
  font-size:calc(13px * var(--zsy-cs,1));
  line-height:1;
}
.zsy-hand.zsy-stack .zsy-card .zsy-suit{
  top:calc(20px * var(--zsy-cs,1));
  font-size:calc(12px * var(--zsy-cs,1));
  line-height:1;
}
/* 大小王是两个字（「大王」/「小王」），得再收一点才放得进角标 */
.zsy-hand.zsy-stack .zsy-card.zsy-joker .zsy-rank{
  font-size:calc(10px * var(--zsy-cs,1));
  letter-spacing:0;
}

/* 选中的牌：抬起 + 高亮描边。
   ⚠️ 这里**故意不提升 z-index**。角标在左上角，选中牌抬起来已经足够醒目；
   而一旦让它浮到最上层，它那张放大后的完整卡面会向右盖掉下一张牌的角标
   （牌放大 1.6 倍后覆盖宽 37px，正好压住 36px 处的角标），
   玩家就看不见右边那张是什么牌、没法决定要不要一起选。
   保持默认层叠顺序时，右侧牌压住的是选中牌的右下空白区，双方的角标都露着。 */
.zsy-hand .zsy-card.zsy-sel{
  --zsy-lift:calc(-18px * var(--zsy-cs,1));
  transform:translateY(var(--zsy-lift));
  border-color:var(--accent);
  box-shadow:0 0 0 1px var(--accent),0 8px 20px rgba(0,0,0,.28);
}
.zsy-hand.zsy-stack .zsy-card.zsy-sel{box-shadow:0 0 0 1px var(--accent),0 10px 24px rgba(0,0,0,.34);}
.zsy-hand .zsy-card.zsy-shake{
  /* 注意：--zsy-lift 是「当前应抬起的距离」，用变量把它和 transform 分开写，
     否则 .zsy-sel 的 translateY(-18px) 会被这条覆盖掉（两者同为单类选择器，看书写顺序） */
  animation:zsyShake .34s ease;
  transform:translateY(var(--zsy-lift,0px));
}
@keyframes zsyShake{
  0%,100%{transform:translateY(var(--zsy-lift,0px)) translateX(0)}
  25%{transform:translateY(var(--zsy-lift,0px)) translateX(-5px)}
  75%{transform:translateY(var(--zsy-lift,0px)) translateX(5px)}
}

/* ---------- 动效 ---------- */

/* 发牌：手牌从下方逐张浮入（--zsy-i 是牌在手里的序号，用来做错峰） */
.zsy-hand.zsy-deal .zsy-card{
  animation:zsyDealIn .44s cubic-bezier(.2,.8,.3,1) backwards;
  animation-delay:calc(var(--zsy-i,0) * 26ms);
}
@keyframes zsyDealIn{
  from{opacity:0;transform:translateY(48px) rotate(-7deg) scale(.86);}
  to{opacity:1;transform:none;}
}

/* 出牌落桌：每一手新牌依次落下 */
.zsy-play-in .zsy-card{
  animation:zsyCardDrop .32s cubic-bezier(.2,.9,.3,1.12) backwards;
  animation-delay:calc(var(--zsy-i,0) * 42ms);
}
.zsy-play-in .zsy-play-tag{animation:zsyTagIn .22s ease backwards;}
@keyframes zsyCardDrop{
  from{opacity:0;transform:translateY(-18px) scale(.88);}
  to{opacity:1;transform:none;}
}
@keyframes zsyTagIn{
  from{opacity:0;transform:translateY(-6px);}
  to{opacity:1;transform:none;}
}

/* 回合回收：桌面上的牌整体淡出，再由 JS 清空 */
.zsy-fadeout .zsy-card,
.zsy-fadeout .zsy-play-tag{
  animation:zsyFadeOut .26s ease forwards;
}
@keyframes zsyFadeOut{
  to{opacity:0;transform:translateY(8px) scale(.94);}
}

/* ---------- 操作栏 ---------- */

.zsy-actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}

.zsy-btn{
  font-family:inherit;font-size:13px;
  padding:10px 20px;border-radius:10px;
  background:var(--bg-2);border:1px solid var(--border-light);
  color:var(--fg);cursor:pointer;
  transition:all .16s ease;
}
.zsy-btn:hover:not(:disabled){border-color:var(--accent-alpha-40);color:var(--accent);}
.zsy-btn:disabled{opacity:.35;cursor:not-allowed;}
.zsy-btn-primary{
  background:linear-gradient(135deg,var(--accent) 0%,var(--accent-dim) 100%);
  border-color:transparent;color:#0a0d12;font-weight:600;
}
.zsy-btn-primary:hover:not(:disabled){box-shadow:var(--glow);color:#0a0d12;}
.zsy-btn-ghost{margin-left:auto;}

/* 电脑难度切换 */
.zsy-levels{display:flex;align-items:center;gap:6px;margin-right:4px;}
.zsy-level-label{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--fg-3);}
.zsy-level{
  font-family:inherit;font-size:12px;
  padding:7px 13px;border-radius:8px;
  background:var(--bg-2);border:1px solid var(--border-light);
  color:var(--fg-3);cursor:pointer;
  transition:all .16s ease;
}
.zsy-level:hover{border-color:var(--accent-alpha-40);color:var(--accent);}
.zsy-level.is-on{
  background:var(--accent-alpha-15);
  border-color:var(--accent-alpha-35);
  color:var(--accent);font-weight:600;
}

/* 规则切换（A ⇄ B）。只在开局前可点，出牌开始后禁用。
   B 规则时整颗按钮高亮 —— 玩家一眼能看出当前不是标准玩法。 */
.zsy-ruleset{
  font-family:'JetBrains Mono',monospace;font-size:12px;
  padding:7px 14px;border-radius:8px;
  background:var(--bg-2);border:1px solid var(--border-light);
  color:var(--fg-3);cursor:pointer;
  transition:all .16s ease;
}
.zsy-ruleset:hover:not(:disabled){border-color:var(--accent-alpha-40);color:var(--accent);}
.zsy-ruleset.is-b{
  background:var(--accent-alpha-15);
  border-color:var(--accent-alpha-35);
  color:var(--accent);font-weight:600;
}
.zsy-ruleset:disabled{opacity:.35;cursor:not-allowed;}

/* 音效开关（只放图标的小圆钮） */
.zsy-icon-btn{
  display:grid;place-items:center;
  width:36px;height:36px;padding:0;
  border-radius:10px;
  background:var(--bg-2);border:1px solid var(--border-light);
  color:var(--accent);cursor:pointer;
  transition:all .16s ease;
}
.zsy-icon-btn:hover{border-color:var(--accent-alpha-40);}
.zsy-icon-btn .zsy-snd-off{display:none;}
.zsy-icon-btn.is-off{color:var(--fg-3);}
.zsy-icon-btn.is-off .zsy-snd-on{display:none;}
.zsy-icon-btn.is-off .zsy-snd-off{display:block;}
.zsy-icon-btn[hidden]{display:none;}

.zsy-tip{
  flex-basis:100%;
  font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--fg-3);
  min-height:16px;
}
.zsy-tip.zsy-bad{color:var(--danger);}
.zsy-tip.zsy-good{color:var(--accent);}

/* ---------- 顶部计分：累计分领先者高亮 ---------- */

.stat-pill.zsy-lead{
  border-color:var(--accent-alpha-35);
  background:var(--accent-alpha-10);
}
.stat-pill.zsy-lead .zsy-score{color:var(--accent);}

/* ---------- 结算浮层 ---------- */

.zsy-overlay{
  position:fixed;inset:0;z-index:120;
  background:rgba(0,0,0,.5);
  display:grid;place-items:center;
  animation:zsyFade .18s ease;
}
.zsy-overlay[hidden]{display:none;}
@keyframes zsyFade{from{opacity:0}to{opacity:1}}

.zsy-modal{
  background:var(--bg-2);
  border:1px solid var(--border-light);
  border-radius:16px;
  padding:26px 32px 24px;
  min-width:330px;
  text-align:center;
  box-shadow:0 24px 60px rgba(0,0,0,.4);
  animation:zsyRise .22s cubic-bezier(.2,.9,.3,1.2);
}
@keyframes zsyRise{from{opacity:0;transform:translateY(14px) scale(.97)}to{opacity:1;transform:none}}

.zsy-modal-label{
  font-family:'JetBrains Mono',monospace;font-size:11px;
  color:var(--fg-3);letter-spacing:.08em;margin-bottom:6px;
}
.zsy-modal h3{font-size:19px;font-weight:600;margin-bottom:4px;}
.zsy-ranks{display:flex;flex-direction:column;gap:8px;margin:18px 0 22px;}
.zsy-rank-row{
  display:flex;align-items:center;gap:10px;
  padding:10px 14px;border-radius:10px;
  background:var(--bg-3);border:1px solid var(--border);
  font-size:13px;color:var(--fg-2);
  animation:zsyRowIn .34s cubic-bezier(.2,.8,.3,1) backwards;
  animation-delay:calc(var(--zsy-i,0) * 90ms);
}
@keyframes zsyRowIn{from{opacity:0;transform:translateX(-12px);}to{opacity:1;transform:none;}}
.zsy-rank-row.zsy-win{border-color:var(--accent-alpha-40);background:var(--accent-alpha-10);}
.zsy-rank-no{
  width:22px;height:22px;border-radius:6px;flex-shrink:0;
  display:grid;place-items:center;
  background:var(--bg-4);color:var(--fg-3);
  font-family:'JetBrains Mono',monospace;font-size:11px;font-weight:700;
}
.zsy-rank-row.zsy-win .zsy-rank-no{background:var(--accent);color:#0a0d12;}
.zsy-rank-name{flex:1;text-align:left;color:var(--fg);}
.zsy-rank-pts{font-family:'JetBrains Mono',monospace;font-size:12px;}
.zsy-rank-pts b{color:var(--accent);font-size:14px;}
.zsy-modal-actions{display:flex;gap:10px;justify-content:center;}

/* ---------- 窄屏 ---------- */

@media (max-width:900px){
  .container{padding:18px 18px 36px;}
  .header-stats .zsy-back-text{display:none;}
  .zsy-table{grid-template-columns:1fr;gap:14px;min-height:0;}
  .zsy-seat:last-child .zsy-seat-head,
  .zsy-seat:last-child .zsy-seat-play{justify-content:flex-start;}
  .zsy-center{min-width:0;order:-1;}
  .zsy-btn-ghost{margin-left:0;}
}

/* ---------- 尊重系统的「减弱动效」设置 ---------- */

@media (prefers-reduced-motion:reduce){
  .zsy-hand.zsy-deal .zsy-card,
  .zsy-play-in .zsy-card,
  .zsy-play-in .zsy-play-tag,
  .zsy-fadeout .zsy-card,
  .zsy-fadeout .zsy-play-tag,
  .zsy-rank-row,
  .zsy-modal,
  .zsy-overlay{
    animation:none !important;
  }
  .zsy-hand .zsy-card,
  .zsy-seat .zsy-avatar,
  .zsy-status .zsy-status-dot{
    transition:none !important;
  }
}
