<template>
  <div class="login-page">
    <div class="bg-image" />
    <div class="bg-overlay" />
    <div class="bg-orb bg-orb-a" />
    <div class="bg-orb bg-orb-b" />
    <div class="bg-orb bg-orb-c" />
    <div class="bg-stars" aria-hidden="true">
      <span v-for="i in 18" :key="i" :style="starStyles[i - 1]" />
    </div>

    <div class="login-card mg-glass-lg">
      <!-- 左侧品牌 hero -->
      <div class="hero">
        <div class="hero-brand">
          <div class="hero-mark">迷</div>
          <div class="hero-name">迷毂</div>
        </div>
        <div class="hero-tagline">智 能 调 度 平 台</div>
        <div class="hero-tagline-en">INTELLIGENT · DISPATCH · PLATFORM</div>
        <div class="hero-divider" />
        <ul class="hero-points">
          <li><span class="dot" /> 复刻 ARCHITECTURE.md §3.2 启动登录窗</li>
          <li><span class="dot" /> Web-Enabled · 管理员 / 运营 双视图</li>
          <li><span class="dot" /> 嵌入 webVRender 真实 3D 场景</li>
        </ul>
        <div class="hero-footnote">
          <span class="badge">v1.7</span>
          <span>{{ ui.activeTheme.name }} · {{ ui.activeTheme.preview }}</span>
        </div>
      </div>

      <!-- 右侧表单 -->
      <div class="panel">
        <div class="panel-head">
          <div class="panel-title">登 录</div>
          <div class="panel-sub">访问 SimpleLite 的 Vue 外壳</div>
        </div>

        <el-form ref="formRef" :model="form" :rules="rules" class="glass-form" hide-required-asterisk>
          <el-form-item prop="username">
            <el-input v-model="form.username" size="large" placeholder="用户名" autocomplete="username" clearable>
              <template #prefix><el-icon><User /></el-icon></template>
            </el-input>
          </el-form-item>
          <el-form-item prop="password">
            <el-input v-model="form.password" type="password" size="large" show-password placeholder="密码（Mock，任意非空）" autocomplete="current-password">
              <template #prefix><el-icon><Lock /></el-icon></template>
            </el-input>
          </el-form-item>

          <el-form-item prop="scope" class="scope-item">
            <div class="scope-wrap">
              <button type="button" class="scope-tab" :class="{ active: form.scope === 'Platform' }" @click="form.scope = 'Platform'">
                <el-icon><Setting /></el-icon>
                <div class="scope-meta">
                  <div class="scope-name">管理员</div>
                  <div class="scope-desc">platform-vue · 全功能</div>
                </div>
              </button>
              <button type="button" class="scope-tab" :class="{ active: form.scope === 'RCSMonitor' }" @click="form.scope = 'RCSMonitor'">
                <el-icon><Monitor /></el-icon>
                <div class="scope-meta">
                  <div class="scope-name">运营</div>
                  <div class="scope-desc">rcsmonitor-vue · 受限</div>
                </div>
              </button>
            </div>
          </el-form-item>

          <!-- 会话 N+1（启动反转）：Platform.Server 作为主入口，登录时由用户选择 SimpleLite 的启动模式。
               选 "本地+Web" → SimpleLite 同时启 LocalTerminal + WebTerminal；选 "仅Web" → 只起 WebTerminal。-->
          <el-form-item prop="launchMode" class="scope-item launch-mode-item">
            <div class="launch-mode-head">
              <span class="launch-mode-title">SimpleLite 启动模式</span>
              <el-tooltip placement="top">
                <template #content>
                  <div class="launch-tip">
                    <div><b>本地+Web</b>：登录后由 Platform 后端拉起 SimpleLite，同时打开桌面端 ImGui 窗口与浏览器端 webVRender。</div>
                    <div><b>仅 Web</b>：只起 WebTerminal，不弹本地桌面窗口，适合远程办公 / 服务器部署。</div>
                  </div>
                </template>
                <el-icon class="launch-mode-help"><QuestionFilled /></el-icon>
              </el-tooltip>
            </div>
            <div class="scope-wrap launch-wrap">
              <button
                type="button"
                class="scope-tab"
                :class="{ active: form.launchMode === 'DesktopAndWeb' }"
                @click="form.launchMode = 'DesktopAndWeb'">
                <el-icon><Cpu /></el-icon>
                <div class="scope-meta">
                  <div class="scope-name">本地 + Web</div>
                  <div class="scope-desc">桌面窗口 & 浏览器同时启动</div>
                </div>
              </button>
              <button
                type="button"
                class="scope-tab"
                :class="{ active: form.launchMode === 'WebOnly' }"
                @click="form.launchMode = 'WebOnly'">
                <el-icon><Connection /></el-icon>
                <div class="scope-meta">
                  <div class="scope-name">仅 Web</div>
                  <div class="scope-desc">不启桌面窗口 · 浏览器使用</div>
                </div>
              </button>
            </div>
          </el-form-item>

          <div class="row row-between">
            <el-checkbox v-model="form.remember" size="default" class="remember">下次自动按当前 scope 进入</el-checkbox>
            <el-link underline="never" class="adv-link" @click="adv = adv.length ? [] : ['adv']">高级 ›</el-link>
          </div>

          <el-collapse v-model="adv" class="adv-collapse">
            <el-collapse-item name="adv">
              <template #title><span class="adv-title">Web-Enabled · 端口与监听</span></template>
              <div class="adv-grid">
                <el-form-item label="监听地址">
                  <el-input v-model="adv2.host" size="default" />
                </el-form-item>
                <el-form-item label="WebAPI">
                  <el-input-number v-model="adv2.apiPort" :min="1" :max="65535" size="default" controls-position="right" />
                </el-form-item>
                <el-form-item label="Platform">
                  <el-input-number v-model="adv2.platformPort" :min="1" :max="65535" size="default" controls-position="right" />
                </el-form-item>
                <el-form-item label="webVRender">
                  <el-input-number v-model="adv2.vrPort" :min="1" :max="65535" size="default" controls-position="right" />
                </el-form-item>
              </div>
            </el-collapse-item>
          </el-collapse>

          <el-button type="primary" :loading="loading" class="btn-login" size="large" @click="submit">
            登 录
          </el-button>

          <div class="bottom-note">
            任意非空用户名 + 任意密码即可登录；scope 决定进入 admin / monitor 视图；权限按 Mock 表生成。
          </div>
        </el-form>
      </div>
    </div>

    <div class="footer-stamp">
      迷毂 · {{ year }} · ARCHITECTURE v1.6 · powered by webVRender
    </div>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import { User, Lock, Setting, Monitor, Cpu, Connection, QuestionFilled } from '@element-plus/icons-vue'
