/* ==========================================================
   消消乐 - 样式表
   设计取向：深色"办公室夜灯"配色，方块高饱和，护眼且不刺眼；
             棋盘占据主要视觉，HUD 克制，保证移动端可读。
   ========================================================== */

:root {
  --bg:        #1a1030;
  --bg-2:      #241645;
  --panel:     rgba(255, 255, 255, .06);
  --panel-2:   rgba(255, 255, 255, .10);
  --line:      rgba(255, 255, 255, .12);
  --text:      #f3eeff;
  --text-dim:  #b9aee0;
  --accent:    #ffb454;
  --accent-2:  #ff7ab8;
  --good:      #4ade80;
  --radius:    14px;
  --gap:       4px;

  /* ---- 间距变量（Chrome 61 基线友好）----
     flex 容器不用 gap（Chrome 84+ 才有），改用子项 margin，
     统一由这里的变量驱动，媒体查询只改变量、不改规则。 */
  --gap-app:          10px;   /* .app 列向间距 */
  --gap-topbar-c:     10px;   /* .topbar 横向间距 */
  --gap-topbar-r:     10px;   /* .topbar 换行行距 */
  --gap-brand:         9px;   /* .brand 横向间距 */
  --gap-topbtns:       6px;   /* .topbtns 横向间距 */
  --gap-hud:           5px;   /* .hud 网格间距 */
  --gap-rank:          8px;   /* .rank-bar 横向间距 */
  --gap-bar-c:         8px;   /* .bar-block 列间距 */
  --gap-bar-r:         6px;   /* .bar-block 行间距 */
  --gap-statcard:      5px;   /* .statcard 网格间距 */
  --gap-legend-c:     10px;   /* .legend 横向间距 */
  --gap-legend-r:      4px;   /* .legend 换行行距 */
  --gap-lg:            4px;   /* .lg 图标与文字间距 */
  --gap-ov-actions:    8px;   /* .ov-actions 列间距 */
  --gap-guide-actions:10px;   /* .guide-actions 横向间距 */
  --gap-boss-head:     8px;   /* .boss-head 横向间距 */

  /* ================= 弹幕文字统一规范 =================
     适用于所有"浮在内容之上"的短文本层：.toast（摸鱼文案）、
     .float（飘分）、.combo（连击）。
     规则：
       1) 字号统一用 --dm-size，特殊态用 --dm-size-lg / --dm-size-sm 派生；
       2) 行高统一 --dm-line，保证同一视觉密度；
       3) 描边用 4 向 text-shadow（等价于 1px 描边），
          白字 + 深色描边 => 在浅色与深色背景上都能辨识；
          再叠一层柔和投影拉开与棋盘方块的层次。            */
  --dm-size:     15px;
  --dm-size-lg:  17px;
  --dm-size-sm:  13px;
  --dm-line:     1.5;
  --dm-weight:   700;
  --dm-stroke:
      0  1px 0 rgba(0,0,0,.92),
      0 -1px 0 rgba(0,0,0,.92),
      1px  0   0 rgba(0,0,0,.92),
     -1px  0   0 rgba(0,0,0,.92);
  --dm-shadow:
      0 2px 8px rgba(0,0,0,.55),
      0 0 18px rgba(0,0,0,.35);

  /* 6 种方块颜色 */
  --c0: #ff6b6b;
  --c1: #ffb84d;
  --c2: #4ade80;
  --c3: #4dabff;
  --c4: #b47dff;
  --c5: #ff5fc4;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0; padding: 0;
  min-height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei",
               "Helvetica Neue", Arial, sans-serif;
  overscroll-behavior: none;
}

