<script setup lang="ts">
import { computed, reactive } from 'vue';
import type { CSSProperties, Component } from 'vue';
import { loginModuleRecord } from '@/constants/app';
import { useThemeStore } from '@/store/modules/theme';
import { $t } from '@/locales';
import PwdLogin from './modules/pwd-login.vue';
import ResetPwd from './modules/reset-pwd.vue';

defineOptions({ name: 'LoginPage' });

interface Props {
  /** The login module */
  module?: UnionKey.LoginModule;
}

const props = defineProps<Props>();

const themeStore = useThemeStore();

interface LoginModule {
  label: App.I18n.I18nKey;
  component: Component;
}

const moduleMap: Record<UnionKey.LoginModule, LoginModule> = {
  'pwd-login': { label: loginModuleRecord['pwd-login'], component: PwdLogin },
  'reset-pwd': { label: loginModuleRecord['reset-pwd'], component: ResetPwd }
};

const activeModule = computed(() => moduleMap[props.module || 'pwd-login']);

const currentYear = new Date().getFullYear();

/** 登录页品牌色：取自公司 logo 的湛蓝，不跟随系统主题色（主题色偏紫，与企业蓝不符） */
const LOGIN_BRAND = '#1e80df';

/** 鼠标视差：归一化指针位置，不同景深的层按系数反向位移 */
const pointer = reactive({ x: 0, y: 0 });

function onPointerMove(event: MouseEvent) {
  pointer.x = (event.clientX / window.innerWidth - 0.5) * 2;
  pointer.y = (event.clientY / window.innerHeight - 0.5) * 2;
}

function layerStyle(depth: number) {
  return {
    transform: `translate3d(${(-pointer.x * depth).toFixed(1)}px, ${(-pointer.y * depth).toFixed(1)}px, 0)`
  };
}

/** 协作分支：角色 → 颜色 → 汇入主干的路径（git 分支汇流的意象），曲线两端均水平相切，过渡柔和 */
const branches = [
  {
    key: 'demand',
    label: '需求',
    color: '#f59e0b',
    y0: 195,
    mergeX: 660,
    path: 'M -80,195 C 320,195 440,470 660,470',
    dur: '7.5s',
    begin: '0s'
  },
  {
    key: 'design',
    label: '设计',
    color: '#ec4899',
    y0: 330,
    mergeX: 780,
    path: 'M -80,330 C 360,330 540,470 780,470',
    dur: '6.5s',
    begin: '1.2s'
  },
  {
    key: 'dev',
    label: '开发',
    color: '#0ea5e9',
    y0: 615,
    mergeX: 880,
    path: 'M -80,615 C 380,615 560,470 880,470',
    dur: '7s',
    begin: '2.1s'
  },
  {
    key: 'test',
    label: '测试',
    color: '#22c55e',
    y0: 745,
    mergeX: 970,
    path: 'M -80,745 C 420,745 620,470 970,470',
    dur: '8s',
    begin: '0.6s'
  }
];

/** 分支汇入主干的节点位置 */
const mergePoints = [
  { x: 660, color: '#f59e0b' },
  { x: 780, color: '#ec4899' },
  { x: 880, color: '#0ea5e9' },
  { x: 970, color: '#22c55e' }
];

/** 角色徽章在场景中的落位（跟随分支起始段） */
const roleChips: { label: string; color: string; style: CSSProperties }[] = [
  { label: '需求', color: '#f59e0b', style: { left: '5%', top: '20%', '--float-d': '0s' } },
  { label: '设计', color: '#ec4899', style: { left: '11%', top: '35%', '--float-d': '0.8s' } },
  { label: '开发', color: '#0ea5e9', style: { left: '8%', top: '66%', '--float-d': '1.6s' } },
  { label: '测试', color: '#22c55e', style: { left: '13%', top: '80%', '--float-d': '2.4s' } }
];

/**
 * 电能质量波形（公司主营：电能质量监测）
 *
 * 主干汇流完成后，尾段"输出"为基波 + 谐波叠加的正弦波组，寓意协作成果守护电能质量。
 * 用二次贝塞尔 Q/T 拼接出周期波形，CSS 平移一个整周期实现无缝流动。
 */
interface WaveShape {
  /** 波形中线 y */
  mid: number;
  /** 振幅 */
  amp: number;
  /** 半周期（x 方向） */
  half: number;
}