import { useAuthStore } from '@/stores/auth'
import { useUiStore } from '@/stores/ui'
import type { LaunchMode, Scope } from '@/types/auth'

const route = useRoute()
const router = useRouter()
const auth = useAuthStore()
const ui = useUiStore()

const formRef = ref<FormInstance>()
const loading = ref(false)
const adv = ref<string[]>([])

const form = reactive({
  username: 'admin',
  password: 'admin',
  scope: 'Platform' as Scope,
  // 会话 N+1：默认「本地+Web」与改造前 Configuration.displayMode="web+local" 一致，
  // 保证「我啥也不选」时的行为与改造前完全相同。
  launchMode: 'DesktopAndWeb' as LaunchMode,
  remember: true
})

const adv2 = reactive({
  host: '0.0.0.0',
  apiPort: 7001,
  platformPort: 8080,
  vrPort: 8223
})

const rules: FormRules = {
  username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
  password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
  scope: [{ required: true, message: '请选择 scope', trigger: 'change' }],
  launchMode: [{ required: true, message: '请选择启动模式', trigger: 'change' }]
}

const year = computed(() => new Date().getFullYear())

const starStyles = Array.from({ length: 18 }, (_, i) => {
  const top = Math.random() * 100
  const left = Math.random() * 100
  const size = 2 + Math.random() * 3
  const delay = -Math.random() * 6
  const opacity = 0.35 + Math.random() * 0.45
  void i
  return {
    top: `${top}%`,
    left: `${left}%`,
    width: `${size}px`,
    height: `${size}px`,
    opacity: `${opacity}`,
    animationDelay: `${delay}s`
  } as Record<string, string>
})

