/* ============================================================
 *  public/styles.css —— 页面样式与 CSS 动画
 * ============================================================
 *
 *  作用：
 *    1. 重置默认样式，把页面变成"满屏黑底无滚动条"的画布
 *    2. 让 <canvas id="bg"> 充满全屏作为背景层
 *    3. 让 .content 区域居中显示文字
 *    4. 用纯 CSS 实现三种动画：彩虹流光、字符浮动、文字淡入
 *
 *  与其他文件的关系：
 *    - 所有选择器对应的元素由 public/index.html 提供
 *    - 本文件只决定"长什么样"，不决定"做什么" —— 交互逻辑全部在 public/script.js
 *
 *  阅读顺序建议：先看顶部的"重置 + 全局"，再看 .title 的彩虹效果，
 *  最后看底部的 @keyframes 关键帧定义。
 * ============================================================ */


/* ─── 全局重置 ──────────────────────────────────────────────
 * "通配选择器 *" 匹配文档中每一个元素。
 * 浏览器默认会给某些元素（body / h1 / p ...）加上 margin 和 padding，
 * 在做精细布局时这些默认值常常带来意想不到的偏移，于是约定俗成的做法
 * 是一进文件就先"归零"。
 *
 * box-sizing: border-box  表示"width/height 包含 padding 和 border"，
 * 这样设置 width:100% 时不会因为有 padding 就溢出父容器 —— 强烈推荐。
 * ──────────────────────────────────────────────────────────── */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* ─── 根元素与 body：占满视口、禁滚动、定基色 ────────────────
 * width/height: 100% 配合 overflow: hidden 共同作用：
 *   - 页面绝对不会出现滚动条（背景动画不该被滚走）
 *   - 子元素的 100vh / 100% 才能正确生效
 *
 * background 用很深的蓝紫色做兜底色，万一 canvas 还没绘制完，
 * 用户也不会看到一闪而过的白屏（白屏 = 体验差）。
 *
 * font-family 列表是"字体回退栈"：
 *   浏览器从左到右依次尝试，找到一个用户系统里安装的就用它。
 *   -apple-system / BlinkMacSystemFont   → macOS / iOS 的系统字体
 *   "Segoe UI"                            → Windows 的系统字体
 *   "PingFang SC" / "Hiragino Sans GB"    → macOS 中文字体
 *   "Microsoft YaHei"                     → Windows 中文字体（微软雅黑）
 *   sans-serif                            → 最后兜底：任意无衬线字体
 * ──────────────────────────────────────────────────────────── */
html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #05060f;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
    "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  color: #fff;
}

/* ─── WebGL 背景画布 ─────────────────────────────────────────
 * Three.js 的 WebGLRenderer 会通过 renderer.setSize() 设置
 * canvas 的 width / height（物理像素）和 style.width / style.height（CSS 像素）。
 * 我们只需要把它用 position:fixed 固定在视口左上角，其余尺寸交给 Three.js。
 *
 * 不再写 width:100%; height:100%，避免与 Three.js 的内联样式冲突
 *（内联样式优先级高于外部 CSS，会覆盖掉 100% 的声明）。
 * ──────────────────────────────────────────────────────────── */
#bg {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 0;
  display: block;
}

/* ─── CSS 暗角遮罩 ────────────────────────────────────────────
 * 用纯 CSS 径向渐变实现四角压暗效果。
 * 之所以不在 WebGL 里实现：
 *   1. 避免 UnrealBloomPass 把暗角边缘也算入泛光计算，造成奇怪的光晕
 *   2. CSS 层实现零开销，不消耗 GPU 帧时间
 *
 * z-index 与 canvas 同为 0，但在 DOM 中排在 canvas 之后，
 * 因此浏览器会把它渲染在 canvas 之上、文字层（z-index:1）之下。
 *
 * pointer-events: none 使其不拦截任何鼠标/触摸事件。
 * ──────────────────────────────────────────────────────────── */
#vignette {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(
    ellipse at 50% 55%,
    transparent 20%,
    rgba(0, 0, 0, 0.70) 100%
  );
}