function buildWavePath(shape: WaveShape, from: number, to: number) {
  const { mid, amp, half } = shape;
  let d = `M ${from} ${mid} Q ${from + half / 2} ${mid - amp} ${from + half} ${mid}`;
  for (let x = from + 2 * half; x <= to; x += half) {
    d += ` T ${x} ${mid}`;
  }
  return d;
}

const waves = [
  // 基波：主题色，振幅最大
  { key: 'fundamental', mid: 470, amp: 26, half: 110, color: 'var(--brand)', width: 2, opacity: 0.5, dur: '7s' },
  // 高次谐波：短周期小振幅
  { key: 'harmonic', mid: 470, amp: 10, half: 55, color: '#0ea5e9', width: 1.5, opacity: 0.45, dur: '4.5s' },
  // 低频包络：慢速衬底
  { key: 'flux', mid: 474, amp: 40, half: 220, color: '#60a5fa', width: 2, opacity: 0.22, dur: '14s' }
].map(wave => ({
  ...wave,
  path: buildWavePath(wave, 900 - wave.half * 2, 2000 + wave.half * 2),
  shift: `${-2 * wave.half}px`
}));

/** 电力场景剪影：输电铁塔（底部接地，局部坐标基点为塔脚中心） */
const towers = [
  { x: 150, s: 1.42 },
  { x: 540, s: 1.2 },
  { x: 1280, s: 1.0 }
];

/** 塔间悬垂导线（悬链线意象），坐标对应各塔最宽横担端点（随铁塔 scale 同步重算） */
const powerLines = [
  { path: 'M -60,712 Q 4,756 68,700' },
  { path: 'M 232,700 Q 350,777 470,726' },
  { path: 'M 610,726 Q 915,831 1222,750' },
  { path: 'M 1338,750 Q 1429,788 1520,768' }
];

/** 导线上滑过的电流光点（端点对齐 powerLines 的中间两段） */
const lineSparks = [
  { key: 'spark-1', path: 'M 232,700 Q 350,777 470,726', dur: '5s', begin: '0s' },
  { key: 'spark-2', path: 'M 610,726 Q 915,831 1222,750', dur: '7s', begin: '2s' }
];

/** 风机（新能源应用场景），dur 为叶轮旋转周期 */
const turbines = [
  { key: 'turbine-1', x: 715, s: 1.28, dur: '9s' },
  { key: 'turbine-2', x: 828, s: 0.88, dur: '13s' }
];
</script>

