:root{
  --bg1:#1b1f3b; --bg2:#0e1124;
  --board:#23262f; --board-edge:#14161c; --hole:#16181e;
  --text:#f4f6ff; --muted:#9aa3c7; --accent:#ffcf1f;
  /* 下列尺寸由 game.js 根据实际可视区域实时计算覆盖 */
  --cell:52px; --gap:6px; --tray-cell:22px; --slot-w:104px; --slot-h:80px; --slot-gap:8px; --tray-cols:3;
  --die:40px; --btn-h:42px; --fs:15px; --lbl:20px; --bpad:12px; --bgap:5px; --sp:10px; --pad:12px;
  --colw:420px; --sidew:340px; --boardw:440px;
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0;width:100%;height:100%}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
body{
  font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Noto Sans CJK SC",sans-serif;
  color:var(--text);
  background-color:var(--bg2);
  background-image:radial-gradient(1200px 700px at 15% -10%,#3a2c78 0%,transparent 60%),
             radial-gradient(900px 600px at 110% 110%,#0f5a6e 0%,transparent 55%),
             linear-gradient(160deg,var(--bg1),var(--bg2));
  background-repeat:no-repeat;background-size:100% 100%;
  min-height:100%;min-height:100vh;min-height:100dvh;
  display:flex;flex-direction:column;
  overflow:hidden; user-select:none; -webkit-user-select:none; -webkit-touch-callout:none;
  overscroll-behavior:none;
}
html.scroll,html.scroll body{overflow:auto;height:auto}
/* 拟合测量时忽略绝对定位的拼块/骰子（它们的位置还停留在旧尺寸） */
html.measuring .grid>.blocker,html.measuring .grid>.piece,html.measuring .slot>.piece{display:none}
/* 整体：CSS Grid，横屏=棋盘左/侧栏右，竖屏=上下堆叠；尺寸由 JS 拟合到可视区域 */
.app{
  margin:auto; padding:var(--pad);
  display:grid; gap:var(--sp); justify-content:center; align-content:center;
  grid-template-columns:var(--colw);
  grid-template-areas:"top" "dice" "board" "tools" "tray" "actions" "help" "foot";
}
.top{grid-area:top}.dice-strip{grid-area:dice}.board-wrap{grid-area:board}.tools{grid-area:tools}
.tray{grid-area:tray}.actions{grid-area:actions}.help{grid-area:help}.foot{grid-area:foot}
html[data-mode=land] .app{
  grid-template-columns:var(--boardw) var(--sidew);
  grid-template-rows:auto auto auto auto auto auto 1fr;
  grid-template-areas:"board top" "board dice" "board tools" "board tray" "board actions" "board help" "board foot";
  column-gap:calc(var(--sp)*1.8);
}
html[data-mode=land] .board-wrap{align-self:center}
html[data-mode=land] .foot{align-self:end;text-align:left}
html[data-density="1"] .sub,html[data-density="1"] .help,html[data-density="1"] .foot,
html[data-density="2"] .sub,html[data-density="2"] .help,html[data-density="2"] .foot{display:none}
html[data-density="2"] .logo{display:none}
html[data-density="2"] .stat{flex-direction:row;gap:6px;padding:3px 8px;min-width:0}

.top{display:flex;align-items:center;justify-content:space-between;gap:8px;min-width:0}
.brand{display:flex;align-items:center;gap:10px;min-width:0;overflow:hidden;flex:0 1 auto}
.titles{min-width:0}
.logo{flex:0 0 auto;width:calc(var(--btn-h)*.95);height:calc(var(--btn-h)*.95);display:grid;grid-template-columns:1fr 1fr;gap:3px;padding:5px;border-radius:11px;background:#23262f;box-shadow:0 4px 14px rgba(0,0,0,.35)}
.logo i{border-radius:4px}
.logo i:nth-child(1){background:#2fbf55}.logo i:nth-child(2){background:#ffcf1f}.logo i:nth-child(3){background:#f2433c}.logo i:nth-child(4){background:#22c3e6}
h1{margin:0;font-size:calc(var(--fs)*1.45);letter-spacing:2px;font-weight:800;white-space:nowrap;line-height:1.2}
.ver{font-size:11px;font-weight:700;letter-spacing:0;color:#2a1a00;background:var(--accent);border-radius:6px;padding:1px 5px;vertical-align:middle}
.sub{margin:2px 0 0;font-size:12px;color:var(--muted);letter-spacing:1px;white-space:nowrap}
.stats{display:flex;gap:6px;flex:0 0 auto}
.stat{background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:4px 10px;display:flex;flex-direction:column;align-items:center;justify-content:center;min-width:64px}
.stat .lbl{font-size:11px;color:var(--muted)}
.stat .val{font-size:calc(var(--fs)*1.2);font-weight:700;font-variant-numeric:tabular-nums;line-height:1.2}

.dice-strip{display:flex;justify-content:center}
.dice-row{display:flex;gap:calc(var(--die)*.16);flex-wrap:wrap;justify-content:center;min-height:var(--die)}
.die{width:44px;height:44px;border-radius:10px;background:linear-gradient(145deg,#ffffff,#dfe3ee);color:#1f2433;font-weight:800;font-size:16px;display:flex;align-items:center;justify-content:center;box-shadow:0 3px 0 #a9afc2,0 6px 14px rgba(0,0,0,.35);letter-spacing:.5px}
.die.mini{width:var(--die);height:var(--die);font-size:calc(var(--die)*.36);border-radius:calc(var(--die)*.22);box-shadow:0 2px 0 #a9afc2,0 4px 10px rgba(0,0,0,.35);animation:pop .35s cubic-bezier(.3,1.6,.5,1) both}

.board-wrap{display:flex;justify-content:center;min-width:0}
.board{
  position:relative;display:grid;
  grid-template-columns:var(--lbl) auto; grid-template-rows:var(--lbl) auto;
  gap:var(--bgap);padding:var(--bpad);border-radius:calc(var(--cell)*.42);
  background:linear-gradient(160deg,#2c2f39,#1d1f26);
  box-shadow:0 2px 0 #3a3e4a inset,0 -3px 0 #101216 inset,0 14px 32px rgba(0,0,0,.5);
  touch-action:none;
}
.col-labels{display:grid;grid-template-columns:repeat(6,var(--cell));gap:var(--gap);padding:0 var(--gap)}
.row-labels{display:grid;grid-template-rows:repeat(6,var(--cell));gap:var(--gap);padding:var(--gap) 0}
.col-labels span,.row-labels span{display:flex;align-items:center;justify-content:center;font-weight:800;color:#c9cfe6;font-size:calc(var(--lbl)*.68)}
.grid{
  position:relative;display:grid;
  grid-template-columns:repeat(6,var(--cell));grid-template-rows:repeat(6,var(--cell));
  gap:var(--gap);padding:var(--gap);border-radius:calc(var(--cell)*.28);background:var(--board-edge);
  box-shadow:0 2px 6px rgba(0,0,0,.6) inset;touch-action:none;
}
.cell{border-radius:22%;background:radial-gradient(circle at 50% 40%,#2a2d36 0%,var(--hole) 75%);box-shadow:0 2px 3px rgba(0,0,0,.7) inset,0 -1px 0 rgba(255,255,255,.05) inset;position:relative}
.cell.ghost-ok::after,.cell.ghost-bad::after{content:"";position:absolute;top:3px;right:3px;bottom:3px;left:3px;border-radius:22%;border:3px dashed rgba(255,255,255,.75)}
.cell.ghost-ok::after{background:rgba(255,255,255,.12)}
.cell.ghost-bad::after{border-color:rgba(255,80,80,.9);background:rgba(255,60,60,.15)}
.blocker{
  position:absolute;border-radius:50%;z-index:3;pointer-events:none;
  background:radial-gradient(circle at 35% 30%,#ffffff 0%,#eef0f6 45%,#c9cdd8 100%);
  box-shadow:0 4px 0 #9ca2b3,0 7px 10px rgba(0,0,0,.45);
  animation:drop .5s cubic-bezier(.3,1.5,.5,1) both;
}
.blocker::after{content:attr(data-c);position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;font-size:calc(var(--cell)*.2);font-weight:800;color:#9aa0b2}

/* 拼块 */
.piece{position:absolute;touch-action:none;-ms-touch-action:none;cursor:grab;z-index:4}
.piece .blk{position:absolute;touch-action:none;-ms-touch-action:none;border-radius:18%;
  background:var(--pc);
  box-shadow:inset 0 3px 0 rgba(255,255,255,.35),inset 0 -4px 0 rgba(0,0,0,.25),0 3px 6px rgba(0,0,0,.35)}
.piece .blk::after{content:"";position:absolute;left:28%;top:28%;width:44%;height:44%;border-radius:50%;background:radial-gradient(circle at 40% 35%,rgba(255,255,255,.35),rgba(0,0,0,.1) 70%)}
.piece.selected .blk{outline:3px solid #fff;outline-offset:-1px}
.piece.dragging{cursor:grabbing;z-index:50;filter:drop-shadow(0 14px 18px rgba(0,0,0,.55))}
.piece.hinted .blk{animation:glow 1.2s ease-in-out 2}
.floating{position:fixed;left:0;top:0;pointer-events:none;z-index:1000;will-change:transform;transform-origin:0 0}

.tools{display:flex;gap:calc(var(--sp)*.7)}
.tray{position:relative;display:grid;grid-template-columns:repeat(var(--tray-cols),var(--slot-w));grid-auto-rows:var(--slot-h);gap:var(--slot-gap);justify-content:center;align-content:center;padding:var(--slot-gap);border-radius:calc(var(--slot-gap)*2.2);background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.09);touch-action:none;-ms-touch-action:none}
.slot{position:relative;display:flex;align-items:center;justify-content:center;border-radius:calc(var(--slot-gap)*1.6);background:rgba(0,0,0,.18);width:var(--slot-w);height:var(--slot-h);transition:background .2s;touch-action:none;-ms-touch-action:none;cursor:grab}
.slot.empty{background:rgba(0,0,0,.08);outline:1px dashed rgba(255,255,255,.08);cursor:default}
.slot.selected{background:rgba(255,207,31,.18);outline:2px solid rgba(255,207,31,.7)}
.slot .piece{position:relative}
.actions{display:grid;grid-template-columns:1fr 1fr;gap:calc(var(--sp)*.7)}
.actions .primary{grid-column:1 / -1}
html[data-mode=port] .actions{grid-template-columns:1fr 1fr 1.3fr}
html[data-mode=port] .actions .primary{grid-column:auto}
.btn{appearance:none;-webkit-appearance:none;border:0;border-radius:calc(var(--btn-h)*.32);height:var(--btn-h);padding:0 10px;font-size:var(--fs);font-weight:700;color:var(--text);background:rgba(255,255,255,.1);cursor:pointer;font-family:inherit;transition:transform .08s,background .2s;touch-action:manipulation;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.btn:hover{background:rgba(255,255,255,.17)}
.btn:active{transform:translateY(1px) scale(.98)}
.btn:disabled{opacity:.45;cursor:not-allowed}
.btn.tool{flex:1;display:flex;align-items:center;justify-content:center;gap:5px}
.btn .ico{font-size:calc(var(--fs)*1.15)}
.btn.primary{background:linear-gradient(135deg,#ffcf1f,#ff8a1f);color:#2a1a00;box-shadow:0 4px 0 #b25d0b}
.btn.primary:hover{filter:brightness(1.06)}
.btn.hint{background:linear-gradient(135deg,#22c3e6,#2f6bff)}
.btn.ghost{background:transparent;border:1px solid rgba(255,255,255,.22)}
.btn.big{font-size:18px;height:auto;padding:14px 26px}
.help{margin:0;font-size:12px;line-height:1.7;color:var(--muted)}
.help b{color:#e6e9fa;background:rgba(255,255,255,.1);padding:0 5px;border-radius:4px}
.foot{text-align:center;font-size:11px;color:rgba(154,163,199,.7)}

/* 掷骰层 */
.overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:2000;display:flex;align-items:center;justify-content:center;background:rgba(6,8,20,.6);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);transition:opacity .3s}
.overlay.hidden{opacity:0;pointer-events:none}
.roll-box{text-align:center;padding:20px}
.roll-title{font-size:20px;font-weight:800;margin-bottom:18px;letter-spacing:3px}
.roll-dice{display:flex;gap:10px;gap:min(14px,2vw);flex-wrap:wrap;justify-content:center;max-width:560px}
.roll-dice .die{width:var(--rdie,64px);height:var(--rdie,64px);font-size:calc(var(--rdie,64px)*.34);border-radius:14px}
.roll-dice .die.rolling{animation:tumble .32s linear infinite}
.roll-dice .die.done{animation:land .45s cubic-bezier(.3,1.7,.5,1) both;background:linear-gradient(145deg,#fff8d9,#ffe27a)}
.win-card{background:linear-gradient(160deg,#2c2f45,#1c1f33);border:1px solid rgba(255,255,255,.12);border-radius:24px;padding:28px 34px;text-align:center;box-shadow:0 30px 70px rgba(0,0,0,.6);animation:pop .45s cubic-bezier(.3,1.6,.5,1) both;max-width:92vw;max-height:92vh;overflow:auto}
.win-emoji{font-size:54px}
.win-card h2{margin:6px 0 8px;font-size:26px}
.win-card p{margin:0 0 20px;color:#c9cfe6;line-height:1.7}
.confetti{position:fixed;top:0;right:0;bottom:0;left:0;pointer-events:none;z-index:2500;width:100%;height:100%}
.toast{position:fixed;left:50%;bottom:28px;transform:translate(-50%,20px);background:rgba(20,22,36,.95);border:1px solid rgba(255,255,255,.14);padding:10px 18px;border-radius:12px;font-size:14px;opacity:0;transition:all .25s;z-index:3000;pointer-events:none;max-width:90vw;text-align:center}
.toast.show{opacity:1;transform:translate(-50%,0)}

@keyframes tumble{0%{transform:rotate(0) translateY(0)}25%{transform:rotate(90deg) translateY(-10px)}50%{transform:rotate(180deg) translateY(0)}75%{transform:rotate(270deg) translateY(-6px)}100%{transform:rotate(360deg)}}
@keyframes land{0%{transform:scale(1.5) rotate(-25deg)}100%{transform:none}}
@keyframes pop{0%{transform:scale(.4);opacity:0}100%{transform:none;opacity:1}}
@keyframes drop{0%{transform:translateY(-40px) scale(1.3);opacity:0}100%{transform:none;opacity:1}}
@keyframes glow{0%,100%{filter:none}50%{filter:brightness(1.5) drop-shadow(0 0 8px #fff)}}
@keyframes shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-5px)}75%{transform:translateX(5px)}}
.shake{animation:shake .25s 2}