async function submit() {
  if (!formRef.value) return
  await formRef.value.validate(async (ok) => {
    if (!ok) return
    loading.value = true
    try {
      const resp = await auth.login({
        username: form.username,
        password: form.password,
        scope: form.scope,
        launchMode: form.launchMode
      })
      ElMessage.success(`欢迎，${auth.user?.displayName ?? form.username}`)
      // 会话 N+1：如果后端返回了 launchWarning（如「检测到既有 SimpleLite 在跑、本次启动模式未生效」），
      // 在登录成功的 toast 之后再追加一条警告条，确保用户感知到「实际行为」与「期望」之间的偏差。
      if (resp.launchWarning) {
        ElMessage({ message: resp.launchWarning, type: 'warning', duration: 6000, showClose: true })
      } else if (resp.runMode === 'Detached') {
        ElMessage({
          message: 'SimpleLite 未启动（Platform.Server 单独运行），/api/sl/* 相关功能将不可用。',
          type: 'warning',
          duration: 6000,
          showClose: true
        })
      }
      const target = (route.query.redirect as string | undefined) ?? (form.scope === 'Platform' ? '/admin/dashboard' : '/monitor/map')
      router.push(target)
    } catch (e) {
      const msg = e instanceof Error ? e.message : String(e)
      ElMessage.error(`登录失败：${msg}`)
    } finally {
      loading.value = false
    }
  })
}
</script>

<style scoped>
/* ===== 背景层 ===== */
.login-page {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  font-family: 'PingFang SC', 'Microsoft YaHei', 'Segoe UI', sans-serif;
}
.bg-image {
  position: absolute; inset: 0;
  background: url('/login-bg.jpg') center/cover no-repeat;
  filter: saturate(0.35) brightness(0.34) hue-rotate(-12deg);
  transform: scale(1.08);
  z-index: 0;
}
.bg-overlay {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse at 12% 18%, rgba(var(--mg-primary-hover-rgb), 0.65) 0%, transparent 55%),
    radial-gradient(ellipse at 85% 80%, rgba(var(--mg-bg-app-deep-rgb), 0.78) 0%, transparent 60%),
    radial-gradient(ellipse at 50% 50%, rgba(var(--mg-primary-rgb), 0.40) 0%, transparent 70%),
    linear-gradient(135deg, rgba(var(--mg-bg-aside-rgb), 0.85) 0%, rgba(var(--mg-primary-rgb), 0.48) 50%, rgba(var(--mg-bg-app-deep-rgb), 0.88) 100%);
  z-index: 1;
}
/* 登录页：紫色网格层(更明显) */
.bg-overlay::after {
  content: '';
  position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(var(--mg-accent-rgb), 0.08) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--mg-accent-rgb), 0.08) 1px, transparent 1px);
  background-size: 56px 56px, 56px 56px;
  mask-image: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.7) 0%, transparent 70%);
  -webkit-mask-image: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.7) 0%, transparent 70%);
}
.bg-orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  z-index: 1;
  pointer-events: none;
  animation: drift 18s ease-in-out infinite;
}
.bg-orb-a {
  width: 460px; height: 460px;
  top: -140px; left: -120px;
  background: radial-gradient(circle, var(--mg-accent) 0%, var(--mg-primary) 50%, transparent 80%);
  opacity: 0.6;
}
.bg-orb-b {
  width: 580px; height: 580px;
  bottom: -200px; right: -180px;
  background: radial-gradient(circle, var(--mg-primary-hover) 0%, var(--mg-bg-app-3) 60%, transparent 85%);
  opacity: 0.55;
  animation-delay: -6s;
}
.bg-orb-c {
  width: 320px; height: 320px;
  top: 30%; right: 8%;
  background: radial-gradient(circle, var(--mg-primary-light-8) 0%, var(--mg-primary-hover) 60%, transparent 90%);
  opacity: 0.32;
  animation-delay: -12s;
}
@keyframes drift {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(20px, -30px) scale(1.05); }
}

