<template>
  <div class="login-wrapper">
    <!-- 左右分栏双面板容器 -->
    <div class="login-split-container">
      
      <!-- 左侧：明亮科技感极光大面板 -->
      <div class="login-left-brand">
        <!-- 方案D：化学分子科技网格插图 -->
        <div class="brand-bg-pattern"></div>
        
        <div class="brand-content-wrapper">
          <!-- 顶部系统微标 -->
          <div class="brand-mini-logo">
            <div class="mini-logo-icon">
              <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
                <path d="M12 2L2 7l10 5 10-5-10-5z"/>
                <path d="M2 17l10 5 10-5"/>
                <path d="M2 12l10 5 10-5"/>
              </svg>
            </div>
            <span class="mini-logo-text">华邦制药 · CTMS</span>
          </div>

          <!-- 中部标语区 -->
          <div class="brand-slogan-block">
            <h1 class="brand-main-title">
              <span class="system-name">临床试验管理系统</span>
            </h1>
            <p class="brand-sub-desc">
              全流程覆盖临床试验立项、执行、监查与归档，以规范化管理保障数据质量，助力研究团队高效推进项目合规落地。
            </p>
          </div>

          <!-- 特征卡片网格 -->
          <div class="brand-features-grid">
            <div class="feature-card delay-1">
              <div class="feature-icon-wrapper">
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
                  <path d="M12 20h9M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/>
                </svg>
              </div>
              <div class="feature-info">
                <h3 class="feature-title">项目全流程管理</h3>
                <p class="feature-desc">覆盖立项审批、方案配置、人员分工到进度追踪，多中心协同操作，信息集中透明可查。</p>
              </div>
            </div>
            
            <div class="feature-card delay-2">
              <div class="feature-icon-wrapper">
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
                  <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
                </svg>
              </div>
              <div class="feature-info">
                <h3 class="feature-title">合规核查与数据溯源</h3>
                <p class="feature-desc">深度契合 GCP 与 NMPA 规范，记录完整操作轨迹与数据变更历史，确保每一条记录真实可追溯。</p>
              </div>
            </div>
            
            <div class="feature-card delay-3">
              <div class="feature-icon-wrapper">
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
                  <path d="M3 3v18h18M18.7 8l-5.1 5.2-2.8-2.7L7 14.3"/>
                </svg>
              </div>
              <div class="feature-info">
                <h3 class="feature-title">偏差与安全事件管理</h3>
                <p class="feature-desc">结构化记录研究偏差与不良事件，支持分级处理与闭环追踪，保障受试者安全与项目数据完整性。</p>
              </div>
            </div>
          </div>

          <!-- 左侧底部声明 -->
          <div class="brand-legal-info">
            <p class="legal-item">Compliance with GCP & NMPA Regulations</p>
          </div>
        </div>
      </div>

      <!-- 右侧：极简登录面板 -->
      <div class="login-right-form">
        <!-- 兼容提示已去除 -->

        <div class="login-card-container">
          <!-- 顶部 Logo 组合 -->
          <div class="login-brand-header">
            <div class="brand-logo-icon">
              <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
                <path d="M12 2L2 7l10 5 10-5-10-5z"/>
                <path d="M2 17l10 5 10-5"/>
                <path d="M2 12l10 5 10-5"/>
              </svg>
            </div>
            <div class="brand-divider"></div>
            <span class="brand-system-text">CTMS</span>
          </div>

          <!-- 当前登录方式 -->
          <div class="login-tabs">
            <span class="tab-item active">账号登录</span>
          </div>

          <div v-if="showDesktopServerSettings" class="desktop-server-status">
            <span class="desktop-server-label">服务器</span>
            <code>{{ desktopServerUrl || "未配置" }}</code>
            <RouterLink to="/desktop/server-settings" class="desktop-server-action">设置</RouterLink>
          </div>

          <!-- 退出通知 -->
          <div v-if="logoutNotice" class="logout-notice" :class="'logout-notice--' + logoutNotice.type">
            <div class="ln-icon">
              <svg v-if="logoutNotice.type === 'warning'" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <circle cx="12" cy="12" r="10"/><path d="M12 7v6"/><path d="M12 17h.01"/>
              </svg>
              <svg v-else viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                <path d="M20 6 9 17l-5-5"/>
              </svg>
            </div>
            <div class="ln-body">
              <strong>{{ logoutNotice.title }}</strong>
              <span>{{ logoutNotice.message }}</span>
            </div>
          </div>

          <!-- 登录错误横幅 -->
          <transition name="error-slide">
            <div v-if="loginError" class="login-error-banner">
              <div class="leb-icon">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                  <circle cx="12" cy="12" r="10"/><path d="M12 8v4"/><path d="M12 16h.01"/>
                </svg>
              </div>
              <div class="leb-body">
                <strong>{{ loginError.title }}</strong>
                <span v-if="loginError.message">{{ loginError.message }}</span>
              </div>
              <button class="leb-close" @click="loginError = null" aria-label="关闭">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
                  <path d="M18 6 6 18M6 6l12 12"/>
                </svg>
              </button>
            </div>
          </transition>

          <!-- 登录表单 -->
          <el-form ref="formRef" :model="form" :rules="rules" @keyup.enter="onSubmit" label-position="top" class="login-form">
            <el-form-item label="账号" prop="email">
              <div class="email-unified-box">
                <input
                  id="email"
                  v-model="form.emailLocal"
                  type="text"
                  placeholder="请输入账号"
                  name="username"
                  autocomplete="username"
                  class="email-local-field"
                  @paste="handleAccountPaste"
                />
                <span class="email-at-sign">@</span>
                <div class="email-domain-wrapper">
                  <select
                    v-model="form.emailDomain"
                    class="email-domain-field"
                    aria-label="邮箱域名"
                    :disabled="availableEmailDomains.length === 0"
                  >
                    <option v-for="domain in availableEmailDomains" :key="domain" :value="domain">{{ domain }}</option>
                  </select>
                  <svg class="email-domain-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="m6 9 6 6 6-6"/></svg>
                </div>
              </div>
            </el-form-item>

            <el-form-item label="密码" prop="password">
              <el-input
                id="password" v-model="form.password" type="password"
                placeholder="请输入密码" show-password size="large"
                name="ctms-login-password" autocomplete="new-password" class="login-input">
              </el-input>
            </el-form-item>

            <div class="login-options">
              <el-checkbox v-model="form.agreeProtocol" class="protocol-checkbox">
                <span class="protocol-text">
                  我已阅读并同意
                  <button type="button" class="protocol-link" @click.stop.prevent="openProtocolDialog">《用户协议》</button>
                  登录即代表同意当前协议
                </span>
              </el-checkbox>
            </div>

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

            <!-- 忘记密码与注册 -->
            <div class="forgot-register-row">
              <RouterLink to="/forgot-password" class="forgot-link">忘记密码？</RouterLink>
              <RouterLink to="/register" class="register-link">新用户注册</RouterLink>
            </div>
          </el-form>

          <!-- 右侧底部客户支持与版权 -->
          <div class="login-right-footer">
            <div class="footer-row">
              <span class="footer-label">技术开发：</span>
              <a href="mailto:zhouchengcheng@huapont.cn" class="footer-link-text">医学事务部·周成成 (zhouchengcheng@huapont.cn)</a>
            </div>
            
            <div class="footer-row copyright-line">
              <span class="lang-switch">CHINA(中国) <svg width="8" height="8" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="m6 9 6 6 6-6"/></svg></span>
              <span class="meta-sep">|</span>
              <span class="copyright-text">© {{ currentYear }} 重庆华邦制药有限公司 版权所有</span>
              <span class="meta-sep">|</span>
              <span class="privacy-link">隐私政策</span>
            </div>
            
            <div class="footer-row compliance-line">
              <span class="version-tag">v{{ appVersion }}</span>
              <span class="meta-sep">|</span>
              <span class="compliance-text">本系统依照 GCP 及 NMPA 规范管理数据</span>
            </div>
          </div>

        </div>
      </div>
      
    </div>

    <!-- 协议弹窗 -->
    <el-dialog v-model="protocolDialogVisible" title="用户协议" width="860px"
      class="protocol-dialog" append-to-body align-center>
      <div class="protocol-content">
        <section v-for="section in protocolSections" :key="section.title" class="protocol-section">
          <h3>{{ section.title }}</h3>
          <p v-for="p in section.paragraphs" :key="p">{{ p }}</p>
        </section>
      </div>
      <template #footer>
        <el-button type="primary" size="large" class="protocol-confirm-btn" @click="confirmProtocol">确 定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { computed, reactive, ref, onMounted, onUnmounted, watch } from "vue";
