@charset "UTF-8";
/* =============================================================================
   xunsuan-login-theme.css — 登录 / 注册 / 找回密码 页面视觉增强
   注入:nginx sub_filter 写入 <head>(/etc/nginx/sites-available/sub2api)
   作用域:仅 AuthLayout 容器内部。双锚点 =
     [data-v-86388737]                  Vue scoped 属性(当前构建)
     .min-h-screen.overflow-hidden.p-4  结构类组合(重建后依然稳定)
   任一命中即生效;都不命中时样式静默失效,不会破坏页面。
   主色沿用应用自带 teal:#14b8a6 / #0d9488
   ============================================================================= */

/* ---------- 1. 背景层 ----------
   踩坑记录:曾用 background-image 覆盖应用自带的 bg-gradient-to-br,
   结果在内容容器范围出现一块边界清晰的矩形色差(登录页/注册页都复现)。
   原因是该层同时受 Tailwind 的 --tw-gradient-* 变量与自定义渐变影响,
   两者叠加后在合成阶段产生硬边。
   现在改为完全不碰这一层 —— 只靠第 2 节的光斑做氛围,背景保持应用原样。 */

/* ---------- 2. 光斑缓慢浮动 + 网格边缘淡出 ---------- */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .pointer-events-none > div:nth-child(1) {
  animation: xs-orb-a 24s ease-in-out infinite;
}
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .pointer-events-none > div:nth-child(2) {
  animation: xs-orb-b 31s ease-in-out infinite;
}
/* 第 3 团光斑自带 translate(-50%,-50%) 居中,关键帧必须保留该位移,否则会跳位 */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .pointer-events-none > div:nth-child(3) {
  animation: xs-orb-c 38s ease-in-out infinite;
}
/* 网格底纹保持应用原样。
   踩坑记录:曾给它加 mask-image 做边缘淡出,结果 mask 强制创建合成层,
   把网格裁成一块边界清晰的矩形(正好是内容容器宽度),在登录页/注册页
   都能看到明显色块。不要再加 mask-image / -webkit-mask-image。        */
@keyframes xs-orb-a {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(-30px, 26px) scale(1.09); }
}
@keyframes xs-orb-b {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(26px, -22px) scale(1.07); }
}
@keyframes xs-orb-c {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50%      { transform: translate(-50%, -50%) scale(1.13); }
}

/* ---------- 3. 入场动画 ----------
   关键约定:绝不用 `both` / `backwards`。
   动画一旦没跑(截图工具的虚拟时间、动画被禁用、CSS 部分加载失败),
   `both` 会把内容永久钉在 opacity:0 —— 登录框直接看不见。
   所以默认完全可见,只用 forwards 叠加一次入场。                        */
@media (prefers-reduced-motion: no-preference) {
  :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mb-8 {
    animation: xs-rise .68s cubic-bezier(.16, 1, .3, 1) .04s forwards;
  }
  :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .card-glass {
    animation: xs-rise .72s cubic-bezier(.16, 1, .3, 1) .12s forwards;
  }
  :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mt-6,
  :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mt-8 {
    animation: xs-rise .7s cubic-bezier(.16, 1, .3, 1) .22s forwards;
  }
}
/* 结束帧 transform:none —— 既清除合成层,也避免残留 transform 形成包含块
   影响卡片内 fixed 弹窗(如 TOTP 对话框)的定位 */
@keyframes xs-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* ---------- 4. Logo:保留原图(object-contain 不裁切),加托板 + 光泽 + 悬停微抬 ---------- */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .h-16.w-16.rounded-2xl {
  padding: 5px;
  background: linear-gradient(145deg, rgba(255, 255, 255, .95), rgba(240, 253, 250, .78));
  border: 1px solid rgba(255, 255, 255, .9);
  box-shadow:
    0 12px 26px -10px rgba(13, 148, 136, .48),
    0 3px 8px -3px rgba(15, 23, 42, .18),
    inset 0 1px 0 rgba(255, 255, 255, .95);
  transition: transform .35s cubic-bezier(.16, 1, .3, 1), box-shadow .35s ease;
}
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .h-16.w-16.rounded-2xl:hover {
  transform: translateY(-2px) scale(1.04);
  box-shadow:
    0 18px 34px -12px rgba(13, 148, 136, .58),
    0 4px 10px -3px rgba(15, 23, 42, .2),
    inset 0 1px 0 rgba(255, 255, 255, .95);
}
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .h-16.w-16.rounded-2xl img {
  border-radius: 12px;
  filter: saturate(1.06) contrast(1.03);
}
.dark :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .h-16.w-16.rounded-2xl {
  background: linear-gradient(145deg, rgba(51, 65, 85, .9), rgba(15, 23, 42, .8));
  border-color: rgba(148, 163, 184, .28);
  box-shadow:
    0 12px 26px -10px rgba(13, 148, 136, .4),
    inset 0 1px 0 rgba(255, 255, 255, .08);
}