.bg-stars { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.bg-stars span {
  position: absolute;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 0 8px rgba(255, 255, 255, 0.6);
  animation: twinkle 4s ease-in-out infinite;
}
@keyframes twinkle {
  0%, 100% { opacity: 0.4; transform: scale(0.8); }
  50%      { opacity: 1.0; transform: scale(1.2); }
}

/* ===== 卡片：双栏 hero ===== */
.login-card {
  position: relative;
  z-index: 2;
  width: 880px;
  max-width: calc(100vw - 32px);
  min-height: 560px;
  display: grid;
  grid-template-columns: 340px 1fr;
  overflow: hidden;
  box-shadow:
    0 40px 100px rgba(0, 0, 0, 0.65),
    0 0 80px rgba(var(--mg-primary-rgb), 0.42),
    0 0 0 1px rgba(var(--mg-accent-rgb), 0.30) inset,
    0 1px 0 rgba(255, 255, 255, 0.40) inset !important;
}
/* 顶部霓虹高光线 */
.login-card::before {
  content: '';
  position: absolute;
  top: 0; left: 12%; right: 12%;
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(var(--mg-accent-rgb), 0.6) 30%,
    rgba(255, 255, 255, 0.95) 50%,
    rgba(var(--mg-accent-rgb), 0.6) 70%,
    transparent 100%);
  pointer-events: none;
  z-index: 3;
}

/* ===== 左侧 hero ===== */
.hero {
  position: relative;
  padding: 40px 32px;
  color: #fff;
  background:
    linear-gradient(180deg, rgba(var(--mg-primary-hover-rgb), 0.42) 0%, rgba(var(--mg-bg-aside-rgb), 0.35) 100%);
  border-right: 1px solid rgba(255, 255, 255, 0.12);
  display: flex;
  flex-direction: column;
}
.hero::before {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at 80% 20%, rgba(var(--mg-accent-rgb), 0.35), transparent 60%);
  pointer-events: none;
}
.hero-brand { display: flex; align-items: center; gap: 14px; }
.hero-mark {
  width: 56px; height: 56px; border-radius: 14px;
  background: linear-gradient(135deg, var(--mg-accent) 0%, var(--mg-primary-hover) 50%, var(--mg-primary-active) 100%);
  display: flex; align-items: center; justify-content: center;
  font-size: 28px; font-weight: 700; color: #fff;
  box-shadow:
    0 14px 32px rgba(var(--mg-primary-rgb), 0.65),
    0 0 36px rgba(var(--mg-primary-hover-rgb), 0.55),
    0 0 0 1px rgba(255, 255, 255, 0.30) inset;
  letter-spacing: 1px;
  animation: mg-pulse-glow 3.6s ease-in-out infinite;
}
.hero-name {
  font-size: 34px; font-weight: 700;
  letter-spacing: 4px;
  background: linear-gradient(90deg, #ffffff 0%, var(--mg-accent) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: 0 0 24px rgba(var(--mg-accent-rgb), 0.45);
}
.hero-tagline {
  margin-top: 32px;
  font-size: 18px;
  font-weight: 500;
  letter-spacing: 8px;
  color: rgba(255, 255, 255, 0.94);
}
.hero-tagline-en {
  margin-top: 4px;
  font-size: 11px;
  letter-spacing: 3px;
  color: rgba(232, 215, 245, 0.6);
  text-transform: uppercase;
}
.hero-divider {
  margin: 22px 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
}
.hero-points {
  list-style: none;
  padding: 0; margin: 0;
  font-size: 12.5px;
  color: rgba(236, 225, 245, 0.85);
  line-height: 1.9;
  flex: 1;
}
.hero-points li { display: flex; align-items: center; gap: 8px; }
.hero-points .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--mg-accent);
  box-shadow: 0 0 10px rgba(var(--mg-accent-rgb), 0.85);
  flex-shrink: 0;
}
.hero-footnote {
  margin-top: auto;
  display: flex; align-items: center; gap: 10px;
  font-size: 11px;
  color: rgba(232, 215, 245, 0.55);
  letter-spacing: 1px;
}
.hero-footnote .badge {
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.16);
  border: 1px solid rgba(255, 255, 255, 0.22);
  color: #fff;
  font-weight: 600;
}

