  /* 全站字体：Lexend（可变字重 100-900） */
  @font-face {
    font-family: "Lexend";
    src: url("Lexend-VariableFont_wght.ttf") format("truetype");
    font-weight: 100 900;
    font-display: swap;
  }
  :root {
    --ink: #0a0a0a;          /* 主色。全站黑白单色：除小球外只有黑/白/灰 */
    --bg: #ffffff;
    --font: "Lexend", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Helvetica Neue", Arial, sans-serif;
  }
  * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
  html, body {
    margin: 0; padding: 0; height: 100%; overflow: hidden;
    background: var(--bg);
    font-family: var(--font);
    color: var(--ink);
    overscroll-behavior: none;
    touch-action: none;
  }
  #stage { position: fixed; inset: 0; }
  canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
  #tunnel { z-index: 0; }      /* 时空隧道背景（滚动时出现） */
  #main   { z-index: 1; }      /* 轨道 logo + 小球 */

  /* 四角字母（平面内自转）—— 压到**最底层**（在时空隧道底之上、笔触与球之下）：
     字母转到中心也不会盖住笔触；球在字母上滚动时也在字母前面。 */
  .letter {
    position: absolute; z-index: 0; left: 0; top: 0;   /* 位置由 JS 按方形角点算，这里只给基准 */
    font-weight: 500;        /* 兜底：实际每个字母的字重由 JS 设（G/D=100，L/F=500） */
    line-height: 1;
    letter-spacing: .02em;
    transform-origin: 50% 50%;
    will-change: transform;
    user-select: none;
  }
  /* 时间显示 */
  #clockWrap {
    position: absolute; left: 0; right: 0; bottom: 15vh; z-index: 3;
    display: flex; align-items: center; justify-content: center; gap: 14px;
    user-select: none;
  }
  /* 年月日 + 时分秒：一行显示，同色同字号（基础字重） */
  #clockLine {
    font-family: var(--font);
    font-size: clamp(22px, 3.6vw, 46px);
    font-weight: 400; letter-spacing: .08em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }
  button { font-family: var(--font); font-weight: 400; }   /* 按钮不会自动继承字体 */
  #nowBtn {
    /* 紧贴时间行右侧，与时间垂直居中 */
    flex: 0 0 auto;
    border: 1px solid currentColor; background: transparent; color: inherit;
    opacity: .38; cursor: pointer; border-radius: 999px;
    font-size: 10px; padding: 4px 9px; letter-spacing: .08em;
    transition: opacity .2s;
  }
  #nowBtn:hover { opacity: .85; }

  /* Ask AI */
  #askAi {
    position: absolute; z-index: 4;
    left: 50%; transform: translateX(-50%); bottom: 3.4vh;
    padding: 15px 46px; border-radius: 999px; cursor: pointer;
    border: 1px solid currentColor; background: transparent; color: inherit;
    font-size: clamp(14px, 1.6vw, 17px); font-weight: 400; letter-spacing: .16em;
    transition: transform .18s ease, background .25s, opacity .25s, visibility 0s;
  }
  #askAi:active { transform: translateX(-50%) scale(.97); }
  #askAi:hover { background: rgba(127,127,127,.10); }

  /* 时间没停稳（还在滚）或字幕已打开时隐藏。
     用 visibility 而不是单靠 opacity —— 不可见的同时也不吃点击，还能被 collectObstacles 排除掉
     （opacity:0 的元素 getBoundingClientRect() 仍有尺寸，会变成看不见的挡板把小球弹开） */
  #askAi.ask-hidden {
    opacity: 0; visibility: hidden; pointer-events: none;
    transition: transform .18s ease, background .25s, opacity .25s, visibility 0s .25s;
  }

  /* 滚动时的整体反色（由 JS 设置 intensity）—— 反成白字，仍是黑白单色 */
  body.tunnel-on { color: #ffffff; }
  @media (prefers-reduced-motion: reduce) {
    #tunnel { display: none; }
  }

  /* ============================================================
     Ask AI —— 字幕层
     全宽 · 半透明深底 · 自底部随内容增高（上限 3/4 屏）· 超出可滚
     ============================================================ */
  #subtitle {
    position: absolute; z-index: 6;
    left: 0; right: 0; bottom: 0;
    max-height: 75%;
    display: flex; flex-direction: column;
    background: rgba(0, 0, 0, .78);
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
    border-top: 1px solid rgba(255, 255, 255, .14);
    color: #fff;
    opacity: 0; visibility: hidden; transform: translateY(12px);
    transition: opacity .28s ease, transform .28s ease, visibility 0s .28s;
  }
  #subtitle:not(.sub-off) {
    opacity: 1; visibility: visible; transform: translateY(0);
    transition: opacity .28s ease, transform .28s ease, visibility 0s;
  }

  .sub-head {
    flex: 0 0 auto;
    display: flex; align-items: center; justify-content: space-between;
    padding: 9px 14px 4px 18px;
  }
  .sub-date {
    font-size: clamp(10px, 1.1vw, 12px); letter-spacing: .14em;
    color: rgba(255, 255, 255, .48);
    font-variant-numeric: tabular-nums;
  }
  .sub-close {
    flex: 0 0 auto; width: 30px; height: 30px; padding: 0;
    display: flex; align-items: center; justify-content: center;
    border: 0; border-radius: 50%; background: transparent;
    color: rgba(255, 255, 255, .6); font-size: 19px; line-height: 1; cursor: pointer;
    transition: color .2s, background .2s;
  }
  .sub-close:hover { color: #fff; background: rgba(255, 255, 255, .1); }

  /* min-height:0 是 flex 子项能被压缩、进而出现滚动条的前提 */
  .sub-body {
    flex: 1 1 auto; min-height: 0;
    overflow-y: auto; -webkit-overflow-scrolling: touch;
    padding: 4px 18px 22px;
  }
  .sub-body::-webkit-scrollbar { width: 6px; }
  .sub-body::-webkit-scrollbar-track { background: transparent; }
  .sub-body::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .22); border-radius: 3px; }

  /* 免责声明（fictitious disclaimer）：小字斜体，直接淡入、不参与打字机 */
  .sub-note {
    margin: 0 0 10px;
    font-size: clamp(11px, 1.15vw, 13px); font-style: italic; line-height: 1.5;
    color: rgba(255, 255, 255, .55);
    opacity: 0; transition: opacity .45s ease;
  }
  .sub-note.on { opacity: 1; }

  .sub-text {
    margin: 0; min-height: 1.62em;
    font-size: clamp(15px, 1.9vw, 21px); line-height: 1.62;
    color: #fff; white-space: pre-wrap; overflow-wrap: break-word;
  }

  /* 状态着色 —— 这是「全站黑白、只有小球有颜色」的明确例外：
     黄 = 被限流/太频繁（等一会儿还有救）· 红 = 故障 · 中性 = 本环境没接后端 */
  #subtitle.sub-loading .sub-text { color: rgba(255, 255, 255, .45); animation: subPulse 1.2s ease-in-out infinite; }
  #subtitle.sub-error   .sub-text { color: #ff6b6b; }
  #subtitle.sub-limited .sub-text { color: #f5c451; }
  #subtitle.sub-info    .sub-text { color: rgba(255, 255, 255, .62); }
  @keyframes subPulse { 0%, 100% { opacity: .32; } 50% { opacity: .92; } }

  /* 字幕打开时按钮整体让位（JS 也会加 .ask-hidden，这里是双保险） */
  body.subtitle-open #askAi { opacity: 0; visibility: hidden; pointer-events: none; }
