@import url("../typography.css?v=2");
@import url("../semantic_title.css?v=7");
@import url("../semantic_prose.css?v=3");

/* ============================================================
   羽球·错题本 · 产品讲解页
   视觉沿用投资材料 deck：深海军蓝（系统／数据）+ 铜橙（关键时刻）
   动画约定：静态定位写在父级 <g transform> 属性上，
             CSS 只负责子级的 transform / opacity，互不覆盖。
   ============================================================ */

:root{
  /* 页底取全站的近黑 #02070b（site.css 的 --ink），顶栏、导航因此可以直接用站点默认样式。
     卡片本身仍是亮的：这一页是一组逐幕讲解，幕二的本子、幕四的人工复盘场景、幕八的档案卡都是"材料"，
     暗厅里放一张亮材料，比把纸也刷黑更贴合内容。 */
  --ground:#02070b;
  /* 卡片与舞台的中性色阶取暖灰（Notion gray 100–900），铜橙与海军蓝落在暖灰上更协调 */
  --paper:#F7F6F4;
  --surface:#FFFFFF;
  --surface-2:#F6F5F4;
  --surface-3:#EEECE8;
  --ink:#191918;
  --ink-2:#31302E;
  --muted:#615D59;
  --faint:#8E8983;
  --rule:#DFDCD9;
  --rule-soft:#E9E7E3;
  --navy:#143865;
  --navy-tint:#E7EDF6;
  --accent:#C25E17;
  --accent-tint:#FBEEE2;
  --teal:#1B6076;
  --teal-tint:#E2EEF2;
  --indigo:#3B4A85;
  --indigo-tint:#ECEDF7;
  --crimson:#9C2E3F;
  --screen:#0E2038;
  --screen-fg:#8FA3BC;
  /* 卡片轮廓统一走 hairline（描边而非投影），只有承载媒体的容器才叠一层柔投影 */
  --hairline:rgba(25,25,24,.10);
  --hairline-soft:rgba(25,25,24,.06);
  /* 近黑底上投影不可见，卡片靠一圈极淡的亮色描边把边缘读出来，投影只负责把它"坐"下去 */
  --shadow:0 0 0 1px rgba(241,248,250,.08), 0 28px 76px -24px rgba(0,0,0,.9);
  --shadow-media:0 10px 28px -16px rgba(25,25,24,.42);
  /* 铜橙 #C25E17 落在近黑上偏暗发褐，页底那一层控件用提亮一档的同色相 */
  --accent-on-ground:#E8792A;
  --on-ground:rgba(241,248,250,.72);
  /* 旁白色阶：卡片外壳去掉后，右列文字直接落在近黑底上，需要自己一套明度。
     章节色同理——海军蓝 #143865、深红 #9C2E3F 在近黑上几乎看不见，各提亮一档。 */
  --voice:#F1F8FA;
  --voice-2:rgba(241,248,250,.62);
  --voice-faint:rgba(241,248,250,.36);
  --voice-rule:rgba(241,248,250,.13);
  --navy-on-ground:#79A6DE;
  --crimson-on-ground:#D9697C;
  /* 只用系统字体栈，与站点其余页面一致。外链 Google Fonts 是渲染阻塞的外网依赖：
     中文字体按子集分片，一次要拉二十多个请求一兆多，而在国内网络下这个域名往往不通，
     整页会卡在等超时上。系统里本来就有 PingFang SC / 微软雅黑，落地效果与站点其他页统一。 */
  --font-cn:"PingFang SC","Microsoft YaHei",Inter,"SF Pro Display",sans-serif;
  --font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --page-w:1240px;
  /* 卡片左右各留 84px 走道给翻页箭头；窄屏由 --gutter 收窄 */
  --gutter:84px;
  --ease-out:cubic-bezier(.23,1,.32,1);
  --ease-in-out:cubic-bezier(.77,0,.175,1);
  /* Notion 的两档动效：控件用 150ms 线性减速，入场用带停顿感的减速曲线 */
  --ease-ui:cubic-bezier(.2,0,.2,1);
  --ease-enter:cubic-bezier(.16,1,.3,1);
  --dur-ui:.15s;
}

*{ box-sizing:border-box; }
body{
  margin:0; background:var(--ground); color:var(--ink); overflow:hidden;
  font-family:var(--font-cn); font-size:16px; line-height:1.7;
  -webkit-font-smoothing:antialiased;
}

/* ---------- 一屏一张卡片 ---------- */
.deck{
  position:relative; height:100svh; display:grid; place-items:center;
  padding:0 var(--gutter);
  /* 亮舞台落在近黑上会显得"贴"在底上，垫一层极弱的冷光把它托起来 */
  background:radial-gradient(118% 86% at 33% 44%, rgba(74,110,138,.16), transparent 64%);
  /* 卡片同时受三条上限约束：版心、可用宽度、以及"高度换算成宽度"后的上限 */
  --card-w:min(var(--page-w), calc(100vw - var(--gutter) * 2), calc((100svh - 132px) * 2.28));
  /* 一次翻幕的节奏：亮面交叉溶解 → 旧字先出 → 新字由 act-rise 逐条抬入；
     --flip-total 是整段交接的长度，explainer.js 按它摘 .is-leaving，两边只有这一个来源 */
  --flip-stage:.28s;
  --flip-rim:.18s;
  --flip-rim-delay:.2s;
  --flip-out:.1s;
  --flip-total:.38s;
  /* 正文框的高度：六幕的正文一到三行不等（第七幕是三行备赛结论，最高，约 84px），
     写死一个够装下最高那一份的下界，翻幕时标题与画面才不会跟着文字长短上下移动。
     对照幕的两句解说是并排常驻的（只改强调层级），因此两列都按这个高度留位。 */
  --narration-body-height:5.6em;
  /* 舞台高度必须让「宽」成为唯一的缩放约束：场景按 640x400 构图，
     半幅面板的可用宽是 564px，横向缩放上限 564/640=0.881，纵向要不拖后腿就得给到
     0.881x400=352px 的内容高（含 10px 上下内边距即 372px）。低于这条线时纵向变成瓶颈，
     场景连同它自己的字号一起被再压一档——场景内 13px 的标签会掉到 8.7px。
     声明在 .deck 上而不是对照卡上：小结那一幕也要按同一个高度对齐。
     下界 346px 是另一条约束：@media (max-width:1240px) 里舞台改成宽度驱动
     （.scene 取 height:auto），1240px 视口下半幅面板给到 522px 宽、
     场景因此高 522*0.625=326px，加上下 10px 内边距即 346px。低于这条线场景会被裁掉一截。 */
  --comparison-stage-height:clamp(346px,46svh,430px);
  /* 对照面板 = 上下内边距 22 + 标签 30 + 舞台 + 正文上边距 11 + 正文 --narration-body-height */
  --comparison-panel-extra:158px;
  /* 对照幕在面板下面还有一条解说进度条（轨道 + 12px 上边距）。
     开场幕与小结没有进度条，各自补上这一档才和对照幕等高。 */
  --narration-progress-block:28px;
}
/* 八幕共用同一个画框，翻页时边界不跳 */
.deck .card{
  position:absolute; width:var(--card-w); min-height:calc(var(--card-w) * .45);
  visibility:hidden; z-index:1;
}
/* 一次交接场上有两张卡：新卡在上（.is-current），旧卡垫在下面（.is-leaving），
   由 explainer.js 在 --flip-total 之后摘掉 .is-leaving。 */
.deck .card.is-current{ visibility:visible; z-index:2; }
.deck .card.is-leaving{ visibility:visible; pointer-events:none; }

/* 左栏亮面：两幕的舞台同框（752 宽，多数幕连位置和高度都一样），
   新舞台直接盖在旧舞台上淡入，底下那块在此期间一直亮着。
   整屏因此不会出现"两张都接近透明"的亮度洼地——逐幕翻下来的频闪正是从那里来的。
   入场用 stage-in 而不是右列那支 act-rise：溶解期间舞台一旦位移，
   同一块画面就会和身下的旧画面拖出重影。 */
.deck .card.is-current .act-stage{
  animation:stage-in var(--flip-stage) var(--ease-ui) both;
}
/* 旧舞台先原样撑住，等新舞台盖上来之后再退：只有新舞台盖不到的外沿会淡出
   （幕间舞台高度不等时才有），不会整块"啪"地消失。 */
.deck .card.is-leaving .act-stage{
  animation:stage-out var(--flip-rim) var(--ease-ui) var(--flip-rim-delay) both;
}
/* 右栏文字体量小，重影比闪更难受，仍是先出后进：旧字上移淡出，
   新字由下方那支 act-rise 逐条抬入（最早 .18s），两幕文字不叠。 */
.deck .card.is-leaving .card-body{
  animation:body-out var(--flip-out) var(--ease-ui) both;
}
@keyframes stage-in{ from{ opacity:0; } to{ opacity:1; } }
@keyframes stage-out{ from{ opacity:1; } to{ opacity:0; } }
@keyframes body-out{
  from{ opacity:1; transform:none; }
  to{ opacity:0; transform:translateY(-6px); }
}

/* 翻页控件在近黑页底上，用幽灵按钮：透明底 + 一根亮色描边，悬停才浮出一层底色。
   白底按钮在这里会比卡片还抢眼。 */
.deck-arrow{
  position:absolute; top:50%; margin-top:-20px; width:40px; height:40px; padding:0;
  display:grid; place-items:center; cursor:pointer;
  border:1px solid rgba(241,248,250,.16); border-radius:10px;
  background:transparent; color:var(--on-ground);
  transition:background-color var(--dur-ui) var(--ease-ui),
             border-color var(--dur-ui) var(--ease-ui),
             color var(--dur-ui) var(--ease-ui),
             transform var(--dur-ui) var(--ease-ui);
}
.deck-arrow.prev{ left:22px; }
.deck-arrow.next{ right:22px; }
.deck-arrow svg{ width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round; }
.deck-arrow:hover{
  background:rgba(241,248,250,.08); border-color:rgba(241,248,250,.28); color:#F1F8FA;
}
.deck-arrow:active{ transform:scale(.94); }
.deck-arrow:focus-visible{ outline:2px solid var(--accent-on-ground); outline-offset:2px; }
.deck-arrow[disabled]{ opacity:.26; cursor:default; }
.deck-arrow[disabled]:hover{
  background:transparent; border-color:rgba(241,248,250,.16); color:var(--on-ground);
}

.deck-dots{
  position:absolute; left:50%; bottom:26px; transform:translateX(-50%);
  display:flex; align-items:center; gap:8px;
}
.deck-dot{
  width:7px; height:7px; padding:0; border:0; border-radius:99px; cursor:pointer;
  background:rgba(241,248,250,.24);
  transition:width var(--dur-ui) var(--ease-ui), background-color var(--dur-ui) var(--ease-ui);
}
.deck-dot:hover{ background:rgba(241,248,250,.48); }
.deck-dot.is-on{ width:26px; background:var(--accent-on-ground); }
.deck-dot.is-on:hover{ background:var(--accent-on-ground); }
/* 开场、逐项对比与小结之间留出更宽的章节间隔。 */
.deck-dot:nth-child(2), .deck-dot:nth-child(8){ margin-left:16px; }
.deck-dot:focus-visible{ outline:2px solid var(--accent-on-ground); outline-offset:3px; }