import { useRouter } from "vue-router";
import { ElMessage, type FormInstance, type FormRules } from "element-plus";
// 从 package.json 读取版本号，构建时由 Vite 注入
const appVersion = (import.meta.env.VITE_APP_VERSION as string) || "1.0.0";
// 动态获取当前年份，避免硬编码
const currentYear = new Date().getFullYear();
import { useAuthStore } from "../store/auth";
import { useStudyStore } from "../store/study";
import { fetchEmailDomains } from "../api/auth";
import { TEXT, requiredMessage } from "../locales";
import { DESKTOP_SERVER_URL_CHANGED_EVENT, getDesktopServerUrl, isTauriRuntime } from "../runtime";
import {
  consumeLogoutReason,
  LOGOUT_REASON_AUTH_EXPIRED,
  LOGOUT_REASON_MANUAL,
  LOGOUT_REASON_TIMEOUT,
} from "../session/sessionManager";
import { authProtocolSections } from "../content/authProtocol";

const auth = useAuthStore();
const router = useRouter();
const AGREE_PROTOCOL_KEY = "ctms_agree_protocol";

const formRef = ref<FormInstance>();
const form = reactive({ email: "", emailLocal: "", emailDomain: "", password: "", agreeProtocol: false });
const configuredEmailDomains = ref<string[]>([]);