/* ---------- 5. 站名:渐变流光 ----------
   注意:亮/暗两套都必须整体够亮,因为文字用 background-clip:text 取色,
   起始色太深会在深色背景上直接"消失"。                                   */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) h1.text-gradient {
  background-image: linear-gradient(100deg, #0d9488 0%, #14b8a6 28%, #5eead4 50%, #14b8a6 72%, #0d9488 100%);
  background-size: 220% 100%;
  animation: xs-sheen 9s ease-in-out infinite;
  line-height: 1.28;
  padding-bottom: .08em;   /* 防止 background-clip:text 裁掉下沉笔画 */
  letter-spacing: -.01em;
}
.dark :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) h1.text-gradient {
  background-image: linear-gradient(100deg, #5eead4 0%, #99f6e4 28%, #ccfbf1 50%, #99f6e4 72%, #5eead4 100%);
}
/* 副标题在深色背景 + 光斑上偏灰,提亮一档保证可读 */
.dark :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mb-8 > p {
  color: #cbd5e1;
}
@keyframes xs-sheen {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

/* ---------- 6. 玻璃卡片 ----------
   只加边框色 + 阴影,不覆写 background,也不覆写 backdrop-filter。
   踩过的坑:再叠一层 padding-box/border-box 背景 => 卡片出现可见矩形色差。
   应用自带的 blur(24px) 已经够用,保持原样最干净。                       */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .card-glass {
  border: 1px solid rgba(20, 184, 166, .22);
  box-shadow:
    0 30px 60px -24px rgba(13, 148, 136, .28),
    0 12px 28px -16px rgba(15, 23, 42, .16),
    inset 0 1px 0 rgba(255, 255, 255, .55);
  transition: border-color .4s ease, box-shadow .4s ease;
}
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .card-glass:hover {
  border-color: rgba(20, 184, 166, .34);
  box-shadow:
    0 38px 72px -26px rgba(13, 148, 136, .34),
    0 14px 32px -18px rgba(15, 23, 42, .18),
    inset 0 1px 0 rgba(255, 255, 255, .6);
}
.dark :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .card-glass {
  border-color: rgba(45, 212, 191, .2);
  box-shadow:
    0 30px 60px -24px rgba(0, 0, 0, .62),
    inset 0 1px 0 rgba(255, 255, 255, .07);
}
.dark :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .card-glass:hover {
  border-color: rgba(45, 212, 191, .32);
}

/* ---------- 7. 输入框:按元素选择,不依赖类名 ---------- */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .card-glass input:not([type="checkbox"]):not([type="radio"]) {
  transition: border-color .2s ease, box-shadow .25s ease, background-color .2s ease;
}
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .card-glass input:not([type="checkbox"]):not([type="radio"]):hover:not(:focus) {
  border-color: rgba(20, 184, 166, .45);
}
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .card-glass input:not([type="checkbox"]):not([type="radio"]):focus {
  border-color: #14b8a6;
  box-shadow: 0 0 0 3px rgba(20, 184, 166, .18);
  outline: none;
}

/* ---------- 8. 主按钮:悬停微抬 + 一次性高光扫过 ---------- */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .btn-primary {
  position: relative;
  overflow: hidden;
  box-shadow: 0 10px 22px -10px rgba(13, 148, 136, .62);
  transition: transform .2s cubic-bezier(.16, 1, .3, 1), box-shadow .25s ease;
}
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 16px 30px -12px rgba(13, 148, 136, .72);
}
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .btn-primary:active {
  transform: translateY(0) scale(.995);
}
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .btn-primary::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -40%;
  width: 34%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .38), transparent);
  transform: skewX(-18deg);
  pointer-events: none;
  opacity: 0;
}
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .btn-primary:hover::after {
  animation: xs-shine .85s ease;
}
@keyframes xs-shine {
  0%   { left: -40%; opacity: .9; }
  100% { left: 112%; opacity: 0; }
}