body {
  background:
    radial-gradient(1200px 700px at 15% -10%, #3a1f6b 0%, transparent 60%),
    radial-gradient(900px 600px at 110% 15%, #4a1f52 0%, transparent 55%),
    var(--bg);
  display: flex; justify-content: center;
  padding: 0;
  user-select: none; -webkit-user-select: none;
}

/* ================= 主题皮肤（L6） =================
   复盘问题：只有深色「办公室夜灯」一套配色，缺少差异化与场景适配。
   方案：用 body[data-theme] 覆写 CSS 变量实现「日间模式」——
   白天在工位上开着更不显眼（浅色反而不刺眼），晚上切回夜灯模式。
   方块配色（--c0~--c5）不随主题变化，保证消除辨识度一致。 */
body[data-theme="day"] {
  --bg:        #eef1f8;
  --bg-2:      #dde3f2;
  --panel:     rgba(30, 40, 80, .07);
  --panel-2:   rgba(30, 40, 80, .12);
  --line:      rgba(30, 40, 80, .14);
  --text:      #1f2540;
  --text-dim:  #5b6480;
  --accent:    #e07b18;
  --accent-2:  #d94f8c;
  --good:      #16a34a;
  --radius:    14px;
}
body[data-theme="day"] {
  background:
    radial-gradient(1200px 700px at 15% -10%, #d9e2f7 0%, transparent 60%),
    radial-gradient(900px 600px at 110% 15%, #f0dcec 0%, transparent 55%),
    var(--bg);
}
body[data-theme="day"] .g-S { color: #b8860b; }
body[data-theme="day"] .g-A { color: #16a34a; }
body[data-theme="day"] .g-B { color: #1d6fd0; }
body[data-theme="day"] .g-C { color: #6b7280; }
body[data-theme="day"] .sc-value.g-S { color: #b8860b; }
body[data-theme="day"] .sc-value.g-A { color: #16a34a; }
body[data-theme="day"] .sc-value.g-B { color: #1d6fd0; }
body[data-theme="day"] .sc-value.g-C { color: #6b7280; }
body[data-theme="day"] .board-frame { background: rgba(30, 40, 80, .10); }
body[data-theme="day"] .tile {
  box-shadow: inset 0 -3px 0 rgba(0,0,0,.14), 0 2px 5px rgba(30,40,80,.18);
}

/* ================= 布局 ================= */
.app {
  width: 100%; max-width: 560px;
  /* 用 box-sizing:border-box（全局 * 已设）时，min-height 含 padding，
     故这里写 100dvh 不会额外撑高；旧写法 100vh 在移动端地址栏收起时会溢出，
     故优先用 100dvh（不支持时回落 100vh）。 */
  min-height: 100vh; min-height: 100dvh;
  display: flex; flex-direction: column;
  /* 安全区内边距改由 css/compat.css 承担：
     Chrome 61（69+ 才有 env()）无法解析含 env() 的整条 padding，
     会导致内边距整体丢失，故此处不写，交给兼容层给基线值。 */
  min-width: 0;                 /* 关键：允许 flex 子项收缩，避免内容撑破布局 */
  overflow-x: hidden;
}
/* 所有含长中文文本的容器都要允许收缩 + 断行，
   否则 min-content 宽度会把整个页面撑宽，导致右侧内容被裁切 */
.brand, .topbtns, .hud, .footer, .board-area, .legend, .topbar { min-width: 0; }

/* ================= 顶栏 ================= */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: nowrap;
}
.brand { display: flex; align-items: center; min-width: 0; flex: 1 1 auto; }
.logo { font-size: 26px; filter: drop-shadow(0 2px 6px rgba(0,0,0,.4)); flex-shrink: 0; }
.brand-text { min-width: 0; overflow: hidden; }
.brand-text h1 {
  margin: 0; font-size: 17px; font-weight: 700; letter-spacing: .5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand-text p {
  margin: 1px 0 0; font-size: 11.5px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbtns { display: flex; flex-shrink: 0; }
.icon-btn {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  font-size: 16px; line-height: 1;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--text); cursor: pointer;
  transition: background .16s, transform .12s;
}
.icon-btn:hover { background: var(--panel-2); }
.icon-btn:active { transform: scale(.92); }

/* ================= HUD ================= */
.hud {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));   /* minmax(0,1fr) 防止内容撑破列宽 */
  gap: var(--gap-hud);
}
.stat {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 6px 2px;
  text-align: center;
  min-width: 0;
  overflow: hidden;
}
.stat-label {
  display: block; font-size: 10px; color: var(--text-dim);
  letter-spacing: .3px; margin-bottom: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.stat-value {
  display: block; font-size: 15px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.stat-value.big { color: var(--accent); font-size: 17px; }

/* 评级色（M3）：S 金 / A 绿 / B 蓝 / C 灰。
   与数字本身同色系，弱化标签，突显数值。 */
.stat-value.grade { font-size: 16px; letter-spacing: .5px; }
.g-S { color: #ffd166; }
.g-A { color: #4ade80; }
.g-B { color: #4dabff; }
.g-C { color: #b9aee0; }

/* 段位条（H2 段位 + H4 连续摸鱼）
   位置：HUD 之下、进度条之上。
   层级：图标 > 段位名 > 进度槽 > 最高分 > 连续天数。
   最高分从 HUD 降级到这里（跨局数据不该和本局数据抢视觉焦点），
   段位进度槽做 flex:1 让它在任何宽度下都能占满剩余空间。 */
.rank-bar {
  display: flex; align-items: center;
  min-width: 0;
  padding: 5px 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 11px;
}
.rank-icon {
  font-size: 15px; line-height: 1;
  flex-shrink: 0;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,.45));
}
.rank-name {
  font-size: 12px; font-weight: 700; color: var(--accent);
  white-space: nowrap; flex-shrink: 0;
  letter-spacing: .2px;
}
.rank-track {
  position: relative;
  flex: 1 1 auto; min-width: 30px;
  height: 5px;
  background: rgba(0,0,0,.32);
  border-radius: 3px;
  overflow: hidden;
}
.rank-fill {
  height: 100%; width: 0;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  border-radius: 3px;
  transition: width .5s cubic-bezier(.4,1.2,.5,1);
}
.rank-meta {
  font-size: 10.5px; color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap; flex-shrink: 0;
}
.streak {
  font-size: 10.5px; color: var(--accent);
  white-space: nowrap; flex-shrink: 0;
  padding: 1px 6px;
  background: rgba(255,180,84,.14);
  border: 1px solid rgba(255,180,84,.32);
  border-radius: 9px;
}
.streak[hidden] { display: none; }
.streak b { font-weight: 800; font-variant-numeric: tabular-nums; }

/* ================= 进度条 ================= */
/* bar-block：进度条 + 弹幕槽的垂直容器。
   用 CSS Grid 而非 Flex，并把左右两列设为等宽（46px），
   这样中间的进度条列天然居中于容器 —— 弹幕槽跨满整行后，
   弹幕的水平中心 = 进度条的水平中心，两条要求同时成立。

   若左右列不等宽（标签长短不一时），进度条会偏左，
   弹幕就会与进度条错位，故此处固定等宽。 */
.bar-block {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr) 46px;
  column-gap: var(--gap-bar-c);
  row-gap: var(--gap-bar-r);   /* 进度条与弹幕槽的间距 */
  min-width: 0;
  position: relative;
}
/* bar-cap / bar-wrap / bar-num 直接作为 .bar-block 的网格项，
   弹幕槽跨满整行。
   实时数值从进度条内部文字改为条外数字，
   好处：进度条填充动画不会被文字挤压，数值也能用等宽数字稳定不跳。 */
.bar-cap {
  grid-column: 1; grid-row: 1;
  align-self: center;
  font-size: 11px; color: var(--text-dim);
  white-space: nowrap;
  letter-spacing: .2px;
  text-align: right;
  overflow: hidden; text-overflow: ellipsis;
}
.bar-num {
  grid-column: 3; grid-row: 1;
  align-self: center;
  font-size: 11.5px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums;   /* 等宽数字，避免每次刷新宽度跳动 */
  white-space: nowrap;
  text-align: left;
  overflow: hidden; text-overflow: ellipsis;
}
.bar-wrap {
  grid-column: 2; grid-row: 1;
  position: relative;
  min-width: 40px;
  height: 22px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 11px;
  overflow: hidden;
}
.bar-fill {
  height: 100%; width: 0;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  transition: width .4s cubic-bezier(.4,1.2,.5,1);
  border-radius: 11px 0 0 11px;
}
.bar-wrap.done .bar-fill { background: linear-gradient(90deg, #34d399, #4ade80); }

/* ================= 弹幕槽 =================
   常驻固定高度的槽位：弹幕出现/消失时不引起棋盘上下位移。
   跨满整行（1 / -1）以保证长文案有足够宽度不被裁切；
   由于 .bar-block 左右两列等宽，进度条居中于容器，
   因此满宽弹幕槽的水平中心仍与进度条中心重合。 */
.danmaku-slot {
  grid-column: 1 / -1; grid-row: 2;
  position: relative;
  /* 高度按「两行弹幕」预留：15px × 1.5 × 2 = 45px + padding 6 + border 2 = 53px。
     文案已在 game.js 的 toast() 里裁剪到 22 字，窄屏也最多折两行，
     所以 54px 足够，超长文案不会溢出到棋盘上。
     槽位高度固定 → 弹幕出现/消失不会引起棋盘上下位移。 */
  height: 54px;
  min-width: 0;
  display: flex; align-items: center; justify-content: center;
}


/* ================= 棋盘 ================= */
.board-area {
  flex: 1;
  /* 垂直居中：长屏手机上棋盘已吃满宽度，剩余空间均分到上下，
     避免出现"棋盘悬在半空、下方一大片空白"的观感。
     短屏时棋盘受高度限制，居中同样成立。 */
  display: flex; align-items: center; justify-content: center;
  min-height: 0;
  padding: 10px 0 4px;
}
.board-frame {
  position: relative;
  width: 100%;
  /* 棋盘边长：优先吃满可用宽度，同时不超过「视口高度减去上下各区块」，
     避免 56vh 这种固定比例在长屏手机上留出大片空白。
     520px 是上限，防止桌面端棋盘过大。 */
  /* Chrome 61 无 min()/dvh：先给可解析的回退值，现代浏览器用后面的值覆盖 */
  max-width: 520px;
  max-width: min(100%, calc(100vh - 300px), 520px);
  max-width: min(100%, calc(100dvh - 300px), 520px);
  /* 正方形：aspect-ratio 是增强层；Chrome 61 下由 js/compat.js 按实测宽度写死高度 */
  aspect-ratio: 1 / 1;
  background: rgba(0, 0, 0, .26);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 5px;
  box-shadow: 0 18px 44px rgba(0,0,0,.42);
  min-width: 0;
}
.grid {
  position: relative;
  width: 100%; height: 100%;
  touch-action: none;             /* 关键：禁止浏览器接管滑动，才能自己做滑动手势 */
  outline: none;
}
.grid.shuffling { animation: shakeGrid .26s ease-in-out 2; }
@keyframes shakeGrid {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(-5px, 2px); }
  75% { transform: translate(5px, -2px); }
}

/* ================= 方块 ================= */
.tile {
  position: absolute; top: 0; left: 0;
  border-radius: 9px;
  display: grid; place-items: center;
  font-size: 20px; font-weight: 800;
  color: rgba(0,0,0,.62);
  transition: top .2s cubic-bezier(.3,.9,.4,1), transform .18s ease-out;
  will-change: top, transform;
  box-shadow: inset 0 -3px 0 rgba(0,0,0,.18), 0 2px 5px rgba(0,0,0,.3);
  cursor: pointer;
}
.tile.c0 { background: linear-gradient(160deg, #ff8a8a, var(--c0)); }
.tile.c1 { background: linear-gradient(160deg, #ffd08a, var(--c1)); }
.tile.c2 { background: linear-gradient(160deg, #8ef0ad, var(--c2)); }
.tile.c3 { background: linear-gradient(160deg, #8ac6ff, var(--c3)); }
.tile.c4 { background: linear-gradient(160deg, #d3b0ff, var(--c4)); }
.tile.c5 { background: linear-gradient(160deg, #ff9fd8, var(--c5)); }

/* ================= 形状编码（M6 色觉友好） =================
   复盘问题：仅靠颜色区分 6 种方块，红绿色觉障碍用户（约 8% 男性）
   难以分辨相邻的暖色方块。
   方案：给 6 种颜色各加一个固定形状的浅色浮层（圆/三角/方/菱/十字/环），
   位置在方块正中、大小约 34%，用半透明深色绘制，不干扰原有配色与动画。
   纯 CSS 实现，零额外美术资源、零运行时开销。
   注意：特殊块自带图标（炸弹/箭头），不再叠加形状，避免视觉噪声。 */
.tile.c0:not(.sp-bomb):not(.sp-row):not(.sp-col)::before,
.tile.c1:not(.sp-bomb):not(.sp-row):not(.sp-col)::before,
.tile.c2:not(.sp-bomb):not(.sp-row):not(.sp-col)::before,
.tile.c3:not(.sp-bomb):not(.sp-row):not(.sp-col)::before,
.tile.c4:not(.sp-bomb):not(.sp-row):not(.sp-col)::before,
.tile.c5:not(.sp-bomb):not(.sp-row):not(.sp-col)::before {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: 34%; height: 34%;
  transform: translate(-50%, -50%);
  background: rgba(0, 0, 0, .22);
  pointer-events: none;
}
/* c0 红 → 圆 */
.tile.c0:not(.sp-bomb):not(.sp-row):not(.sp-col)::before { border-radius: 50%; }
/* c1 橙 → 三角（用 clip-path，border-width 不支持百分比） */
.tile.c1:not(.sp-bomb):not(.sp-row):not(.sp-col)::before {
  background: rgba(0, 0, 0, .22);
  -webkit-clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
  clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
  border-radius: 0;
}
/* c2 绿 → 圆角方 */
.tile.c2:not(.sp-bomb):not(.sp-row):not(.sp-col)::before { border-radius: 22%; }
/* c3 蓝 → 菱形 */
.tile.c3:not(.sp-bomb):not(.sp-row):not(.sp-col)::before { transform: translate(-50%, -50%) rotate(45deg); border-radius: 12%; }
/* c4 紫 → 十字（clip-path 十字形，比 mask 兼容性更好） */
.tile.c4:not(.sp-bomb):not(.sp-row):not(.sp-col)::before {
  background: rgba(0, 0, 0, .22);
  border-radius: 0;
  -webkit-clip-path: polygon(38% 0%, 62% 0%, 62% 38%, 100% 38%, 100% 62%, 62% 62%, 62% 100%, 38% 100%, 38% 62%, 0% 62%, 0% 38%, 38% 38%);
  clip-path: polygon(38% 0%, 62% 0%, 62% 38%, 100% 38%, 100% 62%, 62% 62%, 62% 100%, 38% 100%, 38% 62%, 0% 62%, 0% 38%, 38% 38%);
}
/* c5 粉 → 圆环 */
.tile.c5:not(.sp-bomb):not(.sp-row):not(.sp-col)::before {
  background: none;
  border-radius: 50%;
  box-shadow: inset 0 0 0 3px rgba(0, 0, 0, .25);
}

.tile.selected {
  outline: 3px solid #fff;
  outline-offset: -3px;
  transform-origin: center;
  animation: selPulse .9s ease-in-out infinite;
  z-index: 5;
}
@keyframes selPulse {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.28); }
}
.tile.selected { z-index: 5; }
.tile.hinting { animation: hintGlow 1s ease-in-out infinite; z-index: 4; }
@keyframes hintGlow {
  0%, 100% { box-shadow: inset 0 -3px 0 rgba(0,0,0,.18), 0 0 0 0 rgba(255,255,255,.7); }
  50%      { box-shadow: inset 0 -3px 0 rgba(0,0,0,.18), 0 0 0 4px rgba(255,255,255,.35); }
}
.tile.popping { animation: pop .3s ease-out forwards; z-index: 6; }
@keyframes pop {
  0%   { transform: scale(1); opacity: 1; filter: brightness(1); }
  40%  { transform: scale(1.22); filter: brightness(1.9); }
  100% { transform: scale(.2); opacity: 0; }
}
.tile.shake { animation: shakeX .32s ease-in-out; }
@keyframes shakeX {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-6px); }
  75% { transform: translateX(6px); }
}
.tile.fresh { }

/* 特殊块：用 ::after 叠加图标，普通方块不带图标。
   注意：.tile 本身已有 color/font-size，若用 ::before 会与内容冲突，
   因此统一用 ::after 绘制标识。 */
.tile.sp-bomb {
  background: linear-gradient(160deg, #3a3a4d, #1c1c26);
  box-shadow: inset 0 -3px 0 rgba(0,0,0,.45), 0 0 16px rgba(255,209,102,.55);
}
/* 炸弹图标用纯 CSS 绘制，避免 emoji 在不同系统上的渲染差异 */
.tile.sp-bomb::after {
  content: '';
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
}
.tile.sp-bomb::before {
  content: '';
  position: absolute;
  left: 50%; top: 52%;
  width: 46%; height: 46%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle at 35% 30%, #ffe9a8, #f0a500 60%, #b06d00);
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0,0,0,.5);
}
/* 引线：用 ::after 的 border 画出右上角的弯折引线 + 火花点 */
.tile.sp-bomb::after {
  content: '';
  position: absolute;
  left: 58%; top: 20%;
  width: 24%; height: 24%;
  border-top: 2px solid #ffd166;
  border-right: 2px solid #ffd166;
  border-radius: 0 12px 0 0;
  transform: rotate(-8deg);
  box-shadow: none;
}

.tile.sp-row {
  background: linear-gradient(160deg, #63e6ff, #1c9fd4);
  color: #04303f;
  box-shadow: inset 0 -3px 0 rgba(0,0,0,.2), 0 0 12px rgba(99,230,255,.5);
}
.tile.sp-row::after {
  content: '↔';
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  display: grid; place-items: center;
  font-size: 24px; font-weight: 900; line-height: 1;
  color: #04303f;
  text-shadow: 0 1px 0 rgba(255,255,255,.35);
}

.tile.sp-col {
  background: linear-gradient(160deg, #ffa8e0, #d94fa8);
  color: #3d0b28;
  box-shadow: inset 0 -3px 0 rgba(0,0,0,.2), 0 0 12px rgba(255,168,224,.5);
}
.tile.sp-col::after {
  content: '↕';
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  display: grid; place-items: center;
  font-size: 24px; font-weight: 900; line-height: 1;
  color: #3d0b28;
  text-shadow: 0 1px 0 rgba(255,255,255,.35);
}

/* ================= 战绩卡（M3） =================
   位置：棋盘与页脚之间。棋盘在桌面端是 max-width 560 居中，
   左右两侧会留出大片空白；把本局关键数据做成一张四格横条，
   既填补留白，又把"打完了这局到底表现如何"显性化。 */
.statcard {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--gap-statcard);
  min-width: 0;
  padding: 6px 8px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 11px;
}
.sc-item {
  min-width: 0;
  text-align: center;
  overflow: hidden;
}
.sc-label {
  display: block;
  font-size: 9.5px; color: var(--text-dim);
  letter-spacing: .2px; margin-bottom: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sc-value {
  display: block;
  font-size: 14px; font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sc-value.g-S { color: #ffd166; }
.sc-value.g-A { color: #4ade80; }
.sc-value.g-B { color: #4dabff; }
.sc-value.g-C { color: #b9aee0; }

/* ================= 飘分 ================= */
.float {
  position: absolute;
  transform: translate(-50%, -50%);
  font-weight: 800; font-size: var(--dm-size);
  line-height: var(--dm-line);
  color: #fff;
  text-shadow: var(--dm-stroke), var(--dm-shadow);
  pointer-events: none;
  animation: floatUp .9s ease-out forwards;
  z-index: 8;
}
.float.f-mega   { font-size: var(--dm-size-lg); color: var(--accent); }
.float.f-special{ font-size: var(--dm-size-sm); color: #7ef0ff; }
.float.f-create { font-size: var(--dm-size-sm); color: #ffe08a; font-weight: 900; }
@keyframes floatUp {
  0%   { opacity: 0; transform: translate(-50%, -30%) scale(.7); }
  25%  { opacity: 1; transform: translate(-50%, -60%) scale(1.1); }
  100% { opacity: 0; transform: translate(-50%, -170%) scale(1); }
}

/* ================= 连击提示 ================= */
.combo {
  position: absolute; top: 8px; left: 50%;
  transform: translateX(-50%) scale(.6);
  padding: 4px 14px;
  font-size: var(--dm-size);
  line-height: var(--dm-line);
  font-weight: 800;
  color: var(--accent);
  background: rgba(0,0,0,.42);
  border: 1px solid rgba(255,180,84,.4);
  border-radius: 20px;
  opacity: 0;
  transition: opacity .2s, transform .2s;
  pointer-events: none;
  z-index: 10;
  white-space: nowrap;
  text-shadow: var(--dm-stroke);
}
.combo.show { opacity: 1; transform: translateX(-50%) scale(1); }


/* ================= 底部 ================= */
.footer {
  text-align: center; min-width: 0;
  padding-bottom: 4px;
}
.hint {
  margin: 0 0 6px;
  font-size: 11.5px; color: var(--text-dim);
  overflow-wrap: break-word; word-break: break-word;
}
.legend {
  display: flex; flex-wrap: wrap;
  justify-content: center;
  font-size: 10.5px; color: var(--text-dim);
}
.lg {
  display: inline-flex; align-items: center;
  min-width: 0; overflow-wrap: break-word;
}

/* ================= 扩展功能入口条（L1/L2/L6） =================
   复盘问题：低优先级功能（每日一局 / 伪装图分享 / 主题切换）缺少入口，
   放在底部做成一行小按钮，不与顶栏图标按钮抢空间，
   也不打断"看棋盘—消除"的主路径。 */
.extbar {
  display: flex; flex-wrap: wrap; gap: 6px;
  justify-content: center;
  margin-top: 8px;
}
.ext-btn {
  font: inherit;
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--text-dim);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px 11px;
  cursor: pointer;
  transition: color .18s, background .18s, transform .12s;
  -webkit-tap-highlight-color: transparent;
}
.ext-btn:hover { color: var(--text); background: var(--panel-2); }
.ext-btn:active { transform: scale(.96); }
.ext-btn.on { color: var(--accent); border-color: var(--accent); }

/* ================= 合规信息行 =================
   隐私政策入口 + 数据存储说明 + 版本号。
   字号取 10.5px（与图例同级），是页面最次要的信息，
   但必须存在 —— H5 在应用商店/公众号/企业内网分发时，
   「数据存哪里」是审核必查项。 */
.legal {
  margin: 8px 0 0;
  font-size: 10.5px;
  color: var(--text-dim);
  opacity: .8;
  display: flex; flex-wrap: wrap; gap: 4px 6px;
  justify-content: center; align-items: center;
  overflow-wrap: break-word;
}
.legal a { color: var(--text-dim); text-decoration: none; }
.legal a:hover { color: var(--accent); text-decoration: underline; }
.legal-sep { opacity: .5; }

.lg-dot {
  width: 13px; height: 13px; border-radius: 3px;
  display: inline-block; flex-shrink: 0;
  position: relative;
}
.lg-dot.sp-bomb { background: linear-gradient(160deg, #3a3a4d, #1c1c26); box-shadow: 0 0 6px rgba(255,209,102,.45); }
.lg-dot.sp-bomb::before {
  content: ''; position: absolute;
  left: 50%; top: 54%; width: 52%; height: 52%;
  transform: translate(-50%,-50%);
  background: radial-gradient(circle at 35% 30%, #ffe9a8, #f0a500 65%, #b06d00);
  border-radius: 50%;
}
.lg-dot.sp-row  { background: linear-gradient(160deg, #63e6ff, #1c9fd4); }
.lg-dot.sp-row::before {
  content: '↔'; position: absolute; inset: 0;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 900; color: #04303f; line-height: 1;
}
.lg-dot.sp-col  { background: linear-gradient(160deg, #ffa8e0, #d94fa8); }
.lg-dot.sp-col::before {
  content: '↕'; position: absolute; inset: 0;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 900; color: #3d0b28; line-height: 1;
}

/* ================= 弹幕（摸鱼文案） =================
   位置：从 fixed 浮层改为进度条正下方的常驻槽位内，
   在槽位中水平居中，不与棋盘/标题/图例发生重叠。 */
.toast {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, calc(-50% + 6px));
  padding: 3px 14px;
  background: rgba(20, 12, 40, .92);
  border: 1px solid var(--line);
  border-radius: 16px;
  font-size: var(--dm-size);
  line-height: var(--dm-line);
  font-weight: var(--dm-weight);
  color: #fff;
  text-shadow: var(--dm-stroke);
  box-shadow: var(--dm-shadow);
  opacity: 0; pointer-events: none;
  transition: opacity .25s, transform .25s;
  max-width: 420px;                                   /* Chrome 61 回退 */
  max-width: min(100%, 420px);
  text-align: center;
  /* 长文案（如 26 字的 streak 提示）不再被 ellipsis 截断，
     改为自动换行；弹幕槽高度足够容纳两行，不引起棋盘位移。
     overflow-wrap 保证长英文/URL 也能断行。 */
  white-space: normal;
  overflow-wrap: break-word;
  word-break: break-word;
  z-index: 20;
}
.toast.show { opacity: 1; transform: translate(-50%, -50%); }



/* ================= 遮罩层 ================= */
.overlay {
  position: fixed;
  top: 0; right: 0; bottom: 0; left: 0;   /* inset 简写是 Chrome 87+，展开写 */
  background: rgba(10, 6, 22, .88);   /* 不依赖模糊的实色底：不支持 backdrop-filter 时也可读 */
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  display: grid; place-items: center;
  opacity: 0; pointer-events: none;
  transition: opacity .22s;
  z-index: 50;
  padding: 20px;
}
.overlay.show { opacity: 1; pointer-events: auto; }
.ov-card {
  width: 100%; max-width: 340px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 18px;
  padding: 24px 20px 20px;
  text-align: center;
  box-shadow: 0 24px 60px rgba(0,0,0,.55);
  transform: translateY(12px) scale(.97);
  transition: transform .22s;
}
.overlay.show .ov-card { transform: translateY(0) scale(1); }
.ov-card h2 {
  margin: 0 0 8px; font-size: 21px; font-weight: 800;
  color: var(--accent);
}
.ov-card p {
  margin: 0 0 18px; font-size: 13.5px; color: var(--text-dim);
  line-height: 1.6;
}
.ov-actions { display: flex; flex-direction: column; }
.btn {
  width: 100%;
  padding: 12px 16px;
  font-size: 14.5px; font-weight: 700;
  color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 11px;
  cursor: pointer;
  transition: background .15s, transform .1s;
  font-family: inherit;
}
.btn:hover { background: rgba(255,255,255,.16); }
.btn:active { transform: scale(.97); }
.btn:first-child {
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: #2a1405; border-color: transparent;
}
/* 次要操作（分享战绩）：描边不填充，与主按钮拉开层级 */
.btn.ghost {
  background: transparent;
  border-color: rgba(255,180,84,.5);
  color: var(--accent);
  font-weight: 600;
  padding: 10px 16px;
  font-size: 13.5px;
}
.btn.ghost:hover { background: rgba(255,180,84,.12); }

/* ================= 新手引导（H3） =================
   采用「棋盘下方抽屉」而非全屏遮罩：棋盘仍可见，
   用户能对照着真实方块理解规则，避免第一次进来被强制打断。 */
.guide {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 45;
  display: flex; justify-content: center;
  /* 安全区 padding 见 css/compat.css（Chrome 61 无法解析 env()） */
  pointer-events: none;
  animation: guideUp .26s ease-out;
}
.guide[hidden] { display: none; }
.guide-card {
  width: 100%; max-width: 380px;
  pointer-events: auto;
  background: var(--bg-2);
  border: 1px solid rgba(255,180,84,.35);
  border-radius: 16px;
  padding: 14px 16px 12px;
  box-shadow: 0 18px 48px rgba(0,0,0,.55);
  position: relative;
}
.guide-step {
  position: absolute; top: 12px; right: 14px;
  font-size: 10.5px; color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1px 6px;
}
.guide-title {
  margin: 0 0 5px;
  font-size: 15px; font-weight: 800; color: var(--accent);
  letter-spacing: .3px;
}
.guide-text {
  margin: 0 0 12px;
  font-size: 13px; line-height: 1.65; color: var(--text);
  overflow-wrap: break-word;
}
.guide-actions {
  display: flex; align-items: center; justify-content: flex-end;
}
.guide-skip {
  background: none; border: none;
  color: var(--text-dim);
  font-size: 12.5px; font-family: inherit;
  cursor: pointer; padding: 6px 2px;
}
.guide-skip:hover { color: var(--text); }
.guide-next {
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: #2a1405; border: none;
  font-size: 13px; font-weight: 700; font-family: inherit;
  border-radius: 10px;
  padding: 8px 20px;
  cursor: pointer;
  transition: transform .1s;
}
.guide-next:active { transform: scale(.96); }
@keyframes guideUp {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ================= 老板键 ================= */
.boss {
  position: fixed;
  top: 0; right: 0; bottom: 0; left: 0;
  background: #f3f4f6;
  color: #1f2937;
  display: flex; align-items: center; justify-content: center;
  padding: 18px;
  opacity: 0; pointer-events: none;
  transition: opacity .12s;
  z-index: 999;
  font-family: -apple-system, "PingFang SC", "Microsoft YaHei", Arial, sans-serif;
}
.boss.show { opacity: 1; pointer-events: auto; }
.boss-card {
  width: 100%; max-width: 620px;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: 18px 20px;
  box-shadow: 0 8px 30px rgba(0,0,0,.1);
}
.boss-head {
  display: flex; align-items: center;
  font-size: 15px; font-weight: 700;
  padding-bottom: 12px; margin-bottom: 12px;
  border-bottom: 1px solid #e5e7eb;
}
.boss-dot { width: 9px; height: 9px; border-radius: 50%; background: #22c55e; }
.boss-time { margin-left: auto; font-size: 12px; color: #6b7280; font-weight: 400; }
.boss-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.boss-table th, .boss-table td {
  text-align: left; padding: 9px 8px;
  border-bottom: 1px solid #f3f4f6;
}
.boss-table th { color: #6b7280; font-weight: 600; font-size: 12px; }
.boss-table td:last-child { color: #f59e0b; }
.boss-foot { margin: 12px 0 0; font-size: 11.5px; color: #9ca3af; }

/* ================= 响应式 ================= */
/* 窄屏（≤360px）：弹幕字号下调一档，保证 19 字长文案单行不溢出槽位。
   断点取 360 而非 400，因为 390/393/414 是 iPhone 主力宽度，
   那里应使用完整的 15px 字号。 */
@media (max-width: 360px) {
  :root { --dm-size: 13.5px; --dm-size-lg: 15px; --dm-size-sm: 12px; }
  .danmaku-slot { height: 50px; }
  .toast { padding: 3px 11px; }
  :root { --gap-rank: 6px; }
  .rank-bar { padding: 4px 8px; }
  .rank-name { font-size: 11px; }
  .rank-meta { display: none; }        /* 极窄屏优先保证段位名与进度槽完整 */
  .bar-cap { display: none; }          /* 标签让位给进度条与数值 */
  .sc-label { font-size: 9px; }
  .sc-value { font-size: 12.5px; }
}

/* 矮屏（如手机横放）：压缩非棋盘区域，把空间让给棋盘 */
@media (max-height: 680px) {
  :root { --gap-app: 7px; --gap-bar-c: 5px; --gap-bar-r: 5px; }
  .app { padding-top: 8px; }
  .stat { padding: 4px 3px; }
  .stat-value { font-size: 13.5px; }
  .stat-value.big { font-size: 15px; }
  .legend { display: none; }
  .board-frame { max-width: 88vw; max-width: min(88vw, 52vh); }
  .bar-block { column-gap: 5px; row-gap: 5px; }
  .danmaku-slot { height: 50px; }
  .statcard { padding: 4px 6px; }
  .sc-value { font-size: 12.5px; }
  .sc-label { font-size: 9px; margin-bottom: 1px; }
  .legal { margin-top: 5px; font-size: 10px; }
}
@media (max-height: 560px) {
  .brand-text p, .legend, .footer .hint { display: none; }
  .hud { grid-template-columns: repeat(6, 1fr); }
  .board-frame { max-width: 80vw; max-width: min(80vw, 68vh); }
  .danmaku-slot { height: 48px; }
  .toast { font-size: 13px; padding: 2px 10px; }
  .statcard { display: none; }         /* 极矮屏优先保证棋盘可视面积 */
  .rank-bar { padding: 3px 8px; }
  :root { --gap-app: 5px; }
  .app { padding-top: 4px; }
  .board-area { padding: 4px 0 2px; }
}

/* ============ 手机横屏（矮而宽）：改为左右两栏 ============
   问题：iPhone 横放时视口只有 390px 高。若保持单列竖排，
   顶栏 + HUD + 段位条 + 进度条 + 弹幕槽要占掉约 186px，
   留给棋盘仅剩 ~204px —— 8×8 每格只有 21.8px，远低于
   可点按阈值（约 28px），横屏几乎没法玩。
   方案：宽屏时把「信息列」与「棋盘列」并排 —— 左侧一列放
   HUD/段位/进度/入口，右侧整列留给棋盘。棋盘边长按 88vh 算，
   390px 高的横屏可得 343px 棋盘，每格 38px，手感接近竖屏。 */
@media (orientation: landscape) and (max-height: 560px) {
  .app {
    display: grid;
    grid-template-columns: minmax(180px, 210px) minmax(0, 1fr);
    grid-template-rows: auto auto auto auto 1fr;
    grid-template-areas:
      "top  board"
      "hud  board"
      "rank board"
      "bar  board"
      "foot board";
    align-content: start;
    column-gap: 14px;
    row-gap: 6px;
    max-width: 100%;
    /* 横屏时内容按 grid 排布，min-height 交给视口，
       避免 100dvh + padding 叠加多出 2px 产生滚动条。 */
    min-height: 0;
    height: 100vh;      /* Chrome 61 回退 */
    height: 100dvh;
  }
  .topbar    { grid-area: top;  flex-wrap: wrap; }
  .brand-text h1 { font-size: 15px; }
  .icon-btn { width: 32px; height: 32px; font-size: 15px; }
  .hud       { grid-area: hud; grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .rank-bar  { grid-area: rank; }
  .bar-block { grid-area: bar;  grid-template-columns: 40px minmax(0, 1fr) 42px; }
  .footer    { grid-area: foot; }
  .board-area {
    grid-area: board;
    align-items: center;
    padding: 0;
    min-height: 0;
  }
  /* 高度主导：88vh 保证棋盘一屏放得下且方块够大。
     用 86vh 留出余量，避免 padding + gap 累加后总高超出视口 1~2px 产生滚动条。 */
  .board-frame { max-width: 46vw; max-width: min(46vw, 86vh); }
  .statcard { display: none; }
  .extbar { margin-top: 4px; }
  .legal { margin-top: 4px; font-size: 10px; }
  /* 左列只有 210px 宽，弹幕放两行会把整列撑高导致纵向滚动；
     横屏下回到单行 + 允许省略号截断（竖屏才是主场景）。 */
  .danmaku-slot { height: 28px; }
  .toast { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

  /* 引导层改为覆盖在左侧信息列上，不再压住棋盘 */
  .guide {
    left: 0; right: auto;
    width: 210px;
    width: min(210px, 44vw);
    bottom: 0;
    /* 安全区 padding 见 css/compat.css */
    align-items: flex-end;
    justify-content: flex-start;
  }
  .guide-card { max-width: none; padding: 11px 12px 10px; }
  .guide-text { font-size: 12px; line-height: 1.55; margin-bottom: 9px; }
  .guide-title { font-size: 13.5px; }
  .guide-step { font-size: 9.5px; padding: 1px 5px; }
  .guide-next { font-size: 12px; padding: 7px 15px; }
  .guide-skip { font-size: 11.5px; }
}

/* 宽屏（桌面）：棋盘放大并垂直居中，避免上下留白 */
@media (min-width: 900px) {
  :root { --dm-size: 16px; --dm-size-lg: 18px; --dm-size-sm: 14px; }
  .app {
    max-width: 940px;
    justify-content: center;      /* 整列垂直居中 */
    /* 安全区 padding 见 css/compat.css（桌面端 env() 恒为 0，不影响） */
  }
  .board-area { align-items: center; }
  .board-frame { max-width: 62vh; max-width: min(62vh, 560px); }
  .topbar { padding: 0 4px; }
  :root { --gap-hud: 8px; }
  .stat { padding: 9px 4px; }
  .bar-block { column-gap: 8px; row-gap: 8px; }
  .danmaku-slot { height: 58px; }
  .toast { padding: 4px 16px; }
  :root { --gap-rank: 10px; }
  .rank-bar { padding: 7px 14px; }
  .rank-icon { font-size: 17px; }
  .rank-name { font-size: 13px; }
  .rank-meta { font-size: 11.5px; }
  .streak { font-size: 11.5px; }
  .statcard { max-width: 560px; margin: 0 auto; padding: 9px 12px; }
  .sc-label { font-size: 10.5px; }
  .sc-value { font-size: 16px; }
  .bar-cap { font-size: 12px; }
  .bar-num { font-size: 12.5px; min-width: 56px; }
}


@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