const rules: FormRules<typeof form> = {
  email: [
    { required: true, message: requiredMessage(TEXT.modules.auth.emailLabel), trigger: "blur" },
    { type: "email", message: TEXT.common.validation.invalidEmail, trigger: "blur" },
  ],
  password: [{ required: true, message: requiredMessage(TEXT.modules.auth.passwordLabel), trigger: "blur" }],
};

const loading = ref(false);
const protocolDialogVisible = ref(false);
const logoutNotice = ref<{ type: "info" | "warning"; title: string; message: string } | null>(null);
const loginError = ref<{ title: string; message?: string } | null>(null);
const protocolSections = authProtocolSections;
const showDesktopServerSettings = isTauriRuntime();
const desktopServerUrl = ref(getDesktopServerUrl());

const refreshDesktopServerUrl = () => {
  desktopServerUrl.value = getDesktopServerUrl();
};

const normalizeDomain = (value: string) => value.trim().toLowerCase().replace(/^@/, "");
const availableEmailDomains = computed(() => configuredEmailDomains.value);

const syncEmailFromParts = () => {
  const local = form.emailLocal.trim().toLowerCase();
  const domain = normalizeDomain(form.emailDomain);
  form.emailDomain = domain;
  form.email = local && domain ? `${local}@${domain}` : "";
};

const applyEmailValue = (email: string) => {
  const normalized = email.trim().toLowerCase();
  const separator = normalized.lastIndexOf("@");
  if (separator > 0) {
    form.emailLocal = normalized.slice(0, separator);
    const domain = normalizeDomain(normalized.slice(separator + 1));
    form.emailDomain = configuredEmailDomains.value.includes(domain)
      ? domain
      : configuredEmailDomains.value[0] || "";
  } else {
    form.emailLocal = normalized;
    form.emailDomain = configuredEmailDomains.value[0] || "";
  }
  syncEmailFromParts();
};

const loadEmailDomains = async () => {
  try {
    const { data } = await fetchEmailDomains();
    configuredEmailDomains.value = Array.from(new Set(
      data.items.map(normalizeDomain).filter(Boolean)
    ));
    if (!configuredEmailDomains.value.includes(form.emailDomain)) {
      form.emailDomain = configuredEmailDomains.value[0] || "";
    }
  } catch {
    configuredEmailDomains.value = [];
    form.emailDomain = "";
  }
};

const handleAccountPaste = (event: ClipboardEvent) => {
  const pasted = event.clipboardData?.getData("text").trim() || "";
  if (!pasted.includes("@")) return;
  event.preventDefault();
  applyEmailValue(pasted);
};

onMounted(async () => {
  window.addEventListener(DESKTOP_SERVER_URL_CHANGED_EVENT, refreshDesktopServerUrl);
  await loadEmailDomains();
  const reason = consumeLogoutReason();
  if (reason === LOGOUT_REASON_TIMEOUT) {
    logoutNotice.value = { type: "warning", title: "已自动退出登录", message: "30 分钟未检测到任何操作。为保护项目数据，请重新登录后继续。" };
  } else if (reason === LOGOUT_REASON_AUTH_EXPIRED) {
    logoutNotice.value = { type: "warning", title: "登录状态已失效", message: "当前会话无法继续使用，请重新登录。" };
  } else if (reason === LOGOUT_REASON_MANUAL) {
    logoutNotice.value = { type: "info", title: "已安全退出", message: "本机登录状态已清除，需要时可再次登录。" };
  }
  applyEmailValue(localStorage.getItem("ctms_last_login_email") || "");
  form.agreeProtocol = localStorage.getItem(AGREE_PROTOCOL_KEY) === "true";
});

