/* ============================================================
   点阵 Lattice —— 知微生物医药有限公司统一身份中心
   tokens 与组件原样移植自开源设计系统
   github.com/ruiqichenbiec/design-systems (lattice, MIT)
   世界为夜：深墨上的光点。ink=静息 · hot=行动 · hot-2=次级
   ============================================================ */
:root {
  --bg: #07080b;
  --bg-2: #0d0f14;
  --ink: #ece7da;
  --text: var(--ink);
  --text-dim: #9d988c;
  --text-faint: #6c685f;
  --hot: #ff5a1f;
  --hot-2: #7fd8ff;
  --line: rgb(236 231 218 / 0.14);
  --line-strong: rgb(236 231 218 / 0.3);
  --panel: rgb(7 8 11 / 0.78);

  --f-ui: "Atkinson Hyperlegible Next", "Noto Sans SC", system-ui, sans-serif;
  --f-dot: "Doto", "Atkinson Hyperlegible Next", monospace;
  --f-zh: "Noto Sans SC", "Atkinson Hyperlegible Next", system-ui, sans-serif;

  --t-12: 12px; --t-13: 13px; --t-15: 15px; --t-17: 17px;
  --t-21: 21px; --t-28: 28px; --t-40: 40px; --t-64: 64px;
  --s-1: 6px; --s-2: 10px; --s-3: 14px; --s-4: 18px;
  --s-5: 24px; --s-6: 32px; --s-7: 44px; --s-8: 60px; --s-9: 84px;
  --r-1: 6px; --r-2: 12px; --r-pill: 999px;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --t-fast: 150ms; --t-mid: 300ms; --t-slow: 650ms;
  --pitch: 9px;
}

/* ---- base ---- */
*, *::before, *::after { box-sizing: border-box; }
[hidden], .hidden { display: none !important; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 var(--t-15) / 1.6 var(--f-ui);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}

/* ---- 点队光标（canvas 由 cursor.js 绘制：环绕点队 / 收敛到控件轮廓） ---- */
body { cursor: none; }
input, textarea { cursor: text; }
.lx-cursor {
  position: fixed; inset: 0; width: 100vw; height: 100vh;
  pointer-events: none; z-index: 100;
}
.has-cursor, .has-cursor * { cursor: none !important; }
.has-cursor input[type="text"], .has-cursor input[type="email"], .has-cursor input[type="password"], .has-cursor textarea { cursor: text !important; }
a { color: inherit; }

/* ---- 点阵画布与氛围（背景点阵网格由引擎绘制并与粒子互动） ---- */
#latticeCanvas { position: fixed; inset: 0; width: 100vw; height: 100vh; display: block; cursor: crosshair; }
.vignette {
  position: fixed; inset: 0; pointer-events: none;
  background: radial-gradient(130% 100% at 50% 44%, transparent 62%, rgb(0 0 0 / 0.38) 100%);
}
.grain {
  position: fixed; inset: -50%; pointer-events: none; opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain 9s steps(6) infinite;
}
@keyframes grain {
  0%, 100% { transform: translate(0, 0); }
  20% { transform: translate(-2%, 1%); }
  40% { transform: translate(1%, -2%); }
  60% { transform: translate(2%, 2%); }
  80% { transform: translate(-1%, -1%); }
}
/* 无 WebGL 时引擎退回 Canvas 2D，同一套物理与配色，画布仍然在场 */

/* ============================================================
   组件 —— 移植自 lattice/src/components.css
   ============================================================ */

