/* ============================================================================
 * 易登录 · Design System stylesheet
 * 对应 docs/07-UI设计规范.md
 * 深浅色:默认跟随系统,支持 [data-theme=dark]/[data-theme=light] 手动切换
 * ============================================================================ */

/* ---- 1. 色彩令牌(浅色)---- */
:root{
  --brand:#24457A; --brand-strong:#1B3560; --brand-soft:#E9EFF8; --on-brand:#FFFFFF;
  --wechat:#07C160;
  --bg:#F5F7FA; --surface:#FFFFFF; --border:#E3E8F0;
  --ink:#1B2432; --ink-2:#5C6B82; --ink-3:#94A1B5;
  --danger:#D64545; --warn:#C87F1F; --ok:#2E8F5B;
  --shadow-card:0 1px 2px rgb(27 36 50 / .05), 0 8px 24px rgb(27 36 50 / .06);
  --shadow-pop:0 12px 32px rgb(27 36 50 / .16);
  --ring:0 0 0 3px var(--brand-soft);

  /* 圆角令牌(替换魔法数字) */
  --radius-sm:4px;
  --radius-md:8px;
  --radius-lg:14px;
  --radius-xl:20px;
  --radius-pill:999px;

  /* 间距令牌(4pt基准) */
  --space-1:4px;  --space-2:8px;  --space-3:12px;  --space-4:16px;
  --space-5:20px; --space-6:24px; --space-8:32px;
  --space-10:40px; --space-12:48px;

  /* 字号令牌(对应 07 字阶表) */
  --fs-xs:12px;  --fs-sm:13px;  --fs-base:15px; --fs-md:16px;
  --fs-lg:18px;  --fs-xl:20px;  --fs-2xl:28px;  --fs-3xl:32px;

  /* 行高令牌 */
  --lh-tight:1.35;  --lh-base:1.6;  --lh-relaxed:1.7;

  /* 动效令牌 */
  --ease-out:cubic-bezier(.2,.7,.3,1);
  --dur-fast:150ms;  --dur-norm:250ms;  --dur-slow:400ms;

  /* 阴影第三阶(浮层增强) */
  --shadow-elevation-2:0 4px 12px rgb(27 36 50/.08);

  /* 最大宽度令牌 */
  --max-w-xs:480px;  --max-w-sm:600px;  --max-w-md:720px;
  --max-w-lg:960px;  --max-w-xl:1080px;
}

/* 系统深色 */
@media (prefers-color-scheme: dark){
  :root:not([data-theme]){
    --brand:#8FB0E8; --brand-strong:#A9C4F0; --brand-soft:#1E2C44; --on-brand:#0E141F;
    --bg:#0E141F; --surface:#161E2C; --border:#273347;
    --ink:#E8EDF5; --ink-2:#93A1B8; --ink-3:#5E6C82;
    --danger:#F08A8A; --warn:#E8B15C; --ok:#5BC48A;
    --shadow-card:0 1px 2px rgb(0 0 0 / .3), 0 8px 24px rgb(0 0 0 / .2);
    --shadow-pop:0 12px 32px rgb(0 0 0 / .5);
    --shadow-elevation-2:0 4px 12px rgb(0 0 0 / .25);
  }
}

/* 手动深色 */
[data-theme="dark"]{
  --brand:#8FB0E8; --brand-strong:#A9C4F0; --brand-soft:#1E2C44; --on-brand:#0E141F;
  --bg:#0E141F; --surface:#161E2C; --border:#273347;
  --ink:#E8EDF5; --ink-2:#93A1B8; --ink-3:#5E6C82;
  --danger:#F08A8A; --warn:#E8B15C; --ok:#5BC48A;
  --shadow-card:0 1px 2px rgb(0 0 0 / .3), 0 8px 24px rgb(0 0 0 / .2);
  --shadow-pop:0 12px 32px rgb(0 0 0 / .5);
  --shadow-elevation-2:0 4px 12px rgb(0 0 0 / .25);
}

/* 手动浅色(显式覆盖系统)---- */
[data-theme="light"]{
  --brand:#24457A; --brand-strong:#1B3560; --brand-soft:#E9EFF8; --on-brand:#FFFFFF;
  --bg:#F5F7FA; --surface:#FFFFFF; --border:#E3E8F0;
  --ink:#1B2432; --ink-2:#5C6B82; --ink-3:#94A1B5;
  --danger:#D64545; --warn:#C87F1F; --ok:#2E8F5B;
  --shadow-card:0 1px 2px rgb(27 36 50 / .05), 0 8px 24px rgb(27 36 50 / .06);
  --shadow-pop:0 12px 32px rgb(27 36 50 / .16);
}

