/* ==========================================================================
   归浦GEO v8.0 Design System
   方向：完成版国际科技 SaaS —— 白底、蓝色主色、信息密度高、动效克制、业务动作明显
   ========================================================================== */

:root {
  /* 底色 */
  --bg: #F7F9FC;
  --surface: #FFFFFF;
  --surface-2: #FBFCFE;
  --surface-3: #F2F5FA;

  /* 主色 */
  --brand: #1B54A6;
  --brand-600: #2F7FE0;
  --brand-500: #4A93EC;
  --brand-50: #EDF4FE;
  --brand-100: #DCE9FD;
  --accent: #6D5CE7;
  --accent-50: #F1EEFE;

  /* 文本 */
  --text: #101828;
  --text-2: #475467;
  --text-3: #667085;
  --text-4: #98A2B3;

  /* 边框与分隔 */
  --line: #E6EBF2;
  --line-2: #EEF2F7;

  /* 状态色 */
  --success: #12B76A;
  --success-bg: #E9FBF2;
  --warn: #F79009;
  --warn-bg: #FFF8EC;
  --danger: #F04438;
  --danger-bg: #FEF3F2;
  --info: #2E90FA;
  --info-bg: #EFF8FF;

  /* 圆角 / 阴影 / 动效 */
  --r-sm: 8px;
  --r: 12px;
  --r-lg: 16px;
  --shadow-1: 0 1px 2px rgba(16, 24, 40, .04);
  --shadow-2: 0 4px 12px rgba(16, 24, 40, .06);
  --shadow-3: 0 12px 32px rgba(16, 24, 40, .10);
  --ease: cubic-bezier(.4, 0, .2, 1);
  --t-fast: 160ms;
  --t: 220ms;
  --t-slow: 300ms;

  --sidebar-w: 224px;
  --topbar-h: 64px}

* { box-sizing: border-box}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
    "Hiragino Sans GB", "Microsoft YaHei", "Source Han Sans SC", sans-serif;
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased}

