/* =========================================================================
   Killion · 品牌门户
   ---------------------------------------------------------------------
   布局（2026-09-25 用户定，第四次改版）：
     ┌──────────────────────────────────────────────────────────────────────┐
     │ ☰  Killion 字样                                 登录/昵称   中文/EN  │ ← 顶栏（通栏、吸顶）
     ├───────────────┬──────────────────────────────────────────────────────┤
     │ 账号中心       │                                                      │
     │    账号与安全  │            想象力无限                                 │
     │ 产品中心       │            生产力有限      ← 字后有柔光              │
     │    科链文件    │            请期待更多作品                              │
     │ （贴屏幕左边）  │                       © + ICP 备案号                  │
     └───────────────┴──────────────────────────────────────────────────────┘
   ⚠️ **顶栏与侧栏并存**（2026-09-25 用户明确要求）：字标回到顶栏，侧栏是它下面的一条通高左栏，
     贴屏幕左边缘 —— 别再把字标挪进侧栏（那样侧栏会变成"挂在 logo 下方的一块"）。
   侧栏**可展开收起**：☰ 按钮切换，`<html data-side="expanded|collapsed">` 是唯一状态源
   （初始化在页面 `<head>` 的内联脚本里，为了避免首屏闪一下；切换与记忆在 `assets/js/nav.js`）。
   桌面默认展开、**手机默认收起**，两端的记忆互不干扰（localStorage 里连 mode 一起存）。
   🆕 **2026-09-26：顶栏与侧栏都改成了"玻璃"（半透明 + backdrop-filter 模糊），
   并且侧栏从"占位块"改成了"浮层"** —— 用户要求"展开时不要挤压画面"：
   现在主区宽度**不随侧栏伸缩变化**，标语永远居中于整个视口；收起靠 `translateX(-100%)`（合成层，不重排）。
   ⚠️ 玻璃的透明度别往回加：以前顶栏是 `rgba(8,13,28,.74)`，那个 alpha 下 backdrop-filter 等于没生效，
   看起来就是一块实心色板。可读性靠内高光 + 1px 亮边 + 投影来兜，不靠把底色涂厚。

   其他几条容易改错的地方：
   1. 入口**只在侧栏**（顶栏与主区都不放入口按钮）。顶栏放：☰ + 字标 + 登录态 + 语言。
   2. 主区不是 logo 而是标语，那层柔光（`.hero-text::before`）是**刻意保留**的。
   3. 页脚只留 © + **ICP 备案号**（工信部要求，别删）。
   4. 术语：**账号** = `username`（登录用、唯一）；界面上的**昵称** = `user.name`。

   设计令牌与产品站 `killionfileswebsite` 保持一致（同品牌同观感）。
   ========================================================================= */

:root {
  --brand: #2f6bff;
  --brand-400: #5a93f6;
  --accent: #38e1ff;
  --grad: linear-gradient(135deg, #4f8cff 0%, #38e1ff 100%);

  --bg: #080d1c;
  --bg-2: #0b1226;
  --glow-1: rgba(47, 107, 255, .22);
  --glow-2: rgba(56, 225, 255, .14);
  --surface: rgba(255, 255, 255, .05);
  --border: rgba(255, 255, 255, .12);
  --border-strong: rgba(255, 255, 255, .22);
  --text: #eaf0ff;
  --text-2: #9fb0cf;
  --text-3: #6f80a3;

  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "PingFang SC", "Microsoft YaHei", "Hiragino Sans GB", sans-serif;
  --topbar-h: 64px;
  --side-w: 264px;
  --side-pad: 16px;
  --t: .28s cubic-bezier(.22, .61, .36, 1);
  color-scheme: dark;
}

* , *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font-sans);
  color: var(--text);
  background: var(--bg);
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
}
/* 背景三层：两团径向辉光 + 竖向渐变（与产品站同一配方） */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -1;
  background:
    radial-gradient(60vw 60vw at 76% -10%, var(--glow-1), transparent 60%),
    radial-gradient(46vw 46vw at 8% 6%, var(--glow-2), transparent 55%),
    linear-gradient(180deg, var(--bg) 0%, var(--bg-2) 100%);
}
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }
[hidden] { display: none !important; }