/* ─── 内容容器：Flex 居中 ────────────────────────────────────
 * 经典的"全屏居中"技巧：
 *   display: flex + flex-direction: column   → 子元素纵向排列
 *   justify-content: center                  → 主轴（纵向）居中
 *   align-items: center                      → 交叉轴（横向）居中
 *
 * 100vh 表示"视口高度的 100%"。在移动端，
 * 部分浏览器的"地址栏"会动态出现/消失导致 100vh 跳变；
 * 如果未来需要更严格的体验，可以改用 100svh / 100dvh。
 *
 * user-select: none + pointer-events: none：
 *   让这一整层"穿透"鼠标事件 —— 点击/拖选都会落到底下的 canvas，
 *   于是 script.js 里的 mousemove 监听才能拿到全屏范围的坐标。
 * ──────────────────────────────────────────────────────────── */
.content {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 24px;
  user-select: none;
  pointer-events: none;
}

/* ─── 主标题：彩虹渐变 + 流光 ────────────────────────────────
 * 这是整页视觉的"主角"。技术要点：
 *
 * 1) clamp(min, preferred, max)
 *    响应式字号的标准做法 —— "最小 64px、偏好 14vw（视口宽度的 14%）、
 *    最大 180px"。这样在小手机上不会过大、在大屏上也不会无限放大。
 *
 * 2) background + background-clip: text + text-fill-color: transparent
 *    这是"让文字内部显示渐变"的经典三件套：
 *      - 先给元素铺一层彩色渐变背景
 *      - background-clip: text 把"背景"剪裁成"文字形状"
 *      - text-fill-color: transparent 把原本的文字颜色变透明，
 *        于是看到的就是被剪裁出来的渐变。
 *    -webkit- 前缀仍需保留，以兼容部分 Safari / iOS 旧版本。
 *
 * 3) background-size: 300% 100% + animation
 *    让渐变背景"超出"文字宽度 3 倍，然后用 keyframes 平移 background-position，
 *    就形成了"颜色从左往右无限流动"的效果（见底部 @keyframes shine）。
 *
 * 4) filter: drop-shadow(...)
 *    给文字加一圈紫色发光晕。注意是 drop-shadow 而不是 box-shadow ——
 *    drop-shadow 会"沿着文字形状"投影，而 box-shadow 只会沿矩形边框。
 * ──────────────────────────────────────────────────────────── */
.title {
  font-size: clamp(64px, 14vw, 180px);
  font-weight: 800;
  letter-spacing: 0.08em;
  line-height: 1;
  background: linear-gradient(
    90deg,
    #ff6b9d 0%,    /* 粉 */
    #c66bff 25%,   /* 紫 */
    #6bb8ff 50%,   /* 蓝 */
    #6bffd1 75%,   /* 薄荷 */
    #ffe46b 100%   /* 鹅黄 */
  );
  background-size: 300% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: shine 8s linear infinite;
  filter: drop-shadow(0 0 40px rgba(198, 107, 255, 0.35));
}

/* ─── 字符浮动：每个字母错峰起伏 ─────────────────────────────
 * inline-block 让 <span> 既能保持"在一行内"，又能接受 transform。
 * 注意：纯 inline 元素（默认）是无法应用 transform 的。
 *
 * 接下来的 5 条 :nth-child(N) 给每个字母分别指定 animation-delay，
 * 相邻字母相差 0.2s，于是 5 个字母构成"波浪"般的错位效果。
 * 如果未来主标题改字数，记得同步调整这些 nth-child 数量。
 * ──────────────────────────────────────────────────────────── */
.title span {
  display: inline-block;
  animation: float 4s ease-in-out infinite;
}
.title span:nth-child(1) { animation-delay: 0s; }
.title span:nth-child(2) { animation-delay: 0.2s; }
.title span:nth-child(3) { animation-delay: 0.4s; }
.title span:nth-child(4) { animation-delay: 0.6s; }
.title span:nth-child(5) { animation-delay: 0.8s; }

/* ─── 关键帧：彩虹流光 ──────────────────────────────────────
 * "把渐变背景从 0% 平移到 300%"。因为 background-size 设成了 300%，
 * 移动 300% 刚好回到起点，所以衔接处看不出"跳变"，无限循环顺滑流动。
 * 用 linear（匀速）而不是 ease，是为了让颜色流动节奏稳定不忽快忽慢。
 * ──────────────────────────────────────────────────────────── */
