:root{
  --bg:#eef1f5; --panel:#ffffff; --ink:#1f2937; --muted:#64748b; --line:#dfe4ea;
  --felt:#14532d; --felt2:#0d3b21; --gold:#f0c14b; --red:#c92a2a; --green:#15803d;
  --blue:#2563eb; --shadow:0 2px 10px rgba(15,23,42,.08);
}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:"PingFang SC","Microsoft YaHei","Hiragino Sans GB","Segoe UI",system-ui,sans-serif;
  background:var(--bg);color:var(--ink);font-size:15px;line-height:1.6;min-height:100vh}
.app{max-width:1120px;margin:0 auto;padding:12px 14px 28px;
  display:flex;flex-direction:column}
/* .mwrap 在桌面上「消隐」（display:contents），让牌桌与面板回到 .app 直接子级，
   用 order 保持原有视觉顺序：顶栏 → 状态条 → 牌桌 → 出牌区 → 记牌器/战况 */
.mwrap{display:contents}
.topbar{order:1}
.statusbar{order:2}
/* 观众名单条：夹在状态条与牌桌之间，永远在牌桌正上方 */
.spectbar{order:3}
.table{order:4}
.playarea{order:5}
/* 顺序：顶栏 → 状态条 → 观众名单 → 牌桌 → 出牌区（含出牌按钮） → 聊天框 → 记牌器/战况
   ⚠ .chatbox 必须显式给 order：flex 项默认 order:0，会被排到所有正序项之前（跑到页面最顶端）。 */
.chatbox{order:6}
.panels{order:7}

/* ---------- 顶栏 ---------- */
.topbar{display:flex;align-items:center;gap:16px;flex-wrap:wrap;background:var(--panel);
  border:1px solid var(--line);border-radius:14px;padding:10px 16px;box-shadow:var(--shadow)}
.brand{font-weight:800;font-size:19px;letter-spacing:.5px}
.brand small{display:block;font-weight:500;font-size:11px;color:var(--muted);letter-spacing:0}
.lvwrap{display:flex;align-items:center;gap:10px;flex:1;min-width:320px}
.lvbox{display:flex;align-items:center;gap:6px;background:#f8fafc;border:1px solid var(--line);
  border-radius:10px;padding:4px 10px;font-size:13px;color:var(--muted)}