/* ---- 2. reset + base ---- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
html,body{margin:0;padding:0}
body{
  background:var(--bg);
  color:var(--ink);
  font-family:-apple-system,"PingFang SC","HarmonyOS Sans SC","Microsoft YaHei","Noto Sans CJK SC",sans-serif;
  font-size:15px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  min-height:100vh;
}
img{max-width:100%;display:block}
button{font-family:inherit}
input,textarea,select{font-family:inherit;font-size:inherit;color:inherit}
a{color:var(--brand);text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3,h4,h5,h6{margin:0;text-wrap:balance}
::selection{background:var(--brand-soft);color:var(--ink)}

:focus{outline:none}
:focus-visible{outline:none;box-shadow:var(--ring);border-radius:var(--radius-sm)}

/* ---- 3. 通用工具类 ---- */
.mono{font-family:ui-monospace,"SF Mono",Menlo,Consolas,monospace;font-variant-numeric:tabular-nums}
.tnum{font-variant-numeric:tabular-nums}
.eyebrow{font-size:var(--fs-xs);font-weight:500;letter-spacing:.08em;color:var(--ink-2);text-transform:uppercase}
.muted{color:var(--ink-2)}
.faint{color:var(--ink-3)}
.center{display:flex;align-items:center;justify-content:center}
.row{display:flex;align-items:center;gap:8px}
.col{display:flex;flex-direction:column}
.gap-4{gap:4px}.gap-8{gap:8px}.gap-12{gap:12px}.gap-16{gap:16px}.gap-24{gap:24px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.hide{display:none !important}

/* ---- 4. Wordmark(双环钥匙孔 SVG)---- */
.wordmark{display:inline-flex;align-items:center;gap:12px;font-size:var(--fs-lg);text-decoration:none !important;white-space:nowrap}
.wordmark b{font-weight:600}
.wordmark .mk{width:26px;height:26px;flex:none;object-fit:cover;border-radius:6px}
.wordmark.lg{font-size:var(--fs-lg)}
.wordmark.sm{font-size:var(--fs-base)}
.wordmark.sm .mk{width:20px;height:20px}

/* ---- 5. 按钮 ---- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  height:44px;padding:0 20px;border-radius:var(--radius-md);
  border:1px solid transparent;
  font-size:var(--fs-base);font-weight:500;cursor:pointer;
  background:var(--brand);color:var(--on-brand);
  transition:background var(--dur-fast) var(--ease-out),
             border-color var(--dur-fast) var(--ease-out),
             color var(--dur-fast) var(--ease-out),
             transform var(--dur-fast) var(--ease-out),
             opacity var(--dur-fast) var(--ease-out);
  user-select:none;white-space:nowrap;
}
.btn:hover{background:var(--brand-strong)}
.btn:active{transform:scale(.98)}
.btn:focus-visible{box-shadow:var(--ring)}
.btn:disabled,.btn[disabled]{opacity:.4;cursor:not-allowed;transform:none}

/* 圆形/方形小图标按钮.IconBtn */
.iconbtn{
  display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;border-radius:50%;
  border:1px solid var(--border);background:transparent;color:var(--ink-2);
  cursor:pointer;transition:background var(--dur-fast),color var(--dur-fast),transform var(--dur-fast);
}
.iconbtn:focus-visible{box-shadow:var(--ring)}
.iconbtn:hover{background:var(--brand-soft);color:var(--brand)}
.iconbtn:active{transform:scale(.96)}

/* 微信按钮(网页端少用,小程序确认页)---- */
.btn.wx{background:var(--wechat);color:#fff;border-color:var(--wechat)}
.btn.wx:hover{background:#06a552;border-color:#06a552}

/* 次按钮/ghost ---- */
.btn.ghost{background:transparent;border-color:var(--border);color:var(--ink)}
.btn.ghost:hover{background:var(--brand-soft);color:var(--brand);border-color:transparent}

/* 危险按钮(描边)---- */
.btn.danger{background:transparent;border-color:var(--danger);color:var(--danger)}
.btn.danger:hover{background:color-mix(in srgb,var(--danger) 10%,transparent);color:var(--danger)}

/* 文字链 ---- */
.link{color:var(--brand);background:none;border:none;padding:0;cursor:pointer;font-size:14px;font-family:inherit;text-decoration:none}
.link:hover{text-decoration:underline}
.link.muted{color:var(--ink-2)}
.link.muted:hover{color:var(--brand)}

.btn.loading{position:relative;color:transparent !important;pointer-events:none}
.btn.loading::after{
  content:"";position:absolute;left:50%;top:50%;
  width:16px;height:16px;margin:-8px 0 0 -8px;
  border:2px solid currentColor;border-right-color:transparent;
  border-radius:50%;
  color:var(--on-brand);
  animation:spin .7s linear infinite;
}
.btn.ghost.loading::after,.btn.danger.loading::after{color:var(--brand)}

/* ---- 6. 输入框 ---- */
.field{display:flex;flex-direction:column;gap:6px}
.field > label{font-size:var(--fs-sm);color:var(--ink-2)}
.field .input-wrap{position:relative;display:flex;align-items:center}
.field .input-wrap .eye{
  position:absolute;right:10px;top:50%;transform:translateY(-50%);
  width:30px;height:30px;border-radius:var(--radius-md);
  display:inline-flex;align-items:center;justify-content:center;
  background:transparent;border:none;color:var(--ink-2);cursor:pointer;
}
.field .input-wrap .eye:hover{color:var(--ink)}
.field input{
  height:44px;width:100%;
  border:1px solid var(--border);border-radius:var(--radius-md);
  padding:0 14px;font-size:var(--fs-base);
  background:var(--surface);color:var(--ink);
}
.field input::placeholder{color:var(--ink-3)}
.field input:focus{border-color:var(--brand);box-shadow:var(--ring)}
.field input:disabled{background:color-mix(in srgb,var(--border) 40%,transparent);color:var(--ink-3);cursor:not-allowed}
.field.err input{border-color:var(--danger)}
.field.err input:focus{box-shadow:0 0 0 3px color-mix(in srgb,var(--danger) 18%,transparent)}
.field .msg{font-size:var(--fs-sm);color:var(--danger);display:flex;align-items:center;gap:4px}
.field .hint{font-size:var(--fs-xs);color:var(--ink-3)}

/* ---- 7. Tab(底部指示条)---- */
.tabs{display:flex;gap:28px;border-bottom:1px solid var(--border);position:relative}
.qr-only-tabs{border-bottom:0;gap:0}
.qr-only-tabs .tab{cursor:default}
.qr-only-tabs .tab-indicator{display:none}
.tab{
  background:none;border:none;
  font-size:var(--fs-md);color:var(--ink-2);
  padding:8px 2px 10px;
  cursor:pointer;font-family:inherit;
  position:relative;
  transition:color var(--dur-fast) var(--ease-out);
}
.tab[aria-selected="true"]{color:var(--ink);font-weight:600}
.tab[aria-selected="true"]::after{
  content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;
  background:var(--brand);border-radius:2px;
}

/* Tab 滑动指示条(07 §5):位置与宽度由 JS 计算,通过 transform/width 平滑过渡 */
.tab-indicator{
  position:absolute;
  bottom:-1px;
  left:0;
  height:2px;
  width:0;
  background:var(--brand);
  border-radius:var(--radius-sm);
  transition:transform var(--dur-norm) var(--ease-out), width var(--dur-norm) var(--ease-out);
  pointer-events:none;
}
@media (prefers-reduced-motion: reduce){
  .tab-indicator{transition:none}
  .tick{animation:none !important}
}

/* ---- 8. 二维码面板(核心)---- */
.qrwrap{align-self:center;display:flex;flex-direction:column;align-items:center;gap:14px}
.qrbox{
  width:220px;height:220px;
  background:#fff;border:1px solid var(--border);border-radius:var(--radius-lg);
  padding:12px;position:relative;
  transition:filter var(--dur-norm) var(--ease-out);
}
.qrbox canvas,.qrbox img{
  width:100%;height:100%;display:block;border-radius:var(--radius-sm);
}
@media (max-width:599px){
  .qrbox{width:180px;height:180px;padding:10px}
}
.qrmask{
  position:absolute;inset:0;border-radius:var(--radius-lg);
  display:none;align-items:center;justify-content:center;flex-direction:column;gap:10px;
  color:var(--ink);
}
.qrbox.qr-loading canvas,.qrbox.qr-loading img{opacity:.28;filter:grayscale(.35)}
.qrbox.qr-loading .qrmask.m-loading{display:flex;background:rgb(255 255 255 / .62);backdrop-filter:blur(1px)}
.qrbox.qr-pending .qrmask{display:none}
.qrbox.qr-scanned .qrmask.m-scan{display:flex;background:rgb(27 36 50 / .08)}
.qrbox.qr-confirmed .qrmask.m-ok{display:flex;background:rgb(255 255 255 / .92)}
.qrbox.qr-expired canvas,.qrbox.qr-expired img,
.qrbox.qr-consumed canvas,.qrbox.qr-consumed img{filter:blur(5px)}
.qrbox.qr-expired .qrmask.m-exp,
.qrbox.qr-consumed .qrmask.m-exp{display:flex;background:rgb(255 255 255 / .55)}
.qrbox.qr-error .qrmask.m-err{display:flex;background:rgb(255 255 255 / .85)}

.qrmask .circ{
  width:64px;height:64px;border-radius:50%;
  background:#fff;box-shadow:var(--shadow-pop);
  display:flex;align-items:center;justify-content:center;
}
.qrmask .pill{
  font-size:var(--fs-sm);color:var(--ink);background:var(--surface);border-radius:var(--radius-pill);
  padding:2px 12px;box-shadow:var(--shadow-pop);
}
.qrmask .text{font-size:var(--fs-sm);color:var(--ink)}
.qrhint{font-size:var(--fs-sm);color:var(--ink-2);text-align:center;max-width:280px}
.footlinks, .muted, .field > label, .field .msg, .qrhint { line-height:20px; }
.qrhint b{color:var(--wechat);font-weight:500}
.qrhint.err b{color:var(--danger)}
.qrhint.warn b{color:var(--warn)}

/* 扫码成功的对勾一次性画入 ---- */
@media (prefers-reduced-motion: no-preference){
  .tick{stroke-dasharray:36;stroke-dashoffset:36;animation:tick .4s var(--ease-out) forwards}
  @keyframes tick{to{stroke-dashoffset:0}}
}

/* ---- 9. 单元格 Cell ---- */
.cell{
  display:flex;align-items:center;gap:14px;
  min-height:56px;padding:8px 20px;
  border-top:1px solid var(--border);
  color:var(--ink);
}
.card > .cell:first-of-type{border-top:none;margin-top:8px}
.cell .ic{width:20px;flex:none;color:var(--ink-2);display:inline-flex;align-items:center;justify-content:center}
.cell .ic.wx{color:var(--wechat)}
/* 头像行:头像作为行图标时用 40px,槽位自适应(默认 .avatar.lg 64px 会溢出 20px 槽) */
.cell .ic.avatar-ic{width:auto}
.cell .ic.avatar-ic .avatar{width:40px;height:40px;font-size:16px}
.cell .t{flex:1;min-width:0}
.cell .t small{display:block;font-size:var(--fs-xs);color:var(--ink-3);margin-top:2px}
.cell .v{font-size:var(--fs-sm);color:var(--ink-2);max-width:50%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cell .v.warn{color:var(--warn)}
.cell .v.danger{color:var(--danger)}
.cell .v.ok{color:var(--ok)}
.cell .chev{
  width:18px;height:18px;flex:none;color:var(--ink-3);
}
.cell .row-actions{display:flex;align-items:center;gap:12px;flex:none}

/* 紧凑型(登录记录等)---- */
.cell.compact{min-height:44px;padding:6px 20px}

/* ---- 10. 徽章 Badge ---- */
.badge{
  display:inline-block;font-size:var(--fs-xs);font-weight:500;letter-spacing:.05em;
  border-radius:var(--radius-pill);padding:2px 10px;line-height:1.4;
  white-space:nowrap;
}
.badge.ok{color:var(--ok);background:color-mix(in srgb,var(--ok) 12%,transparent)}
.badge.off{color:var(--ink-3);background:color-mix(in srgb,var(--ink-3) 14%,transparent)}
.badge.cur{color:var(--brand);background:var(--brand-soft)}
.badge.warn{color:var(--warn);background:color-mix(in srgb,var(--warn) 14%,transparent)}
.badge.danger{color:var(--danger);background:color-mix(in srgb,var(--danger) 14%,transparent)}

/* ---- 11. Toast / 信息条 ---- */

/* Toast(双主题一致)---- */
.toast-wrap{
  position:fixed;top:24px;left:50%;transform:translateX(-50%);
  z-index:9999;display:flex;flex-direction:column;gap:10px;
  pointer-events:none;width:max-content;max-width:90vw;
}
.toast{
  background:#1B2432;color:#fff;
  padding:10px 18px;border-radius:var(--radius-md);
  font-size:14px;
  box-shadow:var(--shadow-pop);
  display:flex;align-items:center;gap:8px;pointer-events:auto;
  transform:translateY(-12px);opacity:0;
  transition:transform var(--dur-norm) var(--ease-out),opacity var(--dur-norm) var(--ease-out);
}
.toast.show{transform:translateY(0);opacity:1}
.toast.success{background:var(--ok)}
.toast.error{background:var(--danger)}
.toast.info{background:#1B2432}
@media (prefers-reduced-motion: reduce){
  .toast{transition:opacity var(--dur-fast)}
  .toast.show{transform:none}
}

/* 页面级信息条(左侧 3px 品牌色竖条)---- */
.infobar{
  display:flex;gap:10px;align-items:center;
  background:var(--brand-soft);border-left:3px solid var(--brand);
  color:var(--brand);font-size:var(--fs-sm);
  padding:8px 12px;border-radius:0 var(--radius-md) var(--radius-md) 0;
}
.infobar b{font-weight:600}
.infobar.danger{background:color-mix(in srgb,var(--danger) 10%,transparent);border-left-color:var(--danger);color:var(--danger)}
.infobar.warn{background:color-mix(in srgb,var(--warn) 12%,transparent);border-left-color:var(--warn);color:var(--warn)}

/* ---- 12. 卡片 ---- */
.card{
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--radius-lg);
  box-shadow:var(--shadow-card);
}
.card > h3{font-size:var(--fs-xl);font-weight:600;padding:16px 20px 0;line-height:28px}

/* ---- 13. 头像 ---- */
.avatar{
  width:34px;height:34px;border-radius:50%;
  background:var(--brand-soft);color:var(--brand);
  display:inline-flex;align-items:center;justify-content:center;
  font-weight:600;flex:none;
  background-size:cover;background-position:center;
  text-transform:uppercase;
}
.avatar.lg{width:64px;height:64px;font-size:24px}
.avatar.sm{width:28px;height:28px;font-size:var(--fs-xs)}

/* ---- 14. 通用转圈 ---- */
.spinner{
  width:36px;height:36px;border-radius:50%;
  border:3px solid var(--border);border-top-color:var(--brand);
  animation:spin .8s linear infinite;
  display:inline-block;
}
.spinner.lg{width:56px;height:56px;border-width:4px}
.spinner.sm{width:18px;height:18px;border-width:2px}
@keyframes spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion: reduce){.spinner{animation-duration:1.6s}}

/* ============================================================================
 * 15. 登录页布局
 * ============================================================================ */
.login-wrap{
  min-height:100vh;
  display:grid;
  grid-template-columns:40% 60%;
}
.brandcol{
  background:var(--brand-strong);color:var(--brand-soft);
  padding:40px 36px;
  display:flex;flex-direction:column;justify-content:space-between;
  position:relative;overflow:hidden;
}
.brandcol .wordmark{color:var(--brand-soft)}
.brandcol h1{
  font-size:var(--fs-2xl);font-weight:600;line-height:38px;margin:36px 0 0;
  text-wrap:balance;
}
.brandcol .subs{
  font-size:var(--fs-sm);color:var(--ink-3);
  display:flex;flex-direction:column;gap:6px;
  margin-top:auto;
}
.brandcol .rings{position:absolute;right:-90px;bottom:-90px;width:300px;height:300px;opacity:.25;pointer-events:none}

.authcol{
  padding:32px 48px;
  display:flex;flex-direction:column;gap:20px;
  justify-content:center;
  max-width:640px;margin:0 auto;width:100%;
}
/* 密码登录/注册表单:字段纵向间距 + 整宽主按钮(07 规范 44px) */
form.pane{display:flex;flex-direction:column;gap:14px}
form.pane > .btn{width:100%;margin-top:4px}
.authcol .formfoot{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;font-size:var(--fs-sm)}
/* 深色模式下浏览器自动填充的高亮底色矫正 */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus{
  -webkit-box-shadow:0 0 0 1000px var(--surface) inset;
  -webkit-text-fill-color:var(--ink);
  caret-color:var(--ink);
  transition:background-color 9999s ease-out 0s;
}
.footlinks{
  font-size:var(--fs-sm);color:var(--ink-3);
  display:flex;gap:16px;justify-content:center;margin-top:16px;flex-wrap:wrap;
}
.footlinks .dot-bullet{color:var(--ink-3);user-select:none}

/* 协议提示行(登录/注册即同意用户协议与隐私政策) */
.agreement-hint{
  margin:12px 0 0;
  text-align:center;
  font-size:var(--fs-xs);
  color:var(--ink-3);
  line-height:var(--lh-base);
}
.agreement-hint .link{font-size:inherit}

/* ============================================================================
 * 15b. OAuth 授权登录:居中简洁窄卡片布局(.login-compact)
 *      深浅色均由设计令牌(--bg/--surface/--border/--brand-soft 等)自动适配
 * ============================================================================ */
.login-wrap.login-compact{
  display:flex;align-items:center;justify-content:center;
  padding:40px 16px;
  background:
    radial-gradient(ellipse at 18% 0%, var(--brand-soft) 0%, transparent 55%),
    radial-gradient(ellipse at 82% 100%, var(--brand-soft) 0%, transparent 55%),
    var(--bg);
}
.login-compact .compact-card{
  width:100%;max-width:440px;
  margin:0;
  padding:32px 32px 28px;
  justify-content:flex-start;
  gap:18px;
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--radius-lg);
  box-shadow:var(--shadow-card);
}
.login-compact .compact-head{
  display:flex;flex-direction:column;align-items:center;
  gap:6px;text-align:center;margin-bottom:2px;
}
.login-compact .compact-head .wordmark{font-size:var(--fs-base)}
.login-compact .compact-head .wordmark .mk{width:20px;height:20px}
.login-compact .compact-title{
  font-size:var(--fs-xl);font-weight:600;line-height:var(--lh-tight);
  color:var(--ink);margin:6px 0 0;
}
.login-compact .compact-title b{color:var(--brand)}
.login-compact .compact-sub{
  margin:0;font-size:var(--fs-sm);color:var(--ink-2);
}
.login-compact .compact-sub b{font-weight:600;color:var(--ink-2)}
@media (max-width:599px){
  .login-wrap.login-compact{padding:20px 12px;align-items:flex-start}
  .login-compact .compact-card{padding:24px 18px 20px;border-radius:var(--radius-md)}
}

/* 响应式:< 960px 单列,品牌栏收缩顶部 */
@media (max-width: 959px){
  .login-wrap{grid-template-columns:1fr;grid-template-rows:auto 1fr}
  .brandcol{
    flex-direction:row;justify-content:space-between;align-items:center;
    padding:14px 24px;min-height:auto;
    gap:16px;
  }
  .brandcol .brand-mid{display:none}
  .brandcol .subs{display:none}
  .brandcol .rings{width:140px;height:140px;right:-50px;bottom:-50px;opacity:.18}
  .authcol{padding:32px 24px 48px}
}
@media (max-width: 599px){
  .brandcol { min-height: 80px; padding: 16px 18px; }
  .brandcol .brand-mid h1 { font-size: 20px; line-height: 28px; }
  .brand-mid { display: flex; align-items: center; gap: 8px; }
  .brandcol .subs { display: none; } /* 小屏隐藏子站列表 */
  .authcol { padding: 16px 18px; gap: 16px; }
  .qrbox { width: 160px; height: 160px; padding: 10px; }
  .tabs { gap: 16px; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .tabs::-webkit-scrollbar { display: none; }
  .tab{font-size:var(--fs-base)}
  .btn { height: 40px; font-size: 14px; }
  .field input { height: 40px; font-size: 14px; }
  /* 长按识别文案 --- JS 在 < 600px 时动态切换说明 */
}

/* ============================================================================
 * 16. 用户中心布局
 * ============================================================================ */
.uc-nav{
  display:flex;justify-content:space-between;align-items:center;
  padding:14px 32px;border-bottom:1px solid var(--border);
  background:var(--surface);
  position:sticky;top:0;z-index:10;
}
.uc-nav .right{display:flex;align-items:center;gap:14px}
.uc-user{
  display:flex;align-items:center;gap:10px;
  font-size:14px;color:var(--ink);
  cursor:pointer;border-radius:var(--radius-md);padding:4px 8px 4px 4px;
  transition:background var(--dur-fast);
  position:relative;
}
.uc-user:hover{background:var(--brand-soft)}
.uc-user .chev{display:inline-flex;align-items:center;color:var(--ink-3);line-height:1}
.uc-menu{
  position:absolute;top:calc(100% + 6px);right:8px;
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-md);box-shadow:var(--shadow-pop);
  min-width:160px;padding:6px;
  display:none;z-index:20;
}
.uc-user[aria-expanded="true"] .uc-menu,
.uc-menu.show{display:block}
.uc-menu button{
  display:flex;align-items:center;gap:10px;width:100%;
  padding:8px 12px;border:none;background:none;
  font-size:14px;color:var(--ink);cursor:pointer;
  border-radius:var(--radius-md);text-align:left;
}
.uc-menu button:hover{background:var(--brand-soft);color:var(--brand)}
.uc-menu button.danger:hover{background:color-mix(in srgb,var(--danger) 12%,transparent);color:var(--danger)}

.uc-body{
  max-width:720px;margin:0 auto;
  padding:32px 24px 48px;
  display:flex;flex-direction:column;gap:20px;
}
.uc-body h2{font-size:var(--fs-2xl); line-height:38px; font-weight:600; }
.uc-empty{
  max-width:420px;margin:48px auto;text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:12px;padding:24px;
}

@media (max-width: 599px){
  .uc-nav{padding:10px 18px;flex-wrap:wrap;gap:8px}
  .uc-user{font-size:var(--fs-sm)}
  .uc-body{padding:24px 18px 40px;gap:16px}
  .uc-body h2{font-size:var(--fs-xl)}
  .cell{padding:8px 16px;gap:10px;flex-wrap:wrap}
  .cell .v{max-width:none}
  /* 登录记录窄屏:行内换行,时间列不被撑开容器 */
  .loglist .cell { flex-wrap: wrap; gap: 4px; }
  .loglist .cell .v.mono { width: auto !important; }
}

/* 行内编辑 / 弹层 ---- */
.inline-edit{
  display:flex;gap:8px;align-items:center;margin-top:4px;
}
.inline-edit input{
  height:34px;border:1px solid var(--border);
  border-radius:var(--radius-md);padding:0 10px;font-size:14px;
  background:var(--surface);color:var(--ink);
  width:min(220px,40vw);
}
.inline-edit input:focus{border-color:var(--brand);box-shadow:var(--ring);border-radius:6px}
.inline-edit .btn{height:34px;padding:0 14px;font-size:var(--fs-sm)}
.inline-edit .btn.ghost{padding:0 12px}

/* 模态弹层 ---- */
.modal-mask{
  position:fixed;inset:0;background:rgb(27 36 50 / .45);
  display:flex;align-items:center;justify-content:center;
  z-index:200;padding:24px;
  animation:fadein .2s ease;
}
.modal-mask.hide{display:none}
.modal{
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-pop);
  width:min(420px,92vw);padding:24px 24px 20px;
  display:flex;flex-direction:column;gap:16px;
}
.modal h3{font-size:var(--fs-lg);font-weight:600}
.modal .modal-foot{display:flex;justify-content:flex-end;gap:8px;margin-top:4px}

/* 微信绑定二维码 ---- */
.wechat-bind-modal{width:min(440px,92vw)}
.wechat-bind-panel{display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center}
.wechat-bind-panel p{margin:0;min-height:24px;color:var(--ink-2);font-size:var(--fs-sm)}
.wechat-bind-panel > .btn{height:40px}
.wechat-bind-panel > .btn[hidden]{display:none !important}
.wechat-bind-qr{
  width:220px;height:220px;position:relative;overflow:hidden;
  border:1px solid var(--border);border-radius:var(--radius-lg);
  background:#fff;padding:12px;
}
.wechat-bind-qr img{width:100%;height:100%;object-fit:contain;border-radius:var(--radius-sm)}
.wechat-bind-state{
  position:absolute;inset:0;display:none;align-items:center;justify-content:center;
  padding:24px;background:rgb(255 255 255 / .9);color:#1B2432;
  font-size:var(--fs-sm);font-weight:500;text-align:center;
}
.wechat-bind-qr.is-loading .wechat-bind-state,
.wechat-bind-qr.is-scanned .wechat-bind-state,
.wechat-bind-qr.is-confirmed .wechat-bind-state,
.wechat-bind-qr.is-expired .wechat-bind-state,
.wechat-bind-qr.is-canceled .wechat-bind-state,
.wechat-bind-qr.is-error .wechat-bind-state{display:flex}
.wechat-bind-qr.is-scanned img,
.wechat-bind-qr.is-expired img,
.wechat-bind-qr.is-canceled img,
.wechat-bind-qr.is-error img{filter:blur(4px)}
.wechat-bind-qr.is-confirmed .wechat-bind-state{color:var(--ok)}
.wechat-bind-qr.is-error .wechat-bind-state{color:var(--danger)}

/* 头像裁剪 ---- */
.avatar-crop-modal{width:min(480px,94vw)}
.avatar-crop-stage{
  width:min(320px,100%);aspect-ratio:1;margin:0 auto;position:relative;
  overflow:hidden;border:1px solid var(--border);border-radius:var(--radius-md);
  background:#fff;cursor:grab;touch-action:none;user-select:none;
}
.avatar-crop-stage.dragging{cursor:grabbing}
.avatar-crop-stage canvas{width:100%;height:100%;display:block}
.avatar-crop-grid{
  position:absolute;inset:0;pointer-events:none;
  border:1px solid rgb(255 255 255 / .75);
  box-shadow:inset 0 0 0 999px rgb(14 20 31 / .08);
}
.avatar-crop-grid::before,.avatar-crop-grid::after{
  content:"";position:absolute;background:rgb(255 255 255 / .55);pointer-events:none;
}
.avatar-crop-grid::before{left:33.333%;right:33.333%;top:0;bottom:0;border-left:1px solid rgb(255 255 255 / .55);border-right:1px solid rgb(255 255 255 / .55);background:none}
.avatar-crop-grid::after{top:33.333%;bottom:33.333%;left:0;right:0;border-top:1px solid rgb(255 255 255 / .55);border-bottom:1px solid rgb(255 255 255 / .55);background:none}
.avatar-crop-zoom{display:grid;grid-template-columns:auto 1fr;align-items:center;gap:14px}
.avatar-crop-zoom label{font-size:var(--fs-sm);color:var(--ink-2)}
.avatar-crop-zoom input{width:100%;accent-color:var(--brand);cursor:pointer}
.avatar-crop-hint{margin:0;text-align:center;color:var(--ink-3);font-size:var(--fs-xs)}

@media (max-width:599px){
  .modal-mask{padding:16px}
  .modal{padding:20px 18px 16px;max-height:calc(100vh - 32px);overflow:auto}
  .avatar-crop-stage{width:min(280px,100%)}
  .modal .modal-foot{position:sticky;bottom:-16px;background:var(--surface);padding-top:8px}
  .wechat-bind-qr{width:200px;height:200px}
}

/* ============================================================================
 * 17. 通用页面(错误页 / 过渡页)
 * ============================================================================ */
.center-page{
  min-height:100vh;display:flex;align-items:center;justify-content:center;
  padding:32px;
  flex-direction:column;
}
.errcard{
  max-width:420px;margin:0 auto;text-align:center;
  padding:36px 32px;display:flex;flex-direction:column;gap:10px;align-items:center;
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-card);
}
.errcard .ic{
  width:56px;height:56px;border-radius:50%;
  background:color-mix(in srgb,var(--danger) 12%,transparent);
  color:var(--danger);
  display:flex;align-items:center;justify-content:center;
  font-size:26px;font-weight:600;
}
.errcard h3{font-size:var(--fs-lg);margin-top:6px}
.errcard p{margin:0;font-size:14px;color:var(--ink-2);line-height:1.7;max-width:36ch}
.errcard .err-detail{
  background:var(--brand-soft);color:var(--brand);
  border-radius:var(--radius-md);padding:10px 14px;font-size:var(--fs-sm);
  margin:4px 0;width:100%;box-sizing:border-box;
  text-align:left;
}
.errcard .footnote{font-size:var(--fs-sm);color:var(--ink-3);margin-top:8px}