a { color: var(--brand-600); text-decoration: none}
::-webkit-scrollbar { width: 10px; height: 10px}
::-webkit-scrollbar-thumb { background: #D7DEE9; border-radius: 8px; border: 3px solid transparent; background-clip: content-box}
::-webkit-scrollbar-thumb:hover { background: #B9C4D4; background-clip: content-box}
::-webkit-scrollbar-track { background: transparent}

/* ============================ 登录页 ============================ */
.v8-login {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  background: var(--surface)}
.v8-login__brand {
  position: relative;
  background:
    radial-gradient(1000px 500px at 12% 18%, rgba(47,127,224,.20), transparent 60%),
    radial-gradient(700px 460px at 82% 78%, rgba(109,92,231,.16), transparent 62%),
    linear-gradient(160deg, #0F3E86 0%, #1B54A6 46%, #2F7FE0 100%);
  color: #fff;
  padding: 56px 60px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden}
.v8-login__brand::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
  background-size: 44px 44px;
  mask-image: radial-gradient(760px 620px at 30% 30%, #000 10%, transparent 78%);
  pointer-events: none}
.v8-login__logo { display: flex; align-items: center; gap: 12px; position: relative; z-index: 1}
.v8-login__logo img { width: 34px; height: 34px}
.v8-login__logo b { font-size: 19px; letter-spacing: .3px; font-weight: 650}
.v8-login__hero { position: relative; z-index: 1; max-width: 520px}
.v8-login__hero h1 { font-size: 38px; line-height: 1.25; margin: 0 0 18px; font-weight: 700; letter-spacing: -.4px}
.v8-login__hero p { font-size: 15px; color: rgba(255,255,255,.82); margin: 0 0 30px}
.v8-login__points { display: grid; gap: 14px}
.v8-login__point {
  display: flex; gap: 12px; align-items: flex-start;
  background: rgba(255,255,255,.10);
  border: 1px solid rgba(255,255,255,.16);
  border-radius: var(--r);
  padding: 14px 16px;
  backdrop-filter: blur(6px)}
.v8-login__point i {
  width: 24px; height: 24px; flex: none; border-radius: 7px;
  background: rgba(255,255,255,.20); display: grid; place-items: center;
  font-size: 12px; font-style: normal; font-weight: 700}
.v8-login__point div b { display: block; font-size: 14px; font-weight: 600}
.v8-login__point div span { font-size: 12.5px; color: rgba(255,255,255,.74)}
.v8-login__foot { position: relative; z-index: 1; font-size: 12.5px; color: rgba(255,255,255,.62)}

.v8-login__panel { display: grid; place-items: center; padding: 40px; background: var(--surface)}
.v8-login__form { width: 100%; max-width: 380px}
.v8-login__form h2 { font-size: 25px; margin: 0 0 6px; font-weight: 680; letter-spacing: -.2px}
.v8-login__form > p { color: var(--text-3); margin: 0 0 28px; font-size: 13.5px}
.v8-field { margin-bottom: 16px}
.v8-field label { display: block; font-size: 13px; font-weight: 560; margin-bottom: 7px; color: var(--text-2)}
.v8-input {
  width: 100%; height: 42px; padding: 0 13px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); font-size: 14px; color: var(--text);
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
  font-family: inherit}
.v8-input:focus { outline: none; border-color: var(--brand-500)}
.v8-input::placeholder { color: var(--text-4)}
textarea.v8-input { height: auto; min-height: 92px; padding: 11px 13px; resize: vertical; line-height: 1.6}
select.v8-input { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23667085' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 13px center; padding-right: 34px}

.v8-login__hint {
  margin-top: 22px; padding: 13px 15px; background: var(--surface-3);
  border-radius: var(--r); font-size: 12.5px; color: var(--text-2); line-height: 1.7}
.v8-login__hint b { color: var(--text)}
.v8-login__hint code {
  background: var(--surface); border: 1px solid var(--line); border-radius: 5px;
  padding: 1px 6px; font-size: 12px; color: var(--brand)}

/* ============================ 应用外壳 ============================ */
.v8-shell { display: flex; min-height: 100vh}

/* 侧栏 */
.v8-side {
  width: var(--sidebar-w); flex: none;
  background: var(--surface); border-right: 1px solid var(--line);
  display: flex; flex-direction: column;
  position: fixed; inset: 0 auto 0 0; z-index: 40}
.v8-side__brand {
  height: var(--topbar-h); display: flex; align-items: center; gap: 10px;
  padding: 0 18px; border-bottom: 1px solid var(--line-2); flex: none}
.v8-side__brand img { width: 28px; height: 28px}
.v8-side__brand b { font-size: 15.5px; font-weight: 660; letter-spacing: -.2px}
.v8-side__brand span {
  font-size: 10.5px; color: var(--brand); background: var(--brand-50);
  border-radius: 5px; padding: 1px 5px; font-weight: 600}
.v8-nav { flex: 1; overflow-y: auto; padding: 10px 10px 18px}
.v8-nav__group { margin-bottom: 3px}
.v8-nav__item {
  display: flex; align-items: center; gap: 10px;
  height: 38px; padding: 0 10px; border-radius: 9px;
  color: var(--text-2); font-size: 13.5px; cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
  user-select: none; position: relative}
.v8-nav__item:hover { background: var(--surface-3); color: var(--text)}
.v8-nav__item.is-active { background: var(--brand-50); color: var(--brand); font-weight: 600}
.v8-nav__item.is-active::before {
  content: ""; position: absolute; left: -10px; top: 9px; bottom: 9px;
  width: 3px; border-radius: 0 3px 3px 0; background: var(--brand)}
.v8-nav__ico { width: 18px; text-align: center; font-size: 14px; flex: none; opacity: .9}
.v8-nav__txt { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap}
.v8-nav__caret { font-size: 10px; color: var(--text-4); transition: transform var(--t-fast) var(--ease)}
.v8-nav__group.is-open .v8-nav__caret { transform: rotate(90deg)}
.v8-nav__sub { display: none; padding: 2px 0 4px 0}
.v8-nav__group.is-open .v8-nav__sub { display: block; animation: v8-slide var(--t) var(--ease)}
.v8-nav__subitem {
  display: flex; align-items: center; height: 32px; padding: 0 10px 0 38px;
  border-radius: 8px; color: var(--text-3); font-size: 13px; cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease)}
.v8-nav__subitem:hover { background: var(--surface-3); color: var(--text)}
.v8-nav__subitem.is-active { color: var(--brand); font-weight: 600; background: var(--brand-50)}
.v8-side__foot { padding: 12px 16px; border-top: 1px solid var(--line-2); font-size: 11.5px; color: var(--text-4)}

/* 主区 */
.v8-main { flex: 1; margin-left: var(--sidebar-w); min-width: 0; display: flex; flex-direction: column}
.v8-top {
  height: var(--topbar-h); flex: none; background: rgba(255,255,255,.88);
  backdrop-filter: blur(10px); border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 14px; padding: 0 24px;
  position: sticky; top: 0; z-index: 30}
.v8-top__title { font-size: 16px; font-weight: 640; letter-spacing: -.2px}
.v8-top__crumb { font-size: 12.5px; color: var(--text-4)}
.v8-top__spacer { flex: 1}
.v8-top__search {
  width: 240px; height: 34px; border: 1px solid var(--line); border-radius: 9px;
  display: flex; align-items: center; padding: 0 11px; gap: 7px; background: var(--surface-2);
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease)}
.v8-top__search:focus-within { border-color: var(--brand-500);  background: #fff}
.v8-top__search input { border: 0; outline: 0; background: transparent; font-size: 13px; width: 100%; font-family: inherit; color: var(--text)}
.v8-top__proj {
  height: 34px; display: flex; align-items: center; gap: 8px; padding: 0 12px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--surface);
  font-size: 13px; cursor: pointer; max-width: 260px;
  transition: border-color var(--t-fast) var(--ease)}
.v8-top__proj:hover { border-color: var(--brand-500)}
.v8-top__proj span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap}
.v8-avatar {
  width: 32px; height: 32px; border-radius: 50%; flex: none;
  background: linear-gradient(135deg, var(--brand-600), var(--accent));
  color: #fff; display: grid; place-items: center; font-size: 12.5px; font-weight: 600;
  cursor: pointer}