/* 解说、声音与重播共用一条轻量工具栏。播放保留文字，另外两项只留图标。 */
.deck-tools{
  position:absolute; z-index:5; bottom:14px;
  right:max(var(--gutter),calc((100vw - var(--card-w))/2));
  display:flex; align-items:center; gap:6px;
}
.deck-replay{
  width:40px; height:40px; display:grid; place-items:center;
  padding:0; border:0;
  background:transparent; color:var(--on-ground); cursor:pointer;
  appearance:none; font:500 12px/1.4 var(--font-cn); letter-spacing:.035em;
  transition:color var(--dur-ui) var(--ease-ui),
             transform var(--dur-ui) var(--ease-ui);
}
.deck-audio::after{
  content:""; position:absolute; left:2px; right:2px; bottom:3px; height:1px;
  background:var(--accent-on-ground); transform:scaleX(0); transform-origin:left;
  transition:transform var(--dur-ui) var(--ease-ui);
}
.deck-replay:hover{ color:#F1F8FA; }
.deck-audio:hover::after{ transform:scaleX(1); }
.deck-replay:active{ transform:translateY(1px); }
.deck-replay:focus-visible{ outline:2px solid var(--accent-on-ground); outline-offset:2px; }
.deck-replay[disabled]{ opacity:.26; cursor:default; }
.deck-replay[disabled]:hover{ color:var(--on-ground); }
.deck-replay .deck-control-icon{ width:22px; height:22px; }

.deck-audio{
  position:relative;
  height:40px;
  display:inline-flex; align-items:center; gap:7px;
  padding:7px 2px; border:0;
  background:transparent; color:var(--on-ground); cursor:pointer;
  appearance:none; font:500 12px/1.4 var(--font-cn); letter-spacing:.035em;
  transition:color var(--dur-ui) var(--ease-ui),
             transform var(--dur-ui) var(--ease-ui);
}
.deck-sound{
  position:relative; z-index:1;
  display:grid; place-items:center;
}
.deck-mute{
  width:40px; height:40px; display:grid; place-items:center;
  padding:0; border:0; background:transparent; color:var(--on-ground); cursor:pointer;
  appearance:none; transition:color var(--dur-ui) var(--ease-ui),
             transform var(--dur-ui) var(--ease-ui);
}
.deck-sound-hint{
  position:absolute; left:50%; bottom:48px; translate:-50% 0;
  width:max-content; max-width:250px;
  padding:8px 11px; border:1px solid rgba(241,248,250,.14); border-radius:8px;
  background:rgba(8,18,25,.96); color:rgba(241,248,250,.88);
  box-shadow:0 10px 28px -12px rgba(0,0,0,.72);
  font:500 12px/1.45 var(--font-cn); letter-spacing:.01em; white-space:nowrap;
  pointer-events:none; animation:deck-sound-hint 3s var(--ease-ui) both;
}
.deck-sound-hint::after{
  content:""; position:absolute; left:50%; bottom:-5px; width:8px; height:8px;
  margin-left:-4px; background:rgba(8,18,25,.96);
  border-right:1px solid rgba(241,248,250,.14);
  border-bottom:1px solid rgba(241,248,250,.14); transform:rotate(45deg);
}
.deck-sound-hint[hidden]{ display:none; }
@keyframes deck-sound-hint{
  0%{ opacity:0; transform:translateX(4px); }
  10%,84%{ opacity:1; transform:none; }
  100%{ opacity:0; transform:translateX(2px); }
}
.deck-control-icon{
  display:block; flex:0 0 auto; width:15px; height:15px;
  fill:none; stroke:currentColor; stroke-width:1.35;
  stroke-linecap:round; stroke-linejoin:round;
}
.deck-audio .deck-control-icon{ position:relative; }
.deck-audio .deck-control-icon svg{ position:absolute; inset:0; width:15px; height:15px; }
.deck-audio [data-icon="play"]{ fill:currentColor; stroke:none; }
.deck-audio [data-icon="pause"]{ display:none; }
.deck-audio[data-audio-state="playing"] [data-icon="play"]{ display:none; }
.deck-audio[data-audio-state="playing"] [data-icon="pause"]{ display:block; }
.deck-mute .deck-control-icon{ position:relative; width:24px; height:24px; }
.deck-mute .deck-control-icon svg{ position:absolute; inset:0; width:24px; height:24px; }
.deck-mute [data-icon="muted"]{ display:none; }
.deck-mute[data-mute-state="muted"] [data-icon="audible"]{ display:none; }
.deck-mute[data-mute-state="muted"] [data-icon="muted"]{ display:block; }
.deck-audio:hover, .deck-mute:hover{ color:#F1F8FA; }
.deck-audio:active, .deck-mute:active{ transform:translateY(1px); }
.deck-audio:focus-visible, .deck-mute:focus-visible{
  outline:2px solid var(--accent-on-ground); outline-offset:2px;
}
.deck-audio[disabled], .deck-mute[disabled]{ opacity:.26; cursor:default; }
.deck.is-audio-paused .act-stage *,
.deck.is-audio-paused .narration-progress-fill{ animation-play-state:paused !important; }

/* ---------- 一幕 = 一张卡片：左动画，右旁白 ----------
   这里不再有"卡片"这个盒子。整幕只有一块亮面——舞台；文字直接写在近黑底上。
   苹果的产品页就是这个结构：画面是全幅的亮物，说明文字落在页底本身，
   两者之间没有任何容器、描边或分隔线，靠明暗差和留白分开。
   */
.card{
  display:grid; grid-template-columns:minmax(0,64fr) minmax(0,36fr);
  gap:clamp(30px, 4.2vw, 58px); align-items:center;
  background:none; border:0; border-radius:0; box-shadow:none; padding:0;
}

/* 独立开场只建立团队与品牌，不借用后续的双栏流程结构。 */
.card.is-team-intro{
  display:grid; grid-template-columns:1fr; gap:22px;
  width:min(940px, var(--card-w)); min-height:0;
}
/* 开场幕与后面七幕整卡等高：八幕在 .deck 里都是居中的，卡片一高一矮，
   翻页时整块画面会上下窜一档。529 = 对照面板高 - 眉题与标题占掉的那一段。 */
.card.is-team-intro .act-stage{
  /* 减去的 34px 是这一幕自己的文字块与对照幕的差额（眉题 + 居中大标题 + 22px 行距，
     对照幕那边是眉题 + 幕标题 + 18px 下边距）。三处常量一起决定八幕落在同一个高度上。 */
  height:calc(var(--comparison-stage-height) + var(--comparison-panel-extra)
    + var(--narration-progress-block) - 30px);
  padding:0; overflow:hidden;
  display:grid; place-items:stretch;
  background:#06130f;
}
/* 画面必须填满亮面：场景自己带一个比亮面矮的固定高度时，
   上下会各露出一条 #06130f 的暗边，读起来就是一条没裁干净的黑边。 */
/* 英文的幕标题排到两行，六张对照卡因此各高出 41px；开场幕的标题两种语言都是一行，
   不跟着长高就会在英文下比别人矮一截。这一档只补给英文。 */
:root[lang="en"] .card.is-team-intro .act-stage{
  height:calc(var(--comparison-stage-height) + var(--comparison-panel-extra)
    + var(--narration-progress-block) + 11px);
}
.card.is-team-intro [data-team-intro]{ width:100%; height:100%; }
.card.is-team-intro .card-body{ width:min(720px,100%); margin-inline:auto; }
/* 标题是居中的，幕序不能右对齐——两条对齐轴会在同一块里打架 */
.card.is-team-intro .act-eyebrow{ margin-bottom:10px; justify-content:center; }
.card.is-team-intro .act-eyebrow .step{ margin-left:0; }
.team-intro-copy{
  margin:0; color:var(--voice); text-align:center;
  font-size:clamp(25px,3vw,42px); font-weight:680; line-height:1.24;
  letter-spacing:-.028em; text-wrap:balance;
}
.team-intro-copy .brand-wordmark{
  display:inline-flex; align-items:baseline; column-gap:.08em;
  line-height:1; font-weight:650; letter-spacing:-.025em;
  vertical-align:baseline;
}
.team-intro-copy .brand-wordmark b{
  color:#f5f5f7; font-style:oblique 10deg; font-weight:550;
  padding-inline-end:.08em;
}
.team-intro-copy .brand-wordmark em{
  color:#73e8ff; font-style:normal; font-weight:750;
}
.team-intro-scene{
  position:relative; width:100%; height:100%; min-height:280px;
  display:grid; place-items:center;
}
.team-intro-court, .team-intro-court span{
  position:absolute; inset:0; pointer-events:none;
}
.team-intro-court{ overflow:hidden; }
.team-intro-court::after{
  content:""; position:absolute; inset:0;
  background:
    linear-gradient(90deg,#285f43 0 18%,rgba(40,95,67,.96) 22%,transparent 36%),
    linear-gradient(180deg,rgba(1,10,8,.12),rgba(1,10,8,.3)),
    radial-gradient(78% 82% at 50% 42%,transparent 28%,rgba(1,10,8,.36) 100%);
}
.act-stage .team-intro-court-drift{
  animation:team-intro-court-drift 31s var(--ease-in-out) infinite alternate;
  animation-iteration-count:infinite !important;
}
.act-stage .team-intro-court-rise{
  animation:team-intro-court-rise 23s var(--ease-in-out) infinite alternate;
  animation-iteration-count:infinite !important;
}
.act-stage .team-intro-court-image{
  background:url("../assets/court_1.jpg") 100% center / 145% auto no-repeat;
  background-size:145% auto;
  background-position:100% center;
  animation:team-intro-court-swell 47s var(--ease-in-out) infinite alternate;
  animation-iteration-count:infinite !important;
}
@keyframes team-intro-court-drift{
  from{ transform:translate3d(2.5%,0,0) rotate(.3deg); }
  to{ transform:translate3d(-2.5%,0,0) rotate(-.3deg); }
}
@keyframes team-intro-court-rise{
  from{ transform:translate3d(0,1.6%,0); }
  to{ transform:translate3d(0,-1.6%,0); }
}
@keyframes team-intro-court-swell{
  from{ transform:scale(1.13); }
  to{ transform:scale(1.2); }
}
.team-intro-people{
  position:absolute; z-index:1; left:33.333%; bottom:18%; width:min(670px,92%); height:68%;
  transform:translateX(-50%);
}
.team-intro-person{
  position:absolute; left:50%; bottom:0; width:24%; aspect-ratio:1;
  border-radius:50%; overflow:hidden; background:#f2f0ec;
  border:1px solid rgba(25,25,24,.08); box-shadow:0 16px 32px -22px rgba(25,25,24,.5);
  opacity:0; transform:translate(var(--team-x),14%) scale(.95);
}
.team-intro-person:nth-child(1), .team-intro-person:nth-child(5){ bottom:5%; z-index:1; }
.team-intro-person:nth-child(2), .team-intro-person:nth-child(4){ bottom:12%; z-index:2; }
.team-intro-person:nth-child(3){ bottom:17%; z-index:3; }
.team-intro-person img{ display:block; width:100%; height:100%; object-fit:cover; }
.card.is-team-intro.is-live .team-intro-person{
  animation:team-intro-person .72s var(--ease-out) calc(.32s + var(--team-index) * .07s) both;
}
@keyframes team-intro-person{
  to{ opacity:1; transform:translate(var(--team-x),0) scale(1); }
}

/* 左列：舞台。整幕唯一的亮面，投影负责把它从暗厅里托出来 */
.act-stage{
  position:relative; margin:0; padding:12px 14px 12px;
  background:var(--surface-2); border:0; border-radius:18px;
  box-shadow:var(--shadow);
}

/* 固定对比：标题统领整幕，两种方法始终并列，解说只改变强调层级。 */
.card[data-narration-compare="fixed"]{ display:block; }
.card[data-narration-compare="fixed"] .card-body{
  display:grid; grid-template-rows:auto auto auto auto; gap:0; padding:0;
}
.comparison-header{ margin-bottom:12px; }

.comparison-header .act-eyebrow{ margin-bottom:9px; }
.comparison-columns{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:16px; }
.comparison-panel{
  min-width:0; padding:10px 12px 12px; border:1px solid rgba(241,248,250,.1);
  border-radius:18px; background:var(--paper); color:var(--ink);
  transition:border-color .28s var(--ease-ui), opacity .28s var(--ease-ui),
             transform .34s var(--ease-enter), box-shadow .28s var(--ease-ui);
}
.comparison-panel.is-keymoment{ border-color:rgba(58,206,199,.28); }
.comparison-panel-label{
  display:inline-flex; align-items:center; min-height:22px; margin:0 2px 6px;
  color:var(--muted); font-size:14px; font-weight:700; letter-spacing:.025em;
}
.comparison-panel-label::before{
  content:""; width:6px; height:6px; margin-right:7px; border-radius:50%;
  background:var(--faint);
}
.comparison-panel.is-keymoment .comparison-panel-label{ color:#07535b; }
.comparison-panel.is-keymoment .comparison-panel-label::before{ background:#21a9a5; }
.card[data-narration-compare="fixed"] .act-stage{
  width:100%; height:var(--comparison-stage-height); margin:0; padding:10px 11px;
  border-radius:12px; box-shadow:none;
  background:var(--surface-2); overflow:hidden;
}
.card[data-narration-compare="fixed"] .comparison-panel.is-keymoment .act-stage *{
  animation-play-state:paused !important;
  animation-iteration-count:1 !important;
  animation-fill-mode:both !important;
}
.card[data-narration-compare="fixed"][data-comparison-playback="keymoment"].is-live
  .comparison-panel.is-keymoment .act-stage *{
  animation-play-state:running !important;
}
.parallel-scan{
  --parallel-scan-total:5.2s;
  --parallel-scan-split-delay:.58s;
  --parallel-scan-detect-delay:1.05s;
  --parallel-scan-detect-duration:1.08s;
  --parallel-scan-convert-delay:2.2s;
  --parallel-scan-select-delay:3.36s;
  --parallel-scan-focus-delay:3.78s;
  --parallel-scan-segment-stagger:43ms;
  position:absolute; z-index:3; inset:10px 11px 38px; overflow:hidden;
  border-radius:9px; background:#e9efed; color:#183235; pointer-events:none;
}
.parallel-scan-source{
  position:absolute; inset:18% 7% auto; height:62%; padding:8% 5% 5%;
  border:1px solid rgba(28,66,68,.14); border-radius:9px; background:#f7f9f7;
  box-shadow:0 12px 28px rgba(18,48,49,.1);
}
.parallel-scan-source-head{
  position:absolute; left:5%; right:5%; top:7%; display:flex; align-items:center;
  justify-content:space-between; color:#536d6d; font:650 10px/1 var(--font-mono);
}
.parallel-scan-source-head b{
  padding:3px 5px; border-radius:99px; background:#d8f4ef; color:#08756f;
  font-size:9.5px;
}
.parallel-scan-filmstrip{ display:grid; grid-template-columns:repeat(6,1fr); gap:2px; height:76%; }
.parallel-scan-filmstrip span{ min-width:0; overflow:hidden; background:#173026; }
.parallel-scan-filmstrip img{
  width:170%; height:100%; object-fit:cover; opacity:.86;
  transform:translateX(calc(var(--frame-index) * -7%));
}
.parallel-scan-source-rail{
  position:absolute; left:5%; right:5%; bottom:8%; display:flex; height:2px;
  justify-content:space-around; border-radius:99px; background:#9fb2af;
}
.parallel-scan-source-rail i{ width:2px; height:6px; margin-top:-2px; background:#f28743; }
.parallel-scan-grid{
  position:absolute; inset:8% 6%; display:grid; grid-template-columns:repeat(3,1fr);
  grid-template-rows:repeat(2,1fr); gap:6px; margin:0; padding:0; list-style:none;
}
.parallel-scan-segment{
  position:relative; min-width:0; overflow:hidden; border:1px solid rgba(20,82,79,.18);
  border-radius:6px; background:#f4f4f1; opacity:0;
  transform:translateY(12%) scale(.96);
}
.parallel-video-frame,
.parallel-detection-canvas{ position:absolute; inset:0; overflow:hidden; }
.parallel-video-frame{ background:#172a24; opacity:1; }
.parallel-video-frame img{
  width:118%; height:118%; object-fit:cover; opacity:.82;
  transform:translate3d(calc(var(--frame-index) * -2.7%),calc(var(--frame-index) * -1.1%),0) scale(1.02);
}
.parallel-video-frame::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(180deg,rgba(4,17,14,.08),rgba(4,17,14,.26));
}
.parallel-video-progress{
  position:absolute; z-index:2; left:5%; right:5%; bottom:7%; height:2px;
  border-radius:99px; background:rgba(255,255,255,.42);
}
.parallel-video-progress::before{
  content:""; display:block; width:var(--video-progress); height:100%;
  border-radius:inherit; background:#f28743;
}
.parallel-detection-canvas{
  width:100%; height:100%; background:#f5f5f2; opacity:0;
}
/* 常驻读数：压在所有分镜之上（含 z-index 5 的推镜层），整幕不退场。
   钉在右上角而不是左上角：分镜自己的字幕（「解析运动员每一拍动作 + 羽毛球轨迹」）
   画在画面左上，两者会叠在一起。
   形式是一块技术读数——两行「标签 / 读数」右对齐，一根 hairline 收口——
   而不是加底色加圆角的标签。这一页场景内不放盒子：画面本身已经是唯一的亮面，
   再叠一层容器就成了盒中盒。 */
.parallel-context{
  /* 对齐的是画面本身而不是亮面：画布比亮面左右各内收 11px，
     读数贴着亮面内沿会正好压在画布那根框线上。 */
  position:absolute; z-index:6; right:26px; top:24px; display:grid; gap:2px;
  padding-bottom:6px; border-bottom:1px solid rgba(24,50,53,.16);
  pointer-events:none;
}
.parallel-context-row{
  display:grid; grid-template-columns:auto minmax(56px,auto); column-gap:14px;
  align-items:baseline; white-space:nowrap;
}
/* 标签退一档、读数进一档：一眼先读到 72:36 与 AI × 6 这两个数 */
.parallel-context-row b{
  color:#7d918f; font:550 11px/1.45 var(--font-cn); letter-spacing:.06em;
}
.parallel-context-row i{
  color:#254a4c; font:650 13px/1.45 var(--font-mono); font-style:normal; text-align:right;
}
/* 并行那一行的读数吃这一页的青色：它说的是「AI 在同时跑」，不是一个中性计数 */
.parallel-context-row:last-child i{ color:#08756f; }
.parallel-focus{
  position:absolute; z-index:5; overflow:hidden; border-radius:9px; opacity:0;
  transform:none; transform-origin:left top; pointer-events:none;
  box-shadow:0 16px 34px rgba(18,48,49,.14); will-change:transform,opacity;
}
.parallel-focus-canvas{ display:block; width:100%; height:100%; }
.parallel-scan-segment[data-focus-source="true"]::after{
  content:""; position:absolute; z-index:5; inset:0; border:1px solid rgba(98,234,220,.8);
  border-radius:inherit; opacity:0;
}
.parallel-scan-range{
  position:absolute; left:4px; top:4px; padding:2px 3px; border-radius:3px;
  background:rgba(5,23,22,.68); color:#e4f4f1; font:550 9px/1 var(--font-mono);
}
.parallel-scan-line{
  position:absolute; left:0; right:0; top:0; height:2px; opacity:0;
  background:#62eadc; box-shadow:0 0 9px 2px rgba(98,234,220,.72);
  transform:translateY(0);
}
.parallel-scan.is-scanning{ animation:parallel-scan-exit var(--parallel-scan-total) linear both; }
.parallel-scan.is-scanning .parallel-scan-source{
  animation:parallel-scan-source-out .65s var(--ease-in-out) var(--parallel-scan-split-delay) both;
}
.parallel-scan.is-scanning .parallel-scan-segment{
  animation:parallel-scan-segment-in .55s var(--ease-out)
    calc(var(--parallel-scan-split-delay) + var(--segment-index) * var(--parallel-scan-segment-stagger)) both;
}
.parallel-scan.is-scanning .parallel-video-frame{
  animation:parallel-video-out .65s var(--ease-in-out) var(--parallel-scan-convert-delay) both;
}
.parallel-scan.is-scanning .parallel-detection-canvas{
  animation:parallel-detection-in .65s var(--ease-in-out) var(--parallel-scan-convert-delay) both;
}
.parallel-scan.is-scanning .parallel-scan-line{
  animation:parallel-scan-line var(--parallel-scan-detect-duration) linear
    var(--parallel-scan-detect-delay) both;
}
.parallel-scan.is-scanning .parallel-scan-grid{
  animation:parallel-scan-grid-out .5s var(--ease-out) var(--parallel-scan-focus-delay) both;
}
.parallel-scan.is-scanning .parallel-scan-segment[data-focus-source="true"]::after{
  animation:parallel-focus-source .35s var(--ease-out) var(--parallel-scan-select-delay) both;
}
.parallel-scan.is-scanning .parallel-scan-segment:not([data-focus-source="true"])::after{
  content:""; position:absolute; z-index:5; inset:0; border-radius:inherit;
  background:rgba(233,239,237,.72); opacity:0;
  animation:parallel-segment-dim .45s var(--ease-out) var(--parallel-scan-select-delay) both;
}
@keyframes parallel-scan-source-out{
  to{ opacity:0; transform:scale(.96); }
}
@keyframes parallel-scan-segment-in{
  to{ opacity:1; transform:translateY(0) scale(1); }
}
@keyframes parallel-video-out{
  to{ opacity:0; transform:scale(1.02); }
}
@keyframes parallel-detection-in{
  to{ opacity:1; }
}
@keyframes parallel-scan-line{
  0%{ opacity:0; transform:translateY(0); }
  12%,88%{ opacity:1; }
  100%{ opacity:0; transform:translateY(6200%); }
}
@keyframes parallel-scan-grid-out{
  to{ opacity:0; transform:scale(.96); }
}
@keyframes parallel-focus-source{
  to{ opacity:1; box-shadow:inset 0 0 0 1px rgba(98,234,220,.55); }
}
@keyframes parallel-segment-dim{
  to{ opacity:1; }
}
@keyframes parallel-scan-exit{
  0%,93.75%{ opacity:1; }
  100%{ opacity:0; }
}
@media (prefers-reduced-motion:reduce){
  .parallel-scan[data-reduced-motion="true"]{ --parallel-scan-total:.9s; }
  .parallel-scan[data-reduced-motion="true"] .parallel-scan-source,
  .parallel-scan[data-reduced-motion="true"] .parallel-scan-grid{
    animation:none !important; transform:none;
  }
  .parallel-focus[data-reduced-motion="true"]{ transform:none !important; }
}
.comparison-traditional-visual{
  position:relative; display:grid; place-items:center; width:100%;
  height:var(--comparison-stage-height);
  overflow:hidden; border-radius:12px;
  background:linear-gradient(155deg,#f3f2ef,#e7e5e1);
}
.card[data-narration-compare="fixed"] .act-stage .scene{ width:100%; height:100%; }
.card[data-narration-compare="fixed"] .act-stage .intro-shell{
  width:auto; height:100%; max-width:100%; margin:0 auto;
}
.comparison-visual-object{
  position:relative; display:block; width:45%; height:46%;
  border:2px solid rgba(55,63,66,.42); border-radius:13px;
  background:rgba(255,255,255,.74); box-shadow:0 16px 34px rgba(25,34,38,.09);
}
.comparison-visual-object::before,
.comparison-visual-object::after,
.comparison-visual-object i{ content:""; position:absolute; display:block; }
.comparison-visual-object::before{
  left:12%; right:12%; top:18%; height:43%; border-radius:8px;
  background:linear-gradient(145deg,#d7dbda,#eff0ed);
}
.comparison-visual-object::after{
  left:13%; right:13%; bottom:14%; height:3px; border-radius:99px;
  background:rgba(64,74,77,.18);
}
.comparison-visual-object i:first-child{
  left:15%; bottom:12%; width:7px; height:7px; border-radius:50%; background:var(--crimson);
}
.comparison-visual-object i:nth-child(2),
.comparison-visual-object i:nth-child(3){
  right:-12%; width:27%; height:28%; border:1px solid rgba(61,69,71,.18);
  border-radius:6px; background:#f8f4eb; box-shadow:0 7px 14px rgba(25,34,38,.08);
}
.comparison-visual-object i:nth-child(2){ top:19%; transform:rotate(6deg); }
.comparison-visual-object i:nth-child(3){ top:55%; transform:rotate(-5deg); }
.comparison-traditional-visual.is-replay .comparison-visual-object i:nth-child(2){
  top:30%; right:37%; width:24%; height:24%; border:2px solid #7e8989;
  border-left-color:transparent; border-radius:50%; background:transparent; box-shadow:none;
}
.comparison-traditional-visual.is-replay .comparison-visual-object i:nth-child(3){ display:none; }
.comparison-traditional-visual.is-notes .comparison-visual-object,
.comparison-traditional-visual.is-archive .comparison-visual-object{
  border:0; background:transparent; box-shadow:none;
}
.comparison-traditional-visual.is-notes .comparison-visual-object::before,
.comparison-traditional-visual.is-archive .comparison-visual-object::before{
  inset:12% 10%; height:auto; border:1px solid rgba(61,69,71,.2); background:#f8f4eb;
  box-shadow:-14px 11px 0 #e4e0d7,14px -9px 0 #eeeadf;
}
.comparison-traditional-visual.is-analysis .comparison-visual-object::before{
  left:18%; right:auto; top:39%; width:12%; height:35%; border-radius:3px 3px 0 0;
  background:#a9b1b0; box-shadow:35px -24px #8e9999,70px -8px #a9b1b0,105px -40px #7c8989;
}
.comparison-traditional-visual.is-search .comparison-visual-object::before{
  left:32%; top:21%; width:31%; height:31%; border:6px solid #7c8889;
  border-radius:50%; background:transparent;
}
.comparison-traditional-visual.is-search .comparison-visual-object::after{
  left:58%; top:55%; width:24%; height:6px; background:#7c8889; transform:rotate(45deg);
}

/* 传统复盘场景复用旧版的录像、教练和纸面记录素材；默认状态停在动作结果。 */
.traditional-scene{
  position:relative; width:100%; height:var(--comparison-stage-height); overflow:hidden;
  border-radius:12px; background:linear-gradient(155deg,#f3f2ef,#e7e5e1);
}
.traditional-player{
  position:absolute; z-index:1; left:5%; right:5%; top:5%; bottom:6%; display:grid;
  grid-template-rows:16px minmax(0,1fr) 38px; overflow:hidden; border-radius:9px;
  background:#30383d; box-shadow:0 12px 24px rgba(25,34,38,.16);
}
.traditional-player-chrome{
  display:flex; align-items:center; gap:6px; min-width:0; padding:0 7px;
  color:#93a0a8; font:500 9px/1 var(--font-mono);
}
.traditional-player-chrome > span{ display:flex; gap:3px; }
.traditional-player-chrome i{ width:3px; height:3px; border-radius:50%; background:#77858d; }
.traditional-player-chrome b{ min-width:0; overflow:hidden; color:#d5dcdf; font-weight:550; text-overflow:ellipsis; white-space:nowrap; }
.traditional-player-chrome em{ margin-left:auto; font-style:normal; white-space:nowrap; }
.traditional-player-screen{ position:relative; min-height:0; overflow:hidden; aspect-ratio:auto; background:#17232a; }
.traditional-video{ display:block; width:100%; height:100%; object-fit:cover; filter:saturate(.72) contrast(.96); }
.traditional-stamp{
  position:absolute; left:6px; bottom:5px; padding:2px 4px; border-radius:3px;
  background:rgba(9,18,24,.66); color:#e5eaec; font:550 9px/1.2 var(--font-mono);
}
.traditional-controls{ min-height:0; padding:4px 7px 6px; color:#d8dddd; }
.traditional-rail{ position:relative; display:block; height:3px; border-radius:99px; background:rgba(255,255,255,.22); }
.traditional-rail i{
  position:absolute; inset:0; border-radius:inherit; background:var(--accent);
  transform:scaleX(1); transform-origin:left center;
}
.traditional-rail b{
  position:absolute; left:100%; top:50%; width:5px; height:5px; border-radius:50%;
  background:#fff; transform:translate(-50%,-50%);
}
.traditional-key-mark{
  position:absolute; top:-2px; width:1px; height:7px; background:#f7a96e;
  transform:translateX(-50%);
}
.traditional-control-row{ display:flex; align-items:center; justify-content:space-between; gap:6px; margin-top:6px; }
.traditional-control-group{ display:flex; align-items:center; gap:5px; min-width:0; }
.traditional-control-icon{ width:8px; height:8px; flex:none; fill:#b6c1c6; stroke:#b6c1c6; stroke-width:1.4; }
.traditional-control-icon.is-play{ width:9px; height:9px; fill:var(--accent); stroke:none; }
.traditional-control-icon.is-sound,
.traditional-control-icon.is-fullscreen{ fill:none; stroke-linecap:round; stroke-linejoin:round; }
.traditional-time{ overflow:hidden; font:500 8px/1 var(--font-mono); text-overflow:ellipsis; white-space:nowrap; }
.traditional-time strong{ color:#fff; font-weight:550; }
.traditional-speed{ padding:2px 3px; border-radius:3px; background:rgba(255,255,255,.08); font:550 8px/1 var(--font-mono); }
.traditional-pause-mark{
  position:absolute; left:50%; top:50%; display:flex; gap:3px; padding:7px;
  border-radius:50%; background:rgba(9,18,24,.58); transform:translate(-50%,-50%);
}
.traditional-pause-mark i{ width:3px; height:10px; border-radius:1px; background:#fff; }
.traditional-replay-ring{
  position:absolute; left:50%; top:50%; width:30px; height:30px; border:2px solid rgba(255,255,255,.86);
  border-left-color:transparent; border-radius:50%; opacity:1; transform:translate(-50%,-50%) rotate(320deg);
}
.traditional-review-clock{
  position:absolute; right:6px; top:6px; width:58px; height:15px; overflow:hidden;
  border-radius:4px; background:rgba(9,18,24,.72); color:#fff; font:600 8px/15px var(--font-mono);
}
.traditional-review-clock i{
  position:absolute; left:5px; top:0; opacity:0; color:#f7a96e; font-style:normal;
}
.traditional-review-clock i:last-of-type{ opacity:1; }
.traditional-review-clock em{ position:absolute; right:4px; top:0; color:#aeb9be; font-style:normal; }
.traditional-review-notes{
  position:absolute; z-index:3; right:4%; bottom:6%; width:25%; padding:7px 8px 6px;
  border:1px solid rgba(61,69,71,.14); border-radius:7px; background:#faf5e9;
  box-shadow:0 8px 18px rgba(25,34,38,.14); transform:rotate(2deg);
}
.traditional-review-notes b,
.traditional-review-notes em{ display:block; color:var(--muted); font:650 9px/1.3 var(--font-mono); }
.traditional-review-notes i{
  display:block; width:82%; height:2px; margin:5px 0; border-radius:99px;
  background:rgba(61,69,71,.18); transform-origin:left center;
}
.traditional-review-notes i:nth-of-type(2){ width:64%; }
.traditional-review-notes i:nth-of-type(3){ width:73%; }
.traditional-search-candidate{ opacity:.35; }
.traditional-scene.is-replay .traditional-player{ left:15%; right:4%; top:6%; bottom:6%; }
.traditional-inspection-lens{
  position:absolute; z-index:4; left:50%; top:50%; width:64px; height:64px; opacity:0;
  transform:translate(-50%,-50%) scale(.94); pointer-events:none;
}
.traditional-inspection-lens > span{
  position:absolute; inset:0; overflow:hidden; border:2px solid rgba(255,255,255,.94);
  border-radius:50%; background:#17232a; box-shadow:0 7px 16px rgba(9,18,24,.3);
}
.traditional-inspection-lens::after{
  content:""; position:absolute; right:-9px; bottom:-7px; width:23px; height:4px;
  border-radius:99px; background:#fff; transform:rotate(45deg); transform-origin:left center;
  box-shadow:0 2px 5px rgba(9,18,24,.24);
}
.traditional-inspection-lens img{
  position:absolute; left:-90%; top:-90%; width:280%; height:280%; object-fit:cover;
  transform:translate(18%,20%);
}
.traditional-thinking-coach{
  position:absolute; z-index:3; left:-4%; bottom:-18%; height:42%; object-fit:contain;
  pointer-events:none; transform-origin:45% 30%;
}
.traditional-thought{
  position:absolute; z-index:4; left:8%; top:53%; display:flex; align-items:center; gap:6px;
  padding:9px 13px; border:1px solid rgba(61,69,71,.14); border-radius:99px;
  background:rgba(255,255,255,.92); box-shadow:0 6px 14px rgba(25,34,38,.12);
}
.traditional-thought::after{
  content:""; position:absolute; left:8px; bottom:-8px; width:6px; height:6px;
  border-radius:50%; background:rgba(255,255,255,.92); box-shadow:-5px 5px 0 -1px rgba(255,255,255,.86);
}
.traditional-thought i{ width:7px; height:7px; border-radius:50%; background:var(--navy); opacity:.38; }
.traditional-thought i:nth-child(2){ animation-delay:.08s; }
.traditional-thought i:nth-child(3){ animation-delay:.16s; }
/* 教练插画按舞台高度取百分比，而舞台变高之后宽度没变：同样的百分比会让插画横向长胖，
   把 .traditional-sort-columns（右沿在 65%）那一排压在身下。
   下面几组数按 289/378=0.765 折算，插画在屏上的落位与原来一致。 */
.traditional-coach{ position:absolute; z-index:2; display:block; object-fit:contain; pointer-events:none; }
.traditional-coach.is-watch{ left:0; bottom:-24%; height:55%; }
.traditional-coach.is-write{ left:-2%; bottom:-20%; height:73%; }
.traditional-coach.is-sort{ right:-2%; bottom:-23%; height:63%; }

.traditional-paused-frame{
  position:absolute; left:5%; top:7%; width:36%; padding:4px; border-radius:8px;
  background:#30383d; box-shadow:0 10px 22px rgba(25,34,38,.14);
}
.traditional-paused-frame img{ display:block; width:100%; aspect-ratio:16/9; border-radius:4px; object-fit:cover; filter:saturate(.72); }
.traditional-paused-frame b{
  position:absolute; left:8px; bottom:8px; padding:2px 5px; border-radius:99px;
  background:rgba(156,46,63,.88); color:#fff; font-size:10px; line-height:1.4;
}
.traditional-paper{
  position:absolute; right:5%; top:7%; width:52%; height:84%; padding:5% 5% 4% 12%;
  display:flex; flex-direction:column;
  border:1px solid rgba(61,69,71,.15); border-radius:8px; background:#fbf7ed;
  box-shadow:-8px 8px 0 #e2ded5,0 12px 24px rgba(25,34,38,.1);
}
.traditional-paper::before{ content:""; position:absolute; left:9%; top:0; bottom:0; width:1px; background:rgba(194,94,23,.18); }
.traditional-note-opponent{
  flex:none; padding-bottom:3%; border-bottom:1px solid rgba(61,69,71,.15);
  color:var(--faint); font:650 12px/1.2 var(--font-mono); letter-spacing:.02em;
  white-space:nowrap;
}
.traditional-note-rows{ flex:1; min-height:0; display:grid; grid-template-rows:repeat(4,1fr); }
.traditional-note-row{
  min-height:0; margin:0; padding:4px 0 3px;
  border-bottom:1px solid rgba(61,69,71,.1);
  transform-origin:left center;
}
.traditional-note-row > b,
.traditional-note-row > span{ display:block; white-space:nowrap; }
.traditional-note-row > b{ color:var(--faint); font:600 10px/1.15 var(--font-mono); }
.traditional-note-row > span{ margin-top:1px; color:var(--ink-2); font:500 12px/1.25 var(--font-cn); }
.traditional-note-page{
  flex:none; padding-top:2%; color:var(--faint); font:500 10px/1 var(--font-mono);
  text-align:right;
}
.traditional-note-pile{ position:absolute; left:5%; top:6%; width:58%; height:59%; }
.traditional-summary-note{
  position:absolute; left:var(--note-x,0); top:var(--note-y,0); width:44%; height:29%;
  padding:2% 4%; overflow:hidden; border:1px solid rgba(61,69,71,.15);
  border-left:3px solid var(--note-accent,var(--navy)); border-radius:6px; background:#fbf5e8;
  box-shadow:0 7px 14px rgba(25,34,38,.08);
  transform:translate(var(--tx,0),var(--ty,0)) rotate(var(--r,-2deg));
}
.traditional-summary-note:nth-child(2){ --note-x:49%;--note-y:2%;--r:4deg; }
.traditional-summary-note:nth-child(3){ --note-x:3%;--note-y:35%;--r:-5deg; }
.traditional-summary-note:nth-child(4){ --note-x:52%;--note-y:36%;--r:3deg; }
.traditional-summary-note:nth-child(5){ --note-x:0;--note-y:71%;--r:4deg; }
.traditional-summary-note:nth-child(6){ --note-x:49%;--note-y:69%;--r:-3deg; }
.traditional-summary-note.is-serve{ --note-accent:var(--teal); }
.traditional-summary-note.is-attack{ --note-accent:var(--accent); }
.traditional-summary-note.is-net{ --note-accent:var(--navy); }
.traditional-summary-note > b,
.traditional-summary-note > strong,
.traditional-summary-note > em{ display:block; white-space:nowrap; }
.traditional-summary-note > b{ color:var(--muted); font:650 10px/1 var(--font-mono); }
.traditional-summary-note > strong{ margin-top:3px; color:var(--ink-2); font:700 12px/1.1 var(--font-cn); }
.traditional-summary-note > em{ margin-top:2px; color:var(--faint); font:550 9.5px/1 var(--font-mono); }
.traditional-sort-columns{
  position:absolute; left:6%; right:35%; bottom:15%; display:grid; grid-template-columns:repeat(3,1fr); gap:4px;
}
.traditional-sort-column{
  min-width:0; padding:5px 4px; border:1px solid rgba(20,56,101,.14); border-radius:5px;
  background:rgba(223,230,239,.72); text-align:center;
}
.traditional-sort-column > b,
.traditional-sort-column > em{ display:block; white-space:nowrap; }
.traditional-sort-column > b{ color:var(--navy); font:650 10px/1 var(--font-cn); }
.traditional-sort-column > em{ margin-top:3px; color:var(--muted); font:550 8.5px/1 var(--font-mono); }
.traditional-manual-verdict{
  position:absolute; left:6%; right:35%; bottom:4%; padding:6px 8px; overflow:hidden;
  border-left:3px solid var(--navy); border-radius:4px; background:rgba(223,230,239,.72);
  color:var(--navy); font:700 10.5px/1.2 var(--font-cn); white-space:nowrap;
}

.traditional-athlete-dossier{ position:absolute; left:6%; top:7%; width:60%; height:73%; }
.traditional-athlete-lock{
  position:absolute; left:0; top:0; right:0; display:flex; align-items:center; gap:8px;
  padding:6px 8px; border:1px solid rgba(61,69,71,.14); border-radius:8px;
  background:rgba(255,255,255,.78); box-shadow:0 7px 14px rgba(25,34,38,.07);
}
.traditional-athlete-avatar{ flex:none; width:34px; height:34px; border-radius:50%; object-fit:cover; object-position:center 24%; }
.traditional-athlete-lock > span{ min-width:0; }
.traditional-athlete-name,
.traditional-athlete-lock em{ display:block; white-space:nowrap; }
.traditional-athlete-name{ color:var(--ink); font:700 14px/1.1 var(--font-cn); }
.traditional-athlete-lock em{ margin-top:4px; color:var(--faint); font:550 9px/1 var(--font-mono); }
.traditional-match-files{ position:absolute; left:0; top:31%; width:100%; height:65%; }
.traditional-match-files i{
  position:absolute; left:var(--file-x,0); top:var(--file-y,0); width:46%; height:40%;
  border:1px solid rgba(61,69,71,.14); border-radius:7px; background:#f9f4e8;
  box-shadow:0 8px 16px rgba(25,34,38,.08); transform:rotate(var(--file-r,-5deg));
}
.traditional-match-files i:nth-child(2){ --file-x:50%;--file-y:3%;--file-r:4deg; }
.traditional-match-files i:nth-child(3){ --file-x:3%;--file-y:51%;--file-r:3deg; }
.traditional-match-files i:nth-child(4){ --file-x:52%;--file-y:49%;--file-r:-4deg; }
.traditional-match-files b,
.traditional-match-files span{ position:absolute; left:9%; }
.traditional-match-files b{ top:17%; color:var(--muted); font:650 10px/1 var(--font-mono); }
.traditional-match-files span{ top:47%; color:var(--ink-2); font:650 10px/1 var(--font-cn); white-space:nowrap; }
.traditional-archive-box{
  position:absolute; left:8%; right:36%; bottom:5%; height:20%; border:2px solid rgba(61,69,71,.32);
  border-top:0; border-radius:0 0 7px 7px;
}
.traditional-archive-box span{ position:absolute; bottom:15%; width:25%; height:55%; border-radius:3px; background:#c4c0b7; }
.traditional-archive-box span:nth-child(1){ left:9%; }.traditional-archive-box span:nth-child(2){ left:38%; }.traditional-archive-box span:nth-child(3){ left:67%; }

.traditional-search-files{ position:absolute; left:7%; top:12%; width:60%; height:72%; }
.traditional-search-record{
  position:absolute; left:var(--search-x,0); top:var(--search-y,0); width:46%; height:27%;
  box-sizing:border-box; overflow:hidden; padding:6px 5px 5px 28px;
  border:1px solid rgba(61,69,71,.15); border-radius:6px; background:#faf5e9;
  box-shadow:0 7px 14px rgba(25,34,38,.08); transform:rotate(var(--search-r,-5deg));
}
.traditional-search-record img{
  position:absolute; left:5px; top:50%; width:19px; height:19px; border-radius:50%;
  object-fit:cover; object-position:center 24%; transform:translateY(-50%); filter:saturate(.78);
}
.traditional-search-record b,
.traditional-search-record span{ display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.traditional-search-record b{ color:var(--ink); font:700 11px/1.1 var(--font-cn); }
.traditional-search-record span{ margin-top:4px; color:var(--faint); font:550 8.5px/1 var(--font-cn); }
.traditional-search-record:nth-child(2){--search-x:48%;--search-y:3%;--search-r:5deg}
.traditional-search-record:nth-child(3){--search-x:7%;--search-y:34%;--search-r:4deg}
.traditional-search-record:nth-child(4){--search-x:53%;--search-y:36%;--search-r:-6deg}
.traditional-search-record:nth-child(5){--search-x:0%;--search-y:69%;--search-r:-3deg}
.traditional-search-record:nth-child(6){--search-x:47%;--search-y:68%;--search-r:3deg}
.traditional-magnifier{
  position:absolute; z-index:3; left:34%; top:38%; width:20%; aspect-ratio:1;
  border:4px solid #768383; border-radius:50%; transform:translate(48%,42%);
}
.traditional-magnifier::after{
  content:""; position:absolute; right:-39%; bottom:-20%; width:48%; height:4px;
  border-radius:99px; background:#768383; transform:rotate(45deg);
}

[data-traditional-phase="traditional"] .traditional-rail i{
  animation:traditional-scrub var(--traditional-duration,3600ms) linear both;
}
[data-traditional-phase="traditional"] .traditional-scene.is-timeline .traditional-rail > i{
  animation-name:traditional-manual-scrub;
}
[data-traditional-phase="traditional"] .traditional-scene.is-replay .traditional-rail > i{
  animation-name:traditional-replay-scrub;
}
[data-traditional-phase="traditional"] .traditional-pause-mark{
  animation:traditional-pause var(--traditional-duration,3600ms) var(--ease-out) both;
}
[data-traditional-phase="traditional"] .traditional-replay-ring{
  animation:traditional-replay var(--traditional-duration,3600ms) var(--ease-in-out) both;
}
[data-traditional-phase="traditional"] .traditional-note-row{
  animation:traditional-note-reveal var(--traditional-duration,3500ms) var(--ease-in-out) both;
}
[data-traditional-phase="traditional"] .traditional-note-row:nth-child(2){ animation-delay:.12s; }
[data-traditional-phase="traditional"] .traditional-note-row:nth-child(3){ animation-delay:.24s; }
[data-traditional-phase="traditional"] .traditional-note-row:nth-child(4){ animation-delay:.36s; }
[data-traditional-phase="traditional"] .traditional-summary-note{
  animation:traditional-sort-note var(--traditional-duration,3500ms) var(--ease-in-out) both;
}
[data-traditional-phase="traditional"] .traditional-sort-column,
[data-traditional-phase="traditional"] .traditional-manual-verdict{
  animation:traditional-summary-reveal var(--traditional-duration,3500ms) var(--ease-out) both;
}
[data-traditional-phase="traditional"] .traditional-match-files i{
  animation:traditional-file-stack var(--traditional-duration,3800ms) var(--ease-in-out) both;
}
[data-traditional-phase="traditional"] .traditional-magnifier{
  animation:traditional-search var(--traditional-duration,3500ms) var(--ease-in-out) both;
}
[data-traditional-phase="traditional"] .traditional-scene.is-timeline .traditional-review-clock i:nth-of-type(1){
  animation:traditional-clock-one var(--traditional-duration,3800ms) linear both;
}
[data-traditional-phase="traditional"] .traditional-scene.is-timeline .traditional-review-clock i:nth-of-type(2){
  animation:traditional-clock-two var(--traditional-duration,3800ms) linear both;
}
[data-traditional-phase="traditional"] .traditional-scene.is-timeline .traditional-review-clock i:nth-of-type(3){
  animation:traditional-clock-three var(--traditional-duration,3800ms) linear both;
}
[data-traditional-phase="traditional"] .traditional-scene.is-timeline .traditional-search-candidate{
  animation:traditional-candidate var(--traditional-duration,3800ms) var(--ease-out) both;
}
[data-traditional-phase="traditional"] .traditional-scene.is-timeline .traditional-search-candidate:nth-of-type(2){ animation-delay:.18s; }
[data-traditional-phase="traditional"] .traditional-scene.is-timeline .traditional-search-candidate:nth-of-type(3){ animation-delay:.36s; }
[data-traditional-phase="traditional"] .traditional-scene.is-timeline .traditional-search-candidate:nth-of-type(4){ animation-delay:.54s; }
[data-traditional-phase="traditional"] .traditional-scene.is-timeline .traditional-review-notes i{
  animation:traditional-write var(--traditional-duration,3800ms) var(--ease-in-out) both;
}
[data-traditional-phase="traditional"] .traditional-scene.is-timeline .traditional-coach{
  animation:traditional-focus-coach var(--traditional-duration,3800ms) var(--ease-in-out) both;
}
[data-traditional-phase="traditional"] .traditional-scene.is-replay .traditional-video{
  animation:traditional-fixed-zoom var(--traditional-duration,3700ms) var(--ease-in-out) both;
}
[data-traditional-phase="traditional"] .traditional-scene.is-replay .traditional-inspection-lens{
  animation:traditional-inspect-view var(--traditional-duration,3700ms) var(--ease-in-out) both;
}
[data-traditional-phase="traditional"] .traditional-scene.is-replay .traditional-inspection-lens img{
  animation:traditional-inspect-crop var(--traditional-duration,3700ms) var(--ease-in-out) both;
}
[data-traditional-phase="traditional"] .traditional-scene.is-replay .traditional-thinking-coach{
  animation:traditional-coach-think 1800ms var(--ease-in-out) infinite alternate;
}
[data-traditional-phase="traditional"] .traditional-scene.is-replay .traditional-thought i{
  animation:traditional-thinking-dot 1500ms var(--ease-in-out) infinite;
}
@keyframes traditional-scrub{ from{transform:scaleX(.08)} to{transform:scaleX(1)} }
@keyframes traditional-manual-scrub{ 0%{transform:scaleX(.06)} 24%{transform:scaleX(.31)} 38%{transform:scaleX(.19)} 63%{transform:scaleX(.68)} 76%{transform:scaleX(.52)} 100%{transform:scaleX(.9)} }
@keyframes traditional-replay-scrub{ 0%,8%{transform:scaleX(.48)} 31%{transform:scaleX(.66)} 36%{transform:scaleX(.48)} 64%{transform:scaleX(.66)} 69%{transform:scaleX(.48)} 100%{transform:scaleX(.66)} }
@keyframes traditional-pause{ 0%,32%,66%{opacity:0;transform:translate(-50%,-50%) scale(.94)} 38%,58%,72%,100%{opacity:1;transform:translate(-50%,-50%) scale(1)} }
@keyframes traditional-replay{ 0%{opacity:.2;transform:translate(-50%,-50%) rotate(0deg)} 18%{opacity:1;transform:translate(-50%,-50%) rotate(320deg)} 28%,100%{opacity:0;transform:translate(-50%,-50%) rotate(320deg)} }
@keyframes traditional-clock-one{ 0%,28%{opacity:1} 31%,100%{opacity:0} }
@keyframes traditional-clock-two{ 0%,30%{opacity:0} 33%,62%{opacity:1} 65%,100%{opacity:0} }
@keyframes traditional-clock-three{ 0%,64%{opacity:0} 67%,100%{opacity:1} }
@keyframes traditional-candidate{ 0%,18%{opacity:.2;transform:translateX(-50%) scaleY(.7)} 31%,72%{opacity:1;transform:translateX(-50%) scaleY(1.25)} 86%,100%{opacity:.42;transform:translateX(-50%) scaleY(1)} }
@keyframes traditional-focus-coach{ 0%,18%{transform:translate(0,0) rotate(0deg)} 52%,100%{transform:translate(4%,-2%) rotate(1.5deg)} }
@keyframes traditional-fixed-zoom{ 0%,18%{transform:scale(1)} 32%,88%{transform:scale(1.05)} 100%{transform:scale(1)} }
@keyframes traditional-inspect-view{
  0%,17%{opacity:0;transform:translate(-210%,20%) scale(.94)}
  24%,38%{opacity:1;transform:translate(-210%,20%) scale(1)}
  47%,62%{opacity:1;transform:translate(-50%,-160%) scale(1)}
  71%,88%{opacity:1;transform:translate(100%,40%) scale(1)}
  100%{opacity:0;transform:translate(100%,40%) scale(.94)}
}
@keyframes traditional-inspect-crop{
  0%,38%{transform:translate(18%,20%)}
  47%,62%{transform:translate(-4%,-22%)}
  71%,100%{transform:translate(-22%,14%)}
}
@keyframes traditional-coach-think{ from{transform:translateY(0) rotate(0deg)} to{transform:translateY(-1.5%) rotate(.5deg)} }
@keyframes traditional-thinking-dot{ 0%,100%{opacity:.38;transform:scale(.84)} 50%{opacity:1;transform:scale(1.18)} }
@keyframes traditional-note-reveal{ 0%,15%{opacity:0;transform:translateY(5px)} 18%,100%{opacity:1;transform:none} }
@keyframes traditional-write{ 0%,15%{transform:scaleX(0);opacity:.2} 75%,100%{transform:scaleX(1);opacity:1} }
@keyframes traditional-sort-note{ 0%,18%{transform:translate(0,0) rotate(var(--r,0deg));opacity:.35} 78%,100%{transform:translate(var(--tx,0),var(--ty,0)) rotate(var(--r,0deg));opacity:1} }
@keyframes traditional-summary-reveal{ 0%,52%{opacity:0;transform:translateY(5px)} 78%,100%{opacity:1;transform:none} }
@keyframes traditional-file-stack{ 0%{transform:translateY(-12%) rotate(var(--file-r,-5deg));opacity:0} 22%,100%{transform:translateY(0) rotate(var(--file-r,-5deg));opacity:1} }
@keyframes traditional-search{ 0%{transform:translate(-42%,-35%)} 34%{transform:translate(58%,-28%)} 67%{transform:translate(-18%,48%)} 100%{transform:translate(48%,42%)} }
.comparison-visual-caption{
  position:absolute; left:0; right:0; bottom:8%; color:var(--muted);
  font-size:12px; font-weight:650; text-align:center; letter-spacing:.015em;
}
/* 正文高度的唯一来源是 --narration-body-height（见 .deck 上那条注释）：
   这里再写一次 min-height 只会多出一处对不上的数，真正生效的永远是后面那条 .deck .act-d。 */
.comparison-panel .comparison-copy{
  margin:11px 4px 0; color:var(--muted);
  font-size:16px; line-height:1.65;
}
/* 备赛结论落在亮面板上，色阶换成舞台内部那一套（暗底的 --voice-* 在白纸上读不出来） */
.comparison-copy.is-plan-copy .plan-list{ margin:0; }
.comparison-copy.is-plan-copy .plan-list li{
  margin-top:7px; padding-left:20px; color:var(--muted);
  font-size:15px; line-height:1.55;
}
.comparison-copy.is-plan-copy .plan-list li::before{ top:7px; width:8px; height:8px; }
.comparison-copy.is-plan-copy .plan-list li.is-threat::before{ background:var(--accent); }
.comparison-copy.is-plan-copy .plan-list li.is-weak::before{ background:var(--crimson); }
.comparison-copy.is-plan-copy .plan-list li.is-plan::before{ background:var(--navy); }
.comparison-copy.is-plan-copy .plan-list b{ color:var(--ink); }
.comparison-result-label{
  display:block; margin-bottom:6px; color:var(--accent-on-ground);
  font-size:11px; font-weight:750; letter-spacing:.08em;
}
.card[data-narration-compare="fixed"] .card-foot{
  margin-top:16px; padding:13px 2px 0; border-top:1px solid var(--voice-rule);
}
.card[data-narration-compare="fixed"] .act-stat{
  display:grid; grid-template-columns:minmax(180px,.72fr) minmax(0,1fr);
  align-items:baseline; gap:20px;
}

.deck .card[data-narration-compare="fixed"] .card-body{
  display:grid; grid-template-rows:auto auto auto auto;
}
.deck [data-narration-compare="fixed"] .narration-step{
  position:static; width:auto; margin:0; opacity:.72; visibility:inherit; transform:none;
  pointer-events:auto; transition:opacity .34s var(--ease-ui);
}
.deck [data-narration-compare="fixed"] .comparison-columns{
  grid-template-columns:minmax(0,1fr);
}
.deck [data-narration-compare="fixed"] .comparison-panel{
  --comparison-center-shift:30.65%;
  --comparison-back-shift:-5.2%;
  --comparison-switch-out:18%;
  --comparison-depth-drop:8px;
  --comparison-rest-angle:1.8deg;
  --comparison-shadow-opacity:.65;
  position:relative; grid-area:1/1; width:62%; z-index:1; opacity:1;
  box-shadow:0 22px 52px -28px rgba(0,0,0,.66);
  transition:transform .9s var(--ease-in-out), z-index 0s linear .45s;
  will-change:transform;
  backface-visibility:hidden;
}
.deck [data-narration-compare="fixed"] .comparison-panel::after{
  content:""; position:absolute; z-index:5; inset:0; border-radius:inherit;
  background:var(--ground); opacity:var(--comparison-shadow-opacity); pointer-events:none;
  transition:opacity .45s var(--ease-ui);
}
.deck [data-narration-compare="fixed"]
  .comparison-panel.is-traditional{
  justify-self:start;
  transform:translate3d(var(--comparison-back-shift),var(--comparison-depth-drop),0)
            rotate(calc(var(--comparison-rest-angle) * -1)) scale(.9);
  transform-origin:left center;
}
.deck [data-narration-compare="fixed"]
  .comparison-panel.is-keymoment{
  justify-self:end;
  transform:translate3d(calc(var(--comparison-back-shift) * -1),var(--comparison-depth-drop),0)
            rotate(var(--comparison-rest-angle)) scale(.9);
  transform-origin:right center;
}
.deck [data-narration-compare="fixed"][data-comparison-playback="traditional"]
  .comparison-panel.is-traditional{
  z-index:2; opacity:1;
  transform:translate3d(var(--comparison-center-shift),0,0) rotate(0deg) scale(1);
}
.deck [data-narration-compare="fixed"][data-comparison-playback="keymoment"]
  .comparison-panel.is-keymoment{
  z-index:2; opacity:1;
  transform:translate3d(calc(var(--comparison-center-shift) * -1),0,0) rotate(0deg) scale(1);
}
.deck [data-narration-compare="fixed"][data-comparison-playback="traditional"]
  .comparison-panel.is-traditional::after,
.deck [data-narration-compare="fixed"][data-comparison-playback="keymoment"]
  .comparison-panel.is-keymoment::after{
  opacity:0;
}
.deck [data-narration-compare="fixed"][data-comparison-switch="to-keymoment"]
  .comparison-panel.is-traditional{
  animation:comparison-exit-traditional .9s var(--ease-in-out) both;
}
.deck [data-narration-compare="fixed"][data-comparison-switch="to-keymoment"]
  .comparison-panel.is-keymoment{
  animation:comparison-enter-keymoment .9s var(--ease-in-out) both;
}
.deck [data-narration-compare="fixed"][data-comparison-switch="to-traditional"]
  .comparison-panel.is-traditional{
  animation:comparison-enter-traditional .9s var(--ease-in-out) both;
}
.deck [data-narration-compare="fixed"][data-comparison-switch="to-traditional"]
  .comparison-panel.is-keymoment{
  animation:comparison-exit-keymoment .9s var(--ease-in-out) both;
}
.deck [data-narration-compare="fixed"][data-comparison-switch]
  .comparison-panel.is-traditional::after,
.deck [data-narration-compare="fixed"][data-comparison-switch]
  .comparison-panel.is-keymoment::after{
  animation-duration:.9s; animation-timing-function:var(--ease-in-out); animation-fill-mode:both;
}
.deck [data-narration-compare="fixed"][data-comparison-switch="to-keymoment"]
  .comparison-panel.is-traditional::after,
.deck [data-narration-compare="fixed"][data-comparison-switch="to-traditional"]
  .comparison-panel.is-keymoment::after{
  animation-name:comparison-shadow-exit;
}
.deck [data-narration-compare="fixed"][data-comparison-switch="to-keymoment"]
  .comparison-panel.is-keymoment::after,
.deck [data-narration-compare="fixed"][data-comparison-switch="to-traditional"]
  .comparison-panel.is-traditional::after{
  animation-name:comparison-shadow-enter;
}
@keyframes comparison-enter-traditional{
  0%{z-index:1;transform:translate3d(var(--comparison-back-shift),var(--comparison-depth-drop),0) rotate(calc(var(--comparison-rest-angle) * -1)) scale(.9)}
  38%{z-index:1;transform:translate3d(calc(var(--comparison-switch-out) * -1),var(--comparison-depth-drop),0) rotate(calc(var(--comparison-rest-angle) * -1)) scale(.9)}
  39%{z-index:2;transform:translate3d(calc(var(--comparison-switch-out) * -1),var(--comparison-depth-drop),0) rotate(calc(var(--comparison-rest-angle) * -1)) scale(.9)}
  100%{z-index:2;transform:translate3d(var(--comparison-center-shift),0,0) rotate(0deg) scale(1)}
}
@keyframes comparison-exit-traditional{
  0%{z-index:2;transform:translate3d(var(--comparison-center-shift),0,0) rotate(0deg) scale(1)}
  38%{z-index:2;transform:translate3d(calc(var(--comparison-switch-out) * -1),var(--comparison-depth-drop),0) rotate(calc(var(--comparison-rest-angle) * -1)) scale(.9)}
  39%{z-index:1;transform:translate3d(calc(var(--comparison-switch-out) * -1),var(--comparison-depth-drop),0) rotate(calc(var(--comparison-rest-angle) * -1)) scale(.9)}
  100%{z-index:1;transform:translate3d(var(--comparison-back-shift),var(--comparison-depth-drop),0) rotate(calc(var(--comparison-rest-angle) * -1)) scale(.9)}
}
@keyframes comparison-enter-keymoment{
  0%{z-index:1;transform:translate3d(calc(var(--comparison-back-shift) * -1),var(--comparison-depth-drop),0) rotate(var(--comparison-rest-angle)) scale(.9)}
  38%{z-index:1;transform:translate3d(var(--comparison-switch-out),var(--comparison-depth-drop),0) rotate(var(--comparison-rest-angle)) scale(.9)}
  39%{z-index:2;transform:translate3d(var(--comparison-switch-out),var(--comparison-depth-drop),0) rotate(var(--comparison-rest-angle)) scale(.9)}
  100%{z-index:2;transform:translate3d(calc(var(--comparison-center-shift) * -1),0,0) rotate(0deg) scale(1)}
}
@keyframes comparison-exit-keymoment{
  0%{z-index:2;transform:translate3d(calc(var(--comparison-center-shift) * -1),0,0) rotate(0deg) scale(1)}
  38%{z-index:2;transform:translate3d(var(--comparison-switch-out),var(--comparison-depth-drop),0) rotate(var(--comparison-rest-angle)) scale(.9)}
  39%{z-index:1;transform:translate3d(var(--comparison-switch-out),var(--comparison-depth-drop),0) rotate(var(--comparison-rest-angle)) scale(.9)}
  100%{z-index:1;transform:translate3d(calc(var(--comparison-back-shift) * -1),var(--comparison-depth-drop),0) rotate(var(--comparison-rest-angle)) scale(.9)}
}
@keyframes comparison-shadow-enter{
  0%,39%{opacity:var(--comparison-shadow-opacity)}
  100%{opacity:0}
}
@keyframes comparison-shadow-exit{
  0%,39%{opacity:0}
  100%{opacity:var(--comparison-shadow-opacity)}
}
.deck .card.is-current[data-narration-compare="fixed"]
  .narration-step.is-narration-visible{ opacity:1; visibility:visible; transform:none; }
.deck [data-narration-compare="fixed"] .card-foot{
  position:static; align-self:auto; margin-top:16px; padding:13px 2px 0;
  border-top:1px solid var(--voice-rule); opacity:.5; visibility:inherit; transform:none;
  transition:opacity .34s var(--ease-ui);
}
.deck [data-narration-compare="fixed"] .card-foot::before,
.deck [data-narration-compare="fixed"] .card-foot::after{ display:none; }
.deck [data-narration-compare="fixed"] .card-foot .act-stat .n,
.deck [data-narration-compare="fixed"] .card-foot .act-stat .k{
  opacity:1; transform:none;
}
.deck .card.is-current[data-narration-compare="fixed"]
  .card-foot.is-narration-visible{ opacity:1; visibility:visible; transform:none; }
.deck [data-narration-compare="fixed"] .narration-progress{
  width:100%; margin-top:26px;
}
.scene{ display:block; width:100%; height:auto; }
/* 小程序那套动画按 640×520 构图；这里把上下多余的空白裁掉，只留画面 */
.intro-shell{ position:relative; width:100%; aspect-ratio:var(--shell, 640 / 408); overflow:hidden; }
.intro-canvas{ position:absolute; z-index:1; left:0; top:var(--crop, -8.6%); width:100%; aspect-ratio:var(--intro-ratio, 640 / 520); display:block; }
#act-keyshot .intro-canvas{ top:50%; transform:translateY(-50%); }
#act-keyshot .comparison-panel.is-keymoment .intro-canvas{
  left:50%; width:122%; max-width:none; transform:translate(-50%,-50%);
}

/* 右列：旁白。没有底、没有边，只有字 */
.card-body{ padding:0; }

/* 眉题：一颗章节色圆点 + 章节名，右侧是幕序 */
.act-eyebrow{
  display:flex; align-items:center; gap:8px; margin:0 0 16px;
  color:var(--chapter, var(--accent-on-ground));
}
.act-eyebrow::before{
  content:""; width:7px; height:7px; border-radius:50%; flex:none;
  background:var(--chapter, var(--accent));
}
.act-eyebrow.is-step-only::before{ display:none; }
.act-eyebrow .step{
  margin-left:auto; font-family:var(--font-mono); color:var(--voice-faint);
}
.is-recap .act-eyebrow::before{ display:none; }
.recap-mark{
  position:relative; display:grid; grid-template-columns:repeat(4,3px) 5px;
  align-items:center; gap:4px; width:37px; height:9px; flex:none;
}
.recap-mark::after{
  content:""; position:absolute; left:2px; right:4px; top:50%; height:1px;
  background:linear-gradient(90deg,rgba(230,107,94,.28),var(--accent-on-ground));
  transform:translateY(-50%);
}
.recap-source, .recap-result{
  position:relative; z-index:1; display:block; border-radius:50%;
}
.recap-source{ width:3px; height:3px; background:rgba(241,248,250,.48); }
.recap-result{
  width:5px; height:5px; background:var(--accent-on-ground);
  box-shadow:0 0 0 3px rgba(232,121,42,.08);
}
#act-hall{ --chapter:rgba(241,248,250,.44); }
#act-watch, #act-write, #act-sort, #act-cost{ --chapter:var(--crimson-on-ground); }
#act-parse, #act-keyshot, #act-cluster,
#act-verdict, #act-multi, #act-scout{ --chapter:var(--navy-on-ground); }
#act-summary{ --chapter:var(--accent-on-ground); }

.act-t{
  color:var(--voice);
}
.act-d{ color:var(--voice-2); margin-top:15px; }
.act-p{ display:block; }
.act-p + .act-p{ margin-top:.45em; }
.narration-step{ display:block; text-wrap:wrap; }
.narration-step + .narration-step{ margin-top:.45em; }

/* 解说版只替换正文层，眉题与标题保持稳定；阅读版沿用完整文案排版。 */
.deck .card-body{
  display:grid;
  grid-template-areas:"eyebrow" "title" "narrative" "progress";
  /* 正文那一行的下界写在 .act-d 上，不写在行模板里：写在行上时，
     开场幕与小结这两张没有 .act-d 的卡也会白白留出 6.6em，整卡比对照幕高出一截。 */
  grid-template-rows:auto auto auto auto;
}
.deck .act-eyebrow{ grid-area:eyebrow; }
.deck .act-t{ grid-area:title; }
.deck .act-d{
  grid-area:narrative; position:relative; min-height:var(--narration-body-height);
}
.deck .narration-step{
  position:absolute; inset:0 auto auto 0; width:100%; margin:0;
  opacity:0; visibility:hidden; transform:translateY(7px); pointer-events:none;
  transition:opacity .18s var(--ease-ui), transform .18s var(--ease-ui),
             visibility 0s linear .18s;
}
.deck .card.is-current .narration-step.is-narration-visible{
  opacity:1; visibility:visible; transform:none; pointer-events:auto;
  transition:opacity .32s var(--ease-enter), transform .36s var(--ease-enter), visibility 0s;
}
/* 备赛结论已经搬进 KeyMoment 面板当正文，解说版跟着一起放出来：
   这三行是全页信息密度最高的三行，藏掉等于把这一幕的结论抽走。 */

/* 解说进度只表达一幕内部的时间，不引入百分比或倒计时。 */
.narration-progress{ display:none; }
.deck .narration-progress{
  grid-area:progress; display:block; width:min(78%,280px); margin-top:12px;
}
.narration-progress-track{
  position:relative; display:block; height:2px; border-radius:99px;
  background:rgba(241,248,250,.10);
}
.narration-progress-fill{
  position:absolute; inset:0; border-radius:inherit; background:var(--accent-on-ground);
  box-shadow:0 0 8px rgba(232,121,42,.18);
  transform:scaleX(0); transform-origin:left center;
}
.narration-progress.is-narration-running:not(.is-complete) .narration-progress-fill{
  animation:narration-progress-fill var(--narration-progress-duration) linear forwards;
}
.narration-progress.is-complete .narration-progress-fill{ transform:scaleX(1); }
.narration-progress-node{
  position:absolute; left:var(--narration-progress-position); top:50%;
  width:5px; height:5px; border:1px solid rgba(241,248,250,.30); border-radius:50%;
  background:var(--ground); transform:translate(-50%,-50%);
  transition:background-color .18s var(--ease-ui), border-color .18s var(--ease-ui),
             box-shadow .18s var(--ease-ui);
}
.narration-progress-node.is-reached{
  border-color:var(--accent-on-ground); background:var(--accent-on-ground);
  box-shadow:0 0 0 3px rgba(232,121,42,.08);
}
@keyframes narration-progress-fill{
  from{ transform:scaleX(0); }
  to{ transform:scaleX(1); }
}

/* 阅读版以分割线收口；解说版让结论接替正文，并以关键节点标记形成一幕的落点。 */
.card-foot{ margin-top:26px; padding-top:19px; border-top:1px solid var(--voice-rule); }
.deck .card-foot{
  grid-area:narrative; position:relative; align-self:start;
  margin:15px 0 0; padding:3px 0; padding-left:18px; border-top:0;
  opacity:0; visibility:hidden; transform:translateY(7px);
  transition:opacity .18s var(--ease-ui), transform .18s var(--ease-ui),
             visibility 0s linear .18s;
}
.deck .card-foot::before{
  content:""; position:absolute; left:0; top:3px; bottom:3px; width:2px;
  border-radius:99px; background:linear-gradient(180deg,var(--accent-on-ground),rgba(232,121,42,.26));
  opacity:0; transform:scaleY(0); transform-origin:top;
  transition:opacity .18s var(--ease-ui), transform .48s var(--ease-enter);
}
.deck .card-foot::after{
  content:""; position:absolute; left:-2px; top:2px; width:6px; height:6px;
  border-radius:50%; background:var(--accent-on-ground);
  box-shadow:0 0 0 4px rgba(232,121,42,.10), 0 0 14px rgba(232,121,42,.34);
  opacity:0; transform:scale(.35);
  transition:opacity .2s var(--ease-ui), transform .38s var(--ease-enter);
}
.deck .card-foot .act-stat .n,
.deck .card-foot .act-stat .k{
  opacity:0; transform:translateY(8px);
  transition:opacity .3s var(--ease-ui), transform .46s var(--ease-enter);
}
.deck .card-foot .act-stat .n{
  font-weight:600;
}
.deck .card-foot .act-stat .k{
  margin-top:7px;
}
.deck .card.is-current .card-foot.is-narration-visible{
  opacity:1; visibility:visible; transform:none;
  transition:opacity .36s var(--ease-enter), transform .46s var(--ease-enter), visibility 0s;
}
.deck .card.is-current .card-foot.is-narration-visible::before,
.deck .card.is-current .card-foot.is-narration-visible::after{
  opacity:1; transform:none;
}
.deck .card.is-current .card-foot.is-narration-visible .act-stat .n,
.deck .card.is-current .card-foot.is-narration-visible .act-stat .k{
  opacity:1; transform:none;
}
.deck .card.is-current .card-foot.is-narration-visible .act-stat .n{
  transition-delay:.08s;
}
.deck .card.is-current .card-foot.is-narration-visible .act-stat .k{
  transition-delay:.15s;
}
.deck.is-narration-paused .act-stage *{ animation-play-state:paused !important; }
.deck.is-narration-paused .narration-progress-fill{ animation-play-state:paused !important; }
.act-stat{ display:flex; flex-direction:column; gap:5px; }
.act-stat .n{
  color:var(--voice); font-variant-numeric:tabular-nums;
}
.act-stat .k{ color:var(--voice-faint); }

/* ---------- 换幕时右列文字逐条抬入 ---------- */
.deck .card.is-current .card-body > *{
  animation:act-rise .5s var(--ease-enter) backwards;
}
.deck .card.is-current .card-body > *:nth-child(1){ animation-delay:.18s; }
.deck .card.is-current .card-body > *:nth-child(2){ animation-delay:.24s; }
.deck .card.is-current .card-body > *:nth-child(3){ animation-delay:.30s; }
.deck .card.is-current .card-body > *:nth-child(4){ animation-delay:.36s; }
.deck .card.is-current .card-body > *:nth-child(5){ animation-delay:.42s; }
@keyframes act-rise{
  from{ opacity:0; transform:translateY(10px); }
  to{ opacity:1; transform:none; }
}

/* ---------- 幕四：人工复盘流水线 ---------- */
#act-cost{ --cost-duration:12s; --cost-process-duration:10s; }
#act-cost .act-stage{ overflow:clip; }
.cost-scene{
  transform-origin:77% 55%;
  animation:cost-camera-close var(--cost-duration) var(--ease-in-out);
}
.cost-landscape-back{ fill:rgba(25,45,58,.08); }
.cost-landscape-mid{ fill:rgba(25,45,58,.13); }
.cost-landscape-front{ fill:rgba(25,45,58,.20); }
.cost-daylight{
  fill:#8DC9EC; opacity:1;
  animation:cost-day-pass var(--cost-process-duration) var(--ease-in-out);
}
.cost-sky-sunset{
  fill:#E99656; opacity:0;
  animation:cost-sunset-pass var(--cost-process-duration) var(--ease-in-out);
}
.cost-sky-night{
  fill:#14233F; opacity:0;
  animation:cost-night-arrive var(--cost-process-duration) var(--ease-in-out);
}
.cost-sun{
  fill:#FFE5A2; transform-box:fill-box; transform-origin:center;
  animation:cost-open-sun-arc var(--cost-process-duration) var(--ease-in-out);
}
.cost-moon{
  fill:#F7EBCB; opacity:0; transform-box:fill-box; transform-origin:center;
  animation:cost-moon-rise var(--cost-process-duration) var(--ease-in-out);
}
.cost-stars{
  fill:#FFF7D8; opacity:0;
  animation:cost-night-arrive var(--cost-process-duration) var(--ease-in-out);
}
.cost-desk{
  fill:none; stroke:var(--ink-2); stroke-width:3; stroke-linecap:round; stroke-linejoin:round;
}
.cost-monitor-body{ fill:var(--ink-2); }
.cost-monitor-screen{ fill:var(--screen); }
.cost-monitor-stand{ fill:none; stroke:var(--ink-2); stroke-width:3; stroke-linecap:round; }
.cost-court{ fill:none; stroke:rgba(241,248,250,.36); stroke-width:1.2; }
.cost-player-dot.is-left{ fill:#79A6DE; }
.cost-player-dot.is-right{ fill:#E8792A; }
.cost-shuttle{
  fill:#F1F8FA; transform-box:fill-box; transform-origin:center;
  animation:cost-rally var(--cost-process-duration) var(--ease-in-out);
}
.cost-review-track{ fill:none; stroke:rgba(241,248,250,.22); stroke-width:2; stroke-linecap:round; }
.cost-review-fill{
  fill:none; stroke:var(--accent-on-ground); stroke-width:2; stroke-linecap:round;
  transform-box:fill-box; transform-origin:left center; transform:scaleX(0);
  animation:cost-review-fill var(--cost-process-duration) linear;
}
.cost-review-knob{
  fill:var(--accent-on-ground); transform-box:fill-box; transform-origin:center;
  animation:cost-review-scrub var(--cost-process-duration) var(--ease-in-out);
}
.cost-scene .clock-hour-hand, .cost-scene .clock-minute-hand{
  animation:cost-clock-pass var(--cost-process-duration) linear;
}
.cost-scene .clock-hour-hand{ --cost-clock-turn:120deg; }
.cost-scene .clock-minute-hand{ --cost-clock-turn:1080deg; }
.cost-coach{
  transform-box:fill-box; transform-origin:center bottom;
  animation:cost-coach-tire var(--cost-process-duration) var(--ease-in-out);
}
.cost-coach-head{ fill:#E3B28B; }
.cost-coach-hair{ fill:#242424; }
.cost-coach-face{ fill:none; stroke:#674A3D; stroke-width:1.5; stroke-linecap:round; }
.cost-coach-body{ fill:var(--navy); }
.cost-work-arm{
  transform-box:fill-box; transform-origin:92% 12%;
  animation:cost-work-arm var(--cost-process-duration) var(--ease-in-out);
}
.cost-coach-arm{ fill:none; stroke:var(--navy); stroke-width:10; stroke-linecap:round; stroke-linejoin:round; }
.cost-coach-hand{ fill:#E3B28B; }
.cost-notebook-page{ fill:#FFF; stroke:var(--rule); stroke-width:1.6; }
.cost-note-line{ fill:none; stroke:var(--navy); stroke-width:1.6; stroke-linecap:round; opacity:.6; }
.cost-page{
  fill:#FFF; stroke:var(--rule); stroke-width:1.4; opacity:0;
  transform-box:fill-box; transform-origin:center bottom;
  animation:cost-page-rise .5s var(--ease-out) var(--page-delay);
}
.cost-page.p1{ --page-delay:1.6s; }
.cost-page.p2{ --page-delay:2.8s; }
.cost-page.p3{ --page-delay:4s; }
.cost-page.p4{ --page-delay:5.2s; }
.cost-note{
  fill:var(--accent-tint); stroke:#E4B58F; stroke-width:1.2; opacity:0;
  transform-box:fill-box; transform-origin:center;
  animation:cost-note-scatter .7s var(--ease-out) var(--note-delay);
}
.cost-note.n1{ --note-delay:5.8s; --note-shift:translate(-12px,8px) rotate(-7deg); }
.cost-note.n2{ --note-delay:6.1s; --note-shift:translate(4px,13px) rotate(5deg); }
.cost-note.n3{ --note-delay:6.4s; --note-shift:translate(15px,5px) rotate(-4deg); }
.cost-cup-body{ fill:#FFF; stroke:var(--muted); stroke-width:1.8; }
.cost-cup-handle{ fill:none; stroke:var(--muted); stroke-width:1.8; }
.cost-cup-level{
  fill:#B87445; opacity:.62; transform-box:fill-box; transform-origin:center bottom;
  animation:cost-cup-drain var(--cost-process-duration) linear;
}
.cost-room-night{
  fill:#101A2D; opacity:0; pointer-events:none;
  animation:cost-room-darken var(--cost-process-duration) var(--ease-in-out);
}
.cost-lamp-cone{
  --lamp-opacity:.12; fill:#FFD98A; opacity:0; pointer-events:none;
  animation:cost-lamp-switch-on var(--cost-process-duration) var(--ease-out);
}
.cost-lamp-glow{
  --lamp-opacity:.22; fill:#FFD47D; opacity:0; pointer-events:none;
  animation:cost-lamp-switch-on var(--cost-process-duration) var(--ease-out);
}
.cost-night-structure, .cost-night-papers{
  opacity:0; pointer-events:none;
  animation:cost-night-detail-reveal var(--cost-process-duration) var(--ease-out);
}
.cost-night-structure{ --night-detail-opacity:.62; }
.cost-night-papers{ --night-detail-opacity:.86; }
.cost-night-desk-line{
  fill:none; stroke:#AEBAC0; stroke-width:2.1; stroke-linecap:round; stroke-linejoin:round;
}
.cost-night-paper{ fill:#E9D9B7; stroke:#BD9B68; stroke-width:1.2; }
.cost-night-ink{ fill:none; stroke:#5D4A36; stroke-width:1.7; stroke-linecap:round; }
.cost-lamp-stand{ fill:none; stroke:#44433F; stroke-width:4; stroke-linecap:round; stroke-linejoin:round; }
.cost-lamp-shade{ fill:#E7A947; stroke:#44433F; stroke-width:2; stroke-linejoin:round; }
.cost-lamp-joint{ fill:#44433F; }
.cost-lamp-base{ fill:#44433F; }
.cost-focus-veil{
  fill:#101722; opacity:0; pointer-events:none;
  animation:cost-world-fade var(--cost-duration) var(--ease-in-out);
}
.cost-coach-focus{
  opacity:0; pointer-events:none;
  filter:drop-shadow(0 0 9px rgba(232,121,42,.16));
  animation:cost-coach-focus var(--cost-duration) var(--ease-in-out);
}
.cost-thought{
  position:absolute; z-index:2; left:55%; top:16%; width:41%;
  color:var(--voice); font-family:var(--font-cn); line-height:1;
  letter-spacing:-.035em; text-align:left; pointer-events:none;
}
.cost-thought-kicker, .cost-thought-core, .cost-thought-action{
  display:block; opacity:0;
}
.cost-thought-kicker{
  color:var(--voice-2); font-size:clamp(16px,1.45vw,20px); font-weight:620;
  letter-spacing:.01em;
  animation:cost-thought-arrive var(--cost-duration) var(--ease-out);
}
.cost-thought-core{
  margin-top:.18em; color:var(--accent-on-ground); font-size:clamp(40px,4.15vw,54px);
  font-weight:760; letter-spacing:-.055em;
  transform-origin:center;
  animation:cost-thought-focus var(--cost-duration) var(--ease-out);
}
.cost-thought-action{
  margin:.08em 0 0 .52em; color:var(--voice); font-size:clamp(38px,3.85vw,50px);
  font-weight:740; letter-spacing:-.05em;
  animation:cost-thought-second var(--cost-duration) var(--ease-out);
}
.cost-thought-beam{
  position:absolute; left:-46%; bottom:10%; width:52%; height:1px;
  background:linear-gradient(90deg,rgba(232,121,42,.12),var(--accent-on-ground));
  transform-origin:left center; opacity:0;
  animation:cost-thought-beam var(--cost-duration) var(--ease-in-out);
}
.deck #act-cost.is-live .card-body{
  animation:cost-copy-depart var(--cost-duration) var(--ease-in-out) forwards;
}
@keyframes cost-camera-close{
  0%,72%{ transform:scale(1); }
  90%,100%{ transform:scale(1.58); }
}
@keyframes cost-world-fade{ 0%,76%{opacity:0} 92%,100%{opacity:.97} }
@keyframes cost-coach-focus{ 0%,78%{opacity:0} 90%,100%{opacity:1} }
@keyframes cost-thought-arrive{
  0%,80%{opacity:0;transform:translateY(12px)}
  86%,100%{opacity:1;transform:none}
}
@keyframes cost-thought-second{
  0%,86%{opacity:0;transform:translateY(14px)}
  92%,100%{opacity:1;transform:none}
}
@keyframes cost-thought-focus{
  0%,83%{opacity:0;transform:translateY(14px) scale(.94)}
  90%,100%{opacity:1;transform:none}
}
@keyframes cost-thought-beam{
  0%,86%{opacity:0;transform:rotate(-16deg) scaleX(0)}
  94%,100%{opacity:1;transform:rotate(-16deg) scaleX(1)}
}
@keyframes cost-copy-depart{
  0%,76%{opacity:1;transform:none}
  87%,100%{opacity:0;transform:translateY(-5px)}
}
@keyframes cost-day-pass{ 0%,28%{opacity:1} 72%,100%{opacity:0} }
@keyframes cost-sunset-pass{ 0%,22%{opacity:0} 48%{opacity:1} 76%,100%{opacity:0} }
@keyframes cost-night-arrive{ 0%,46%{opacity:0} 78%,100%{opacity:1} }
@keyframes cost-open-sun-arc{
  0%,22%{opacity:1;transform:translate(0,0)}
  48%{opacity:.86;transform:translate(184px,-18px)}
  72%,100%{opacity:0;transform:translate(365px,136px)}
}
@keyframes cost-moon-rise{
  0%,48%{opacity:0;transform:translateY(24px)}
  78%,100%{opacity:1;transform:none}
}
@keyframes cost-room-darken{ 0%,48%{opacity:0} 78%,100%{opacity:.34} }
@keyframes cost-lamp-switch-on{ 0%,62%{opacity:0} 72%,100%{opacity:var(--lamp-opacity)} }
@keyframes cost-night-detail-reveal{
  0%,62%{opacity:0}
  78%,100%{opacity:var(--night-detail-opacity)}
}
@keyframes cost-clock-pass{ from{transform:rotate(0)} to{transform:rotate(var(--cost-clock-turn))} }
@keyframes cost-rally{
  0%,8%{transform:translate(0,0)} 20%{transform:translate(36px,11px)}
  34%{transform:translate(-8px,18px)} 48%{transform:translate(28px,-3px)}
  62%,100%{transform:translate(2px,12px)}
}
@keyframes cost-review-fill{ from{transform:scaleX(0)} to{transform:scaleX(1)} }
@keyframes cost-review-scrub{
  0%{transform:translateX(0)} 18%{transform:translateX(86px)} 27%{transform:translateX(39px)}
  43%{transform:translateX(118px)} 52%{transform:translateX(73px)} 72%,100%{transform:translateX(140px)}
}
@keyframes cost-work-arm{
  0%,12%{transform:translate(0,0) rotate(0)} 22%,34%{transform:translate(55px,9px) rotate(13deg)}
  42%,50%{transform:translate(4px,0) rotate(1deg)} 60%,75%{transform:translate(57px,12px) rotate(15deg)}
  86%,100%{transform:translate(42px,15px) rotate(10deg)}
}
@keyframes cost-page-rise{
  from{opacity:0;transform:translateY(12px) scale(.96)}
  to{opacity:1;transform:none}
}
@keyframes cost-note-scatter{
  from{opacity:0;transform:translate(0,-18px) rotate(0)}
  to{opacity:1;transform:var(--note-shift)}
}
@keyframes cost-coach-tire{
  0%,48%{transform:translateY(0) rotate(0)}
  76%,100%{transform:translateY(8px) rotate(3deg)}
}
@keyframes cost-cup-drain{ from{transform:scaleY(1)} to{transform:scaleY(.12)} }
/* ---------- 人工复盘：五段流程合并为一条连续时间轴 ---------- */
#act-manual-review{ --manual-duration:12s;
  --s0-duration:9s; --s0-rally:3.4s; --s1-duration:4.8s; --s3-duration:4.4s;
  --chapter:var(--crimson-on-ground);
}
#act-manual-review .act-stage{ overflow:clip; }
.manual-review{
  position:relative; width:100%; aspect-ratio:640/400; overflow:hidden;
  border-radius:10px; background:var(--surface);
}
.manual-review-scene{ position:absolute; inset:0; width:100%; height:100%; }
.manual-capture{ opacity:0; transform-box:view-box; transform-origin:center; }
.manual-capture-ground{ fill:var(--surface); }
.manual-scene-ground{ fill:var(--surface); }
.manual-write, .manual-sort{ opacity:0; transform-box:view-box; transform-origin:center; }

.manual-watch{
  position:absolute; inset:0; z-index:2; overflow:hidden; opacity:0;
  background:var(--surface); transform-origin:center;
}
.manual-watch .player{ width:78%; margin:14px auto 0; }
.manual-watch .coach-back{ left:22%; bottom:-2px; width:min(272px,38%); }
.manual-watch .player-screen{ overflow:hidden; }
.manual-watch .player-video{ width:100%; height:100%; object-fit:cover; }
.manual-watch .s1-lean, .manual-watch .s1-follow{ animation-delay:9s; }
#act-manual-review[data-review-state="paused"] .review-freeze-effect,
#act-manual-review[data-review-state="complete"] .review-freeze-effect{ opacity:1; transform:scale(1); }

.manual-question{
  position:absolute; inset:0; z-index:7; display:grid; place-items:center;
  background:#071018; opacity:0; pointer-events:none; overflow:hidden;
}
.manual-ai-bridge{ width:100%; height:100%; }
.manual-ai-bridge-world{ transform-box:view-box; transform-origin:50% 42%; }
.manual-ai-room{ fill:#071018; }
.manual-ai-screen-light{ opacity:0; transform-box:fill-box; transform-origin:center; }
.manual-ai-screen-light ellipse{ fill:rgba(57,204,199,.13); filter:blur(18px); }
.manual-ai-screen-light rect{ fill:rgba(61,217,210,.1); filter:blur(8px); }
.manual-ai-monitor{ filter:drop-shadow(0 18px 28px rgba(0,0,0,.32)); }
.manual-ai-monitor-frame{ fill:#172630; stroke:rgba(211,226,225,.35); stroke-width:2; }
.manual-ai-monitor-shade{ fill:rgba(5,14,22,.52); stroke:rgba(113,143,147,.28); stroke-width:1; }
.manual-ai-monitor-stand{ fill:none; stroke:rgba(192,208,208,.46); stroke-width:5; stroke-linecap:round; }
.manual-ai-manual-materials{ transform-box:view-box; transform-origin:center bottom; }
.manual-ai-desk{ fill:#172128; }
.manual-ai-paper{ fill:#e8e6df; stroke:rgba(255,255,255,.28); stroke-width:1; }
.manual-ai-manual-materials g path{
  fill:none; stroke:rgba(65,76,78,.52); stroke-width:2; stroke-linecap:round;
}
.manual-ai-coach{ filter:saturate(.7) brightness(.8) drop-shadow(0 12px 20px rgba(0,0,0,.28)); }
.manual-ai-signal{ opacity:0; transform-box:fill-box; transform-origin:center; }
.manual-ai-badge rect{
  fill:rgba(7,23,31,.9); stroke:rgba(99,225,218,.88); stroke-width:2;
  filter:drop-shadow(0 0 14px rgba(58,206,199,.24));
}
.manual-ai-badge-label{
  fill:#dff8f5; font-family:var(--font-en); font-size:31px; font-weight:760; letter-spacing:.03em;
}
.manual-ai-badge-spark{
  fill:#70ddd7; transform-box:fill-box; transform-origin:center;
  filter:drop-shadow(0 0 7px rgba(80,222,215,.68));
}

#act-manual-review.is-live .manual-capture{ animation:manual-capture var(--manual-duration) var(--ease-in-out) both; }
#act-manual-review.is-live .manual-watch{ animation:manual-watch var(--manual-duration) var(--ease-in-out) both; }
#act-manual-review.is-live .manual-write{ animation:manual-write var(--manual-duration) var(--ease-in-out) both; }
#act-manual-review.is-live .manual-sort{ animation:manual-sort var(--manual-duration) var(--ease-in-out) both; }
#act-manual-review.is-live .manual-question{ animation:manual-question var(--manual-duration) var(--ease-out) both; }
#act-manual-review.is-live .manual-ai-bridge-world{ animation:manual-ai-camera-in var(--manual-duration) var(--ease-in-out) both; }
#act-manual-review.is-live .manual-ai-manual-materials{ animation:manual-ai-materials-recede var(--manual-duration) var(--ease-out) both; }
#act-manual-review.is-live .manual-ai-screen-light{ animation:manual-ai-screen-light var(--manual-duration) var(--ease-out) both; }
#act-manual-review.is-live .manual-ai-signal{ animation:manual-ai-signal var(--manual-duration) var(--ease-out) both; }
#act-manual-review.is-live .manual-ai-badge-spark{ animation:manual-ai-badge-spark var(--manual-duration) var(--ease-out) both; }
#act-manual-review.is-live .manual-sort .s3-note-move,
#act-manual-review.is-live .manual-sort .s3-note.is-lost rect,
#act-manual-review.is-live .manual-sort .s3-cols,
#act-manual-review.is-live .manual-sort .s3-book,
#act-manual-review.is-live .manual-sort .s3-out{
  animation-delay:16.9s;
}

@keyframes manual-capture{
  0%,10%{opacity:1;transform:none} 13%,100%{opacity:0;transform:translateX(-2.5%) scale(.98)}
}
@keyframes manual-watch{ 0%,10%{opacity:0;transform:translateY(7px)} 13%{opacity:1;transform:none} 25%{opacity:1;transform:none} 28%,100%{opacity:0;transform:translateY(-5px)} }
@keyframes manual-write{ 0%,25%{opacity:0;transform:translateY(8px)} 28%{opacity:1;transform:none} 39%{opacity:1;transform:none} 42%,100%{opacity:0;transform:translateX(20px)} }
@keyframes manual-sort{ 0%,39%{opacity:0;transform:translateX(18px)} 42%{opacity:1;transform:none} 51%{opacity:1;transform:none} 54%,100%{opacity:0;transform:translateY(-6px)} }
@keyframes manual-question{ 0%,50%{opacity:0;transform:translateY(14px)} 55%,100%{opacity:1;transform:none} }
@keyframes manual-ai-camera-in{
  0%,51%{transform:scale(.985)} 61%{transform:none} 100%{transform:scale(1.055)}
}
@keyframes manual-ai-materials-recede{
  0%,61%{opacity:1;transform:none} 88%,100%{opacity:.24;transform:translateY(5px)}
}
@keyframes manual-ai-screen-light{
  0%,54%{opacity:0;transform:scale(.92)} 70%{opacity:.5;transform:scale(1)}
  100%{opacity:1;transform:scale(1.08)}
}
@keyframes manual-ai-signal{
  0%,66%{opacity:0;transform:scale(.9)} 82%{opacity:1;transform:scale(1.04)}
  100%{opacity:1;transform:scale(1)}
}
@keyframes manual-ai-badge-spark{
  0%,76%{opacity:0;transform:scale(.9)} 88%{opacity:1;transform:scale(1.12)}
  100%{opacity:1;transform:scale(1)}
}
@keyframes manual-question-reduced{
  0%,80%{opacity:0} 100%{opacity:1}
}

/* ---------- 最终总结：两种做法的对照（静态） ----------
   版式与前六幕的对照幕同一个骨架：眉题 + 标题在上，账本与清单在下面并排。
   DOM 由 explainer.js 的 buildSummaryLayout 重排，这里只给栅格。 */
.card.is-static{ display:block; }
.summary-columns{
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:16px; align-items:stretch;
}
/* 与对照面板等高：八幕的标题因此落在同一条线上，翻页时标题不动 */
.summary-columns > *{
  min-height:calc(var(--comparison-stage-height) + var(--comparison-panel-extra)
    + var(--narration-progress-block));
}
.card.is-static .act-stage{
  display:grid; place-items:center; padding:26px 24px; margin:0;
  background:var(--surface);
}
.summary-aside{
  display:grid; align-content:center; padding:26px 22px;
  border:1px solid rgba(241,248,250,.1); border-radius:18px;
  background:rgba(241,248,250,.03);
}
.ledger{ width:min(580px,100%); font-size:14px; }
/* 英文条目比中文长，同样的行距会把这张表撑得比对照面板高一截 */
:root[lang="en"] .ledger{ font-size:13px; }
.ledger-head, .ledger-row{
  display:grid; grid-template-columns:minmax(0,1fr) 8.615em 12.923em; gap:.923em;
}
.ledger-head{ align-items:end; padding-bottom:1.15em; border-bottom:1px solid var(--rule-soft); }
.ledger-title{ font-size:1.115em; font-weight:700; letter-spacing:-.01em; color:var(--ink); }
.ledger-col{ font-size:.846em; font-weight:600; letter-spacing:.02em; }
/* 被比下去的一方不能弱到读不出来，否则这张对照表只剩单边陈述 */
.ledger-col.is-before{ color:var(--muted); }
.ledger-col.is-after{ color:var(--navy); }
.ledger-row{ align-items:baseline; padding:1.15em 0; border-bottom:1px solid var(--rule-soft); }
.ledger-k{ font-size:1em; line-height:1.6; color:var(--muted); }
/* 旧账用等宽体（像抄下来的记录），新结果用正文体 */
.ledger-before{ font-family:var(--font-mono); font-size:.923em; line-height:1.6; color:var(--muted); }
.ledger-after{ font-size:.962em; line-height:1.6; color:var(--ink-2); }
.ledger-row.is-total{ border-bottom:0; padding:1.6em 0 0; }
.ledger-row.is-total .ledger-k{ color:var(--ink); font-weight:700; }
.ledger-row.is-total .ledger-before{
  font-family:var(--font-mono); font-size:.923em; font-weight:500; letter-spacing:0;
  color:var(--muted);
}
.ledger-row.is-total .ledger-after{ font-size:1em; font-weight:700; color:#075b63; }

/* 优势清单：Notion 的勾选清单，勾用海军蓝 */
.win-list{ margin:0; padding:0; list-style:none; }
.win-list li{
  position:relative; padding-left:26px; margin-top:13px;
  font-size:14.5px; line-height:1.8; color:var(--voice-2);
}
.win-list li:first-child{ margin-top:0; }
.win-list li::before{
  content:""; position:absolute; left:2px; top:9px;
  width:11px; height:6px;
  border-left:2px solid var(--accent-on-ground); border-bottom:2px solid var(--accent-on-ground);
  transform:rotate(-45deg);
}
.win-list b{ color:var(--voice); font-weight:700; }

/* 对手档案的三条：圆点颜色与舞台上的三条球路对应 */
.plan-list{ margin:16px 0 0; padding:0; list-style:none; }
.plan-list li{
  position:relative; padding-left:22px; margin-top:11px;
  font-size:14.5px; line-height:1.78; color:var(--voice-2);
}
.plan-list li:first-child{ margin-top:0; }
.plan-list li::before{
  content:""; position:absolute; left:0; top:11px;
  width:9px; height:9px; border-radius:50%; background:var(--voice-faint);
}
.plan-list li.is-threat::before{ background:var(--accent-on-ground); }
.plan-list li.is-weak::before{ background:var(--crimson-on-ground); }
.plan-list li.is-plan::before{ background:var(--navy-on-ground); }
.plan-list b{ color:var(--voice); font-weight:700; }

/* ============================================================
   场景通用元素
   ============================================================ */
.sv-panel{ fill:var(--surface); stroke:var(--rule); stroke-width:1.2; }
.sv-video{ fill:var(--screen); }
.sv-sheet{ fill:var(--surface); stroke:var(--rule); stroke-width:1.2; }
.sv-sheet.back1{ fill:var(--surface); }
.sv-sheet.back2{ fill:var(--surface-3); stroke:none; }
.sv-hud{ font-family:var(--font-mono); font-size:11px; fill:var(--screen-fg); }
.sv-hud.dim{ fill:#5C6E86; }
.sv-lgd{ font-family:var(--font-cn); font-size:11.5px; fill:var(--faint); }
.sv-lgd.key{ fill:var(--accent); }
.sv-badge-t{ font-family:var(--font-cn); font-size:11px; fill:var(--accent); text-anchor:middle; }

/* SVG 元素的 transform-origin 默认按 viewBox 百分比解析；
   本页所有动画元素都以自身局部原点为锚，统一压成 0 0。 */
.scene *, .coach-back *{ transform-origin:0 0; }

/* 未进入视口时停在第 0 帧，进入后开始播放；重播时先整体断开动画 */
.act-stage *{
  animation-play-state:paused;
  animation-iteration-count:1 !important;
  animation-fill-mode:forwards !important;
}
.act.is-live .act-stage *{ animation-play-state:running; }
.act.is-reset .act-stage *{ animation:none !important; }

/* ============================================================
   职业教练：三幕使用同一人物的高保真透明插画
   ============================================================ */
.fig-desk{ fill:var(--rule); }
.fig-stack rect{ fill:var(--surface-3); stroke:var(--rule); stroke-width:1; }
.fig-cup path{ fill:var(--accent-tint); stroke:var(--accent); stroke-width:1.4; }
.coach-art{ pointer-events:none; image-rendering:auto; }
.coach-art-watch{ filter:drop-shadow(0 2px 2px rgba(8,20,36,.16)); }
.coach-art-write{ filter:drop-shadow(0 3px 3px rgba(8,20,36,.12)); }
.coach-art-sort{ filter:drop-shadow(0 3px 3px rgba(8,20,36,.1)); }

.time-flow-clock{ pointer-events:none; }
.clock-face{ fill:rgba(255,253,248,.96); stroke:var(--navy); stroke-width:1.6; }
.clock-ticks path{ fill:none; stroke:var(--faint); stroke-width:1.4; stroke-linecap:round; }
.clock-hour-hand, .clock-minute-hand{ animation:clock-spin linear infinite; }
.clock-hour-hand{ animation-duration:18s; }
.clock-minute-hand{ animation-duration:3s; }
.clock-hour-hand path{ fill:none; stroke:var(--navy); stroke-width:3; stroke-linecap:round; }
.clock-minute-hand path{ fill:none; stroke:var(--accent); stroke-width:2.2; stroke-linecap:round; }
.clock-pin{ fill:var(--accent); stroke:var(--surface); stroke-width:1; }
@keyframes clock-spin{ to{ transform:rotate(360deg); } }
.fig-mouse{ fill:var(--surface-3); stroke:var(--rule); stroke-width:1.2; }
.fig-mouse-line{ fill:none; stroke:var(--rule); stroke-width:1.2; }

/* ============================================================
   幕零：体育馆里，他把这场比赛录下来
   构图与幕一同源（真实录像在上、教练背影压住下沿），差别在于这里没有播放器外壳——
   幕零是比赛本来的样子，幕一是它被关进播放器之后的样子。
   ============================================================ */
#act-hall{ --s0-duration:9s; }
.hall{ position:relative; }
.scene-0{ display:block; width:100%; height:auto; }

/* 三维球场：线宽与色阶跟幕八的战术档案卡一致，两处画的是同一片场地。
   被录制的那一片是主体；同一个馆里其余场地压淡，只交代「不止这一片」。 */
.s0-line-out{ fill:none; stroke:var(--ink-2); stroke-width:1.4; opacity:.55; }
.s0-line-in{ fill:none; stroke:var(--rule); stroke-width:1; }
.s0-net3d{ fill:none; stroke:var(--ink-2); stroke-width:1.2; opacity:.34; }

/* 运动员：近端铜橙、远端海军蓝，与全页的两方分色一致 */
.s0-p-line{ fill:none; stroke-width:2.2; stroke-linecap:round; }
.s0-p-line.is-arm{ stroke-width:2; }
.s0-player.is-near .s0-p-head, .s0-player.is-near .s0-p-racket{ fill:var(--accent); }
.s0-player.is-near .s0-p-line{ stroke:var(--accent); }
.s0-player.is-near .s0-p-racket{ fill:none; stroke:var(--accent); stroke-width:1.6; }
.s0-player.is-far .s0-p-head{ fill:var(--navy); }
.s0-player.is-far .s0-p-line{ stroke:var(--navy); }
.s0-player.is-far .s0-p-racket{ fill:none; stroke:var(--navy); stroke-width:1.4; }
.s0-player.is-far .s0-p-line{ stroke-width:1.8; }

/* 陪衬场地的人压淡。与上面的 .is-near / .is-far 同特异度，
   靠源码顺序决胜——这几条必须写在它们之后，否则不生效。 */
.s0-court3d.is-back{ opacity:.42; }
.s0-player.is-back{ opacity:.7; }
.s0-player.is-back .s0-p-head{ fill:var(--faint); }
.s0-player.is-back .s0-p-line{ stroke:var(--faint); stroke-width:1.9; }
.s0-player.is-back .s0-p-racket{ fill:none; stroke:var(--faint); stroke-width:1.3; }

/* 轨迹线：同一时刻只显示正在被打的那一条。
   弧线随羽毛球一起划出来，球飞到对面时这条收掉、另一条接上。
   两段弧长只差 1.1%（顶点 2.9 m / 3.5 m），按 50% 切换与球的错位约 39 ms，看不出来，
   因此关键帧用固定百分比即可，不必按实际弧长动态算。 */
.s0-route{
  fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round;
  stroke-dashoffset:var(--len, 240); opacity:0;
  animation:s0-route-near var(--s0-rally) linear infinite;
}
.s0-route.is-near{ stroke:var(--accent); }
.s0-route.is-far{ stroke:var(--navy); animation-name:s0-route-far; }
@keyframes s0-route-near{      /* 近端击出的那一条：前半程 */
  0%          { stroke-dashoffset:var(--len, 240); opacity:.6; }
  48%         { stroke-dashoffset:0; opacity:.6; }
  52%, 100%   { stroke-dashoffset:0; opacity:0; }
}
@keyframes s0-route-far{       /* 远端回过来的那一条：后半程 */
  0%, 48%     { stroke-dashoffset:var(--len, 240); opacity:0; }
  52%         { stroke-dashoffset:var(--len, 240); opacity:.6; }
  100%        { stroke-dashoffset:0; opacity:.6; }
}

/* 一个来回：球沿这两段弧往返，落脚随之左右挪一点 */
#act-hall{ --s0-rally:3.4s; }
.s0-shuttle{
  fill:var(--ink); offset-rotate:0deg;
  animation:s0-fly var(--s0-rally) linear infinite;
}
@keyframes s0-fly{ from{ offset-distance:0%; } to{ offset-distance:100%; } }
.s0-player{ animation:s0-shift var(--s0-rally) var(--ease-in-out) infinite; }
.s0-player.is-far{ animation-delay:calc(var(--s0-rally) / -2); }
@keyframes s0-shift{
  0%,100%{ transform:translate(0,0); }
  50%    { transform:translate(6px,2px); }
}

/* 落地阴影：让教练与三脚架站在地面上，而不是浮在球场旁边 */
.s0-shadow{ fill:rgba(25,25,24,.09); }
.s0-shadow.is-soft{ fill:rgba(25,25,24,.06); }

/* 手机 + 三脚架 */
.s0-leg, .s0-post{ fill:none; stroke:var(--faint); stroke-width:2.4; stroke-linecap:round; }
.s0-clamp{ fill:var(--faint); }
.s0-phone-body{ fill:var(--ink-2); }
.s0-phone-screen{ fill:#1D3552; }
.s0-phone-lens{ fill:rgba(241,248,250,.45); }
.s0-rec-dot{ fill:#F4573B; animation:s0-rec 1.6s steps(1,end) infinite; }
.s0-rec-t{ font-family:var(--font-mono); font-size:8.5px; letter-spacing:.14em; fill:#DCE6F0; }
@keyframes s0-rec{ 0%,49%{ opacity:1; } 50%,100%{ opacity:.16; } }

/* 教练：线稿，比场上两人大一号（他在前景），墨色以便与铜橙／海军蓝两名运动员分开 */
.s0-c-head{ fill:var(--ink-2); }
.s0-c-line{ fill:none; stroke:var(--ink-2); stroke-width:2.6; stroke-linecap:round; }
.s0-c-line.is-point{ stroke:var(--accent); }
.s0-c-cap{ fill:var(--crimson); }
.s0-c-brim{ fill:none; stroke:var(--crimson); stroke-width:3.2; stroke-linecap:round; }
.s0-c-board{ fill:var(--surface); stroke:var(--ink-2); stroke-width:1.8; }
.s0-c-board-line{ fill:none; stroke:var(--faint); stroke-width:1.4; stroke-linecap:round; }

/* .act-stage * 把迭代次数统一压成 1（重播时好从第 0 帧重来）。
   这一幕是一个不断继续的回合，球、人、录制指示灯与两条轨迹线都要一直跟着走，故单独放开。 */
#act-hall .s0-shuttle, #act-hall .s0-player, #act-hall .s0-rec-dot, #act-hall .s0-route,
#act-manual-review .s0-shuttle, #act-manual-review .s0-player,
#act-manual-review .s0-rec-dot, #act-manual-review .s0-route{
  animation-iteration-count:infinite !important;
}

/* ============================================================
   幕一：教练盯着屏幕看 + 播放器（HTML + 真实比赛录像）
   三次击球瞬间暂停 2 s，进度由真实视频时间驱动。
   ============================================================ */
#act-watch{ --s1-duration:10.4s; }
/* 镜头在教练身后：屏幕在上，他的后脑勺挡住屏幕下沿 */
.watch{ position:relative; }
.coach-back{ position:absolute; left:50%; bottom:0; transform:translateX(-50%);
  width:min(272px,38%); height:auto; z-index:2; }
.coach-back .s1-follow{ transform-origin:150px 82px; }

/* 看录像时的微动作：身体随播放起伏，每次暂停或继续时往屏幕凑近。 */
.s1-lean{ animation:s1-lean var(--s1-duration) var(--ease-in-out); }
@keyframes s1-lean{
  0%,9%    { transform:translate(0,0); }
  11.5%,14%,28%{ transform:translate(0,-4px); }
  31%,43%  { transform:translate(0,0); }
  46%,49%,62%{ transform:translate(0,-4px); }
  65%,78%  { transform:translate(0,0); }
  81%,100% { transform:translate(0,-4px); }
}
.s1-follow{ animation:s1-follow var(--s1-duration) var(--ease-in-out); }
@keyframes s1-follow{
  0%,100% { transform:rotate(0deg); }
  16%     { transform:rotate(2.4deg); }
  34%     { transform:rotate(-2.4deg); }
  52%     { transform:rotate(1.8deg); }
  70%     { transform:rotate(-2deg); }
  86%     { transform:rotate(1.4deg); }
}

.player{
  border-radius:12px; overflow:hidden; background:var(--screen);
  box-shadow:var(--shadow-media);
}
.player-chrome{
  display:flex; align-items:center; gap:8px; padding:0 14px; height:34px;
  background:#0A1A2E; border-bottom:1px solid rgba(255,255,255,.07);
}
.chrome-dot{ width:9px; height:9px; border-radius:50%; background:rgba(255,255,255,.16); flex:none; }
.chrome-file{
  flex:1; margin-left:8px; font-family:var(--font-mono); font-size:11px;
  color:#9DB0C8; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.chrome-size{ font-family:var(--font-mono); font-size:10.5px; color:#5C6E86; flex:none; }

.player-screen{ position:relative; background:#000; line-height:0; }
.player-video{ display:block; width:100%; height:auto; }
.review-freeze-effect{
  position:absolute; inset:0; z-index:2; pointer-events:none; opacity:0;
  background:rgba(14,32,56,.08); box-shadow:inset 0 0 0 2px var(--accent);
  transform:scale(1.01); transform-origin:center;
  transition:opacity 120ms var(--ease-out), transform 120ms var(--ease-out);
}
#act-watch[data-review-state="paused"] .review-freeze-effect,
#act-watch[data-review-state="complete"] .review-freeze-effect{
  opacity:1; transform:scale(1);
  transition-duration:160ms;
}
.review-freeze-corner{ position:absolute; width:28px; height:28px; border-color:var(--accent); }
.review-freeze-corner.is-tl{ top:10px; left:10px; border-top:4px solid var(--accent); border-left:4px solid var(--accent); }
.review-freeze-corner.is-tr{ top:10px; right:10px; border-top:4px solid var(--accent); border-right:4px solid var(--accent); }
.review-freeze-corner.is-bl{ bottom:10px; left:10px; border-bottom:4px solid var(--accent); border-left:4px solid var(--accent); }
.review-freeze-corner.is-br{ right:10px; bottom:10px; border-right:4px solid var(--accent); border-bottom:4px solid var(--accent); }
.review-pause-badge{
  position:absolute; top:12px; right:12px; display:flex; align-items:center; gap:6px;
  padding:6px 10px; border:1px solid rgba(194,94,23,.8); border-radius:6px;
  background:rgba(8,20,36,.82); color:#F7E9DC; font-family:var(--font-cn);
  font-size:11px; font-weight:600; line-height:1;
}
.review-pause-badge svg{ width:13px; height:13px; fill:var(--accent); }
.review-pause-badge b{ color:#FFD4B2; font-family:var(--font-mono); font-weight:600; }
.player-stamp{
  position:absolute; left:12px; bottom:12px; padding:4px 9px; border-radius:5px;
  background:rgba(8,14,24,.62); font-family:var(--font-mono); font-size:11px; color:#C6D4E6;
  line-height:1.4; z-index:3;
}

.player-controls{ position:relative; padding:8px 14px 12px; }
.scrub{ position:relative; height:16px; }
.scrub-rail{ position:absolute; left:0; right:0; top:5px; height:4px; border-radius:2px;
  background:rgba(255,255,255,.16); }
.scrub-key-mark{
  position:absolute; top:-3px; width:3px; height:10px; border-radius:2px;
  background:var(--accent); transform:translateX(-50%);
}
.scrub-played{
  position:absolute; left:0; top:5px; height:4px; border-radius:2px; width:70%;
  background:var(--accent); transform:scaleX(var(--review-progress-scale,.257143));
  transform-origin:left center;
}
.scrub-played::after{
  content:""; position:absolute; right:-6px; top:-4px; width:12px; height:12px;
  border-radius:50%; background:var(--accent); box-shadow:0 0 0 3px rgba(194,94,23,.25);
}
.ctl-row{ display:flex; align-items:center; justify-content:space-between; gap:16px; margin-top:2px; }
.ctl-group{ display:flex; align-items:center; gap:12px; }
.ctl-btn{ width:17px; height:17px; fill:#A8BACE; stroke:none; flex:none; }
.ctl-btn.is-play{ width:19px; height:19px; fill:var(--accent); }
.ctl-pause-icon{ display:none; }
#act-watch[data-review-state="playing"] .ctl-play-icon{ display:none; }
#act-watch[data-review-state="playing"] .ctl-pause-icon{ display:block; }
.ctl-btn.is-mini{ width:15px; height:15px; fill:none; stroke:#7F92A8; stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round; }
.ctl-time{ font-family:var(--font-mono); font-size:11.5px; color:#7F92A8; margin-left:4px; }
.ctl-time b{ color:#DCE6F2; font-weight:500; }
.ctl-chip{
  font-family:var(--font-mono); font-size:10.5px; color:#9DB0C8;
  border:1px solid rgba(255,255,255,.18); border-radius:4px; padding:2px 6px;
}

/* 光标停在播放／暂停键上，三次暂停、两次继续。 */
.player-cursor{ position:absolute; left:50px; bottom:4px; width:16px; height:20px;
  animation:s1-press var(--s1-duration) linear; }
.player-cursor svg{ width:16px; height:20px; fill:#F2F6FB; stroke:rgba(6,11,18,.55); stroke-width:1.4; }
.cursor-ping{
  position:absolute; left:-8px; top:-8px; width:28px; height:28px; border-radius:50%;
  border:1.6px solid var(--accent); opacity:0; animation:s1-ping var(--s1-duration) linear;
}
@keyframes s1-press{
  0%,10.5% { transform:translate(0,0); }
  11.5%    { transform:translate(0,3px); }
  12.5%,29.8%{ transform:translate(0,0); }
  30.8%    { transform:translate(0,3px); }
  31.8%,45.2%{ transform:translate(0,0); }
  46.2%    { transform:translate(0,3px); }
  47.2%,64.4%{ transform:translate(0,0); }
  65.4%    { transform:translate(0,3px); }
  66.4%,79.8%{ transform:translate(0,0); }
  80.8%    { transform:translate(0,3px); }
  81.8%,100%{ transform:translate(0,0); }
}
@keyframes s1-ping{
  0%,10.5% { transform:scale(.4); opacity:0; }
  11.5%    { transform:scale(.4); opacity:.9; }
  15%      { transform:scale(1); opacity:0; }
  29.8%    { transform:scale(.4); opacity:0; }
  30.8%    { transform:scale(.4); opacity:.9; }
  34.3%    { transform:scale(1); opacity:0; }
  45.2%    { transform:scale(.4); opacity:0; }
  46.2%    { transform:scale(.4); opacity:.9; }
  49.7%    { transform:scale(1); opacity:0; }
  64.4%    { transform:scale(.4); opacity:0; }
  65.4%    { transform:scale(.4); opacity:.9; }
  68.9%    { transform:scale(1); opacity:0; }
  79.8%    { transform:scale(.4); opacity:0; }
  80.8%    { transform:scale(.4); opacity:.9; }
  84.3%,100%{ transform:scale(1); opacity:0; }
}


/* ============================================================
   幕七：战术聚类（周期 15s）— 多回合抽取完整关键拍集合，再统一分类
   ============================================================ */
/* 抽取这一段要看得清「先圈住、再出卡」，15s 里塞不下：整幕放到 18s，
   多出来的三秒全给前半段（圈 → 卡 → 飞到网格），后半段的归集节奏不变。
   --s7-step 是逐拍的错峰量：八拍依次亮起来，而不是一起冒出来。 */
.scene-7{ --s7-duration:8.7s; --s7-step:100ms; }
.s7-source{ animation:s7-source var(--s7-duration) var(--ease-out) infinite; }
.s7-source-label{
  font-family:var(--font-cn); fill:var(--muted); font-size:16px; font-weight:650; text-anchor:middle;
}
.s7-rally-plate{ fill:rgba(255,255,255,.76); stroke:var(--rule-soft); stroke-width:1; }
.s7-rally-label{ font-family:var(--font-mono); fill:var(--faint); font-size:15px; font-weight:650; }
/* 零线是这张图唯一的标尺：曲线在它上面还是下面，就是占优还是受压。
   去掉颜色编码之后，符号全靠「在线的哪一边」读出来，这根线因此必须先看得见——
   实线、比曲线略淡，量足够指示，又不会跟曲线抢。 */
.s7-rally-zero{ stroke:rgba(61,69,71,.32); stroke-width:1; }
/* 曲线一律单色细线，不做渐变、也不按零线分成两种颜色。
   六条曲线并排时，两段色差会让每一条自己先分成两截，六条就是十二段颜色，
   画面读起来是一片碎色而不是六条走势；面积填充同理，一并去掉。
   曲线安静下来之后，铜橙的那个圈才是这一幕唯一的重音——「就是这一拍」。 */
.s7-situation-curve{
  fill:none; stroke:var(--navy); stroke-width:1.4; opacity:.52;
  stroke-linecap:round; stroke-linejoin:round;
}
/* 关键拍的标记分两层：一个从大收拢到位的圈（这一步是「圈出来」），
   和圈心那颗实点（这一步是「就是它」）。圈定住之后，卡片才从这里浮出来。 */
.s7-peak-ring{
  fill:none; stroke:var(--accent); stroke-width:1.6; opacity:0;
  transform-box:fill-box; transform-origin:center;
  animation:s7-peak-ring var(--s7-duration) var(--ease-out) calc(var(--peak-order) * var(--s7-step));
}
.s7-curve-peak{
  fill:var(--accent); stroke:rgba(255,255,255,.9); stroke-width:1.2; opacity:0;
  transform-box:fill-box; transform-origin:center;
  animation:s7-peak var(--s7-duration) var(--ease-out) calc(var(--peak-order) * var(--s7-step));
}
.s7-status{ opacity:0; animation:s7-status var(--s7-duration) var(--ease-out) infinite; }
.s7-collection-status{
  font-family:var(--font-cn); fill:var(--ink-2); font-size:17px; font-weight:700; text-anchor:middle;
}
.s7-scan{
  stroke:rgba(194,94,23,.64); stroke-width:2; stroke-linecap:round; opacity:0;
  filter:drop-shadow(0 0 5px rgba(194,94,23,.42));
  animation:s7-scan var(--s7-duration) var(--ease-in-out) infinite;
}
/* 曲线要在卡片长到满尺寸之前退场，否则八张卡会把六条曲线整片盖住 */
@keyframes s7-source{
  0%,32%{ opacity:1; }
  40%,100%{ opacity:0; }
}
@keyframes s7-peak-ring{
  0%,10%  { opacity:0; transform:scale(2.6); }
  16%     { opacity:1; transform:scale(1); }
  26%     { opacity:1; transform:scale(1); }
  34%,100%{ opacity:0; transform:scale(1); }
}
@keyframes s7-peak{
  0%,8%   { opacity:0; transform:scale(.6); }
  14%,30% { opacity:1; transform:scale(1); }
  36%,100%{ opacity:0; transform:scale(1); }
}
@keyframes s7-status{
  0%,44%{ opacity:0; }
  50%,62%{ opacity:1; }
  68%,100%{ opacity:0; }
}
@keyframes s7-scan{
  0%,58%{ opacity:0; transform:translateX(0); }
  61%{ opacity:1; transform:translateX(0); }
  70%{ opacity:1; transform:translateX(548px); }
  73%,100%{ opacity:0; transform:translateX(548px); }
}
.s7-ring{ fill:none; stroke:var(--rule); stroke-width:1.4; }
.s7-ring.t-accent{ stroke:#E7C6A5; }
.s7-ring.t-navy{ stroke:#B9CBE6; }
.s7-ring.t-teal{ stroke:#A9CFDA; }
.s7-ring.t-indigo{ stroke:#BCC2E6; }
.s7-label{ font-family:var(--font-cn); font-size:19px; font-weight:700; fill:var(--ink); text-anchor:middle; }
/* 类目名后面挂读数：圈里的点数就是这个数，抽象的点因此有了量纲 */
.s7-count{ font-family:var(--font-mono); font-size:15px; font-weight:600; fill:var(--faint); }

/* ---------- 场景内的英文字号 ----------
   场景是按中文构图的：同一句话换成拉丁文字要长一倍上下，方块字塞得进去的槽位，
   英文会直接顶出卡片或画框。这里按槽位实测宽度逐条收一档，只收字号不改构图。
   凡是收了字号仍然装不下的，收的是文案（见 explainer_i18n.js），不是继续缩字。 */
:root[lang="en"] .s8-title{ font-size:16px; }
:root[lang="en"] .s8-cap{ font-size:12px; }
:root[lang="en"] .s8-advice-t{ font-size:13px; }
:root[lang="en"] .s9-radar-label{ font-size:12px; }
:root[lang="en"] .s9-owner{ font-size:17px; }
:root[lang="en"] .s9-label{ font-size:12px; }
:root[lang="en"] .s9-owner-sub{ font-size:13px; }
:root[lang="en"] .s9-foot-t{ font-size:12.5px; }
:root[lang="en"] .s9-cluster-t{ font-size:13px; }
:root[lang="en"] .s7-label{ font-size:15px; }
:root[lang="en"] .s7-count{ font-size:12.5px; }
:root[lang="en"] .s11-database-name{ font-size:12.5px; }
:root[lang="en"] .s11-database-meta,
:root[lang="en"] .s11-database-state{ font-size:11px; }
:root[lang="en"] .s11-radar-label{ font-size:12.5px; }
:root[lang="en"] .s11-legend-t{ font-size:13px; }
.s7-group{ opacity:0; animation:s7-group var(--s7-duration) var(--ease-out) infinite; }
@keyframes s7-group{
  0%,66%   { opacity:0; }
  72%,100% { opacity:1; }
}
/* 卡片变大之后（60x34 → 140x46）飞行途中会盖住六条曲线、落进圈里又会互相压住，
   所以只有停在集合网格上的那一段是满尺寸：从曲线上摘下来时是小片，飞向类目时又缩回去。 */
.s7-flight{
  transform:translate(var(--sx),var(--sy)) scale(.3);
  animation:s7-extract var(--s7-duration) var(--ease-in-out) calc(var(--order) * var(--s7-step));
}
.s7-keyshot-card{
  opacity:0; transform-box:fill-box; transform-origin:center;
  animation:s7-card-to-dot var(--s7-duration) var(--ease-in-out) calc(var(--order) * var(--s7-step));
}
.s7-keyshot-card > rect:first-child{
  fill:var(--surface); stroke:var(--rule); stroke-width:1.2;
  filter:drop-shadow(0 4px 10px rgba(25,34,38,.06));
}
.s7-keyshot-mark{ fill:var(--accent); }
/* 来源退一档、球种进一档：先认出「这是什么球」，再看它是哪一拍 */
.s7-keyshot-meta{ font-family:var(--font-mono); font-size:13px; fill:var(--faint); }
.s7-keyshot-stroke{ font-family:var(--font-cn); font-size:16px; font-weight:650; fill:var(--ink); }
.s7-result-dot{
  opacity:0; transform-box:fill-box; transform-origin:center; transform:scale(.94);
  animation:s7-result-dot var(--s7-duration) var(--ease-in-out) calc(var(--order) * var(--s7-step));
}
.s7-keyshot.t-accent .s7-result-dot{ fill:var(--accent); }
.s7-keyshot.t-navy .s7-result-dot{ fill:var(--navy); }
.s7-keyshot.t-teal .s7-result-dot{ fill:var(--teal); }
.s7-keyshot.t-indigo .s7-result-dot{ fill:var(--indigo); }
.s7-fill-dot{
  opacity:0; transform-box:fill-box; transform-origin:center; transform:scale(.94);
  animation:s7-fill-dot var(--s7-duration) var(--ease-out) calc(var(--fill-order) * 60ms) infinite;
}
.s7-cluster-fill.t-accent .s7-fill-dot{ fill:var(--accent); }
.s7-cluster-fill.t-navy .s7-fill-dot{ fill:var(--navy); }
.s7-cluster-fill.t-teal .s7-fill-dot{ fill:var(--teal); }
.s7-cluster-fill.t-indigo .s7-fill-dot{ fill:var(--indigo); }
/* 先小片离开曲线（看得出是从那个拐点上摘下来的），曲线退场之后再在网格上长到满尺寸，
   飞向类目时又缩回去。任何一段让满尺寸的卡片与别的东西同框，画面都会被八张卡糊住。 */
@keyframes s7-extract{
  0%,26%{ transform:translate(var(--sx),var(--sy)) scale(.3); }
  36%{ transform:translate(var(--cx),var(--cy)) scale(.3); }
  44%,62%{ transform:translate(var(--cx),var(--cy)) scale(1); }
  82%,100%{ transform:translate(var(--gx),var(--gy)) scale(.3); }
}
/* 卡片要等圈定住之后（s7-peak-ring 的 16%）才浮出来，
   在圈上停一拍再起飞——先圈后卡，两步分得开才看得出「从这条曲线上摘下来」。 */
@keyframes s7-card-to-dot{
  0%,20%{ opacity:0; transform:scale(.94); }
  26%,66%{ opacity:1; transform:scale(1); }
  78%,100%{ opacity:0; transform:scale(.6); }
}
@keyframes s7-result-dot{
  0%,74%{ opacity:0; transform:scale(.94); }
  84%,100%{ opacity:1; transform:scale(1); }
}
@keyframes s7-fill-dot{
  0%,86%{ opacity:0; transform:scale(.94); }
  92%,100%{ opacity:1; transform:scale(1); }
}

/* ============================================================
   幕八：最具威胁 / 最大弱点两张档案（周期 12s）
   球路直接画在俯视球场上，先画威胁那一路，再画弱点那一路与它的改法
   ============================================================ */
.scene-8{ --s8-duration:8.56s; }
.s8-plate{ fill:var(--surface); stroke:var(--rule-soft); stroke-width:1.2; }
.s8-kind.is-threat{ fill:var(--accent); }
.s8-kind.is-weak{ fill:var(--crimson); }
.s8-kind-t{ font-family:var(--font-mono); font-size:17px; letter-spacing:.08em; }
.s8-kind-t.is-threat{ fill:var(--accent); }
.s8-kind-t.is-weak{ fill:var(--crimson); }
.s8-title{ font-family:var(--font-cn); font-size:26px; font-weight:700; letter-spacing:-.02em; fill:var(--ink); }
.s8-court3d path{ fill:none; stroke:var(--rule); stroke-width:1; }
.s8-court3d .s8-line-out{ stroke:var(--ink-2); stroke-width:1.4; opacity:.5; }
.s8-court3d .s8-net3d{ stroke:var(--ink-2); stroke-width:1.2; opacity:.34; }
.s8-num{ font-family:var(--font-mono); font-size:21px; font-weight:600; fill:var(--ink); }
/* 结果数字吃结论色：威胁那一路的得分吃铜橙、弱点那一路的丢分吃深红。
   「本场出现」是中性计数，两边都留 --ink，颜色因此只标结论、不标计数。 */
.s8-num.acc{ fill:var(--accent); }
.s8-num.crim{ fill:var(--crimson); }
.s8-cap{ font-family:var(--font-cn); font-size:16px; fill:var(--muted); }
/* 改法做成 Notion 的 callout：浅色底块 + 同色系文字，和普通说明文字区分开 */
.s8-advice-box{ fill:var(--navy-tint); }
.s8-advice-t{ font-family:var(--font-cn); font-size:16px; font-weight:550; fill:var(--navy); }
.s8-advice.is-threat .s8-advice-box{ fill:var(--accent-tint); }
.s8-advice.is-threat .s8-advice-t{ fill:var(--accent); }

.s8-route .s8-line{ fill:none; stroke-width:2.6; stroke-linecap:round; stroke-linejoin:round;
  stroke-dashoffset:var(--len,220); }
.s8-route .s8-from{ opacity:0; }
.s8-route.is-threat .s8-line{ stroke:var(--accent); }
.s8-route.is-threat .s8-from{ fill:var(--accent); }
.s8-route.is-weak .s8-line{ stroke:var(--crimson); }
.s8-route.is-weak .s8-from{ fill:var(--crimson); }
.s8-land{ opacity:0; transform-box:fill-box; transform-origin:center; }
.s8-land-ring{ fill:none; stroke-width:1.8; }
.s8-land-dot{ opacity:.9; }
.is-threat .s8-land-ring{ stroke:var(--accent); }
.is-threat .s8-land-dot{ fill:var(--accent); }
.is-weak .s8-land-ring{ stroke:var(--crimson); }
.is-weak .s8-land-dot{ fill:var(--crimson); }

/* 一路球的画法：起点亮 → 线走完 → 落点才亮，没有箭头 */
.s8-route .r1, .s8-route .r2{ animation-duration:var(--s8-duration); animation-timing-function:ease-in-out;
  animation-iteration-count:infinite; }
.s8-line.r1{ animation-name:s8-draw-1; }
.s8-line.r2{ animation-name:s8-draw-2; }
@keyframes s8-draw-1{ 0%,10%{ stroke-dashoffset:var(--len); } 26%,100%{ stroke-dashoffset:0; } }
@keyframes s8-draw-2{ 0%,42%{ stroke-dashoffset:var(--len); } 58%,100%{ stroke-dashoffset:0; } }
@keyframes s8-punish{ 0%,66%{ opacity:0; } 78%,100%{ opacity:.75; } }
.s8-from.r1{ animation-name:s8-from-1; }
.s8-from.r2{ animation-name:s8-from-2; }
.s8-land.r1{ animation-name:s8-land-1; }
.s8-land.r2{ animation-name:s8-land-2; }
@keyframes s8-from-1{
  0%,8%    { opacity:0; transform:scale(.4); }
  13%,100% { opacity:1; transform:scale(1); }
}
@keyframes s8-from-2{
  0%,40%   { opacity:0; transform:scale(.4); }
  45%,100% { opacity:1; transform:scale(1); }
}
/* 落点等线走完再亮 */
@keyframes s8-land-1{
  0%,26%   { opacity:0; transform:scale(.4); }
  32%,100% { opacity:1; transform:scale(1); }
}
@keyframes s8-land-2{
  0%,58%   { opacity:0; transform:scale(.4); }
  64%,100% { opacity:1; transform:scale(1); }
}
/* 起点圆点只需要淡入，别跟着缩放跑偏 */
.s8-from{ transform-box:fill-box; transform-origin:center; }

.s8-stat{ opacity:0; animation-duration:var(--s8-duration); animation-timing-function:ease-out;
  animation-iteration-count:infinite; }
.s8-stats.t1 .s8-stat{ animation-name:s8-stat-1; }
.s8-stats.t2 .s8-stat{ animation-name:s8-stat-2; }
.s8-stats > g:nth-child(2) .s8-stat{ animation-delay:.12s; }
.s8-stats > g:nth-child(3) .s8-stat{ animation-delay:.24s; }
@keyframes s8-stat-1{
  0%,26%   { opacity:0; transform:translate(0,6px); }
  34%,100% { opacity:1; transform:translate(0,0); }
}
@keyframes s8-stat-2{
  0%,58%   { opacity:0; transform:translate(0,6px); }
  66%,100% { opacity:1; transform:translate(0,0); }
}
.s8-advice{ opacity:0; animation:s8-advice var(--s8-duration) ease-out infinite; }
/* 两块结论各自跟在自己那一列的统计后面出现：威胁那一路 34% 出统计、42% 出结论，
   弱点那一路 66% / 80%。两块用同一支时间轴会让左边的结论比它的统计先落地。 */
.s8-advice.is-threat{ animation-name:s8-advice-threat; }
@keyframes s8-advice-threat{
  0%,42%   { opacity:0; transform:translate(0,6px); }
  50%,100% { opacity:1; transform:translate(0,0); }
}
@keyframes s8-advice{
  0%,80%   { opacity:0; transform:translate(0,6px); }
  88%,100% { opacity:1; transform:translate(0,0); }
}

/* ============================================================
   第六幕：多场并行 → 跨场聚类 → 五边形能力图（周期 16s）
   几条进度条同时走完是这一幕的第一个重点，聚类收成画像是第二个
   ============================================================ */
.scene-9{ --s9-duration:9.78s; }
.s9-plate{ fill:var(--surface); stroke:var(--rule); stroke-width:1.2; }
.s9-play{ fill:var(--accent); }
.s9-label{ font-family:var(--font-mono); font-size:17px; fill:var(--ink-2); }
.s9-athlete-lock{ fill:rgba(255,255,255,.82); stroke:var(--rule); stroke-width:1.2; }
.s9-owner{ font-family:var(--font-cn); font-size:21px; font-weight:700; fill:var(--ink); }
.s9-owner-sub{ font-family:var(--font-mono); font-size:16px; fill:var(--muted); }
.s9-avatar-bg{ fill:var(--navy-tint); }
.s9-avatar-ring{ fill:none; stroke:rgba(20,56,101,.24); stroke-width:1.2; }
.s9-track{ fill:var(--surface-3); }
/* 列表脚注：把虚化卡片说不出的那句话写出来 */
.s9-foot-t{ font-family:var(--font-cn); font-size:15px; font-weight:600; fill:var(--muted); }
.s9-foot-t.is-sub{ font-weight:400; fill:var(--faint); }
/* 列表 → 能力图的因果，静止画面上也在 */
.s9-flow-line{ fill:none; stroke:var(--rule); stroke-width:1.4; stroke-dasharray:5 5; }
.s9-flow-head{ fill:var(--rule); }
.s9-ghost-line{ fill:var(--surface-3); }
.s9-fill{ fill:var(--accent); transform-origin:0 0; animation:s9-fill var(--s9-duration) ease-in-out infinite; }
@keyframes s9-fill{
  0%,7%    { transform:scaleX(0); }
  26%,100% { transform:scaleX(1); }
}
.s9-head, .s9-row, .s9-ghost, .s9-foot, .s9-flow{ opacity:0; animation:s9-row var(--s9-duration) ease-out infinite; }
.s9-foot{ animation-delay:.34s; }
.s9-flow{ animation-delay:.42s; }
.s9-matches > g:nth-child(2) .s9-row{ animation-delay:.07s; }
.s9-matches > g:nth-child(3) .s9-row{ animation-delay:.14s; }
.s9-matches > g:nth-child(4) .s9-row{ animation-delay:.21s; }
.s9-matches > g:nth-child(5) .s9-row{ animation-delay:.28s; }
@keyframes s9-row{
  0%       { opacity:0; transform:translate(-10px,0); }
  5%,100%  { opacity:1; transform:translate(0,0); }
}
.s9-ghost.g1{ filter:blur(1.1px); animation-delay:.16s; --ghost-alpha:.62; }
.s9-ghost.g2{ filter:blur(2.2px); animation-delay:.22s; --ghost-alpha:.36; }
.s9-ghost.g3{ filter:blur(3.4px); animation-delay:.28s; --ghost-alpha:.18; }
.s9-ghost .s9-plate, .s9-ghost .s9-play, .s9-ghost .s9-track,
.s9-ghost .s9-fill, .s9-ghost-line{ opacity:var(--ghost-alpha); }

/* 聚类：散点飞进八个类目，停一会儿再让位给画像 */
.s9-ring{ fill:none; stroke:var(--rule); stroke-width:1.4; }
.s9-ring.t-accent{ stroke:#E7C6A5; }
.s9-ring.t-navy{ stroke:#B9CBE6; }
.s9-ring.t-teal{ stroke:#A9CFDA; }
.s9-ring.t-indigo{ stroke:#BCC2E6; }
.s9-cluster-t{ font-family:var(--font-cn); font-size:17px; fill:var(--ink-2); text-anchor:middle; }
.s9-group{ opacity:0; animation:s9-group var(--s9-duration) ease-out infinite; }
@keyframes s9-group{
  0%,36%   { opacity:0; }
  48%,64%  { opacity:1; }
  72%,100% { opacity:0; }
}
.s9-dot circle{ fill:var(--navy); }
.s9-dot.t-accent circle{ fill:var(--accent); }
.s9-dot.t-navy circle{ fill:var(--navy); }
.s9-dot.t-teal circle{ fill:var(--teal); }
.s9-dot.t-indigo circle{ fill:var(--indigo); }
.s9-fly{ transform:translate(var(--gx),var(--gy)); animation:s9-fly var(--s9-duration) ease-in-out infinite; }
@keyframes s9-fly{
  0%,28%   { transform:translate(var(--sx),var(--sy)); }
  54%,64%  { transform:translate(var(--gx),var(--gy)); }
  78%,100% { transform:translate(var(--rx),var(--ry)); }
}
.s9-pop{ opacity:0; animation:s9-pop var(--s9-duration) linear infinite; }
@keyframes s9-pop{
  0%,27%   { opacity:0; }
  30%,70%  { opacity:1; }
  80%,100% { opacity:0; }
}

/* 画像：类目圈让位，底图先铺开，散点顺着轴收到各自的落点，边线再连起来 */
.s9-radar{ opacity:0; animation:s9-radar var(--s9-duration) linear infinite; }
@keyframes s9-radar{
  0%,62%   { opacity:0; }
  70%,100% { opacity:1; }
}
.s9-radar-grid{ fill:none; stroke:var(--rule); stroke-width:1; }
.s9-radar-axis{ fill:none; stroke:var(--rule-soft); stroke-width:1; }
.s9-radar-label{ font-family:var(--font-cn); font-size:17px; fill:var(--ink-2); }
.s9-radar-fill{ fill:var(--accent); fill-opacity:0; stroke:none;
  animation:s9-radar-fill var(--s9-duration) ease-out infinite; }
@keyframes s9-radar-fill{
  0%,84%   { fill-opacity:0; }
  92%,100% { fill-opacity:.16; }
}
.s9-radar-edge{ fill:none; stroke:var(--accent); stroke-width:2.4; stroke-linejoin:round;
  stroke-dashoffset:var(--perimeter); animation:s9-radar-edge var(--s9-duration) ease-in-out infinite; }
@keyframes s9-radar-edge{
  0%,76%   { stroke-dashoffset:var(--perimeter); }
  90%,100% { stroke-dashoffset:0; }
}
.s9-radar-dot{ fill:var(--accent); opacity:0; transform-box:fill-box; transform-origin:center;
  animation:s9-radar-dot var(--s9-duration) cubic-bezier(.22,1,.36,1) infinite; }
@keyframes s9-radar-dot{
  0%,74%   { opacity:0; transform:scale(.2); }
  80%,100% { opacity:1; transform:scale(1); }
}

/* ============================================================
   幕二：教练伏案写笔记（周期 13s）
   肩、肘、腕仍按笔尖位置联动；有机轮廓覆盖关节，不显示机械拼接。
   ============================================================ */
.s2-pause rect{ fill:#EAF0F8; }
.s2-pause-bg{ fill:rgba(8,14,24,.55); }
.s2-badge rect{ fill:var(--accent-tint); }
.s2-badge{ animation:s2-blink 1.6s ease-in-out infinite; }
@keyframes s2-blink{ 0%,100%{ opacity:1; } 50%{ opacity:.35; } }
.s2-rings circle{ fill:none; stroke:var(--rule); stroke-width:1.4; }
.s2-margin{ stroke:var(--crimson); stroke-width:1; opacity:.3; }
.s2-rules, .s2-rules path{ fill:none; stroke:var(--rule-soft); stroke-width:1; }
.s2-th{ font-family:var(--font-mono); font-size:10.5px; fill:var(--faint); letter-spacing:.04em; }
.s2-meta{ font-family:var(--font-mono); font-size:10px; fill:var(--faint); letter-spacing:.02em; }
.s2-main{ font-family:var(--font-cn); font-size:12px; fill:var(--ink-2); }
.s2-cover{ fill:var(--surface); }
.s2-nib{ fill:var(--ink-2); }
.s2-barrel{ fill:var(--accent); }
.s2-desk-top{ fill:var(--surface-3); }
.s2-stand{ fill:var(--surface-3); stroke:var(--rule); stroke-width:1.2; }
.s2-lip{ fill:none; stroke:var(--navy); stroke-width:2; stroke-linecap:round; }
.s2-pageno{ font-family:var(--font-mono); font-size:11px; fill:var(--faint); }
.s2-turn{ fill:var(--surface); stroke:var(--rule-soft); stroke-width:1.2; }

/* 四条记录的书写时段：3–20 / 26–43 / 49–66 / 72–89 */
.s2-cover{ animation-duration:13s; animation-timing-function:linear; animation-iteration-count:infinite; }
.s2-cover.c1{ animation-name:s2-c1; }
.s2-cover.c2{ animation-name:s2-c2; }
.s2-cover.c3{ animation-name:s2-c3; }
.s2-cover.c4{ animation-name:s2-c4; }
@keyframes s2-c1{ 0%,3%{ transform:translate(0,0); } 20%,100%{ transform:translate(268px,0); } }
@keyframes s2-c2{ 0%,26%{ transform:translate(0,0); } 43%,100%{ transform:translate(268px,0); } }
@keyframes s2-c3{ 0%,49%{ transform:translate(0,0); } 66%,100%{ transform:translate(268px,0); } }
@keyframes s2-c4{ 0%,72%{ transform:translate(0,0); } 89%,100%{ transform:translate(268px,0); } }



/* 手臂两段骨架：肩 → 肘 → 腕，角度按笔尖位置反解，和遮罩同一条时间轴 */
.s2-upper{ animation:s2-upper 13s linear infinite; }
.s2-fore{ animation:s2-fore 13s linear infinite; }
.s2-hold{ animation:s2-hold 13s linear infinite; }
@keyframes s2-upper{
  0% { transform:rotate(-50.75deg); }
  3% { transform:rotate(-50.75deg); }
  7.25% { transform:rotate(-33.85deg); }
  11.5% { transform:rotate(-23.38deg); }
  15.75% { transform:rotate(-21.21deg); }
  20% { transform:rotate(-33.16deg); }
  23% { transform:rotate(-37.74deg); }
  26% { transform:rotate(-37.74deg); }
  30.25% { transform:rotate(-15.94deg); }
  34.5% { transform:rotate(-2.41deg); }
  38.75% { transform:rotate(1.24deg); }
  43% { transform:rotate(-4.84deg); }
  46% { transform:rotate(-26.94deg); }
  49% { transform:rotate(-26.94deg); }
  53.25% { transform:rotate(4.19deg); }
  57.5% { transform:rotate(20.88deg); }
  61.75% { transform:rotate(23.23deg); }
  66% { transform:rotate(16.14deg); }
  69% { transform:rotate(-18.28deg); }
  72% { transform:rotate(-18.28deg); }
  76.25% { transform:rotate(36.63deg); }
  80.5% { transform:rotate(51.26deg); }
  84.75% { transform:rotate(46.60deg); }
  89% { transform:rotate(35.22deg); }
  94% { transform:rotate(35.22deg); }
  100% { transform:rotate(-50.75deg); }
}
@keyframes s2-fore{
  0% { transform:rotate(-87.08deg); }
  3% { transform:rotate(-87.08deg); }
  7.25% { transform:rotate(-88.79deg); }
  11.5% { transform:rotate(-81.16deg); }
  15.75% { transform:rotate(-63.34deg); }
  20% { transform:rotate(-25.06deg); }
  23% { transform:rotate(-112.18deg); }
  26% { transform:rotate(-112.18deg); }
  30.25% { transform:rotate(-114.03deg); }
  34.5% { transform:rotate(-105.94deg); }
  38.75% { transform:rotate(-88.84deg); }
  43% { transform:rotate(-61.48deg); }
  46% { transform:rotate(-133.88deg); }
  49% { transform:rotate(-133.88deg); }
  53.25% { transform:rotate(-136.29deg); }
  57.5% { transform:rotate(-126.18deg); }
  61.75% { transform:rotate(-107.18deg); }
  66% { transform:rotate(-80.69deg); }
  69% { transform:rotate(-153.64deg); }
  72% { transform:rotate(-153.64deg); }
  76.25% { transform:rotate(-157.79deg); }
  80.5% { transform:rotate(-142.49deg); }
  84.75% { transform:rotate(-119.89deg); }
  89% { transform:rotate(-92.35deg); }
  94% { transform:rotate(-92.35deg); }
  100% { transform:rotate(-87.08deg); }
}
@keyframes s2-hold{
  0% { transform:rotate(137.83deg); }
  3% { transform:rotate(137.83deg); }
  7.25% { transform:rotate(122.64deg); }
  11.5% { transform:rotate(104.54deg); }
  15.75% { transform:rotate(84.55deg); }
  20% { transform:rotate(58.21deg); }
  23% { transform:rotate(149.92deg); }
  26% { transform:rotate(149.92deg); }
  30.25% { transform:rotate(129.97deg); }
  34.5% { transform:rotate(108.35deg); }
  38.75% { transform:rotate(87.60deg); }
  43% { transform:rotate(66.32deg); }
  46% { transform:rotate(160.82deg); }
  49% { transform:rotate(160.82deg); }
  53.25% { transform:rotate(132.11deg); }
  57.5% { transform:rotate(105.30deg); }
  61.75% { transform:rotate(83.95deg); }
  66% { transform:rotate(64.55deg); }
  69% { transform:rotate(171.93deg); }
  72% { transform:rotate(171.93deg); }
  76.25% { transform:rotate(121.16deg); }
  80.5% { transform:rotate(91.23deg); }
  84.75% { transform:rotate(73.29deg); }
  89% { transform:rotate(57.14deg); }
  94% { transform:rotate(57.14deg); }
  100% { transform:rotate(137.83deg); }
}

/* 写字时头微微点，换行时抬一下 */
.s2-jitter{ animation:s2-jitter .34s ease-in-out infinite; }
@keyframes s2-jitter{
  0%,100% { transform:translate(0,0) rotate(0deg); }
  25%     { transform:translate(.5px,-1.1px) rotate(.8deg); }
  50%     { transform:translate(0,.5px) rotate(-.4deg); }
  75%     { transform:translate(-.5px,-.7px) rotate(.5deg); }
}
.s2-nod{ animation:s2-nod 13s ease-in-out infinite; }
@keyframes s2-nod{
  0%,3%    { transform:rotate(0deg); }
  20%      { transform:rotate(1.6deg); }
  24%      { transform:rotate(-1.4deg); }
  43%      { transform:rotate(1.6deg); }
  47%      { transform:rotate(-1.4deg); }
  66%      { transform:rotate(1.6deg); }
  70%      { transform:rotate(-1.4deg); }
  89%,100% { transform:rotate(0deg); }
}
.s2-back{ animation:s2-breathe 13s ease-in-out infinite; }
@keyframes s2-breathe{
  0%,100% { transform:translate(0,0); }
  50%     { transform:translate(0,3px); }
}

.s2-turn{ animation:s2-turn 13s linear infinite; }
@keyframes s2-turn{
  0%,90%  { transform:translate(338px,0); }
  97%     { transform:translate(0,0); }
  100%    { transform:translate(338px,0); }
}
.s2-pageno.a{ animation:s2-page-a 13s linear infinite; }
.s2-pageno.b{ animation:s2-page-b 13s linear infinite; }
@keyframes s2-page-a{ 0%,95%{ opacity:1; } 97%,100%{ opacity:0; } }
@keyframes s2-page-b{ 0%,95%{ opacity:0; } 97%,100%{ opacity:1; } }

/* ============================================================
   幕三：再归纳（单次 9s）
   pile → scatter → sorted 三组坐标由 explainer.js 写成 CSS 变量
   ============================================================ */
.scene-3{ --s3-duration:9s; }
/* 一开始手还搭在桌上，越到后面越要撑着头 */
.s3-prop{ animation:s3-prop var(--s3-duration) ease-in-out; }
@keyframes s3-prop{
  0%,24%   { transform:rotate(88deg); }
  44%,100% { transform:rotate(0deg); }
}
.s3-slump{ animation:s3-slump var(--s3-duration) ease-in-out; }
@keyframes s3-slump{
  0%,18%   { transform:translate(0,0) rotate(0deg); }
  45%      { transform:translate(0,2px) rotate(1.2deg); }
  70%,100% { transform:translate(0,6px) rotate(3.2deg); }
}
.s3-droop{ animation:s3-droop var(--s3-duration) ease-in-out; }
@keyframes s3-droop{
  0%,18%   { transform:rotate(0deg); }
  48%      { transform:rotate(3deg); }
  68%      { transform:rotate(1deg); }
  82%,100% { transform:rotate(8deg); }
}
/* 睁眼与闭眼是两套画法，互相切换；前段是正常眨眼，后段眼皮直打架 */
.scene-3 .fig-eye-open{ animation:s3-blink-open var(--s3-duration) linear; }
.scene-3 .fig-eye-shut{ animation:s3-blink-shut var(--s3-duration) linear; }
@keyframes s3-blink-open{
  0%,7%    { opacity:1; }
  8%,9%    { opacity:0; }
  10%,25%  { opacity:1; }
  26%,27%  { opacity:0; }
  28%,45%  { opacity:1; }
  47%,53%  { opacity:0; }
  55%,62%  { opacity:1; }
  64%,78%  { opacity:0; }
  81%,85%  { opacity:1; }
  87%,92%  { opacity:0; }
  94%,96%  { opacity:1; }
  98%      { opacity:0; }
  100%     { opacity:1; }
}
@keyframes s3-blink-shut{
  0%,7%    { opacity:0; }
  8%,9%    { opacity:1; }
  10%,25%  { opacity:0; }
  26%,27%  { opacity:1; }
  28%,45%  { opacity:0; }
  47%,53%  { opacity:1; }
  55%,62%  { opacity:0; }
  64%,78%  { opacity:1; }
  81%,85%  { opacity:0; }
  87%,92%  { opacity:1; }
  94%,96%  { opacity:0; }
  98%      { opacity:1; }
  100%     { opacity:0; }
}
.scene-3 .fig-mouth{ animation:s3-yawn var(--s3-duration) ease-in-out; }
@keyframes s3-yawn{
  0%,66%   { transform:scaleY(1); }
  73%,77%  { transform:scaleY(4.6); }
  83%,100% { transform:scaleY(1.2); }
}
.s3-col-t{ font-family:var(--font-cn); font-size:12.5px; font-weight:700;
  fill:var(--navy); text-anchor:middle; }
.s3-cols path{ fill:none; stroke:var(--rule); stroke-width:1.2; }
.s3-cols{ opacity:0; animation:s3-cols var(--s3-duration) linear; }
@keyframes s3-cols{ 0%,40%{opacity:0} 48%,100%{opacity:1} }

.s3-book{ opacity:0; animation:s3-book var(--s3-duration) ease-in-out; }
@keyframes s3-book{ 0%,14%{opacity:1} 22%,100%{opacity:0} }
.s3-book-lines path{ fill:none; stroke:var(--rule-soft); stroke-width:1; }
.s3-book-lines path:first-child{ stroke:var(--crimson); opacity:.3; }
.s3-book-ink{ fill:none; stroke:var(--faint); stroke-width:1.6; stroke-linecap:round; opacity:.5; }
.s3-book-rings circle{ fill:none; stroke:var(--rule); stroke-width:1.4; }

.s3-note rect{ fill:var(--navy-tint); }
.s3-note.t-accent rect{ fill:var(--accent-tint); }
.s3-note.t-teal rect{ fill:var(--teal-tint); }
.s3-note path{ fill:none; stroke:var(--faint); stroke-width:1.6; opacity:.55; }
.s3-note.is-lost rect{ stroke:var(--crimson); stroke-width:1.6; stroke-opacity:0;
  animation:s3-lost-mark var(--s3-duration) linear; }
@keyframes s3-lost-mark{ 0%,55%{ stroke-opacity:0; } 62%,100%{ stroke-opacity:.9; } }
.s3-note-move{ transform:translate(var(--gx),var(--gy)); animation:s3-move var(--s3-duration) ease-in-out; }
@keyframes s3-move{
  0%,18%   { transform:translate(var(--px),var(--py)) rotate(var(--pr)); }
  30%,40%  { transform:translate(var(--sx),var(--sy)) rotate(var(--sr)); }
  58%,100% { transform:translate(var(--gx),var(--gy)) rotate(0deg); }
}
.s3-note-drop{ animation:s3-drop var(--s3-duration) linear; }
@keyframes s3-drop{
  0%     { opacity:0; transform:translate(0,-26px); }
  8%,100%{ opacity:1; transform:translate(0,0); }
}

.s3-out rect{ fill:var(--navy-tint); }
.s3-out-t{ font-family:var(--font-cn); font-size:14px; font-weight:700; fill:var(--navy); }
.s3-out{ opacity:0; animation:s3-out var(--s3-duration) ease-out; }
@keyframes s3-out{ 0%,76%{opacity:0} 86%,100%{opacity:1} }

.s3-prop, .s3-slump, .s3-droop, .scene-3 .fig-eye-open, .scene-3 .fig-eye-shut,
.scene-3 .fig-mouth, .s3-cols, .s3-book, .s3-note.is-lost rect, .s3-note-move,
.s3-note-drop, .s3-out{ animation-fill-mode:forwards; }
.scene-3 .clock-hour-hand{ animation:clock-third-hour var(--s3-duration) linear forwards; }
.scene-3 .clock-minute-hand{ animation:clock-spin 3s linear 3 forwards; }
@keyframes clock-third-hour{ to{ transform:rotate(90deg); } }

/* ============================================================
   第七幕：先建立运动员数据库，再锁定对手并调出备赛结论（单次 16s）
   开场是一次推镜：静态画的是终态（左下角举着平板的小人），
   关键帧把它从「放大到画面中央」过渡回 identity，因此开场与常驻是同一组图元。
   ============================================================ */
.scene-11{
  --s11-total-duration:12s;
  --s11-target-duration:8.8s;
  --s11-target-delay:3s;
}
.s11-database-intro{
  opacity:0; transform-origin:320px 200px;
  animation:s11-database-stage var(--s11-total-duration) var(--ease-in-out);
}
@keyframes s11-database-stage{
  0%,24%  { opacity:1; transform:none; }
  29%,100%{ opacity:0; transform:scale(.9); }
}
.s11-database-frame{ fill:var(--surface); stroke:var(--rule); stroke-width:1.2; }
.s11-database-heading-motion{ animation:s11-database-heading var(--s11-total-duration) var(--ease-out); }
@keyframes s11-database-heading{
  0%,4%   { opacity:0; transform:translateY(-5px); }
  8%,100% { opacity:1; transform:none; }
}
.s11-database-title{ font-family:var(--font-cn); font-size:21px; font-weight:700; fill:var(--ink); }
.s11-database-computer rect{ fill:var(--navy-tint); stroke:var(--navy); stroke-width:1.2; }
.s11-database-computer path{ fill:none; stroke:var(--navy); stroke-width:1.4; stroke-linecap:round; }
.s11-database-match-stack{ opacity:0; transform-origin:88px 49px; animation:s11-database-stack var(--s11-total-duration) var(--ease-in-out); }
.s11-database-match-stack rect{ fill:var(--surface); stroke:var(--rule); stroke-width:1; }
.s11-database-match-stack .m2{ fill:var(--navy-tint); }
.s11-database-match-stack .m3{ fill:var(--accent-tint); }
.s11-database-match-stack path{ fill:none; stroke:var(--faint); stroke-width:2; stroke-linecap:round; opacity:.55; }
@keyframes s11-database-stack{
  0%      { opacity:0; transform:translateY(12px) scale(.96); }
  5%,12%  { opacity:1; transform:none; }
  18%,100%{ opacity:0; transform:translateY(-8px) scale(.94); }
}
.s11-database-card-motion{
  opacity:0; transform-origin:88px 63px;
  animation:s11-database-athlete var(--s11-total-duration) var(--ease-in-out) var(--database-delay,0s);
}
@keyframes s11-database-athlete{
  0%,7%   { opacity:0; transform:translate(var(--database-x),var(--database-y)) scale(.96); }
  13%     { opacity:1; }
  18%,24% { opacity:1; transform:none; }
  29%,100%{ opacity:0; transform:scale(.96); }
}
.s11-database-card{ fill:var(--surface); stroke:var(--rule-soft); stroke-width:1; }
.s11-database-photo{ filter:saturate(.82) contrast(1.03); }
.s11-database-photo-ring{ fill:none; stroke:var(--surface); stroke-width:3; }
.s11-database-name{ font-family:var(--font-cn); font-size:20px; font-weight:700; fill:var(--ink); }
.s11-database-meta{ font-family:var(--font-cn); font-size:13px; fill:var(--faint); }
.s11-database-state{ font-family:var(--font-cn); font-size:13px; fill:var(--navy); }

/* 数据库收拢后才启动既有的检索、锁定和战术结论动画。 */
.s11-target-stage .s11-board,
.s11-target-stage .s11-versus,
.s11-target-stage .s11-seat-fill,
.s11-target-stage .s11-dossier,
.s11-target-stage .s11-radar-edge,
.s11-target-stage .s11-radar-fill,
.s11-target-stage .s11-weak,
.s11-target-stage .s11-weak-ring,
.s11-target-stage .s11-court .s0-player,
.s11-target-stage .s11-route .s11-line,
.s11-target-stage .s11-route .s11-from,
.s11-target-stage .s11-land,
.s11-target-stage .s11-zone,
.s11-target-stage .s11-evidence,
.s11-target-stage .s11-scout-zoom,
.s11-target-stage .s11-figure,
.s11-target-stage .s11-focus-ring{ animation-delay:var(--s11-target-delay); }
.s11-target-stage .s11-tablet{ animation-delay:calc(var(--s11-target-delay) + .12s); }
.s11-target-stage .s11-court3d path{ animation-delay:calc(var(--s11-target-delay) + var(--delay,0s)); }

.s11-board{ opacity:0; animation:s11-board-in var(--s11-target-duration) var(--ease-out); }
@keyframes s11-board-in{
  0%,15%  { opacity:0; }
  21%,100%{ opacity:1; }
}

/* ---- 对阵条 ---- */
.s11-versus{ opacity:0; animation:s11-versus-in var(--s11-target-duration) var(--ease-out); }
@keyframes s11-versus-in{
  0%,16%  { opacity:0; transform:translate(0,-6px); }
  23%,100%{ opacity:1; transform:none; }
}
.s11-seat-photo{ filter:saturate(.82) contrast(1.03); }
.s11-seat-ring{ fill:none; stroke-width:2.4; }
.s11-seat-ring.is-navy{ stroke:var(--navy); }
.s11-seat-ring.is-accent{ stroke:var(--accent); }
.s11-seat-slot{ fill:var(--surface-3); stroke:var(--rule); stroke-width:1.2; stroke-dasharray:4 4; }
.s11-vs-badge .is-home{ fill:var(--navy); }
.s11-vs-badge .is-away{ fill:var(--accent); }
.s11-vs-cut{ fill:none; stroke:var(--surface); stroke-width:2.4; }
.s11-vs-t{
  font-family:var(--font-cn); font-size:17px; font-weight:800; font-style:italic;
  letter-spacing:0; text-anchor:middle; fill:var(--surface);
}
/* 命中的人从平板方向飞进空槽：对阵是他自己查出来的 */
.s11-seat-fill{ opacity:0; animation:s11-seat-fill var(--s11-target-duration) var(--ease-enter); }
@keyframes s11-seat-fill{
  0%,18%  { opacity:0; transform:translate(-96px,178px) scale(.34); }
  23%,100%{ opacity:1; transform:none; }
}

/* ---- 对手档案 ---- */
.s11-dossier{ opacity:0; transform-origin:118px 226px;
  animation:s11-dossier-in var(--s11-target-duration) var(--ease-enter); }
@keyframes s11-dossier-in{
  0%,23%  { opacity:0; transform:translate(0,10px) scale(.96); }
  32%,100%{ opacity:1; transform:none; }
}
.s11-card{ fill:var(--surface); stroke:var(--rule-soft); stroke-width:1; }
.s11-card-rule{ fill:none; stroke:var(--rule-soft); stroke-width:1; }
.s11-face-photo{ filter:saturate(.82) contrast(1.03); }
.s11-face-ring{ fill:none; stroke:var(--surface); stroke-width:3; }
.s11-name{ font-family:var(--font-cn); font-size:19px; font-weight:700; fill:var(--ink); }
/* 卡片自姓名起只剩 128 个单位，英文名比中文名长，收一档字号 */
:root[lang="en"] .s11-name{ font-size:15px; }
:root[lang="en"] .s11-english{ display:none; }
.s11-english{ font-family:var(--font-mono); font-size:13px; fill:var(--faint); }

/* ---- 能力图：五轴、两根短轴打红点 ---- */
.s11-radar-grid{ fill:none; stroke:var(--rule-soft); stroke-width:1; }
.s11-radar-axis{ fill:none; stroke:var(--rule); stroke-width:1; }
.s11-radar-label{ font-family:var(--font-cn); font-size:16px; fill:var(--muted); }
.s11-radar-fill{ fill:rgba(194,94,23,.14); }
.s11-radar-edge{
  fill:none; stroke:var(--accent); stroke-width:1.8; stroke-linejoin:round;
  stroke-dasharray:var(--perimeter); stroke-dashoffset:var(--perimeter);
  animation:s11-radar-edge var(--s11-target-duration) var(--ease-out);
}
@keyframes s11-radar-edge{
  0%,30%  { stroke-dashoffset:var(--perimeter); }
  40%,100%{ stroke-dashoffset:0; }
}
.s11-radar-fill{ opacity:0; animation:s11-radar-fill var(--s11-target-duration) var(--ease-out); }
@keyframes s11-radar-fill{
  0%,34%  { opacity:0; }
  42%,100%{ opacity:1; }
}
.s11-weak{ opacity:0; transform-box:fill-box; transform-origin:center;
  animation:s11-weak var(--s11-target-duration) var(--ease-enter); }
.s11-weak-ring{ fill:none; stroke:var(--crimson); stroke-width:1.4; opacity:0;
  transform-box:fill-box; transform-origin:center; animation:s11-weak-pulse var(--s11-target-duration) ease-out; }
.s11-weak-dot{ fill:var(--crimson); }
@keyframes s11-weak{
  0%,40%  { opacity:0; transform:scale(.3); }
  45%     { opacity:1; transform:scale(1.35); }
  48%,100%{ opacity:1; transform:scale(1); }
}
@keyframes s11-weak-pulse{
  0%,41%  { opacity:0; transform:scale(.4); }
  46%     { opacity:.8; transform:scale(1); }
  53%,100%{ opacity:0; transform:scale(2); }
}

/* ---- 三维球场：与幕零、幕八同一台相机 ---- */
.s11-court3d path{ fill:none; }
.s11-line-out{ stroke:var(--ink-2); stroke-width:1.4; opacity:.5; }
.s11-line-in{ stroke:var(--rule); stroke-width:1; }
.s11-net3d{ stroke:var(--ink-2); stroke-width:1.2; opacity:.34; }
.s11-court3d path{
  stroke-dasharray:var(--len); stroke-dashoffset:var(--len);
  animation:s11-court-draw var(--s11-target-duration) var(--ease-out) var(--delay,0s);
}
@keyframes s11-court-draw{
  0%,43%  { stroke-dashoffset:var(--len); }
  50%,100%{ stroke-dashoffset:0; }
}
/* 幕零的简笔运动员在这一幕只站位、不来回移动 */
.s11-court .s0-player{ animation:s11-figure-in var(--s11-target-duration) var(--ease-enter); opacity:0; }
@keyframes s11-figure-in{
  0%,46%  { opacity:0; transform:translate(0,6px); }
  52%,100%{ opacity:1; transform:none; }
}

/* ---- 球路：起点先亮，线走完落点才亮，不画箭头 ---- */
.s11-route .s11-line{
  fill:none; stroke-width:2.6; stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:var(--len); stroke-dashoffset:var(--len);
  animation-duration:var(--s11-target-duration); animation-timing-function:ease-in-out;
}
.s11-route .s11-from{ opacity:0; transform-box:fill-box; transform-origin:center;
  animation-duration:var(--s11-target-duration); animation-timing-function:var(--ease-enter); }
.s11-land{ opacity:0; transform-box:fill-box; transform-origin:center;
  animation-duration:var(--s11-target-duration); animation-timing-function:var(--ease-enter); }
.s11-land-ring{ fill:none; stroke-width:1.8; }
.s11-land-dot{ opacity:.9; }
.s11-route.is-threat .s11-line{ stroke:var(--accent); }
.s11-route.is-threat .s11-from, .s11-route.is-threat .s11-land-dot{ fill:var(--accent); }
.s11-route.is-threat .s11-land-ring{ stroke:var(--accent); }
.s11-route.is-weak .s11-line{ stroke:var(--crimson); }
.s11-route.is-weak .s11-from, .s11-route.is-weak .s11-land-dot{ fill:var(--crimson); }
.s11-route.is-weak .s11-land-ring{ stroke:var(--crimson); }
.s11-route.is-plan .s11-line{ stroke:var(--navy); }
.s11-route.is-plan .s11-from, .s11-route.is-plan .s11-land-dot{ fill:var(--navy); }
.s11-route.is-plan .s11-land-ring{ stroke:var(--navy); }
/* 四条球路依次出场：威胁 → 弱点 → 两条对策 */
.s11-line.r1{ animation-name:s11-draw-1; }
.s11-line.r2{ animation-name:s11-draw-2; }
.s11-line.r3{ animation-name:s11-draw-3; }
.s11-line.r4{ animation-name:s11-draw-4; }
@keyframes s11-draw-1{ 0%,53%{ stroke-dashoffset:var(--len); } 59%,100%{ stroke-dashoffset:0; } }
@keyframes s11-draw-2{ 0%,61%{ stroke-dashoffset:var(--len); } 66%,100%{ stroke-dashoffset:0; } }
@keyframes s11-draw-3{ 0%,73%{ stroke-dashoffset:var(--len); } 79%,100%{ stroke-dashoffset:0; } }
@keyframes s11-draw-4{ 0%,80%{ stroke-dashoffset:var(--len); } 86%,100%{ stroke-dashoffset:0; } }
.s11-from.r1{ animation-name:s11-from-1; }
.s11-from.r2{ animation-name:s11-from-2; }
.s11-from.r3{ animation-name:s11-from-3; }
.s11-from.r4{ animation-name:s11-from-4; }
@keyframes s11-from-1{ 0%,51%{ opacity:0; transform:scale(.4); } 54%,100%{ opacity:1; transform:none; } }
@keyframes s11-from-2{ 0%,59%{ opacity:0; transform:scale(.4); } 62%,100%{ opacity:1; transform:none; } }
@keyframes s11-from-3{ 0%,71%{ opacity:0; transform:scale(.4); } 74%,100%{ opacity:1; transform:none; } }
@keyframes s11-from-4{ 0%,78%{ opacity:0; transform:scale(.4); } 81%,100%{ opacity:1; transform:none; } }
.s11-land.r1{ animation-name:s11-land-1; }
.s11-land.r2{ animation-name:s11-land-2; }
.s11-land.r3{ animation-name:s11-land-3; }
.s11-land.r4{ animation-name:s11-land-4; }
@keyframes s11-land-1{ 0%,59%{ opacity:0; transform:scale(.4); } 62%,100%{ opacity:1; transform:none; } }
@keyframes s11-land-2{ 0%,66%{ opacity:0; transform:scale(.4); } 69%,100%{ opacity:1; transform:none; } }
@keyframes s11-land-3{ 0%,79%{ opacity:0; transform:scale(.4); } 82%,100%{ opacity:1; transform:none; } }
@keyframes s11-land-4{ 0%,86%{ opacity:0; transform:scale(.4); } 89%,100%{ opacity:1; transform:none; } }

/* ---- 目标区：先指出要打哪儿，再画怎么打过去 ---- */
.s11-zone{ fill:rgba(156,46,63,.14); stroke:var(--crimson); stroke-width:1.4; stroke-dasharray:4 3;
  opacity:0; transform-box:fill-box; transform-origin:center;
  animation:s11-zone var(--s11-target-duration) var(--ease-out); }
@keyframes s11-zone{
  0%,66%  { opacity:0; transform:scale(.72); }
  70%     { opacity:1; transform:scale(1.06); }
  73%     { opacity:.72; transform:scale(1); }
  76%     { opacity:1; transform:scale(1.04); }
  79%,100%{ opacity:.9; transform:scale(1); }
}
/* 承重点：能力图上的短轴与球场上的落点区是同一件事的两种画法 */
.s11-evidence{
  fill:none; stroke:var(--crimson); stroke-width:1.2; stroke-dasharray:3 4; opacity:0;
  animation:s11-evidence var(--s11-target-duration) var(--ease-out);
}
@keyframes s11-evidence{
  0%,85%  { opacity:0; }
  92%,100%{ opacity:.62; }
}

/* ---- 球路图注：四条球路的颜色对应关系 ---- */
.s11-legend-dash{ fill:none; stroke-width:2.6; stroke-linecap:round; }
.s11-legend-row.is-threat .s11-legend-dash{ stroke:var(--accent); }
.s11-legend-row.is-weak .s11-legend-dash{ stroke:var(--crimson); }
.s11-legend-row.is-plan .s11-legend-dash{ stroke:var(--navy); }
.s11-legend-t{ font-family:var(--font-cn); font-size:16px; font-weight:600; fill:var(--muted); }
/* 每一行跟着它那条球路一起出现：图注先于球路出场会变成一张无从对照的色卡 */
.s11-legend-row{ opacity:0; animation-duration:var(--s11-target-duration); animation-timing-function:var(--ease-out); }
.s11-legend-row.is-threat{ animation-name:s11-legend-1; }
.s11-legend-row.is-weak{ animation-name:s11-legend-2; }
.s11-legend-row.is-plan{ animation-name:s11-legend-3; }
@keyframes s11-legend-1{ 0%,53%{ opacity:0; } 59%,100%{ opacity:1; } }
@keyframes s11-legend-2{ 0%,61%{ opacity:0; } 66%,100%{ opacity:1; } }
@keyframes s11-legend-3{ 0%,73%{ opacity:0; } 79%,100%{ opacity:1; } }

/* ---- 开场推镜：安赛龙举着平板在库里检索 ----
   放大的只有那块屏：人形一直保持常驻时的大小，
   否则线稿被放大 3 倍后头是个色块、四肢是几根粗棒。 */
.s11-scout-zoom{ animation:s11-zoom var(--s11-target-duration) var(--ease-in-out); }
@keyframes s11-zoom{
  0%,13%  { transform:translate(177px,-60px) scale(3); }
  20%,100%{ transform:none; }
}
.s11-figure{ opacity:0; animation:s11-scout-in var(--s11-target-duration) var(--ease-enter); }
.s11-tablet{ opacity:0; animation:s11-scout-in var(--s11-target-duration) var(--ease-enter) .12s; }
@keyframes s11-scout-in{
  0%     { opacity:0; transform:translate(0,8px); }
  7%,100%{ opacity:1; transform:none; }
}
/* 检索完就退场：人形只负责把开场那次推镜交代清楚。
   留在原地会一直贴着档案卡的左下角，把这一幕最挤的一角再挤一档。 */
.s11-target-stage .s11-scout{ animation:s11-scout-retire var(--s11-target-duration) var(--ease-ui) var(--s11-target-delay); }
@keyframes s11-scout-retire{
  0%,46%  { opacity:1; }
  56%,100%{ opacity:0; }
}
/* 头换成安赛龙的真实头像：这一幕的使用者是他本人，不是一个通用小人 */
.s11-fig-photo{ filter:saturate(.82) contrast(1.03); }
.s11-fig-ring{ fill:none; stroke:var(--navy); stroke-width:2; }
.s11-fig-line{ fill:none; stroke:var(--navy); stroke-width:2.6; stroke-linecap:round;
  stroke-linejoin:round; }
.s11-fig-line.is-thin{ stroke-width:1.8; }
.s11-fig-hand{ fill:var(--navy); }
.s11-fig-racket{ fill:none; stroke:var(--navy); stroke-width:1.6; }
.s11-tablet-body{ fill:var(--ink-2); vector-effect:non-scaling-stroke; }
.s11-tablet-screen{ fill:var(--screen); vector-effect:non-scaling-stroke; }
.s11-mini-photo{ opacity:0; filter:saturate(.82) contrast(1.03);
  animation:s11-mini-in var(--s11-target-duration) var(--ease-out) var(--delay,0s); }
@keyframes s11-mini-in{
  0%,5%   { opacity:0; }
  9%,100% { opacity:1; }
}
/* 落焦之后，没被选中的五个人退到背景里 */
.s11-minis .is-dim .s11-mini-photo{ animation-name:s11-mini-dim; }
@keyframes s11-mini-dim{
  0%,5%   { opacity:0; }
  9%,11%  { opacity:1; }
  17%,100%{ opacity:.28; }
}
/* 对手是定好的，不是从库里随机挑一个：环从外圈收拢到桃田那一颗上，
   同时其余五颗暗下去。不做逐个走位——走位读起来就是「随便选一个」。 */
.s11-focus-ring{
  fill:none; stroke:var(--accent); stroke-width:1.8; opacity:0;
  transform-box:fill-box; transform-origin:center;
  vector-effect:non-scaling-stroke; animation:s11-focus var(--s11-target-duration) cubic-bezier(.22,.61,.36,1);
}
@keyframes s11-focus{
  0%,4%   { opacity:0; transform:scale(3.2); }
  6%      { opacity:.55; }
  14%,100%{ opacity:1; transform:scale(1); }
}

/* ---------- 窄屏 ---------- */
@media (max-width:1240px){
  .deck{ --gutter:68px; }
  /* 两栏还在、右列被压到 285–366px：标题与正文跟着列宽走，
     否则写定的每行会在这一段折断，落回半个词收尾的样子。 */
  .act-t{ font-size:clamp(20px, 1.82vw, 25px); }
  .act-d{ font-size:clamp(12.5px, 1.17vw, 15px); }
}
@media (max-width:1000px){
  /* 单列后一幕的高度不再由内容决定，而是由视口给定：
     文字先按自己需要的高度排完，舞台吃掉剩下的全部空间，画面等比缩进去。

     前提是卡片得有一个「确定高度」——只有确定高度，flex 的 1fr 才有东西可分。
     原来的走道写在 .deck 的 padding 上，卡片是绝对定位 + auto 高度，拿不到这个数；
     改成卡片自己用四边 inset 表达走道（顶部 56px 让开导航，底部 82px 让开翻页控件），
     高度因此等于 deck 高度减去两条走道。 */
  .deck{ --gutter:20px; padding:0; }
  .deck .card{
    inset:132px var(--gutter) 82px; width:auto; min-height:0;
    display:flex; flex-direction:column; gap:18px;
    /* 两列版的 align-items:center 得显式改回 stretch：
       竖排后交叉轴是宽度，居中会让亮面按内容宽收缩（静态两幕加了尺寸容器后更直接塌成 0）。 */
    align-items:stretch;
  }
  .deck .card.is-team-intro{ gap:14px; }
  .deck .card.is-team-intro .act-stage{ min-height:0; }
  /* min-height:0 是必须的：flex 项默认 min-height:auto，舞台会被内容顶住不肯收缩 */
  .act-stage{
    flex:1 1 auto; min-height:0;
    display:grid; grid-template-rows:minmax(0,1fr) auto;
    /* safe：内容缩到下界仍然装不下时（见下），居中会把顶部截掉且滚不回去，此时退回 start */
    align-items:safe center; justify-items:safe center;
    /* 兜底：亮面自己收住溢出，任何情况下都不会有东西画到暗底上 */
    overflow:auto; scrollbar-width:none;
  }
  .act-stage::-webkit-scrollbar{ display:none; }
  /* SVG 自带 viewBox，撑满格子后由 preserveAspectRatio 居中留边，永远不会溢出 */
  .scene{ width:100%; height:100%; }
  /* 幕零的 SVG 外面还包了一层 .hall，高度不传下去 SVG 的 height:100% 就落到 auto */
  .hall{ width:100%; height:100%; min-height:0; display:grid; }
  /* canvas 那两幕没有 viewBox，改成按高度反推宽度 */
  .intro-shell{ width:auto; height:100%; max-width:100%; margin:0 auto; }
  /* 静态小结的"画面"是一张文字表格，没有 viewBox 可缩。
     把亮面声明成尺寸容器，表格的字号改用 cqh——舞台矮多少，整张表就等比小多少。
     只在窄屏声明 container-type:size：宽屏下亮面的高度由内容决定，一旦加上尺寸容器就会塌成 0。 */
  /* 幕一的播放器是一整套定尺寸的窗口 chrome + 16:9 画面，也缩不了高。
     但它的高度是宽度的线性函数（实测 h ≈ 0.53w + 124，另加 35px 的重播行），
     所以反过来由可用高度定宽度——窗口边框保持原尺寸，只有画面跟着缩。 */
  #act-watch .act-stage{ container-type:size; }
  .watch{ width:min(100%, max(220px, calc((100cqh - 162px) * 1.887))); margin-inline:auto; }
  /* 播放器变窄后控件行会把「00:13:04 / 01:12:36」折成两行，压在教练背影上 */
  .ctl-row{ gap:8px; }
  .ctl-group{ gap:8px; }
  .ctl-time{ white-space:nowrap; font-size:10.5px; margin-left:2px; }
  .card.is-static .act-stage{ container-type:size; }
  /* 下界是可读性底线，不是装得下的保证：视口再矮（如 320×568、横屏 500px 高）
     五行表格无论多小都排不进去，那时由亮面自己的 overflow 兜底。 */
  .ledger{ font-size:clamp(7.1px, 3.6cqh, 13px); }
  .card-body{ flex:none; padding:0 4px; }
  .deck-tools{ right:var(--gutter); }
  /* 箭头下沉到与圆点同一行。不再按圆点行宽反推位置——十二颗圆点加三处分组间隔
     已经宽到 239px，任何"半行 + 间距"的常数都会压到圆点上；改成钉在两端。 */
  .deck-arrow{ top:auto; bottom:14px; margin-top:0; }
  .deck-arrow.prev{ left:12px; }
  .deck-arrow.next{ right:12px; }
  .deck-dots{ bottom:31px; }
  .deck .card[data-narration-compare="fixed"]{
    display:block; overflow:auto; scrollbar-width:none;
  }
  .deck .card[data-narration-compare="fixed"]::-webkit-scrollbar{ display:none; }
  .card[data-narration-compare="fixed"] .act-stage{
    display:block; min-height:0; overflow:hidden;
  }
  .card[data-narration-compare="fixed"] .scene{ width:100%; height:auto; }
  .card[data-narration-compare="fixed"] .intro-shell{
    width:100%; height:auto; max-width:none; margin:0; aspect-ratio:var(--shell,640/408);
  }
}
@media (max-width:720px){
  /* 圆点行收窄到 199px，320px 宽的机器上两端的箭头才不会压上来 */
  .deck-dots{ left:50%; bottom:64px; gap:6px; }
  .deck-dot:nth-child(2), .deck-dot:nth-child(8){ margin-left:10px; }
  .deck-tools{ right:60px; bottom:14px; gap:6px; }
  .deck-replay,
  .deck-audio{
    width:40px; height:40px;
    justify-content:center; gap:0; padding:0; font-size:0;
  }
  .act-t{ font-size:22px; }
  .act-stage{ padding:10px 10px 10px; border-radius:14px; }
  .card-foot{ margin-top:20px; padding-top:15px; }
  .cost-thought{ left:50%; top:12%; width:48%; }
  .cost-thought-kicker{ font-size:16px; }
  .cost-thought-core{ font-size:33px; }
  .cost-thought-action{ margin-left:.32em; font-size:32px; }
  .cost-thought-beam{ left:-45%; bottom:8%; width:50%; }
  /* 手机上三列排不下。改成两行：条目名一行，「旧 → 新」并排占第二行。
     固定列宽或等分两列都会让每一格竖排换行，把这张卡撑到其他卡片的一倍半高。 */
  .card.is-static .act-stage{ padding:20px 16px; }
  .ledger-head, .ledger-row{
    grid-template-columns:max-content minmax(0,1fr);
    grid-template-areas:"k k" "before after";
    gap:.154em .615em;
  }
  .ledger-title, .ledger-k{ grid-area:k; }
  .ledger-col.is-before, .ledger-before{ grid-area:before; }
  .ledger-col.is-after, .ledger-after{ grid-area:after; }
  .ledger-head{ gap:.615em; }
  .ledger-row{ padding:.385em 0; }
  .ledger-k{ font-size:.962em; line-height:1.4; }
  .ledger-before, .ledger-after{ font-size:.885em; line-height:1.45; }
  .ledger-before::after{ content:"→"; margin-inline:.385em; color:var(--rule); }
  .ledger-row.is-total{ padding-top:.615em; }
  .ledger-row.is-total .ledger-before{ font-size:1.308em; }
  .ledger-row.is-total .ledger-after{ font-size:.923em; }
  .win-list li{ margin-top:10px; font-size:13.5px; line-height:1.7; }
  .comparison-header{ margin-bottom:10px; }
  .comparison-header .act-eyebrow{ margin-bottom:5px; }
  .comparison-columns{ grid-template-columns:1fr; gap:9px; }
  .deck [data-narration-compare="fixed"] .comparison-panel{
    grid-area:auto; width:auto; z-index:auto; justify-self:stretch;
    opacity:.42; transform:scale(.992); transform-origin:center;
    animation:none !important; transition:opacity .2s var(--ease-ui);
  }
  .deck [data-narration-compare="fixed"] .comparison-panel.is-traditional,
  .deck [data-narration-compare="fixed"] .comparison-panel.is-keymoment{
    width:auto; justify-self:stretch;
    transform:scale(.992); transform-origin:center;
  }
  .deck [data-narration-compare="fixed"] .comparison-panel::after{
    display:none; animation:none !important;
  }
  .deck [data-narration-compare="fixed"][data-comparison-playback="traditional"]
    .comparison-panel.is-traditional,
  .deck [data-narration-compare="fixed"][data-comparison-playback="keymoment"]
    .comparison-panel.is-keymoment{
    z-index:auto; opacity:1; transform:none;
  }
  .comparison-panel{
    display:grid; grid-template-columns:1fr;
    grid-template-areas:"label" "visual" "copy";
    row-gap:8px; padding:9px 10px 12px; border-radius:14px;
  }
  .card[data-narration-compare="fixed"]{
    --type-lead-size:13px;
    --type-caption-size:11px;
  }
  .comparison-panel-label{ grid-area:label; min-height:20px; margin:0 1px 6px; font-size:12.5px; }
  .comparison-traditional-visual,
  .card[data-narration-compare="fixed"] .act-stage{
    grid-area:visual; align-self:center; width:100%; height:180px;
  }
  .comparison-traditional-visual{ height:180px; }
  .traditional-scene{ grid-area:visual; align-self:center; width:100%; height:180px; }
  .traditional-scene.is-notes .traditional-paper{
    right:1%; width:72%; padding:4% 2% 3% 8%;
  }
  .traditional-scene.is-notes .traditional-note-opponent{ font-size:8.5px; }
  .traditional-scene.is-notes .traditional-note-rows{
    grid-template-rows:repeat(4,auto); align-content:space-between;
  }
  .traditional-scene.is-notes .traditional-note-row{ padding:2px 0 1px; }
  .traditional-scene.is-notes .traditional-note-row > b{ font-size:7.2px; line-height:1.15; }
  .traditional-scene.is-notes .traditional-note-row > span{
    margin-top:0; font-size:8.2px; line-height:1.25;
    white-space:normal; overflow-wrap:anywhere;
  }
  .traditional-scene.is-notes .traditional-note-page{ font-size:7px; }
  .traditional-scene.is-analysis .traditional-summary-note{ padding:1% 3%; border-left-width:1px; }
  .traditional-scene.is-analysis .traditional-summary-note > b{ font-size:6.5px; }
  .traditional-scene.is-analysis .traditional-summary-note > strong{ margin-top:1px; font-size:7.8px; }
  .traditional-scene.is-analysis .traditional-summary-note > em{ margin-top:1px; font-size:6px; }
  .traditional-scene.is-analysis .traditional-sort-column{ padding:1.5px 1px; }
  .traditional-scene.is-analysis .traditional-sort-column > b{ font-size:6.5px; }
  .traditional-scene.is-analysis .traditional-sort-column > em{ margin-top:1px; font-size:5.8px; }
  .traditional-scene.is-analysis .traditional-manual-verdict{ padding:3px 4px; border-left-width:1px; font-size:6.8px; }
  .traditional-scene.is-analysis .traditional-coach.is-sort{ right:-14%; bottom:-34%; height:70%; }
  .deck .comparison-panel .comparison-copy{
    grid-area:copy; position:static; align-self:center; min-height:0; margin:0;
    font-size:14.5px; line-height:1.58;
  }
  .comparison-visual-caption{ display:none; }
  .comparison-visual-object{ width:54%; height:49%; }
  .card[data-narration-compare="fixed"] .act-stage{ padding:6px; border-radius:9px; }
  #act-keyshot .comparison-panel.is-keymoment .intro-canvas{ width:114%; }
  .card[data-narration-compare="fixed"] .card-foot,
  .deck [data-narration-compare="fixed"] .card-foot{
    margin-top:10px; padding-top:9px;
  }
  .card[data-narration-compare="fixed"] .act-stat{
    grid-template-columns:1fr; gap:2px;
  }
  .comparison-result-label{ margin-bottom:3px; font-size:9.5px; }
  .deck [data-narration-compare="fixed"] .narration-progress{
    margin-top:18px;
  }
  .deck .card.is-static{
    display:block; overflow:auto; scrollbar-width:thin;
    -webkit-overflow-scrolling:touch;
  }
  .summary-columns{ display:block; }
  .summary-aside{ display:none; }
  .summary-columns > *{ min-height:0; }
  .card.is-static .act-stage{ container-type:normal; padding:12px; }
  .card.is-static .ledger{ font-size:10.5px; }
  .card.is-static .ledger-head,
  .card.is-static .ledger-row{
    grid-template-columns:54px minmax(0,.9fr) minmax(0,1.15fr);
    grid-template-areas:"k before after"; gap:6px;
  }
  .card.is-static .ledger-head{ padding-bottom:7px; }
  .card.is-static .ledger-row{ align-items:start; padding:5px 0; }
  .card.is-static .ledger-before::after{ content:none; }
  .card.is-static .ledger-row.is-total{ padding-top:7px; }
  .card.is-static .ledger-row.is-total .ledger-before,
  .card.is-static .ledger-row.is-total .ledger-after{ font-size:1em; }
}

/* ---------- 降低动态效果 ---------- */
@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  .deck [data-narration-compare="fixed"] .comparison-panel{
    animation:none !important; transition:opacity .2s var(--ease-ui);
  }
  .deck [data-narration-compare="fixed"] .comparison-panel::after{
    animation:none !important; transition:opacity .2s var(--ease-ui);
  }
  .traditional-scene *{ animation:none !important; }
  .team-intro-court-drift,
  .team-intro-court-rise,
  .team-intro-court-image{ animation:none !important; }
  .team-intro-person{
    opacity:1; transform:translate(var(--team-x),0) scale(1);
  }
  .act-stage *{ animation:none !important; }
  #act-manual-review .manual-watch,
  #act-manual-review .manual-write,
  #act-manual-review .manual-sort{ display:none; }
  #act-manual-review .manual-capture{ opacity:1; transform:none; }
  #act-manual-review .manual-question{
    opacity:0; transform:none;
    animation:manual-question-reduced 2.4s linear both !important;
  }
  #act-manual-review .manual-ai-bridge-world,
  #act-manual-review .manual-ai-manual-materials{ transform:none; }
  #act-manual-review .manual-ai-manual-materials{ opacity:.35; }
  #act-manual-review .manual-ai-screen-light,
  #act-manual-review .manual-ai-signal{ opacity:1; transform:none; }
  .deck .card .card-body{ transform:none; }
  .deck .card.is-current .act-stage,
  .deck .card.is-current .card-body > *{ animation:none; }
  .deck .narration-step,
  .deck .narration-step.is-narration-visible,
  .deck .card-foot,
  .deck .card-foot.is-narration-visible{
    transform:none; transition:opacity 120ms linear, visibility 0s linear 120ms;
  }
  .deck .card-foot::before,
  .deck .card-foot::after,
  .deck .card-foot .act-stat .n,
  .deck .card-foot .act-stat .k{
    transition:none;
  }
  .cost-daylight, .cost-sky-sunset, .cost-sun{ opacity:0; }
  .cost-sky-night, .cost-stars, .cost-moon{ opacity:1; transform:none; }
  .cost-room-night{ opacity:.34; }
  .cost-lamp-cone{ opacity:.12; }
  .cost-lamp-glow{ opacity:.22; }
  .cost-night-structure{ opacity:.62; }
  .cost-night-papers{ opacity:.86; }
  .cost-scene{ transform:none; }
  .cost-focus-veil{ opacity:.97; }
  .cost-coach-focus{ opacity:1; }
  .cost-thought-kicker, .cost-thought-core, .cost-thought-action{
    opacity:1; transform:none;
  }
  .cost-thought-beam{ opacity:1; transform:rotate(-16deg) scaleX(1); }
  .deck #act-cost .card-body{
    opacity:0; transform:none; animation:none;
  }
  .cost-review-fill{ transform:scaleX(1); }
  .cost-review-knob{ transform:translateX(140px); }
  .cost-page, .cost-note{ opacity:1; transform:none; }
  .cost-coach{ transform:translateY(8px) rotate(3deg); }
  .cost-work-arm{ transform:translate(42px,15px) rotate(10deg); }
  .cost-cup-level{ transform:scaleY(.12); }
  /* 交接整段取消：新卡直接顶上，旧卡不垫场 */
  .deck .card.is-leaving{ visibility:hidden; }
  .clock-hour-hand{ transform:rotate(70deg); }
  .clock-minute-hand{ transform:rotate(215deg); }
  .s3-cols, .s3-out{ opacity:1; }
  .s2-cover, .s2-turn, .s2-pageno.b{ opacity:0; }
  .s7-source, .s7-status, .s7-keyshot-card, .s7-peak-ring, .s7-curve-peak{ opacity:0; }
  .s7-group, .s7-result-dot, .s7-fill-dot{ opacity:1; }
  .s7-flight{ transform:translate(var(--gx),var(--gy)); }
  .s9-row, .s9-head, .s9-ghost, .s9-foot, .s9-flow, .s9-radar{ opacity:1; }
  .s9-group, .s9-pop{ opacity:0; }
  .s9-radar-edge{ stroke-dashoffset:0; }
  .s9-radar-fill{ fill-opacity:.16; }
  .s9-radar-dot{ opacity:1; transform:scale(1); }
  .s9-fill{ transform:scaleX(1); }
  .s8-line{ stroke-dashoffset:0; }
  .s8-from, .s8-land, .s8-stat, .s8-advice{ opacity:1; transform:none; }
  .s11-board, .s11-versus, .s11-seat-fill, .s11-dossier, .s11-radar-fill,
  .s11-figure, .s11-tablet, .s11-mini-photo, .s11-focus-ring,
  .s11-legend-row{ opacity:1; transform:none; }
  .s11-court3d path, .s11-line{ stroke-dashoffset:0; }
  .s11-radar-edge{ stroke-dashoffset:0; }
  .s11-weak, .s11-from, .s11-land, .s11-court .s0-player{ opacity:1; transform:none; }
  .s11-weak-ring{ opacity:0; }
  .s11-zone{ opacity:.9; transform:none; }
  .s11-evidence{ opacity:.62; }
  .s11-minis .is-dim .s11-mini-photo{ opacity:.28; }
  .scrub-played{ width:70%; }
  .review-freeze-effect{ transform:none; transition:opacity 160ms var(--ease-out); }
  .s2-upper{ transform:rotate(35.22deg); }
  .s2-fore{ transform:rotate(-92.35deg); }
  .s2-hold{ transform:rotate(57.14deg); }
}