onUnmounted(() => {
  window.removeEventListener(DESKTOP_SERVER_URL_CHANGED_EVENT, refreshDesktopServerUrl);
});

watch(() => form.agreeProtocol, (checked) => localStorage.setItem(AGREE_PROTOCOL_KEY, String(checked)));
watch(() => [form.emailLocal, form.emailDomain], syncEmailFromParts);

const openProtocolDialog = () => { protocolDialogVisible.value = true; };
const confirmProtocol = () => { form.agreeProtocol = true; protocolDialogVisible.value = false; };

const onSubmit = async () => {
  if (!formRef.value) return;
  const valid = await formRef.value.validate();
  if (!valid) return;
  if (!form.agreeProtocol) { ElMessage.warning("请先阅读并同意用户协议"); return; }
  loginError.value = null; // 清除上次错误
  loading.value = true;
  try {
    await auth.login(form.email, form.password);
    const studyStore = useStudyStore();
    const userKey = auth.user?.email || form.email;
    await studyStore.restoreStudyForUser(userKey, { preferActive: !!auth.user?.is_admin });
    if (studyStore.currentStudy) {
      router.push("/project/overview");
    } else {
      router.push(auth.user?.is_admin ? "/admin/users" : "/admin/projects");
    }
  } catch (error: any) {
    const status = error?.response?.status;
    const detail: string = error?.response?.data?.detail || error?.response?.data?.message || "";
    // 根据状态码和后端信息做差异化映射
    if (!status || status >= 500) {
      loginError.value = { title: "服务暂时不可用", message: "请稍后重试，如持续出现请联系管理员" };
    } else if (status === 429) {
      loginError.value = { title: "操作过于频繁", message: "登录尝试次数过多，请稍后再试" };
    } else if (status === 403 || detail.includes("未激活") || detail.includes("审核") || detail.includes("pending")) {
      loginError.value = { title: "账号不可用", message: "请联系系统管理员确认账号状态" };
    } else if (detail.includes("锁定") || detail.includes("locked") || detail.includes("disabled")) {
      loginError.value = { title: "账号已被锁定", message: "请联系系统管理员解锁账号" };
    } else if (status === 401) {
      loginError.value = { title: "邮箱或密码不正确", message: "请检查后重新输入，多次失败可能导致账号锁定" };
    } else {
      loginError.value = { title: "登录失败", message: detail || TEXT.modules.auth.authFailed };
    }
  } finally {
    loading.value = false;
  }
};
</script>

<style scoped>
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=Outfit:wght@400;600;800&display=swap");

/* ═══════════════════════
   根容器
   ═══════════════════════ */
.login-wrapper {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: stretch;
  justify-content: stretch;
  overflow: hidden;
  background: #ffffff;
  font-family: "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
}

.login-split-container {
  display: flex;
  width: 100vw;
  min-height: 100vh;
}

/* ═══════════════════════
   左侧：明亮极光科技面板
   ═══════════════════════ */