.lvbox b{font-size:18px;color:var(--ink)}
.lvbox.you b{color:var(--blue)} .lvbox.ai b{color:var(--red)}
.track{flex:1;height:8px;background:#e8edf3;border-radius:99px;position:relative;overflow:hidden}
.track i{position:absolute;top:0;bottom:0;background:linear-gradient(90deg,#3b82f6,#1d4ed8);border-radius:99px}
.track i.ai{background:linear-gradient(90deg,#f87171,#dc2626)}
.tools{display:flex;gap:8px;flex-wrap:wrap}
button{font-family:inherit;font-size:14px;font-weight:600;border-radius:10px;
  border:1px solid #cfd8e3;background:#fff;color:var(--ink);padding:8px 15px;cursor:pointer;
  transition:background .16s,box-shadow .16s,transform .16s,border-color .16s;
  box-shadow:0 1px 2px rgba(15,23,42,.06)}
button:hover:not(:disabled){background:#f1f5f9;border-color:#94a3b8;transform:translateY(-1px);
  box-shadow:0 4px 10px rgba(15,23,42,.10)}
button:active:not(:disabled){transform:translateY(0);box-shadow:inset 0 1px 3px rgba(15,23,42,.14)}
button:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}
button:focus-visible{outline:3px solid rgba(37,99,235,.45);outline-offset:2px}
button.primary{background:linear-gradient(180deg,#1a7a4a,#0f5132);border-color:#0b3d26;color:#fff;
  box-shadow:0 3px 10px rgba(15,81,50,.28)}
button.primary:hover:not(:disabled){background:linear-gradient(180deg,#1e8f57,#12603c);
  border-color:#0b3d26;box-shadow:0 5px 14px rgba(15,81,50,.34)}
button.danger{background:#fff1f2;border-color:#fca5a5;color:#be123c}
button.danger:hover:not(:disabled){background:#ffe4e6;border-color:#f87171}
button.on{background:#eff6ff;border-color:#93c5fd;color:#1d4ed8;box-shadow:0 0 0 2px rgba(37,99,235,.12)}

/* ---------- 状态条 ---------- */
.statusbar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:10px 2px;
  background:#fff;border:1px solid var(--line);border-radius:12px;padding:8px 14px;font-size:14px}
.statusbar .msg{color:#92400e;font-weight:600}
.statusbar .req{color:var(--muted)}
.pill{display:inline-block;background:#f1f5f9;border:1px solid var(--line);border-radius:99px;
  padding:1px 9px;font-size:12px;color:var(--muted)}
.pill.warn{background:#fff7ed;border-color:#fed7aa;color:#c2410c}
.pill.good{background:#ecfdf5;border-color:#a7f3d0;color:#047857}
/* 语音自检提示（点击可解锁语音 / 重试） */

/* ---------- 观众名单条（常驻牌桌正上方） ---------- */
.spectbar{display:flex;align-items:center;gap:7px;flex-wrap:wrap;
  margin:8px 2px 0;padding:5px 12px;border-radius:11px;
  background:#fff7ed;border:1px solid #fed7aa;font-size:12.5px;color:#9a3412}
.spectbar .lb{font-weight:800;color:#c2410c;white-space:nowrap}
.spectbar .sp{display:inline-block;background:#fff;border:1px solid #fed7aa;border-radius:99px;
  padding:0 9px;font-size:12px;color:#7c2d12;white-space:nowrap;line-height:1.7}
.spectbar .sp.me{background:#eef2ff;border-color:#c7d2fe;color:#4338ca;font-weight:700}
.spectbar .sp.off{opacity:.55}

/* ---------- 牌桌 ---------- */
.table{position:relative;background:radial-gradient(ellipse at center,#1a6b3d,#0c3a20 75%);
  border:8px solid #0a2c1a;border-radius:20px;box-shadow:inset 0 0 60px rgba(0,0,0,.35);
  display:grid;grid-template-columns:1fr 1.5fr 1fr;grid-template-rows:auto 1fr auto;
  grid-template-areas:". n ." "w c e" ". s .";gap:8px;padding:10px;min-height:400px}
.zone{position:relative;background:rgba(0,0,0,.16);border-radius:14px;padding:22px 8px 10px;
  min-height:104px;display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:4px}
.zn{grid-area:n} .zw{grid-area:w} .ze{grid-area:e} .zs{grid-area:s}
.zone.self{background:rgba(0,0,0,.24);box-shadow:inset 0 0 0 2px rgba(240,193,75,.45)}
.zone.active{box-shadow:inset 0 0 0 2px var(--gold),0 0 18px rgba(240,193,75,.35)}
/* 座位头部：左右分布 + 各自收缩，杜绝窄屏下名字与张数互相压字 */
.zhead{position:absolute;top:0;left:0;right:0;display:flex;align-items:center;justify-content:space-between;
  gap:4px;padding:3px 7px;font-size:12px;line-height:1.3;pointer-events:none}
.pname{color:#d7ecdf;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pname .team{opacity:.75}
.pcount{color:#ffd98a;font-weight:700;flex:0 0 auto;white-space:nowrap}
.pcount.hot{color:#ff9d9d}
.pcard{position:absolute;bottom:3px;left:7px;font-size:11px;color:#ffb4b4;pointer-events:none}
/* ---------- 报牌徽标（醒目但紧凑） ----------
   ⚠ 上一轮为「更醒目」把它放大到 12.5px + 大内边距 + scale(1.1) 脉冲，
     手机上显得占地方、不协调（实测：手机竖屏占座位框高 34~37%，
     手机横屏占座位框高 84%，几乎撑满整行）。
   现在收紧：字号降到 10.5px、内边距 4px 7px、脉冲缩放幅度降到 1.06，
   保留渐变底色与加粗 —— 醒目靠颜色与字重，不靠占地方。 */
.pcard.reported{font-size:10.5px;font-weight:800;color:#fff;letter-spacing:0;
  background:linear-gradient(135deg,#fb923c,#dc2626);padding:0 7px;border-radius:99px;
  line-height:1.5;box-shadow:0 1px 5px rgba(220,38,38,.5);animation:repPulse 1.3s ease-in-out infinite}
@keyframes repPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
.zone .cards{display:flex;gap:3px;flex-wrap:wrap;justify-content:center;align-items:flex-end;max-width:96%}
.zone .cards .card{opacity:.92}
.zone .cards .card.hi{transform:scale(1.12);box-shadow:0 0 0 2px var(--gold)}
.zone .passed{color:#9fb8a8;font-size:13px;font-style:italic}
.center{grid-area:c;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:6px;text-align:center;color:#eaf5ee;min-width:0;max-width:100%;overflow-wrap:anywhere}
.center .big{font-size:17px;font-weight:700;color:#ffe9a8;text-shadow:0 1px 3px rgba(0,0,0,.4);
  max-width:100%;white-space:normal;overflow-wrap:anywhere}
.center .small{font-size:12px;color:#b9d6c4;max-width:100%;white-space:normal;overflow-wrap:anywhere}
.flipcard{background:#fff;border-radius:6px;padding:3px 8px;font-weight:800;font-size:15px;
  color:#b91c1c;border:1px solid #cbd5e1;box-shadow:0 2px 6px rgba(0,0,0,.3);white-space:nowrap}

/* ---------- 扑克牌 ---------- */
.card{background:#fdfdfa;color:#1f2937;border-radius:7px;border:1px solid #c9c4b4;
  box-shadow:0 1px 3px rgba(0,0,0,.35);display:inline-flex;flex-direction:column;
  align-items:center;justify-content:center;user-select:none;-webkit-user-select:none;position:relative;
  width:40px;height:56px;font-weight:800;font-size:15px;padding:2px;overflow:hidden}
/* 花色图案：内联 SVG，按卡片字号等比缩放（em）——矢量不失真，任何浏览器一致 */
.card .suit{display:flex;align-items:center;justify-content:center;line-height:0;margin-top:1px}
.card .suit-svg{width:1.05em;height:1.05em;display:block;flex:0 0 auto}
/* 牌面点数：大王/小王是双字，必须能完整放进卡框 —— 用容器内缩放 + 溢出裁剪兜底 */
.card .ranktxt{display:block;max-width:100%;line-height:1.1;white-space:nowrap;
  overflow:hidden;text-overflow:clip;transform-origin:center center}
.card.red{color:var(--red)}
.card.lvl{box-shadow:0 0 0 2px var(--gold),0 1px 3px rgba(0,0,0,.35)}
.card.wild{background:#fff8e1;box-shadow:0 0 0 2px #f59e0b,0 1px 3px rgba(0,0,0,.35)}
.card .tag{position:absolute;top:0;left:0;background:var(--gold);color:#5b3b00;
  font-size:9px;border-radius:0 5px 5px 0;padding:0 3px;font-weight:700;
  border-right:1px solid #b98f21;border-bottom:1px solid #b98f21;line-height:1.3}
.card.jk{background:#1f2937;color:#fff;border-color:#111827}
/* 王牌是双字：大卡（手牌）显示完整「大王/小王」，小卡（牌桌）显示单字「大/小」+ 下方星标，绝不撑破卡框。
   字号随卡片基准字号等比缩放，卡面变小（如横屏 28px）时也不会溢出 */
.card.jk .ranktxt{font-size:.82em;line-height:1.05}
.card.jk .jk-short{display:none}
.card.jk .suit-svg{width:.9em;height:.9em}
.card.sm{width:27px;height:38px;font-size:11px;border-radius:5px}
.card.sm .suit-svg{width:1em;height:1em}
.card.sm .jk .ranktxt{font-size:11px}
.card.sm .jk .jk-full{display:none}
.card.sm .jk .jk-short{display:block}
.hand .card{cursor:pointer;transition:transform .12s,box-shadow .12s}
.hand .card:hover{transform:translateY(-5px)}
.hand .card.sel{transform:translateY(-14px);box-shadow:0 0 0 3px var(--gold),0 6px 12px rgba(0,0,0,.3)}

/* ---------- 滑动刷选 + 拖拽理牌 ---------- */
.hand{position:relative}
/* 刷选过程中抑制「选中牌抬起」与 hover 抬起：
   否则每选中一张牌它就上移 14px，手牌几何随之改变，
   指针下一帧命中的牌就会错位（尤其横向扫过一整排时）。 */
body.sliding{user-select:none;-webkit-user-select:none;cursor:crosshair}
body.sliding .hand .card:hover,body.sliding .hand .card.sel{transform:none}
/* 拖拽理牌：浮层 / 占位 / 落点高亮 */
.hand .card.drag-src{opacity:.26;filter:grayscale(.4)}
.hand .card.drag-src::after{content:'';position:absolute;top:0;right:0;bottom:0;left:0;inset:0;
  border:1px dashed var(--gold);border-radius:6px;pointer-events:none}
body.dragging{user-select:none;-webkit-user-select:none;cursor:grabbing}
body.dragging .hand .card:hover,body.dragging .hand .card.sel{transform:none}
/* 浮层：跟随指针（fixed + translate3d，GPU 合成，不触发布局） */
.drag-ghost{position:fixed;left:0;top:0;z-index:9999;pointer-events:none;display:flex;gap:4px;
  align-items:flex-end;will-change:transform;transition:none;filter:drop-shadow(0 10px 18px rgba(0,0,0,.45))}
.drag-ghost .card{transform:rotate(-4deg) scale(1.08);box-shadow:0 8px 20px rgba(0,0,0,.4)}
.drag-ghost.back{transition:transform .24s cubic-bezier(.3,.9,.4,1),opacity .24s}
/* 落点高亮：插入槽 / 叠放目标 */
.drop-mark{position:absolute;width:4px;border-radius:3px;background:var(--gold);pointer-events:none;z-index:6;
  box-shadow:0 0 10px rgba(240,193,75,.9)}
.hand .card.drop-ok{box-shadow:0 0 0 3px #22c55e,0 6px 16px rgba(0,0,0,.35)!important;transform:translateY(-6px)}
.hand .card.drop-bad{box-shadow:0 0 0 3px #ef4444,0 6px 16px rgba(0,0,0,.35)!important;transform:translateY(-6px)}
.drop-msg{position:fixed;z-index:10000;pointer-events:none;background:rgba(15,23,42,.93);color:#fff;
  font-size:12px;padding:4px 10px;border-radius:8px;transform:translate(-50%,-160%);white-space:nowrap;
  box-shadow:0 4px 14px rgba(0,0,0,.35)}
.drop-msg.ok{background:rgba(22,101,52,.95)}
.drop-msg.bad{background:rgba(153,27,27,.95)}

/* ---------- 级牌提示（醒目） ---------- */
#levelinfo{background:linear-gradient(135deg,#fde68a,#f59e0b);border-color:#b45309;color:#451a03;
  font-weight:800;font-size:13.5px;padding:2px 14px;letter-spacing:.4px;
  box-shadow:0 2px 8px rgba(180,83,9,.4);text-shadow:0 1px 0 rgba(255,255,255,.5)}
#levelinfo::before{content:'★ '}
.lvbox b.lv-level{color:#b45309}
@media(max-width:820px){ #levelinfo{font-size:12px;padding:1px 10px} }
@media(max-width:380px){ #levelinfo{font-size:11.5px;padding:1px 8px} }

/* ---------- 进贡动画（桌面飞牌 + 字幕） ---------- */
.trib-fly{position:absolute;z-index:30;pointer-events:none;will-change:transform,opacity;
  box-shadow:0 12px 26px rgba(0,0,0,.55)}
.table.trib-on .center{visibility:hidden}
.trib-cap{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:32;
  pointer-events:none;text-align:center;background:rgba(6,20,13,.92);color:#ffe9a8;
  border:1px solid rgba(240,193,75,.6);border-radius:12px;padding:10px 18px;
  box-shadow:0 10px 28px rgba(0,0,0,.5);max-width:94%;white-space:nowrap;
  animation:tribPop .26s ease-out}
.trib-cap-main{font-size:16px;font-weight:800;letter-spacing:.5px}
.trib-cap-sub{font-size:12.5px;color:#b9d6c4;margin-top:3px}
@keyframes tribPop{from{opacity:0;transform:translate(-50%,-50%) scale(.9)}
  to{opacity:1;transform:translate(-50%,-50%) scale(1)}}
.trib-skip{position:absolute;right:8px;top:8px;z-index:34;font-size:12px;padding:4px 11px;
  border-radius:9px;background:rgba(10,22,16,.82);color:#ffe9a8;border:1px solid rgba(240,193,75,.5)}
/* ---------- 进贡 / 还贡：直接从手牌中选牌（无弹层） ---------- */
.tribpick{display:inline-block;padding:3px 10px;border-radius:8px;background:#fffbeb;
  border:1px solid #fcd9a8;color:#7c2d12;font-weight:600}
.selinfo .tribpick button{margin-left:8px;font-weight:700}
.selinfo .tribpick button:disabled{background:#e2e8f0;color:#94a3b8;border-color:#cbd5e1}

/* ---------- 出牌区 ---------- */
.playarea{background:var(--panel);border:1px solid var(--line);border-radius:14px;
  padding:10px 14px 14px;margin-top:10px;box-shadow:var(--shadow)}
.selinfo{min-height:22px;font-size:13px;color:var(--muted);display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.selinfo b{color:var(--ink)}
.selinfo .bad{color:#be123c} .selinfo .good{color:#047857}
.hand{display:flex;flex-wrap:wrap;gap:6px;justify-content:center;padding:16px 4px 8px;min-height:78px}
.actions{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-top:6px}
.actions button{padding:9px 26px;font-size:16px}
.wildpick{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin-top:8px}
.wildpick button{font-size:12px;padding:4px 10px;border-color:#f59e0b;background:#fffbeb;color:#92400e}
.wildpick button.cur{background:#f59e0b;color:#fff}

/* ---------- 记牌 / 日志 ---------- */
.panels{display:grid;grid-template-columns:1fr 1.35fr;gap:10px;margin-top:10px}
.cardpanel{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:10px 14px;box-shadow:var(--shadow)}
.cardpanel h3{font-size:14px;color:var(--muted);font-weight:700;margin-bottom:6px;letter-spacing:.5px}
.memrow{display:flex;flex-wrap:wrap;gap:5px;font-size:12px}
.memrow span{background:#f1f5f9;border:1px solid var(--line);border-radius:6px;padding:1px 7px;color:var(--muted)}
.memrow span b{color:var(--ink)}
.memrow span.key{background:#fff7ed;border-color:#fcd9a8;color:#9a3412}
/* 「配」= 逢人配，是「级牌」的子集 → 用另一种颜色区分，提醒勿重复相加 */
.memrow span.key.wild{background:#ecfdf5;border-color:#a7f3d0;color:#047857}
.log{background:#0f172a;border-radius:10px;padding:8px 12px;font-size:13px;color:#a9b8cc;
  max-height:190px;overflow-y:auto;line-height:1.75}
.log div:first-child{color:#e8eef7}
.log .mine{color:#7dd3fc}
/* 报牌行：战况记录里高亮 */
.log .rep{color:#fdba74;font-weight:800;background:rgba(249,115,22,.16);
  border-radius:6px;padding:2px 7px;margin-bottom:2px;display:inline-block}

/* ---------- 弹层 ---------- */
.mask{position:fixed;top:0;right:0;bottom:0;left:0;inset:0;background:rgba(15,23,42,.55);
  display:flex;align-items:center;justify-content:center;z-index:90;padding:16px;
  -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
.modal{background:#fff;border-radius:16px;max-width:840px;width:100%;max-height:88vh;overflow:auto;
  padding:22px 26px;box-shadow:0 20px 50px rgba(0,0,0,.3)}
.modal h2{font-size:21px;margin-bottom:4px;color:#0f172a}
.modal h4{font-size:15px;margin:14px 0 4px;color:#b45309}
.modal p{margin:6px 0}
.modal table{width:100%;border-collapse:collapse;font-size:13.5px;margin:8px 0}
.modal th,.modal td{border:1px solid var(--line);padding:6px 9px;text-align:left}
.modal th{background:#f1f5f9}
.modal ul,.modal ol{margin:6px 0 6px 20px}
.modal .foot{display:flex;gap:10px;justify-content:flex-end;margin-top:16px;flex-wrap:wrap}
.guidebody h3{font-size:16px;color:#b45309;margin:12px 0 4px}
.guidebody li{margin:4px 0}
.tipbox{background:#fffbeb;border:1px solid #fcd9a8;border-radius:10px;padding:10px 14px;margin:10px 0;font-size:14px}
.notebox{background:#eff6ff;border:1px solid #bfdbfe;border-radius:10px;padding:10px 14px;margin:10px 0;font-size:14px}
/* 规则速查「级牌（参谋）」小节：一行紧凑的口径切换控件（无底色、无边框块） */
/* ---------- 级牌组牌口径：切换面板（入口 = 状态栏「级牌」徽标） ---------- */
#levelinfo{cursor:pointer;user-select:none;-webkit-user-select:none}
#levelinfo:hover{filter:brightness(1.07);box-shadow:0 2px 12px rgba(180,83,9,.55)}
.lvmodepick{margin:8px 0;padding:9px 12px;border-radius:10px;border:1px solid var(--line);
  background:#fff;cursor:pointer;transition:.15s;line-height:1.62;font-size:13.5px}
.lvmodepick:hover{border-color:var(--gold);background:#fffbeb}
.lvmodepick.cur{border-color:#b45309;background:#fff7e6;font-weight:700}
.lvmodepick .sub{color:var(--muted);font-size:12.5px;font-weight:400}
.resbar{display:flex;gap:14px;flex-wrap:wrap;justify-content:center;margin:10px 0;font-size:14px}
.resbar div{background:#f8fafc;border:1px solid var(--line);border-radius:10px;padding:8px 14px;text-align:center}
.resbar b{display:block;font-size:20px}
.hidden{display:none !important}

/* ---------- 触摸与滚动基础（全平台生效，手机上最明显） ---------- */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{touch-action:manipulation}                       /* 去掉移动端 300ms 点击延迟 */
button,.card{touch-action:manipulation;-webkit-tap-highlight-color:transparent}
.log,.mwrap,.modal,.hand{overscroll-behavior:contain} /* 内部滚动不外溢、不触发整页橡皮筋 */
.log,.modal,.hand{-webkit-overflow-scrolling:touch}   /* iOS 惯性滚动 */

/* ---------- 移动端：整页自然滚动 + 手牌平铺全显 + 底部操作区常驻 ---------- */
@media(max-width:820px){
  /* ① 恢复整页纵向滚动：解除 html/body 的 height:100% 与 overflow:hidden，
        手指在页面任意处（除弹层外）上下滑动都能翻页 */
  html{height:auto;overflow-x:hidden}
  body{height:auto;min-height:100vh;min-height:100dvh;overflow-x:hidden;overscroll-behavior-y:auto;
    padding-bottom:var(--pad-b,0px)}
  .app{max-width:none;min-height:100vh;min-height:100dvh;height:auto;padding:7px 8px 16px;
    display:flex;flex-direction:column;gap:8px}

  /* ② 顶栏吸顶：级牌与工具按钮常驻，滚动时不丢失 */
  .topbar{position:-webkit-sticky;position:sticky;top:0;z-index:30;padding:7px 10px;gap:6px;flex-wrap:wrap}
  .brand{font-size:16px;flex:0 0 auto}
  .brand small{display:none}
  .lvwrap{flex:1 1 auto;min-width:0;gap:7px}
  .lvbox{padding:3px 8px;font-size:12px}
  .lvbox b{font-size:16px}
  /* 工具按钮独立成第二行：5 个按钮 390px 放不下，允许换行而不是被裁 */
  .tools{flex:1 1 100%;min-width:0;flex-wrap:wrap;gap:5px;max-width:100%}
  .tools button{flex:1 1 auto;font-size:12.5px;padding:6px 8px;white-space:nowrap;
    min-width:0;overflow:hidden;text-overflow:ellipsis}

  .statusbar{margin:0;padding:5px 10px;font-size:12.5px;gap:6px;flex-wrap:wrap;line-height:1.35}
  .statusbar .msg{flex:1 1 auto;min-width:0;overflow-wrap:anywhere}
  .statusbar .req{flex:1 1 100%;min-width:0;overflow-wrap:anywhere;font-weight:400;color:var(--muted)}

  /* ③ 牌桌与面板回到 .app 直接子级（与桌面同构），先后顺序靠 order 控制；
        滚动交给页面本身，不再有「中间小窗口」式的内部滚动区 */
  .mwrap{display:contents}

  /* 牌桌：北/南占整行，西-中-东一行，中间信息不再挤爆 */
  .table{order:4;flex:0 0 auto;min-height:225px;grid-template-columns:0.95fr 1.35fr 0.95fr;grid-template-areas:
    "n n n" "w c e" "s s s";gap:5px;padding:6px;border-width:5px;border-radius:14px}
  .zone{min-height:68px;padding:17px 5px 6px;border-radius:10px}
  .zhead{padding:2px 5px;font-size:11px}
  .pname .team{display:none}                 /* 窄屏省掉「（对家）」，留给张数 */
  .pcard{font-size:10px;left:5px;bottom:2px}
  /* 报牌徽标：手机上再收一档。
     ⚠ 必须写成 .pcard.reported（双类）—— 基础样式里的 .pcard{font-size:10px} 是单类，
       会被同名的 .pcard.reported 规则压过，导致手机上徽标字号根本没变小。 */
  .pcard.reported{font-size:9.5px;padding:0 6px;letter-spacing:0}
  .center .big{font-size:14.5px}
  .center .small{font-size:11px;line-height:1.4}
  .flipcard{font-size:13px;padding:2px 6px}

  /* ④ 出牌区：固定在屏幕底部常驻，页面滚动时「出牌/不出/提示」始终可点 */
  .playarea{position:fixed;left:0;right:0;bottom:0;z-index:40;
    padding:5px 8px;padding-bottom:calc(5px + env(safe-area-inset-bottom));
    margin-top:0;border-radius:14px 14px 0 0;border-bottom:0;
    box-shadow:0 -6px 20px rgba(15,23,42,.18)}
  .selinfo{font-size:11.5px;line-height:1.4;min-height:0;margin-bottom:0}
  /* ⑤ 手牌：全部平铺可见（27 张一次看全），不再横向裁切成一字长条 */
  .hand{flex-wrap:wrap;justify-content:center;gap:6px 3px;
    padding:9px 2px 4px;min-height:0;overflow:visible;touch-action:auto}
  .hand .card{flex:0 0 auto;width:33px;height:45px;font-size:13px;border-radius:6px}
  .hand .card.sel{transform:translateY(-6px)}
  .hand .card:hover{transform:none}
  .wildpick{margin-top:4px;gap:6px}
  .wildpick button{font-size:11.5px;padding:5px 8px}
  .actions{gap:7px;margin-top:4px;flex-wrap:nowrap}
  .actions button{flex:1 1 0;min-width:0;padding:11px 4px;font-size:14px;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .actions .more{display:none}          /* 窄屏按钮放不下长文案，只留「不出」 */

  /* 面板：单列、日志区更矮 */
  .panels{order:7;flex:0 0 auto;grid-template-columns:1fr;gap:7px;margin-top:0}
  /* 移动端同样：聊天框在出牌区之后、记牌器之前 */
  .chatbox{order:6;flex:0 0 auto}
  .cardpanel{padding:7px 10px;border-radius:12px}
  .cardpanel h3{font-size:12.5px;margin-bottom:4px}
  .log{max-height:132px;font-size:12px;line-height:1.6}
  .memrow{font-size:11px}

  /* 弹层：贴底半屏、表格可横向滑动、正文不被遮挡 */
  .mask{padding:0;align-items:flex-end}
  .modal{max-width:none;border-radius:16px 16px 0 0;max-height:92vh;max-height:92dvh;
    padding:16px 14px;padding-bottom:calc(16px + env(safe-area-inset-bottom));
    -webkit-overflow-scrolling:touch}
  .modal h2{font-size:18px}
  .modal h4{font-size:14px}
  .modal p,.modal li{font-size:13px}
  .modal table{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;white-space:nowrap}
  .modal th,.modal td{padding:5px 7px;font-size:12px}
  .modal .foot button{flex:1 1 0}
}

/* ---------- 超窄屏（iPhone SE / 小安卓） ---------- */
@media(max-width:380px){
  .card.sm{width:24px;height:34px;font-size:10px}
  .hand .card{width:30px;height:42px;font-size:12px}
  .table{grid-template-columns:1fr 1.05fr 1fr;min-height:205px}
  .zone{min-height:62px}
  .actions button{font-size:13px;padding:10px 2px}
  .selinfo{font-size:11px}
}

/* ---------- 横屏手机：改为左牌桌 / 右手牌+按钮 的左右分栏，一屏看全 ---------- */
/* 横屏判定放宽到 max-height:640 / max-width:1400：
   Edge 桌面版把窗口压成窄横条（如 1280×600）时，宽>高但高度不足，
   原条件（520/1100）匹配不上 → 整块出牌区掉到视口外，页面必须滚动才能点「出牌」。
   手机横屏（740×360 / 844×390 / 915×412）本就落在该区间内。 */
@media(max-height:640px) and (orientation:landscape) and (max-width:1400px){
  html,body{overflow:auto}
  body{padding-bottom:0}
  .app{display:grid;height:100vh;height:100dvh;min-height:0;
    padding:6px 8px calc(8px + env(safe-area-inset-bottom));gap:5px;
    grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
    /* 横屏：左列 = 顶栏/状态/观众/牌桌/记牌器/聊天，右列 = 出牌区（聊天在记牌器之后） */
    grid-template-rows:auto auto auto minmax(0,1fr) auto auto;
    grid-template-areas:"top top" "status status" "spect spect" "table play" "panels play" "chat play"}
  .topbar{grid-area:top;position:static;padding:4px 9px;gap:6px;flex-wrap:wrap}
  .brand{font-size:15px;flex:0 0 auto}
  .brand small{display:none}
  .lvwrap{flex:0 1 auto;min-width:150px;gap:6px}
  .lvbox{padding:2px 7px;font-size:11.5px}
  .lvbox b{font-size:15px}
  .tools{flex:1 1 auto;min-width:0;flex-wrap:wrap;gap:4px;max-width:100%}
  .tools button{flex:0 1 auto;font-size:11.5px;padding:4px 6px;white-space:nowrap;min-width:0;
    overflow:hidden;text-overflow:ellipsis}
  /* 状态栏压成一行（原来在窄屏会折成两行，占掉 70px 高度，把出牌按钮顶出屏幕）；
     同时清掉基础样式的 margin:10px 0 —— grid 行里这 20px 外边距纯属浪费，
     清掉后第 2 行高度从 53.6px 降到 33.6px，整条右栏净增 20px */
  .statusbar{grid-area:status;margin:0;padding:2px 9px;font-size:11.5px;gap:6px;
    flex-wrap:nowrap;overflow:hidden}
  .statusbar .msg,.statusbar .req{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
  .statusbar .req{flex:0 1 auto}
  /* 观众条：横屏压成一行，避免挤掉牌桌高度 */
  .spectbar{grid-area:spect;margin:0;padding:1px 9px;font-size:10.5px;gap:5px;
    flex-wrap:nowrap;overflow:hidden}
  .spectbar .lb{font-size:10.5px}
  .spectbar .sp{padding:0 6px;font-size:10px;line-height:1.5}
  .mwrap{overflow:visible}
  .table{grid-area:table;min-height:118px;padding:3px;border-width:4px;gap:2px;border-radius:12px;
    overflow:hidden}
  /* ★ 出牌区：撑满右栏（横跨 table + panels 两行）
       —— 原先 align-self:start 让白框按内容收缩成 187px，右栏下方空一大片，
          看着像「方框不全」；改为 stretch 后框体四边与左栏整列对齐、完整可见。
       框内改用纵向 flex：手牌吃掉多余高度并垂直居中，按钮固定在框底 → 留白均匀不拥挤。 */
  .playarea{grid-area:play;position:static;align-self:stretch;min-height:0;margin-top:0;
    overflow-y:auto;display:flex;flex-direction:column;
    border-radius:14px;border:1px solid var(--line);box-shadow:var(--shadow);padding:6px 9px 8px}
  .panels{grid-area:panels;margin-top:0;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:5px}
  /* 横屏聊天：压缩成「输入框 + 一行消息」，避免挤掉牌桌高度 */
  .chatbox{grid-area:chat;margin-top:0;padding:3px 7px 5px;display:flex;flex-direction:column;gap:3px}
  .chatbox h3{font-size:11px;margin-bottom:0}
  .chatbox h3 .hint{display:none}
  .chatbox .quick{display:none}
  .chatbox .chatrow{margin-top:0;gap:5px}
  .chatbox .chatrow input{padding:4px 8px;font-size:12px}
  .chatbox .chatrow button{padding:4px 10px;font-size:12px}
  .chatbox .chatlog{height:34px;font-size:10.5px;padding:4px 7px}
  .cardpanel{padding:3px 7px}
  .cardpanel h3{font-size:11.5px;margin-bottom:2px}
  /* 日志高度取「行高整数倍」，避免最后一行被切成半行 */
  .log{max-height:40px;font-size:10px;line-height:1.5;padding:5px 8px}
  .memrow{gap:3px}
  /* 左栏较窄 → 记牌器改为换行显示，避免条目被横向截断看不见 */
  .memrow{flex-wrap:wrap;overflow-x:visible;font-size:10px;gap:3px}
  .memrow span{padding:0 5px}
  /* 三个座位行（北 / 中 / 南）要塞进 ~120px 的牌桌高度 → 每个压到 32px */
  .zone{min-height:30px;padding:8px 4px 1px;border-radius:8px}
  .zone .cards .card.sm{width:18px;height:25px;font-size:8px;border-radius:3px}
  .zone .cards{gap:2px}
  .zhead{padding:1px 4px;font-size:10px}
  .center .big{font-size:12.5px}
  .center .small{font-size:10px}
  .zone .cards .card.sm{width:20px;height:28px;font-size:8.5px}
  /* 手牌：吃掉框内剩余高度（flex:1）+ 行垂直居中（align-content:center），
     牌阵不再挤在上半段；牌面略放大，横屏点选更好按 */
  .hand{flex:1 1 auto;min-height:0;flex-wrap:wrap;align-content:center;align-content:safe center;
    justify-content:center;gap:4px 3px;padding:12px 2px 6px;overflow:visible}
  .hand .card{width:25px;height:34px;font-size:10.5px;border-radius:5px}
  .hand .card.sel{transform:translateY(-6px)}
  .selinfo{flex:0 0 auto;min-height:0;font-size:10.5px;line-height:1.35;margin-bottom:2px}
  .wildpick{flex:0 0 auto;margin-top:4px}
  .actions{flex:0 0 auto;gap:6px;margin-top:6px}
  .actions button{padding:8px 6px;font-size:13px}
  /* 报牌徽标：横屏座位行只有 22px 高，徽标必须再收一档，
     否则会占掉整行 84% 的高度，与其它座位不协调。
     ★ 且必须靠右摆放（right 而非 left）：徽标是绝对定位在座位框左下，
       座位名「南 · 你」也在左上，两者会重叠 —— 改前的大徽标甚至完全盖住了座位名。
       靠右后与右上角的张数「N 张」分列两侧，互不遮挡。 */
  .pcard.reported{font-size:9px;padding:0 5px;bottom:1px;left:auto;right:5px;
    box-shadow:0 1px 4px rgba(220,38,38,.45)}
  .actions .more{display:none}
}
/* ---------- 横屏 + 极矮视口（如 740×300 被地址栏挤剩的窄条） ----------
   牌桌与面板原本的固定高度会把两列都顶出视口（table min-height 118 + 面板 109 > 可用高度），
   导致出牌区底部被裁、南座位也越出牌桌底。
   对策：① 记牌器限高并内部滚动，把第 4 行（panels）从 106px 压到 ~55px，
        腾出的高度还给第 3 行的牌桌；② 牌桌中排允许收缩（minmax(0,1fr)），
        保证北/南座位永远在牌桌边界内。 */
@media(max-height:400px) and (orientation:landscape) and (max-width:1400px){
  .app{padding:4px 6px calc(5px + env(safe-area-inset-bottom));gap:4px}
  .topbar{padding:3px 7px}
  .statusbar{padding:1px 7px;font-size:11px}
  .table{min-height:0;grid-template-rows:auto minmax(0,1fr) auto}
  .zone{min-height:22px;padding:6px 3px 1px}
  /* 极矮横屏：座位行仅 22px 高，垂直空间不足以「标题行 + 徽标」各占一层。
     把两者行高同时压到 1.15 并让徽标贴底 → 标题行占 0~10.9px、徽标占 12.8~22px，
     上下错开，互不遮挡（改前徽标大到直接盖住座位名）。 */
  .zhead{font-size:9.5px;padding:0 3px;line-height:1.15}
  .pcard.reported{font-size:8px;padding:0 4px;bottom:0;left:auto;right:4px;line-height:1.15}
  .center .big{font-size:11.5px}
  .center .small{font-size:9px}
  .panels{gap:4px}
  .log{max-height:32px;font-size:9.5px;line-height:1.5;padding:4px 6px}
  /* 记牌器限高 + 内部滚动：避免它把牌桌行挤扁 */
  .memrow{font-size:9.5px;max-height:32px;overflow-y:auto}
  .playarea{padding:5px 7px 6px}
  .hand .card{width:23px;height:31px;font-size:10px}
  .hand{padding:8px 2px 4px}
  .actions button{padding:6px 5px;font-size:12px}
}
/* =====================================================================
   联机版新增样式（大厅 / 座位面板 / 聊天框 / 连接状态 / 进贡提示）
   基础版式沿用单机版 v4.0，此处只做增量，不改动上面的既有规则。
   ===================================================================== */

/* ---------- 连接状态徽标 ---------- */
.conn{display:inline-flex;align-items:center;gap:5px;font-size:12px;padding:1px 9px;border-radius:99px;
  border:1px solid var(--line);background:#f1f5f9;color:var(--muted)}
.conn i{width:7px;height:7px;border-radius:50%;background:#94a3b8;display:inline-block;flex:0 0 auto}
.conn.ok{background:#ecfdf5;border-color:#a7f3d0;color:#047857}
.conn.ok i{background:#22c55e;box-shadow:0 0 0 3px rgba(34,197,94,.18)}
.conn.wait{background:#fffbeb;border-color:#fcd9a8;color:#b45309}
.conn.wait i{background:#f59e0b;animation:blink 1s infinite}
.conn.bad{background:#fff1f2;border-color:#fecdd3;color:#be123c}
.conn.bad i{background:#ef4444}
@keyframes blink{0%,100%{opacity:1}50%{opacity:.25}}

/* ---------- 大厅遮罩 ---------- */
.lobby{position:fixed;inset:0;z-index:80;background:rgba(15,23,42,.55);
  -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);
  display:flex;align-items:center;justify-content:center;padding:14px;overflow:auto}
.lobby-box{background:#fff;border-radius:16px;max-width:880px;width:100%;max-height:94vh;overflow:auto;
  padding:18px 22px 20px;box-shadow:0 20px 50px rgba(0,0,0,.32)}
.lobby-box h2{font-size:20px;margin-bottom:2px}
.lobby-box .sub{color:var(--muted);font-size:13px;margin-bottom:12px}
.lrow{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin:8px 0}
.lrow input[type=text]{font-family:inherit;font-size:14px;padding:7px 10px;border:1px solid var(--line);
  border-radius:9px;background:#f8fafc;color:var(--ink);min-width:0}
.invitebox{display:flex;gap:8px;flex-wrap:wrap;align-items:center;background:#eff6ff;border:1px solid #bfdbfe;
  border-radius:10px;padding:9px 12px;margin:10px 0}
.invitebox code{flex:1 1 260px;min-width:0;word-break:break-all;font-size:13px;color:#1d4ed8;
  font-family:ui-monospace,Consolas,Menlo,monospace;background:#fff;padding:5px 9px;border-radius:7px;border:1px solid #dbeafe}
/* ---------- 座位网格 ---------- */
/* 四张座位卡：加粗描边 + 顶部队伍色条 + 更大留白，一眼能分清座位与状态 */
.seats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin:14px 0 6px}
.seat{position:relative;display:flex;flex-direction:column;gap:7px;
  min-height:154px;padding:13px 14px 12px;border-radius:15px;
  border:2px solid #e2e8f0;border-top:5px solid #cbd5e1;background:#fff;
  box-shadow:0 3px 10px rgba(15,23,42,.07);
  transition:transform .16s,box-shadow .16s,border-color .16s}
.seat:hover{transform:translateY(-2px);box-shadow:0 12px 24px rgba(15,23,42,.13)}
/* 座位 0/2 为队伍①（蓝），1/3 为队伍②（红）——与右上角标签同色 */
.seat:nth-child(odd){border-top-color:#3b82f6}
.seat:nth-child(even){border-top-color:#f87171}
.seat.self{border-color:var(--blue);background:linear-gradient(180deg,#eff6ff,#fff);
  box-shadow:0 0 0 3px rgba(37,99,235,.16),0 8px 20px rgba(37,99,235,.14)}
.seat.empty{border-style:dashed;border-top-style:solid;background:#fbfcfe;box-shadow:none}
.seat.empty:hover{box-shadow:0 8px 18px rgba(15,23,42,.09)}
.seat.empty .sname{color:#94a3b8;font-weight:700}
.seat .sno{display:flex;align-items:center;gap:7px;font-size:12.5px;color:#475569;font-weight:700;
  /* 右上角「队伍①/②」是绝对定位，会盖住这行文字：右侧留出它的宽度 + 6px 间隙 */
  padding-right:60px;white-space:nowrap;overflow:hidden}
.seat .sno span{overflow:hidden;text-overflow:ellipsis;min-width:0}
.seat .sno b{display:inline-flex;align-items:center;justify-content:center;width:25px;height:25px;
  border-radius:8px;background:#0f172a;color:#fff;font-size:13px;font-weight:800;letter-spacing:0}
.seat:nth-child(odd) .sno b{background:#1d4ed8}
.seat:nth-child(even) .sno b{background:#b91c1c}
.seat .sname{font-size:17px;font-weight:800;line-height:1.3;word-break:break-all;color:#0f172a}
.seat .sops{display:flex;gap:6px;flex-wrap:wrap;align-items:center;margin-top:auto}
.seat .sops button{font-size:12.5px;padding:6px 12px;border-radius:9px;font-weight:700}
/* 「坐下」用主色实心，是这张卡最该点的动作 */
.seat .sops button[data-act="sit"]{background:linear-gradient(180deg,#1a7a4a,#0f5132);
  border-color:#0b3d26;color:#fff;box-shadow:0 2px 8px rgba(15,81,50,.26)}
.seat .sops button[data-act="sit"]:hover{background:linear-gradient(180deg,#1e8f57,#12603c)}
.seat .sops select{font-size:12px;padding:4px 6px;border-radius:8px;border:1px solid #cfd8e3;background:#fff}
.seat .teamtag{position:absolute;right:10px;top:10px;font-size:11.5px;font-weight:800;
  padding:1px 9px;border-radius:99px;background:#f1f5f9;border:1px solid var(--line);color:#475569}
.seat:nth-child(odd) .teamtag{background:#eff6ff;border-color:#bfdbfe;color:#1d4ed8}
.seat:nth-child(even) .teamtag{background:#fff1f2;border-color:#fecdd3;color:#be123c}
.badge{display:inline-block;font-size:11.5px;padding:2px 10px;border-radius:99px;border:1px solid var(--line);
  background:#f1f5f9;color:var(--muted);font-weight:700;white-space:nowrap}
.badge.ai{background:#fef2f2;border-color:#fecaca;color:#b91c1c}
.badge.human{background:#ecfdf5;border-color:#a7f3d0;color:#047857}
.badge.off{background:#fff7ed;border-color:#fed7aa;color:#c2410c}
.badge.take{background:#eff6ff;border-color:#bfdbfe;color:#1d4ed8}
.badge.you{background:#eef2ff;border-color:#c7d2fe;color:#4338ca}
@media(max-width:820px){
  .seats{grid-template-columns:repeat(2,minmax(0,1fr));gap:9px}
  .seat{min-height:136px;padding:11px 11px 10px;border-radius:13px}
  .seat .sname{font-size:15.5px}
  /* 手机上「队伍①/②」与 sno 里的「南北队/东西队」信息重复，且卡片仅约 142px 宽，
     它与 sno 抢同一行必然压字 → 窄屏隐藏（队伍仍由卡片顶部色条 + sno 文字体现） */
  .seat .teamtag{display:none}
  .seat .sno{padding-right:0;font-size:12px}
  .seat .sops button{font-size:12px;padding:6px 10px}
  .lobby{padding:0;align-items:flex-end}
  .lobby-box{max-width:none;border-radius:16px 16px 0 0;max-height:92vh;padding:14px 13px 18px}
}

/* ---------- 聊天框（页面下部） ---------- */
.chatbox{margin-top:10px;background:var(--panel);border:1px solid var(--line);border-radius:14px;
  padding:9px 12px 11px;box-shadow:var(--shadow)}
.chatbox h3{font-size:13px;color:var(--muted);font-weight:700;margin-bottom:5px;letter-spacing:.5px;
  display:flex;align-items:center;gap:8px}
.chatbox h3 .hint{font-weight:400;font-size:11.5px;color:#94a3b8}
.chatlog{height:132px;overflow-y:auto;background:#f8fafc;border:1px solid var(--line);
  border-radius:10px;padding:7px 10px;font-size:13px;line-height:1.65;margin-top:7px;
  -webkit-overflow-scrolling:touch;overscroll-behavior:contain}
.chatlog .cm{margin:2px 0;word-break:break-word}
.chatlog .cm b{color:var(--blue)}
.chatlog .cm.sys{color:#b45309;font-style:italic}
.chatlog .cm.mine b{color:#047857}
.chatrow{display:flex;gap:7px;margin-top:7px}
.chatrow input{flex:1 1 auto;min-width:0;font-family:inherit;font-size:14px;padding:8px 11px;
  border:1px solid var(--line);border-radius:9px;background:#fff;color:var(--ink)}
.chatrow button{flex:0 0 auto;padding:8px 18px}
.quick{display:flex;gap:5px;flex-wrap:wrap;margin-top:6px}
.quick button{font-size:11.5px;padding:3px 9px;border-radius:99px;background:#f8fafc}
@media(max-width:820px){
  .chatlog{height:104px;font-size:12.5px}
}

/* ---------- 进贡 / 还贡 选牌提示 ---------- */
.tribbar{background:#fffbeb;border:1px solid #fcd9a8;border-radius:11px;padding:9px 13px;margin:8px 0;font-size:13.5px}
.tribbar b{color:#7c2d12}
.tribbar .cands{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px}
.tribbar .cands button{padding:3px 10px;font-size:12.5px;border-color:#f59e0b;background:#fff;color:#92400e}

/* ---------- 结算条 ---------- */
.resline{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-top:8px}

/* ---------- 桌面字幕（进贡动画）沿用单机版 ---------- */
.fxskip{position:absolute;right:8px;top:8px;z-index:34;font-size:12px;padding:4px 11px;border-radius:9px;
  background:rgba(10,22,16,.82);color:#ffe9a8;border:1px solid rgba(240,193,75,.5)}

/* ---------- 观众席（大厅内可主动选择） ---------- */
.specbox{border:1px dashed var(--line);border-radius:12px;padding:9px 12px 10px;background:#fff;margin:10px 0 2px}
.spechead{font-size:12.5px;font-weight:700;color:var(--muted);letter-spacing:.5px;margin-bottom:6px}
.spechead .hint,.specops .hint{font-weight:400;color:#94a3b8;font-size:11.5px}
.specops{display:flex;gap:7px;flex-wrap:wrap;align-items:center}
.specops button{font-size:12.5px;padding:5px 12px}
.speclist{font-size:12.5px;color:#475569;margin-top:6px;line-height:1.6;min-height:18px}
.speclist .sp{display:inline-block;background:#f8fafc;border:1px solid var(--line);border-radius:99px;
  padding:1px 10px;margin:2px 5px 2px 0}
.speclist .sp.me{background:#eef2ff;border-color:#c7d2fe;color:#4338ca;font-weight:700}
.speclist .sp.off{opacity:.55}
.speclist .none{color:#94a3b8}
@media(max-width:820px){
  .specbox{padding:8px 10px 9px}
  .specops button{flex:1 1 auto}
}

/* ---------- 大厅：「进入牌桌」按钮（醒目但不占地方） ---------- */
/* 右上角 X：面板较高需滚动时也能随时关掉 */
.lobby-box{position:relative}
.lobby-x{position:absolute;right:9px;top:9px;width:30px;height:30px;padding:0;border-radius:50%;
  font-size:15px;line-height:28px;text-align:center;background:#f1f5f9;border:1px solid var(--line);
  color:#475569;cursor:pointer;z-index:3}
.lobby-x:hover{background:#e2e8f0;color:#0f172a}
.lobby-x:active{transform:scale(.94)}
/* 紧凑版：浅绿底 + 深绿字 + 细描边，尺寸与「开始游戏」同级，但颜色一眼可辨 */
button.enter-sm{font-size:13.5px;font-weight:800;letter-spacing:.5px;padding:7px 14px;
  border-radius:9px;color:#065f46;border:1px solid #6ee7b7;
  background:linear-gradient(180deg,#ecfdf5,#d1fae5);
  box-shadow:0 2px 6px rgba(16,185,129,.22),inset 0 1px 0 rgba(255,255,255,.8)}
button.enter-sm:hover:not(:disabled){background:linear-gradient(180deg,#d1fae5,#a7f3d0);
  border-color:#34d399;transform:translateY(-1px)}
button.enter-sm:active{transform:translateY(0)}
@media(prefers-reduced-motion:reduce){ button.enter-sm{transition:none} }


/* ---------- 大厅：本机身份行（清除记录 / 退出房间） ---------- */
.idrow{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:4px 0 12px;
  font-size:12px;color:#94a3b8}
.idrow .idtext{line-height:1.5}
.idrow .idtext b{color:#64748b}
/* 这两颗按钮要能一眼看见、好点按（原来 11.5px / 3px 内边距太小） */
.idrow .mini{font-size:13.5px;font-weight:700;padding:8px 16px;border-radius:10px;
  background:#fff;border:1.5px solid #cfd8e3;color:#334155;
  box-shadow:0 2px 6px rgba(15,23,42,.08);
  white-space:nowrap;       /* 「退出房间（让出座位）」在窄屏会被挤成两行，这里禁止换行 */
  flex:0 0 auto}
.idrow .mini:hover:not(:disabled){background:#f1f5f9;border-color:#94a3b8;
  transform:translateY(-1px);box-shadow:0 5px 12px rgba(15,23,42,.12)}
.idrow .mini:active{transform:translateY(0);box-shadow:inset 0 1px 3px rgba(15,23,42,.14)}
.idrow .mini.danger{color:#b91c1c;border-color:#fca5a5;background:#fff5f5}
.idrow .mini.danger:hover:not(:disabled){background:#ffe4e6;border-color:#f87171}
@media(max-width:820px){
  .idrow{flex-wrap:wrap;gap:8px}
  .idrow .idtext{flex:1 1 100%}
  /* 不再等分：等分会把长文案挤换行；按内容宽度排，两颗并排刚好放得下 */
  .idrow .mini{flex:0 0 auto;font-size:12.5px;padding:9px 11px;letter-spacing:0}
}
@media(max-width:360px){
  .idrow .mini{font-size:11.5px;padding:8px 8px}
}

/* ---------- 等待开局（等所有人进房间） ---------- */
.waitnote{background:#eff6ff;border:1px solid #bfdbfe;border-left:4px solid var(--blue);
  border-radius:10px;padding:9px 13px;margin:8px 0 4px;font-size:13px;color:#1e3a8a;line-height:1.6}
.waitnote b{color:#1d4ed8}
.waitnote .cnt{display:inline-block;min-width:2.4em;text-align:center;font-weight:800;
  font-size:15px;color:#1d4ed8;background:#fff;border:1px solid #bfdbfe;border-radius:7px;padding:0 7px;margin:0 2px}
.waitnote .seats{margin-top:4px;font-size:12.5px;color:#475569}
.waitnote .seats i{font-style:normal;background:#fff;border:1px solid #dbeafe;border-radius:99px;
  padding:0 9px;margin-right:5px;color:#1d4ed8}

/* ---------- 「邀请链接已失效」覆盖页：必须盖住大厅，且不提供关闭入口 ---------- */
.mask.stale-mask{z-index:95}
.mask.stale-mask .modal{max-width:460px;animation:staleIn .18s ease-out}
@keyframes staleIn{from{transform:translateY(8px);opacity:.6}to{transform:none;opacity:1}}
