
#title-screen {
  position: relative; /* 这是一个标准的、随页面滚动的块 */
  height: 100vh;      /* 关键：让它占据整个第一屏 */
  width: 100%;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: #fff;
  z-index: 60; /* 确保它在最前面 */
}

#title-screen .title-content {
  max-width: min(60ch, 90vw); /* 限制文本宽度 */
  opacity: 0.9;
}

#title-screen h1 {
  /* 适配不同屏幕的响应式字体 */
  font-size: clamp(2.5rem, 6vw, 3.8rem); 
  font-weight: 700;
  margin-bottom: 0.5em;
  color: #fff;
  /* 使用和你正文一致的字体，保持风格统一 */
  font-family: Georgia, 'Times New Roman', Times, serif; 
}

#title-screen p {
  font-size: clamp(1.1rem, 2.5vw, 1.25rem);
  font-family: sans-serif; /* 副标题用一个干净的无衬线字体 */
  color: #ccc;
  line-height: 1.6;
  font-style: italic; /* 匹配 "—" 的风格 */
}

#title-scroll-cue {
  position: absolute;
  bottom: 6vh;             /* 距离底部 6% 屏高 */
  left: 50%;
  transform: translateX(-50%);
  color: #fff;
  text-align: center;
  font-size: 16px;
  line-height: 1.3;
  opacity: 0.85;
  animation: cueBlink 1.2s ease-in-out infinite;
  z-index: 20;             /* 保证在标题文字之上 */
}

.highlight-yellow {
  color: #ffaa00; /* 一个醒目的黄色 */
}

.highlight-red {
  color: #df0c0c; 
}

html, body {
  margin: 0;
  padding: 0;
  background: #000;  /* 让背景彻底黑 */
}

/* ============ Intro Scrollytelling (before globe) ============ */
:root{
  --planeW: 120px;     /* 飞机尺寸 */
  --contrailW: 10px;   /* 尾迹宽度（更细） */
}

#title-screen p.byline {
  margin-top: 1.5rem;
  
  font-family: Georgia, 'Times New Roman', Times, serif; 
  
  /* 为了保险，这里加个 !important 强制生效，并改得更小一点 */
  font-size: 1.0rem !important;  
  
  color: #ccc;
  font-style: italic;
  text-transform: none;
  letter-spacing: normal;
  opacity: 0.9;
}

#title-screen p.byline a {
  color: #ffffff;             /* 名字由灰色改为纯白，显眼一点 */
  text-decoration: underline; /* 加回下划线，这是一眼识别链接的关键 */
  text-underline-offset: 4px; /* 让下划线离文字稍微远一点点，更有呼吸感 */
  text-decoration-thickness: 1px; /* 下划线细一点，保持精致 */
  cursor: pointer;
  transition: all 0.2s ease;
}

/* 2. 鼠标悬停样式：变黄 */
#title-screen p.byline a:hover {
  color: #ffaa00;             /* 悬停时变成你主题的高亮黄色 */
  text-decoration-color: #ffaa00; /* 下划线也跟着变黄 */
  opacity: 1;
}

.intro{
  position: relative;
  background: #000;
}
.intro-scene{
  position: sticky; top:0; left:0; right:0;
  height: 100vh;
  overflow: hidden;
  background: #000;
  z-index: 20;
  pointer-events: none;
}

/* 像素感 */
.px{ image-rendering: pixelated; image-rendering: crisp-edges; }

/* ── 飞机 / 尾迹（尾迹在飞机上方，不再遮飞机） ───────────────── */
/* 整机容器：做动画、统一定位 */

/* 飞机：贴容器底部，宽度用变量控制 */
#aircraft .plane{
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  width: var(--planeW);
  height: auto;
  filter: drop-shadow(0 2px 0 rgba(255,255,255,.25));
  z-index: 3;
}

/* 尾流：底边贴在“飞机顶边”（= 容器顶边），向上延伸 */
#aircraft .contrail{
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 100%;                      /* 关键：贴到容器顶边 */
  width: var(--contrailW);
  opacity: .95;
  z-index: 2;                        /* 尾流在飞机后面；想要在前面就改为 3 */
  image-rendering: pixelated;
}


/* ── 山：强制贴底 ──────────────────────────────────────────── */
.mountain{
  position: absolute;
  left: 50%; bottom: 0 !important; top: auto !important;
  transform: translateX(-50%) translateY(0);
  width: 120vw; height: auto;
  z-index: 1;
  pointer-events: none;
}

/* ── 云：不再用 CSS 动画，改为 JS 驱动的滚动视差 ─────────────── */
.cloud{
  position: absolute;
  width: 140px; height: auto;
  will-change: transform;
  z-index: 2;
}
/* 仅定义初始位置（具体移动由 JS translateY 控制） */
.cloud.c1{ left: 15%; top: 65%; width: 140px; }
.cloud.c2{ left: 60%; top: 72%; width: 150px; }
.cloud.c3{ left: 78%; top: 58%; width: 110px; }