/* -------------------------- 浮动按钮条（原"顶栏"） -------------------------- */
/* 2026-09-26 用户拍板"直接不要顶部栏了"→ 这一层已经**没有任何"栏"的痕迹**：
   没有背景、没有模糊、没有边框、没有投影，可见的只有 ☰ / 字标（左）与 登录 / 语言（右）。
   ⚠️ 关键改动是 **`absolute` 而不是 `sticky`**：
     · `sticky` 会让这 64px 永远压在画面上，将来页面一旦变成多屏、内容从它底下滚过去，
       文字就会与内容叠在一起（用户明确提到担心这一点）；
     · `absolute` 让它跟着文档走，单屏时就在顶部，页面变长时直接滚出视口 —— 结构上不可能重叠。
   ⚠️ `pointer-events: none` + 子元素 `auto` 不能省：容器是透明的，但它仍会盖住
     所在区域的点击（尤其左上角会压住侧栏玻璃的顶部），必须让事件透过去。
   结构上保留 `<header class="topbar">` 是为了少改 HTML/JS（`auth.js` 找 `[data-auth]`、
   `nav.js` 找 `[data-side-toggle]`），它现在只承担"浮动按钮容器"的角色。 */
.topbar {
  position: absolute; top: 0; left: 0; right: 0; z-index: 20;
  display: flex; align-items: center; gap: 12px;
  height: var(--topbar-h); padding-inline: 18px;
  pointer-events: none;
}
.topbar > * { pointer-events: auto; }
/* 侧栏开关：移动端是主要入口，桌面上也留着（用户要求"可以展开收起"） */
.side-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: none;
  border: 1px solid transparent; border-radius: 10px;
  background: transparent; color: var(--text-2); cursor: pointer; transition: var(--t);
}
.side-toggle:hover { background: var(--surface); border-color: var(--border); color: var(--text); }
.side-toggle svg { width: 18px; height: 18px; }
/* h1 只是语义标签（首页标题 = 品牌名），外观完全复用 .brand，所以把 h1 的默认样式清掉 */
h1.brand-h1 { margin: 0; font: inherit; display: inline-flex; align-items: center; }
.brand { display: inline-flex; align-items: center; }
/* 字标是 3.57:1 的横长形状，按宽度定尺寸、高度自适应 */
.brand img { width: 68px; height: auto; opacity: .94; transition: var(--t); }
.brand:hover img { opacity: 1; }
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 6px; font-size: 14px; }
.topbar-right > a { padding: 8px 14px; border-radius: 999px; color: var(--text-3); transition: var(--t); }
.topbar-right > a:hover { color: var(--brand-400); background: var(--surface); }

/* --------------------------- 顶栏登录态（登录 / 昵称） --------------------------- */
/* 默认渲染「登录」链接，`assets/js/auth.js` 取到会话后换成昵称；未登录或取不到会话就保持原样。 */
.auth { display: flex; align-items: center; }
.auth-signin { padding: 8px 14px; border-radius: 999px; color: var(--text-2); transition: var(--t); }
.auth-signin:hover { color: var(--brand-400); background: var(--surface); }
.auth-user { position: relative; }
.auth-name {
  display: inline-flex; align-items: center; gap: 6px;
  max-width: 12em; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  padding: 8px 14px; border: 1px solid transparent; border-radius: 999px;
  background: transparent; color: var(--text);
  font: inherit; font-size: 14px; font-weight: 600; cursor: pointer; transition: var(--t);
}
.auth-name:hover { background: var(--surface); border-color: var(--border); }
/* 「鼠标放上去不动」就出现退出登录：纯 CSS 悬停 + 键盘 focus 同样可见 */
.auth-menu {
  position: absolute; right: 0; top: calc(100% + 6px); min-width: 150px; padding: 6px;
  border: 1px solid var(--border); border-radius: 12px;
  background: rgba(11, 18, 38, .96);
  box-shadow: 0 18px 44px -20px rgba(0, 0, 0, .95);
  opacity: 0; visibility: hidden; transform: translateY(-4px);
  transition: opacity .18s ease, transform .18s ease, visibility .18s;
  z-index: 30;
}
.auth-user:hover .auth-menu,
.auth-user:focus-within .auth-menu { opacity: 1; visibility: visible; transform: none; }
.auth-signout {
  display: block; width: 100%; padding: 9px 12px; text-align: left;
  border: 0; border-radius: 8px; background: transparent;
  color: var(--text-2); font: inherit; font-size: 13px; cursor: pointer; transition: var(--t);
}
.auth-signout:hover { background: var(--surface); color: var(--text); }
.auth-signout[disabled] { opacity: .6; cursor: default; }