.login-left-brand {
  flex: 1;
  background: linear-gradient(135deg, #e0f2fe 0%, #e0e7ff 50%, #f3e8ff 100%);
  padding: 60px 80px;
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* 渐变圆形球光效 */
.brand-glow-sphere {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  pointer-events: none;
  z-index: 1;
}

.sphere-1 {
  width: 480px;
  height: 480px;
  background: rgba(99, 102, 241, 0.16);
  top: 15%;
  left: -10%;
  animation: floatSphere1 20s infinite alternate ease-in-out;
}

.sphere-2 {
  width: 420px;
  height: 420px;
  background: rgba(6, 182, 212, 0.14);
  bottom: 10%;
  right: -5%;
  animation: floatSphere2 25s infinite alternate ease-in-out;
}

@keyframes floatSphere1 {
  0% { transform: translate(0, 0) scale(1); }
  100% { transform: translate(30px, 40px) scale(1.1); }
}

@keyframes floatSphere2 {
  0% { transform: translate(0, 0) scale(1); }
  100% { transform: translate(-40px, -30px) scale(1.08); }
}

.brand-bg-pattern {
  position: absolute;
  bottom: 5%;
  right: -5%;
  width: 440px;
  height: 440px;
  background-image: url("data:image/svg+xml,%3Csvg width='380' height='380' viewBox='0 0 380 380' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M60 120 L130 80 L200 120 L200 200 L130 240 L60 200 Z' stroke='rgba(99, 102, 241, 0.12)' stroke-width='1.2'/%3E%3Cpath d='M200 120 L270 80 L340 120 L340 200 L270 240 L200 200' stroke='rgba(6, 182, 212, 0.1)' stroke-width='1.2'/%3E%3Ccircle cx='60' cy='120' r='4' fill='rgba(99, 102, 241, 0.25)'/%3E%3Ccircle cx='60' cy='120' r='8' stroke='rgba(99, 102, 241, 0.08)' stroke-width='1'/%3E%3Ccircle cx='130' cy='80' r='3' fill='rgba(99, 102, 241, 0.18)'/%3E%3Ccircle cx='200' cy='120' r='4' fill='rgba(99, 102, 241, 0.25)'/%3E%3Ccircle cx='200' cy='200' r='3' fill='rgba(99, 102, 241, 0.18)'/%3E%3Ccircle cx='130' cy='240' r='4' fill='rgba(99, 102, 241, 0.2)'/%3E%3Ccircle cx='60' cy='200' r='3' fill='rgba(99, 102, 241, 0.15)'/%3E%3Ccircle cx='270' cy='80' r='4' fill='rgba(6, 182, 212, 0.2)'/%3E%3Ccircle cx='340' cy='120' r='5' fill='rgba(6, 182, 212, 0.25)'/%3E%3Ccircle cx='340' cy='120' r='10' stroke='rgba(6, 182, 212, 0.08)' stroke-width='1'/%3E%3Ccircle cx='340' cy='200' r='3' fill='rgba(6, 182, 212, 0.15)'/%3E%3Ccircle cx='270' cy='240' r='4' fill='rgba(6, 182, 212, 0.2)'/%3E%3Cpath d='M130 80 L130 30 M270 80 L270 30' stroke='rgba(99, 102, 241, 0.08)' stroke-width='1.2' stroke-dasharray='2 2'/%3E%3Ccircle cx='130' cy='30' r='2' fill='rgba(99, 102, 241, 0.12)'/%3E%3Ccircle cx='270' cy='30' r='2' fill='rgba(6, 182, 212, 0.12)'/%3E%3C/svg%3E");
  background-size: contain;
  background-repeat: no-repeat;
  pointer-events: none;
  z-index: 1;
  opacity: 0.8;
  animation: bgPatternFloat 30s infinite alternate ease-in-out;
}

@keyframes bgPatternFloat {
  0% { transform: translate(0, 0) rotate(0deg); }
  100% { transform: translate(-10px, 15px) rotate(2deg); }
}

.brand-content-wrapper {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  flex: 1;
}

/* 迷你Logo */
.brand-mini-logo {
  display: flex;
  align-items: center;
  gap: 14px;
}

.mini-logo-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 55px;
  height: 55px;
  background: #2563eb;
  border-radius: 14px;
  color: white;
}

.mini-logo-text {
  font-size: 26px;
  font-weight: 700;
  color: #1e293b;
  letter-spacing: 0.5px;
}

/* Slogan 区 */
.brand-slogan-block {
  margin: 32px 0 0;
  max-width: 520px;
}

.brand-main-title {
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: 38px;
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: -1px;
  margin: 0 0 20px;
  color: #1e293b;
}

.company-name {
  background: linear-gradient(135deg, #1d4ed8, #0891b2);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.system-name {
  color: #0f172a;
}

.brand-sub-desc {
  font-size: 15px;
  color: #64748b;
  line-height: 1.8;
  margin: 0;
  font-weight: 500;
}

/* 特征卡片网格 */
.brand-features-grid {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin: 32px 0;
  width: 100%;
  max-width: 520px;
}

.feature-card {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 18px 22px;
  background: rgba(255, 255, 255, 0.25);
  border: 1px solid rgba(255, 255, 255, 0.45);
  border-radius: 16px;
  transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
  cursor: default;
  opacity: 0;
  transform: translateY(20px);
  animation: cardFadeIn 0.8s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.feature-card.delay-1 { animation-delay: 0.15s; }
.feature-card.delay-2 { animation-delay: 0.3s; }
.feature-card.delay-3 { animation-delay: 0.45s; }

@keyframes cardFadeIn {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

.feature-card:hover {
  background: rgba(255, 255, 255, 0.55);
  border-color: rgba(37, 99, 235, 0.22);
  transform: translateY(-3px);
  box-shadow: 
    0 12px 30px -10px rgba(37, 99, 235, 0.08),
    0 4px 12px -2px rgba(0, 0, 0, 0.02);
}

.feature-icon-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  background: rgba(37, 99, 235, 0.06);
  border-radius: 10px;
  color: #2563eb;
  flex-shrink: 0;
  transition: all 0.3s ease;
}

.feature-card:hover .feature-icon-wrapper {
  background: #2563eb;
  color: #ffffff;
  box-shadow: 0 4px 12px rgba(37, 99, 235, 0.35);
}

.feature-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.feature-title {
  font-size: 15px;
  font-weight: 700;
  color: #1e293b;
  margin: 0;
  line-height: 1.4;
  transition: color 0.3s;
}

.feature-card:hover .feature-title {
  color: #0f172a;
}

.feature-desc {
  font-size: 12px;
  color: #64748b;
  line-height: 1.6;
  margin: 0;
  font-weight: 500;
}

/* 底部声明 */
.brand-legal-info {
  border-top: 1px solid rgba(148, 163, 184, 0.15);
  padding-top: 24px;
}

.legal-item {
  font-family: 'Outfit', sans-serif;
  font-size: 11px;
  color: #94a3b8;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  margin: 0;
}

/* ═══════════════════════
   右侧：极简白底登录面板
   ═══════════════════════ */
.login-right-form {
  flex: 1;
  background: #ffffff;
  padding: 60px 80px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 上方浏览器兼容建议 */
.browser-tip {
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  width: 90%;
  max-width: 600px;
  text-align: center;
  font-size: 12px;
  color: #64748b;
  white-space: nowrap;
}

.download-link {
  color: #2563eb;
  text-decoration: none;
  font-weight: 600;
}
.download-link:hover {
  text-decoration: underline;
}

/* 卡片容器 */
.login-card-container {
  width: clamp(480px, 34vw, 560px);
  max-width: calc(100vw - 40px);
  display: flex;
  flex-direction: column;
}

/* 顶部品牌Logo */
.login-brand-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 40px;
}

.brand-logo-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  background: #2563eb;
  border-radius: 9px;
  color: white;
}

.brand-divider {
  width: 1.5px;
  height: 18px;
  background: #e2e8f0;
}

.brand-system-text {
  font-family: 'Outfit', sans-serif;
  font-size: 20px;
  font-weight: 800;
  color: #1e293b;
  letter-spacing: -0.5px;
}

/* Tabs */
.login-tabs {
  display: flex;
  gap: 24px;
  margin-bottom: 36px;
  border-bottom: 1.5px solid #f1f5f9;
}

.tab-item {
  font-size: 15px;
  font-weight: 600;
  color: #94a3b8;
  padding-bottom: 10px;
  cursor: pointer;
  position: relative;
  transition: color 0.2s;
  user-select: none;
}

.tab-item.active {
  color: #2563eb;
}

.tab-item.active::after {
  content: "";
  position: absolute;
  bottom: -1.5px;
  left: 0;
  width: 100%;
  height: 2px;
  background: #2563eb;
  border-radius: 2px;
}

.desktop-server-status {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  margin: -18px 0 24px;
  padding: 10px 12px;
  border: 1px solid #dbe7f5;
  border-radius: 8px;
  background: #f8fafc;
  color: #64748b;
  font-size: 12px;
}

.desktop-server-label {
  color: #64748b;
  font-weight: 700;
}

.desktop-server-status code {
  min-width: 0;
  overflow-wrap: anywhere;
  color: #1e293b;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
}

.desktop-server-action {
  color: #2563eb;
  font-weight: 700;
  text-decoration: none;
}

.desktop-server-action:hover {
  color: #1d4ed8;
}

/* ═══════════════════════
   通知与错误提示
   ═══════════════════════ */
.logout-notice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 24px;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid;
}

.logout-notice--warning {
  color: #b45309;
  background: #fffbeb;
  border-color: #fde68a;
}

.logout-notice--info {
  color: #047857;
  background: #f0fdf4;
  border-color: #bbf7d0;
}

.ln-icon { width: 16px; height: 16px; flex-shrink: 0; margin-top: 1px; }
.ln-icon svg { width: 100%; height: 100%; }
.ln-body { display: flex; flex-direction: column; gap: 2px; }
.ln-body strong { font-size: 12px; font-weight: 700; }
.ln-body span   { font-size: 11px; opacity: 0.9; }

.login-error-banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 20px;
  padding: 12px 14px;
  border-radius: 10px;
  background: #fef2f2;
  border: 1px solid #fecaca;
  color: #b91c1c;
}