<template>
  <div class="login-scene" :style="{ '--brand': LOGIN_BRAND }" @mousemove="onPointerMove">
    <!-- 远景：浮尘微粒 -->
    <div class="scene-motes" :style="layerStyle(6)"></div>

    <!-- 中景：协作汇流图（需求/设计/开发/测试 → 主干 → 登录入口） -->
    <div class="scene-graph" :style="layerStyle(14)">
      <svg class="scene-graph__svg" viewBox="0 0 1440 900" preserveAspectRatio="xMidYMid slice" aria-hidden="true">
        <defs>
          <linearGradient id="trunk-grad" x1="0" y1="0" x2="1" y2="0">
            <!-- presentation attribute 不解析 CSS var，必须用 style -->
            <stop offset="0" style="stop-color: var(--brand); stop-opacity: 0" />
            <stop offset="0.45" style="stop-color: var(--brand); stop-opacity: 0.85" />
            <stop offset="1" style="stop-color: #0ea5e9; stop-opacity: 0.9" />
          </linearGradient>
          <!-- 每条分支一个渐变：起点透明、临近汇入处渐显，模拟光流自然汇聚 -->
          <linearGradient
            v-for="branch in branches"
            :id="`branch-grad-${branch.key}`"
            :key="`grad-${branch.key}`"
            gradientUnits="userSpaceOnUse"
            :x1="-80"
            :y1="branch.y0"
            :x2="branch.mergeX"
            :y2="470"
          >
            <stop offset="0" :stop-color="branch.color" stop-opacity="0" />
            <stop offset="0.45" :stop-color="branch.color" stop-opacity="0.2" />
            <stop offset="1" :stop-color="branch.color" stop-opacity="0.65" />
          </linearGradient>
          <filter id="trunk-glow" x="-30%" y="-300%" width="160%" height="700%">
            <feGaussianBlur stdDeviation="5" result="blur" />
            <feMerge>
              <feMergeNode in="blur" />
              <feMergeNode in="SourceGraphic" />
            </feMerge>
          </filter>
          <!-- 波形渐显遮罩：汇流完成后波形才"长出来"，遮罩静止、波形在其下平移 -->
          <linearGradient id="wave-fade" gradientUnits="userSpaceOnUse" x1="920" y1="0" x2="1980" y2="0">
            <stop offset="0" stop-color="#fff" stop-opacity="0" />
            <stop offset="0.3" stop-color="#fff" stop-opacity="0.9" />
            <stop offset="1" stop-color="#fff" stop-opacity="1" />
          </linearGradient>
          <mask id="wave-mask">
            <rect x="920" y="330" width="1100" height="300" fill="url(#wave-fade)" />
          </mask>
        </defs>

        <!-- 主干 -->
        <path class="trunk" d="M -60,470 L 1520,470" stroke="url(#trunk-grad)" filter="url(#trunk-glow)" />

        <!-- 四条角色分支 -->
        <path
          v-for="(branch, index) in branches"
          :key="branch.key"
          class="branch"
          :d="branch.path"
          :stroke="`url(#branch-grad-${branch.key})`"
          :style="{ '--breathe-d': `${index * 1.4}s` }"
        />

        <!-- 分支上行进的光点 -->
        <circle
          v-for="branch in branches"
          :key="`dot-${branch.key}`"
          r="3.5"
          :fill="branch.color"
          class="travel-dot"
          :style="{ color: branch.color }"
        >
          <animateMotion :dur="branch.dur" :begin="branch.begin" repeatCount="indefinite" :path="branch.path" />
        </circle>

        <!-- 主干上行进的光点 -->
        <circle r="3" fill="#5db1f5" class="travel-dot" style="color: #5db1f5">
          <animateMotion dur="4.5s" begin="0.5s" repeatCount="indefinite" path="M 660,470 L 1520,470" />
        </circle>
        <circle r="2.5" fill="#5db1f5" class="travel-dot" style="color: #5db1f5">
          <animateMotion dur="5.5s" begin="2.6s" repeatCount="indefinite" path="M 660,470 L 1520,470" />
        </circle>

        <!-- 电能质量波形：基波 + 谐波 + 低频包络，沿主干尾段流出 -->
        <g mask="url(#wave-mask)">
          <path
            v-for="wave in waves"
            :key="wave.key"
            class="wave"
            :d="wave.path"
            :stroke-width="wave.width"
            :style="{
              stroke: wave.color,
              opacity: wave.opacity,
              '--wave-shift': wave.shift,
              '--wave-dur': wave.dur
            }"
          />
        </g>

        <!-- 电力场景剪影：输电铁塔 + 悬垂导线 + 风机 -->
        <g class="industry">
          <!-- 输电铁塔 -->
          <g
            v-for="tower in towers"
            :key="`tower-${tower.x}`"
            :transform="`translate(${tower.x}, 870) scale(${tower.s})`"
          >
            <path d="M -32 0 L -10 -150 L 0 -178 L 10 -150 L 32 0" />
            <path
              d="M -28 -25 L 28 -45 M 28 -25 L -28 -45 M -24 -70 L 24 -88 M 24 -70 L -24 -88 M -19 -112 L 19 -126 M 19 -112 L -19 -126"
            />
            <path d="M -58 -120 L 58 -120 M -46 -150 L 46 -150" />
            <path d="M -58 -120 L -58 -110 M 58 -120 L 58 -110 M -46 -150 L -46 -140 M 46 -150 L 46 -140" />
          </g>

          <!-- 塔间导线 -->
          <path v-for="line in powerLines" :key="line.path" :d="line.path" />

          <!-- 风机 -->
          <g
            v-for="turbine in turbines"
            :key="turbine.key"
            :transform="`translate(${turbine.x}, 870) scale(${turbine.s})`"
          >
            <path d="M -3 0 L 0 -120 M 3 0 L 0 -120" />
            <g transform="translate(0, -120)">
              <g>
                <path d="M 0 0 L 0 -52" />
                <path d="M 0 0 L 0 -52" transform="rotate(120)" />
                <path d="M 0 0 L 0 -52" transform="rotate(240)" />
                <animateTransform
                  attributeName="transform"
                  type="rotate"
                  from="0 0 0"
                  to="360 0 0"
                  :dur="turbine.dur"
                  repeatCount="indefinite"
                />
              </g>
            </g>
            <circle cx="0" cy="-120" r="3" class="industry__hub" />
          </g>
        </g>

        <!-- 导线上的电流光点 -->
        <circle v-for="spark in lineSparks" :key="spark.key" r="2.5" class="travel-dot industry__spark">
          <animateMotion :dur="spark.dur" :begin="spark.begin" repeatCount="indefinite" :path="spark.path" />
        </circle>

        <!-- 汇入节点：脉冲 -->
        <g v-for="point in mergePoints" :key="`merge-${point.x}`">
          <circle :cx="point.x" cy="470" r="5" :fill="point.color" />
          <circle :cx="point.x" cy="470" r="5" :stroke="point.color" class="merge-pulse" />
        </g>
      </svg>

      <!-- 角色徽章 -->
      <span v-for="chip in roleChips" :key="chip.label" class="role-chip" :style="chip.style">
        <i class="role-chip__dot" :style="{ backgroundColor: chip.color }"></i>
        {{ chip.label }}
      </span>
    </div>

    <!-- 顶部：品牌 -->
    <header class="scene-header reveal" style="--d: 0s">
      <SystemLogo class="text-36px" />
      <span class="scene-header__name">{{ $t('system.title') }}</span>
    </header>

    <!-- 主文案 -->
    <div class="scene-hero" :style="layerStyle(10)">
      <p class="scene-hero__eyebrow reveal" style="--d: 0.15s">BUILD TOGETHER · GUARD POWER QUALITY</p>
      <h1 class="scene-hero__slogan reveal" style="--d: 0.25s">
        独行快
        <span class="scene-hero__comma">，</span>
        <br />
        众行
        <em>远</em>
      </h1>
      <p class="scene-hero__sub reveal" style="--d: 0.4s">每一次提交，都让电能质量的守护更进一步</p>
    </div>

    <!-- 登录卡片 -->
    <div class="login-card">
      <header class="login-card__header reveal" style="--d: 0.3s">
        <SystemLogo class="login-card__logo text-52px" />
        <h2 class="login-card__title">{{ $t('system.title') }}</h2>
        <p class="login-card__subtitle">欢迎回来，开始今天的协作</p>
      </header>
      <main class="reveal" style="--d: 0.45s">
        <Transition :name="themeStore.page.animateMode" mode="out-in" appear>
          <component :is="activeModule.component" />
        </Transition>
      </main>
    </div>

    <footer class="scene-footer reveal" style="--d: 0.6s">
      © {{ currentYear }} 南京灿能电力自动化股份有限公司 · {{ $t('system.title') }}
    </footer>
  </div>