/* ---------- 9. 文字链接:下划线滑入 ---------- */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mt-6 a,
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .card-glass a {
  position: relative;
  text-decoration: none;
}
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mt-6 a::after,
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .card-glass a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .25s cubic-bezier(.16, 1, .3, 1);
}
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mt-6 a:hover::after,
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .card-glass a:hover::after {
  transform: scaleX(1);
}

/* ---------- 10. 页脚版权:再淡一档 ---------- */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mt-8 {
  letter-spacing: .02em;
  opacity: .8;
}

/* ---------- 11. 窄屏 ---------- */
@media (max-width: 420px) {
  :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) .card-glass { padding: 1.5rem; }
  :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) h1.text-gradient { font-size: 1.75rem; }
}

/* =============================================================================
   13. 文案增强
   ---------------------------------------------------------------------------
   全部用伪元素生成,不改 DOM、不碰应用逻辑、不参与表单提交。
   一律 pointer-events:none,确保不遮挡任何可点击区域。
   注意:这些文字对屏幕阅读器不可见(CSS content 的固有限制),
   因此只放营销性文案,不放功能性信息。
   ============================================================================= */

/* ---------- 13a. 顶部胶囊标签(站名上方) ----------
   坑:.mb-8 是 text-center 的行内上下文,inline-flex 的 ::before 会和
   Logo 挤在同一行。必须先用 display:block + ::before 独占一行,
   再靠 width:fit-content + margin auto 居中。                            */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mb-8::before {
  content: "✦ 官方直连 · 稳定不断流";
  display: block;
  width: -moz-fit-content;
  width: fit-content;
  margin: 0 auto 1.15rem;
  padding: .34rem .85rem;
  border: 1px solid rgba(20, 184, 166, .32);
  border-radius: 999px;
  color: #0f766e;
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .04em;
  line-height: 1.5;
  white-space: nowrap;
  pointer-events: none;
}
.dark :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mb-8::before {
  border-color: rgba(45, 212, 191, .34);
  color: #5eead4;
}

/* ---------- 13b. 卡片底部特性小字 ----------
   ::after 追加在卡片内容流末尾,自然位于登录按钮/第三方登录下方 */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .card-glass::after {
  content: "官方接口直连  ·  高并发稳定不断流  ·  7×24 全天候可用";
  display: block;
  margin-top: 1.35rem;
  padding-top: 1.1rem;
  border-top: 1px solid rgba(148, 163, 184, .18);
  color: #64748b;
  font-size: .7rem;
  letter-spacing: .02em;
  line-height: 1.6;
  text-align: center;
  pointer-events: none;
}
.dark :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .card-glass::after {
  border-top-color: rgba(148, 163, 184, .14);
  color: #94a3b8;
}

/* ---------- 13c. 页脚补充行(版权行上方) ---------- */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mt-8::before {
  content: "为开发者提供可靠的 AI 接口中转服务";
  display: block;
  margin-bottom: .5rem;
  color: #94a3b8;
  font-size: .72rem;
  letter-spacing: .02em;
  line-height: 1.6;
  pointer-events: none;
}
.dark :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mt-8::before {
  color: #64748b;
}

/* ---------- 13e. 副标题中文化 ----------
   应用默认值是英文 "Subscription to API Conversion Platform"。
   这里用 CSS 隐藏原文 + 伪元素输出中文,不改数据库。
   若日后在后台把 site_subtitle 改成中文,删掉本节即可(两者会重复)。   */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mb-8 > p {
  font-size: 0;              /* 隐藏原文,又不影响元素占位 */
  line-height: 1.6;
}
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mb-8 > p::after {
  content: "稳定 · 高速 · 安全的 AI 接口中转服务";
  font-size: .875rem;
  letter-spacing: .01em;
}
@media (max-width: 480px) {
  :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mb-8::before {
    font-size: .7rem;
    padding: .3rem .7rem;
  }
  :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .card-glass::after,
  :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) > .relative.z-10 > .mt-8::before {
    font-size: .66rem;
    white-space: normal;
  }
}

