/* ============================================================
 *  登录页专属视觉层
 * ------------------------------------------------------------
 *  为什么单独一个文件，而不是并进 style.css：
 *    这里全是「只有登录页用」的规则（光斑、玻璃卡片、打字机）。
 *    混进 1000 多行的 style.css 里，以后想调登录页观感得在
 *    全站样式中翻；而独立文件的真正价值是**隔离**——
 *    登录页不引它，观感改动就绝无可能波及登录后的任何页面。
 *
 *  【性能取舍，都是老安卓 WebView 上真会卡的地方】
 *    1) 光斑**不用 filter:blur()**，改用 radial-gradient 自然收边。
 *       320px 的元素每帧做一次高斯模糊，低端机直接掉到 30fps 以下，
 *       而径向渐变是 GPU 一次绘制，几乎免费。
 *    2) 所有动画**只动 transform / opacity**。
 *       动 width/height/top/left 会每帧触发重排，登录页在低端机上
 *       从「丝滑」变成「一卡一卡」，用户第一印象就没了。
 *    3) 毛玻璃用 @supports 包起来。默认（不支持时）是**实色**高对比卡片，
 *       支持了才升级成通透玻璃 —— 方向是「老设备得到更朴素但清晰的样子」，
 *       而不是反过来让老设备得到一堆看不清的字。
 * ============================================================ */

/* ---- 底色 ---- */
/* 兜底色写在 background 之前：万一某天整条渐变被老浏览器判非法丢弃，
   页面至少是深蓝底而不是刺眼白底 —— 白底 + 浅色文字 = 什么都看不见。 */
