/* ==========================================================================
   丝路通 SilkChat —— 样式表
   重写要点（2026-09-21）：统一圆角与阴影节奏、导航改毛玻璃、支持深色模式、
   所有可点元素给触摸反馈、页面切换走 iOS 那条顺滑曲线。
   类名一律沿用，不动 HTML 结构，也不动 app.js 里的选择器。
   ========================================================================== */

:root{
  /* 品牌 */
  --green:#07c160; --green-d:#06ad56; --green-l:#e9f9f0;
  /* 中性 */
  --bg:#f4f5f7; --card:#ffffff; --line:#ebedf0; --line-2:#f3f4f6;
  --nav:rgba(255,255,255,.78); --nav-bd:rgba(0,0,0,.06);
  --txt:#16181d; --txt2:#878b93; --txt3:#b6babf;
  /* 气泡 */
  --bub-me:#9eea72; --bub-other:#ffffff;
  --bub-me-txt:#0f2417;
  /* 功能色 */
  --blue:#4a6cf7; --danger:#f04438; --warn:#f79009;
  /* 圆角 */
  --r-s:9px; --r-m:14px; --r-l:20px; --r-xl:26px;
  /* 阴影：两层叠加，近处收边、远处散开 —— 比单层阴影更像"浮起来" */
  --sh-1:0 1px 2px rgba(16,24,40,.04), 0 1px 3px rgba(16,24,40,.03);
  --sh-2:0 2px 5px rgba(16,24,40,.05), 0 10px 28px rgba(16,24,40,.07);
  --sh-3:0 8px 20px rgba(16,24,40,.10), 0 24px 56px rgba(16,24,40,.14);
  /* 动效：这条曲线是 iOS 页面切换那条，起步快、末端收得稳 */
  --ease:cubic-bezier(.32,.72,0,1);
  --dur:.34s;
  --tabh:58px;
  --safe-b:env(safe-area-inset-bottom,0px);
  --safe-t:env(safe-area-inset-top,0px);
}

