/* ===========================================================================
   扫雷 · 联机 Web 版   style.css
   =========================================================================== */

:root{
  --bg:#060911;
  --panel:rgba(18,26,44,.62);
  --panel-solid:#0c1424;
  --line:rgba(140,170,220,.14);
  --line-strong:rgba(140,170,220,.28);
  --text:#e9eefc;
  --text-2:#9aa9c6;
  --text-3:#8494ad;   /* 深底上 ≥4.5:1（WCAG AA），原 #67748f 只有 4.24:1 */
  --cyan:#22d3ee;
  --violet:#8b5cf6;
  --amber:#fbbf24;
  --rose:#fb7185;
  --green:#34d399;
  --n1:#60a5fa; --n2:#34d399; --n3:#fb7185; --n4:#a78bfa;
  --n5:#fbbf24; --n6:#22d3ee; --n7:#e2e8f0; --n8:#94a3b8;
  --r-sm:9px; --r:14px; --r-lg:20px; --r-xl:28px;
  --t-fast:120ms; --t:200ms; --t-slow:380ms;
  --ease:cubic-bezier(.2,.8,.2,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --mono:ui-monospace,SFMono-Regular,"Cascadia Mono",Menlo,Consolas,"Liberation Mono",monospace;
  --sans:system-ui,-apple-system,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
}

*{box-sizing:border-box}
[hidden]{display:none !important}
html,body{height:100%}
body{
  margin:0;background:var(--bg);color:var(--text);font-family:var(--sans);
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
button,input{font:inherit;color:inherit}
a{color:var(--cyan);text-decoration-color:rgba(34,211,238,.45);text-underline-offset:3px}
a:hover{color:#67e8f9}
button{cursor:pointer;border:0;background:none}
h1,h2,h3{margin:0;font-weight:700;letter-spacing:-.01em}
ul{margin:0;padding-left:1.15em}
::selection{background:rgba(34,211,238,.3)}

/* ---------- 背景 ---------- */
.bg{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
#stars{position:absolute;inset:0;width:100%;height:100%;opacity:.55}
.glow{position:absolute;border-radius:50%;filter:blur(90px);opacity:.5}
.g1{width:52vw;height:52vw;left:-14vw;top:-18vw;background:radial-gradient(circle,rgba(34,211,238,.34),transparent 66%)}
.g2{width:56vw;height:56vw;right:-18vw;bottom:-24vw;background:radial-gradient(circle,rgba(139,92,246,.32),transparent 66%)}
.grain{position:absolute;inset:0;opacity:.035;mix-blend-mode:overlay;
  background-image:radial-gradient(rgba(255,255,255,.9) 1px,transparent 1px);background-size:3px 3px}

/* ---------- 共享锚点 A1 星图网格层 / A2 扫描光带 ---------- */
.ms-layer{position:fixed;inset:0;z-index:1;pointer-events:none;overflow:hidden}
#msGrid{position:absolute;inset:-12%;--grid-gap:22px;--grid-alpha:.14;
  background-image:
    linear-gradient(to right,rgba(140,180,230,var(--grid-alpha)) 1px,transparent 1px),
    linear-gradient(to bottom,rgba(140,180,230,var(--grid-alpha)) 1px,transparent 1px),
    radial-gradient(rgba(190,220,255,var(--grid-alpha)) 1px,transparent 1px);
  background-size:var(--grid-gap) var(--grid-gap),var(--grid-gap) var(--grid-gap),
                  calc(var(--grid-gap) * 2) calc(var(--grid-gap) * 2);
  -webkit-mask-image:radial-gradient(ellipse at 50% 38%,#000 18%,transparent 76%);
  mask-image:radial-gradient(ellipse at 50% 38%,#000 18%,transparent 76%);
  will-change:transform,opacity}
#msScanline{position:absolute;top:-10%;bottom:-10%;left:0;width:34vw;opacity:0;
  background:linear-gradient(90deg,transparent,rgba(34,211,238,.10) 42%,rgba(34,211,238,.44) 50%,rgba(34,211,238,.10) 58%,transparent);
  mix-blend-mode:screen;will-change:transform,opacity}


/* ---------- 顶栏 ---------- */
.topbar{
  position:relative;z-index:5;display:flex;align-items:center;justify-content:space-between;
  gap:16px;padding:14px clamp(14px,3vw,34px);max-width:1560px;margin:0 auto;
}
.brand{display:flex;align-items:center;gap:10px;font-size:16px;letter-spacing:.01em}
.brand .brand-name{font-size:16px;font-weight:600;margin:0;line-height:1.2}
.logo{width:26px;height:26px;border-radius:9px;position:relative;
  background:linear-gradient(150deg,var(--cyan),var(--violet));
  box-shadow:0 0 22px rgba(34,211,238,.45)}
.logo::after{content:"";position:absolute;inset:8px;border-radius:50%;background:#060911;opacity:.85}
.brand-name em{font-style:normal;color:var(--text-3);font-weight:600}
.top-actions{display:flex;align-items:center;gap:8px}
.icon-btn{width:36px;height:36px;border-radius:11px;border:1px solid var(--line);
  background:rgba(255,255,255,.03);color:var(--text-2);font-size:15px;
  display:grid;place-items:center;transition:all var(--t) var(--ease)}
.icon-btn:hover{border-color:var(--line-strong);color:var(--text);background:rgba(255,255,255,.06)}
.icon-btn.is-off{color:var(--text-3);text-decoration:line-through}
.icon-btn.is-on{color:var(--cyan);border-color:rgba(34,211,238,.4)}
.conn{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--text-3);
  padding:7px 12px;border-radius:999px;border:1px solid var(--line);background:rgba(255,255,255,.02)}
.conn i{width:7px;height:7px;border-radius:50%;background:var(--text-3);transition:all var(--t)}
.conn[data-state="on"]{color:var(--green);border-color:rgba(52,211,153,.3)}
.conn[data-state="on"] i{background:var(--green);box-shadow:0 0 10px var(--green)}
.conn[data-state="wait"]{color:var(--amber);border-color:rgba(251,191,36,.3)}
.conn[data-state="wait"] i{background:var(--amber);box-shadow:0 0 10px var(--amber);animation:pulse 1.1s infinite}
.conn[data-state="off"]{color:var(--rose);border-color:rgba(251,113,133,.32)}
.conn[data-state="off"] i{background:var(--rose)}
@keyframes pulse{50%{opacity:.25}}

/* ---------- 视图容器 ---------- */
main{position:relative;z-index:2;max-width:1560px;margin:0 auto;padding:0 clamp(14px,3vw,34px) 40px}
.view{display:none}
.view.is-active{display:block;animation:fadeUp var(--t-slow) var(--ease-out)}
@keyframes fadeUp{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* ---------- 首页 ---------- */
.hero{max-width:660px;margin:clamp(8px,4vh,44px) 0 26px}
.eyebrow{font-size:12.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--cyan);
  margin:0 0 12px;font-weight:600;opacity:.9}
.hero .hero-title{font-size:clamp(38px,6vw,68px);line-height:1.02;letter-spacing:-.035em;margin:0;color:#fff}
/* 渐变文字：background-clip:text 必须挂在「直接包含文字的叶子元素」上。
   挂到父元素 + inline-block 子元素时，子元素会继承 color:transparent 而没有背景 → 整段文字变成全透明
   （axe 与对比度探针都会跳过 transparent，属于检测盲区，所以另配 ink 探针，见 test/axe-scan.mjs）。 */
.hero .hero-title .hero-line{display:inline-block;
  background:linear-gradient(120deg,#fff 22%,#a5f3fc 52%,#c4b5fd 84%);
  -webkit-background-clip:text;background-clip:text;
  color:transparent;-webkit-text-fill-color:transparent}
.hero .hero-title .dot{color:var(--cyan);-webkit-text-fill-color:var(--cyan)}
.hero .sub{margin:16px 0 0;color:var(--text-2);font-size:15px;line-height:1.75;max-width:56ch}

.nick-row{display:flex;align-items:center;gap:14px;margin:0 0 18px;flex-wrap:wrap}
.nick-row label{font-size:13px;color:var(--text-3);letter-spacing:.04em}
.nick-row input{width:min(260px,60vw);padding:11px 14px;border-radius:var(--r-sm);
  border:1px solid var(--line);background:rgba(255,255,255,.035);outline:none;
  transition:border-color var(--t),box-shadow var(--t)}
.nick-row input:focus{border-color:rgba(34,211,238,.55);box-shadow:0 0 0 3px rgba(34,211,238,.12)}

.home-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:18px;align-items:start}
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:22px;backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
  box-shadow:0 22px 50px -30px rgba(0,0,0,.9)}
.card-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:18px}
.card-head h2{font-size:18px}
.tag{font-size:11.5px;color:var(--text-3);border:1px solid var(--line);padding:4px 9px;border-radius:999px}

.opt-row{display:flex;gap:12px;align-items:flex-start;margin-bottom:14px}
.opt-label{font-size:12.5px;color:var(--text-3);min-width:42px;padding-top:8px;letter-spacing:.04em}
.chips{display:flex;gap:7px;flex-wrap:wrap}
.chip{padding:7px 13px;border-radius:999px;border:1px solid var(--line);
  background:rgba(255,255,255,.025);color:var(--text-2);font-size:13px;
  transition:all var(--t) var(--ease)}
.chip:hover{border-color:var(--line-strong);color:var(--text);transform:translateY(-1px)}
.chip.is-on{background:linear-gradient(140deg,rgba(34,211,238,.22),rgba(139,92,246,.22));
  border-color:rgba(34,211,238,.5);color:#fff;box-shadow:0 0 0 1px rgba(34,211,238,.16)}
.chip[disabled]{opacity:.4;cursor:not-allowed;transform:none}

.custom-box{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:0 0 14px;}
.custom-box[hidden]{display:none}
.custom-box label{display:flex;flex-direction:column;gap:6px;font-size:12px;color:var(--text-3)}
.custom-box input{padding:9px 11px;border-radius:var(--r-sm);border:1px solid var(--line);
  background:rgba(255,255,255,.035);outline:none}
.custom-box input:focus{border-color:rgba(34,211,238,.5)}

.switches{display:flex;gap:16px;flex-wrap:wrap;padding-top:4px}
.switch{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-size:13px;color:var(--text-2)}
.switch input{position:absolute;opacity:0;width:0;height:0}
.switch i{width:36px;height:20px;border-radius:999px;background:rgba(255,255,255,.09);
  position:relative;transition:background var(--t);flex:none}
.switch i::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;
  background:#cbd5e1;transition:transform var(--t) var(--ease)}
.switch input:checked + i{background:linear-gradient(120deg,var(--cyan),var(--violet))}
.switch input:checked + i::after{transform:translateX(16px);background:#fff}
.switch input:focus-visible + i{box-shadow:0 0 0 3px rgba(34,211,238,.25)}

.code-label{display:block;font-size:12px;color:var(--text-3);margin-bottom:9px;letter-spacing:.06em}
.code-input{width:100%;padding:16px;border-radius:var(--r);border:1px solid var(--line);
  background:rgba(255,255,255,.035);outline:none;text-align:center;
  font-family:var(--mono);font-size:30px;letter-spacing:.42em;text-indent:.42em;
  text-transform:uppercase;margin-bottom:14px;transition:border-color var(--t),box-shadow var(--t)}
.code-input:focus{border-color:rgba(34,211,238,.55);box-shadow:0 0 0 3px rgba(34,211,238,.12)}
.code-input.is-complete{border-color:rgba(34,211,238,.6);box-shadow:0 0 0 3px rgba(34,211,238,.14)}
.code-hint{margin:-6px 0 12px;font-size:11.5px;color:var(--text-3)}
.btn.is-ready{box-shadow:0 0 0 1px rgba(34,211,238,.45),0 12px 34px -14px rgba(34,211,238,.8)}
.lan-box{margin-top:16px;padding-top:16px;border-top:1px solid var(--line);font-size:12.5px;color:var(--text-3);line-height:1.8}
.lan-box b{color:var(--text-2);font-weight:600}
.lan-box code{font-family:var(--mono);color:var(--cyan);font-size:12.5px;word-break:break-all}

/* ---------- 内网联机面板（协议 v3 §3/§4） ---------- */
/* 公网版 / 发现未开启：卡片收成一行说明，不放列表与空态大块留白 */
/* 比正常卡片更轻：更小字号 + 更弱颜色，一眼看出公网版这里没内容 */
.lan-compact{margin:0;font-size:12px;color:var(--text-3);line-height:1.8;letter-spacing:.01em}
.lan-self{margin:0 0 14px;font-size:12.5px;color:var(--text-3);line-height:1.7;word-break:break-all}
.lan-self b{color:var(--text-2);font-weight:600}
.lan-group{margin-bottom:13px}
.lan-group-head{display:flex;align-items:center;justify-content:space-between;gap:8px;
  font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--text-3);margin-bottom:7px}
.lan-count{font-family:var(--mono);font-size:11.5px;color:var(--text-2)}
.lan-list{display:flex;flex-direction:column;gap:6px}
.lan-item{display:flex;align-items:center;gap:10px;width:100%;min-width:0;text-align:left;
  padding:9px 11px;border-radius:var(--r-sm);border:1px solid var(--line);
  background:rgba(255,255,255,.028);color:var(--text);font-size:13px;
  transition:all var(--t) var(--ease)}
.lan-item.is-static{cursor:default;opacity:.6}
.lan-item:not(.is-static):hover{border-color:var(--line-strong);background:rgba(255,255,255,.07);transform:translateY(-1px)}
.lan-code{font-family:var(--mono);font-size:13.5px;font-weight:700;letter-spacing:.14em;color:var(--cyan);flex:none}
.lan-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600}
.lan-meta{flex:none;font-size:11.5px;color:var(--text-3);font-family:var(--mono)}
.lan-dot{width:7px;height:7px;border-radius:50%;flex:none;background:var(--green);box-shadow:0 0 8px rgba(52,211,153,.7)}
.lan-dot.warn{background:var(--amber);box-shadow:0 0 8px rgba(251,191,36,.6)}
.lan-status{margin:12px 0 0;padding-top:12px;border-top:1px solid var(--line);
  font-size:12px;color:var(--text-3);line-height:1.7}
.lan-empty{margin:0;padding:9px 11px;border-radius:var(--r-sm);border:1px dashed var(--line);
  font-size:12px;color:var(--text-3);line-height:1.6}
.hint{margin:12px 0 0;font-size:12px;color:var(--text-3);line-height:1.7}

/* ---------- 按钮 ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:11px 18px;border-radius:var(--r-sm);border:1px solid var(--line);
  background:rgba(255,255,255,.035);color:var(--text);font-size:14px;font-weight:600;
  transition:all var(--t) var(--ease);white-space:nowrap}
.btn:hover{border-color:var(--line-strong);background:rgba(255,255,255,.075);transform:translateY(-1px)}
.btn:active{transform:translateY(0)}
.btn[disabled]{opacity:.35;cursor:not-allowed;transform:none;box-shadow:none}
.btn-primary{background:linear-gradient(135deg,var(--cyan),#a78bfa);border-color:transparent;color:#04121a}   /* 紫色端用浅一档：原 --violet 与深色文字仅 ~4.5:1 */
.btn-primary:hover{box-shadow:0 10px 30px -12px rgba(34,211,238,.7);filter:brightness(1.06)}
.btn-ghost{background:transparent}
.btn-sm{padding:7px 12px;font-size:12.5px}
.btn-lg{width:100%;padding:14px 20px;font-size:15px;margin-top:6px;border-radius:var(--r)}
.btn-flag.is-on{background:linear-gradient(135deg,rgba(251,191,36,.9),rgba(251,113,133,.9));
  border-color:transparent;color:#2a1503}
.danger{color:var(--rose);border-color:rgba(251,113,133,.28)}
.danger:hover{background:rgba(251,113,133,.1)}
/* 快速开始：与「创建房间」并列的次一级主按钮（同一套渐变语言，弱一档） */
.btn-quick{margin-top:8px;border-color:rgba(34,211,238,.34);
  background:linear-gradient(135deg,rgba(34,211,238,.15),rgba(139,92,246,.15))}
.btn-quick:hover{border-color:rgba(34,211,238,.62);background:linear-gradient(135deg,rgba(34,211,238,.22),rgba(139,92,246,.22))}
/* 「以观众身份进入」：沿用 .switch 的滑块，改成整行可点 */
.switch-block{display:flex;width:100%;margin:0 0 12px;padding:10px 12px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:rgba(255,255,255,.025);
  transition:border-color var(--t) var(--ease),background var(--t) var(--ease)}
.switch-block:hover{border-color:var(--line-strong);background:rgba(255,255,255,.05)}

/* ---------- 对局布局 ---------- */
.view-table.is-active{display:block}
.table-layout{display:grid;grid-template-columns:minmax(230px,270px) minmax(0,1fr) minmax(274px,330px);
  gap:16px;align-items:start}
.panel{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);
  backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);overflow:hidden;
  box-shadow:0 22px 50px -32px rgba(0,0,0,.9)}
.panel-head{display:flex;align-items:center;justify-content:space-between;
  padding:14px 16px;border-bottom:1px solid var(--line)}
.panel-head h2,.panel-head h3{font-size:13px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3);font-weight:600;margin:0}
.count{font-family:var(--mono);font-size:12px;color:var(--text-2)}

/* 玩家列表 */
.player-list{padding:10px;display:flex;flex-direction:column;gap:8px;max-height:44vh;overflow-y:auto}
.pcard{display:grid;grid-template-columns:auto 1fr auto;gap:10px;align-items:center;
  padding:10px 11px;border-radius:var(--r);border:1px solid transparent;
  background:rgba(255,255,255,.028);position:relative;transition:all var(--t) var(--ease)}
.pcard .avatar{width:30px;height:30px;border-radius:10px;display:grid;place-items:center;
  font-size:13px;font-weight:800;color:#06121c;flex:none}
.pcard .pname{font-size:13.5px;font-weight:600;display:flex;align-items:center;gap:6px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pcard .pmeta{display:flex;align-items:center;gap:8px;font-size:11.5px;color:var(--text-3);margin-top:3px}
.pcard .pscore{font-family:var(--mono);font-size:16px;font-weight:700;text-align:right}
.pcard.is-turn{border-color:rgba(34,211,238,.5);background:rgba(34,211,238,.09);
  box-shadow:0 0 0 1px rgba(34,211,238,.2),0 8px 26px -18px rgba(34,211,238,.8)}
.pcard.is-turn::before{content:"";position:absolute;left:0;top:10px;bottom:10px;width:3px;
  border-radius:0 3px 3px 0;background:var(--cyan);box-shadow:0 0 12px var(--cyan)}
.pcard.is-out{opacity:.5}
.pcard.is-out .pname{text-decoration:line-through}
.pcard.is-offline{opacity:.42}
.badge{font-size:10px;padding:2px 6px;border-radius:5px;background:rgba(255,255,255,.09);color:var(--text-2);font-weight:600}
.badge.you{background:rgba(34,211,238,.2);color:#a5f3fc}
.badge.ready{background:rgba(52,211,153,.2);color:#a7f3d0}
.badge.host{background:rgba(251,191,36,.2);color:#fde68a}
.badge.out{background:rgba(251,113,133,.2);color:#fecdd3}
.hearts{display:inline-flex;gap:3px}
.heart{width:11px;height:11px;border-radius:3px;background:rgba(255,255,255,.13)}
.heart.on{background:linear-gradient(140deg,var(--rose),#f43f5e);box-shadow:0 0 8px rgba(251,113,133,.55)}
/* 玩家 / 观众 分组（观众卡片弱化：虚线边、降低对比，仍满足 AA 对比度） */
.pgroup{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:2px 4px 0;font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3)}
.pgroup:not(:first-child){margin-top:6px;padding-top:9px;border-top:1px solid var(--line)}
.badge.spec{background:rgba(140,170,220,.18);color:var(--text-2)}
.pcard.is-spec{background:rgba(255,255,255,.014);border-style:dashed;border-color:var(--line)}
.pcard.is-spec .avatar{opacity:.62}
.pcard.is-spec .pscore{color:var(--text-3);font-size:13px;font-weight:600}
.head-counts{display:inline-flex;align-items:center;gap:9px}
.count-spec{color:var(--text-3)}

.room-meta{padding:12px 14px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:10px}
.code-block{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.code{font-family:var(--mono);font-size:24px;letter-spacing:.2em;color:var(--cyan);
  text-shadow:0 0 22px rgba(34,211,238,.55)}
.meta-btns{display:flex;flex-direction:column;gap:7px}
.room-tip{margin:0;font-size:11.5px;color:var(--text-3);line-height:1.6;word-break:break-all}

/* 舞台 */
.stage{display:flex;flex-direction:column;gap:14px;min-width:0}
.hud{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:14px 16px;backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
  display:grid;grid-template-columns:auto 1fr;gap:16px;align-items:center}
.hud-turn{display:flex;align-items:center;gap:13px}
.ring{--p:0;position:relative;width:58px;height:58px;border-radius:50%;flex:none;
  background:conic-gradient(var(--cyan) calc(var(--p) * 1%),rgba(255,255,255,.07) 0);
  display:grid;place-items:center;transition:background var(--t) linear}
.ring::before{content:"";position:absolute;inset:5px;border-radius:50%;background:#0a1020}
.ring span{position:relative;font-family:var(--mono);font-size:17px;font-weight:700}
.ring.low{background:conic-gradient(var(--rose) calc(var(--p) * 1%),rgba(255,255,255,.07) 0)}
.ring.idle{background:rgba(255,255,255,.07)}
.turn-text{display:flex;flex-direction:column;gap:3px;min-width:0}
.turn-name{font-size:15px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:26ch}
.turn-hint{font-size:12px;color:var(--text-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:34ch}
.hud-stats{display:flex;gap:22px;justify-content:flex-end;flex-wrap:wrap}
.stat{display:flex;flex-direction:column;gap:3px;align-items:flex-end}
.stat span{font-size:11px;color:var(--text-3);letter-spacing:.06em}
.stat strong{font-family:var(--mono);font-size:15px}
.progress{grid-column:1 / -1;height:4px;border-radius:99px;background:rgba(255,255,255,.07);overflow:hidden}
.progress i{display:block;height:100%;width:0;border-radius:99px;
  background:linear-gradient(90deg,var(--cyan),var(--violet));transition:width var(--t-slow) var(--ease-out)}

/* 大厅占位面板 */
.lobby-stage{background:rgba(8,13,24,.55);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:clamp(22px,5vw,54px);display:flex;flex-direction:column;align-items:center;gap:14px;
  text-align:center;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  animation:fadeUp var(--t-slow) var(--ease-out)}
.lobby-stage[hidden]{display:none}
.ls-eyebrow{margin:0;font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--cyan)}
.ls-code{display:flex;flex-direction:column;gap:6px;align-items:center}
.ls-code span{font-size:12px;color:var(--text-3);letter-spacing:.1em}
.ls-code strong{font-family:var(--mono);font-size:clamp(34px,7vw,52px);letter-spacing:.22em;
  text-indent:.22em;color:var(--cyan);text-shadow:0 0 34px rgba(34,211,238,.45);line-height:1.1}
.ls-hint{margin:0;font-size:13.5px;color:var(--text-2);line-height:1.8;max-width:44ch}
.ls-people{display:flex;gap:9px;flex-wrap:wrap;justify-content:center;margin-top:6px}
.ls-p{display:inline-flex;align-items:center;gap:7px;padding:6px 12px;border-radius:999px;
  border:1px solid var(--line);background:rgba(255,255,255,.03);font-size:12.5px;color:var(--text-2)}
.ls-p i{width:9px;height:9px;border-radius:3px}
.ls-p.on{border-color:rgba(52,211,153,.5);color:#a7f3d0;background:rgba(52,211,153,.08)}
.ls-p.off{opacity:.55}
.ls-p.spec{opacity:.72;border-style:dashed}

/* 棋盘 */
.board-wrap{position:relative;background:rgba(8,13,24,.62);border:1px solid var(--line);
  border-radius:var(--r-lg);padding:clamp(8px,1.4vw,16px);overflow:auto;
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  display:flex;align-items:center;justify-content:center;min-height:280px}
/* 无障碍：role="grid" 必须直接包含 role="row"，role="gridcell" 必须被 role="row" 包含，
   所以这里用「board(列) > board-row(grid) > cell」三层结构；视觉与之前完全一致。 */
.board{--cell:32px;--gap:3px;display:flex;flex-direction:column;gap:var(--gap);
  width:max-content;margin:auto;touch-action:manipulation}
.board-row{display:grid;grid-template-columns:repeat(var(--cols),var(--cell));gap:var(--gap)}
.cell{width:var(--cell);height:var(--cell);border-radius:calc(var(--cell) * .2);
  display:grid;place-items:center;position:relative;user-select:none;-webkit-user-select:none;
  font-family:var(--mono);font-weight:800;font-size:calc(var(--cell) * .54);
  line-height:1;padding:0;border:0;background:none;color:var(--text-2);
  transition:background var(--t-fast) var(--ease),transform var(--t-fast) var(--ease),
             box-shadow var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
.cell.hidden{background:linear-gradient(158deg,#26334b,#151d2f);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.09),inset 0 -1px 0 rgba(0,0,0,.35),0 1px 2px rgba(0,0,0,.35)}
.cell.hidden::after{content:"";position:absolute;width:22%;height:22%;border-radius:50%;
  background:rgba(255,255,255,.07)}
.cell.can{cursor:pointer}
.cell.can:hover{background:linear-gradient(158deg,#33456b,#1d2842);transform:translateY(-1px)}
.cell.can:active{transform:translateY(0) scale(.95)}
.cell.revealed{background:rgba(10,16,28,.85);box-shadow:inset 0 0 0 1px rgba(140,170,220,.07)}
.cell.revealed::after{display:none}
.cell.flag{background:linear-gradient(158deg,#3a2f14,#241d0c);color:var(--amber);
  box-shadow:inset 0 0 0 1px rgba(251,191,36,.35),0 0 14px -4px rgba(251,191,36,.6)}
.cell.boom{background:radial-gradient(circle at 50% 45%,#7f1d2e,#3b0d16);color:#fecdd3;
  box-shadow:inset 0 0 0 1px rgba(251,113,133,.5),0 0 24px -4px rgba(244,63,94,.9)}
.cell.sel{outline:2px solid rgba(34,211,238,.85);outline-offset:1px;z-index:3}
.cell.pop{animation:cellPop var(--t-slow) var(--ease-out)}
@keyframes cellPop{0%{transform:scale(.72);opacity:.25}60%{transform:scale(1.06)}100%{transform:scale(1);opacity:1}}
.cell.flagIn{animation:flagPop 320ms var(--ease-out)}
@keyframes flagPop{0%{transform:scale(.4) rotate(-25deg)}70%{transform:scale(1.15) rotate(4deg)}100%{transform:none}}
.cell.boomIn{animation:boomPop 520ms var(--ease-out)}
@keyframes boomPop{0%{transform:scale(.5);filter:brightness(2.6)}55%{transform:scale(1.22)}100%{transform:none;filter:none}}
.board.shake{animation:shake 460ms var(--ease)}
@keyframes shake{10%,90%{transform:translateX(-3px)}20%,80%{transform:translateX(5px)}
  30%,50%,70%{transform:translateX(-7px)}40%,60%{transform:translateX(7px)}}
.n1{color:var(--n1)}.n2{color:var(--n2)}.n3{color:var(--n3)}.n4{color:var(--n4)}
.n5{color:var(--n5)}.n6{color:var(--n6)}.n7{color:var(--n7)}.n8{color:var(--n8)}
.cell.revealed.n0{color:rgba(255,255,255,.14)}

.veil{position:absolute;inset:0;display:none;place-items:center;border-radius:var(--r-lg);
  background:rgba(6,9,17,.55);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);
  font-size:14px;color:var(--text-2);text-align:center;padding:20px;z-index:4}
.veil.is-on{display:grid}

.actions{display:flex;gap:10px;flex-wrap:wrap}
.actions .btn{flex:1 1 auto;min-width:120px}
.lobby-opts{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:16px;display:flex;flex-direction:column;gap:12px;
  backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}
.lobby-opts[hidden]{display:none}
.lo-row{display:flex;gap:12px;align-items:flex-start}
.lo-row > span{font-size:12.5px;color:var(--text-3);min-width:42px;padding-top:8px;letter-spacing:.04em}

/* 聊天 / 战报 */
.chat-panel{display:flex;flex-direction:column;height:min(76vh,760px)}
.tabs{display:flex;gap:4px;padding:10px 12px;border-bottom:1px solid var(--line);position:relative}
.tab{padding:7px 14px;border-radius:9px;font-size:13px;color:var(--text-3);transition:all var(--t)}
.tab:hover{color:var(--text-2);background:rgba(255,255,255,.04)}
.tab.is-active{background:rgba(255,255,255,.07);color:var(--text);font-weight:600}
.tab-toggle{display:none;margin-left:auto;width:30px;height:30px;border-radius:8px;
  color:var(--text-3);border:1px solid var(--line)}
.feed{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:8px;
  scrollbar-width:thin;scrollbar-color:rgba(140,170,220,.28) transparent}
.feed::-webkit-scrollbar{width:7px}
.feed::-webkit-scrollbar-thumb{background:rgba(140,170,220,.24);border-radius:99px}
.msg{display:flex;flex-direction:column;gap:3px;animation:fadeUp var(--t) var(--ease-out)}
.msg .who{font-size:11.5px;font-weight:700;display:flex;align-items:center;gap:6px}
.msg .who i{width:8px;height:8px;border-radius:3px;flex:none}
.msg .body{font-size:13.5px;line-height:1.6;color:var(--text);word-break:break-word;
  background:rgba(255,255,255,.04);padding:8px 11px;border-radius:4px 12px 12px 12px}
.msg.mine .body{background:rgba(34,211,238,.13)}
.sys{font-size:12px;color:var(--text-3);line-height:1.6;padding:2px 4px;border-left:2px solid var(--line);padding-left:9px}
.sys.good{color:#a7f3d0;border-color:rgba(52,211,153,.5)}
.sys.bad{color:#fecdd3;border-color:rgba(251,113,133,.5)}
.sys.warn{color:#fde68a;border-color:rgba(251,191,36,.5)}
.sys.muted{color:var(--text-3)}
.chat-form{display:flex;gap:8px;padding:11px;border-top:1px solid var(--line)}
.chat-form input{flex:1;min-width:0;padding:10px 13px;border-radius:var(--r-sm);
  border:1px solid var(--line);background:rgba(255,255,255,.035);outline:none;font-size:13.5px}
.chat-form input:focus{border-color:rgba(34,211,238,.5)}

/* ---------- 弹层 ---------- */
.overlay{position:fixed;inset:0;z-index:40;display:grid;place-items:center;padding:20px;
  background:rgba(4,7,14,.72);backdrop-filter:blur(9px);-webkit-backdrop-filter:blur(9px);
  animation:fade var(--t) var(--ease-out)}
.overlay[hidden]{display:none}
@keyframes fade{from{opacity:0}to{opacity:1}}
.modal{width:min(460px,100%);max-height:88vh;overflow-y:auto;background:var(--panel-solid);
  border:1px solid var(--line-strong);border-radius:var(--r-xl);padding:26px;
  box-shadow:0 40px 90px -40px #000;animation:modalIn var(--t-slow) var(--ease-out)}
.modal-wide{width:min(660px,100%)}
@keyframes modalIn{from{opacity:0;transform:translateY(18px) scale(.97)}to{opacity:1;transform:none}}
.modal-eyebrow{margin:0 0 8px;font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--cyan)}
.modal h2{font-size:24px;margin-bottom:18px}
.rank-list{display:flex;flex-direction:column;gap:9px;margin-bottom:22px}
.rank-row{display:grid;grid-template-columns:38px 1fr auto;gap:12px;align-items:center;
  padding:12px 14px;border-radius:var(--r);background:rgba(255,255,255,.04);
  border:1px solid transparent;animation:fadeUp var(--t-slow) var(--ease-out) backwards}
.rank-row.top{border-color:rgba(251,191,36,.45);background:linear-gradient(120deg,rgba(251,191,36,.16),rgba(251,191,36,.03))}
.rank-row .rk{font-family:var(--mono);font-weight:800;font-size:16px;color:var(--text-3);text-align:center}
.rank-row.top .rk{color:var(--amber)}
.rank-row .rn{font-size:14.5px;font-weight:600;display:flex;align-items:center;gap:8px}
.rank-row .rs{font-family:var(--mono);font-size:17px;font-weight:700;text-align:right}
.rank-row .rsub{font-size:11.5px;color:var(--text-3);margin-top:2px}
.modal-actions{display:flex;gap:10px;flex-wrap:wrap}
.modal-actions .btn{flex:1 1 auto}
.help-body{font-size:13.5px;line-height:1.85;color:var(--text-2)}
.help-body h3{font-size:14px;color:var(--text);margin:16px 0 7px;letter-spacing:.02em}
.help-body h3:first-child{margin-top:0}
.help-body li{margin-bottom:5px}

/* ---------- 提示条 ---------- */
.toasts{position:fixed;left:50%;bottom:26px;transform:translateX(-50%);z-index:60;
  display:flex;flex-direction:column;gap:9px;align-items:center;pointer-events:none;width:max-content;max-width:92vw}
.toast{padding:11px 17px;border-radius:var(--r);background:rgba(12,20,36,.96);
  border:1px solid var(--line-strong);font-size:13.5px;box-shadow:0 18px 44px -20px #000;
  animation:toastIn 260ms var(--ease-out)}
.toast.bad{border-color:rgba(251,113,133,.55);color:#fecdd3}
.toast.good{border-color:rgba(52,211,153,.5);color:#a7f3d0}
.toast.out{animation:toastOut 260ms var(--ease) forwards}
@keyframes toastIn{from{opacity:0;transform:translateY(14px) scale(.96)}to{opacity:1;transform:none}}
@keyframes toastOut{to{opacity:0;transform:translateY(8px) scale(.97)}}

/* ---------- 响应式 ---------- */
@media (max-width:1180px){
  .table-layout{grid-template-columns:minmax(0,1fr) minmax(260px,320px)}
  .players-panel{grid-column:1 / -1}
  .player-list{flex-direction:row;overflow-x:auto;max-height:none}
  .pcard{min-width:190px;flex:none}
  .room-meta{flex-direction:row;align-items:center;flex-wrap:wrap}
  .meta-btns{flex-direction:row}
}
@media (max-width:820px){
  .table-layout{grid-template-columns:minmax(0,1fr)}
  .chat-panel{height:auto;max-height:52vh}
  .feed{max-height:34vh}
  .tab-toggle{display:grid;place-items:center}
  .chat-panel.collapsed .feed,.chat-panel.collapsed .chat-form{display:none}
  .hud{grid-template-columns:1fr;gap:12px}
  .hud-stats{justify-content:flex-start;gap:18px}
  .stat{align-items:flex-start}
  .hero .hero-title{font-size:clamp(32px,10vw,46px)}
  .board-wrap{justify-content:flex-start;min-height:220px;padding:8px}
  .board{margin:0}
  .modal{padding:20px;border-radius:var(--r-lg)}
  .actions .btn{min-width:calc(50% - 5px)}
}
@media (max-width:520px){
  .home-grid{grid-template-columns:1fr}
  .lan-item{flex-wrap:wrap;gap:6px 10px}
  .lan-name{flex:1 1 100%;white-space:normal}
  .nick-row input{width:100%}
  .custom-box{grid-template-columns:1fr 1fr}
}

/* 无障碍 / 减动效 */
@media (max-width:820px){
  #msGrid{--grid-gap:30px;--grid-alpha:.10}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important}
  .view.is-active{animation:none}
}
:focus-visible{outline:2px solid rgba(34,211,238,.8);outline-offset:2px;border-radius:6px}
.cell:focus-visible{outline:2px solid var(--cyan);outline-offset:1px}