/* ── 左侧时间轴 / 对话气泡（带尖角） ─────────────────────────── */
.timeline{
  position: absolute; left:24px; top:72px; width:280px;
  color:#eee; font-size:14px; line-height:1.35; z-index: 8;
}
.timeline .row{ display:flex; gap:8px; align-items:flex-start; margin:8px 0; }
.timeline .t{ color:#aeb6c2; min-width:96px; font-variant-numeric: tabular-nums; }
.timeline .msg{ color:#fff; }
.timeline .egpws{ color:#ffd37a; }
.timeline .dim{ opacity:.5; }

.speaker-icon {
  display: inline-block; /* 允许 transform */
  margin-left: 8px;
  cursor: pointer;
  transition: transform 0.1s ease;
}
.speaker-icon:hover {
  transform: scale(1.2);
}
.speaker-icon:active {
  transform: scale(1.05);
}

#timeline-cue {
  position: absolute;
  /* * 定位: 
   * 时间轴在 left: 24px, width: 280px。
   * 我们把它放在 24 + 280 = 304px 的右侧。
   */
  left: 345px;
  /* * 大约在 EGPWS 警告行的高度。
   * 你可以微调这个 top 值来精确对齐。
   */
  top: 120px;

  color: #fff;
  font-size: 16px;
  text-align: left;
  line-height: 1.3;
  opacity: .85;
  user-select: none;
  pointer-events: none;
  z-index: 9;
  white-space: nowrap;

  /* * 关键：复用 #scroll-cue 的闪烁动画 
   * (这个 @keyframes cueBlink 在你的 style.css 
   * 第 465 行附近已经定义过了，所以我们直接用)
   */
  animation: cueBlink 1.2s ease-in-out infinite;
}

/* 确保 hidden 属性生效 */
#timeline-cue[hidden] {
  display: none;
}

.bubble{
  position:absolute; max-width:38ch;
  background:#111; color:#fff; border-radius:12px; padding:10px 14px;
  box-shadow:0 10px 24px rgba(0,0,0,.45);
  font-size:14px; line-height:1.35;
  z-index: 7;               /* 高于云/山，低于时间轴 */
}
.bubble[hidden]{ display:none; }

/* 尖角：默认在左侧（→ 指向屏幕中线/飞机） */

/* --- 气泡：尖角 + 阴影（改成 .bubble） --- */
/* --- 彩色气泡：整块填充 + 尖角方向正确 --- */
.bubble {
  position: absolute;
  max-width: min(56ch, 60vw);
  color: #fff;
  font-size: clamp(14px, 2.1vw, 15px);
  line-height: 1.35;
  padding: 0.7rem 1rem;
  border-radius: 2px;
  box-shadow: 0 8px 24px rgba(0,0,0,.35);
  z-index: 7;
  pointer-events: none;
}

/* 整体上色：蓝、红、橘、黄（颜色不变） */
.bubble.fo {
  background: #1100ff;    /* FO 蓝 */
}
.bubble.captain {
  background: #ff0000;    /* Captain 红 */
}
.bubble.atc {
  background: #ff7300;    /* ATC 橘 */
}
.bubble.egpws {
  background: #ffd972;    /* EGPWS 黄 */
  color: #000;            /* 黄色底换黑字 */
}

/* 尖角基础 */
.bubble::after {
  content: "";
  position: absolute;
  width: 0;
  height: 0;
  border: 10px solid transparent;
  transform: translateY(-50%); /* ✅ 让尖角垂直居中 */
}

/* 朝向（尖角在中间且自动匹配背景颜色） */
.bubble.left::after {
  left: 100%;             /* 尖角朝右 */
  top: 50%;
  border-left-color: #1100ff;
}
.bubble.right::after {
  right: 100%;            /* 尖角朝左 */
  top: 50%;
  border-right-color: #ff0000;
}
.bubble.down::after {
  right: 24px;
  top: 100%; /* 1. 改为 top: 100% (让尖角贴在气泡底部) */
  bottom: auto; /* 2. 清除旧的 bottom 属性 */
  border-top-color: #ff7300; /* 3. 改为 border-top-color (使箭头朝下) */
  transform: translateY(0); /* 4. 覆盖基础规则的 transform，取消垂直居中 */
}

.bubble::before {
  /* 1. 默认内容为空 */
  content: ""; 
  position: absolute;
  
  /* 2. 定位: 紧贴在气泡的左上角 (外部) */
  left: 1rem;
  bottom: 100%;      /* 关键: 元素的底部 = 气泡的顶部 */
  margin-bottom: 2px; /* 在标签和气泡间加 4px 间距 */

  /* 3. 样式 */
  color: #fff;
  font-family: sans-serif;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase; /* 统一大写，更像标签 */
  letter-spacing: 0.05em;
  opacity: 0.8;      /* 稍微弱化，不抢主对话 */
  white-space: nowrap; /* 防止标签换行 */
}

/* 4. 为每个气泡指定标签内容 */
.bubble.fo::before {
  content: "First Officer";
}
.bubble.captain::before {
  content: "Captain";
}
.bubble.atc::before {
  content: "Air Traffic Control";
}
.bubble.egpws::before {
  content: "EGPWS (System)";
}


/* ── 旁白文本（飞机下方） ── */
.narrator-text {
  position: absolute;
  left: 50%;
  /* 放在飞机(35%)和ATC默认位置(58%)之间 */
  top: 52%; 
  transform: translateX(-50%);
  width: min(50ch, 80vw); /* 限制文本宽度 */
  
  color: #fff; /* 白色字 */
  font-family: sans-serif; /* 使用干净的无衬线字体 */
  font-size: clamp(14px, 2.1vw, 15px);
  line-height: 1.4;
  text-align: center; /* 居中 */
  
  /* 加一点阴影让文字在云上更清晰 */
  text-shadow: 0 1px 4px rgba(0,0,0,0.7);
  
  z-index: 7; /* 和气泡一个层级 */
  pointer-events: none;
  font-style: italic; /* 旁白通常用斜体 */
}

.narrator-text[hidden] {
  display: none;
}



/* 放置（不会与飞机重叠） */
#speech-fo{
  left: calc(50% - 340px); top: 40%;
}
#speech-captain{
  left: calc(50% + 160px); top: 42%;
}
#speech-atc{
  left: 50%; transform: translateX(-50%); top: 58%;
}