/* ---- 按钮：胶囊，墨底或墨描边，热点只在行动 ---- */
.lx-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: 44px; padding: 0 var(--s-5);
  border: 0; border-radius: var(--r-pill);
  font: 700 var(--t-15) / 1 var(--f-ui); color: var(--bg);
  background: var(--text); cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast), transform var(--t-fast) var(--ease), box-shadow var(--t-mid);
  text-decoration: none;
}
.lx-btn:hover { background: #fff; }
.lx-btn:active { transform: scale(0.98); }
.lx-btn:disabled { opacity: 0.45; cursor: wait; }
.lx-btn .num { font-family: var(--f-dot); font-weight: 700; }
.lx-btn.accent { background: var(--hot); color: #140a05; }
.lx-btn.accent:hover { background: #ff7038; }
.lx-btn.ghost {
  background: transparent; color: var(--text-dim);
  box-shadow: inset 0 0 0 1px var(--line-strong);
}
.lx-btn.ghost:hover { color: var(--text); box-shadow: inset 0 0 0 1px var(--ink); background: transparent; }
.lx-btn.small { min-height: 34px; padding: 0 var(--s-4); font-size: var(--t-13); }
.lx-icon { width: 18px; height: 18px; flex: none; fill: currentColor; }

/* ---- 文本域：无边框，一行点作为下划线（画在 ::after 上，避免被自动填充遮盖）；
    聚焦时点变 hot 并向右流动 ---- */
.lx-field { display: flex; flex-direction: column; gap: var(--s-2); margin: 0 0 var(--s-5); position: relative; }
.lx-field > label {
  font: 700 var(--t-12) / 1 var(--f-ui);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-dim);
  transition: color var(--t-fast) var(--ease);
}
.lx-field:focus-within > label { color: var(--text); }
.lx-field > input {
  appearance: none; border: 0; border-radius: 0;
  background: transparent; color: var(--text);
  font: 500 var(--t-17) / 1.3 var(--f-ui);
  padding: var(--s-2) 0; outline: none; min-width: 0;
  caret-color: var(--hot);
  transition: color var(--t-fast);
}
.lx-field::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background-image: radial-gradient(circle, var(--line-strong) 1px, transparent 1.5px);
  background-size: 9px 2px; background-repeat: repeat-x; background-position: 0 100%;
}
.lx-field:focus-within::after {
  background-image: radial-gradient(circle, var(--hot) 1.2px, transparent 1.7px);
  animation: lx-dotflow 1.1s linear infinite;
}
.lx-field > input::placeholder { color: var(--text-faint); }
@keyframes lx-dotflow { to { background-position: 9px 100%; } }

/* 浏览器自动填充：用内阴影盖住默认白底，文字保持主题色 */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:autofill {
  -webkit-box-shadow: 0 0 0 1000px #0d0f14 inset;
  box-shadow: 0 0 0 1000px #0d0f14 inset;
  -webkit-text-fill-color: var(--text);
  caret-color: var(--text);
  transition: background-color 99999s ease-out;
}

/* ---- 密码显隐：贴在输入行右端的眼睛，不打断下划线式的字段结构 ---- */
.lx-field.has-reveal > input { padding-right: 36px; }
.lx-reveal {
  position: absolute; right: -5px; bottom: 2px;
  display: grid; place-items: center;
  width: 32px; height: 32px; padding: 0;
  border: 0; border-radius: 50%;
  background: transparent; color: var(--text-faint);
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.lx-reveal:hover { color: var(--text); }
.lx-reveal:focus-visible { outline: 2px solid var(--hot-2); outline-offset: 1px; }
.lx-reveal svg {
  width: 18px; height: 18px; fill: none;
  stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}
.lx-reveal__slash { opacity: 0; transition: opacity var(--t-fast) var(--ease); }
.lx-reveal.is-on { color: var(--hot-2); }
.lx-reveal.is-on .lx-reveal__slash { opacity: 1; }

/* ---- 验证码行：按钮与输入文字同线，底部留 4px 不压住点状下划线 ---- */
.lx-field-row {
  display: flex; align-items: flex-end; gap: var(--s-2);
  margin-bottom: var(--s-5);
}
.lx-field-row > .lx-field { flex: 1; min-width: 0; margin-bottom: 0; }
.lx-field-row > .lx-btn { flex: none; margin-bottom: 4px; white-space: nowrap; }

/* ---- 面板 ---- */
.lx-panel {
  background: var(--panel);
  border-radius: var(--r-2);
  box-shadow: inset 0 0 0 1px var(--line);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}

/* ---- 结晶进度（canvas 由 JS 绘制） ---- */
.lx-progress {
  display: inline-flex; align-items: center; gap: var(--s-3);
  font: 700 var(--t-12) / 1 var(--f-dot);
  letter-spacing: 0.08em; height: 28px; color: var(--text-dim);
}
.lx-progress canvas { width: var(--progress-w, 220px); height: 100%; display: block; }
.lx-progress small { font: inherit; color: var(--text-faint); letter-spacing: 0.15em; }
.lx-progress.is-complete { color: var(--hot); }
.lx-progress.is-complete canvas {
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--hot) 60%, transparent));
}