.leb-icon { width: 16px; height: 16px; flex-shrink: 0; margin-top: 1px; }
.leb-icon svg { width: 100%; height: 100%; }
.leb-body { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.leb-body strong { font-size: 12px; font-weight: 700; }
.leb-body span   { font-size: 11px; opacity: 0.9; }
.leb-close {
  flex-shrink: 0;
  appearance: none;
  background: none;
  border: none;
  padding: 2px;
  cursor: pointer;
  color: #f87171;
  display: flex;
  align-items: center;
  justify-content: center;
}
.leb-close:hover { color: #b91c1c; }
.leb-close svg { width: 12px; height: 12px; }

/* ═══════════════════════
   表单输入框 (下划线风格)
   ═══════════════════════ */
.login-form :deep(.el-form-item) {
  margin-bottom: 22px;
}

.login-form :deep(.el-form-item__label) {
  font-weight: 600;
  color: #475569;
  font-size: 13px;
  padding-bottom: 6px;
  line-height: 1;
}

.login-form :deep(.el-form-item__error) {
  margin-top: 6px;
  font-size: 11px;
  color: #ef4444;
}

.login-input :deep(.el-input__wrapper) {
  background: transparent !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  border-bottom: 1.5px solid #e2e8f0;
  padding: 6px 0 !important;
  transition: border-color 0.25s ease;
}

.login-input :deep(.el-input__wrapper:hover) {
  border-bottom-color: #cbd5e1;
}

.login-input :deep(.el-input__wrapper.is-focus) {
  border-bottom-color: #2563eb !important;
}

.login-input :deep(.el-input__inner) {
  height: 38px;
  font-size: 15px;
  color: #0f172a;
}

.login-input :deep(.el-input__inner::placeholder) {
  color: #94a3b8;
}

/* 账号与邮箱域名组合输入 */
.email-unified-box {
  display: flex;
  align-items: center;
  width: 100%;
  border-bottom: 1.5px solid #e2e8f0;
  transition: border-color 0.25s ease;
  padding: 4px 0;
}

.email-unified-box:focus-within {
  border-bottom-color: #2563eb;
}

.email-local-field,
.email-domain-field {
  min-width: 0;
  background: transparent;
  border: none;
  outline: none;
  font-family: inherit;
  font-size: 15px;
  line-height: 1.5;
}

.email-local-field {
  flex: 1;
  color: #0f172a;
  padding: 6px 0;
}

.email-local-field::placeholder {
  color: #94a3b8;
}

.email-at-sign {
  flex-shrink: 0;
  padding: 0 4px;
  color: #64748b;
  font-size: 15px;
  font-weight: 600;
  user-select: none;
}

.email-domain-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  flex-shrink: 0;
  max-width: 55%;
}

.email-domain-field {
  width: auto;
  max-width: 100%;
  appearance: none;
  -webkit-appearance: none;
  color: #1e3a5f;
  font-weight: 600;
  padding: 6px 22px 6px 4px;
  cursor: pointer;
}

.email-domain-field:disabled {
  color: #94a3b8;
  cursor: not-allowed;
}

.email-domain-chevron {
  position: absolute;
  right: 2px;
  top: 50%;
  width: 14px;
  height: 14px;
  color: #94a3b8;
  pointer-events: none;
  transform: translateY(-50%);
}

/* 协议区 */
.login-options {
  margin: 4px 0 24px;
}

.protocol-checkbox :deep(.el-checkbox__input .el-checkbox__inner) {
  border-color: #cbd5e1;
  border-radius: 4px;
}

.protocol-checkbox :deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
  background: #2563eb;
  border-color: #2563eb;
}