.v8-body { flex: 1; padding: 22px 24px 40px; min-width: 0}
.v8-wrap { max-width: 1440px; margin: 0 auto}

/* ============================ 通用组件 ============================ */
.v8-page-head { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 18px; flex-wrap: wrap}
.v8-page-head__l { flex: 1; min-width: 260px}
.v8-page-head h1 {
  font-size: 21px; margin: 0 0 5px; font-weight: 660; letter-spacing: -.3px;
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap}
.v8-page-head p { margin: 0; color: var(--text-3); font-size: 13px; max-width: 760px}
.v8-page-head__r { display: flex; gap: 9px; align-items: center; flex-wrap: wrap}

.v8-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg)}
.v8-card + .v8-card { margin-top: 16px}
.v8-card__head {
  display: flex; align-items: center; gap: 12px; padding: 15px 18px;
  border-bottom: 1px solid var(--line-2)}
.v8-card__head h3 {
  margin: 0; font-size: 14.5px; font-weight: 620; display: flex; align-items: center; gap: 8px}
.v8-card__head .v8-sub { font-size: 12px; color: var(--text-4); font-weight: 400}
.v8-card__head__r { margin-left: auto; display: flex; gap: 8px; align-items: center}
.v8-card__body { padding: 18px}
.v8-card__body--flush { padding: 0}

.v8-grid { display: grid; gap: 16px}
.v8-grid--5 { grid-template-columns: repeat(5, minmax(0, 1fr))}
.v8-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr))}
.v8-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr))}
.v8-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr))}
.v8-grid--21 { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr)}
.v8-grid--12 { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr)}

/* KPI */
.v8-kpi {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 16px 17px;  position: relative; overflow: hidden;
  transition: box-shadow var(--t) var(--ease), transform var(--t) var(--ease)}
.v8-kpi:hover {  transform: translateY(-1px)}
.v8-kpi__top { display: flex; align-items: center; gap: 8px; margin-bottom: 10px}
.v8-kpi__label { font-size: 12.5px; color: var(--text-3); font-weight: 500}
.v8-kpi__val {
  font-size: 30px; font-weight: 700; letter-spacing: -.8px; line-height: 1.1;
  font-variant-numeric: tabular-nums}