</template>

<style scoped lang="scss">
.login-scene {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  width: 100%;
  height: 100%;
  padding-right: 9vw;
  overflow: hidden;
  background:
    radial-gradient(90% 70% at 80% 42%, color-mix(in srgb, var(--brand) 10%, transparent) 0%, transparent 60%),
    radial-gradient(80% 60% at 6% 92%, rgb(56 189 248 / 10%) 0%, transparent 60%),
    radial-gradient(70% 50% at 18% 8%, rgb(14 165 233 / 6%) 0%, transparent 55%),
    linear-gradient(160deg, #f5f9ff 0%, #ecf2fb 50%, #fafcff 100%);

  @media (max-width: 1023px) {
    justify-content: center;
    padding-right: 0;
  }
}

/* ---------- 远景浮尘微粒 ---------- */
.scene-motes {
  position: absolute;
  inset: -40px;
  background-image:
    radial-gradient(2px 2px at 12% 22%, rgb(30 128 223 / 30%) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 28% 68%, rgb(23 44 84 / 16%) 50%, transparent 51%),
    radial-gradient(2.5px 2.5px at 44% 12%, rgb(30 128 223 / 22%) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 58% 44%, rgb(23 44 84 / 12%) 50%, transparent 51%),
    radial-gradient(2px 2px at 72% 78%, rgb(56 189 248 / 25%) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 86% 28%, rgb(23 44 84 / 14%) 50%, transparent 51%),
    radial-gradient(2px 2px at 94% 62%, rgb(30 128 223 / 20%) 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 6% 86%, rgb(56 189 248 / 18%) 50%, transparent 51%);
  background-size: 520px 520px;
  background-repeat: repeat;
  animation: motes-breathe 6s ease-in-out infinite alternate;
  transition: transform 0.25s ease-out;
  pointer-events: none;
}

@keyframes motes-breathe {
  from {
    opacity: 0.5;
  }

  to {
    opacity: 1;
  }
}

/* ---------- 协作汇流图 ---------- */
.scene-graph {
  position: absolute;
  inset: 0;
  transition: transform 0.25s ease-out;
  pointer-events: none;
}

.scene-graph__svg {
  width: 100%;
  height: 100%;
}

.trunk {
  fill: none;
  stroke-width: 2.5;
  stroke-linecap: round;
}

.branch {
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  animation: branch-breathe 6s ease-in-out infinite alternate;
  animation-delay: var(--breathe-d, 0s);
}

@keyframes branch-breathe {
  from {
    opacity: 0.55;
  }

  to {
    opacity: 1;
  }
}

.travel-dot {
  filter: drop-shadow(0 0 6px currentColor);
}

.wave {
  fill: none;
  stroke-linecap: round;
  animation: wave-drift var(--wave-dur) linear infinite;
}

@keyframes wave-drift {
  to {
    transform: translateX(var(--wave-shift));
  }
}

/* 电力场景剪影 */
.industry {
  fill: none;
  stroke: #424a8c;
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: 0.22;
}

.industry__hub {
  fill: #424a8c;
  stroke: none;
}

.industry__spark {
  fill: var(--brand);
  color: var(--brand);
  opacity: 0.65;
}

.merge-pulse {
  fill: none;
  stroke-width: 1.5;
  transform-box: fill-box;
  transform-origin: center;
  animation: merge-pulse 2.6s ease-out infinite;
}

@keyframes merge-pulse {
  0% {
    opacity: 0.8;
    transform: scale(1);
  }

  70%,
  100% {
    opacity: 0;
    transform: scale(3.2);
  }
}

/* 角色徽章 */
.role-chip {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 16px;
  border: 1px solid rgb(30 35 80 / 10%);
  border-radius: 999px;
  font-size: 13px;
  letter-spacing: 0.14em;
  color: rgb(30 35 80 / 72%);
  background: rgb(255 255 255 / 65%);
  box-shadow: 0 6px 18px -8px rgb(23 92 171 / 22%);
  backdrop-filter: blur(8px);
  animation: chip-float 5.5s ease-in-out infinite alternate;
  animation-delay: var(--float-d, 0s);
}

.role-chip__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  box-shadow: 0 0 8px 1px currentcolor;
}

