/* =============================================================
   幻影解析 — 后台登录（桌面端左右两栏 / 窄屏收成单栏）
   -------------------------------------------------------------
   结构：body(grid 居中) > .stage(flex)
         .stage = [左] .intro 系统介绍 + [右] .box 登录表单
   窄屏 (<900px)：.intro 隐藏，品牌信息压缩进 .box 顶部的 .brand
   ============================================================= */

:root{
  --c-primary:#5b6cff;
  --c-primary-deep:#4553e6;
  --c-violet:#8b5cf6;
  --grad-main:linear-gradient(135deg,#5b6cff 0%,#8b5cf6 100%);
  --t1:#111528;--t2:#4a5169;--t3:#8b91a7;--t4:#aeb3c4;
  --line:#e8eaf3;
  --ease:cubic-bezier(.4,0,.2,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
}

*{margin:0;padding:0;box-sizing:border-box}
/* 全局 SVG 尺寸约束：SVG 无宽高属性时会按替换元素默认尺寸（约 300×150）渲染成巨图 */
svg{width:1em;height:1em;flex:none;display:inline-block;vertical-align:-.125em;overflow:visible}

body{
  font:15px/1.7 -apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  color:var(--t1);
  background:#0d1022;
  /* 居中同时给出「兜底」与「safe」两行：不支持 safe 的浏览器忽略后者、保留 place-items:center；
     支持 safe 的浏览器在内容放不下时改为「从顶部对齐」，顶部永远可达、不会被裁死。 */
  display:grid;place-items:center;padding:24px;
  place-items:safe center;
  /* 容器高度用 svh（最小视口高度），不再依赖 100%/100vh：
     移动端地址栏收放、软键盘弹出只改变「动态视口」，svh 保持恒定，
     居中基准不会重算 → 卡片不会被二次“顶”上去。100vh 作为老浏览器回退。 */
  min-height:100vh;
  min-height:100svh;
  /* 只裁横向溢出；纵向留 visible——按规范，overflow-x 非 visible 时 overflow-y 的
     visible 会计算为 auto，于是矮视口下内容超出时视口可正常滚动，卡片底部不会被裁死。 */
  position:relative;overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}

/* 背景极光 */
.bg{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.bg span{position:absolute;border-radius:50%;filter:blur(90px);opacity:.55;animation:drift 16s ease-in-out infinite alternate}
.bg .b1{width:560px;height:560px;top:-180px;left:-140px;background:radial-gradient(circle,rgba(91,108,255,.6),transparent 70%)}
.bg .b2{width:480px;height:480px;bottom:-170px;right:-120px;background:radial-gradient(circle,rgba(139,92,246,.5),transparent 70%);animation-delay:-6s}
.bg .b3{width:360px;height:360px;top:38%;left:52%;background:radial-gradient(circle,rgba(255,122,69,.18),transparent 70%);animation-delay:-11s}
@keyframes drift{from{transform:translate3d(0,0,0) scale(1)}to{transform:translate3d(30px,-24px,0) scale(1.08)}}

/* 细网格 */
.bg::after{content:"";position:absolute;inset:0;opacity:.35;
  background-image:radial-gradient(rgba(255,255,255,.14) 1px,transparent 1px);
  background-size:28px 28px;
  mask-image:radial-gradient(circle at 50% 45%,#000,transparent 70%);
  -webkit-mask-image:radial-gradient(circle at 50% 45%,#000,transparent 70%)}

/* ===== 两栏舞台：宽度足够时左右并排，窄屏改为纵向单栏（见文末媒体查询） ===== */
.stage{position:relative;z-index:2;width:100%;max-width:880px;
  display:flex;align-items:center;justify-content:center;gap:44px}

/* ---------- 左栏：系统介绍 ---------- */
.intro{flex:1 1 auto;min-width:0;max-width:460px;color:#eef1ff;
  /* 不给 .intro 设 max-height/overflow:hidden：高度兜底由「元素级内容上限」承担——
     每个子元素各自封顶：.i-title 3 行 / .i-desc 3 行 / .i-tags max-height:84px /
     .i-brand strong 2 行 / .i-foot 2 行，外加服务端「标签数 6 + 每标签 8 字」，
     叠加把左栏自然高锁死，页面总高恒 <480，与视口高度无关。
     而 .intro 上的 overflow:hidden 会在极矮视口把左栏底部（备案号 / 标签末行）
     静默裁掉且无法滚动找回，属于信息丢失，得不偿失（QA 已实测：配 ICP 时 H≤334 开始裁）。 */
  animation:cardIn .5s var(--ease-out)}
.intro .i-brand{display:flex;align-items:center;gap:14px;margin-bottom:16px}
/* 站名（site_name）限 2 行：无长度上限会在极矮视口把左栏撑高；
   min-width:0 让 flex 子项可收缩，overflow-wrap:anywhere 防「无空格超长串」把整页横向撑破 */
.intro .i-brand strong{font-size:18.5px;font-weight:800;letter-spacing:-.2px;color:#fff;min-width:0;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}
/* 标题（site_slogan）限 3 行：后台把标语写长也不会撑高左栏 */
.intro .i-title{font-size:clamp(20px,2.2vw,27px);line-height:1.32;font-weight:800;
  letter-spacing:-.4px;color:#fff;margin-bottom:12px;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
/* 介绍段限宽 + 限 3 行。
   注意：不要为了「给站名/备案号腾纵向余量」把它压到 2 行——实测 clamp:2 对默认/典型
   文案的页面高度毫无改善（默认 62 字文案在 clamp:2 与 clamp:3 下页面总高都是 426px），
   却会多出一个截断点（文案超过约 80 字即触发），而默认文案恰好卡在 2 行边界、仅有约
   +7% 字宽余量，换到更宽的字体就可能被顶到第 3 行而遭截断。
   限 3 行时「组合最坏态」页面总高实测 449px，仍 <480（余 31px）；且各元素都是定行数
   clamp，该上界是硬的，不会随字体/内容浮动。 */
.intro .i-desc{font-size:13.5px;line-height:1.75;color:rgba(226,231,255,.72);
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
/* 特性标签：由后台 site_keywords 驱动，自动换行 + 硬上限（两行）。
   服务端已把「数量截到 6、每个截到 8 字」，6 个 ≤8 字的词最多两行 ≈ 64px，留 84px 余量；
   overflow:hidden 仅作最后安全网，正常配置下不应触发。 */
.intro .i-tags{list-style:none;display:flex;flex-wrap:wrap;gap:8px;margin-top:14px;
  max-height:84px;overflow:hidden}
.intro .i-tags li{font-size:12px;line-height:1;padding:7px 11px;border-radius:999px;
  color:rgba(233,237,255,.92);background:rgba(255,255,255,.08);
  border:1px solid rgba(255,255,255,.14)}
/* 备案号（icp）限 2 行：同上，避免无上限撑高左栏；overflow-wrap 防无空格超长串横向溢出 */
.intro .i-foot{margin-top:14px;font-size:12px;color:rgba(200,207,235,.55);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}

/* ---------- 右栏：登录卡片 ---------- */
.box{position:relative;z-index:2;flex:0 0 auto;width:400px;max-width:100%;
  padding:24px 30px 20px;border-radius:24px;
  background:rgba(255,255,255,.97);
  backdrop-filter:blur(20px) saturate(180%);
  box-shadow:0 30px 70px rgba(4,6,20,.55),inset 0 1px 0 rgba(255,255,255,.9);
  animation:cardIn .5s var(--ease-out)}
/* 入场只做透明度淡入，不做任何位移/缩放：
   translateY(16px)/scale(.98) 会让卡片的视觉位置相对居中基准发生变化，
   视觉上就是“又多动了一下、还往上跳”。纯淡入几何零位移，最稳。 */
@keyframes cardIn{from{opacity:0}to{opacity:1}}

/* 品牌（46px 图标 + 站名 / 副标题）：桌面端由左栏承担，故默认隐藏；窄屏才显示在表单顶部 */
.brand{display:none;align-items:center;gap:13px;margin-bottom:16px}
.mark{width:46px;height:46px;flex:none;border-radius:14px;display:grid;place-items:center;
  color:#fff;font-weight:800;font-size:21px;background:var(--grad-main);
  box-shadow:0 10px 24px rgba(91,108,255,.42)}
/* 后台配置了站点 Logo 时：图片铺满同尺寸圆角，替换文字「幻」 */
.mark-img{background:#fff;overflow:hidden}
.mark-img img{width:100%;height:100%;object-fit:cover;display:block}
.intro .mark{width:52px;height:52px;font-size:24px;border-radius:16px}
.brand strong{display:block;font-size:17.5px;font-weight:800;letter-spacing:-.2px}
.brand small{color:var(--t3);font-size:12.5px}

/* 错误提示（紧凑：单行文案，line-height 收紧不影响观感，只省纵向空间） */
.err{display:flex;align-items:center;gap:9px;padding:6px 12px;border-radius:11px;
  background:#fef2f2;color:#b91c1c;border:1px solid #fecaca;font-size:13.5px;line-height:1.4;margin-bottom:9px;
  animation:alertIn .3s var(--ease-out)}
.err svg{width:16px;height:16px;flex:none}
/* 提示条同样只做透明度淡入，避免出现时产生额外位移抖动 */
@keyframes alertIn{from{opacity:0}to{opacity:1}}

/* 成功提示（改密后跳转过来时展示） */
.ok{display:flex;align-items:center;gap:9px;padding:6px 12px;border-radius:11px;
  background:#ecfdf5;color:#047857;border:1px solid #a7f3d0;font-size:13.5px;line-height:1.4;margin-bottom:9px;
  animation:alertIn .3s var(--ease-out)}
.ok svg{width:16px;height:16px;flex:none}

/* 表单 */
.field{margin-bottom:11px}
.field label{display:block;font-size:13px;color:var(--t2);margin-bottom:5px;font-weight:600}
.in-wrap{position:relative;display:flex;align-items:center}
.in-wrap .ico{position:absolute;left:14px;color:var(--t4);font-size:16px;pointer-events:none;
  transition:color .18s var(--ease)}
.in-wrap:focus-within .ico{color:var(--c-primary)}
input{width:100%;padding:10px 14px;border:1.5px solid var(--line);border-radius:12px;
  font-size:15px;font-family:inherit;color:var(--t1);background:#fbfcff;transition:.16s var(--ease)}
input::placeholder{color:var(--t4)}
input:focus{outline:none;border-color:var(--c-primary);background:#fff;
  box-shadow:0 0 0 4px rgba(91,108,255,.12)}
.in-wrap input{padding-left:41px}
.in-wrap input[type=password]{padding-right:44px}
/* 浏览器自动填充：去掉默认的淡蓝底，保持主题观感 */
input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus{
  -webkit-box-shadow:0 0 0 1000px #fbfcff inset;
  -webkit-text-fill-color:var(--t1);
  caret-color:var(--t1);
  transition:background-color 99999s ease-out}
.eye{position:absolute;right:8px;width:32px;height:32px;display:grid;place-items:center;
  border:none;border-radius:9px;background:none;color:var(--t4);cursor:pointer;font-size:15px;
  transition:.16s var(--ease)}
.eye:hover{background:#f1f3fa;color:var(--t2)}

/* 提交 */
button.submit{width:100%;margin-top:9px;padding:12px;border:none;border-radius:12px;cursor:pointer;
  color:#fff;font-size:15px;font-weight:700;letter-spacing:1px;font-family:inherit;
  background:var(--grad-main);box-shadow:0 10px 24px rgba(91,108,255,.36);
  transition:transform .18s var(--ease),box-shadow .18s var(--ease)}
button.submit:hover{transform:translateY(-1px);box-shadow:0 14px 30px rgba(91,108,255,.44)}
button.submit:active{transform:translateY(0) scale(.99)}

.back{display:flex;align-items:center;justify-content:center;gap:6px;margin-top:14px;
  color:var(--t3);font-size:13px;text-decoration:none;transition:.18s var(--ease)}
.back:hover{color:var(--c-primary)}
.back svg{width:14px;height:14px}

.tip{margin-top:14px;padding-top:11px;border-top:1px solid var(--line);
  font-size:12.5px;color:var(--t3);text-align:center;line-height:1.5}

/* 窄屏底部的备案号（桌面端由左栏 .i-foot 承担） */
.stage-foot{display:none}

/* ===== 窄屏 / 移动端：收成单栏，仅保留登录表单 ===== */
@media (max-width:899px){
  .stage{flex-direction:column;gap:0;max-width:400px}
  .intro{display:none}
  .brand{display:flex}
  .box{width:100%}
  .stage-foot{display:block;margin-top:18px;font-size:12px;color:rgba(200,207,235,.5);text-align:center}
}
@media (max-width:480px){
  body{padding:16px}
  .box{padding:28px 22px 24px;border-radius:20px}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;transition-duration:.001ms!important}
}