.v8-kpi__val small { font-size: 14px; font-weight: 500; color: var(--text-3); margin-left: 2px}
.v8-kpi__foot {
  display: flex; align-items: center; gap: 8px; margin-top: 10px;
  font-size: 11.5px; color: var(--text-4); flex-wrap: wrap}
.v8-kpi__spark { height: 34px; margin-top: 10px}

/* 徽标 */
.v8-badge {
  display: inline-flex; align-items: center; gap: 4px; height: 21px; padding: 0 8px;
  border-radius: 6px; font-size: 11.5px; font-weight: 560; white-space: nowrap;
  border: 1px solid transparent}
.v8-badge--brand { background: var(--brand-50); color: var(--brand); border-color: var(--brand-100)}
.v8-badge--success { background: var(--success-bg); color: #067647; border-color: #C6F0DC}
.v8-badge--warn { background: var(--warn-bg); color: #B54708; border-color: #FDE5B8}
.v8-badge--danger { background: var(--danger-bg); color: #B42318; border-color: #FECDCA}
.v8-badge--info { background: var(--info-bg); color: #175CD3; border-color: #CBE4FF}
.v8-badge--gray { background: var(--surface-3); color: var(--text-3); border-color: var(--line)}

/* 数据源角标（v8 核心：绝不隐藏数据来源） */
.v8-src {
  display: inline-flex; align-items: center; gap: 4px; height: 20px; padding: 0 7px;
  border-radius: 5px; font-size: 11px; font-weight: 560; font-family: ui-monospace, Menlo, Consolas, monospace;
  cursor: help}
.v8-src--REAL { background: var(--success-bg); color: #067647}
.v8-src--IMPORT { background: var(--info-bg); color: #175CD3}
.v8-src--MANUAL { background: #F4F3FF; color: #5925DC}
.v8-src--SAMPLED { background: var(--warn-bg); color: #B54708}
.v8-src--DEMO { background: #F2F4F7; color: #475467}
.v8-src--AI_ANALYSIS { background: var(--accent-50); color: #5925DC}
.v8-src--ESTIMATED { background: #F2F4F7; color: #475467}
.v8-src--ERROR { background: var(--danger-bg); color: #B42318}

/* 按钮 */
.v8-btn {
  height: 34px; padding: 0 14px; border-radius: 9px; border: 1px solid var(--line);
  background: var(--surface); color: var(--text-2); font-size: 13px; font-weight: 540;
  cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
  transition: all var(--t-fast) var(--ease); font-family: inherit; white-space: nowrap}
.v8-btn:hover { background: var(--surface-3); border-color: #D5DEEA; color: var(--text)}
.v8-btn:active { transform: translateY(1px)}
.v8-btn:disabled { opacity: .5; cursor: not-allowed; transform: none}
.v8-btn--primary {
  background: linear-gradient(180deg, var(--brand-600), var(--brand));
  border-color: var(--brand); color: #fff}
.v8-btn--primary:hover { background: linear-gradient(180deg, #3C88E6, #1E5CB4); border-color: var(--brand); color: #fff}
.v8-btn--ghost { border-color: transparent; background: transparent}
.v8-btn--ghost:hover { background: var(--surface-3)}
.v8-btn--danger { color: var(--danger); border-color: #FECDCA; background: var(--danger-bg)}
.v8-btn--danger:hover { background: #FEE4E2; color: #B42318}
.v8-btn--sm { height: 28px; padding: 0 10px; font-size: 12.5px; border-radius: 7px}
.v8-btn--xs { height: 24px; padding: 0 8px; font-size: 12px; border-radius: 6px}
.v8-btn--block { width: 100%; justify-content: center}

/* 表格 */
.v8-table { width: 100%; border-collapse: collapse; font-size: 13px}
.v8-table th {
  text-align: left; padding: 10px 14px; font-size: 12px; font-weight: 600;
  color: var(--text-3); background: var(--surface-2); border-bottom: 1px solid var(--line);
  white-space: nowrap; position: sticky; top: 0; z-index: 1}
.v8-table td { padding: 11px 14px; border-bottom: 1px solid var(--line-2); vertical-align: top}
.v8-table tbody tr { transition: background var(--t-fast) var(--ease)}
.v8-table tbody tr:hover { background: var(--surface-2)}
.v8-table tbody tr.is-clickable { cursor: pointer}
.v8-table tbody tr:last-child td { border-bottom: 0}
.v8-table__empty { padding: 46px 14px; text-align: center; color: var(--text-4)}

/* 空态 */
.v8-empty {
  padding: 44px 22px; text-align: center}
.v8-empty__ico {
  width: 52px; height: 52px; margin: 0 auto 14px; border-radius: 15px;
  background: var(--surface-3); display: grid; place-items: center; font-size: 22px; color: var(--text-4)}
.v8-empty h4 { margin: 0 0 6px; font-size: 14.5px; font-weight: 600; color: var(--text-2)}
.v8-empty p { margin: 0 0 16px; font-size: 13px; color: var(--text-3); max-width: 460px; margin-inline: auto}
.v8-empty__acts { display: flex; gap: 9px; justify-content: center; flex-wrap: wrap}

/* 进度 */
.v8-prog { height: 6px; background: var(--surface-3); border-radius: 99px; overflow: hidden}
.v8-prog__bar {
  height: 100%; border-radius: 99px;
  background: linear-gradient(90deg, var(--brand-500), var(--brand));
  transition: width var(--t-slow) var(--ease);
  position: relative; overflow: hidden}
.v8-prog__bar::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.45), transparent);
  animation: v8-shimmer 1.4s infinite}
.v8-prog__bar--success { background: linear-gradient(90deg, #4ADE9B, var(--success))}
.v8-prog__bar--danger { background: linear-gradient(90deg, #F97066, var(--danger))}

/* 维度条 */
.v8-dim { display: flex; align-items: center; gap: 10px; padding: 7px 0}
.v8-dim__label { width: 92px; flex: none; font-size: 12.5px; color: var(--text-2)}
.v8-dim__bar { flex: 1; height: 7px; background: var(--surface-3); border-radius: 99px; overflow: hidden}
.v8-dim__bar i { display: block; height: 100%; border-radius: 99px; background: linear-gradient(90deg, var(--brand-500), var(--brand)); transition: width var(--t-slow) var(--ease)}
.v8-dim__val { width: 52px; text-align: right; font-size: 12.5px; font-weight: 620; font-variant-numeric: tabular-nums}
.v8-dim__w { width: 34px; text-align: right; font-size: 11px; color: var(--text-4)}

/* 平台矩阵 */
.v8-matrix { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 12.5px}
.v8-matrix th { padding: 8px 10px; font-size: 11.5px; color: var(--text-3); font-weight: 600; background: var(--surface-2); border-bottom: 1px solid var(--line)}
.v8-matrix td { padding: 8px 10px; border-bottom: 1px solid var(--line-2)}
.v8-cell {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 46px; height: 26px; border-radius: 7px; font-weight: 600; font-size: 12px;
  font-variant-numeric: tabular-nums}
.v8-cell--0 { background: #F2F4F7; color: #98A2B3}
.v8-cell--1 { background: #FEF3F2; color: #B42318}
.v8-cell--2 { background: #FFF8EC; color: #B54708}
.v8-cell--3 { background: #EFF8FF; color: #175CD3}
.v8-cell--4 { background: var(--success-bg); color: #067647}

/* 抽屉 */
.v8-drawer-mask {
  position: fixed; inset: 0; background: rgba(16,24,40,.42); z-index: 60;
  animation: v8-fade var(--t) var(--ease)}
.v8-drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: 620px; max-width: 92vw;
  background: var(--surface); z-index: 61; display: flex; flex-direction: column;
   animation: v8-slide-in var(--t-slow) var(--ease)}
.v8-drawer--wide { width: 860px}
.v8-drawer__head {
  padding: 16px 20px; border-bottom: 1px solid var(--line);
  display: flex; align-items: flex-start; gap: 12px; flex: none}
.v8-drawer__head h3 { margin: 0 0 4px; font-size: 16px; font-weight: 640}
.v8-drawer__body { flex: 1; overflow-y: auto; padding: 18px 20px 30px}
.v8-drawer__foot { padding: 14px 20px; border-top: 1px solid var(--line); display: flex; gap: 9px; justify-content: flex-end; flex: none}
.v8-drawer__close {
  width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--surface); cursor: pointer; color: var(--text-3); flex: none;
  display: grid; place-items: center; font-size: 15px;
  transition: all var(--t-fast) var(--ease)}
.v8-drawer__close:hover { background: var(--surface-3); color: var(--text)}

/* 模态 */
.v8-modal-mask { position: fixed; inset: 0; background: rgba(16,24,40,.42); z-index: 70; display: grid; place-items: center; padding: 24px; animation: v8-fade var(--t) var(--ease)}
.v8-modal {
  background: var(--surface); border-radius: var(--r-lg); width: 520px; max-width: 100%;
  max-height: 86vh; display: flex; flex-direction: column; 
  animation: v8-pop var(--t) var(--ease)}
.v8-modal__head { padding: 17px 20px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 12px}
.v8-modal__head h3 { margin: 0; font-size: 15.5px; font-weight: 640; flex: 1}
.v8-modal__body { padding: 20px; overflow-y: auto; flex: 1}
.v8-modal__foot { padding: 14px 20px; border-top: 1px solid var(--line); display: flex; gap: 9px; justify-content: flex-end}

/* Toast */
.v8-toasts { position: fixed; top: 18px; right: 18px; z-index: 90; display: flex; flex-direction: column; gap: 9px}
.v8-toast {
  min-width: 260px; max-width: 400px; background: var(--surface);
  border: 1px solid var(--line); border-left: 3px solid var(--brand);
  border-radius: var(--r);  padding: 11px 14px;
  display: flex; gap: 10px; align-items: flex-start; font-size: 13px;
  animation: v8-slide-in var(--t) var(--ease)}
.v8-toast--success { border-left-color: var(--success)}
.v8-toast--error { border-left-color: var(--danger)}
.v8-toast--warn { border-left-color: var(--warn)}
.v8-toast__ico { font-size: 14px; flex: none; line-height: 1.4}
.v8-toast__msg { flex: 1; word-break: break-word}
.v8-toast__msg small { display: block; color: var(--text-4); font-size: 11.5px; margin-top: 2px; font-family: ui-monospace, Menlo, monospace}

/* 提示气泡 */
.v8-tip { position: relative}
.v8-tip:hover::after {
  content: attr(data-tip); position: absolute; bottom: calc(100% + 6px); left: 50%;
  transform: translateX(-50%); background: #101828; color: #fff; font-size: 11.5px;
  padding: 5px 9px; border-radius: 6px; white-space: pre; z-index: 20; pointer-events: none;
  font-weight: 400; line-height: 1.5}

/* 分段控件 */
.v8-seg { display: inline-flex; background: var(--surface-3); border-radius: 9px; padding: 3px; gap: 2px}
.v8-seg button {
  height: 28px; padding: 0 12px; border: 0; background: transparent; border-radius: 7px;
  font-size: 12.5px; color: var(--text-3); cursor: pointer; font-family: inherit;
  transition: all var(--t-fast) var(--ease); font-weight: 520}
.v8-seg button.is-active { background: var(--surface); color: var(--brand); font-weight: 620}

/* 筛选栏 */
.v8-filters { display: flex; gap: 9px; align-items: center; flex-wrap: wrap; margin-bottom: 14px}
.v8-filters .v8-input { height: 34px; width: auto; min-width: 130px}
.v8-filters__spacer { flex: 1}

/* 分页 */
.v8-pager { display: flex; align-items: center; gap: 8px; padding: 12px 18px; border-top: 1px solid var(--line-2); font-size: 12.5px; color: var(--text-3)}
.v8-pager__spacer { flex: 1}

/* 列表项（机会榜 / 任务列表） */
.v8-item {
  display: flex; gap: 12px; padding: 13px 16px; border-bottom: 1px solid var(--line-2);
  transition: background var(--t-fast) var(--ease); cursor: pointer; align-items: flex-start}
.v8-item:hover { background: var(--surface-2)}
.v8-item:last-child { border-bottom: 0}
.v8-item__pri {
  width: 40px; flex: none; text-align: center; padding-top: 1px}
.v8-item__pri b { display: block; font-size: 17px; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums}
.v8-item__pri span { font-size: 10px; color: var(--text-4)}
.v8-item__main { flex: 1; min-width: 0}
.v8-item__title { font-size: 13.5px; font-weight: 560; margin-bottom: 4px; line-height: 1.5}
.v8-item__meta { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; font-size: 12px; color: var(--text-3)}
.v8-item__acts { display: flex; gap: 7px; align-items: center; flex: none}

/* 状态点 */
.v8-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; flex: none}
.v8-dot--success { background: var(--success)}
.v8-dot--warn { background: var(--warn)}
.v8-dot--danger { background: var(--danger)}
.v8-dot--info { background: var(--info)}
.v8-dot--gray { background: var(--text-4)}
.v8-dot--spin { animation: v8-pulse 1.2s infinite}

/* 代码块 / 原文 */
.v8-raw {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r);
  padding: 14px 16px; font-size: 13px; line-height: 1.75; white-space: pre-wrap;
  word-break: break-word; max-height: 420px; overflow-y: auto; color: var(--text-2);
  font-family: inherit}
.v8-quote {
  border-left: 3px solid var(--brand-500); background: var(--brand-50);
  padding: 9px 12px; border-radius: 0 8px 8px 0; font-size: 12.5px;
  color: var(--text-2); margin: 6px 0; line-height: 1.65}

/* 统计块 */
.v8-stat { padding: 14px 16px}
.v8-stat + .v8-stat { border-top: 1px solid var(--line-2)}
.v8-stat__l { display: flex; align-items: baseline; gap: 8px}
.v8-stat__l b { font-size: 22px; font-weight: 700; letter-spacing: -.5px; font-variant-numeric: tabular-nums}
.v8-stat__l span { font-size: 12.5px; color: var(--text-3)}
.v8-stat__r { margin-left: auto; font-size: 12px; color: var(--text-3)}

/* 时间线 */
.v8-timeline { padding: 4px 0}
.v8-timeline__item { display: flex; gap: 11px; padding: 7px 0; font-size: 12.5px}
.v8-timeline__t { width: 62px; flex: none; color: var(--text-4); font-size: 11.5px; padding-top: 2px; font-variant-numeric: tabular-nums}
.v8-timeline__d { flex: 1; color: var(--text-2)}
.v8-timeline__item--error .v8-timeline__d { color: var(--danger)}
.v8-timeline__item--warn .v8-timeline__d { color: #B54708}

/* 骨架屏 */
.v8-skel {
  background: linear-gradient(90deg, var(--surface-3) 25%, #EDF1F7 37%, var(--surface-3) 63%);
  background-size: 400% 100%; animation: v8-skel 1.3s ease-in-out infinite; border-radius: 8px}

/* 移动端 */
.v8-mnav { display: none}
@media (max-width: 1080px) {
  .v8-grid--5 { grid-template-columns: repeat(3, minmax(0, 1fr))}
  .v8-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr))}
  .v8-grid--21, .v8-grid--12 { grid-template-columns: minmax(0, 1fr)}
}
@media (max-width: 860px) {
  .v8-side { transform: translateX(-100%); transition: transform var(--t-slow) var(--ease)}
  .v8-side.is-open { transform: none}
  .v8-main { margin-left: 0}
  .v8-grid--5, .v8-grid--4, .v8-grid--3, .v8-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr))}
  .v8-body { padding: 16px 14px 34px}
  .v8-top { padding: 0 14px; gap: 10px}
  .v8-top__search { display: none}
  .v8-login { grid-template-columns: 1fr}
  .v8-login__brand { display: none}
  .v8-mnav {
    display: flex; position: fixed; bottom: 0; left: 0; right: 0; z-index: 50;
    background: var(--surface); border-top: 1px solid var(--line);
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom))}
  .v8-mnav a {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px;
    font-size: 10.5px; color: var(--text-3); padding: 4px 0; border-radius: 8px}
  .v8-mnav a.is-active { color: var(--brand); background: var(--brand-50)}
  .v8-mnav a i { font-size: 17px; font-style: normal}
  .v8-body { padding-bottom: 74px}
  .v8-table thead { display: none}
  .v8-table, .v8-table tbody, .v8-table tr, .v8-table td { display: block; width: 100%}
  .v8-table tr {
    border: 1px solid var(--line); border-radius: var(--r); margin-bottom: 10px;
    padding: 4px 0; background: var(--surface)}
  .v8-table td { border: 0; padding: 7px 12px; display: flex; gap: 10px}
  .v8-table td::before {
    content: attr(data-label); flex: none; width: 84px; color: var(--text-4); font-size: 12px}
  .v8-drawer { width: 100%}
  /* 矩阵表列多，窄屏改为卡片内横向滚动，避免整页被撑出横向滚动条 */
  .v8-card__body, .v8-card--flush > .v8-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch}
  .v8-matrix { min-width: 520px}
  .v8-grid--5, .v8-grid--4, .v8-grid--3 { grid-template-columns: minmax(0, 1fr)}
}

/* 动画 */
@keyframes v8-fade { from { opacity: 0 } to { opacity: 1 } }
@keyframes v8-slide { from { opacity: 0; transform: translateY(-4px) } to { opacity: 1; transform: none } }
@keyframes v8-slide-in { from { opacity: 0; transform: translateX(18px) } to { opacity: 1; transform: none } }
@keyframes v8-pop { from { opacity: 0; transform: scale(.97) } to { opacity: 1; transform: none } }
@keyframes v8-shimmer { from { transform: translateX(-100%) } to { transform: translateX(100%) } }
@keyframes v8-pulse { 0%,100% { opacity: 1 } 50% { opacity: .35 } }
@keyframes v8-skel { 0% { background-position: 100% 50% } 100% { background-position: 0 50% } }
@keyframes v8-spin { to { transform: rotate(360deg) } }

.v8-spin { animation: v8-spin .8s linear infinite; display: inline-block}

/* 数字滚动 */
.v8-num { font-variant-numeric: tabular-nums}

/* 辅助 */
.v8-mono { font-family: ui-monospace, Menlo, Consolas, monospace}
.v8-muted { color: var(--text-3)}
.v8-dim-muted { color: var(--text-4)}
.v8-right { text-align: right}
.v8-center { text-align: center}
.v8-nowrap { white-space: nowrap}
.v8-ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap}
.v8-clamp2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden}
.v8-clamp3 { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden}
.v8-mt8 { margin-top: 8px} .v8-mt16 { margin-top: 16px} .v8-mb8 { margin-bottom: 8px}
.v8-flex { display: flex; gap: 8px; align-items: center}
.v8-flex--wrap { flex-wrap: wrap}
.v8-chart { width: 100%}

/* ================================================================
   v8.1 公众号扫码登录（P0-03）
   仅新增扫码入口与弹层所需的最小样式，复用现有设计 tokens，
   不换主色、不改字体体系、不动整体布局。
   ================================================================ */
.v8-wx-entry { margin-top: 16px}
.v8-wx-divider { position: relative; text-align: center; margin: 14px 0 12px}
.v8-wx-divider::before {
  content: ''; position: absolute; left: 0; right: 0; top: 50%;
  height: 1px; background: var(--line)}
.v8-wx-divider span {
  position: relative; background: var(--surface); padding: 0 12px;
  font-size: 12px; color: var(--text-4)}
.v8-wx-btn {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  height: 40px; font-size: 13.5px; color: var(--text-2);
  border-color: var(--line); background: var(--surface)}
.v8-wx-btn:hover { border-color: var(--brand); color: var(--brand); background: var(--brand-50, #F5F9FF)}

.v8-wx-modal { width: 400px}
.v8-wx-qr {
  width: 208px; height: 208px; margin: 4px auto 14px;
  border: 1px solid var(--line); border-radius: var(--r);
  display: grid; place-items: center; background: #fff; overflow: hidden}
.v8-wx-qr canvas { width: 188px !important; height: 188px !important}
.v8-wx-qr__ph { font-size: 12.5px; color: var(--text-4); padding: 20px; text-align: center}
.v8-wx-status { font-size: 14px; font-weight: 600; color: var(--text); margin-bottom: 6px}
.v8-wx-status.is-ok { color: var(--success)}
.v8-wx-status.is-warn { color: var(--warn)}
.v8-wx-tip { font-size: 12px; color: var(--text-3); line-height: 1.6; margin-bottom: 4px}
.v8-wx-bind { margin-top: 14px; text-align: left}