/* 结尾卡 */
.outro{
  display: none;
  position: fixed; /* 关键：改回 fixed */
  left:50%; top:50%; transform:translate(-50%,-50%); /* 居中 */
  width:min(720px, 86vw); 
  margin: 0; /* 移除 margin */
  text-align:center; 
  color:#fff;
  background:rgba(0,0,0,.6); 
  padding:18px 20px; 
  border-radius:12px;
  box-shadow:0 10px 24px rgba(0,0,0,.5); 
  z-index: 10;
  opacity: 0; 
  transition: transform 300ms ease-out, opacity 300ms ease-out; 
}


.outro .muted{ color:#b5bccc; font-size:12px; }

/* 步进距离（与 JS 保持一致） */
.steps .step{ height: 160vh; }


/* Intro 期间隐藏底部过滤按钮 */
.filters.is-visible{ display:flex; }

/* ============ /Intro Scrollytelling ============ */


/* ============ Globe Scrollytelling (新增) ============ */
#viz {
  position: sticky;
  top: 0;
  width: 100%;
  height: 100vh;
  opacity: 0;             /* 默认透明 */
  transition: opacity 1s ease-in-out; 
  z-index: 1;             /* 在最底层 */
}

#viz:active {
  cursor: grabbing; /* 拖动时变成“抓紧”的手 */
}

/* ===== Filters ===== */

#filters {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}


.filters.is-visible{
  display: flex; /* 保持不变 */
}




/* 右侧整体：年份滑条 + 过滤按钮 */
#globe-ui-right {
  position: fixed;
  top: 50%;
  right: 90px;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 0px;
  z-index: 15;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease;
}

#globe-ui-right.is-visible {
  opacity: 1;
  pointer-events: auto;
}

/* 年份滑条面板 */
#year-slider-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #e4ebff;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.year-slider-title {
  margin-bottom: 6px;
  opacity: 0.75;
}

.year-slider-wrap {
  position: relative;
  width: 100px;          /* 稍微大一点，给数字留空间 */
  height: 340px;         /* 滚动条更长一点 */
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 年份刻度：刻度线压在轨道上，数字在右边 */
.year-slider-ticks {
  position: absolute;
  left: 40px;            /* ❗ 和滑条同一条竖线 */
  top: 10px;
  bottom: 10px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  font-size: 10px;
  line-height: 1.1;
  color: #cfd7f5;
}

.year-slider-ticks span {
  position: relative;
  padding-left: 12px;    /* 数字往右挪一点 */
}

/* 小短线 = 刻度，画在竖线的位置上 */
.year-slider-ticks span::before {
  content: "";
  position: absolute;
  left: 0;               /* 就是竖线所在位置 */
  top: 50%;
  width: 8px;
  height: 1px;
  background: #cfd7f5;
  transform: translateY(-50%);
}

/* 真正的滚动条（竖直） */
#year-slider {
  -webkit-appearance: none;
  appearance: none;
  position: absolute;
  left: -120px;            /* ❗ 和刻度线同一个 x */
  top: 50%;
  width: 320px;          /* 竖直方向长度，比刚才更长一点 */
  height: 4px;
  transform-origin: center;
  transform: translateY(-50%) rotate(90deg);
  background: #2e05d4;   /* 深紫色 */
  border-radius: 999px;
  outline: none;
  cursor: pointer;
  z-index: 50; 
}


/* 滑条轨道（Firefox 等） */
#year-slider::-moz-range-track {
  height: 4px;
  background: #2e05d4;
  border-radius: 999px;
}

/* 滑块按钮样式：小圆点 */
#year-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #ffffff;
  border: 2px solid #101218;
  box-shadow: 0 0 8px rgba(255, 255, 255, 0.6);
}

#year-slider::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #ffffff;
  border: 2px solid #101218;
  box-shadow: 0 0 8px rgba(255, 255, 255, 0.6);
}







/* 地图元素 */
.land {
  fill: #232731; /* 比海洋亮一些，明显区分 */
  stroke: #5b5a65; /* 边界线更亮 */
  stroke-width: 0.8px; /* 稍微加粗边界线 */
  filter: drop-shadow(0 0 2px rgba(0,0,0,0.4));
}
.grat{fill:none;stroke:#1f242d;stroke-width:.5px;opacity:.6}
.ocean{fill:#0a0c10}

/* 航线基础样式 */
.route{
  cursor:pointer;                   /* 悬停变手型 */
  stroke: white;
  fill:none;
  stroke-width:2px;
  stroke-opacity:.9;
  transition:stroke-width .15s ease, stroke-opacity .15s ease, filter .15s ease;
  vector-effect: non-scaling-stroke; /* 缩放保持像素宽度 */
  stroke-linecap:round;
}
.route-upcoming{
  stroke-opacity:.75;
  stroke-dasharray:6 6;
}
.route.active{
  stroke-width:2.8px;
  stroke-opacity:1;
  filter: drop-shadow(0 0 4px rgba(255,120,120,.65));
}

/* 城市点与标签（仅 hover 时出现） */
.city-dot{ pointer-events:none }
.city-label{
  font-size:11px;
  fill:#e8e8e8;
  paint-order:stroke;
  stroke:rgba(0,0,0,.55);
  stroke-width:2px;
  pointer-events:none;
}

/* 飞机图标 */
.plane{
  fill:#fff;
  stroke:#000;
  stroke-opacity:.35;
  stroke-width:.6px;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.35));
  pointer-events:none;
}