/* =============================================================================
   14. 特性卡片(登录卡下方)
   ---------------------------------------------------------------------------
   DOM 由 xunsuan-login-cards.js 生成并追加到 AuthLayout 根容器末尾。
   根容器原本是 flex + items-center + justify-center(单列居中),
   追加第二个流内子元素后需要显式 column,否则会和登录卡并排。
   :has() 限定 —— 只有卡片真的插入了才改布局,脚本没跑时布局保持原样。
   ============================================================================= */
:is([data-v-86388737], .min-h-screen.overflow-hidden.p-4):has(> #xs-feature-cards) {
  flex-direction: column;
  gap: 2.25rem;
  padding-top: 3rem;
  padding-bottom: 3rem;
}

#xs-feature-cards {
  position: relative;
  z-index: 10;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: .85rem;
  width: 100%;
  max-width: 60rem;
  margin: 0 auto;
}

#xs-feature-cards .xs-fc {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 1.15rem 1.1rem 1.25rem;
  border: 1px solid rgba(148, 163, 184, .22);
  border-radius: 1rem;
  background: rgba(255, 255, 255, .62);
  box-shadow: 0 10px 26px -18px rgba(15, 23, 42, .35);
  transition: transform .28s cubic-bezier(.16, 1, .3, 1),
              border-color .28s ease,
              box-shadow .28s ease;
}
#xs-feature-cards .xs-fc:hover {
  transform: translateY(-3px);
  border-color: rgba(20, 184, 166, .42);
  box-shadow: 0 18px 34px -20px rgba(13, 148, 136, .5);
}
.dark #xs-feature-cards .xs-fc {
  border-color: rgba(148, 163, 184, .16);
  background: rgba(30, 41, 59, .5);
  box-shadow: 0 10px 26px -18px rgba(0, 0, 0, .6);
}
.dark #xs-feature-cards .xs-fc:hover {
  border-color: rgba(45, 212, 191, .4);
}

#xs-feature-cards .xs-fc-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  margin-bottom: .7rem;
  border-radius: .6rem;
  background: rgba(20, 184, 166, .12);
  color: #0d9488;
}
.dark #xs-feature-cards .xs-fc-ico {
  background: rgba(45, 212, 191, .14);
  color: #5eead4;
}
#xs-feature-cards .xs-fc-ico svg {
  width: 1.15rem;
  height: 1.15rem;
}

#xs-feature-cards .xs-fc-t {
  margin: 0 0 .3rem;
  color: #0f172a;
  font-size: .875rem;
  font-weight: 600;
  line-height: 1.4;
}
.dark #xs-feature-cards .xs-fc-t { color: #f1f5f9; }

#xs-feature-cards .xs-fc-d {
  margin: 0;
  color: #64748b;
  font-size: .75rem;
  line-height: 1.65;
}
.dark #xs-feature-cards .xs-fc-d { color: #94a3b8; }

/* 平板:两列 */
@media (max-width: 900px) {
  #xs-feature-cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    max-width: 30rem;
  }
}
/* 手机:单列 */
@media (max-width: 520px) {
  #xs-feature-cards {
    grid-template-columns: minmax(0, 1fr);
    max-width: 26rem;
  }
  #xs-feature-cards .xs-fc { padding: .95rem 1rem 1rem; }
  :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4):has(> #xs-feature-cards) {
    gap: 1.75rem;
  }
}

/* ---------- 12. 尊重"减少动态效果";但保留 loading 转圈 ---------- */
@media (prefers-reduced-motion: reduce) {
  :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) *:not(.animate-spin),
  :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) *:not(.animate-spin)::before,
  :is([data-v-86388737], .min-h-screen.overflow-hidden.p-4) *:not(.animate-spin)::after {
    animation: none !important;
    transition-duration: .01ms !important;
  }
}
