/* === 麻将战棋 - 仰止学院主题 === */

/* ── 基础重置 ── */
*, *::before, *::after { margin:0; padding:0; box-sizing:border-box; }
html, body { height:100%; font-family:'Noto Serif SC','STSong','SimSun','KaiTi','PingFang SC','Microsoft YaHei',serif; background:#0c0a14; color:#c8c0b8; overflow-x:hidden; }

/* 背景：暮山紫 + 宣纸纹理（CSS渐变模拟） */
body::before {
  content:''; position:fixed; inset:0; z-index:-1;
  background:
    /* 宣纸纤维纹理 */
    repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(180,160,140,0.015) 2px, rgba(180,160,140,0.015) 4px),
    repeating-linear-gradient(90deg, transparent, transparent 3px, rgba(180,160,140,0.01) 3px, rgba(180,160,140,0.01) 6px),
    /* 暮山紫基调 */
    radial-gradient(ellipse at 30% 20%, #1a1530 0%, transparent 55%),
    radial-gradient(ellipse at 70% 85%, #141025 0%, transparent 55%),
    linear-gradient(180deg, #0c0a14 0%, #100e1c 50%, #0a0812 100%);
}

a { color:inherit; text-decoration:none; }
button { cursor:pointer; border:none; border-radius:4px; font-size:0.9rem; padding:10px 20px; transition:all 0.25s; font-family:inherit; }
input, select { border:1px solid rgba(196,163,90,0.25); border-radius:4px; padding:10px 14px; font-size:0.9rem; background:rgba(20,18,30,0.8); color:#c8c0b8; outline:none; font-family:inherit; }
input:focus, select:focus { border-color:#c4a35a; box-shadow:0 0 0 2px rgba(196,163,90,0.15); }

/* ── 导航栏 ── */
#nav { display:flex; align-items:center; justify-content:space-between; padding:10px 24px; background:rgba(14,12,22,0.92); border-bottom:1px solid rgba(196,163,90,0.2); position:sticky; top:0; z-index:100; backdrop-filter:blur(8px); }
#nav .logo { font-size:1.25rem; font-weight:700; color:#c4a35a; letter-spacing:2px; }
#navLinks { display:flex; gap:20px; }
#navLinks a { font-size:0.85rem; opacity:0.6; transition:opacity 0.2s,color 0.2s; letter-spacing:1px; }
#navLinks a:hover, #navLinks a.active { opacity:1; color:#c4a35a; }
#userArea { font-size:0.85rem; }
#loginBtn { cursor:pointer; padding:6px 16px; border-radius:4px; background:rgba(196,163,90,0.08); color:#c4a35a; border:1px solid rgba(196,163,90,0.2); font-size:0.8rem; transition:all 0.2s; }
#loginBtn:hover { background:rgba(196,163,90,0.18); }

/* ── 主容器 ── */
#view { max-width:960px; margin:0 auto; padding:28px 24px; min-height:calc(100vh - 56px); }

/* ── 卡片系统：「」暗金角标 ── */
.card {
  position:relative; background:rgba(16,14,26,0.65); padding:20px 28px 24px 28px; margin-bottom:16px;
  border:none; border-radius:4px;
  box-shadow:0 1px 4px rgba(0,0,0,0.3);
  transition:box-shadow 0.3s;
}
.card:hover { box-shadow:0 2px 12px rgba(0,0,0,0.4); }

/* 卡片角标：CSS border 画线（左上/右下两个 L 形直角角线，竖线长、横线短） */
.card::before, .card::after {
  content:''; position:absolute; width:10px; height:20px;
  border:1px solid rgba(196,163,90,0.3);
  pointer-events:none;
}
.card::before {
  top:0; left:0;
  border-right:none; border-bottom:none;
}
.card::after {
  bottom:0; right:0;
  border-left:none; border-top:none;
}

/* 卡片标题 */
.card h2 { font-size:1.05rem; margin-bottom:14px; color:#c4a35a; font-weight:600; letter-spacing:1px; padding-left:14px; border-bottom:none; position:relative; }
.card h2::before { content:''; position:absolute; left:0; top:2px; bottom:2px; width:2px; background:rgba(196,163,90,0.5); border-radius:1px; }
/* 面板统一入场：上方滑入（淡入 + 从上方 6px 滑下，0.2s，无缩放） */
@keyframes fadeIn { from { opacity:0; transform:translateY(-6px); } to { opacity:1; transform:translateY(0); } }
@keyframes overlayIn { from { opacity:0; } to { opacity:1; } }
.card strong { color:#d4c8a0; font-weight:600; }

/* ── 按钮系统 ── */
.btn { display:inline-block; padding:10px 20px; border-radius:4px; font-size:0.9rem; transition:all 0.25s; font-weight:500; letter-spacing:0.5px; font-family:inherit; }
/* 主按钮：朱砂红 */
.btn-primary { background:#8b3a3a; color:#f0d8c0; box-shadow:0 2px 6px rgba(139,58,58,0.35); border:1px solid rgba(180,100,100,0.3); }
.btn-primary:hover { background:#9b4444; transform:translateY(-1px); box-shadow:0 4px 14px rgba(139,58,58,0.5); }
.btn-primary:disabled { opacity:0.35; transform:none; box-shadow:none; cursor:not-allowed; }
/* 次按钮：暗金边框 */
.btn-secondary { background:rgba(30,26,20,0.7); color:#c8c0b0; border:1px solid rgba(196,163,90,0.3); }
.btn-secondary:hover { background:rgba(40,34,26,0.8); border-color:rgba(196,163,90,0.5); color:#d4c8a0; }
.btn-secondary:disabled { opacity:0.35; cursor:not-allowed; }
.btn-secondary.active { background:rgba(212,168,67,0.25); border-color:#d4a843; color:#d4a843; }
/* 金色按钮：分享入口专用（胡牌后显眼） */
.btn-gold { background:#c4a35a; color:#1a1408; border:1px solid #d4a843; font-weight:600; }
.btn-gold:hover { background:#d4a843; color:#1a1408; }
/* 危险按钮 */
.btn-danger { background:#5a2020; color:#e0a0a0; border:1px solid rgba(160,80,80,0.3); }
.btn-danger:hover { background:#6e2828; }
.btn-danger:disabled { opacity:0.35; cursor:not-allowed; }

/* 注册同意勾选：行布局（框样式统一由下方 input[type="checkbox"] 提供，避免两套样式打架） */
.agree-row { display:flex; align-items:center; gap:8px; margin-top:12px; font-size:0.78rem; color:#9a9088; line-height:1.7; cursor:pointer; }
.agree-row a { color:#c4a35a; }

/* 隐私政策页排版（#privacy）：文案在 ui.js 的 renderPrivacy（t('字面量')），样式集中在这里 */
.privacy-card h3 { color:#c4a35a; font-size:1rem; margin:16px 0 8px; }
.privacy-card p { font-size:0.85rem; color:#c8c0b8; line-height:2; }
.privacy-card ul { font-size:0.85rem; color:#c8c0b8; line-height:2; padding-left:1.2em; }
.privacy-card .priv-updated { font-size:0.78rem; color:#9a9088; margin-bottom:6px; line-height:1.6; }
/* 尺寸 */
.btn-narrow { box-sizing:border-box; padding:0 10px; height:38px; min-width:0; width:100%; display:inline-flex; align-items:center; justify-content:center; white-space:nowrap; font-size:0.82rem; }
.btn-sm { padding:6px 14px; font-size:0.8rem; }
.btn-block { display:block; width:100%; text-align:center; }

/* ── 表单 ── */
.form-group { margin-bottom:14px; }
.form-group label { display:block; margin-bottom:4px; font-size:0.85rem; color:#9a9088; letter-spacing:0.5px; }
.form-group input, .form-group select { width:100%; }

/* 下拉选择框 */
select {
  appearance:none; -webkit-appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23c4a35a' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 12px center; padding-right:32px; cursor:pointer;
}
select option { background:#1a1628; color:#c8c0b8; }

/* 复选框：竖长条无勾方框（6×18，最初版 4×18 加宽到 6）——未选暗底描边、选中亮金填充（明暗交替），
   不再绘制勾（旧的 ::after 勾只适配固定尺寸，缩放后会与框错位） */
input[type="checkbox"] {
  -webkit-appearance:none; appearance:none; width:6px; height:18px; padding:0; flex-shrink:0;
  border:2px solid rgba(196,163,90,0.3); border-radius:3px; cursor:pointer;
  background:rgba(20,18,30,0.8); vertical-align:middle; margin:0;
  transition:background 0.2s, border-color 0.2s, box-shadow 0.2s;
}
input[type="checkbox"]:checked {
  background:#c4a35a; border-color:#c4a35a; box-shadow:0 0 6px rgba(196,163,90,0.5);
}
input[type="checkbox"]:focus-visible { outline:2px solid rgba(196,163,90,0.6); outline-offset:2px; }

/* 音量滑块 */
input[type="range"] {
  -webkit-appearance:none; appearance:none; height:6px; border-radius:3px;
  background:rgba(20,18,30,0.8); border:1px solid rgba(196,163,90,0.2); padding:0; cursor:pointer;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance:none; width:18px; height:18px; border-radius:50%;
  background:#c4a35a; border:2px solid rgba(14,12,22,0.8); cursor:pointer;
  box-shadow:0 0 6px rgba(196,163,90,0.4);
}
input[type="range"]::-moz-range-thumb {
  width:18px; height:18px; border-radius:50%;
  background:#c4a35a; border:2px solid rgba(14,12,22,0.8); cursor:pointer;
}

/* ── 模态框 ── */
/* ── 交互区禁止文本/元素选中（防止拖选蓝条覆盖棋子与面板）── */
#gameContainer,                 /* 游戏页：棋盘/手牌/按钮/状态栏/吃碰杠面板 */
#demoBoard,                     /* 大厅演示棋盘 */
#replayBoardArea,               /* 历史回放棋盘 */
#replayHand1, #replayHand2,     /* 历史回放手牌区 */
.win-pattern-box,               /* 复盘弹窗的胡牌型显示区 */
#nav, .logo,                    /* 顶部导航栏与 logo */
.btn,                           /* 所有按钮（防连点时拖选文字） */
.btn-mute-fab, .btn-lang-fab,   /* 右下角静音/语言切换悬浮按钮 */
.board,                         /* 所有棋盘（主游戏/教程/预览等） */
#volSlider, #bgmVolSlider,      /* 设置页音量滑块 */
#roomList {                     /* 大厅房间列表卡片主体 */
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}
#roomList .room-code {          /* 房间码单独放行：可选中复制分享给朋友 */
  user-select: text;
  -webkit-user-select: text;
}

/* ── 禁止图片被原生拖拽（棋子/牌背/图标被按住拖动会拖出幽灵图）── */
img {
  -webkit-user-drag: none;
  user-drag: none;
}

/* 弹窗遮罩：内容超出视口时可滚动（手机 / 横屏 / 内容很长的弹窗）
   注意：不能用 align-items:center 居中——flex 居中会让超高内容的**顶部**溢出到滚动区之外，
   导致“看得到底部、却滚不到顶部”。改用 .modal 的 margin:auto 居中，两个方向都安全。 */
.modal-overlay { position:fixed; inset:0; background:rgba(0,0,0,0.8); backdrop-filter:blur(6px); z-index:200; display:flex; animation:overlayIn 0.22s ease; overflow-y:auto; overflow-x:hidden; -webkit-overflow-scrolling:touch; padding:16px; }
.modal { position:relative; margin:auto; background:rgba(18,16,28,0.95); border-radius:0; padding:28px 32px; min-width:0; max-width:90vw; border:1px solid rgba(196,163,90,0.2); box-shadow:0 8px 32px rgba(0,0,0,0.6); animation:fadeIn 0.2s cubic-bezier(0.22, 0.61, 0.36, 1); }
/* 站内弹窗统一：直角矩形 + L 形角线（左上/右下，竖长横短；与消息面板/卡片同款）——
   内缩 10px：不压在弹窗边框上（1px 边框 + 28/32px 内边距） */
.modal::before, .modal::after {
  content: '';
  position: absolute;
  width: 10px;
  height: 20px;
  border: 1px solid rgba(196, 163, 90, 0.3);
  pointer-events: none;
}
.modal::before { top: 10px; left: 10px; border-right: none; border-bottom: none; }
.modal::after { bottom: 10px; right: 10px; border-left: none; border-top: none; }
.modal h2 { color:#c4a35a; margin-bottom:18px; font-size:1.05rem; letter-spacing:1px; }
.modal-btns { display:flex; gap:10px; margin-top:20px; justify-content:flex-end; }

/* ── Toast ── */
.toast { position:fixed; top:70px; left:50%; transform:translateX(-50%); padding:10px 24px; border-radius:4px; font-size:0.85rem; z-index:300; opacity:0; transition:opacity 0.3s; pointer-events:none; letter-spacing:0.5px; backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px); }
.toast.show { opacity:1; }
.toast.success { background:rgba(26,80,40,0.55); color:#b0e8b0; border:1px solid rgba(50,130,60,0.35); }
.toast.error   { background:rgba(80,22,22,0.55); color:#e8b0b0; border:1px solid rgba(130,40,40,0.35); }
.toast.info    { background:rgba(22,50,75,0.55); color:#b0c8e8; border:1px solid rgba(40,80,130,0.35); }
.toast.warning { background:rgba(80,65,20,0.55); color:#e8d8b0; border:1px solid rgba(130,100,40,0.35); }

/* ── 首屏（登录前大厅）：小棋盘 + 游戏说明 ── */
.hero-flex { display:flex; gap:28px; align-items:center; flex-wrap:wrap; }
.hero-board { flex:0 0 auto; margin-left:22px; }
.hero-text { flex:1; min-width:260px; }
@media (max-width:768px) {
  .hero-board { margin-left:16px; }
  .hero-flex { justify-content:center; }
  .hero-text { text-align:center; }
}

/* ── 游戏棋盘 ── */
#gameContainer { display:flex; flex-wrap:wrap; gap:24px; justify-content:center; }
#boardWrap { flex:0 0 auto; }
#sidePanel { flex:1; min-width:250px; max-width:340px; }

.board {
  /* 皮肤装饰（楚河漢界文字）定位用的几何变量：随响应式同步 */
  --cw: 60px; --board-pad: 5px;
  display:grid; grid-template-columns:repeat(7,60px); grid-template-rows:repeat(7,60px);
  gap:0; padding:5px; border-radius:4px; position:relative;
  background:linear-gradient(135deg,#0e0c18,#161420);
  border:2px solid rgba(196,163,90,0.3);
  box-shadow: inset 0 2px 16px rgba(0,0,0,0.5), 0 4px 20px rgba(0,0,0,0.5);
}

.cell { display:flex; align-items:center; justify-content:center; position:relative; cursor:pointer; border-radius:0; transition:all 0.2s;
  border:0.5px solid rgba(180,140,90,0.25); }

/* 大厅演示棋盘：纯展示不可交互，悬停不改变光标/样式 */
#demoBoard .cell { cursor:default; }

/* 第1行和第5-6行：古绢色（淡黄宣纸纹理） */
.cell.light { background:#d8c19c; }
.cell.dark  { background:#b6906a; }

/* 牌河第3行（row=3）：天青釉色 */
.cell.river.light { background:#8bc0c0; }
.cell.river.dark  { background:#65a3a4; }

/* 归属方底色：棋子着色（中底深度 + 内侧光晕，双方更易分辨） */
.piece-stack { border:2px solid transparent; border-radius:4px; padding:1px; line-height:0; }
.cell.my-piece .piece-stack { border-color:rgba(35,128,190,0.95); background:rgba(39,154,231,0.24); box-shadow: inset 0 0 6px rgba(41,128,185,0.25); }
.cell.opp-piece .piece-stack { border-color:rgba(216,50,39,0.9); background:rgba(230,64,46,0.26); box-shadow: inset 0 0 6px rgba(210,55,45,0.25); }

/* ── 高亮样式（仰止学院风：半透明底色 + 暗金内边框）── */
/* 选中格 */
.cell.selected {
  box-shadow: inset 0 0 0 3px #c4a35a !important;
  background: rgba(196, 163, 90, 0.12) !important;
}
/* 可移动位置 — 按牌型区分颜色（仰止学院暗金色系 + 小圆点） */
.cell.possible-move-single   { background: rgba(196,163,90,0.10) !important; box-shadow: inset 0 0 0 0.15em rgba(196,163,90,0.50); }
.cell.possible-move-single::after   { content:''; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:28%; height:28%; border-radius:50%; background:rgba(196,163,90,0.55); pointer-events:none; z-index:5; }
.cell.possible-move-pair     { background: rgba(155,130,175,0.10) !important; box-shadow: inset 0 0 0 0.15em rgba(155,130,175,0.50); }
.cell.possible-move-pair::after     { content:''; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:28%; height:28%; border-radius:50%; background:rgba(155,130,175,0.55); pointer-events:none; z-index:5; }
.cell.possible-move-sequence { background: rgba(111,165,160,0.10) !important; box-shadow: inset 0 0 0 0.15em rgba(111,165,160,0.50); }
.cell.possible-move-sequence::after { content:''; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:28%; height:28%; border-radius:50%; background:rgba(111,165,160,0.55); pointer-events:none; z-index:5; }
/* 刻子改走马步后，把原红色让给杠子（强度：杠 > 刻），两行配对交换 */
.cell.possible-move-triplet  { background: rgba(205,185,155,0.10) !important; box-shadow: inset 0 0 0 0.15em rgba(205,185,155,0.50); }
.cell.possible-move-triplet::after  { content:''; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:28%; height:28%; border-radius:50%; background:rgba(205,185,155,0.55); pointer-events:none; z-index:5; }
.cell.possible-move-quad     { background: rgba(175,105,95,0.10) !important; box-shadow: inset 0 0 0 0.15em rgba(175,105,95,0.50); }
.cell.possible-move-quad::after     { content:''; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:28%; height:28%; border-radius:50%; background:rgba(175,105,95,0.55); pointer-events:none; z-index:5; }
/* 己方格上不显示圆点（圆点会遮挡棋子） */
.cell.possible-move-single.my-piece::after,
.cell.possible-move-pair.my-piece::after,
.cell.possible-move-sequence.my-piece::after,
.cell.possible-move-triplet.my-piece::after,
.cell.possible-move-quad.my-piece::after { display:none; }
/* 可提子位置（暗红脉冲） */
.cell.possible-capture {
  background: rgba(175,85,75,0.20) !important;
  box-shadow: inset 0 0 0 0.15em rgba(175,85,75,0.55);
  animation: captureCellPulse 1.6s ease-in-out infinite;
}
@keyframes captureCellPulse {
  0%, 100% { box-shadow: inset 0 0 0 0.1em rgba(200, 70, 55, 0.35); }
  50% { box-shadow: inset 0 0 0 0.15em rgba(200, 70, 55, 0.55); }
}
/* 可打入位置 — 边框 + 小圆点 */
.cell.possible-place {
  background: transparent !important;
  box-shadow: inset 0 0 0 0.15em rgba(196, 163, 90, 0.40);
}
.cell.possible-place::after {
  content: '';
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 14px; height: 14px;
  border-radius: 50%;
  background: rgba(196, 163, 90, 0.50);
  pointer-events: none; z-index: 5;
}
.cell.possible-place.my-piece::after { display: none; }
.cell.possible-place.opp-piece::after { background: rgba(200, 70, 55, 0.60); }
/* 对手走棋高亮：颜色跟随格子归属方（蓝格蓝系、红格红系），脉冲摆幅收窄（不淡到看不清）。
   描边加宽内缩：方形描边覆盖牌底圆角四角处的空隙，不露尖点 */
.cell.highlight-opp-to { --opp-c: 168, 68, 46; --opp-bg: 220, 70, 55;
  outline: 6px solid rgba(var(--opp-c), 0.6);
  outline-offset: -6px;
  animation: oppToPulse 0.8s ease-in-out infinite alternate;
}
/* 目标格的牌堆一起闪：红色牌下方 outline 不明显，牌堆边框/底色同步呼吸 */
.cell.highlight-opp-to .piece-stack {
  animation: oppToStackPulse 0.8s ease-in-out infinite alternate;
}
.cell.highlight-opp-from { --opp-c: 168, 68, 46;
  outline: 6px solid rgba(var(--opp-c), 0.9);
  outline-offset: -6px;
  box-shadow: inset 0 0 10px rgba(var(--opp-c), 0.3);
  animation: oppFromPulse 0.8s ease-in-out infinite alternate;
}
/* 交叉着色：默认红=对方触发；自己（by===myPlayer）触发→蓝，覆盖 from/to 默认色 */
.cell.highlight-opp-by-me { --opp-c: 41, 128, 185; --opp-bg: 52, 152, 219; }
@keyframes oppToPulse {
  from { outline-color: rgba(var(--opp-c), 0.25); }
  to   { outline-color: rgba(var(--opp-c), 0.7); }
}
@keyframes oppToStackPulse {
  from { border-color: rgba(var(--opp-c), 0.30); background: rgba(var(--opp-bg), 0.10); box-shadow: inset 0 0 6px rgba(var(--opp-c), 0.12); }
  to   { border-color: rgba(var(--opp-c), 0.95); background: rgba(var(--opp-bg), 0.30); box-shadow: inset 0 0 12px rgba(var(--opp-c), 0.45); }
}
@keyframes oppFromPulse {
  from { outline-color: rgba(var(--opp-c), 0.25); }
  to   { outline-color: rgba(var(--opp-c), 0.7); }
}

/* 吃碰杠选中高亮：亮金描边 + 月光白外晕——金保持主题与木色底区分，白光晕拉升对比度
   （暗金 #c4a35a 已用于胡牌高亮；与红/蓝上一步高亮均可区分） */
.cell.cpg-highlight { --cpg-c: 246, 182, 43; --cpg-w: 255, 250, 235; }
.cell.cpg-highlight {
  outline: 8px solid rgba(var(--cpg-c), 0.95);
  outline-offset: -8px;
  box-shadow: inset 0 0 0 2px rgba(30, 22, 14, 0.9), 0 0 6px rgba(var(--cpg-w), 0.6), 0 0 2px rgba(var(--cpg-c), 0.7);
  animation: cpgPulse 0.8s ease-in-out infinite alternate;
}
@keyframes cpgPulse {
  from { outline-color: rgba(var(--cpg-c), 0.5); }
  to { outline-color: rgba(var(--cpg-c), 1); }
}

/* 取消选择：淡出（覆盖脉冲动画，0.2s 后由 JS 移除高亮类） */
.cell.cpg-highlight.cpg-fade {
  animation: cpgFadeOut 0.2s ease-out forwards;
}
.hand-tile.cpg-highlight-tile.cpg-fade .tile-img {
  animation: cpgHandFadeOut 0.2s ease-out forwards;
}
@keyframes cpgFadeOut {
  from {
    outline-color: rgba(var(--cpg-c), 1);
    box-shadow: inset 0 0 0 2px rgba(30, 22, 14, 0.9), 0 0 6px rgba(var(--cpg-w), 0.6), 0 0 2px rgba(var(--cpg-c), 0.7);
  }
  to {
    outline-color: rgba(var(--cpg-c), 0);
    box-shadow: inset 0 0 0 2px rgba(30, 22, 14, 0), 0 0 0 rgba(var(--cpg-w), 0), 0 0 0 rgba(var(--cpg-c), 0);
  }
}
@keyframes cpgHandFadeOut {
  from {
    box-shadow: 0 0 10px rgba(var(--cpg-w), 0.7), 0 0 4px rgba(var(--cpg-c), 0.6);
    transform: translateY(-6px);
  }
  to {
    box-shadow: 0 0 0 rgba(var(--cpg-w), 0), 0 0 0 rgba(var(--cpg-c), 0);
    transform: translateY(0);
  }
}

/* 吃碰杠面板退场动画（淡出） */
.cpg-out { animation: cpgOut 0.22s ease forwards; }
@keyframes cpgOut {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(6px); }
}

/* 手牌（均为自己的牌）吃碰杠高亮：亮金描边 + 月光白外晕（同棋盘格） */
.hand-tile.cpg-highlight-tile { --cpg-c: 246, 182, 43; --cpg-w: 255, 250, 235; }
.hand-tile.cpg-highlight-tile .tile-img {
  outline: 2px solid rgba(var(--cpg-c), 1);
  outline-offset: 1px;
  box-shadow: 0 0 10px rgba(var(--cpg-w), 0.7), 0 0 4px rgba(var(--cpg-c), 0.6);
  transform: translateY(-6px);
  transition: transform 0.15s;
  animation: cpgHandPulse 0.8s ease-in-out infinite alternate;
}
/* 摆棋模式：玩家1手牌在上方区（裸 img），吃碰杠高亮同等样式 */
#oppHand img.cpg-highlight-tile { --cpg-c: 246, 182, 43; --cpg-w: 255, 250, 235; }
#oppHand img.cpg-highlight-tile {
  outline: 2px solid rgba(var(--cpg-c), 1);
  outline-offset: 1px;
  box-shadow: 0 0 10px rgba(var(--cpg-w), 0.7), 0 0 4px rgba(var(--cpg-c), 0.6);
  transform: translateY(-6px);
  transition: transform 0.15s;
  animation: cpgHandPulse 0.8s ease-in-out infinite alternate;
}
#oppHand img.cpg-highlight-tile.cpg-fade { animation: cpgHandFadeOut 0.2s ease-out forwards; }
/* 摆棋模式：玩家1回合时上方手牌选中高亮 */
#oppHand img.selected {
  box-shadow: 0 0 0 3px #c4a35a, 0 0 14px rgba(196,163,90,0.5);
  border-radius: 3px;
}
@keyframes cpgHandPulse {
  from { box-shadow: 0 0 6px rgba(var(--cpg-w), 0.5), 0 0 3px rgba(var(--cpg-c), 0.5); }
  to   { box-shadow: 0 0 12px rgba(var(--cpg-w), 0.75), 0 0 5px rgba(var(--cpg-c), 0.7); }
}

.cell.river.ripple { animation: riverRipple 1.2s ease-out; }
@keyframes riverRipple {
  0% { box-shadow:inset 0 0 0 0 rgba(200,230,255,0.6); }
  50% { box-shadow:inset 0 0 0 5px rgba(200,230,255,0.25); }
  100% { box-shadow:inset 0 0 0 0 rgba(200,230,255,0); }
}

/* 胡牌高亮：金色描边呼吸 + 牌面白色斜向扫光（组成胡牌的格子，终局常驻）。
   牌图不裁剪（阴影/微超底部保留）；光带放在独立的 .win-clip 裁切层内扫动，
   裁切层用牌图自身做 mask（牌图已转 RGBA，alpha 精确贴合牌形：圆角、
   object-fit:contain 的左右留白都是透明，扫光不会超出） */
.cell.win-highlight {
  outline: 5px solid rgba(196,163,90,0);
  outline-offset: -5px;
  box-shadow: none;   /* 胡牌高光优先：清掉「上一步」（highlight-opp-from）的内阴影 */
  animation:
    winFlash 0.6s ease-out 1,
    winBorderPulse 1.4s ease-in-out 0.6s infinite alternate;
}
/* 胡牌高光优先于「上一步」：牌堆的红/蓝上一步脉冲让位（与金色描边同时存在会花） */
.cell.win-highlight .piece-stack { animation: none; }
@keyframes winFlash {
  0%   { outline-color: rgba(196,163,90,0); }
  40%  { outline-color: rgba(196,163,90,1); }
  100% { outline-color: rgba(196,163,90,0.15); }
}
@keyframes winBorderPulse {
  from { outline-color: rgba(196,163,90,0.15); }
  to   { outline-color: rgba(196,163,90,0.95); }
}
.win-shine {
  position:relative; display:inline-block; line-height:0;
}
.win-clip {
  position:absolute; left:0; top:0; right:0; bottom:0;
  overflow:hidden; pointer-events:none;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-size:contain; mask-size:contain;
  -webkit-mask-position:center; mask-position:center;
}
.win-bar {
  position:absolute; top:0; left:-75%; width:50%; height:100%;
  background: linear-gradient(120deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.45) 50%, rgba(255,255,255,0) 100%);
  transform: skewX(-20deg);
  animation: winShine 2.5s infinite;
  pointer-events:none;
}
@keyframes winShine {
  0%        { left: -75%; }
  60%, 100% { left: 125%; }
}

/* 回放棋盘（replay-cell）胡牌高亮：同款金色描边呼吸 + 牌面白扫光（光带走 win-clip） */
.replay-cell.win-highlight {
  outline: 5px solid rgba(196,163,90,0);
  outline-offset: -5px;
  animation:
    winFlash 0.6s ease-out 1,
    winBorderPulse 1.4s ease-in-out 0.6s infinite alternate;
}

/* ── 移动动画：落点冲击波（滑动/打入落格的金色光圈，短促不拖尾） ── */
.cell.impact-pulse::before {
  content: ''; position: absolute; inset: 8%; border-radius: 6px;
  border: 2px solid rgba(212, 168, 67, 0.8);
  pointer-events: none; z-index: 6;
  animation: impactRing 0.55s ease-out forwards;
}
@keyframes impactRing {
  0%   { transform: scale(0.6); opacity: 0.8; }
  100% { transform: scale(1.2); opacity: 0; }
}

/* 牌堆样式（参考联机版：顶牌+数量+牌型标签） */
.piece-stack { position:relative; display:flex; flex-wrap:wrap; flex-direction:column; gap:1px; align-items:center; justify-content:center; width:90%; height:90%; }
.piece-count-badge { position:absolute; top:1px; right:1px; min-width:16px; height:15px; border-radius:3px; background:rgba(30,20,15,0.85); color:#d4a843; font-size:clamp(7px,1.9vw,0.6rem); display:flex; align-items:center; justify-content:center; font-weight:600; padding:0 3px; letter-spacing:0.5px; line-height:1; }
.piece-type-badge { position:absolute; bottom:1px; left:1px; font-size:clamp(7px,1.9vw,0.6rem); background:rgba(30,20,15,0.85); color:#d4a843; padding:0 clamp(2px,0.5vw,4px); border-radius:3px; line-height:1.3; font-weight:500; }
/* 牌型文字跟随玩家色（低饱和仰止学院风：青瓷蓝 / 陶土红） */
.cell.my-piece .piece-type-badge { color:#9abcce; }
.cell.opp-piece .piece-type-badge { color:#d6967a; }
.cell.my-piece .piece-count-badge { color:#9abcce; }
.cell.opp-piece .piece-count-badge { color:#d6967a; }
@keyframes pulse { 0%,100%{opacity:0.6} 50%{opacity:1} }

.tile-img { display:block; width:40px; height:54px; border-radius:2px; object-fit:contain; filter:drop-shadow(0 1px 3px rgba(0,0,0,0.35)); }
.tile-img.back { filter:brightness(1) drop-shadow(0 1px 3px rgba(0,0,0,0.35)); }

/* ── 手牌 ── */
#handArea { display:flex; flex-wrap:wrap; gap:5px; padding:10px 0; min-height:102px; align-content:flex-start; align-items:flex-start; }
/* 手牌新增牌进入动画（回放/对战共用） */
.hand-enter { animation: handIn 0.25s ease; }
.hand-pending { opacity: 0; }
@keyframes handIn {
  from { transform: scale(0.4); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

.hand-tile { cursor:pointer; border-radius:3px; transition:transform 0.2s, box-shadow 0.2s, opacity 0.2s; opacity:0.92; }
.hand-tile:hover { transform:translateY(-3px); opacity:1; }
.hand-tile:active { transform:translateY(-1px); }
.hand-tile.selected .tile-img { box-shadow:0 0 0 3px #c4a35a, 0 0 14px rgba(196,163,90,0.5); border-radius:3px; }

/* 对手手牌（空时由隐形占位牌维持一行高度，0↔1 张不伸缩） */
#oppHand { display:flex; flex-wrap:wrap; gap:4px; padding:4px 0; align-content:flex-start; align-items:flex-start; }
#oppHand .hand-ghost { visibility:hidden; pointer-events:none; }

/* ── 状态栏 ── */
#statusBar { padding:10px 16px; border-radius:4px; margin-bottom:12px; font-size:0.9rem; text-align:center; font-weight:500; letter-spacing:1px; }
#statusBar.info    { background:rgba(40,60,90,0.5); color:#b0c8e8; border-left:3px solid #5080b8; }
#statusBar.warning { background:rgba(70,55,20,0.5); color:#e8d8b0; border-left:3px solid #c4a35a; }
#statusBar.success { background:rgba(30,70,35,0.5); color:#b0e8b0; border-left:3px solid #50a050; }
#statusBar.error   { background:rgba(70,25,25,0.5); color:#e8b0b0; border-left:3px solid #b85050; }

/* ── 匹配等待 ── */
.spinner {
  display:inline-block; width:16px; height:16px; border:2px solid rgba(196,163,90,0.2);
  border-top-color:#c4a35a; border-radius:50%; animation:spin 0.8s linear infinite; vertical-align:middle; margin-right:6px;
}
@keyframes spin { to { transform:rotate(360deg); } }

/* ── 棋盘行列标签 ── */
.board-wrap { position:relative; }
.board-labels-col { position:absolute; left:-20px; top:5px; bottom:5px; display:flex; flex-direction:column; justify-content:space-around; pointer-events:none; }
.board-labels-col span { font-size:0.6rem; color:rgba(196,163,90,0.35); }
.board-labels-row { position:absolute; left:5px; right:5px; bottom:-18px; display:flex; justify-content:space-around; pointer-events:none; }
.board-labels-row span { font-size:0.6rem; color:rgba(196,163,90,0.35); }

/* ── 终局算番面板（棋盘下方原地弹出）── */
/* 与棋盘拉开间距：棋盘下方紧邻行列标签（.board-labels-row 在棋盘外 18px 处），再留出呼吸空间 */
#fanPanelArea { margin-top:32px; }
#fanPanelArea:empty { display:none; }

/* 算番面板 · 宝牌牌位：指示牌小图 + 已获宝牌逐张 + 牌背补位（凑满 5 张） */
.fan-dora { display:flex; align-items:center; gap:6px; }
.fan-dora-label { font-size:0.72rem; color:#9a9088; flex:none; }
.fan-dora-tiles { display:flex; gap:1px; }
.fan-tile { width:20px; height:26px; object-fit:contain; }
/* 指示牌：淡蓝描边区分（它是明牌信息，不是自己手里的宝牌） */
.fan-tile-ind { box-shadow:0 0 0 1px rgba(143,176,208,0.55); border-radius:2px; }
/* 未凑满的宝牌位：牌背，压低透明度避免抢眼 */
.fan-tile-back { opacity:0.32; }

/* ── 空状态 ── */
#handArea:empty::after { content:'手牌为空'; color:#605a50; font-size:0.85rem; padding:10px 0; letter-spacing:1px; }
html[lang="en"] #handArea:empty::after { content:'Hand is empty'; }

/* ── 历史/复盘 ── */
#historyList .card { cursor:pointer; transition:transform 0.2s, box-shadow 0.2s; }
#historyList .card:hover { transform:translateY(-2px); }

/* ── 响应式 ── */
@media (max-width:768px) {
  #view { padding:14px 10px; }
  /* 弹窗：窄屏收窄内边距并撑满可用宽度（宽屏时弹窗按内容自适应收缩） */
  .modal-overlay { padding:10px; }
  .modal { padding:18px 14px; max-width:100%; width:100%; }
  #gameContainer { flex-direction:column; align-items:center; gap:14px; }
  #sidePanel { width:100%; max-width:100%; min-width:100%; }
  #boardWrap { width:100%; display:flex; flex-direction:column; align-items:center; }
  .board { grid-template-columns:repeat(7, minmax(36px, 11vw)); grid-template-rows:repeat(7, minmax(36px, 11vw)); gap:0; padding:3px; --cw:clamp(36px, 11vw, 999px); --board-pad:3px; }
  /* 牌面随格宽缩放：之前上限 36px，720 宽时格子约 79px，牌面卡在 36px，留白越拉越大。
     0.62 / 0.82 与桌面 40×54 / 60px 格的比例接近，同时保证叠牌仍放得下。 */
  .board .tile-img { width:calc(var(--cw) * 0.62); height:calc(var(--cw) * 0.82); }
  .card { padding:16px; margin-bottom:12px; }
  .card h2 { font-size:0.95rem; }
  .btn { padding:8px 14px; font-size:0.85rem; }
  #handArea { padding:8px 4px; gap:4px; }
  #oppHand { flex-wrap:wrap; }
  #nav { padding:8px 12px; }
  #nav .logo { font-size:1rem; }
  #navLinks { gap:8px; }
  #navLinks a { font-size:0.7rem; }
  .board-labels-col { left:-16px; }
  .board-labels-col span, .board-labels-row span { font-size:0.5rem; }
  button, .btn { min-height:36px; }
  .hand-tile, .cell { -webkit-tap-highlight-color:transparent; }
}

@media (max-width:400px) {
  .board { grid-template-columns:repeat(7, minmax(28px, 10vw)); grid-template-rows:repeat(7, minmax(28px, 10vw)); --cw:clamp(28px, 10vw, 999px); }
  .board .tile-img { width:calc(var(--cw) * 0.62); height:calc(var(--cw) * 0.82); }
}
/* 吃碰杠高亮标签：当多牌格子的非顶牌被选中时显示 */
.cell.cpg-highlight .cpg-tile-label {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: rgba(10, 8, 4, 0.92);
  border: 1px solid rgba(168, 68, 46, 0.9);
  border-radius: 6px;
  padding: 4px 8px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.75rem;
  color: #e0b48c;
  font-weight: 700;
  z-index: 15;
  pointer-events: none;
  white-space: nowrap;
  box-shadow: 0 2px 12px rgba(0,0,0,0.6);
}
.cell.cpg-highlight .cpg-tile-label .tile-img {
  width: 24px;
  height: 32px;
  flex-shrink: 0;
}

/* 解锁后悬浮提示 */
#creditNote[title] {
  position: relative;
}
#creditNote[title]:hover::after {
  content: attr(title);
  position: absolute;
  bottom: 120%;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(10,8,4,0.92);
  color: #c4a35a;
  border: 1px solid #4a4038;
  border-radius: 4px;
  padding: 4px 10px;
  font-size: 0.65rem;
  white-space: nowrap;
  z-index: 20;
  pointer-events: none;
}

/* 回放步骤变化高亮：内圈描边（深度）+ 描边呼吸脉冲；变化格青色，目标绿/旧格红保持语义 */
.replay-step-change { --hl: 64,224,255; z-index: 5; }
.replay-step-to     { --hl: 46,204,113; }
.replay-step-from   { --hl: 231,76,60; }
.replay-step-change, .replay-step-to, .replay-step-from {
  outline: 6px solid rgba(var(--hl), 0.85);
  outline-offset: -6px;
  box-shadow: inset 0 0 10px rgba(var(--hl), 0.35);
  animation: replayStepPulse 0.8s ease-in-out infinite alternate;
}
@keyframes replayStepPulse {
  from { outline-color: rgba(var(--hl), 0.3); }
  to   { outline-color: rgba(var(--hl), 1); }
}

/* 回放棋盘：双方牌底色加深（与对局界面一致的中底深度） */
.replay-cell.replay-p1 { background-image: linear-gradient(rgba(39,154,231,0.24), rgba(39,154,231,0.24)); box-shadow: inset 0 0 6px rgba(41,128,185,0.25); }
.replay-cell.replay-p2 { background-image: linear-gradient(rgba(230,64,46,0.26), rgba(230,64,46,0.26)); box-shadow: inset 0 0 6px rgba(210,55,45,0.25); }

/* 帮助弹窗小棋盘：可走位复用主棋盘 possible-move-* 组件样式；纯展示禁手型光标 */
#pieceHelpBody .cell { cursor: default; }

/* ===== 顶部账号菜单 + 未读消息红点 ===== */
#loginBtn { position: relative; }
#loginBtn.has-unread::after {
  content: '';
  position: absolute;
  top: -2px;
  right: -2px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #e05555;
  box-shadow: 0 0 0 2px rgba(20, 16, 12, 0.9);
  pointer-events: none;
}
.user-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  min-width: 150px;
  background: #1a1a2e;
  border: 1px solid #3a2a1e;
  border-radius: 8px;
  padding: 4px;
  z-index: 300;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
.user-menu-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 9px 12px;
  background: transparent;
  border: 0;
  border-radius: 6px;
  color: #d0d0d0;
  font-size: 0.85rem;
  cursor: pointer;
  text-align: left;
}
.user-menu-item:hover { background: rgba(196, 163, 90, 0.12); color: #c4a35a; }
.user-menu-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 8px;
  background: #e05555;
  color: #fff;
  font-size: 0.68rem;
  font-weight: 700;
}

/* ── 消息面板：直角 + L 形角线已统一到通用 .modal（见文件顶部），此处无需专属规则 ── */

.msg-item {
  position: relative;
  padding: 10px 4px 10px 12px;
  border-bottom: 1px solid rgba(196, 163, 90, 0.12);
  cursor: pointer;
  transition: background 0.2s;
}
.msg-list > .msg-item:last-child { border-bottom: none; }
.msg-item:hover { background: rgba(196, 163, 90, 0.05); }
/* 左侧金色竖线：与卡片标题同款；未读/展开时加亮 */
.msg-item::before {
  content: '';
  position: absolute;
  left: 0;
  top: 12px;
  bottom: 12px;
  width: 2px;
  border-radius: 1px;
  background: rgba(196, 163, 90, 0.30);
  transition: background 0.2s;
}
.msg-item.msg-new::before, .msg-item.open::before { background: rgba(196, 163, 90, 0.85); }

.msg-head { display: flex; align-items: center; gap: 8px; }
.msg-title {
  flex: 1 1 auto;
  min-width: 0;
  color: #e8e0d4;
  font-weight: 600;
  font-size: 0.9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.msg-item.open .msg-title { color: #c4a35a; }
.msg-time { flex: 0 0 auto; color: #9a9088; font-size: 0.72rem; }
.msg-dot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: #e05555; }
.msg-summary {
  color: #9a9088;
  font-size: 0.82rem;
  line-height: 1.6;
  margin-top: 5px;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.msg-body {
  display: none;
  color: #d8d0c4;
  font-size: 0.86rem;
  line-height: 1.8;
  margin-top: 6px;
  white-space: pre-wrap;
  word-break: break-word;
}
.msg-item.open .msg-summary { display: none; }
.msg-item.open .msg-body { display: block; }

/* ===== 后台管理（#backstage） ===== */
.backstage-card { max-width: 460px; margin: 0 auto; }
.bs-hint { font-size: 0.8rem; color: #9a9088; margin-bottom: 10px; }
#bsErr { color: #e05555; font-size: 0.8rem; margin-top: 10px; min-height: 1em; }
.bs-header { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; flex-wrap: wrap; }
.bs-header h2 { margin: 0; margin-right: auto; }
.bs-cards { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 16px; }
.bs-card { flex: 1 1 150px; background: rgba(212,168,67,0.10); border: 1px solid rgba(212,168,67,0.25); border-radius: 10px; padding: 14px; text-align: center; }
.bs-card-v { font-size: 1.35rem; font-weight: 700; color: #d4a843; }
.bs-card-t { font-size: 0.78rem; color: #9a9088; margin-top: 4px; }
.bs-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; margin-top: 8px; }
.bs-table th, .bs-table td { border-bottom: 1px solid #2a2620; padding: 7px 10px; text-align: left; }
.bs-table th { color: #9a9088; font-weight: 600; white-space: nowrap; }
.bs-table td { color: #d0c4a8; word-break: break-all; }
.bs-table tr:last-child td { border-bottom: none; }

/* 后台·全服消息富文本编辑器（#backstage_msg）与列表徽标 */
.rt-toolbar { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border: 1px solid #3a2a1e; border-bottom: none; border-radius: 6px 6px 0 0; background: #1a1a2e; flex-wrap: wrap; }
.rt-btn { width: 30px; height: 28px; border: 1px solid #3a2a1e; background: #141420; color: #d0d0d0; border-radius: 4px; cursor: pointer; font-size: 0.85rem; }
.rt-btn:hover { border-color: #c4a35a; color: #c4a35a; }
.rt-sep { width: 1px; height: 18px; background: #3a2a1e; margin: 0 4px; }
.rt-color { width: 22px; height: 22px; border-radius: 50%; border: 2px solid #3a2a1e; cursor: pointer; padding: 0; }
.rt-color:hover { border-color: #c4a35a; }
.rt-custom { display: inline-flex; align-items: center; justify-content: center; background: #141420; color: #9a9088; font-size: 0.78rem; border: 1px solid #3a2a1e; border-radius: 4px; width: 46px; height: 24px; cursor: pointer; position: relative; }
.rt-custom:hover { border-color: #c4a35a; color: #c4a35a; }
.rt-custom input[type=color] { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.rt-editor { min-height: 130px; max-height: 340px; overflow-y: auto; padding: 10px 12px; border: 1px solid #3a2a1e; border-radius: 0 0 6px 6px; background: #1a1a2e; color: #d0d0d0; line-height: 1.75; font-size: 0.88rem; }
.rt-editor:empty::before { content: attr(data-placeholder); color: #6a645c; }
.rt-editor b, .rt-editor strong { color: #eee6d8; }
.bs-badge { font-size: 0.65rem; color: #c4a35a; border: 1px solid rgba(196, 163, 90, 0.4); border-radius: 3px; padding: 0 4px; margin-left: 4px; white-space: nowrap; }

/* ===== 全局滚动条（暗金主题，配合整体配色） ===== */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: rgba(20, 18, 30, 0.55); }
::-webkit-scrollbar-thumb {
  background: rgba(196, 163, 90, 0.32);
  border-radius: 5px;
  border: 2px solid rgba(14, 12, 22, 0.9);
}
::-webkit-scrollbar-thumb:hover { background: rgba(196, 163, 90, 0.55); }
::-webkit-scrollbar-corner { background: transparent; }
* { scrollbar-width: thin; scrollbar-color: rgba(196, 163, 90, 0.4) rgba(20, 18, 30, 0.6); }

/* ===== 登录界面右下角静音按钮（文字风格，与整体配色一致） ===== */
.btn-mute-fab {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 900;
  background: rgba(20, 16, 10, 0.9);
  color: #9a9088;
  border: 1px solid #4a4038;
  border-radius: 999px;
  padding: 8px 18px;
  font-size: 0.8rem;
  letter-spacing: 3px;
  cursor: pointer;
  font-family: inherit;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.4);
}
.btn-mute-fab:hover { color: #d4a843; border-color: rgba(196, 163, 90, 0.55); background: rgba(26, 20, 12, 0.95); }

/* 语言切换按钮：与静音按钮同风格，叠放在其上方；仅大厅页显示（app.js 控制） */
.btn-lang-fab { bottom: 62px; letter-spacing: 2px; padding: 8px 14px; }

/* 吃碰杠面板的底部留白由 JS 按实际重叠量计算（showCPGPanel）：只有面板与右下角悬浮按钮
   真的冲突时才补足可滚动余量，桌面上面板与按钮不冲突时不会产生任何额外留白。
   这里只保留一个基线值。 */
#cpgInline { margin-bottom: 4px; }

/* ==================== 皮肤系统 ==================== */
/* 棋盘皮肤按 body[data-board-skin] 生效；本块写「中国象棋」皮肤（default 即上方现有样式）。
   结构对齐预览页：木色棋盘 + 外框双线 + 格心交叉点网格 + 牌河双平行线 + 楚河漢界。
   网格线由 skin.js 注入的 SVG 绘制（端点严格对齐：底线是真底、侧边不被横线突出）；
   棋子本来就居格心 → 视觉上即“棋子压在交叉点上”；落子点与坐标逻辑完全不变。 */

:root {
  /* 中国象棋皮肤的木色（暖调偏暗），大/小棋盘共用一处定义 */
  --cn-wood: linear-gradient(135deg, #ecd394, #d9b878 45%, #e5c98f);
}

/* ── 棋盘：暖木色底（线条与外框由 skin.js 注入的 SVG 绘制，逐笔照预览页）── */
body[data-board-skin="cn"] .board {
  background: var(--cn-wood);
  border-color: transparent;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .45);
}
/* 小棋盘（回放/帮助/设置预览）容器：同木色底（与棋盘皮肤绑定）*/
body[data-board-skin="cn"] .skin-cn-board {
  background: var(--cn-wood);
  border-radius: 6px;
}
/* 格子：底色/边框全透明（露棋盘本底，网格线由棋盘容器绘制，不被格子遮挡）*/
body[data-board-skin="cn"] .cell,
body[data-board-skin="cn"] .cell.light,
body[data-board-skin="cn"] .cell.dark,
body[data-board-skin="cn"] .cell.river.light,
body[data-board-skin="cn"] .cell.river.dark {
  background: transparent;
  border-color: transparent;
}
/* （牌河双线已并入棋盘容器的背景层，格子不再单独画线）*/
/* 棋子永远压在装饰文字之上（文字仅作底饰，不遮牌面）*/
body[data-board-skin="cn"] .piece-stack { position: relative; z-index: 2; border-radius: 50%; width: calc(94% - 1.5px); height: calc(94% - 1.5px); }

/* ── 「楚河」「漢界」：横排大字，每字旋转 90°；压在两条中心线之间（在棋子之下）── */
body[data-board-skin="cn"] .skin-river-word {
  position: absolute;
  display: inline-flex; align-items: center; gap: calc(var(--cw) * 0.08); line-height: 1;
  font-family: "KaiTi", "STKaiti", "Kaiti SC", serif;
  font-size: calc(var(--cw) * 0.6); font-weight: 600;
  color: rgba(18, 15, 12, .90);
  text-shadow: 0 1px 0 rgba(255,255,255,.55), 0 0 8px rgba(255,255,255,.45);
  transform: translate(-50%, -50%);
  z-index: 1; pointer-events: none;
}
body[data-board-skin="cn"] .skin-river-word i { display: block; font-style: normal; }
body[data-board-skin="cn"] .skin-river-word.left  { left: calc(var(--board-pad) + 2 * var(--cw)); top: calc(var(--board-pad) + 3.5 * var(--cw)); }
body[data-board-skin="cn"] .skin-river-word.right { left: calc(var(--board-pad) + 5 * var(--cw)); top: calc(var(--board-pad) + 3.5 * var(--cw)); }
body[data-board-skin="cn"] .skin-river-word.left  i { transform: rotate(-90deg); }
body[data-board-skin="cn"] .skin-river-word.right i { transform: rotate(90deg); }

/* ── 可走位高亮随棋盘皮肤：中国象棋皮肤下只留圆点（去掉底色与描边）── */
body[data-board-skin="cn"] .cell.possible-move-single,
body[data-board-skin="cn"] .cell.possible-move-pair,
body[data-board-skin="cn"] .cell.possible-move-sequence,
body[data-board-skin="cn"] .cell.possible-move-triplet,
body[data-board-skin="cn"] .cell.possible-move-quad {
  background-color: transparent !important;   /* 只清底色，保留 ::before 的网格线 */
  box-shadow: none !important;
  animation: none !important;
}
/* 木色底上加深圆点，保留牌型间的配色区分 */
body[data-board-skin="cn"] .cell.possible-move-single::after   { background: rgba(150, 95, 40, .78); }
body[data-board-skin="cn"] .cell.possible-move-pair::after     { background: rgba(122, 85, 155, .78); }
body[data-board-skin="cn"] .cell.possible-move-sequence::after { background: rgba(45, 120, 112, .78); }
body[data-board-skin="cn"] .cell.possible-move-triplet::after  { background: rgba(120, 95, 55, .82); }
body[data-board-skin="cn"] .cell.possible-move-quad::after     { background: rgba(160, 70, 52, .78); }
/* 中国象棋皮肤：可走位圆点在己方/敌方棋子上都显示（点在棋子之上，明确指示落点）*/
body[data-board-skin="cn"] .cell.possible-move-single.my-piece::after,
body[data-board-skin="cn"] .cell.possible-move-pair.my-piece::after,
body[data-board-skin="cn"] .cell.possible-move-sequence.my-piece::after,
body[data-board-skin="cn"] .cell.possible-move-triplet.my-piece::after,
body[data-board-skin="cn"] .cell.possible-move-quad.my-piece::after,
body[data-board-skin="cn"] .cell.possible-move-single.opp-piece::after,
body[data-board-skin="cn"] .cell.possible-move-pair.opp-piece::after,
body[data-board-skin="cn"] .cell.possible-move-sequence.opp-piece::after,
body[data-board-skin="cn"] .cell.possible-move-triplet.opp-piece::after,
body[data-board-skin="cn"] .cell.possible-move-quad.opp-piece::after { display: block; z-index: 6; }
/* 可提子（吃）位置：同皮肤下也去框、只留圆点（红色）*/
body[data-board-skin="cn"] .cell.possible-capture {
  background: transparent !important;
  box-shadow: none !important;
  animation: none !important;
}
body[data-board-skin="cn"] .cell.possible-capture::after {
  content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 28%; height: 28%; border-radius: 50%;
  background: rgba(170, 50, 35, .80);
  pointer-events: none; z-index: 6;
}

/* ── 「打入位置」也随皮肤：去框、只留圆点（稍淡，与可走位圆点区分）── */
body[data-board-skin="cn"] .cell.possible-place {
  background: transparent !important;
  box-shadow: none !important;
}
body[data-board-skin="cn"] .cell.possible-place::after { background: rgba(122, 72, 30, .72); }
body[data-board-skin="cn"] .cell.possible-place.opp-piece::after { background: rgba(168, 48, 32, .72); }
/* 打入圆点也要能覆盖己方棋子（同可走位圆点）*/
body[data-board-skin="cn"] .cell.possible-place.my-piece::after { display: block; z-index: 6; }

/* ── 小棋盘的归属底色也用圆形（与棋盘皮肤绑定）── */
body[data-board-skin="cn"] .replay-cell.replay-p1,
body[data-board-skin="cn"] .replay-cell.replay-p2 { border-radius: 50%; }
/* ── 步骤变化高亮同样随圆形底座（含空格子：离场格没有归属类，也要圆形）──
   outline / box-shadow 均跟随 border-radius（空心圆环描边）*/ 
body[data-board-skin="cn"] .replay-step-change,
body[data-board-skin="cn"] .replay-step-to,
body[data-board-skin="cn"] .replay-step-from {
  border-radius: 50%;
}

/* ── 棋子底座（归属色）：该皮肤下换成更暗的底，配暖木色棋盘不刺眼 ── */
body[data-board-skin="cn"] .cell.my-piece .piece-stack {
  border-color: rgba(28, 96, 145, .95);
  background: rgba(22, 84, 128, .42);
  box-shadow: inset 0 0 6px rgba(16, 62, 96, .35);
}
body[data-board-skin="cn"] .cell.opp-piece .piece-stack {
  border-color: rgba(168, 42, 32, .95);
  background: rgba(140, 34, 26, .42);
  box-shadow: inset 0 0 6px rgba(104, 24, 18, .35);
}
/* 小棋盘的归属底色同步调暗（与大棋盘一致）*/
/* 归属底色：有棋子的格子必须有归属色。
   加 !important 是因为皮肤那段「格子底色全透明」的规则里，`.cell.river.light/.dark` 特属性 (0,4,1)
   高于本规则的 (0,3,1)，会把牌河行棋子格的 background-image 一并清掉（实测牌河行我方格底色丢失），
   而归属底色是棋子归属的唯一标识，不能丢。 */
body[data-board-skin="cn"] .replay-cell.replay-p1 {
  background-image: linear-gradient(rgba(22, 84, 128, .42), rgba(22, 84, 128, .42)) !important;
  box-shadow: inset 0 0 6px rgba(16, 62, 96, .35);
}
body[data-board-skin="cn"] .replay-cell.replay-p2 {
  background-image: linear-gradient(rgba(140, 34, 26, .42), rgba(140, 34, 26, .42)) !important;
  box-shadow: inset 0 0 6px rgba(104, 24, 18, .35);
}

/* ── 「上一步」高亮随皮肤：中国象棋皮肤下改为圆形、更淡的描边（保留脉冲）── */
body[data-board-skin="cn"] .cell.highlight-opp-to,
body[data-board-skin="cn"] .cell.highlight-opp-from {
  border-radius: 50%;
  outline-width: 5px;
  outline-offset: -5px;
  box-shadow: none;
  animation: cnOppPulse 0.9s ease-in-out infinite alternate;
}
/* 牌堆本身的方形呼吸去掉（圆形描边已经足够，且方形框与交叉点棋盘不搭）*/
body[data-board-skin="cn"] .cell.highlight-opp-to .piece-stack { animation: none; }
@keyframes cnOppPulse {
  from { outline-color: rgba(var(--opp-c), .14); }
  to   { outline-color: rgba(var(--opp-c), .40); }
}

/* ── 「胡牌高亮」随皮肤：中国象棋皮肤下改为圆形描边（与「上一步」同款圆环；方框与交叉点棋盘不搭）──
   抢先闪动 + 描边呼吸（winFlash + winBorderPulse）沿用通用样式，仅把形状由方改圆 */
body[data-board-skin="cn"] .cell.win-highlight,
body[data-board-skin="cn"] .replay-cell.win-highlight {
  border-radius: 50%;
  outline-width: 5px;
  outline-offset: -5px;
  /* 胡牌高光优先于「上一步」：显式重申金色动画（同特异度下后定义，压过 cnOppPulse） */
  animation: winFlash 0.6s ease-out 1, winBorderPulse 1.4s ease-in-out 0.6s infinite alternate;
}
/* 落点冲击波（打入即胡牌时与高亮同帧出现）也随皮肤改圆 */
body[data-board-skin="cn"] .cell.impact-pulse::before {
  border-radius: 50%;
}

/* ── 大厅演示棋盘（#demoBoard）：开场随机到中国象棋皮肤时的容器级样式 ──
   作用域限定在 #demoBoard.board-cn 上，不依赖 body[data-board-skin]，
   因此不会影响用户自己的皮肤设置，也不会泄漏到其它棋盘。
   增加新皮肤时：在此照抄该皮肤在 body[data-board-skin="<id>"] 下的棋盘相关规则即可。 */
#demoBoard.board-cn {
  background: var(--cn-wood);
  border-color: transparent;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .45);
}
#demoBoard.board-cn .cell,
#demoBoard.board-cn .cell.light,
#demoBoard.board-cn .cell.dark,
#demoBoard.board-cn .cell.river.light,
#demoBoard.board-cn .cell.river.dark {
  background: transparent;
  border-color: transparent;
}
#demoBoard.board-cn .piece-stack {
  position: relative;
  z-index: 2;
  border-radius: 50%;
  width: calc(94% - 1.5px);
  height: calc(94% - 1.5px);
}
#demoBoard.board-cn .skin-river-word {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: calc(var(--cw) * 0.08);
  line-height: 1;
  font-family: "KaiTi", "STKaiti", "Kaiti SC", serif;
  font-size: calc(var(--cw) * 0.6);
  font-weight: 600;
  color: rgba(18, 15, 12, .90);
  text-shadow: 0 1px 0 rgba(255,255,255,.55), 0 0 8px rgba(255,255,255,.45);
  transform: translate(-50%, -50%);
  z-index: 1;
  pointer-events: none;
}
#demoBoard.board-cn .skin-river-word i { display: block; font-style: normal; }
#demoBoard.board-cn .skin-river-word.left  { left: calc(var(--board-pad) + 2 * var(--cw)); top: calc(var(--board-pad) + 3.5 * var(--cw)); }
#demoBoard.board-cn .skin-river-word.right { left: calc(var(--board-pad) + 5 * var(--cw)); top: calc(var(--board-pad) + 3.5 * var(--cw)); }
#demoBoard.board-cn .skin-river-word.left  i { transform: rotate(-90deg); }
#demoBoard.board-cn .skin-river-word.right i { transform: rotate(90deg); }
#demoBoard.board-cn .cell.my-piece .piece-stack {
  border-color: rgba(28, 96, 145, .95);
  background: rgba(22, 84, 128, .42);
  box-shadow: inset 0 0 6px rgba(16, 62, 96, .35);
}
#demoBoard.board-cn .cell.opp-piece .piece-stack {
  border-color: rgba(168, 42, 32, .95);
  background: rgba(140, 34, 26, .42);
  box-shadow: inset 0 0 6px rgba(104, 24, 18, .35);
}
#demoBoard.board-cn .cell.highlight-opp-to,
#demoBoard.board-cn .cell.highlight-opp-from {
  border-radius: 50%;
  outline-width: 5px;
  outline-offset: -5px;
  box-shadow: none;
  animation: cnOppPulse 0.9s ease-in-out infinite alternate;
}
#demoBoard.board-cn .cell.highlight-opp-to .piece-stack { animation: none; }
#demoBoard.board-cn .cell.win-highlight {
  border-radius: 50%;
  outline-width: 5px;
  outline-offset: -5px;
  animation: winFlash 0.6s ease-out 1, winBorderPulse 1.4s ease-in-out 0.6s infinite alternate;
}
#demoBoard.board-cn .cell.impact-pulse::before { border-radius: 50%; }