/* 手机开了深色模式就跟着变。整套颜色都由变量驱动，改这一处就够。 */
@media (prefers-color-scheme:dark){
  :root{
    --bg:#0f1115; --card:#181b21; --line:#252932; --line-2:#1f232a;
    --nav:rgba(20,22,27,.76); --nav-bd:rgba(255,255,255,.07);
    --txt:#e9ebef; --txt2:#8f959f; --txt3:#5c626c;
    --bub-me:#2f6b45; --bub-other:#23272f; --bub-me-txt:#eaf7ee;
    --green-l:#16301f;
    --blue:#8b9dff; --danger:#ff6b63; --warn:#fdb022;
    --sh-1:0 1px 2px rgba(0,0,0,.24);
    --sh-2:0 2px 6px rgba(0,0,0,.30), 0 12px 30px rgba(0,0,0,.32);
    --sh-3:0 10px 24px rgba(0,0,0,.44), 0 28px 60px rgba(0,0,0,.5);
  }
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{height:100%;margin:0;padding:0}
body{
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI","PingFang SC","Microsoft YaHei","Tahoma",sans-serif;
  background:var(--bg);color:var(--txt);font-size:16px;line-height:1.45;
  overscroll-behavior:none;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
input,textarea,button{font-family:inherit;font-size:16px;color:var(--txt)}
button{border:0;background:none;cursor:pointer}
img{display:block}
.hide{display:none !important}

/* 统一的按压反馈：所有可点的地方按下时轻微缩一点，手指能"感觉到"点到了 */
.row:active,.celld:active,.sh-i:active,.tab:active,.mo-f b:active{
  background:var(--line-2);
}
@media (hover:hover){
  .btn.primary:hover{filter:brightness(1.04)}
}

/* ---------- 登录 ---------- */
.login{
  position:fixed;inset:0;display:flex;align-items:center;justify-content:center;padding:24px;z-index:50;
  background:
    radial-gradient(1100px 560px at 12% -8%, #d9f7e6 0%, transparent 62%),
    radial-gradient(900px 520px at 108% 104%, #dce9ff 0%, transparent 58%),
    linear-gradient(168deg,#f7fbf8,#eef4f1);
}
@media (prefers-color-scheme:dark){
  .login{background:
    radial-gradient(1100px 560px at 12% -8%, #10321f 0%, transparent 62%),
    radial-gradient(900px 520px at 108% 104%, #131d38 0%, transparent 58%),
    linear-gradient(168deg,#0d1014,#0f1218);}
}
.login-stack{width:100%;max-width:360px}
.login-box{width:100%;max-width:360px;text-align:center;animation:loginIn .5s var(--ease) both}
@keyframes loginIn{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.login-box .logo img{
  width:78px;height:78px;margin:0 auto 16px;border-radius:22px;
  box-shadow:0 10px 30px rgba(7,193,96,.3),0 2px 8px rgba(7,193,96,.2);
}
.login-box h1{font-size:25px;margin:0;letter-spacing:2.5px;font-weight:600}
.login-box .sub{color:var(--txt2);font-size:13px;margin:7px 0 24px;letter-spacing:.3px}
.fld{text-align:start;margin-bottom:13px}
.fld label{display:block;font-size:12px;color:var(--txt2);margin-bottom:6px;padding-inline-start:3px;font-weight:500}
.fld input,.fld textarea{
  width:100%;padding:13px 14px;border:1px solid var(--line);border-radius:var(--r-m);
  background:var(--card);outline:none;transition:border-color .18s,box-shadow .18s;
}
.fld textarea{font:inherit;font-size:15px;line-height:1.5;resize:none;color:inherit}
.fld input:focus,.fld textarea:focus{border-color:var(--green);box-shadow:0 0 0 3.5px rgba(7,193,96,.13)}
.btn{
  width:100%;padding:14px;border-radius:var(--r-m);font-size:16px;margin-top:10px;font-weight:600;
  transition:transform .12s var(--ease),filter .16s,background .16s;
}
.btn:active{transform:scale(.982)}
.btn.primary{background:var(--green);color:#fff;box-shadow:0 6px 16px rgba(7,193,96,.28)}
.btn.primary:active{background:var(--green-d);box-shadow:0 3px 10px rgba(7,193,96,.24)}
.btn.ghost{background:transparent;color:var(--blue);font-size:14px;font-weight:500}
.langrow{display:flex;gap:8px;justify-content:center;margin-top:20px}
.langrow b{
  padding:6px 14px;border-radius:20px;font-size:13px;font-weight:500;color:var(--txt2);
  border:1px solid var(--line);background:var(--card);transition:all .2s var(--ease);
}
.langrow b.on{color:#fff;background:var(--green);border-color:var(--green);box-shadow:0 4px 12px rgba(7,193,96,.3)}
.err{color:var(--danger);font-size:13px;margin-top:12px;min-height:18px}
.ok{color:var(--green);font-size:13px;margin-top:12px;line-height:1.7;min-height:0}
.ok:empty{display:none}

/* ---------- 主框架 ---------- */
.main{position:fixed;inset:0;display:flex;flex-direction:column;background:var(--bg)}
.screens{flex:1;position:relative;overflow:hidden}
.screen{position:absolute;inset:0;display:none;flex-direction:column}
.screen.on{display:flex;animation:fadeUp .3s var(--ease) both}
@keyframes fadeUp{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* 顶栏：半透明 + 毛玻璃。内容从底下滚过去时能透出来一点，是"层次感"的关键。 */
.topbar{
  display:flex;align-items:center;justify-content:space-between;
  padding:calc(var(--safe-t) + 11px) 16px 11px;
  background:var(--nav);-webkit-backdrop-filter:saturate(180%) blur(20px);
  backdrop-filter:saturate(180%) blur(20px);
  border-bottom:1px solid var(--nav-bd);flex:0 0 auto;z-index:2;
}
.topbar .t{font-size:18px;font-weight:700;letter-spacing:.2px}
.topbar .plus{
  width:34px;height:34px;display:flex;align-items:center;justify-content:center;
  border-radius:50%;color:var(--txt);transition:background .16s,transform .12s var(--ease);
}
.topbar .plus:active{background:var(--line);transform:scale(.92)}
.topbar .plus svg{width:22px;height:22px}
.list{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding-bottom:8px}

/* ---------- 列表行 ---------- */
.row{
  display:flex;align-items:center;gap:12px;padding:12px 15px;
  background:var(--card);position:relative;transition:background .15s;
  animation:rowIn .28s var(--ease) both;
}
@keyframes rowIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
.row+.row::before{content:'';position:absolute;inset-inline-start:71px;inset-inline-end:0;top:0;height:1px;background:var(--line)}
/* 第一行和最后一行给点圆角，整块看起来像一张卡片而不是一条长条 */
.list>.row:first-child{border-start-start-radius:var(--r-l);border-start-end-radius:var(--r-l)}
.list>.row:last-child{border-end-start-radius:var(--r-l);border-end-end-radius:var(--r-l)}
.av{
  width:47px;height:47px;border-radius:var(--r-m);flex:0 0 auto;object-fit:cover;
  background:linear-gradient(140deg,#c2d8c9,#a9c6b3);
  display:flex;align-items:center;justify-content:center;color:#fff;font-size:19px;font-weight:600;
  box-shadow:var(--sh-1);
}
.av.sm{width:38px;height:38px;border-radius:11px;font-size:16px}
.av.rd{border-radius:50%}
.rowmain{flex:1;min-width:0}
.rowmain .n{display:flex;justify-content:space-between;align-items:baseline;gap:8px}
.rowmain .n b{font-weight:600;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;letter-spacing:.1px}
.rowmain .n s{text-decoration:none;color:var(--txt3);font-size:12px;flex:0 0 auto}
.rowmain .p{color:var(--txt2);font-size:13.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:3px}
.badge{
  background:var(--danger);color:#fff;font-size:11px;font-weight:600;min-width:19px;height:19px;
  border-radius:10px;display:flex;align-items:center;justify-content:center;padding:0 5px;flex:0 0 auto;
  box-shadow:0 2px 6px rgba(240,68,56,.36);
}

/* ---------- 设置项 ---------- */
.celld{
  display:flex;align-items:center;gap:12px;padding:14px 15px;background:var(--card);
  position:relative;font-size:16px;transition:background .15s;
}
.celld+.celld::before{content:'';position:absolute;inset-inline-start:53px;inset-inline-end:0;top:0;height:1px;background:var(--line)}
/* 和会话列表一样：整块首尾收圆角，看起来是一张卡片而不是一条长条 */
.list>.celld:first-child{border-start-start-radius:var(--r-l);border-start-end-radius:var(--r-l)}
.list>.celld:last-child{border-end-start-radius:var(--r-l);border-end-end-radius:var(--r-l)}
.celld .ico{
  width:30px;height:30px;border-radius:9px;color:#fff;display:flex;align-items:center;justify-content:center;
  font-size:15px;flex:0 0 auto;box-shadow:0 2px 5px rgba(0,0,0,.16);
}
.celld .ico svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.celld .chev{color:var(--txt3);font-size:19px;margin-inline-start:auto;transition:transform .18s var(--ease)}
.celld:active .chev{transform:translateX(2px)}
.celld .val{color:var(--txt2);font-size:14px;margin-inline-start:auto}
.celld.danger{color:var(--danger)}
.sw{width:48px;height:29px;border-radius:15px;background:#d6d9de;position:relative;margin-inline-start:auto;transition:background .22s var(--ease);flex:0 0 auto}
.sw i{position:absolute;top:2.5px;inset-inline-start:2.5px;width:24px;height:24px;border-radius:50%;background:#fff;transition:inset-inline-start .22s var(--ease);box-shadow:0 1px 3px rgba(0,0,0,.22)}
.sw.on{background:var(--green)}
.sw.on i{inset-inline-start:21.5px}
.grp-hd{padding:18px 17px 7px;font-size:12.5px;font-weight:600;color:var(--txt2);letter-spacing:.4px;text-transform:none}
.mecard{
  display:flex;align-items:center;gap:15px;padding:24px 18px;background:var(--card);margin-bottom:12px;
  animation:fadeUp .32s var(--ease) both;
}
.mecard .av{width:64px;height:64px;font-size:27px;border-radius:19px}
.mecard .mc-n b{font-size:20px;font-weight:700;display:block;letter-spacing:.2px}
.mecard .mc-n s{text-decoration:none;color:var(--txt2);font-size:13px}
/* 「我」这张卡片上的个性签名。min-width:0 是必须的：不加的话
   一句长签名会把昵称那一列撑宽，整张卡片跟着挪位。 */
.mecard .mc-n{min-width:0}
.mecard .mc-n .mc-s{
  display:block;font-style:normal;color:var(--txt2);font-size:13px;margin-top:5px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}

/* ---------- 个人资料卡（点别人头像进来） ---------- */
.ucard{
  background:var(--card);padding:26px 20px 18px;text-align:center;
  animation:fadeUp .32s var(--ease) both;
}
/* 头像那层要自己居中：.av 是个 display:flex 的块级元素，
   父级的 text-align:center 管不到它，不写这行它就一直贴在左边。 */
.ucard .uav{display:flex;justify-content:center}
.ucard .uav .av{width:78px;height:78px;font-size:32px;border-radius:24px;box-shadow:var(--sh-1)}
.ucard .un{margin-top:14px}
.ucard .un b{font-size:21px;font-weight:700;letter-spacing:.2px;word-break:break-word}
.ucard .un s{display:block;text-decoration:none;color:var(--txt2);font-size:13px;margin-top:4px}
.ucard .usig{
  margin-top:13px;font-size:14.5px;color:var(--txt);line-height:1.65;
  word-break:break-word;unicode-bidi:plaintext;
}
.ucard .usig i{color:var(--txt2);font-style:normal}
.ucard .utip{margin-top:11px;font-size:12.5px;color:var(--txt2)}
.ucard .uacts{display:flex;gap:9px;width:100%;margin-top:19px}
.ubt{
  flex:1;padding:12px 6px;border-radius:var(--r-m);font-size:14.5px;font-weight:600;
  background:var(--bg);color:var(--txt);border:1px solid var(--line);font-family:inherit;
  transition:transform .12s var(--ease),background .16s;
}
.ubt:active{transform:scale(.97)}
.ubt.primary{background:var(--green);color:#fff;border-color:var(--green);box-shadow:0 6px 16px rgba(7,193,96,.26)}
/* 朋友圈那条动态的头像外面包了一层，点了看资料 —— 包起来是为了挂 data-um，
   所以这层要自己撑起原来头像占的那一格宽度。 */
.tapav{flex:0 0 auto;display:flex;cursor:pointer}
.row[data-um]{cursor:pointer}
.ver{text-align:center;color:var(--txt3);font-size:12px;padding:22px;letter-spacing:.3px}

/* ---------- 空状态 ---------- */
.empty{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:56px 32px;text-align:center;animation:fadeUp .36s var(--ease) both}
.empty .ei{font-size:44px;line-height:1;opacity:.5;margin-bottom:14px}
.empty .et{color:var(--txt2);font-size:14.5px;line-height:1.7}

/* ---------- 底部 tab ---------- */
.tabbar{
  display:flex;background:var(--nav);-webkit-backdrop-filter:saturate(180%) blur(20px);
  backdrop-filter:saturate(180%) blur(20px);border-top:1px solid var(--nav-bd);
  padding-bottom:var(--safe-b);flex:0 0 auto;z-index:2;
}
.tab{flex:1;text-align:center;padding:7px 0 6px;position:relative;color:#9aa0a8;transition:color .2s var(--ease)}
.tab i{display:flex;align-items:center;justify-content:center;height:24px;font-style:normal;transition:transform .24s var(--ease)}
.tab i svg{width:24px;height:24px;stroke:currentColor;fill:none;stroke-width:1.85;stroke-linecap:round;stroke-linejoin:round}
.tab span{display:block;font-size:10.5px;margin-top:2px;font-weight:500;letter-spacing:.2px}
.tab.on{color:var(--green)}
.tab.on i{transform:translateY(-1px) scale(1.06)}
.tab .dot{position:absolute;top:6px;inset-inline-start:calc(50% + 9px);width:8px;height:8px;border-radius:50%;background:var(--danger);display:none;box-shadow:0 0 0 2px var(--card)}
.tab .dot.on{display:block;animation:pop .3s var(--ease) both}
@keyframes pop{from{transform:scale(0)}to{transform:scale(1)}}

/* ---------- 滑入页面 ---------- */
.page{
  position:fixed;inset:0;background:var(--bg);display:flex;flex-direction:column;
  transform:translateX(100%);transition:transform var(--dur) var(--ease),visibility var(--dur);
  z-index:30;visibility:hidden;
}
.page.open{transform:translateX(0);visibility:visible}
.page.open .gbody>*{animation:fadeUp .38s var(--ease) both}
.navbar{
  display:flex;align-items:center;gap:6px;padding:calc(var(--safe-t) + 9px) 12px 9px;
  background:var(--nav);-webkit-backdrop-filter:saturate(180%) blur(20px);
  backdrop-filter:saturate(180%) blur(20px);border-bottom:1px solid var(--nav-bd);flex:0 0 auto;z-index:2;
}
.navbar .back{font-size:27px;line-height:1;width:34px;color:var(--txt);margin-top:-3px;transition:opacity .16s}
.navbar .back:active{opacity:.45}
.navbar .ttl{
  flex:1;font-size:17px;font-weight:700;text-align:center;margin-inline-start:-34px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none;
}
.navbar .acts{display:flex;gap:15px;font-size:19px;min-width:34px;justify-content:flex-end;position:relative;z-index:2}
.navbar .back{position:relative;z-index:2}
.navbar .acts b{cursor:pointer;transition:opacity .16s}
.navbar .acts b:active{opacity:.45}
.navbar .acts svg{width:21px;height:21px;stroke:currentColor;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;vertical-align:-3px}
.gbody{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch}

/* ---------- 消息 ---------- */
.msgs{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:14px 10px 8px}
/* 消息时间：跟微信一个做法 —— 居中一行浅灰小字，只在"新一轮说话"时露一次。
   规则是「第一条」和「跟上一句隔了 5 分钟以上」，不是每条都挂时间；
   每条都挂的话满屏都是数字，反而没人看。颜色用 --txt2（不是更浅的 --txt3），
   深色模式下浅灰容易糊在黑底上，这一档两边都还看得清。 */
.daysep{text-align:center;margin:4px 0 15px;user-select:none}
.daysep span{font-size:11.5px;color:var(--txt2);letter-spacing:.2px}
.msg{display:flex;gap:9px;margin-bottom:17px;align-items:flex-start;animation:msgIn .3s var(--ease) both}
@keyframes msgIn{from{opacity:0;transform:translateY(8px) scale(.97)}to{opacity:1;transform:none}}
.msg.me{flex-direction:row-reverse}
.msg .av{width:38px;height:38px;border-radius:11px;font-size:16px}
.mbody{max-width:calc(100% - 118px);min-width:0}
.msg .mname{font-size:11px;color:var(--txt2);margin-bottom:4px;padding-inline-start:2px}
.bub{
  background:var(--bub-other);border-radius:var(--r-m);padding:9px 13px;font-size:16px;
  word-break:break-word;white-space:pre-wrap;position:relative;
  box-shadow:var(--sh-1);unicode-bidi:plaintext;line-height:1.5;
}
.msg.me .bub{background:var(--bub-me);color:var(--bub-me-txt)}
.bub::after{content:'';position:absolute;top:12px;width:0;height:0;border:6px solid transparent}
.msg:not(.me) .bub::after{left:-10px;border-right-color:var(--bub-other)}
.msg.me .bub::after{right:-10px;border-left-color:var(--bub-me)}
.bub.plain{background:none!important;box-shadow:none;padding:0}
.bub.plain::after{display:none}
.bub img.pic{max-width:190px;max-height:240px;border-radius:9px}
.bub img.stk{width:110px;height:110px}
.bub .tr{border-top:1px dashed rgba(0,0,0,.14);margin-top:8px;padding-top:7px;font-size:14px;color:#3b5c46}
.msg.me .bub .tr{color:#2c4a37}
.mtime{text-align:center;color:var(--txt3);font-size:11.5px;margin:16px 0 13px;letter-spacing:.3px}
.sysmsg{text-align:center;margin:12px 0}
.sysmsg span{background:rgba(140,145,155,.22);color:var(--txt2);font-size:11.5px;padding:4px 11px;border-radius:8px;font-weight:500}
/* ---------- 通话记录（聊天里那一行） ----------
   微信的样子：居中一行，图标 + 「通话时长 00:12」/「未接来电」。
   没接上的显眼一点（暖红），接通过的就安静一点。 */
.callrec{display:flex;align-items:center;justify-content:center;gap:6px;margin:12px 0;user-select:none}
.callrec svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.callrec span{font-size:11.5px;color:var(--txt2);font-weight:500;letter-spacing:.2px}
.callrec.miss span{color:#c8442e}
@media (prefers-color-scheme:dark){
  .callrec.miss span{color:#ff8a72}
}
.bub .voice{display:flex;align-items:center;gap:8px;min-width:74px}
.bub .voice i{font-style:normal;font-size:17px}
.bub .voice s{text-decoration:none;font-size:12px;color:var(--txt2)}
.trbtn{
  font-size:11px;color:var(--blue);border:1px solid var(--line);background:var(--card);
  border-radius:11px;padding:2px 8px;margin-top:5px;display:inline-block;transition:transform .12s var(--ease);
}
.trbtn:active{transform:scale(.94)}
.msg.me .trbtn{margin-inline-start:auto}

/* ---------- 输入栏 ---------- */
.inputbar{
  display:flex;align-items:flex-end;gap:5px;padding:9px 10px calc(9px + var(--safe-b));
  background:var(--nav);-webkit-backdrop-filter:saturate(180%) blur(20px);
  backdrop-filter:saturate(180%) blur(20px);border-top:1px solid var(--nav-bd);flex:0 0 auto;z-index:2;
}
/* 图标按钮：固定方框 + 居中，四个一排宽度才稳，不会因为字形宽窄互相挤动 */
.inputbar .ib{
  width:33px;height:38px;display:flex;align-items:center;justify-content:center;
  flex:0 0 auto;color:var(--txt2);transition:transform .12s var(--ease),color .16s;
}
.inputbar .ib svg{
  width:23px;height:23px;fill:none;stroke:currentColor;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;
}
.inputbar .ib:active{transform:scale(.86);color:var(--green)}
.ipt{flex:1;background:var(--card);border-radius:19px;border:1px solid var(--line);min-height:38px;display:flex;align-items:center;padding:0 12px;transition:border-color .18s,box-shadow .18s}
.ipt:focus-within{border-color:var(--green);box-shadow:0 0 0 3px rgba(7,193,96,.11)}
.ipt textarea{width:100%;border:0;outline:none;resize:none;background:none;max-height:96px;line-height:1.4;padding:9px 0;unicode-bidi:plaintext}
.holdbtn{flex:1;background:var(--card);border:1px solid var(--line);border-radius:19px;height:38px;font-size:15px;display:none;transition:all .16s}
.holdbtn.rec{background:var(--green-l);border-color:var(--green);color:var(--green)}
/* 发送键常驻最右：不管有没有打字都在原位，不然它会跳来跳去、还找不到 */
.sendbtn{
  background:var(--green);color:#fff;border-radius:19px;padding:0 15px;height:38px;font-size:15px;font-weight:600;
  flex:0 0 auto;width:64px;box-shadow:0 3px 10px rgba(7,193,96,.28);
  transition:transform .12s var(--ease),opacity .18s var(--ease),background .18s;
}
.sendbtn:active{transform:scale(.94)}
/* 没内容时变淡但仍占着位置——位置不动的按钮才谈得上"顺手" */
.sendbtn.idle{opacity:.42;background:var(--txt3);box-shadow:none}
.sendbtn.idle:active{transform:scale(.94)}

/* ---------- 弹层 / 表情 ---------- */
.sheet-wrap{position:fixed;inset:0;background:rgba(12,14,18,.42);z-index:60;display:none;align-items:flex-end;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
.sheet-wrap.on{display:flex;animation:fadeIn .22s ease both}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
.sheet{
  width:100%;background:var(--card);border-radius:var(--r-xl) var(--r-xl) 0 0;max-height:72vh;overflow-y:auto;
  padding:6px 0 calc(6px + var(--safe-b));animation:up .36s var(--ease);
  box-shadow:0 -8px 40px rgba(0,0,0,.18);
}
@keyframes up{from{transform:translateY(100%)}to{transform:none}}
.sheet::before{content:'';display:block;width:36px;height:4.5px;border-radius:3px;background:var(--line);margin:8px auto 4px}
.sh-t{text-align:center;font-size:13px;color:var(--txt2);padding:10px 0 6px;font-weight:500}
.sh-i{display:flex;align-items:center;gap:13px;padding:14px 20px;font-size:16px;transition:background .14s}
.sh-i:active{background:var(--line-2)}
.sh-i.danger{color:var(--danger)}
/* 菜单图标：统一线性 SVG。以前这里是 emoji，颜色跟着系统字体走、
   深浅色模式还会自己变样，看着就像临时拼的。 */
.sh-i .shi{
  width:24px;height:24px;flex:0 0 auto;display:flex;align-items:center;justify-content:center;
  color:var(--txt2);
}
.sh-i .shi svg{width:21px;height:21px;fill:none;stroke:currentColor;stroke-width:1.85;stroke-linecap:round;stroke-linejoin:round}
.sh-i .shi.tx{font-size:13px;font-weight:700;color:var(--txt3)}
/* 还没换掉的 emoji（比如游戏自己的图标）：保持正常大小，别缩成小字 */
.sh-i .shi.em{font-size:19px}
.sh-i.danger .shi{color:var(--danger)}
/* 表情面板：挂在输入栏**下面**，高度从 0 长出来。
   以前是"从屏幕底部弹一层盖上来"，直接把输入栏连同上方的消息一起压住 ——
   点完表情看不到自己有没有点上，还得先把面板关掉；这也就是"选个表情这么费劲"的根。
   现在 #p-chat 是纵向 flex，面板一展开就自动把消息区挤矮，输入栏始终露在最上面。 */
.emopanel{
  display:flex;flex-direction:column;flex:0 0 auto;
  height:0;overflow:hidden;background:var(--nav);
  -webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);
  border-top:1px solid transparent;z-index:2;
  transition:height .26s var(--ease),border-color .26s;
}
.emopanel.on{height:268px;border-top-color:var(--nav-bd)}
.emopanel .emo-tabs{border-bottom:1px solid var(--line);flex:0 0 auto}
.emo-body{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding-bottom:calc(6px + var(--safe-b))}
.emo-tabs{display:flex;gap:6px;padding:8px 12px 4px;overflow-x:auto;border-bottom:1px solid var(--line)}
.emo-tabs b{font-size:19px;padding:4px 8px;border-radius:9px;flex:0 0 auto;transition:background .16s}
.emo-tabs b.on{background:var(--green-l)}
.emo-grid{display:grid;grid-template-columns:repeat(8,1fr);gap:2px;padding:10px}
.emo-grid span{font-size:26px;text-align:center;padding:4px 0;border-radius:9px;transition:background .14s,transform .12s var(--ease)}
.emo-grid span:active{background:var(--line-2);transform:scale(.9)}
.stk-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;padding:12px 14px}
.stk-grid img{width:100%;aspect-ratio:1;border-radius:var(--r-m);background:var(--line-2);object-fit:contain}
.plus-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;padding:14px 8px}
.plus-grid div{text-align:center;font-size:12px;color:var(--txt2)}
.plus-grid div b{
  display:flex;width:54px;height:54px;margin:0 auto 7px;background:var(--line-2);border-radius:17px;
  align-items:center;justify-content:center;font-size:25px;transition:transform .14s var(--ease);
}
.plus-grid div:active b{transform:scale(.9)}
.toast{
  position:fixed;left:50%;top:50%;transform:translate(-50%,-50%) scale(.94);
  background:rgba(20,22,28,.86);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  color:#fff;padding:11px 19px;border-radius:var(--r-m);font-size:14px;z-index:99;opacity:0;
  pointer-events:none;transition:opacity .2s,transform .26s var(--ease);max-width:80vw;text-align:center;
  box-shadow:var(--sh-3);line-height:1.5;
}
.toast.on{opacity:1;transform:translate(-50%,-50%) scale(1)}

/* ---------- 朋友圈 ---------- */
.mo{display:flex;gap:11px;padding:15px;background:var(--card);border-bottom:1px solid var(--line-2);animation:fadeUp .3s var(--ease) both}
.mo .av{width:42px;height:42px;border-radius:13px}
.mo-b{flex:1;min-width:0}
.mo-b .nm{color:var(--blue);font-size:15.5px;font-weight:600}
.mo-b .tx{margin:6px 0;font-size:15.5px;white-space:pre-wrap;word-break:break-word;unicode-bidi:plaintext}
.mo-imgs{display:grid;gap:4px;margin:8px 0}
.mo-imgs.n1{grid-template-columns:1fr}
.mo-imgs.n2{grid-template-columns:repeat(2,1fr)}
.mo-imgs.n3{grid-template-columns:repeat(3,1fr)}
.mo-imgs img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:9px}
.mo-imgs.n1 img{aspect-ratio:auto;max-height:320px;object-fit:contain;background:var(--line-2)}
.mo-f{display:flex;align-items:center;gap:14px;margin-top:8px;color:var(--txt2);font-size:13px}
.mo-f b{padding:3px 7px;border-radius:8px;transition:background .14s}
.mo-likes{background:var(--line-2);border-radius:9px;padding:7px 10px;font-size:13px;color:var(--blue);margin-top:8px;unicode-bidi:plaintext}
.mo-cm{background:var(--line-2);border-radius:9px;padding:8px 10px;font-size:14px;margin-top:8px}
.mo-cm div{padding:2px 0;unicode-bidi:plaintext;word-break:break-word}
.mo-cm div b{color:var(--blue);font-weight:600}
.composer{padding:14px;background:var(--card)}
.composer textarea{width:100%;min-height:110px;border:0;outline:none;resize:none;font-size:16px;unicode-bidi:plaintext;background:transparent;color:var(--txt)}
.composer .cimgs{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin:8px 0}
.composer .cimgs img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:11px}
.composer .cimgs .add{
  display:flex;align-items:center;justify-content:center;background:var(--line-2);border-radius:11px;
  font-size:28px;color:var(--txt3);aspect-ratio:1;transition:transform .14s var(--ease);
}
.composer .cimgs .add:active{transform:scale(.94)}
.pv-img{width:100%;max-height:76vh;object-fit:contain;background:#000}
.srch{padding:11px 13px;background:var(--card);display:flex;gap:9px;align-items:center;border-bottom:1px solid var(--line)}
.srch input{flex:1;border:0;outline:none;background:var(--line-2);padding:10px 14px;border-radius:19px;transition:box-shadow .18s}
.srch input:focus{box-shadow:0 0 0 3px rgba(7,193,96,.13)}
.srch button{color:var(--green);font-size:15px;font-weight:600;transition:opacity .16s}
.srch button:active{opacity:.5}
/* 「加好友」页搜索框下面那句说明 */
.afhint{padding:14px 17px 2px;font-size:12.5px;color:var(--txt2);line-height:1.65}
.pvwrap{position:fixed;inset:0;background:#000;z-index:80;display:flex;align-items:center;justify-content:center}

/* ---------- 卡片式入口（加好友 / 我的 ID） ---------- */
.entry{
  margin:13px 14px 6px;padding:16px 17px;border-radius:var(--r-l);background:var(--card);
  box-shadow:var(--sh-2);display:flex;align-items:center;gap:14px;
  animation:fadeUp .34s var(--ease) both;transition:transform .14s var(--ease);
}
.entry:active{transform:scale(.985)}
.entry .eic{
  width:46px;height:46px;border-radius:15px;flex:0 0 auto;display:flex;align-items:center;justify-content:center;
  font-size:23px;background:linear-gradient(140deg,var(--green),#0aa653);color:#fff;
  box-shadow:0 6px 16px rgba(7,193,96,.3);
}
.entry.accent .eic{background:linear-gradient(140deg,#5b8def,#4a6cf7);box-shadow:0 6px 16px rgba(74,108,247,.3)}
.entry .eb{flex:1;min-width:0}
.entry .eb b{display:block;font-size:16px;font-weight:600;margin-bottom:3px}
.entry .eb s{text-decoration:none;font-size:12.5px;color:var(--txt2);line-height:1.5;display:block}
.entry .go{color:var(--txt3);font-size:20px;flex:0 0 auto}
/* 「我的 ID」那张卡片内容比一般入口高（标题 + 说明 + 一串 ID），
   图标要跟标题对齐，不能傻居中沉到下面去 */
.entry.idcard{align-items:flex-start}
.entry.idcard .eic{margin-top:2px}

/* 我的 ID —— 显示成一段可以一眼看全、方便念给对方的等宽字 */
.idbox{
  display:flex;align-items:center;gap:10px;background:var(--line-2);border-radius:var(--r-m);
  padding:11px 13px;margin-top:11px;
}
.idbox .idtxt{
  flex:1;min-width:0;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:16px;font-weight:600;letter-spacing:.6px;color:var(--txt);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.idbox .idcp{
  flex:0 0 auto;background:var(--green);color:#fff;border-radius:11px;padding:7px 13px;
  font-size:13px;font-weight:600;box-shadow:0 3px 10px rgba(7,193,96,.26);
  transition:transform .12s var(--ease);
}
.idbox .idcp:active{transform:scale(.93)}

/* ---------- 通话 ---------- */
.call{position:fixed;inset:0;background:#111;z-index:90;overflow:hidden}
.call video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;background:#000}
#localVid{width:104px;height:150px;left:auto;right:12px;top:calc(var(--safe-t) + 12px);bottom:auto;border-radius:16px;object-fit:cover;border:1px solid rgba(255,255,255,.28);z-index:2;box-shadow:0 10px 28px rgba(0,0,0,.5)}
/* 本地小画面（照着自己的那一格）。
   苹果手机会把前置摄像头拍到的自己显示成"照镜子" —— 左右是反的；安卓不会。
   别人看你可不是反的，所以在苹果上再翻一次翻回来，跟对方看到的对上。
   ⚠ 只翻这一格。远端画面（#remoteVid）和发给对方的流都不动。 */
html.is-ios #localVid{transform:scaleX(-1)}
.cinfo{position:absolute;top:calc(var(--safe-t) + 18px);left:0;right:0;text-align:center;color:#fff;font-size:17px;z-index:3;text-shadow:0 1px 6px rgba(0,0,0,.7)}
.cinfo s{display:block;text-decoration:none;font-size:13px;opacity:.85;margin-top:5px}
.cbar{position:absolute;bottom:calc(30px + var(--safe-b));left:0;right:0;display:flex;justify-content:center;gap:13px;z-index:4}
.cbar button{
  width:54px;height:54px;border-radius:50%;background:rgba(255,255,255,.2);color:#fff;
  display:flex;align-items:center;justify-content:center;
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  transition:transform .14s var(--ease),background .16s,color .16s;
}
.cbar button svg{width:25px;height:25px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.cbar button:active{transform:scale(.92)}
.cbar button.off{background:#fff;color:#111}
.cbar button.hang{background:#e04b4b}

/* 「画面缩小」：通话收成右上角的小窗，聊天照常进行，点一下回全屏。
   注意这里只改尺寸和位置，视频流一直挂着——不能重建，重建会黑屏。 */
.call.mini{
  inset:auto;right:12px;top:calc(var(--safe-t) + 58px);bottom:auto;left:auto;
  width:104px;height:146px;border-radius:18px;z-index:88;border:1px solid rgba(255,255,255,.16);
  box-shadow:0 14px 38px rgba(0,0,0,.55);
  transition:width .3s var(--ease),height .3s var(--ease),border-radius .3s var(--ease),top .3s var(--ease);
}
.call.mini .cbar,.call.mini .cinfo,.call.mini #localVid{display:none}
.call.mini:active{transform:scale(.96)}

/* 「谁大谁小」反过来：点一下右上角那格小画面，自己铺满整屏、对方缩到角上，
   再点一下换回来。默认仍然是"看对方为主"，只是把选择权交回给用户。
   ⚠ 跟 mini 一样，只改尺寸和位置 —— 一旦重建 video 就会黑屏、还会断流。 */
.call.swap #localVid{
  width:100%;height:100%;left:0;right:0;top:0;bottom:0;
  border-radius:0;border:0;box-shadow:none;z-index:1;
}
.call.swap #remoteVid{
  width:104px;height:150px;left:auto;right:12px;top:calc(var(--safe-t) + 12px);bottom:auto;
  border-radius:16px;object-fit:cover;border:1px solid rgba(255,255,255,.28);
  z-index:2;box-shadow:0 10px 28px rgba(0,0,0,.5);
}
/* 波斯语界面从右往左排，缩到角上的那格要跟着换边 */
html[dir="rtl"] .call.swap #remoteVid{left:12px;right:auto}

/* 「这一格为什么是黑的」：一句说明摆在画面正中央。
   以前黑就是黑，用户分不清是对方关了摄像头、还是网络压根没连上。 */
.cnote{
  position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);
  display:flex;flex-direction:column;align-items:center;gap:12px;
  padding:0 40px;text-align:center;color:#fff;z-index:5;
  font-size:15px;line-height:1.55;pointer-events:none;
  text-shadow:0 1px 8px rgba(0,0,0,.65);
}
.cnote b{
  width:62px;height:62px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.22);
}
.cnote svg{width:30px;height:30px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}

/* ---------- 来电全屏 ----------
   微信那样：全屏铺深色底、大头像呼吸、底下两个大圆钮。
   之前的底部弹层又矮又容易被忽略，还得多一步才进得去通话。 */
.ring{
  position:fixed;inset:0;z-index:95;display:flex;flex-direction:column;
  align-items:center;justify-content:center;color:#fff;overflow:hidden;
}
.ring-bg{
  position:absolute;inset:0;z-index:-1;
  background:radial-gradient(120% 78% at 50% 0%,#2a3552 0%,#151a26 52%,#0a0c11 100%);
}
.ring-av{
  width:110px;height:110px;border-radius:34px;display:flex;align-items:center;justify-content:center;
  font-size:43px;font-weight:600;color:#fff;overflow:hidden;
  background:linear-gradient(140deg,#5b8def,#3b5bdb);
  animation:ringPulse 2.5s var(--ease) infinite;
}
.ring-av img{width:100%;height:100%;object-fit:cover}
@keyframes ringPulse{
  0%{box-shadow:0 18px 48px rgba(0,0,0,.5),0 0 0 0 rgba(120,160,255,.40)}
  70%{box-shadow:0 18px 48px rgba(0,0,0,.5),0 0 0 26px rgba(120,160,255,0)}
  100%{box-shadow:0 18px 48px rgba(0,0,0,.5),0 0 0 0 rgba(120,160,255,0)}
}
.ring-nm{font-size:25px;font-weight:600;margin-top:26px;letter-spacing:.3px;text-align:center;padding:0 28px}
.ring-sub{font-size:15px;opacity:.72;margin-top:9px}
.ring-bar{position:absolute;left:0;right:0;bottom:calc(52px + var(--safe-b));display:flex;justify-content:center;gap:76px}
.rbtn{display:flex;flex-direction:column;align-items:center;gap:11px;font-size:13px;opacity:.94;color:#fff}
.rbtn b{
  width:70px;height:70px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  transition:transform .14s var(--ease);
}
/* 描边给到 2.2 而不是 1.9：白图标压在彩色圆底上，线太细会"发飘" */
.rbtn b svg{width:31px;height:31px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.rbtn:active b{transform:scale(.9)}
/* ⚠ 接听那个类名是 acc 不是 ok —— 登录页有 `.ok{color:var(--green)}`，
   一叫 ok 就会把图标 stroke 也染成绿色，正好跟绿底同色，图标直接"消失"（踩过）。 */
.rbtn.acc b{background:#07c160;box-shadow:0 10px 26px rgba(7,193,96,.42)}
.rbtn:not(.acc) b{background:#e04b4b;box-shadow:0 10px 26px rgba(224,75,75,.4)}
/* 关于接听钮的对比度（试过又回退了，记一笔免得以后重复折腾）：
   白图标压在微信绿 #07c160 上，算出来只有 2.38:1，低于无障碍建议的 3:1。
   试过深色下把绿压到 #0a9d52（能到 3.52:1），但代价是同一屏里出现两种绿
   —— 来电头像也是 #07c160，两个绿并排一眼就看出不是一套配色。
   最终保持微信原绿：图标本身够大够粗（31px / 2.2 描边），下面还有「接听」
   两个白字（对比度 18.9:1）兜底，实际辨识没有问题，微信自己也是这么配的。
   tools/ui-dark-check.js 里对这条留了防退化断言。 */

/* Jitsi 通话（只在直连彻底不通时兜底） */
#jitsiUI{display:flex!important;flex-direction:column}
#jitsiUI[style*="display:none"]{display:none!important}
.jbar{display:flex;align-items:center;gap:10px;padding:calc(var(--safe-t) + 8px) 12px 8px;background:#1c1c1e;color:#fff;font-size:15px;flex:0 0 auto}
.jbar span{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.jbar button{color:#fff;background:rgba(255,255,255,.16);border-radius:11px;padding:8px 15px;font-size:14px;transition:transform .12s var(--ease)}
.jbar button:active{transform:scale(.94)}
.jbar button.hang2{background:#e04b4b}
#jFrame{flex:1;width:100%;border:0;background:#000}

/* ---------- 游戏 ---------- */
/* 「一起玩」大厅：四个游戏摆成 2×2 的方块。
   以前这页只列「进行中的游戏」，一局没开就是一片空白，进去等于没东西可点；
   现在一眼能看到有什么可玩，点一下选人就能开局。 */
.ghall{display:grid;grid-template-columns:1fr 1fr;gap:11px;padding:2px 14px 4px}
.gcell{
  position:relative;background:var(--card);border:1px solid var(--line);border-radius:var(--r-l);
  padding:14px 13px;display:flex;flex-direction:column;gap:9px;box-shadow:var(--sh-1);
  transition:transform .14s var(--ease),background .16s;animation:fadeUp .3s var(--ease) both;
}
.gcell:active{transform:scale(.965);background:var(--line-2)}
.gcell .gico{
  width:40px;height:40px;border-radius:12px;color:#fff;flex:0 0 auto;
  display:flex;align-items:center;justify-content:center;box-shadow:0 3px 8px rgba(0,0,0,.15);
}
.gcell .gico svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.gcell .gtx{min-width:0}
.gcell .gtx b{display:block;font-size:15.5px;font-weight:600;letter-spacing:.1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gcell .gtx s{text-decoration:none;display:block;font-size:12px;color:var(--txt2);margin-top:3px;line-height:1.45}
.gcell .go{position:absolute;inset-inline-end:11px;top:12px;color:var(--txt3);font-size:17px;line-height:1}
.ghint{text-decoration:none;font-weight:400;color:var(--txt3);font-size:12px;margin-inline-start:6px}
/* 列表行里的游戏图标（大厅「进行中的游戏」、开局前选人那页的头像位都用它） */
.av svg{width:21px;height:21px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.row .chev{color:var(--txt3);font-size:19px;flex:0 0 auto}
.gcard{
  display:flex;align-items:center;gap:10px;background:var(--card);border:1px solid var(--line);
  border-radius:var(--r-m);padding:11px 13px;min-width:200px;box-shadow:var(--sh-1);
}
.msg.me .gcard{background:var(--bub-me);border-color:transparent;color:var(--bub-me-txt)}
.gcard.off{opacity:.55}
.gcard .gico{font-size:26px;line-height:1;display:flex;align-items:center}
.gcard .gico svg{width:26px;height:26px;display:block;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.gcard .gtxt{display:flex;flex-direction:column;min-width:0}
.gcard .gtxt b{font-size:15px}
.gcard .gtxt s{text-decoration:none;font-size:12px;color:var(--txt2)}
.gcard .gopen{margin-inline-start:auto;font-size:12px;color:var(--blue);white-space:nowrap;font-weight:600}
.gwrap{padding:12px 14px 30px;display:flex;flex-direction:column;align-items:center}
.gbar{display:flex;flex-wrap:wrap;gap:6px;padding:11px 14px 5px;background:var(--card);border-bottom:1px solid var(--line)}
.gpl{font-size:12.5px;background:var(--line-2);border-radius:20px;padding:5px 11px;color:var(--txt2)}
.gpl.turn{background:var(--green-l);color:var(--green);font-weight:700}
.gstat{font-size:14px;color:var(--txt2);text-align:center;padding:10px 6px;line-height:1.7}
.gstat b{color:var(--green)}
.gscore{font-size:12.5px;color:var(--txt2)}
.grow{display:flex;gap:8px;justify-content:center;flex-wrap:wrap;margin-top:12px;width:100%}
.gbtn{background:var(--card);border:1px solid var(--line);border-radius:var(--r-m);padding:10px 17px;font-size:14.5px;color:var(--txt);transition:transform .12s var(--ease),background .16s}
.gbtn:active{background:var(--line-2);transform:scale(.96)}
.gbtn.big{font-size:30px;padding:10px 26px;line-height:1.2}
.gbtn.go{background:var(--green);color:#fff;border-color:var(--green);box-shadow:0 4px 12px rgba(7,193,96,.26)}
.rpsrow{gap:16px}
.gtools{width:100%;max-width:420px}
.gcolors{display:flex;gap:9px;justify-content:center;margin-top:12px;flex-wrap:wrap}
.gcolors b{width:28px;height:28px;border-radius:50%;border:2px solid var(--line);display:block;position:relative;transition:transform .16s var(--ease)}
.gcolors b.on{border-color:var(--green);transform:scale(1.16)}
.gcolors b.eraser{border-color:#bbb;background-image:linear-gradient(45deg,#eee 25%,transparent 25%,transparent 75%,#eee 75%),linear-gradient(45deg,#eee 25%,#fff 25%,#fff 75%,#eee 75%);background-size:8px 8px;background-position:0 0,4px 4px}
.gguess input{flex:1;min-width:0;border:1px solid var(--line);border-radius:var(--r-m);padding:11px 13px;outline:none;background:var(--card);transition:border-color .18s,box-shadow .18s}
.gguess input:focus{border-color:var(--green);box-shadow:0 0 0 3px rgba(7,193,96,.13)}
.ghist{width:100%;max-width:420px;margin-top:10px;font-size:13.5px;color:var(--txt2);max-height:150px;overflow-y:auto}
.ghist div{padding:2px 0;unicode-bidi:plaintext}
.ghist div.ok{color:var(--green);font-weight:600}
.gdice{display:flex;flex-wrap:wrap;gap:14px;justify-content:center;margin-top:8px}
.gdie{text-align:center;min-width:64px}
.gdie b{display:block;font-size:52px;line-height:1.15;color:var(--txt)}
.gdie s{text-decoration:none;font-size:12px;color:var(--txt2)}
.grps{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;margin-top:8px}

/* ---------- 战舰 / 四子棋 / 黑白棋 / 翻翻乐 ----------
 * 四种新游戏都是「在网格上点一下」，共用一套棋盘语言。
 * 棋盘一律 direction:ltr —— 波斯语界面下整页是右到左的，棋盘若跟着镜像，
 * 左上角那格会跑到右上，两个人对着同一张图说的位置都对不上。 */
.bslab{width:100%;max-width:420px;display:flex;align-items:baseline;gap:7px;margin:13px 0 6px;font-size:13px;color:var(--txt2)}
.bslab s{text-decoration:none;color:var(--txt3);font-size:12px}
.bslab i{margin-inline-start:auto;font-style:normal;color:var(--green);font-size:12px;font-weight:600}
.bsgrid{width:100%;max-width:420px;display:grid;gap:2px;direction:ltr;background:#9fc6e8;padding:4px;border-radius:10px;box-shadow:var(--sh-1)}
.bsgrid.ro{background:#c2d8ea}
.bsc{display:block;aspect-ratio:1;border-radius:3px;background:#eaf4fd;position:relative;transition:background .18s}
.bsc.ship{background:#5d84a4}
.bsc.miss::after{content:'';position:absolute;inset:35%;border-radius:50%;background:#b3c3d1}
.bsc.hit{background:#e35d5d}
.bsc.hit::after{content:'';position:absolute;inset:31%;border-radius:50%;background:#fff}
.bsc.hit.sunk{background:#9c1c1c;box-shadow:inset 0 0 0 1.5px #6f1010}
.bsgrid.can .bsc{cursor:pointer}
.bsgrid.can .bsc:active{background:#bcdcf6}
.c4board{width:100%;max-width:420px;direction:ltr;display:grid;gap:6px;background:#2f6fb5;padding:8px;border-radius:14px;box-shadow:var(--sh-2)}
.c4col{display:flex;flex-direction:column;gap:6px;border-radius:8px;padding:2px}
.c4col.can{cursor:pointer}
.c4col.can:active{background:rgba(255,255,255,.18)}
.c4c{display:block;aspect-ratio:1;border-radius:50%;background:#e9f2fb;box-shadow:inset 0 2px 3px rgba(0,0,0,.16)}
.c4c.p1{background:#e0453f;box-shadow:inset 0 -2px 5px rgba(0,0,0,.3)}
.c4c.p2{background:#f2c02c;box-shadow:inset 0 -2px 5px rgba(0,0,0,.22)}
.c4c.win{outline:3px solid #fff;outline-offset:-3px}
.c4c.last{animation:c4drop .22s var(--ease)}
@keyframes c4drop{from{transform:translateY(-40%);opacity:.35}to{transform:none;opacity:1}}
.rvboard{width:100%;max-width:400px;direction:ltr;display:grid;gap:2px;background:#1a6f4b;padding:6px;border-radius:12px;box-shadow:var(--sh-2)}
.rvc{display:block;aspect-ratio:1;background:#2f9663;border-radius:3px;position:relative}
.rvc.can{cursor:pointer}
.rvc.can::after{content:'';position:absolute;inset:36%;border-radius:50%;background:rgba(255,255,255,.42)}
.rvc.p1::before,.rvc.p2::before{content:'';position:absolute;inset:11%;border-radius:50%;box-shadow:0 1px 4px rgba(0,0,0,.36)}
.rvc.p1::before{background:radial-gradient(circle at 34% 30%,#616161,#0c0c0c 74%)}
.rvc.p2::before{background:radial-gradient(circle at 34% 30%,#fff,#cbcbcb 76%)}
.rvc.last::before{outline:2px solid #ffd76a;outline-offset:1px}
.rvc.did::before{animation:rvflip .32s var(--ease)}
@keyframes rvflip{from{transform:rotateY(88deg) scale(.9)}to{transform:none}}
.meboard{width:100%;max-width:400px;direction:ltr;display:grid;gap:8px;margin-top:4px}
.mec{display:block;aspect-ratio:1;border-radius:12px;background:linear-gradient(140deg,#9268f2,#6a3fd0);position:relative;box-shadow:var(--sh-1);transition:transform .14s var(--ease),background .2s}
.mec::before{content:'';position:absolute;inset:0;border-radius:12px;background-image:radial-gradient(circle,rgba(255,255,255,.3) 0 1.6px,transparent 1.6px);background-size:10px 10px;opacity:.6}
.mec.can{cursor:pointer}
.mec.can:active{transform:scale(.95)}
.mec.on{background:var(--card);box-shadow:inset 0 0 0 2px var(--line)}
.mec.on::before{opacity:0}
.mec.on svg{position:absolute;inset:19%;width:62%;height:62%}
.mec.done::after{content:'';position:absolute;inset:0;border-radius:12px;background:var(--green-l);opacity:.55}
.mec.done svg{position:relative;z-index:1}
.mec.new{animation:meflash .4s var(--ease)}
@keyframes meflash{0%{box-shadow:0 0 0 0 rgba(7,193,96,.6)}100%{box-shadow:0 0 0 11px rgba(7,193,96,0)}}

/* ================= 波斯语 / RTL =================
 * 界面语言为波斯语时，<html dir="rtl"> 会让 flex/逻辑属性自动镜像，
 * 这里只补那些无法用逻辑属性表达的地方：页面滑入方向、箭头字形、气泡小三角。 */
html[dir="rtl"] .page{transform:translateX(-100%)}
html[dir="rtl"] .page.open{transform:translateX(0)}
/* 返回箭头「‹」和列表箭头「›」要跟着镜像，否则指向反了 */
html[dir="rtl"] .navbar .back,
html[dir="rtl"] .celld .chev,
html[dir="rtl"] .arw{transform:scaleX(-1)}
html[dir="rtl"] .celld:active .chev{transform:scaleX(-1) translateX(2px)}
.arw{display:inline-block}
html[dir="rtl"] .navbar .back{margin-top:-3px}
/* 气泡小三角：RTL 下说话人位置左右互换，三角得跟着换边 */
html[dir="rtl"] .msg:not(.me) .bub::after{left:auto;right:-10px;border-right-color:transparent;border-left-color:var(--bub-other)}
html[dir="rtl"] .msg.me .bub::after{right:auto;left:-10px;border-left-color:transparent;border-right-color:var(--bub-me)}
/* 视频小窗留在右上角不动，这是习惯位置 */
html[dir="rtl"] #localVid{left:auto;right:12px}

/* 用户系统里关掉了动画（有些人会晕），那就别动 */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
}