.protocol-checkbox :deep(.el-checkbox__label) {
  padding-left: 8px;
  white-space: normal;
  line-height: 1.6;
}

.protocol-text {
  color: #64748b;
  font-size: 12px;
}

.protocol-link {
  appearance: none;
  padding: 0;
  border: 0;
  background: transparent;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  color: #2563eb;
}
.protocol-link:hover {
  text-decoration: underline;
}

/* 按钮 */
.login-btn {
  width: 100%;
  height: 48px;
  border-radius: 8px;
  font-size: 15px;
  font-weight: 600;
  background: #2563eb;
  border: none;
  box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2);
  transition: all 0.2s ease;
}

.login-btn:hover {
  background: #1d4ed8;
  box-shadow: 0 6px 16px rgba(37, 99, 235, 0.3);
  transform: translateY(-1px);
}

.login-btn:active {
  transform: translateY(0);
}

/* 注册与忘记密码左右分开 */
.forgot-register-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 20px;
}

.forgot-link, .register-link {
  font-size: 13px;
  color: #2563eb;
  text-decoration: none;
  font-weight: 500;
  transition: color 0.15s;
}

.forgot-link:hover, .register-link:hover {
  color: #1d4ed8;
  text-decoration: underline;
}

/* ═══════════════════════
   右侧底部页脚 (支持与版权)
   ═══════════════════════ */