/* Tooltip（固定定位，跟随鼠标） */
#tip{
  position:fixed;
  pointer-events:none;
  z-index:9999;
  background:rgba(20,20,20,.94);
  color:#fff;
  padding:10px 12px;
  border-radius:12px;
  font-size:12px;
  line-height:1.35;
  box-shadow:0 8px 24px rgba(0,0,0,.45);
  opacity:0;
  left:-9999px; top:-9999px;
  max-width:320px;
  backdrop-filter: blur(4px);
}
#tip .tip-title{ font-weight:700; font-size:13px; margin-bottom:2px; }
#tip .tip-sub{ color:#bfc6cf; margin-bottom:6px; }
#tip .tip-row{ display:flex; gap:6px; margin:2px 0; }
#tip .key{ color:#bfc6cf; min-width:70px; }
#tip .val{ color:#fff; }
#tip .muted{ color:#9aa3ad; }
#tip hr{ border:none; border-top:1px solid rgba(255,255,255,.08); margin:6px 0; }
#tip .badge{ padding:1px 6px; border-radius:999px; background:rgba(255,255,255,.08); }


#tip b{color:#fff}
#tip .muted{color:var(--muted)}


/* ============ Globe Rotation Scroll (新增) ============ */
#globe-rotate-scroll {
  position: relative;
  /* 关键：这个高度定义了旋转需要滚动多久 */
  height: 300vh; 
  z-index: 5; /* 和毛玻璃文本框在同一层 */
  /* 关键：允许鼠标“穿透”这个区域，点到下面的地球 */
  /* (但 JS 会禁用拖拽) */
  pointer-events: none; 
}

.rotate-prompt {
  position: sticky; /* 粘在屏幕中央 */
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(70ch, 90vw);
  text-align: center;
  color: #fff;
  pointer-events: auto; /* 允许选择这段文字 */
  padding: 1.5rem 2rem;
  border-radius: 16px;  
  transition: opacity 300ms ease-out;
}

.rotate-prompt h2 {
  font-family: Georgia, 'Times New Roman', Times, serif;
  font-size: 2.2rem;
  font-weight: 700;
  color: #fff;
  margin-top: 0;
}

.rotate-prompt p {
  font-family: sans-serif;
  font-size: 1.1rem;
  line-height: 1.7;
  color: #eee;
}
.map-prose-content a {
  color: #ffaa00;  /* ★ 使用你主题里的“高亮黄” */
  text-decoration: underline; /* 加下划线, 清楚表明它是链接 */
  transition: opacity 0.2s ease-in-out; /* 添加平滑过渡 */
}

/* ★ 添加 hover 效果 ★ */
.map-prose-content a:hover {
  opacity: 0.7; /* 鼠标悬浮时稍微变淡 */
  color: #ffaa00; /* 确保悬浮时颜色不变 */
}

#a321-focus-step {
  height: 100vh;
  pointer-events: none; /* 允许鼠标穿透 */
  position: relative;
  z-index: 5;
}

/* 默认隐藏 A321 的毛玻璃文本框 */
.a321-prompt {
  position: sticky;
  top: 50%;
  transform: translateY(-50%);
  opacity: 0;
  transition: opacity 300ms ease-out;
}


/* ===== 毛玻璃 ===== */
#globe-scroll-steps {
  position: relative; /* 必须是 relative */
  z-index: 5;         /* z-index 在地球(1)和过滤器(10)之间 */
  width: 100%;
  pointer-events: none;
}

.globe-step-spacer {
  height: 100vh; /* 占位符，给你 1 整个屏幕的滚动距离 */
}

.globe-step-content {
  position: sticky;
  top: 50%;
  transform: translate(-50%, -50%);
  left: 50%;
  opacity: 0;
  transition: opacity 300ms ease-out;
  width: min(70ch, 90vw);
  padding: 1.5rem 2rem;
  color: #fff;
  border-radius: 16px;
  pointer-events: auto;
  text-align: center;
}

.globe-step-content h2 {
  font-family: Georgia, 'Times New Roman', Times, serif;
  font-size: 2.2rem;
  font-weight: 700;
  color: #fff;
  margin-top: 0;
}

.globe-step-content p {
  font-family: sans-serif;
  font-size: 1.1rem;
  line-height: 1.7;
  color: #eee; /* 正文用稍暗的白色 */
}


.pill {
  /* 1. 统一形状 */
  display: block;        /* 确保它是块级行为，方便控制宽度 */
  width: 160px;          /* 强制统一宽度 */
  padding: 5px 0;       /* 增加垂直内边距，显大方 */
  border-radius: 4px;    /* 改为小圆角，不再是药丸形 */
  border: 1px solid rgba(255, 255, 255, 0.15); /* 加一道微弱的边框增加质感 */
  
  /* 2. 字体样式 */
  color: #fff;           /* 白色字体 */
  font-weight: 600;
  font-size: 11px;
  text-align: center;    /* 文字居中 */
  letter-spacing: 0.05em;
  
  /* 3. 默认背景：深红色 (对应 Mechanical) */
  background: rgba(160, 30, 30, 0.85); 
  backdrop-filter: blur(4px); /* 毛玻璃效果 */
  
  cursor: pointer;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5); /* 深邃阴影 */
  transition: all 0.2s ease;
}

/* 悬停效果：变亮并轻微上浮 */
.pill:hover { 
  filter: brightness(1.2); 
  transform: translateY(-2px);
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.6);
}