/* ===== 右侧表单 ===== */
.panel {
  padding: 44px 44px 32px;
  display: flex;
  flex-direction: column;
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.02));
}
.panel-head { margin-bottom: 28px; }
.panel-title {
  font-size: 30px; font-weight: 700;
  letter-spacing: 12px;
  background: linear-gradient(135deg, #ffffff 0%, var(--mg-accent) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: 0 0 22px rgba(var(--mg-primary-hover-rgb), 0.6);
}
.panel-sub {
  margin-top: 6px;
  font-size: 12.5px;
  color: rgba(232, 215, 245, 0.65);
  letter-spacing: 1px;
}

.glass-form { flex: 1; display: flex; flex-direction: column; }
.glass-form :deep(.el-form-item) { margin-bottom: 18px; }

/* 输入框 透明玻璃 */
.glass-form :deep(.el-input__wrapper) {
  background: rgba(255, 255, 255, 0.08) !important;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.18) inset !important;
  border-radius: 10px !important;
  transition: all .25s;
}
.glass-form :deep(.el-input__wrapper:hover) {
  background: rgba(255, 255, 255, 0.13) !important;
  box-shadow: 0 0 0 1px rgba(var(--mg-accent-rgb), 0.55) inset !important;
}
.glass-form :deep(.el-input__wrapper.is-focus) {
  background: rgba(255, 255, 255, 0.15) !important;
  box-shadow:
    0 0 0 1px rgba(var(--mg-accent-rgb), 0.85) inset,
    0 0 20px rgba(var(--mg-primary-hover-rgb), 0.55) !important;
}
.glass-form :deep(.el-input__inner) {
  color: #fff !important;
  -webkit-text-fill-color: #fff !important;
  font-size: 14px;
  height: 42px;
}
.glass-form :deep(.el-input__inner::placeholder) { color: rgba(255, 255, 255, 0.45); }
.glass-form :deep(.el-input__prefix-inner > :first-child),
.glass-form :deep(.el-input__suffix-inner) { color: rgba(255, 255, 255, 0.6); }

/* scope 双卡 */
.scope-item :deep(.el-form-item__content) { width: 100%; }
.scope-wrap { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; width: 100%; }

/* 启动模式（会话 N+1）：与 scope 双卡共用 .scope-tab 样式，仅在外层做一些标题/留白调整 */
.launch-mode-item :deep(.el-form-item__content) { display: flex; flex-direction: column; align-items: stretch; }
.launch-mode-head {
  display: flex; align-items: center; gap: 6px;
  margin-bottom: 8px;
  font-size: 12px;
  color: rgba(232, 215, 245, 0.72);
  letter-spacing: 1px;
}
.launch-mode-title { font-weight: 500; }
.launch-mode-help {
  color: rgba(232, 215, 245, 0.55);
  cursor: help;
  font-size: 14px;
}
.launch-mode-help:hover { color: var(--mg-accent); }
.launch-wrap { /* 与 scope 一致，留位置给 hover 阴影 */ margin-bottom: 4px; }
.launch-tip { max-width: 280px; line-height: 1.6; font-size: 12px; }
.launch-tip > div + div { margin-top: 6px; }
.scope-tab {
  appearance: none;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 12px;
  padding: 14px 14px;
  display: flex; align-items: center; gap: 12px;
  color: rgba(255, 255, 255, 0.78);
  cursor: pointer;
  transition: all .2s;
  text-align: left;
}
.scope-tab:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  transform: translateY(-1px);
}
.scope-tab.active {
  background: linear-gradient(135deg,
    rgba(var(--mg-primary-rgb), 0.62) 0%,
    rgba(var(--mg-primary-hover-rgb), 0.42) 100%);
  border-color: rgba(var(--mg-accent-rgb), 0.85);
  color: #fff;
  box-shadow:
    0 0 24px rgba(var(--mg-primary-hover-rgb), 0.55),
    0 0 0 1px rgba(var(--mg-accent-rgb), 0.55) inset;
}
.scope-tab .el-icon { font-size: 20px; }
.scope-meta { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.scope-name { font-size: 14px; font-weight: 600; }
.scope-desc { font-size: 11px; opacity: 0.75; margin-top: 2px; }

/* 行 - 记住选择 & 高级 */
.row { display: flex; align-items: center; }
.row-between { justify-content: space-between; margin: -6px 0 10px; }
.remember :deep(.el-checkbox__label) {
  color: rgba(255, 255, 255, 0.92) !important;
  font-size: 12.5px;
  text-shadow: 0 1px 2px rgba(22, 4, 31, 0.4);
}
.remember :deep(.el-checkbox__inner) {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.35);
}
.remember :deep(.el-checkbox.is-checked .el-checkbox__inner) {
  background: var(--mg-primary);
  border-color: var(--mg-primary);
}
.adv-link { color: rgba(232, 215, 245, 0.82) !important; font-size: 12.5px; }
.adv-link:hover { color: #fff !important; }

/* 高级折叠 */
.adv-collapse { background: transparent !important; border: none !important; margin-bottom: 16px; }
.adv-collapse :deep(.el-collapse-item__wrap),
.adv-collapse :deep(.el-collapse-item__header) {
  background: transparent !important;
  border-color: rgba(255, 255, 255, 0.15) !important;
  color: rgba(232, 215, 245, 0.82) !important;
}
.adv-title { font-size: 12px; letter-spacing: 1px; }
.adv-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; padding-top: 6px; }
.adv-grid :deep(.el-form-item__label) {
  color: rgba(232, 215, 245, 0.7);
  font-size: 12px;
}
.adv-grid :deep(.el-input-number) { width: 100%; }
.adv-grid :deep(.el-input-number .el-input__inner) { text-align: left; }