/* ---- 卡片 ---- */
.lx-card { padding: var(--s-5); }
.lx-card__kind {
  font: 700 var(--t-12) / 1.2 var(--f-dot);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--hot);
}
.lx-card__title { font: 600 var(--t-17) / 1.3 var(--f-ui); margin-top: var(--s-2); }
.lx-card__zh { font: 400 var(--t-13) / 1.6 var(--f-zh); color: var(--text-dim); margin-top: var(--s-1); }
.lx-card.is-ghost { background: transparent; box-shadow: none; }

/* ---- 提示 ---- */
.lx-toast {
  display: flex; align-items: baseline; gap: var(--s-3);
  background: var(--bg-2); border-radius: var(--r-1);
  box-shadow: inset 0 0 0 1px var(--line-strong);
  padding: var(--s-2) var(--s-3);
  font: 400 var(--t-13) / 1.4 var(--f-ui);
  opacity: 0; transform: translateY(var(--s-2));
  transition: opacity var(--t-mid) var(--ease), transform var(--t-mid) var(--ease);
}
.lx-toast.is-in { opacity: 1; transform: translateY(0); }
.lx-toast strong { font: 700 var(--t-12) / 1 var(--f-dot); letter-spacing: 0.1em; color: var(--text-faint); }
.lx-toast.ok strong { color: var(--ink); }
.lx-toast.err strong { color: var(--hot); }

/* ---- 点标签（状态） ---- */
.lx-dot-label {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font: 700 var(--t-12) / 1 var(--f-dot); letter-spacing: 0.12em;
  color: var(--text-dim); text-transform: uppercase;
}
.lx-dot-label::before { content: ''; width: 4px; height: 4px; border-radius: 50%; background: var(--text-faint); }
.lx-dot-label.ok::before { background: var(--ink); }
.lx-dot-label.warn::before { background: var(--hot); }
.lx-dot-label.info::before { background: var(--hot-2); }

/* ============================================================
   页面 —— 启动幕 / 登录 / 门户（布局基于上述 tokens）
   ============================================================ */

/* ---- 视图切换 ---- */
.view {
  position: fixed; inset: 0; z-index: 20;
  display: flex; flex-direction: column;
  opacity: 0; transition: opacity var(--t-slow) var(--ease);
}
.view.shown { opacity: 1; }

/* ---- 顶栏 ---- */
/* ---- 顶栏（融入背景：无底色无边线，只留排版） ---- */
.topbar {
  display: flex; justify-content: space-between; align-items: center;
  padding: var(--s-4) var(--s-7);
}
.brand { display: flex; align-items: center; gap: var(--s-3); }
.brand img { width: 42px; height: 42px; object-fit: contain; }
.brand .t1 { display: block; font: 700 var(--t-15) / 1.2 var(--f-ui); letter-spacing: 0.04em; }
.brand .t2 {
  display: block; font: 700 10px / 1.4 var(--f-dot);
  letter-spacing: 0.28em; color: var(--text-faint);
}
.who { display: flex; align-items: center; gap: var(--s-3); }
.who .name { font: 700 var(--t-12) / 1 var(--f-dot); letter-spacing: 0.1em; color: var(--text-dim); }

/* ---- 表单辅助 ---- */
.msg {
  min-height: 18px; font: 400 var(--t-13) / 1.5 var(--f-zh);
  color: var(--hot); margin: 0 0 var(--s-3);
}
.msg:not(:empty)::before {
  content: ''; display: inline-block;
  width: 5px; height: 5px; margin-right: var(--s-2); border-radius: 50%;
  background: currentColor; box-shadow: 0 0 8px currentColor;
  vertical-align: 2px;
}
.hint {
  font: 400 var(--t-12) / 1.7 var(--f-zh);
  color: var(--text-faint); margin: 0 0 var(--s-4);
}
summary { cursor: pointer; }
summary.hint { transition: color var(--t-fast); }
summary.hint:hover { color: var(--text-dim); }

