/* 杭州麻将 · 手机优先 2D
   家规：手机只做 2D 游戏。牌面全部 CSS 画，不加载任何图片资源——
   加载快、任意分辨率都清晰、也不用维护素材。
   交互按 apple-design：按压即反馈、尊重 reduced-motion、间距用 rem 跟随系统字号。 */
:root{
  --felt:#0f5132; --felt-2:#0b3d27;
  --tile:#faf8f2; --tile-edge:#d8d2c4; --tile-ink:#1f2421;
  --red:#b3261e; --green:#1b6b3a; --blue:#1c4f8f;
  --gold:#c8a24a;
  --gap:.4rem;
  /* 这里原来钉了 font-size:16px。全站间距都用 rem，钉死根字号 = 家规「间距用 rem
     跟随系统字号」整条失效，把系统字体调大这个页面会纹丝不动。跟随浏览器默认即可。 */
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{
  font:100%/1.5 system-ui,-apple-system,"PingFang SC","Hiragino Sans GB",sans-serif;
  /* 台面：细密的呢面织纹 + 中心打光 + 四角压暗，比一层纯色渐变有质感得多 */
  background:
    repeating-linear-gradient(45deg,rgba(255,255,255,.014) 0 1px,transparent 1px 3px),
    repeating-linear-gradient(-45deg,rgba(0,0,0,.02) 0 1px,transparent 1px 3px),
    radial-gradient(ellipse 120% 80% at 50% 30%,#1a7048 0%,var(--felt) 42%,var(--felt-2) 100%);
  background-attachment:fixed;
  color:#eef2ee;-webkit-font-smoothing:antialiased;
  overscroll-behavior:none;user-select:none;-webkit-user-select:none;
}
.hidden{display:none!important}

/* ---------- 进厅 ---------- */
.lobby{min-height:100%;display:grid;place-items:center;padding:1.2rem}
.lobby-card{width:min(26rem,100%);background:rgba(0,0,0,.28);border:1px solid rgba(255,255,255,.14);
  border-radius:1.1rem;padding:1.4rem 1.2rem 1.2rem;backdrop-filter:blur(14px)}
.lobby h1{margin:0 0 .15rem;font-size:clamp(1.7rem,7vw,2.2rem);line-height:1.1;letter-spacing:-.02em;
  color:var(--gold)}
.lobby .sub{margin:0 0 1.1rem;opacity:.72;font-size:.92rem;letter-spacing:.01em}
.fld{display:block;margin:0 0 .7rem}
.fld span{display:block;font-size:.8rem;opacity:.7;margin:0 0 .28rem;letter-spacing:.02em}
.fld input{width:100%;padding:.7rem .8rem;border-radius:.65rem;border:1px solid rgba(255,255,255,.2);
  background:rgba(0,0,0,.3);color:inherit;font:inherit;font-size:1rem}
.fld input:focus{outline:2px solid var(--gold);outline-offset:1px}
.big{width:100%;padding:.85rem;border:0;border-radius:.75rem;font:inherit;font-size:1.05rem;font-weight:600;
  background:var(--gold);color:#231a05;transition:transform 100ms ease-out,filter 100ms ease-out}
.big:active{transform:scale(.975);filter:brightness(.93)}
.big.ghost{background:transparent;border:1px solid rgba(255,255,255,.3);color:inherit}
.or{text-align:center;opacity:.5;font-size:.82rem;margin:.7rem 0}
.err{color:#ff9a8f;min-height:1.2em;font-size:.88rem;margin:.6rem 0 0}
.rules{margin:1rem 0 0;font-size:.86rem}
.rules summary{cursor:pointer;opacity:.8;padding:.3rem 0}
.rules ul{margin:.5rem 0;padding-left:1.1rem;line-height:1.75}
.rules li{margin:.25rem 0}
.rules .tiny{font-size:.78rem;opacity:.62;line-height:1.65;border-left:2px solid var(--gold);
  padding-left:.6rem;margin:.6rem 0 0}

/* ---------- 牌桌 ---------- */
.table{min-height:100%;display:flex;flex-direction:column;padding:.5rem .5rem calc(.5rem + env(safe-area-inset-bottom))}
.topbar{display:flex;align-items:center;gap:.6rem;font-size:.85rem;opacity:.85;padding:.1rem .2rem .4rem}
.topbar .wall{margin-left:auto}
.mini{background:transparent;border:1px solid rgba(255,255,255,.25);color:inherit;border-radius:.5rem;
  padding:.28rem .6rem;font:inherit;font-size:.8rem;transition:transform 100ms ease-out}
.mini:active{transform:scale(.95)}

/* 牌河要吃掉中间的空白。原来 .opps 不伸展、中间塞一个 flex:1 的 .spacer，
   于是 375×812 上牌桌中段是约 700px 的纯绿色，牌河反而被挤在顶部 170px 的小盒子里。 */
/* 上家/对家/下家 + 牌河这一整块，在剩余空间里**垂直居中**。
   两个极端都试过：不伸展的话中段留 700px 纯绿；铺满的话 3 张牌撑一口 900px 的空井。
   居中之后牌桌是聚拢的，牌河也按内容长。 */
.opps{flex:1 1 auto;display:flex;flex-direction:column;min-height:0}
.oppRow{display:grid;grid-template-columns:auto 1fr auto;gap:.4rem;align-items:start;
  margin:.35rem 0;flex:1 1 auto;min-height:0}
.opp{text-align:center;font-size:.75rem;opacity:.95}
.opp .oname{font-weight:600;opacity:.9;display:flex;gap:.25rem;align-items:center;justify-content:center;
  flex-wrap:wrap;line-height:1.3}
.opp.side{width:4.8rem;font-size:.7rem}
/* 侧面两家的牌背再小一号，才码得成一小垛而不是一长条 */
.opp.side .ohand .t{--w:.58rem}
/* 庄 / 断线 做成小徽章，比拼在名字后面的括号干净 */
.badge{font-style:normal;font-size:.62rem;font-weight:700;line-height:1;padding:.16em .38em;
  border-radius:.3rem;background:var(--gold);color:#231a05;letter-spacing:.02em}
.badge.off{background:#8a3b32;color:#ffdcd6}
/* 别家的暗牌：一排牌背。轮到谁，谁那排就亮起来 */
.ohand{display:flex;gap:1px;justify-content:center;flex-wrap:wrap;margin-top:.22rem;opacity:.72}
.ohand .t{--w:.72rem;border-radius:.14rem}
.opp.now .ohand{opacity:1}
.opp.now .oname{color:var(--gold)}
.omelds{display:flex;flex-wrap:wrap;gap:2px;justify-content:center;margin-top:.25rem}

/* 牌河：一口凹进去的井，里面按家分成四片 —— 谁打的一眼看得出。
   对家在上、自己在下、左右两家在两侧，跟坐在牌桌前的方位一致。 */
.pool{min-height:7.5rem;height:100%;padding:.4rem;border-radius:.7rem;overflow:auto;
  display:grid;gap:.15rem;
  grid-template-columns:auto 1fr auto;
  grid-template-rows:auto 1fr auto;
  grid-template-areas:"tl top tr" "left mid right" "bl bottom br";
  background:linear-gradient(180deg,rgba(0,0,0,.22),rgba(0,0,0,.1));
  box-shadow:inset 0 2px 6px rgba(0,0,0,.32),inset 0 -1px 0 rgba(255,255,255,.06)}
.dz{display:grid;gap:1px;align-content:start;justify-content:center}
/* ⚠️ 尺寸要算得过来：牌河宽度 = 左区 + 上下区 + 右区。
   手机上牌河只有约 193px，原来 6×1.15rem(上下) + 2×2×1.15rem(左右) = 216px，
   装不下就把右边那区裁掉了。牌小一号、左右两家改单列，正好塞下。 */
.dz .t{--w:1.02rem;border-radius:.12rem}
/* 上下两家：横着六张一行（竞技规则就是六张一排，方便数） */
.dz-top{grid-area:top;grid-template-columns:repeat(6,auto);align-content:start}
.dz-bottom{grid-area:bottom;grid-template-columns:repeat(6,auto);align-content:end}
/* 左右两家：位置窄，竖着两张一列排下去 */
.dz-left{grid-area:left;grid-template-columns:auto;justify-content:start}
.dz-right{grid-area:right;grid-template-columns:auto;justify-content:end}
/* 正中间摆牌墙剩余张数（像牌墙立在桌心），空牌河也不至于是一块死绿。
   ⚠️ 这里要用 flex 不能用 grid：grid 会把文字节点和 ::after 当成两个格子，
   「77」和「张」会被拆到上下两行去。 */
.dz-mid{grid-area:mid;display:flex;align-items:center;justify-content:center;gap:.1em;
  font-size:1.6rem;font-weight:700;color:rgba(255,255,255,.14);letter-spacing:-.02em}
.dz-mid::after{content:"张";font-size:.48em;opacity:.85;align-self:center}

/* 轮到谁 —— 服务端一直把 turn 发下来，前端从来没画过，玩家只能靠猜 */
.whose{text-align:center;font-size:.85rem;padding:.15rem 0 .1rem;min-height:1.3em;
  color:var(--gold);letter-spacing:.02em}
.whose.mine{font-weight:700}
.topbar .chi{opacity:.8}
.opp.now .oname{color:var(--gold)}

/* 报错/提示：浮在牌桌上，不再往已经隐藏的大厅里写 */
.toast{position:fixed;left:50%;transform:translateX(-50%);bottom:22%;z-index:20;
  max-width:min(22rem,86vw);padding:.6rem .9rem;border-radius:.6rem;
  background:rgba(20,10,10,.92);border:1px solid rgba(255,154,143,.6);color:#ffd9d3;
  font-size:.9rem;line-height:1.5;text-align:center;box-shadow:0 4px 16px rgba(0,0,0,.5)}
/* 断线横幅常驻，直到真的连回来 */
.netbar{position:fixed;left:0;right:0;top:0;z-index:21;padding:.45rem .8rem;text-align:center;
  font-size:.85rem;background:#7a2b22;color:#ffe6e1;border-bottom:1px solid rgba(255,255,255,.18)}
.table.offline .myhand .t,.table.offline .act{opacity:.45;pointer-events:none}

/* ---------- 麻将牌 ----------
   牌面全部用内联 SVG 画（见 app.js 的 faceSVG）：筒是点子、条是竹节、
   万是上数字下「萬」，跟真牌一个样。不用图片 —— 任意分辨率都清晰，
   加载零请求，也不用维护素材。
   牌身做出厚度：顶面亮、底部一道深色侧边、外圈一层极淡描边。 */
.t{
  --w:2.05rem;
  position:relative;
  width:var(--w);height:calc(var(--w)*1.34);
  border-radius:calc(var(--w)*.16);
  background:
    linear-gradient(180deg,#fffefa 0%,#fbf8f0 46%,#f2ede0 82%,#ded7c6 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.95),
    inset 0 calc(var(--w)*-.09) 0 rgba(120,105,75,.13),
    inset 0 0 0 1px rgba(120,105,75,.16),
    0 1px 1px rgba(0,0,0,.28),
    0 2px 4px rgba(0,0,0,.22);
  flex:none;overflow:hidden;
}
.t svg{position:absolute;inset:0;width:100%;height:100%;display:block}
.t.sm{--w:1.3rem}
.t.lg{--w:2.6rem}

/* 财神：整张牌泛金，边上再镶一圈 —— 一眼能从手牌里挑出来 */
.t.joker{
  background:linear-gradient(180deg,#fffdf2 0%,#fdf3d4 50%,#f2e2ae 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.95),
    inset 0 0 0 1px var(--gold),
    0 0 0 1px rgba(200,162,74,.55),
    0 1px 2px rgba(0,0,0,.3),
    0 2px 6px rgba(180,140,50,.35);
}

/* 牌背：竹席斜纹，深绿 */
.t.back{
  background:
    repeating-linear-gradient(135deg,rgba(255,255,255,.055) 0 2px,transparent 2px 5px),
    linear-gradient(180deg,#2e7f55 0%,#236b46 60%,#164c31 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.22),
    inset 0 0 0 1px rgba(0,0,0,.28),
    0 1px 2px rgba(0,0,0,.35);
}
.t.last{box-shadow:0 0 0 2px var(--gold),0 0 10px rgba(200,162,74,.55),0 2px 4px rgba(0,0,0,.3)}

/* 我的牌 */
.mine{flex:0 0 auto;padding-top:.5rem}
/* 明牌要和手牌一样居中，否则两行错开、明牌看着像掉在牌桌外面 */
.mymelds{display:flex;flex-wrap:wrap;justify-content:center;gap:.3rem;margin:0 0 .4rem;min-height:1.9rem}
.meld{display:flex;gap:1px;padding:2px;background:rgba(0,0,0,.22);border-radius:.35rem;
  box-shadow:inset 0 1px 3px rgba(0,0,0,.28)}
.myhand{display:flex;gap:.16rem;flex-wrap:wrap;justify-content:center}
/* 手牌立在台边：底下垫一道阴影，看着是竖着的一排牌不是贴纸 */
.myhand .t{transition:transform 110ms ease-out,box-shadow 110ms ease-out}
.myhand .t:active{transform:translateY(-.35rem) scale(1.04)}
.myhand .t.sel{transform:translateY(-.5rem);
  box-shadow:0 0 0 2px var(--gold),0 6px 10px rgba(0,0,0,.42),inset 0 1px 0 rgba(255,255,255,.9)}
/* 刚摸的那张空开一格，并且微微抬起 */
.myhand .t.drawn{margin-left:.5rem;transform:translateY(-.14rem)}
.myhand .t.drawn::after{content:"";position:absolute;left:50%;bottom:-.3rem;translate:-50% 0;
  width:.28rem;height:.28rem;border-radius:50%;background:var(--gold);opacity:.85}

/* 动作条 */
.actions{display:flex;gap:.5rem;flex-wrap:wrap;justify-content:center;min-height:2.9rem;
  padding:.55rem .2rem .2rem}
.act{border:0;border-radius:.65rem;padding:.62rem 1.15rem;font:inherit;font-size:.98rem;font-weight:600;
  letter-spacing:.01em;color:#fff;
  background:linear-gradient(180deg,rgba(255,255,255,.2),rgba(255,255,255,.11));
  border:1px solid rgba(255,255,255,.28);
  box-shadow:0 1px 0 rgba(255,255,255,.18) inset,0 2px 5px rgba(0,0,0,.28);
  transition:transform 100ms ease-out,filter 100ms ease-out}
.act:active{transform:scale(.96);filter:brightness(1.25)}
/* 自摸是全场唯一的胡牌路径，给它最高的视觉权重 */
.act.hu{background:linear-gradient(180deg,#e2bc63,#c8a24a);color:#231a05;border-color:#e8c979;
  box-shadow:0 1px 0 rgba(255,255,255,.5) inset,0 3px 12px rgba(200,162,74,.5);font-size:1.05rem}
.act.pass{background:transparent;box-shadow:none;opacity:.7;font-weight:500}

.log{font-size:.76rem;opacity:.6;text-align:center;min-height:1.2em;padding:.2rem}

/* ---------- 掷骰开门 ---------- */
.dice-ov{position:fixed;inset:0;z-index:30;display:grid;place-items:center;
  background:rgba(0,0,0,.55);backdrop-filter:blur(10px)}
.dice-card{text-align:center;padding:1.6rem 1.5rem 1.2rem;width:min(20rem,86vw);
  background:#16352a;border:1px solid var(--gold);border-radius:1rem;
  box-shadow:0 12px 40px rgba(0,0,0,.5)}
.dice-step{margin:0 0 1rem;font-size:1.05rem;color:var(--gold);letter-spacing:.02em;min-height:1.5em}
.dice-note{margin:1rem 0 0;font-size:.9rem;opacity:.85;line-height:1.6;min-height:2.6em}
.dice-skip{margin:1.2rem 0 0;font-size:.75rem;opacity:.4}
.dice-pair{display:flex;gap:1rem;justify-content:center}
/* 骰子：白底红一四、其余黑点，跟真骰子一样 */
.die{width:3.4rem;height:3.4rem;border-radius:.7rem;background:linear-gradient(160deg,#fff,#ece7dc);
  box-shadow:inset 0 1px 0 #fff,inset 0 -2px 3px rgba(0,0,0,.14),0 4px 10px rgba(0,0,0,.45);
  display:grid;grid-template:repeat(3,1fr)/repeat(3,1fr);padding:.42rem;gap:.1rem}
/* 每一格居中放一个点。⚠️ <i> 默认是行内元素，宽高不生效 —— 少了 display:block
   骰子就是一片空白（第一版就是这么错的）。 */
.die span{display:grid;place-items:center}
.die i{display:block;border-radius:50%;background:#26282b;width:.66rem;height:.66rem}
.die i.r{background:#c0271d}
.die.roll{animation:dieRoll .45s ease-out both}
@keyframes dieRoll{
  0%{transform:rotate(-24deg) scale(.7);opacity:0}
  60%{transform:rotate(8deg) scale(1.06)}
  100%{transform:none;opacity:1}
}

/* 结算 */
.over{position:fixed;inset:0;display:grid;place-items:center;background:rgba(0,0,0,.6);
  backdrop-filter:blur(8px);padding:1.2rem;z-index:10}
.over-card{width:min(24rem,100%);background:#16352a;border:1px solid var(--gold);border-radius:1rem;
  padding:1.3rem;text-align:center}
.over-card h2{margin:0 0 .4rem;color:var(--gold);letter-spacing:-.01em}
.over-card p{margin:.3rem 0 .9rem;font-size:.95rem;line-height:1.7;opacity:.9}
.scores{display:grid;gap:.3rem;margin:0 0 1rem;font-size:.9rem}
.scores div{display:flex;justify-content:space-between;padding:.3rem .5rem;background:rgba(0,0,0,.22);
  border-radius:.4rem}
.scores .up{color:#8ee6a8} .scores .dn{opacity:.65}

@media (prefers-reduced-motion:reduce){
  .big,.mini,.act,.myhand .t{transition:none}
  .big:active,.mini:active,.act:active{transform:none}
  .myhand .t:active,.myhand .t.sel{transform:none}
}
@media (prefers-reduced-transparency:reduce){
  .lobby-card,.over{backdrop-filter:none;background:#123a29}
}
@media (max-width:360px){ .t{--w:1.8rem} }
@media (min-width:700px){
  .t{--w:2.5rem}
  /* 宽屏下别让牌河摊成横贯全屏的一长条：收窄居中，牌才码得成一片 */
  .pool{min-height:9rem;max-width:30rem;margin:0 auto}
  .dz .t{--w:1.3rem}
  .dz-left,.dz-right{grid-template-columns:repeat(2,auto)}
  .opp.side{width:6rem}
}