/* 点击效果：下沉 */
.pill:active { 
  transform: translateY(1px); 
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
}

/* === CFIT 按钮 (深金色) === */
.pill-yellow { 
  background: rgba(160, 120, 10, 0.85); 
  color: #fff; 
}

/* === Reset 按钮 (深灰蓝) === */
.pill-reset { 
  background: rgba(50, 60, 75, 0.85); 
  color: #ccc; /* 稍微灰一点，以示区别 */
  border-color: rgba(255, 255, 255, 0.1);
}

/* === 选中状态 (高亮边框) === */
.pill.is-active {
  outline: 2px solid #fff;       /* 白色外发光 */
  background-color: rgb(200, 40, 40); /* 激活时背景稍微提亮不透明 */
  box-shadow: 0 0 15px rgba(255, 77, 77, 0.4); /* 红色辉光 */
}

/* CFIT 选中时的特有辉光 */
.pill-yellow.is-active {
  background-color: rgb(200, 150, 10);
  box-shadow: 0 0 15px rgba(255, 215, 0, 0.4); /* 金色辉光 */
}

/* 隐藏用（比 opacity 好，事件不会命中） */
.hidden{ display:none; }


/* --- 山：默认隐藏，接近结尾时升起 --- */
.mountain{
  position:absolute; left:50%; bottom:0; transform:translateX(-50%) translateY(24vh);
  width:120vw; height:28vh;
  background:url("image/mountains.png") bottom center/contain no-repeat;
  opacity:0;
  transition:transform .9s ease-out, opacity .9s ease-out;
  z-index:1; pointer-events:none;
}
.mountain.mountain-in{
  transform:translateX(-50%) translateY(0);
  opacity:1;
}

/* ====== 飞机分阶段位移（支持上下滚回）====== */
/* 初始隐藏在屏外上方 */
#aircraft{
  position:absolute;
  left:50%;
  transform: translateX(-50%);
  top:-40%;                   /* 初始在屏外 */
  opacity:0;
  transition: top 600ms cubic-bezier(.2,.8,.2,1), opacity 300ms ease;
  z-index:5;                  /* 低于山体，才能“钻到山下” */
  animation: floatAircraft 3.5s ease-in-out infinite;
}

/* 出场就绪：滚到第一条对白时让飞机到 35% 高度并可见 */
#aircraft.ready{
  top:35%;
  opacity:1;
}

/* 匀速俯冲：从当前 top 匀速滑到 90%（撞山）*/
#aircraft.descent{
  transition: top 2.8s linear;   /* 匀速 */
  top:90%;
}


/* 尾流始终贴飞机顶部（你已有逻辑保持 bottom:100%） */
#aircraft .contrail{ bottom:100%; z-index:3; }

/* 山体在飞机之上，让飞机“钻到山下” */
.mountain{ z-index:8; }

/* 首屏“向下滑动”提示 */
#scroll-cue,
#title-scroll-cue{
  position:absolute; left:50%; bottom:6vh; transform:translateX(-50%);
  color:#fff; font-size:16px; text-align:center; line-height:1.3;
  opacity:.85; user-select:none; pointer-events:none;
  animation: cueBlink 1.2s ease-in-out infinite;
  z-index:9;
}
@keyframes cueBlink{
  0%,100%{ opacity:.2; transform:translateX(-50%) translateY(0); }
  50%{ opacity:1; transform:translateX(-50%) translateY(4px); }
}



/* ★ 新增：确保 strong 和 highlight 生效 ★ */
.flash-boom .boom strong {
   font-weight: 700;
}
.flash-boom .boom .highlight-red {
  color: #df0c0c;
  font-weight: 700;
}