/* 过渡页 ---- */
.transition-page{
  min-height:100vh;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:24px;background:var(--bg);
}
.transition-page .wordmark{margin-bottom:8px}
.transition-page .tip{
  font-size:var(--fs-base);color:var(--ink-2);text-align:center;max-width:36ch;
}
.transition-page .dest{color:var(--brand);font-weight:600}
.transition-page .spinner.lg{margin-bottom:4px}

@keyframes fadein{from{opacity:0}to{opacity:1}}

/* ============================================================================
 * 19. 骨架屏 Shimmer
 * ============================================================================ */
@keyframes shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}
.skeleton{background:linear-gradient(90deg,var(--surface) 25%,var(--border) 37%,var(--surface) 63%);background-size:400% 100%;animation:shimmer 1.5s ease-in-out infinite}
.skeleton.text{height:1em;border-radius:var(--radius-sm);margin-bottom:.5em;width:100%}
.skeleton.avatar{width:40px;height:40px;border-radius:50%;flex:none}
.skeleton.btn{height:44px;border-radius:var(--radius-md);width:120px}

/* ============================================================================
 * 20. 通用动效工具类
 * ============================================================================ */
.fade-in{animation:fadeIn var(--dur-norm) var(--ease-out) both}
.slide-up{animation:slideUp var(--dur-norm) var(--ease-out) both}
.scale-in{animation:scaleIn var(--dur-norm) var(--ease-out) both}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes slideUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
@keyframes scaleIn{from{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}

/* ============================================================================
 * 21. empty-state 组件
 * ============================================================================ */
.empty-state{display:flex;flex-direction:column;align-items:center;gap:var(--space-4);padding:var(--space-12) var(--space-6);text-align:center;color:var(--ink-3)}
.empty-state .empty-icon{width:64px;height:64px;border-radius:50%;background:var(--brand-soft);display:flex;align-items:center;justify-content:center;font-size:28px;color:var(--brand);opacity:.6}
.empty-state .empty-title{font-size:var(--fs-base);color:var(--ink-2);font-weight:500}
.empty-state .empty-desc{font-size:var(--fs-sm);color:var(--ink-3);max-width:280px}

/* ============================================================================
 * 22. loading-overlay
 * ============================================================================ */
.loading-overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--bg) 60%,transparent);z-index:10;border-radius:inherit;backdrop-filter:blur(2px)}

/* ============================================================================
 * 18. 减少动效
 * ============================================================================ */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
  .skeleton{animation:none;background:var(--border)}
  .fade-in,.slide-up,.scale-in{animation:none}
}

/* === 最近登录:子站首字母徽标(oauth_clients 无图标字段,以首字充当站点图标) === */
.site-ini{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;
  border-radius:5px;background:var(--brand-soft);color:var(--brand);font-size:11px;font-weight:600;
  margin-right:6px;vertical-align:-3px;flex:none}