/* ==================== 启动幕 ==================== */
#bootView {
  position: fixed; inset: 0; z-index: 40;
  display: flex; align-items: flex-end; justify-content: center;
  padding-bottom: 16vh;
  pointer-events: none;
  transition: opacity 0.9s var(--ease), visibility 0.9s;
}
#bootView.gone { opacity: 0; visibility: hidden; pointer-events: none; }
.boot-inner { width: min(420px, 72vw); }
.boot-inner .lx-progress { width: 100%; --progress-w: 100%; }
.boot-caption {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-top: var(--s-3);
}
.boot-slogan {
  font: 700 var(--t-12) / 1 var(--f-dot);
  letter-spacing: 0.35em; color: var(--text-dim);
  animation: sloganPulse 2.4s ease-in-out infinite;
}
@keyframes sloganPulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }
.boot-pct { font: 700 var(--t-12) / 1 var(--f-dot); letter-spacing: 0.1em; color: var(--hot); }

/* ==================== 登录视图 ==================== */
.login-stage { flex: 1; display: grid; grid-template-columns: minmax(420px, 520px) 1fr; }
.login-panel {
  position: relative;
  align-self: center; justify-self: start;
  width: min(460px, 86vw);
  margin-left: 7vw;
  padding: 38px 36px 24px;
  background:
    linear-gradient(158deg, rgb(236 231 218 / 0.055), transparent 42%),
    var(--panel);
  box-shadow:
    inset 0 0 0 1px var(--line),
    inset 0 1px 0 rgb(236 231 218 / 0.07),
    0 36px 96px rgb(0 0 0 / 0.55);
  transform: translateX(-28px); opacity: 0;
  transition: transform var(--t-slow) var(--ease) 0.15s, opacity var(--t-slow) var(--ease) 0.15s;
}
/* 右上角点阵标记：沿用背景点阵的语言，做一处不抢眼的装帧 */
.login-panel::before {
  content: '';
  position: absolute; top: 20px; right: 20px;
  width: 27px; height: 27px;
  background-image: radial-gradient(circle, var(--line-strong) 1px, transparent 1.4px);
  background-size: 9px 9px;
  opacity: 0.55; pointer-events: none;
  -webkit-mask-image: linear-gradient(135deg, transparent 18%, #000 62%);
  mask-image: linear-gradient(135deg, transparent 18%, #000 62%);
}
.login-panel::after {
  content: '';
  position: absolute; top: 40px; right: 22px;
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--hot);
  box-shadow: 0 0 9px color-mix(in srgb, var(--hot) 70%, transparent);
  opacity: 0.8; pointer-events: none;
}
.view.shown .login-panel { transform: translateX(0); opacity: 1; }
.login-panel.shake { animation: shake 0.5s; }
@keyframes shake {
  20% { transform: translateX(-9px); } 40% { transform: translateX(8px); }
  60% { transform: translateX(-5px); } 80% { transform: translateX(3px); }
}
.login-head {
  font: 700 24px / 1.25 var(--f-ui);
  letter-spacing: 0.01em;
  margin: 30px 0 var(--s-2);
}
.login-panel .lx-btn { width: 100%; }
.login-panel .lx-btn:not(.ghost) {
  letter-spacing: 0.12em;
  box-shadow: 0 10px 28px rgb(236 231 218 / 0.08);
}
.login-panel .lx-btn:not(.ghost):hover { box-shadow: 0 12px 34px rgb(236 231 218 / 0.16); }
.login-panel .lx-btn:focus-visible { outline: 2px solid var(--hot-2); outline-offset: 3px; }
.login-panel .wecom-login { margin-top: var(--s-3); letter-spacing: 0.04em; }
.login-platforms {
  display: flex; align-items: center; gap: var(--s-3);
  margin: 0 0 var(--s-6);
  font: 700 var(--t-12) / 1 var(--f-dot);
  letter-spacing: 0.3em; color: var(--hot-2);
}
.login-platforms::before {
  content: ''; flex: none;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--hot-2);
  box-shadow: 0 0 10px color-mix(in srgb, var(--hot-2) 60%, transparent);
}
/* MFA / 恢复码阶段：主标题让位给子流程标题，避免一个面板里出现两套标题 */
.login-panel:has(#loginForm.hidden) > .login-head,
.login-panel:has(#loginForm.hidden) > .login-platforms { display: none; }
.login-aux {
  display: flex; justify-content: flex-end;
  margin-top: var(--s-2);
}
.login-aux a {
  font: 400 var(--t-13) / 1.4 var(--f-zh);
  letter-spacing: 0.06em;
  color: var(--text-dim); text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 1px dotted var(--line-strong);
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.login-aux a:hover { color: var(--hot); border-bottom-color: var(--hot); }
.login-icp {
  position: relative;
  margin-top: var(--s-6);
  padding-top: var(--s-4);
  text-align: center;
  font: 400 var(--t-12) / 1.4 var(--f-zh);
  letter-spacing: 0.06em; color: var(--text-faint);
}
.login-icp::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background-image: radial-gradient(circle, var(--line-strong) 1px, transparent 1.4px);
  background-size: 9px 2px;
  opacity: 0.55;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
}
.login-icp a { color: inherit; text-decoration: none; transition: color var(--t-fast); }
.login-icp a:hover { color: var(--text-dim); }

/* ==================== 门户视图 ==================== */
.portal-stage {
  flex: 1; display: grid;
  grid-template-columns: minmax(340px, 5fr) minmax(360px, 460px);
  gap: 4vw; align-items: center;
  padding: 0 5vw 4vh;
  pointer-events: none;
}
.portal-intro, .portal-modules > * { pointer-events: auto; }

.portal-intro { position: relative; min-height: 320px; width: min(640px, 100%); }
.intro-layer {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: center; gap: var(--s-3);
  max-width: 60ch;
  opacity: 0; transform: translateY(14px);
  transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
  pointer-events: none;
}
.intro-layer.on { opacity: 1; transform: translateY(0); pointer-events: auto; }
.intro-layer .eyebrow {
  font: 700 var(--t-12) / 1.4 var(--f-dot);
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--hot);
}
.intro-layer h1 { font: 700 var(--t-40) / 1.15 var(--f-ui); margin: 0; }
.intro-layer p { font: 400 var(--t-13) / 1.8 var(--f-zh); color: var(--text-dim); max-width: 52ch; margin: 0; }
.intro-stats { display: flex; gap: var(--s-7); margin-top: var(--s-3); }
.intro-stat .num { display: block; font: 700 var(--t-28) / 1.1 var(--f-dot); }
.intro-stat .lb { font: 400 var(--t-12) / 1.4 var(--f-zh); letter-spacing: 0.2em; color: var(--text-faint); }

/* 右：三个长模块 —— Next set 卡片（常显，切换不加背景高亮） */
.portal-modules { display: flex; flex-direction: column; gap: var(--s-3); }
.next-set {
  display: grid; grid-template-columns: 44px 1fr; gap: var(--s-4);
  align-items: start;
  cursor: pointer;
  opacity: 0; transform: translateX(40px);
  transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
}
.portal-modules.enter .next-set { opacity: 1; transform: translateX(0); }
.portal-modules.enter .next-set:nth-child(1) { transition-delay: 0.15s; }
.portal-modules.enter .next-set:nth-child(2) { transition-delay: 0.30s; }
.portal-modules.enter .next-set:nth-child(3) { transition-delay: 0.45s; }
.ns-idx { font: 700 var(--t-21) / 1 var(--f-dot); color: var(--text-dim); padding-top: var(--s-1); }
.ns-main { display: flex; flex-direction: column; gap: var(--s-1); min-width: 0; }
.ns-title { color: var(--text); }
.ns-foot { display: flex; justify-content: space-between; align-items: center; margin-top: var(--s-2); gap: var(--s-3); }

/* 进入平台 —— 参考 NEXT SET 主按钮（ink 胶囊 + 点阵箭头）的卡片内小号版 */
.ns-enter { min-height: 32px; padding: 0 var(--s-4); gap: var(--s-2); font-size: var(--t-12); letter-spacing: 0.06em; }
.ns-enter .lx-icon { width: 15px; height: 15px; }
.ns-open {
  font: 700 var(--t-12) / 1 var(--f-dot); letter-spacing: 0.1em;
  color: var(--text-faint); text-decoration: none; text-transform: uppercase;
  transition: color var(--t-fast), transform var(--t-fast) var(--ease);
  white-space: nowrap;
}
a.ns-open:hover { color: var(--hot); transform: translateX(3px); }
.ns-open.disabled { pointer-events: none; color: var(--text-dim); opacity: 0.8; }

/* 点集圆环：自动切换的指示与开关（canvas 点环 + 中心代号） */
#setRing {
  position: absolute; left: 50%; bottom: 30px;
  width: 84px; height: 84px; margin-left: -42px;
  display: none; place-items: center;
  pointer-events: auto; cursor: pointer;
  opacity: 0; transition: opacity 0.8s var(--ease) 0.4s;
}
#portalView.shown #setRing { display: grid; opacity: 1; }
#setRing canvas { position: absolute; inset: 0; }
#setRing .sr-label {
  font: 700 15px / 1 var(--f-dot); letter-spacing: 0.08em;
  color: var(--text-dim); pointer-events: none; user-select: none;
}
#setRing:hover .sr-label { color: var(--text); }