html, body{ background:#000; transition: background-color 800ms ease-out; }


/* 放大→略缩→稳定（一次播放） */
@keyframes boomOnce {
  0%   { transform: scale(1);   opacity: 0.9; }
  25%  { transform: scale(1.6); opacity: 1;   }
  45%  { transform: scale(0.95);}
  65%  { transform: scale(1.15);}
  85%  { transform: scale(0.98);}
  100% { transform: scale(1);   }
}



@keyframes flashToBlack{
  0%   { opacity: 0; background: #fff; }
  15%  { opacity: 1; background: #fff; }
  65%  { opacity: 1; background: #fff; }
  100% { opacity: 1; background: #000; }  /* 渐入黑场 */
}


#boom-scroll-cue {
  position: fixed; /* ★ 1. 确保是 sticky */
  bottom: 6vh;      /* ★ 2. 粘在底部 6vh */
  width: auto;      /* ★ 3. 宽度 100% */
  text-align: center; /* ★ 4. 文本居中 */
  color: #000;
  z-index: 1;
  font-size: 16px;
  line-height: 1.3;
  user-select: none;
  pointer-events: none;
  opacity: 1;
  transition: opacity 300ms ease-out;
  animation: cueBlinkBlack 1.2s ease-in-out infinite;
  z-index: 13;
}

@keyframes cueBlinkBlack {
  0%,100% { opacity: .2; transform: translateY(0); } /* ★ 修复：删除 translateX */
  50%    { opacity: 1; transform: translateY(4px); } /* ★ 修复：删除 translateX */
}

/* ── 闪烁的 WARNING 提示 ──────────────── */
@keyframes flashWarning {
  0%, 100% { 
    /* 匹配 EGPWS 的黄色 */
    color: #ffd37a; 
    opacity: 1; 
  }
  50% { 
    /* 闪烁时变为更醒目的红色 */
    color: #ff4d4d;
    opacity: 0.6; 
  }
}

/*
 * 定位到时间轴(.timeline)的第一个(.row:first-child)
 * 里的时间栏(.t)，也就是 [EGPWS]WARNING🚨 那行
 */
.timeline .row.warning-row .t {
  color: #ffd37a; /* 默认设为 EGPWS 黄色 */
  font-weight: 700; /* 加粗一点 */
  
  /* * 应用动画：
   * 名字: flashWarning
   * 时长: 1.1 秒
   * 循环: infinite (无限)
   * 步调: steps(1, end) - 这会让它像数字时钟一样“跳闪”
   * 而不是平滑“渐变”，更有危机感。
   */
  animation: flashWarning 1.1s infinite steps(1, end);
}

/* ── 飞机漂浮动画 ──────────────── */
@keyframes floatAircraft {
  0%, 100% {
    /* 保持 X 轴居中，Y 轴在原位 */
    transform: translateX(-50%) translateY(0);
  }
  50% {
    /* 保持 X 轴居中，Y 轴向上浮动 8px */
    transform: translateX(-50%) translateY(-8px);
  }
}


/* ── BOOM 文本震动动画 (恢复原始版本) ── */
@keyframes shakeBoomSimple {
  0%, 100% {
    transform: translate(0, 0) rotate(0);
  }
  15% {
    transform: translate(-5px, -6px) rotate(-2deg);
  }
  30% {
    transform: translate(0, -3px) rotate(2deg);
  }
  45% {
    transform: translate(-6px, -5px) rotate(-1deg);
  }
  60% {
    transform: translate(3px, -4px) rotate(1deg);
  }
  75% {
    transform: translate(-5px, -6px) rotate(0deg);
  }
}



/* === 序言的首字下沉 (Drop Cap) === */
.prose-section p:first-of-type::first-letter {
  color: #fff;           /* 让这个字母更亮 (白色) */
  font-size: 4.5rem;      /* 设置一个大字号 */
  font-weight: 700;       /* 加粗 */
  float: left;            /* 关键：让它浮动在段落左侧 */
  line-height: 1;         /* 调整行高，让它对齐 */
  padding-right: 0.5rem;  /* 在字母和右侧文本之间留出空隙 */
  padding-top: 0.2rem;    /* 微调垂直位置 */
}

.prose-section p {
  margin-bottom: 1.5em;
}

/* ============ 新增: 简单 Scrollytelling 样式 ============ */

/* ── 新增: "闪屏" 图层 (Fixed) ── */
.flash-boom {
  position: fixed;/* 关键：改为 fixed，不再随滚动条移动 */
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: #000 !important;
  z-index: 50; /* 层级较高，盖住云层 */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  opacity: 0;
  pointer-events: none; 
  transition: opacity 0.1s ease-in-out !important; 
}

.flash-boom.release-fix {
  position: absolute !important; /* 强制改为绝对定位 */
  top: auto !important;          /* 取消顶部定位 */
  bottom: 0 !important;          /* 钉在容器底部 */
  width: 100%;                   /* 确保宽度正确 */
  height: 100vh;                 
}

/* ── 2. 【新增】 "背景图" 规则 (可以添加到 .flash-boom 后面) ── */
.flash-boom-bg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover; /* 裁剪并填满, 不拉伸 */
  z-index: 1; /* 放在最底层 */
  opacity: 0; /* 稍微调暗一点, 不抢镜 */
}

/* [hidden] 属性会设置 display: none */
.flash-boom[hidden] {
  display: none;
}

/* ── 新增: "Boom" 文本内容 (在闪屏内居中) ── */
.flash-boom .boom-content {
  pointer-events: auto; 
  padding: 1.5rem 2rem; /* ★ 添加内边距 */
  margin: 0 auto; 
  width: min(65ch, 90vw);
  max-width: 720px;
  text-align: left;
  font-family: Georgia, 'Times New Roman', Times, serif;
  font-size: clamp(1.1rem, 2.5vw, 1.25rem);
  line-height: 1.6;
  color: #ffffff;
  animation: none !important; /* 禁用震动 */
  /* ★ 以下是毛玻璃效果 ★ */
  position: relative; /* 确保 z-index 生效 */
  z-index: 2; /* 放在背景图之上 */
  background: rgba(255, 255, 255, 0.01); 
  backdrop-filter: blur(12px); /* 模糊背景 */
  -webkit-backdrop-filter: blur(12px); /* 兼容 Safari */
  border-radius: 12px; /* 圆角 */
  box-shadow: 0 4px 20px rgba(0,0,0,0.1); /* 柔和阴影 */
}

.flash-boom .flash-boom-bg,
.flash-boom .boom-content {
  opacity: 0; /* ★ 关键：默认看不见 */
  /* 取消自动 transition，因为我们要用 JS 实时控制 opacity，这样跟手 */
  transition: none; 
  will-change: opacity;
}

.flash-boom .boom-content .attribution {
  font-size: 0.8rem;
  font-family: sans-serif;
  color: #ffffff;
  text-align: center;
  margin-top: 1.5em;
  margin-bottom: 0;
  font-style: italic;
}
.flash-boom .boom-content .attribution a {
  color: #ffea00; /* 保持链接颜色一致 */
  text-decoration: underline;
  /* (你之前那个链接指针的bug, 最好在这里也加上) */
  cursor: pointer !important;
  pointer-events: auto !important;
}

/* "Boom" 内部的段落样式 */
.flash-boom .boom-content p {
  margin-bottom: 1em;
}
.flash-boom .boom-content .muted {
  color: #ffffff;
  font-size: 0.9rem;
  font-family: sans-serif;
}
.flash-boom .boom-content .muted a {
  color: #ffea00;
  text-decoration: underline;
  font-style: italic;
  transition: opacity 0.2s ease-in-out; 
  cursor: pointer !important;
  pointer-events: auto !important;
}

/* ★ 修复点 4 (添加 hover 效果) ★ */
.flash-boom .boom-content .muted a:hover {
  opacity: 0.7; 
  cursor: pointer !important;
  pointer-events: auto !important;
}

.flash-boom .boom-content strong {
   font-weight: 700;
}
.flash-boom .boom-content .highlight-red {
  color: #df0c0c;
}

/* 1. (保持不变) 粘性容器 */
.sticky-story-wrapper {
  position: relative;
  z-index: 30;
  /* ★ 修改 1: 高度大大增加，把后面的内容推下去，给 Boom 留出表演空间 */
  height: 250vh; 
  margin-top: -100vh; 
  pointer-events: none; 
}

/* 2. (保持不变) "步骤"占位符 */
.story-step {
  height: auto;
  margin-bottom: 0; 
  background: #000;
  position: relative;
  z-index: 5;
}
.story-step:last-child {
   margin-bottom: 100vh;
}

/* 普通正文 */
.story-step .story-content {
  z-index: 5; 
  width: min(65ch, 90vw);
  max-width: 720px;
  margin: 0 auto; 
  padding: 20vh 0;
  text-align: left;
  color: #ccc;

  /* 字体样式 (保持不变) */
  font-family: Georgia, 'Times New Roman', Times, serif;
  line-height: 1.7;
  font-size: 1.1rem;
  opacity: 1;
  pointer-events: auto;
}

/* ============ 修复正文链接样式 ============ */
/* 针对 .story-content 下的所有链接应用黄色 */
.story-content a {
  color: #ffaa00 !important;   /* 强制使用高亮黄，加 !important 确保覆盖学校默认样式 */
  text-decoration: underline;    /* 加下划线 */
  transition: opacity 0.2s ease-in-out;
  cursor: pointer;
}

/* 访问过的链接也保持黄色，不要变紫 */
.story-content a:visited {
  color: #ffaa00 !important;
}

/* 鼠标悬停时的效果 */
.story-content a:hover {
  opacity: 0.7;             /* 稍微变暗 */
  color: #ffaa00 !important; /* 保持黄色，防止变红 */
}

/* 5. "Prose" 文本的特定样式 */

#prose-step {
  position: relative;
  background-color: #000; 
  z-index: 60;  /* ★ 关键：必须比 .flash-boom (50) 高，这样才能“滚着离开” */
  margin-top: 0;
  padding-top: 10vh;
  min-height: 100vh;
}

#prose-step .story-content {
  color: #ccc; /* Prose 文本用稍暗的灰色 */
}

/* 复制首字下沉样式 */
#prose-step .story-content p:first-of-type::first-letter {
  color: #ffffff;
  font-size: 4.5rem;
  font-weight: 700;
  float: left;
  line-height: 1;
  padding-right: 0.5rem;
  padding-top: 0.2rem;
}