@keyframes shine {
  0%   { background-position: 0% 50%; }
  100% { background-position: 300% 50%; }
}

/* ─── 关键帧：上下浮动 ─────────────────────────────────────
 * 0% 和 100% 都保持原位、50% 抬高 10px —— 一个完整的"上 → 下"循环。
 * ease-in-out 让起止平滑、中段加速，营造"呼吸感"。
 * ──────────────────────────────────────────────────────────── */
@keyframes float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}

/* ─── 副标题：渐入 ──────────────────────────────────────────
 * font-weight: 300 表示 Light（细体）—— 视觉上比标题更"轻"，
 * 营造主次对比。
 *
 * opacity: 0 + animation: ... forwards 是"页面加载时淡入一次"的标准写法：
 *   - 初始透明
 *   - animation 把它过渡到不透明
 *   - forwards 表示"动画结束后保持最后一帧"，否则会跳回 opacity:0
 *   - 延迟 0.4s 是为了让标题先出现，再依次出现副标题（参见下方的 .line / .meta 延迟）
 * ──────────────────────────────────────────────────────────── */
.subtitle {
  margin-top: 28px;
  font-size: clamp(14px, 1.8vw, 18px);
  color: rgba(255, 255, 255, 0.78);
  letter-spacing: 0.12em;
  font-weight: 300;
  opacity: 0;
  animation: fadeUp 1.6s 0.4s ease forwards;
}

/* ─── 装饰横线 ───────────────────────────────────────────────
 * width: 80px / height: 1px 让它非常细窄；
 * 用 linear-gradient(透明 → 白半透明 → 透明) 做"两端淡出"的丝带感。
 * 比 <hr> 或 border-bottom 更可控，因为可以精确控制两端的透明度。
 * ──────────────────────────────────────────────────────────── */
.line {
  margin-top: 32px;
  width: 80px;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.6), transparent);
  opacity: 0;
  animation: fadeUp 1.6s 0.8s ease forwards;
}

/* ─── 页脚：ICP 备案 + 投诉邮箱 ─────────────────────────────────
 * 放在页面最底部、content 容器的最末尾。
 * 因为 .content 是 flex column + justify-content: center，
 * 给 footer 设 margin-top: auto 可以让它在剩余空间被"推"到底部，
 * 同时不影响标题/副标题/横线的居中位置。
 *
 * 注意：footer 是 <main> 的最后一个子元素。
 * .content 默认 pointer-events: none（穿透鼠标），
 * 但备案链接和邮箱链接需要能点击，所以在 a 标签上单独恢复
 * pointer-events: auto。
 * ──────────────────────────────────────────────────────────── */
.site-footer {
  margin-top: auto;
  padding-bottom: 16px;
  text-align: center;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.3);
  letter-spacing: 0.06em;
  opacity: 0;
  animation: fadeUp 1.6s 1.6s ease forwards;
}

/* 备案号行：纯展示文字 + 微弱的竖线分隔 */
.site-footer .icp {
  margin: 0;
}

.site-footer .icp-sep {
  display: none;
}

/* 邮箱链接：比备案号略亮一点，hover 时提亮并拉近视觉焦点 */
.site-footer .contact-email {
  margin: 6px 0 0;
}

.site-footer .contact-email a {
  color: rgba(255, 255, 255, 0.4);
  text-decoration: none;
  pointer-events: auto;                /* 穿透 .content 的 pointer-events: none */
  transition: color 0.3s ease;
}

.site-footer .contact-email a:hover {
  color: rgba(255, 255, 255, 0.75);
  text-decoration: underline;
}

/* ─── 关键帧：淡入并轻微上移 ─────────────────────────────────
 * 比单纯 fade-in 多了一点点 translateY(12px → 0)，
 * 让元素"从下方升起"，是当下流行的入场动效。
 * 三处使用（subtitle 0.4s / line 0.8s / meta 1.2s）的延迟差是 0.4s，
 * 形成"上中下依次冒头"的节奏感。
 * ──────────────────────────────────────────────────────────── */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