/* ==================== 技术路线（瀑 × 巡） ==================== */
#techView {
  z-index: 30;
  transform: translateY(100%);
  transition: transform 0.75s var(--ease-in-out), opacity 0.55s var(--ease);
}
#techView.shown { transform: translateY(0); }
/* 进入技术路线时门户上移让位（首页仍是一页，点按钮才滑到下方） */
#portalView.pushed {
  transform: translateY(-22%);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.75s var(--ease-in-out), opacity 0.5s var(--ease);
}
.tech-top {
  position: absolute; top: 0; left: 0; right: 0; z-index: 6;
  display: flex; justify-content: space-between; align-items: center;
  padding: var(--s-4) var(--s-7);
}
.tech-heading { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.tech-heading .zh { font: 700 var(--t-17) / 1.2 var(--f-zh); letter-spacing: 0.3em; margin-left: 0.3em; }
.tech-heading .en { font: 700 10px / 1.3 var(--f-dot); letter-spacing: 0.3em; color: var(--text-faint); }
.tech-hud { display: flex; align-items: baseline; gap: var(--s-2); }
.tech-hud b { font: 700 var(--t-21) / 1 var(--f-dot); color: var(--hot); }
.tech-hud span { font: 700 var(--t-12) / 1 var(--f-dot); letter-spacing: 0.15em; color: var(--text-dim); }

.tech-labels { position: absolute; inset: 0; pointer-events: none; z-index: 4; overflow: hidden; }
.fx-label {
  position: absolute; left: 0; top: 0;
  transform: translate(-999px, -999px);
  white-space: nowrap; will-change: transform, opacity;
  text-shadow: 0 1px 10px rgb(0 0 0 / 0.9), 0 0 24px rgb(0 0 0 / 0.6);
  transition: opacity 0.2s linear;
}
.fx-label b { display: block; font: 700 13px / 1.35 var(--f-zh); color: var(--text); }
.fx-label i { display: block; font: 700 9px / 1.5 var(--f-dot); letter-spacing: 0.16em; color: var(--text-faint); font-style: normal; }
.fx-label.is-hot b { color: var(--hot); }
.fx-label.is-hot2 b { color: var(--hot-2); }
.fx-label.is-dim { filter: saturate(0.4); }

.tech-card {
  position: absolute; left: var(--s-7); bottom: 12vh; z-index: 5;
  width: min(380px, 82vw);
  transition: opacity 0.4s var(--ease), transform 0.5s var(--ease);
}
.tech-card.flat { opacity: 0; transform: translateY(14px); pointer-events: none; }
.tech-card .lx-card__rel b.hot { color: var(--hot); }
.tech-card .lx-card__rel b.hot2 { color: var(--hot-2); }
/* 瀑布总览态：全图一屏，标签收紧只留中文 */
#techLabels.fall .fx-label b { font-size: 12px; }
#techLabels.fall .fx-label i { display: none; }

.tech-tip {
  position: absolute; right: var(--s-7); bottom: 12vh; z-index: 5;
  font: 700 var(--t-12) / 1.8 var(--f-dot); letter-spacing: 0.14em;
  color: var(--text-faint); text-align: right;
}

.tech-scroll {
  position: absolute; inset: 0; z-index: 3;
  overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: none;
}
.tech-scroll::-webkit-scrollbar { display: none; }

/* ==================== 弹窗 / 提示 ==================== */
.modal-mask {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  background: rgb(3 4 5 / 0.72);
  backdrop-filter: blur(6px);
}
.modal { width: min(420px, 88vw); padding: var(--s-6); }
.modal h3 { font: 700 var(--t-21) / 1.3 var(--f-ui); margin: 0 0 var(--s-5); }
.modal .foot { display: flex; justify-content: flex-end; gap: var(--s-3); margin-top: var(--s-2); }

#toastHost {
  position: fixed; right: var(--s-5); bottom: var(--s-5); z-index: 80;
  display: flex; flex-direction: column; gap: var(--s-2);
}