.flash-boom.is-fixed-flash .boom-content {
  position: static; /* 取消 sticky */
  padding-top: 0; /* 取消 padding */
}

.flash-boom[hidden]{ display:none !important; }
.flash-boom{ pointer-events:none; }


.pull-quote {
  /* 使用你已有的 highlight-yellow 颜色作为左边框 */
  border-left: 4px solid #ffaa00; 
  padding-left: 1.5rem;
  margin: 2.5rem 0.5rem; /* 上下留白，左右留一点白 */
  font-size: 1.3rem;      /* 字体稍大 */
  font-style: italic;     /* 斜体 */
  font-weight: 600;       /* 稍粗 */
  color: #fff;            /* 比正文的 #ccc 更亮 */
}

.pull-quote p {
  margin: 0;
}

.globe-scroll-step {
  height: 100vh;
  position: relative;
  z-index: 5;
  pointer-events: none;
}

.scroll-buffer {
  height: 100vh;
  width: 100%;
  position: relative;
  z-index: 5;
  pointer-events: none;
}


/* ============ NEW: 章节标题样式 (Overrides) ============ */

/* 1. 章节数字的样式 */
.chapter-number {
  display: block;
  font-family: Georgia, 'Times New Roman', Times, serif;
  font-size: 4rem; /* 大数字 */
  font-weight: 700;
  color: #ffaa00; /* 使用高亮黄 */
  line-height: 1.1;
  opacity: 0.8;
  margin-bottom: 0.5rem;
}

/* 2. 修复 A321 提示 (它没有章节号，保持原样) */
.a321-prompt {
  text-align: center; /* 居中 */
}
.a321-prompt h2 {
  font-size: 1.8rem; /* 保持小字体 */
  white-space: normal; /* 允许换行 */
}

/* 3. 修复章节 3 的副标题 */
#cfit-human-step h2 {
  margin-bottom: 0.5rem; /* 为副标题留出空间 */
}

#cfit-human-step p {
   white-space: normal; /* 允许副标题换行 */
}

/* 地图正文 */
.map-prose-step {
  height: 100vh; /* 占满一屏滚动区域 */
  position: relative;
  z-index: 5;
  pointer-events: none; /* 允许穿透 */
}