/* ------------------------- 外壳：左侧栏 + 右内容列 ------------------------- */
.shell { flex: 1; display: flex; min-height: 0; }
.content { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* ------------------------------- 侧栏 -------------------------------- */
/* 2026-09-26：从"占位的 flex 子项"改成**浮在主区之上的玻璃板**。
   两条要求一起满足：① 玻璃质感（半透明 + 模糊，能看到背后的星云透过来）；
   ② **展开时不挤压画面** —— 主区宽度不再随侧栏伸缩而重排，标语永远居中于整个视口。
   ⚠️ 收起用 `transform: translateX(-100%)` 而不是 `width: 0`：
      width 动画会触发主区每帧重排（画面会跟着抖），transform 只走合成层。 */
.side {
  position: fixed; z-index: 15;
  /* 从**视口顶端**开始（原来是从顶栏下沿 64px 处开始）—— 顶栏已经不再占位了，
     玻璃板现在是一整条从顶到底，不再有一道"上边缘"。顶部留出的那 64px 是给
     ☰ 与字标的（它们 z-index 更高，浮在这块玻璃上）。 */
  top: 0; left: 0; bottom: 0;
  width: var(--side-w);
  padding: calc(var(--topbar-h) + 6px) var(--side-pad) 24px;
  border-right: 1px solid rgba(255, 255, 255, .10);
  background: rgba(9, 14, 28, .17);
  background-image: linear-gradient(180deg, rgba(255, 255, 255, .04), rgba(255, 255, 255, 0) 45%);
  -webkit-backdrop-filter: blur(9px) saturate(165%); backdrop-filter: blur(9px) saturate(165%);
  box-shadow: 18px 0 44px -30px rgba(0, 0, 0, .95);
  overflow: hidden;
  transition: transform .3s cubic-bezier(.22, .61, .36, 1), opacity .24s ease;
}
.side-nav { width: calc(var(--side-w) - 2 * var(--side-pad)); display: flex; flex-direction: column; gap: 2px; }
[data-side="collapsed"] .side {
  transform: translateX(-100%); opacity: 0;
  pointer-events: none;            /* 滑出去之后别还挡着主区 —— 收起时它压在画面左侧 */
}

/* 大标题：分组标题，**不可点**（账号中心 / 产品中心） */
.side-head {
  display: block; padding: 11px 14px; border-radius: 12px;
  font-size: 19px; font-weight: 600; letter-spacing: .01em;
  color: var(--text-2); cursor: default;
}
/* 小标题：缩进 + 左侧竖线，挂在所属大标题下面，可点 */
.side-sub {
  display: block; margin: 2px 0 2px 15px; padding: 9px 14px;
  border-left: 1px solid var(--border); border-radius: 0 10px 10px 0;
  font-size: 15px; color: var(--text-2); transition: var(--t);
}
.side-sub:hover {
  color: var(--brand-400); border-left-color: var(--brand-400);
  background: var(--surface); transform: translateX(2px);
}

/* ------------------------------- 主区 -------------------------------- */
.main {
  position: relative;                 /* 装饰层以它为定位基准 */
  flex: 1;
  display: flex; align-items: center; justify-content: center;
  padding: 24px 24px 48px;
}

/* ===================== 主区装饰层（没有宣传图/视频，用它撑画面） =====================
   2026-09-26 整层换过一版：**旧的「网格 + 虚线环 + 节点网络」已删**。当时诊断出的三条病根：
     · 全是"线"没有"光"（网格 10%、连线峰值 26%），整屏灰蒙蒙一层，像一张工程图纸；
     · 网格 + 虚线圆环是模板级套路，且环 140s 转一圈肉眼几乎看不出动，实际等于一张静态图；
     · 直线网格 / 圆弧 / 随机噪点三种几何语言互相抢，没有视觉中心，读起来"碎"。
   现在是**星云隧道**：几万颗真星星贴着一条隧道壁排布、向深处的黑洞汇聚（WebGL 点精灵）。
   三层，从下到上：

     ① .stage-blackhole canvas：**星云隧道**（WebGL 点精灵，assets/js/scene-blackhole.js）
     ② .stage-scrim     半透明黑遮罩：压低背景亮度，保证前景文字可读
     ③ .stage-grain     颗粒噪点（静态，压在最上层）

   2026-09-26 试过的候选（极光层 `.stage-aurora`、光链 `.stage-stream`、星云宇宙 `.stage-cosmos`、
   星系团 `.stage-galaxy`）与对比页 `scene-lab.html` **已按用户要求全部删除**。
   想回顾它们的做法与"为什么被否"，看 README「设计约定」第 7 条那张版本表 —— 别再重新发明一遍。

   三条硬约束（改之前先读，理由都在 README「设计约定」第 7 条）：
     · **纯装饰**：整层 `aria-hidden` + `pointer-events:none`，不进无障碍树、不挡任何点击；
     · **不抢主角**：动效只碰 transform / opacity，线上的 alpha ≤ .09，主角始终是标语（`.hero-text` 有 z-index:1）；
     · **可关**：`prefers-reduced-motion: reduce` 时动画全停（CSS 走文件末尾那条全局规则，
       canvas 在脚本里自己判断），退化成一幅**静态图案**。
       ⚠️ 连带要求：每层"静止时"的样子必须本身就好看 —— CSS 动画的 `0% / 100%` 那一帧
       就是 reduced-motion 下用户看到的画面，别把好看的那一帧只放在动画中间。
   ================================================================================ */
/* ⚠️ `fixed` 而不是 `absolute`：装饰层要**铺满整个视口**，而不是只铺主区。
   顶栏改成全透明之后，如果它还是 `absolute inset:0`（包含块是 `.main`），
   星空就会从顶栏下沿才开始画 —— 屏幕上会露出一条清清楚楚的水平边界，
   看起来像画面被切了一刀。铺满之后，顶栏那几样文字是直接浮在星云上的。 */
.stage {
  position: fixed; inset: 0; overflow: hidden;
  pointer-events: none;
}
/* ---- ① canvas 画面（星云隧道）---- */
.stage-blackhole {
  position: absolute; inset: 0; width: 100%; height: 100%;
  /* **没有 WebGL 时的退路**：脚本取不到 context 就什么都不画，这里垫一条深空渐变，
     用户看到的至少是一块干净的夜空 —— 绝不能白屏。 */
  background: radial-gradient(120% 100% at 50% 50%, #0a1020 0%, #04060d 70%);
}

/* ---- ② 遮罩层：压在画面之上、文字之下（`.hero-text` 有 z-index:1，永远在它上面）----
   ⚠️ 这个数值与"底图有多亮"绑定，**不能照抄**：明亮的背景视频按用户要求给 `rgba(0,0,0,.6)`，
   而这段隧道画面本身就极暗，真给 .6 会把星云整个吃掉 —— 所以这里用 .30。
   单独留一层的好处就是随时能调、不需要动画面本身。 */
.stage-scrim { position: absolute; inset: 0; background: rgba(0, 0, 0, .30); }

/* ---- ③ 颗粒噪点：压在最上层，消掉大面积渐变的色带（banding）与"塑料感" -------------
   静态图层（不做动画）：一次合成，不占 canvas 那 30fps 的预算。
   ⚠️ data-URI 里的 `#` 必须写成 %23，否则整条声明作废（也看不出报错，只是颗粒莫名不出现）。 */
.stage-grain {
  position: absolute; inset: 0;
  /* 颗粒要"粗"一点才管用：160px 的 tile 在 1440px 宽下每像素颗粒被平均掉了，
     压不住大渐变里的色带（截图实测：深色区域仍能看到横向条纹）。200px 刚好。 */
  opacity: .065;
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 200px 200px;
}

.hero-text {
  position: relative; z-index: 1;      /* 标语永远在装饰层上面 */
  text-align: center;
  animation: rise .7s cubic-bezier(.22, .61, .36, 1) both;
}
/* 文字后的柔光：没有宣传图，靠它把字托起来（用户明确要求保留；2026-09-26 加了"呼吸"）
   ⚠️ 基准态就是"满"的那一帧（opacity:1）：reduced-motion 关掉动画后停在这里，
     所以别把 0% 写成接近透明的值 —— 那样开"减少动态效果"的用户会看到一团几乎不存在的柔光。 */
.hero-text::before {
  content: ""; position: absolute; inset: -70% -14%; z-index: -1;
  background: radial-gradient(closest-side, rgba(79, 140, 255, .30), transparent 70%);
  filter: blur(10px);
  animation: halo-breathe 8s ease-in-out infinite;
}
@keyframes halo-breathe {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: .76; transform: scale(1.05); }
}
.hero-text .line {
  margin: 0;
  font-size: clamp(26px, 4.4vw, 52px); font-weight: 700;
  line-height: 1.3; letter-spacing: .02em;
  background: linear-gradient(180deg, #ffffff 0%, #c9dbff 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 10px 30px rgba(47, 107, 255, .38));
}
.hero-text .line-sub {
  margin-top: 20px;
  font-size: clamp(15px, 1.9vw, 20px); font-weight: 500;
  letter-spacing: .08em; color: var(--text-2);
}
/* 门户首页的说明段（2026-09-29 加）：唯一作用是给搜索引擎一句"这一页讲什么"。
   刻意小字号 + 淡色 —— 不抢标语的主角地位，也不改变"主区只有标语"的观感。
   移动端跟着 clamp 缩，别单独加媒体查询。 */
.hero-text .intro-text {
  margin: 26px auto 0;
  max-width: 32em;
  font-size: clamp(13px, 1.15vw, 15px);
  line-height: 1.85;
  letter-spacing: .02em;
  color: var(--text-3);
  text-wrap: pretty;
}

@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

/* ------------------------------- 页脚 -------------------------------- */
/* ⚠️ `position: relative` 不能删：装饰层 `.stage` 改成了 `fixed`（铺满视口），
   而**定位元素会盖住无定位的块级元素** —— 页脚不写成 relative 就会整块被星空压住、看不见。 */
.footer {
  position: relative;
  display: flex; flex-wrap: wrap; gap: 8px 20px; align-items: center; justify-content: center;
  padding: 20px; font-size: 12px; color: var(--text-3);
}
.footer a { color: var(--text-3); transition: var(--t); }
.footer a:hover { color: var(--text-2); }

/* --------------------------- 内容页（关于本站） ---------------------------
   与主区不同：顶部对齐、限制行宽、可滚动。
   ⚠️ 左侧必须留出 `--side-w`：侧栏是**浮层**（fixed），不留的话在 1024px 这类宽度上
   正文会被那块玻璃板盖住（主区因为标语居中，天然不会撞上）。 */
.about {
  flex: 1;
  padding: calc(var(--topbar-h) + 24px) 24px 48px calc(var(--side-w) + 24px);
}
.about-inner { max-width: 44em; }
.about h1 { margin: 0 0 16px; font-size: clamp(22px, 2.6vw, 28px); letter-spacing: .01em; }
.about h2 { margin: 30px 0 12px; font-size: clamp(16px, 1.8vw, 19px); color: var(--text); }
.about p { margin: 0 0 14px; font-size: 15px; line-height: 1.95; color: var(--text-2); }
.about ul { margin: 0 0 14px; padding-left: 20px; }
.about li { margin-bottom: 8px; font-size: 15px; line-height: 1.85; color: var(--text-2); }
.about a { color: var(--brand-400); }
.about a:hover { text-decoration: underline; }

/* ---------------- 窄屏：侧栏仍是浮层，只是窄一点（从左侧滑入） ---------------- */
@media (max-width: 760px) {
  /* 手机 GPU 弱，而 backdrop-filter 要**每帧重新模糊背后的 WebGL 画面** ——
     半径从 20/24 降到 14/16，视觉上几乎看不出，代价省一半。 */
  .side {
    width: min(78vw, 300px);
    /* 顶部同样留出 ☰ / 字标 的位置（侧栏现在是贴顶的） */
    padding: calc(var(--topbar-h) + 4px) var(--side-pad) 20px;
    -webkit-backdrop-filter: blur(8px) saturate(150%); backdrop-filter: blur(8px) saturate(150%);
  }
  .side-nav { width: auto; }
  .side-head { font-size: 17px; padding: 9px 12px; }
  .side-sub { margin-left: 13px; }
  .brand img { width: 58px; }
  .main { padding: 40px 20px 56px; }
  /* 手机上颗粒细一档（移动 GPU 与桌面差一个量级；粒子数是脚本里按屏宽减半的） */
  .stage-grain { background-size: 150px 150px; opacity: .055; }
}

@media (prefers-reduced-motion: reduce) {
  * , *::before, *::after { animation: none !important; transition: none !important; }
}