@keyframes chip-float {
  from {
    transform: translateY(-6px);
  }

  to {
    transform: translateY(8px);
  }
}

/* ---------- 品牌与文案 ---------- */
.scene-header {
  position: absolute;
  top: 40px;
  left: 56px;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 12px;
  color: #232850;
}

.scene-header__name {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.08em;
}

.scene-hero {
  position: absolute;
  top: 24%;
  left: 6.5%;
  z-index: 2;
  color: #1b2050;
  transition: transform 0.25s ease-out;
  pointer-events: none;

  @media (max-width: 1023px) {
    display: none;
  }
}

.scene-hero__eyebrow {
  margin-bottom: 26px;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 13px;
  letter-spacing: 0.46em;
  color: rgb(30 35 80 / 45%);
}

.scene-hero__slogan {
  font-size: 64px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0.14em;
  text-shadow: 0 8px 32px rgb(255 255 255 / 70%);

  em {
    font-style: normal;
    background: linear-gradient(120deg, var(--brand) 0%, #0b66c3 55%, #38bdf8 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}

.scene-hero__comma {
  color: rgb(30 35 80 / 28%);
}

.scene-hero__sub {
  margin-top: 26px;
  font-size: 16px;
  letter-spacing: 0.22em;
  color: rgb(30 35 80 / 52%);
}

.scene-footer {
  position: absolute;
  bottom: 26px;
  left: 56px;
  z-index: 2;
  font-size: 12px;
  letter-spacing: 0.1em;
  color: rgb(30 35 80 / 32%);
}

/* ---------- 登录卡片（白玻璃质感） ---------- */
.login-card {
  position: relative;
  z-index: 3;
  width: 420px;
  padding: 44px 40px 40px;
  border: 1px solid rgb(255 255 255 / 75%);
  border-radius: 20px;
  background: linear-gradient(168deg, rgb(255 255 255 / 82%) 0%, rgb(248 250 255 / 88%) 100%);
  backdrop-filter: blur(20px) saturate(140%);
  box-shadow:
    0 30px 70px -24px rgb(23 92 171 / 26%),
    0 0 0 1px rgb(30 35 80 / 5%),
    0 1px 0 rgb(255 255 255 / 90%) inset;
}

.login-card__header {
  margin-bottom: 32px;
  text-align: center;
}

.login-card__logo {
  display: block;
  margin: 0 auto 16px;
  filter: drop-shadow(0 10px 26px color-mix(in srgb, var(--brand) 35%, transparent));
}

.login-card__title {
  font-size: 24px;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: #20254d;
}

.login-card__subtitle {
  margin-top: 10px;
  font-size: 13.5px;
  letter-spacing: 0.06em;
  color: rgb(30 35 80 / 48%);
}

/* 卡片内表单：浅色质感统一覆盖（作用于子模块） */
.login-card :deep(.el-input__wrapper) {
  height: 48px;
  padding: 0 14px;
  border-radius: 10px;
  background-color: rgb(30 128 223 / 5%);
  box-shadow: 0 0 0 1px rgb(30 35 80 / 12%) inset;
  transition:
    box-shadow 0.2s ease,
    background-color 0.2s ease;

  &:hover {
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--brand) 55%, rgb(30 35 80 / 20%)) inset;
  }

  &.is-focus {
    background-color: #fff;
    box-shadow:
      0 0 0 1.5px var(--brand) inset,
      0 0 0 4px color-mix(in srgb, var(--brand) 14%, transparent);
  }

  .el-input__inner {
    color: #1f244a;
    caret-color: var(--brand);

    &::placeholder {
      color: rgb(30 35 80 / 34%);
    }
  }

  .el-input__prefix,
  .el-input__suffix {
    font-size: 18px;
    color: rgb(30 35 80 / 35%);
  }

  .el-input__prefix {
    margin-right: 6px;
  }
}

.login-card :deep(.el-form-item) {
  margin-bottom: 22px;
}

.login-card :deep(.el-checkbox__label) {
  letter-spacing: 0.04em;
  color: rgb(30 35 80 / 58%);
}

/* 选中态跟随登录页品牌蓝，而非系统主题色 */
.login-card :deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
  border-color: var(--brand);
  background-color: var(--brand);
}