.login-right-footer {
  margin-top: 40px;
  border-top: 1px solid #f1f5f9;
  padding-top: 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.footer-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  font-size: 11px;
  color: #94a3b8;
  line-height: 1.5;
}

.footer-label {
  font-weight: 500;
  color: #64748b;
}

.footer-link-text {
  color: #64748b;
  text-decoration: none;
  font-weight: 500;
  transition: all 0.2s;
}
.footer-link-text:hover {
  text-decoration: underline;
  color: #2563eb;
}

.copyright-line {
  margin-top: 2px;
}

.lang-switch {
  font-weight: 600;
  color: #64748b;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.meta-sep {
  color: #e2e8f0;
  margin: 0 8px;
}

.privacy-link {
  cursor: pointer;
  transition: color 0.2s;
}
.privacy-link:hover {
  color: #475569;
}

.compliance-line {
  color: #94a3b8;
}

.version-tag {
  font-weight: 600;
  color: #64748b;
}

.compliance-text {
  opacity: 0.85;
}

/* ═══════════════════════
   协议弹窗
   ═══════════════════════ */
.protocol-content {
  max-height: 58vh;
  overflow-y: auto;
  padding: 2px 8px 2px 0;
}

.protocol-section { margin-bottom: 26px; }
.protocol-section:last-child { margin-bottom: 0; }
.protocol-section h3 { margin: 0 0 14px; font-size: 18px; font-weight: 800; line-height: 1.4; color: #111827; }
.protocol-section p  { margin: 0 0 10px; font-size: 15px; font-weight: 400; line-height: 1.8; color: #6b7280; }
.protocol-section p:last-child { margin-bottom: 0; }

.protocol-confirm-btn {
  min-width: 112px;
  height: 44px;
  border-radius: 22px;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 2px;
  background: #2563eb;
  border: none;
  box-shadow: 0 8px 20px -4px rgba(37, 99, 235, 0.4);
}
.protocol-confirm-btn:hover {
  background: #1d4ed8;
}

:global(.protocol-dialog .el-dialog) {
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 24px 64px rgba(0,0,0,0.1);
}

:global(.protocol-dialog .el-dialog__header) {
  padding: 24px 28px 12px;
  margin-right: 0;
  background: #fafafa;
}

:global(.protocol-dialog .el-dialog__title) {
  font-size: 18px;
  font-weight: 800;
  color: #111827;
}

:global(.protocol-dialog .el-dialog__body) { padding: 22px 36px 10px; }
:global(.protocol-dialog .el-dialog__footer) { padding: 18px 28px 24px; }

/* ═══════════════════════
   响应式断点适配
   ═══════════════════════ */

/* 大屏保持 1:1 分栏，通过扩大有效内容区改善内容密度 */
@media (min-width: 1440px) {
  .login-left-brand {
    flex: 1;
    padding: clamp(64px, 5vw, 96px);
  }

  .login-right-form {
    flex: 1;
    padding: clamp(64px, 6vw, 112px);
  }

  .brand-slogan-block,
  .brand-features-grid {
    max-width: 640px;
  }

  .brand-main-title {
    font-size: clamp(38px, 2.4vw, 48px);
  }

  .brand-sub-desc {
    font-size: 16px;
  }

  .feature-card {
    padding: 20px 24px;
  }

  .login-card-container {
    max-width: 440px;
  }
}

@media (max-width: 960px) {
  .login-left-brand {
    display: none;
  }
  .login-right-form {
    padding: 40px 24px;
    width: 100%;
  }
  .browser-tip {
    display: none;
  }
  .login-card-container {
    max-width: 440px;
  }
  .login-right-footer {
    margin-top: 40px;
  }
}

@media (max-width: 480px) {
  .login-brand-header {
    margin-bottom: 28px;
  }
  .login-tabs {
    margin-bottom: 24px;
  }
  .login-right-footer {
    margin-top: 32px;
  }
}
</style>