/* ==================== 企微扫码视图 ====================
   iframe 尺寸由企微组件固定（small = 320×380），只能整体缩放不能拉伸；
   深色 color_scheme 生效时面板即融入夜世界，浅色兜底时则是一张白卡 */
.wecom-qr-card {
  margin: var(--s-4) auto var(--s-2);
  width: 320px; max-width: 100%;
  border-radius: var(--r-2);
  overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--line), 0 18px 48px rgb(0 0 0 / 0.45);
}
#wecomQrBox { display: flex; justify-content: center; }
#wecomQrBox iframe { display: block; border: 0; }
/* 二维码挂载前的占位（iframe 一出现即自动让位） */
#wecomQrBox:not(:has(iframe)) { height: 380px; align-items: center; }
#wecomQrBox:not(:has(iframe))::after {
  content: '正在加载二维码…';
  font: 400 var(--t-13) / 1 var(--f-zh);
  letter-spacing: 0.06em; color: var(--text-faint);
}

/* ==================== 响应式 ==================== */
@media (max-width: 1060px) {
  body { overflow: auto; }
  .login-stage { grid-template-columns: 1fr; }
  .login-panel { justify-self: center; margin: 8vh 5vw; }
  .portal-stage { grid-template-columns: 1fr; align-items: start; padding: 4vh 6vw 16vh; }
  .portal-intro { min-height: 0; width: 100%; }
  .intro-layer { position: static; display: none; }
  .intro-layer.on { display: flex; }
  .intro-layer h1 { font-size: var(--t-28); }
  .topbar { padding: var(--s-3) var(--s-4); }
  .who .name { display: none; }
  .tech-top { padding: var(--s-3) var(--s-4); }
  .tech-heading .zh { font-size: var(--t-15); letter-spacing: 0.2em; }
  .tech-heading .en { display: none; }
  .tech-card { left: var(--s-4); right: var(--s-4); bottom: 9vh; width: auto; }
  .tech-tip { display: none; }
}

/* 矮屏：收紧垂直节奏，保证登录框完整落在首屏内 */
@media (max-height: 720px) and (min-width: 1061px) {
  .login-panel { padding-top: var(--s-5); padding-bottom: var(--s-4); }
  .login-head { font-size: var(--t-21); margin-top: var(--s-5); }
  .login-panel .lx-field { margin-bottom: var(--s-4); }
  .login-icp { margin-top: var(--s-5); }
}

/* 企微扫码 iframe 定宽 320px：窄屏按档缩放（zoom 连布局一起缩，卡片随之收窄） */
@media (max-width: 460px) {
  #wecomQrBox iframe { zoom: 0.85; }
  .wecom-qr-card { width: 272px; }
}
@media (max-width: 390px) {
  #wecomQrBox iframe { zoom: 0.74; }
  .wecom-qr-card { width: 237px; }
}
@media (max-width: 340px) {
  #wecomQrBox iframe { zoom: 0.62; }
  .wecom-qr-card { width: 199px; }
}

@media (prefers-reduced-motion: reduce) {
  .grain { animation: none; }
  * { transition-duration: 0.01s !important; animation-duration: 0.01s !important; }
}