html.lg{background:#0b1220}
body.lg{
  min-height:100vh;min-height:100dvh;
  background:
    radial-gradient(120% 85% at 50% -12%, rgba(37,99,235,.55) 0%, rgba(37,99,235,0) 62%),
    radial-gradient(90% 60% at 108% 8%, rgba(139,92,246,.42) 0%, rgba(139,92,246,0) 60%),
    linear-gradient(168deg,#0b1220 0%,#111d33 46%,#0a1728 100%);
  background-attachment:fixed;
  color:#e8eefb;
  /* 光斑是会横向漂移的，不锁掉就会出现左右晃动的一像素滚动条 */
  overflow-x:hidden;
}

/* ---- 漂浮光斑（装饰层，永远在卡片之下）----
   pointer-events:none 是硬要求：任何一层漏掉它，
   Selenium/用户的手指就可能点到「看不见的圆」上，
   表现为点击提交偶发失灵 —— 这类故障极难定位。 */
.lg-bg{
  position:fixed;left:0;top:0;right:0;bottom:0;
  z-index:0;overflow:hidden;pointer-events:none;
}
.lg-blob{
  position:absolute;border-radius:50%;
  will-change:transform,opacity;
}
.lg-blob.b1{width:340px;height:340px;left:-110px;top:-90px;opacity:.6;
  background:radial-gradient(circle at 50% 50%,rgba(56,189,248,.60) 0%,rgba(56,189,248,0) 70%);
  animation:lg-drift1 24s ease-in-out infinite}
.lg-blob.b2{width:300px;height:300px;right:-90px;top:14%;opacity:.5;
  background:radial-gradient(circle at 50% 50%,rgba(167,139,250,.55) 0%,rgba(167,139,250,0) 70%);
  animation:lg-drift2 30s ease-in-out infinite}
.lg-blob.b3{width:420px;height:420px;left:-80px;bottom:-150px;opacity:.42;
  background:radial-gradient(circle at 50% 50%,rgba(34,211,238,.42) 0%,rgba(34,211,238,0) 70%);
  animation:lg-drift1 36s ease-in-out infinite reverse}
@keyframes lg-drift1{
  0%,100%{transform:translate3d(0,0,0) scale(1)}
  50%    {transform:translate3d(26px,34px,0) scale(1.12)}
}
@keyframes lg-drift2{
  0%,100%{transform:translate3d(0,0,0) scale(1)}
  50%    {transform:translate3d(-30px,26px,0) scale(1.1)}
}

/* ---- 主体层级：卡片必须明确高于装饰层 ---- */
.loginwrap{position:relative;z-index:1}

/* ---- 卡片 ----
   默认（无毛玻璃）：实色深底，保证任何底图上文字都够清楚。
   @supports 里才换成半透明玻璃。 */
.logincard.lg-card{
  max-width:360px;
  padding:30px 26px 24px;
  border-radius:18px;
  border:1px solid rgba(255,255,255,.14);
  background:rgba(13,22,40,.86);
  box-shadow:0 20px 50px rgba(2,8,20,.5);
  color:#e8eefb;
  animation:lg-rise .5s cubic-bezier(.22,.9,.3,1) both;
}
@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .logincard.lg-card{
    background:rgba(17,29,51,.62);
    -webkit-backdrop-filter:blur(14px) saturate(1.5);
    backdrop-filter:blur(14px) saturate(1.5);
    box-shadow:0 20px 50px rgba(2,8,20,.42);
  }
}

/* ---- 低端机降级：把最贵的几项关掉 ----
 *
 * 【为什么需要这一段】
 * backdrop-filter: blur(14px) 是登录页**最贵的一条样式**：
 * 它要求 GPU 每帧重新采样卡片背后的像素。手机上还有 3 个
 * 无限循环的漂浮光斑在背后不断移动，等于每帧都要重新做一次
 * 半径 14px 的高斯模糊。低端机（Mali-T6xx / Adreno 3xx 一带）
 * 跑这个组合会持续掉帧，表现为「进登录页时明显卡一下、
 * 滑动时整页发涩」。
 *
 * 【为什么用 JS 加类，而不是 @media 静态查询】
 * CSS 媒体查询查不到「帧率低」—— 卡顿是运行时现象，不是设备属性。
 * 真正能判断的是 JS：先量一帧的实际耗时，超过了就降级。
 * 见 login.html 末尾的 lg-perf-guard 脚本。
 *
 * 【降级后保留什么】
 * 保留：渐变背景（GPU 成本可忽略）、入场动画（只跑 0.5s）。
 * 去掉：毛玻璃模糊（换成不透明度略高的实色）、三个漂浮光斑的持续动画
 *       与 logo 的呼吸光环。
 * 视觉上仍是同一套设计，只是「静」了一点 —— 而这正是低端机
 * 最需要的：宁可不漂亮，也不能卡。
 *
 * 注意 !important 是必须的：上面那些规则写在 @supports 里，
 * 特异性相同的情况下后写的规则本来就能覆盖，
 * 但光斑动画用的是 lg-drift-* 这类 keyframes，
 * 关掉它的干净做法是让元素不再触发动画（lg-slow 类）。
 */
.lg-slow .lg-card{
  -webkit-backdrop-filter:none !important;
  backdrop-filter:none !important;
  /* 模糊没了就要靠不透明度补，否则文字压在高光上会看不清 */
  background:rgba(15,25,44,.92) !important;
}
.lg-slow .lg-blob{
  /* 光斑保留但不参与动画：静态的一层浅色渐变几乎不花成本 */
  animation:none !important;
  opacity:.5 !important;
}
.lg-slow .lg-logo::before{
  animation:none !important;
}
@keyframes lg-rise{
  from{opacity:0;transform:translateY(14px) scale(.985)}
  to  {opacity:1;transform:none}
}

/* ---- 品牌图标：悬浮 + 呼吸光环 ---- */
.lg-logo{
  position:relative;
  width:70px;height:70px;margin:0 auto 16px;
  display:flex;align-items:center;justify-content:center;
  font-size:33px;line-height:1;border-radius:22px;
  background:linear-gradient(140deg,#3b82f6,#8b5cf6);
  box-shadow:0 12px 28px rgba(99,102,241,.42);
  animation:lg-float 4.6s ease-in-out infinite;
}
/* 光环用 ::before 画：只动 transform/opacity，不触发重排 */
.lg-logo::before{
  content:"";position:absolute;left:0;top:0;right:0;bottom:0;
  border-radius:22px;border:1.5px solid rgba(255,255,255,.5);
  animation:lg-halo 2.9s ease-out infinite;
}
@keyframes lg-float{
  0%,100%{transform:translateY(0)}
  50%    {transform:translateY(-6px)}
}
@keyframes lg-halo{
  0%  {transform:scale(1);opacity:.85}
  70% {opacity:0}
  100%{transform:scale(1.38);opacity:0}
}

.lg-title{
  font-size:20px;font-weight:700;letter-spacing:.6px;
  margin:0 0 6px;color:#fff;
}
/* 打字机副标题：min-height 预留一行高度，否则文字逐字出现时
   下面的表单会一格一格往下跳 —— 那是「没做好的动态」的典型观感。 */
.lg-sub{
  color:#9db0cd;font-size:13px;letter-spacing:.5px;
  margin:0 0 20px;min-height:20px;
}
.lg-sub .lg-caret{
  display:inline-block;width:2px;height:13px;margin-left:2px;
  vertical-align:-2px;background:#4cc2ff;
  animation:lg-blink 1s steps(1,end) infinite;
}
@keyframes lg-blink{0%,49%{opacity:1}50%,100%{opacity:0}}

/* 今天的日期/农历：每天真的会变，属于「有信息量的动态」而不是纯装饰 */
.lg-today{
  display:inline-block;margin:0 0 18px;padding:5px 13px;
  border-radius:20px;font-size:12.5px;letter-spacing:.3px;
  color:#bcd3f5;background:rgba(96,165,250,.14);
  border:1px solid rgba(96,165,250,.28);
}

/* ---- 表单 ---- */
.lg-card .fld{margin-bottom:16px}
.lg-card .fld > span{color:#9db0cd;margin-bottom:7px}
.lg-card .fld input{
  padding:11px 13px;
  font-size:16px;               /* 手机上 <16px 会触发 iOS 式聚焦缩放，这里是安卓 WebView，
                                  同样按大字号走，虚拟键盘不会顶掉输入框 */
  border-radius:11px;
  background:rgba(255,255,255,.07);
  border:1px solid rgba(255,255,255,.16);
  color:#eef4ff;
  transition:border-color .2s ease,box-shadow .2s ease,background-color .2s ease;
}
.lg-card .fld input::placeholder{color:#7b8ca6}
.lg-card .fld input:focus{
  outline:none;border-color:#4cc2ff;
  background:rgba(255,255,255,.10);
  box-shadow:0 0 0 4px rgba(76,194,255,.16);
}
/* 密码可见性按钮
   ------------------------------------------------------------------
   【踩过的坑：它曾经掉到密码框下面另起一行】
   原来只写了 color 和 :hover，没写定位。按钮是 inline-block，
   跟着密码框（block）在文档流里自然换行，于是渲染成密码框下方
   一个灰色小方块 —— 看着像"多出来一个控件"，而不是密码框的一部分。

   【正确做法三件套】
   1) .pwdwrap 声明 position:relative —— 成为按钮的定位参照。
      不能拿 .lg-card 当参照：卡片上还有别的装饰元素，用卡片当参照
      会让按钮跟着整卡布局漂。
   2) 密码框 padding-right 预留按钮宽度 —— 输入的文字不会被压在眼睛底下。
      留48px：按钮 34px + 左右各 7px 余量。
   3) 按钮 position:absolute 贴右侧居中 —— 视觉上"长在框里"。
   老安卓 WebView 对 position:absolute 支持是完整的，不需要降级。 */
.pwdwrap{
  position:relative;
  display:block;                /* <span> 默认 inline，不声明的话
                                  absolute 定位的参照计算在部分 WebView 上会偏 */
}
.lg-card .pwdwrap input{
  padding-right:48px;/* 给眼睛让位 */
}

/* 按钮本体：只做背景/颜色/尺寸，禁止动 width/height/top/left（会每帧重排） */
.lg-card .eyebtn{
  position:absolute;
  top:50%;
  right:7px;
  transform:translateY(-50%);   /* 垂直居中只动 transform，不动 top —— 符合性能约定 */
  width:34px;height:34px;
  display:flex;align-items:center;justify-content:center;
  padding:0;margin:0;
  border:none;border-radius:9px;
  background:transparent;
  color:#8fa4c2;
  cursor:pointer;
  transition:color .18s ease,background-color .18s ease;
  /* 触摸热区：视觉34px，但四周扩到48px，小拇指也点得中。
     用伪元素扩大热区，不影响布局，也不怕背景跟着变大。 */
  -webkit-tap-highlight-color:transparent;
}
.lg-card .eyebtn::before{
  content:"";
  position:absolute;
  top:50%;left:50%;
  width:48px;height:48px;
  transform:translate(-50%,-50%);
}
.lg-card .eyebtn:hover{background:rgba(255,255,255,.10);color:#dce8f8}
.lg-card .eyebtn:active{background:rgba(255,255,255,.16);color:#fff}

/* 键盘可达性：只有键盘聚焦（:focus-visible）才给描边，
   手指点击不描边 —— 否则每次点眼睛按钮都留一圈难看的焦点框 */
.lg-card .eyebtn:focus{outline:none}
.lg-card .eyebtn:focus-visible{
  outline:2px solid #4cc2ff;outline-offset:2px;
}

/* SVG 图标：描边式，随 currentColor 变色 */
.lg-card .eyebtn svg{
  width:19px;height:19px;
  fill:none;
  stroke:currentColor;
  stroke-width:1.7;
  stroke-linecap:round;
  stroke-linejoin:round;
  pointer-events:none;         /* 图标不挡按钮自身的点击 */
}
/* 两态切换：默认显示「睁眼（点击可看）」，
   .on 是 JS 切上的，此时显示「闭眼（点击可藏）」。
   用 visibility 而不是 display —— 两者都参与无障碍树，但 visibility
   切换不触发重排，动画过渡也更顺。 */
.lg-card .eyebtn .ico-shut{display:none}
.lg-card .eyebtn.on .ico-open{display:none}
.lg-card .eyebtn.on .ico-shut{display:block}
.lg-card .eyebtn.on{color:#4cc2ff}   /* 密码可见时给个明确提示，避免忘了自己开着 */

/* ---- 登录按钮：渐变 + 悬停微光扫过 ---- */
.btn.primary.lg-btn{
  position:relative;overflow:hidden;
  padding:12px;border-radius:11px;
  font-size:15.5px;font-weight:600;letter-spacing:5px;
  border:none;color:#fff;
  background:linear-gradient(135deg,#3b82f6,#7c5cf0);
  box-shadow:0 10px 24px rgba(59,130,246,.36);
  transition:transform .12s ease,box-shadow .2s ease,filter .2s ease;
}
.btn.primary.lg-btn:hover{filter:brightness(1.07)}
.btn.primary.lg-btn:active{transform:translateY(1px) scale(.99)}
/* 微光是一层斜切的高光带，只在悬停/聚焦时跑一次 0.9s 的扫过。
   【为什么扫动的是 translateX 而不是 left】
   left 属于布局属性，每改一帧都要重排整个按钮（老安卓机上尤其明显，
   表现为「按下去卡一下」）。transform 走的是合成层，只动像素不重排。 */
.lg-btn::after{
  content:"";position:absolute;top:0;bottom:0;left:0;
  width:55%;pointer-events:none;
  background:linear-gradient(100deg,rgba(255,255,255,0),rgba(255,255,255,.42),rgba(255,255,255,0));
  transform:translateX(-240%) skewX(-18deg);
}
.lg-btn:hover::after,.lg-btn:focus-visible::after{animation:lg-sheen .9s ease-out}
@keyframes lg-sheen{
  from{transform:translateX(-240%) skewX(-18deg)}
  to  {transform:translateX(320%) skewX(-18deg)}
}

/* ---- 底部文字 ---- */
.lg-foot{margin:18px 0 0;text-align:center;font-size:12px;color:#7588a4;letter-spacing:.4px}
.lg-foot .lg-alt{margin:0 0 4px;color:#9db0cd;font-size:13px}
.lg-foot a{color:#6fb3ff;font-weight:600}
.lg-foot a:hover{color:#9ccbff}

/* ---- 深色底上的提示条 ----
   flash.js 会把它们改造成浮条/弹窗，但转换前的第一帧、
   以及脚本彻底没跑起来时的 noscript 横幅，都是这里的底色在撑着。
   沿用 style.css 的浅底浅字即可，不必为深色背景重写一套。 */

/* ---- 动画降级 ----
   「动态」是加分项，不是功能。开了「减少动态效果」或在老设备上
   掉帧时，宁可静态也不要晃。所有入场/循环动画在此一刀切停掉，
   光斑保留（它就是一层静态渐变，不动而已）。 */
@media (prefers-reduced-motion:reduce){
  .lg-blob,.lg-logo,.lg-logo::before,.lg-sub .lg-caret,
  .logincard.lg-card,.lg-btn::after{animation:none !important}
}

/* 极窄屏（如 320px 的老设备）再收一点，避免按钮文字被 letter-spacing 挤换行 */
@media (max-width:360px){
  .logincard.lg-card{padding:24px 18px 20px;border-radius:16px}
  .btn.primary.lg-btn{letter-spacing:2px}
  .lg-logo{width:60px;height:60px;font-size:28px;border-radius:19px}
  .lg-logo::before{border-radius:19px}
}