/* 登录按钮：紫色霓虹 · 扫光动效 */
.btn-login {
  position: relative;
  overflow: hidden;
  height: 46px !important;
  border-radius: 10px;
  margin-top: 6px;
  font-size: 15px;
  letter-spacing: 6px;
  font-weight: 600;
  background: linear-gradient(135deg, var(--mg-primary) 0%, var(--mg-primary-hover) 100%) !important;
  border: none !important;
  box-shadow:
    0 12px 28px rgba(var(--mg-primary-rgb), 0.55),
    0 0 28px rgba(var(--mg-primary-hover-rgb), 0.40),
    0 0 0 1px rgba(255, 255, 255, 0.22) inset !important;
  transition: all .28s cubic-bezier(.25, .8, .25, 1);
}
.btn-login::after {
  content: '';
  position: absolute;
  top: 0; left: -120%;
  width: 80%; height: 100%;
  background: linear-gradient(110deg,
    transparent 0%,
    rgba(255, 255, 255, 0.0) 30%,
    rgba(255, 255, 255, 0.40) 50%,
    rgba(255, 255, 255, 0.0) 70%,
    transparent 100%);
  transition: left .6s cubic-bezier(.25, .8, .25, 1);
  pointer-events: none;
}
.btn-login:hover {
  transform: translateY(-2px);
  background: linear-gradient(135deg, var(--mg-primary-hover) 0%, var(--mg-primary-light-3) 100%) !important;
  box-shadow:
    0 18px 38px rgba(var(--mg-primary-rgb), 0.65),
    0 0 42px rgba(var(--mg-primary-hover-rgb), 0.65),
    0 0 0 1px rgba(var(--mg-accent-rgb), 0.55) inset !important;
}
.btn-login:hover::after { left: 120%; }

.bottom-note {
  margin-top: 16px;
  font-size: 11.5px;
  color: rgba(232, 215, 245, 0.55);
  text-align: center;
  line-height: 1.6;
}

/* 底部水印 */
.footer-stamp {
  position: absolute;
  bottom: 18px; left: 50%;
  transform: translateX(-50%);
  font-size: 11px;
  letter-spacing: 1.5px;
  color: rgba(232, 215, 245, 0.4);
  z-index: 2;
}

/* 错误提示 */
.glass-form :deep(.el-form-item__error) {
  color: #ff9bb8;
  padding-top: 4px;
}

/* 小屏自适应 */
@media (max-width: 720px) {
  .login-card { grid-template-columns: 1fr; min-height: auto; }
  .hero { border-right: none; border-bottom: 1px solid rgba(255, 255, 255, 0.12); padding: 28px; }
  .panel { padding: 28px; }
  .hero-points, .hero-divider { display: none; }
}
</style>