.map-prose-content {
  position: sticky;
  top: 50%;
  transform: translateY(-50%);
  
  /* ★ 关键：左对齐 */
  margin: 0 auto; /* 距离左侧 2rem */
  text-align: left;
  
  /* ★ 关键：毛玻璃 */
  width: min(65ch, 90vw); /* 限制宽度 */
  max-width: 720px;
  padding: 1.5rem 2rem;
  color: #ccc;
  background: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  
  /* 字体样式 (和 Normal Prose 一致) */
  font-family: Georgia, 'Times New Roman', Times, serif;
  line-height: 1.7;
  font-size: 1.1rem;
  opacity: 1;
  pointer-events: auto; /* 允许选择文字 */
}

.chart-block {
  width: 100%;
  max-width: 900px;
  margin: 40px auto;
  text-align: center;
}

.chart-block img {
  width: 100%;
  height: auto;
  border-radius: 6px;
  box-shadow: 0 0 20px rgba(255,255,255,0.08);
}

.chart-caption {
  color: #ccc;
  font-size: 14px;
  margin-top: 8px;
  font-style: italic;
}

/* =========================================
   为 "Explore the World" 交互提示框添加专属样式
   ========================================= */

/* 选中 id 为 interaction-step 里面的内容框 */
#interaction-step .globe-step-content {
  /* 1. 继承之前那个大文本框的毛玻璃背景样式 */
  background: rgba(0, 0, 0, 0.6); /* 半透明黑底 */
  backdrop-filter: blur(10px);      /* 毛玻璃模糊效果 */
  -webkit-backdrop-filter: blur(10px); /* 兼容 Safari */
  border-radius: 12px;              /* 圆角 */
  box-shadow: 0 4px 24px rgba(0,0,0,0.4); /* 增加阴影提升立体感 */
  
  /* 2. 调整一下内边距和宽度，让它看起来精致一些 */
  padding: 30px 40px;
  max-width: 500px; /* 比上面的大段文字稍微窄一点 */
  
  /* 确保文字居中对齐 */
  text-align: center; 

  /* 3. 关键：确保它在淡出时是原地消失，而不是滑走 */
  /* .globe-scroll-step 是 flex 布局居中，
     只要它的父级 section 足够高，它就会在屏幕中间完成淡入淡出。
     现有的 CSS transition: opacity 0.6s 已经足够处理动画。*/
}

/* 微调里面的标题和文字间距 */
#interaction-step .globe-step-content h2 {
  margin-top: 0;
  margin-bottom: 15px;
  color: #fff; /* 纯白标题 */
  font-size: 1.8rem;
}

#interaction-step .globe-step-content p {
  margin-bottom: 0;
  color: #ddd; /* 稍微灰一点的正文 */
  font-size: 1.1rem;
  line-height: 1.5;
}

/* ============ 修复 Explore 环节的退出动画 ============ */
#explore-buffer {
  /* 关键：让这个缓冲区的逻辑判定线提前 50vh (半个屏幕) 开始 */
  /* 这样当 Explore 文字还在屏幕正中间时，就会触发淡出，而不是等到被顶走才淡出 */
  margin-top: -50vh; 
  
  /* 补回高度，保证物理空间足够 */
  height: 150vh; 
  
  /* 保持穿透，不挡住地球的操作 */
  pointer-events: none; 
}

/* 确保 Explore 环节本身足够高，保证 sticky 状态持久 */
#interaction-step {
  height: 150vh;
}

.route {
  stroke-width: 1px;
  stroke-linejoin: round;
  stroke-linecap: round;
  transition: stroke 0.3s, stroke-width 0.3s, stroke-opacity 0.3s;
}

/* 鼠标悬停或激活时 */
.route.active {
  stroke: #00ffff !important; /* 强制变成青色，或者你也可以去掉这行，只增加线宽 */
  stroke-width: 2.5px;
  stroke-opacity: 1;
  z-index: 999;
}

html, body {
  overflow-x: visible !important; /* 关键：允许 sticky 运作 */
  overflow-y: auto !important;    /* 确保垂直能滚 */
  width: 100%;
  position: static !important;    /* 防止学校 CSS 加 fixed */
}

/* 确保你的链接颜色不被学校 CSS (黄色/红色) 覆盖，
   强制使用你设计的高亮色 */
a, a:visited, a:hover, a:active {
  text-decoration: none; /* 根据你的设计调整 */
}

/* 重新申明你的高亮样式权重 */
.story-content a, 
.map-prose-content a,
.flash-boom .boom-content a {
  color: #ffaa00 !important; /* 你的高亮黄 */
  text-decoration: underline !important;
}

/* 修复可能的导航栏遮挡 (以防万一) */
nav.essential-nav {
  pointer-events: none; /* 让鼠标穿透导航栏空白处 */
}
#menuToggle {
  pointer-events: auto; /* 汉堡按钮本身可点 */
}

/* style.css 最底部 - 必须粘贴在这里 */

/* 1. 暴力解锁所有可能的父级容器 */
html, body, #app {
  overflow-x: visible !important;  /* 核心：打死也不能是 clip/hidden */
  overflow-y: visible !important;  /* 确保垂直能滚 */
  height: auto !important;         /* 防止高度被锁死 */
  min-height: 100vh !important;
  position: static !important;     /* 防止被 fixed 锁住 */
}

/* 2. 专门针对 Intro 区域的修复 */
/* 有时候 sticky 失效是因为父级高度不够，这里强制撑开 */
.intro {
  overflow: visible !important; 
  height: auto !important; 
  /* 你的 JS 会计算高度，但 CSS 先给个保底，防止 JS 没跑起来时高度为 0 */
  min-height: 200vh; 
}

/* 3. 确保 sticky 属性不被覆盖 */
.intro-scene, #viz {
  position: -webkit-sticky !important; /* Safari 兼容 */
  position: sticky !important;
  top: 0 !important;
}