.login-card :deep(.el-checkbox__input.is-checked + .el-checkbox__label) {
  color: var(--brand);
}

.login-card :deep(.login-submit-button) {
  position: relative;
  width: 100%;
  height: 48px;
  margin-top: 4px;
  border: none;
  border-radius: 10px;
  overflow: hidden;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.32em;
  text-indent: 0.32em;
  background: linear-gradient(135deg, var(--brand) 0%, color-mix(in srgb, var(--brand) 68%, #0a3f8f) 100%);
  box-shadow: 0 12px 26px -10px color-mix(in srgb, var(--brand) 60%, transparent);
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease,
    filter 0.2s ease;

  /* 流光扫过 */
  &::after {
    content: '';
    position: absolute;
    top: 0;
    left: -60%;
    width: 40%;
    height: 100%;
    background: linear-gradient(100deg, transparent 0%, rgb(255 255 255 / 35%) 50%, transparent 100%);
    transform: skewX(-20deg);
    transition: left 0.55s ease;
  }

  &:hover {
    transform: translateY(-1px);
    filter: brightness(1.06);
    box-shadow: 0 16px 32px -10px color-mix(in srgb, var(--brand) 70%, transparent);

    &::after {
      left: 130%;
    }
  }

  &:active {
    transform: translateY(0);
  }
}

.login-card :deep(.login-back-button) {
  width: 100%;
  height: 44px;
  margin-top: 14px;
  margin-left: 0;
  border: 1px solid rgb(30 35 80 / 15%);
  border-radius: 10px;
  color: rgb(30 35 80 / 70%);
  background: transparent;

  &:hover {
    border-color: color-mix(in srgb, var(--brand) 60%, transparent);
    color: var(--brand);
    background: color-mix(in srgb, var(--brand) 6%, transparent);
  }
}

/* ---------- 入场动效 ---------- */
.reveal {
  animation: reveal-up 0.7s cubic-bezier(0.22, 0.61, 0.36, 1) both;
  animation-delay: var(--d, 0s);
}

@keyframes reveal-up {
  from {
    opacity: 0;
    transform: translateY(18px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>
