/* ============================================================
 * nexus-video · cards-skin.css
 * 帆船自做视频「视觉资产库」单一权威源
 * v1 2026-06-13 抽自 hinton 实战（11 组件）
 * v2 2026-06-14 架构重组扩展至 28 组件（补 17 种 Result 库 CSS 基础）
 * v3 2026-07-04 全面去 backdrop-filter（.lc4/.odo-panel/.mapcard → 高 alpha 底色）· HF 官方 performance 实证大面积 backdrop blur 最高 200ms/帧 · ai-kefu-38k 渲染 11fps 元凶
 *
 * 用法：composition / cards mock-up 在 <head> 引用即可：
 *   <link rel="stylesheet" href="../../.claude/skills/nexus-video/templates/cards-skin.css">
 * 或 inline 引用（部署独立画廊用）。
 *
 * 演化原则：
 *   - 这是**单一权威源**。skill 工法描述指向本文件，不指向具体片子实例
 *   - 新片做完发现本文件没覆盖的视觉资产 → 抽出来加进本文件持续迭代
 *   - 本文件 CSS 都是**画幅无关**（横竖屏都适用），字号/位置用 CSS 变量或类名修饰符控制
 *
 * 历史来源（首版抽取自）：hinton-full/gen_full.py 第 776-823 行 + helper 函数 866-880 行
 * v1.4 mapcard animation infinite→1 forwards · 2026-06-14 ep03 C1.2 实证
 * ============================================================ */

/* === 字体 === */
/* 字体文件需放各项目 assets/fonts/ 下（子集化后的 woff2 / 原 ttc 任选）*/
/* @font-face 由各项目 index.html 自己写（不在本 skin 里硬绑路径）*/

/* === 调色层（每张卡 / 每个 composition 必有，质感一半在这两层）=== */
.vignette{position:absolute;inset:0;z-index:14;pointer-events:none;
  background:radial-gradient(ellipse 80% 66% at 50% 40%,rgba(0,0,0,0) 40%,rgba(0,0,0,.28) 76%,rgba(5,4,3,.66) 100%)}
.toneWash{position:absolute;inset:0;z-index:15;pointer-events:none;mix-blend-mode:soft-light;opacity:.55;
  background:radial-gradient(circle at 50% 32%,rgba(232,182,77,.2),rgba(232,182,77,0) 46%),
             radial-gradient(circle at 50% 90%,rgba(28,60,120,.24),rgba(28,60,120,0) 52%)}

/* === C4 玻璃卡（招牌组件 · logo 卡 / 任何方形 / 圆形玻璃容器）=== */
.lc4{position:absolute;z-index:45;border-radius:32px;display:flex;align-items:center;justify-content:center;overflow:hidden;
  /* 2026-07-04 去 backdrop-filter（HF performance：大面积 backdrop blur 最高 200ms/帧）→ 提底色 alpha 保可读 */
  background:linear-gradient(165deg,rgba(247,224,174,.16) 0%,rgba(18,22,34,.78) 38%,rgba(14,17,26,.80) 62%,rgba(229,169,60,.12) 100%);
  box-shadow:inset 0 1px 0 rgba(255,252,245,.22), 0 18px 44px rgba(0,0,0,.5);
  will-change:transform,opacity}
.lc4::after{content:"";position:absolute;inset:0;border-radius:32px;padding:3.5px;
  background:linear-gradient(165deg,#f7e0ae 0%,#9c7a38 28%,#e5a93c 50%,#5d4519 72%,#d9b66e 100%);
  -webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;pointer-events:none}
/* glint 扫光（GSAP 驱动：xPercent -260 → 330，duration .7，ease power2.inOut，触发时 t+.15）*/
.lc4 .glint{position:absolute;top:-20%;bottom:-20%;width:72%;left:0;z-index:2;
  background:linear-gradient(105deg,transparent 0%,rgba(255,250,235,0) 28%,rgba(255,250,235,.34) 50%,transparent 78%);
  transform:translateX(-260%) skewX(-12deg);pointer-events:none}
.lc4 img{width:62%;height:62%;object-fit:contain;position:relative;z-index:1;opacity:0}

/* 圆形变体（责任链节点 / 角色 ring）*/
.lc4.round,.lc4.round::after{border-radius:50%}

/* === 流式布局修饰类（in-flow）=== */
/* skin 默认 position:absolute（为 composition 精确定位）；mock-up / 横排画廊 / 多卡 flex 场景用 .inflow 改 relative */
.lc4.inflow,.port.inflow,.newscard.inflow,.splitcard.inflow,.tline.inflow,.chain.inflow,.list4.inflow,.quote.inflow,.gate.inflow,.pop.inflow,.lst.inflow,.punchline.inflow,.mapcard.inflow{position:relative;left:auto;right:auto;top:auto;bottom:auto;inset:auto}

/* === 端口标签（信息标签：左/右上信息区 · 暖金玻璃质感）=== */
.port{position:absolute;z-index:11;padding:14px 30px;border-radius:12px;
  border:1.6px solid rgba(255,216,116,.6);
  background:linear-gradient(180deg,rgba(22,17,10,.8),rgba(8,6,4,.66));
  font-family:"Source Han Serif SC",serif;font-weight:800;color:#FFE7AE;letter-spacing:6px;
  box-shadow:0 0 46px rgba(232,182,77,.28),inset 0 0 22px rgba(232,182,77,.14);
  text-shadow:0 6px 22px rgba(0,0,0,.7);
  opacity:0;will-change:opacity,transform}

/* === Gate 大字（高潮揭示 · 三层 text-shadow）=== */
.gate{position:absolute;z-index:47;left:0;right:0;text-align:center;
  font-family:"Source Han Serif SC",serif;font-weight:800;color:#fff;letter-spacing:10px;
  text-shadow:0 0 70px rgba(229,169,60,.78),0 0 150px rgba(229,169,60,.4),0 18px 56px rgba(0,0,0,.82);
  opacity:0;will-change:opacity,transform}
.gate em{font-style:normal;color:#E5A93C}

/* === Text-Behind 大字（帆船招牌·z=18 夹在 subjVid z=20 之后 / 背景 z=1+ 之前 · 钦点核心视觉）=== */
/* 来源：ep03 drone-full 2026-06-13 抽出（SKILL §A 三层 composition / §B 行 158-164 / 沉淀铁律 10）
   用法：z=18 必须 < subjVid z=20 = 大字被人物挡 = text-behind 效果成立；
        藏字法 = JS GSAP translateX/Y 让"被遮字"落到人头投影 x 区间 */
.tbh{position:absolute;left:0;right:0;text-align:center;white-space:nowrap;
  font-family:"Source Han Serif SC",serif;font-weight:900;color:#fff;letter-spacing:8px;
  text-shadow:0 0 56px rgba(0,0,0,.78),0 14px 48px rgba(0,0,0,.72),0 4px 18px rgba(0,0,0,.92);
  opacity:0;will-change:opacity,transform;z-index:18}
.tbh.gold{color:#FFD874;text-shadow:0 0 60px rgba(229,169,60,.42),0 14px 48px rgba(0,0,0,.72)}
.tbh em{font-style:normal;color:#E5A93C}

/* === Pop 关键花字（金句 · GSAP popIn 用）=== */
.pop{position:absolute;z-index:46;font-family:"Source Han Serif SC",serif;font-weight:800;color:#fff;
  text-shadow:0 0 34px rgba(229,169,60,.66),0 12px 42px rgba(0,0,0,.74),0 4px 18px rgba(0,0,0,.9);
  opacity:0;will-change:opacity,transform}
.pop.gold{color:#FFD874}
.pop .edge{-webkit-text-stroke:2.5px rgba(10,8,4,.62)}

/* === 列表大字（lst · 阶进步进项目）=== */
.lst{position:absolute;z-index:46;
  font-family:"Source Han Serif SC",serif;font-weight:800;color:#fff;letter-spacing:3px;
  text-shadow:0 0 30px rgba(0,0,0,.8),0 10px 36px rgba(0,0,0,.74);
  opacity:0;will-change:opacity,transform}
.lst.gold{color:#FFD874;text-shadow:0 0 34px rgba(229,169,60,.5),0 10px 36px rgba(0,0,0,.74)}

/* === Mask Reveal（语义 reveal：行容器 overflow + 子元素 yPercent 上升）=== */
.mrv{position:absolute;z-index:47;left:0;right:0;text-align:center}
.mrv .ln{overflow:hidden;line-height:1.32}
.mrv .ln i{display:block;font-style:normal;font-family:"Source Han Serif SC",serif;font-weight:800;
  color:#fff;text-shadow:0 0 60px rgba(229,169,60,.6),0 14px 46px rgba(0,0,0,.8);will-change:transform}
.mrv .ln .mgold{color:#E5A93C;text-shadow:0 0 70px rgba(229,169,60,.7),0 14px 46px rgba(0,0,0,.8)}

/* === Quote 引用卡（金边 + 双层渐变 + 大阴影）=== */
.quote{position:absolute;z-index:46;padding:44px 52px;border-radius:18px;
  border:1.5px solid rgba(229,169,60,.4);
  background:linear-gradient(180deg,rgba(16,12,7,.88),rgba(8,6,4,.8));
  font-family:"Source Han Serif SC",serif;color:#f3ead4;
  box-shadow:0 24px 80px rgba(0,0,0,.6);
  opacity:0;will-change:opacity,transform}
.quote .qkicker{font-weight:700;color:rgba(229,169,60,.85);letter-spacing:4px;
  font-family:ui-monospace,"SF Mono",Menlo,monospace;margin-bottom:18px}
.quote .qtext{font-weight:700;line-height:1.4;font-style:italic}
.quote .qfrom{font-style:normal;color:rgba(229,169,60,.85);text-align:right;letter-spacing:3px;margin-top:18px}

/* === Punchline 大字（核心金句 · 三层阴影）=== */
.punchline{position:absolute;z-index:48;left:0;right:0;text-align:center;
  font-family:"Source Han Serif SC",serif;font-weight:800;color:#fff;letter-spacing:4px;
  text-shadow:0 0 70px rgba(229,169,60,.6),0 18px 56px rgba(0,0,0,.85);
  opacity:0;will-change:opacity,transform}
.punchline em{font-style:normal;color:#E5A93C}

/* === 字幕基础（横竖屏字号通过 class 修饰符或外部变量控制）=== */
.sub{position:absolute;left:0;right:0;top:0;white-space:nowrap;
  font-family:"Noto Sans CJK SC",sans-serif;font-weight:800;line-height:1;letter-spacing:1px;
  text-shadow:0 3px 14px rgba(0,0,0,.96),0 0 26px rgba(0,0,0,.82);opacity:0}
.sub .ch{display:inline-block;color:rgba(235,235,235,.62);will-change:color,transform}
.sub .ch.kw{color:rgba(234,210,150,.62)}
.sub .ch.lit{color:#fff}
.sub .ch.kw.lit{color:#FFD874}

/* ============================================================
 * 报道截图卡（v1 新增 · ep03 抽出，hinton 没有此组件）
 * 用于 F8 引用 / 媒体报道展示
 * ============================================================ */
.newscard{position:absolute;z-index:46;background:#fafafa;border-radius:12px;overflow:hidden;color:#222;
  font-family:Georgia,"Source Han Serif SC",serif;
  box-shadow:0 30px 80px rgba(0,0,0,.7),0 0 0 1px rgba(229,169,60,.4);
  opacity:0;will-change:opacity,transform}
.newscard .nhead{background:#E5A93C;color:#0a0c10;padding:18px 40px;font-weight:900;letter-spacing:6px;
  font-family:-apple-system,"Noto Sans CJK SC",sans-serif}
.newscard .nbody{padding:40px 50px 50px}
.newscard .ntitle{font-weight:700;line-height:1.25;margin-bottom:24px}
.newscard .nhl{display:inline;background:rgba(229,169,60,.45);padding:0 4px}
.newscard .nmeta{color:#777;display:flex;gap:30px;font-family:-apple-system,sans-serif}

/* ============================================================
 * 分屏对比卡（v1 新增 · ep03 抽出，hinton 没有此组件）
 * 用于 F7 对比 / 左静右动信号
 * ============================================================ */
.splitcard{position:absolute;z-index:46;display:flex;border-radius:24px;overflow:hidden;
  background:linear-gradient(180deg,rgba(16,12,7,.7),rgba(8,6,4,.5));
  border:1.5px solid rgba(229,169,60,.3);box-shadow:0 24px 60px rgba(0,0,0,.6);
  opacity:0;will-change:opacity,transform}
.splitcard > div{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:36px;padding:60px}
.splitcard .l{border-right:2px dashed rgba(229,169,60,.3)}
.splitcard .lab{font-family:"Source Han Serif SC",serif;color:rgba(229,169,60,.85);letter-spacing:8px;font-weight:700}
.splitcard .val{font-family:"Source Han Serif SC",serif;font-weight:900;letter-spacing:3px;
  text-shadow:0 0 40px rgba(229,169,60,.5),0 12px 36px rgba(0,0,0,.7)}
.splitcard .l .val{color:#fff}
.splitcard .r .val{color:#c25a3e;text-shadow:0 0 40px rgba(194,90,62,.6),0 12px 36px rgba(0,0,0,.7)}

/* ============================================================
 * 时间轴节点链（v1 新增 · ep03 抽出，hinton 没有此组件）
 * 用于 F9 时序列举 / 阶段递进
 * ============================================================ */
.tline{position:absolute;z-index:46}
.tline .bar{position:absolute;left:0;right:0;height:4px;background:rgba(229,169,60,.18);border-radius:2px}
.tline .bar i{position:absolute;inset:0;background:linear-gradient(90deg,#E5A93C,#c25a3e);
  transform-origin:left;transform:scaleX(0);box-shadow:0 0 20px rgba(229,169,60,.6);will-change:transform}
.tline .nodes{display:flex;justify-content:space-between;position:relative}
.tline .nd{display:flex;flex-direction:column;align-items:center}
.tline .nd .dot{width:32px;height:32px;border-radius:50%;background:rgba(60,68,80,.8);
  border:3px solid rgba(229,169,60,.3);position:relative;z-index:2;will-change:background,box-shadow}
.tline .nd.lit .dot{background:#E5A93C;border-color:#E5A93C;box-shadow:0 0 24px rgba(229,169,60,.8)}
.tline .nd.warn .dot{background:#c25a3e;border-color:#c25a3e;box-shadow:0 0 30px rgba(194,90,62,.9)}
.tline .nd .yr{font-family:"Source Han Serif SC",serif;font-weight:900;color:#fff;letter-spacing:4px;
  text-shadow:0 0 40px rgba(229,169,60,.5),0 12px 36px rgba(0,0,0,.7);opacity:0;will-change:opacity}
.tline .nd .lbl{font-family:"Source Han Serif SC",serif;color:rgba(255,231,174,.7);letter-spacing:4px;opacity:0}
.tline .nd.warn .yr{color:#c25a3e;text-shadow:0 0 50px rgba(194,90,62,.7),0 12px 36px rgba(0,0,0,.7)}
.tline .nd.warn .lbl{color:#c25a3e}

/* ============================================================
 * 责任链节点 + 末环粒子消散（v1 新增 · ep03 抽出）
 * 用于 F9 列举 + F1 链条断裂强声明
 * 节点用 .lc4.round 玻璃环；粒子用 .pburst 单元
 * ============================================================ */
.chain{position:absolute;z-index:46;display:flex;align-items:center;justify-content:center;gap:0}
.chain .nd{display:flex;flex-direction:column;align-items:center;position:relative}
.chain .nd .lbl{font-family:"Source Han Serif SC",serif;font-weight:800;color:#FFE7AE;letter-spacing:4px;
  text-shadow:0 6px 22px rgba(0,0,0,.7),0 0 20px rgba(232,182,77,.4);margin-top:24px;opacity:0;will-change:opacity}
.chain .seg{height:4px;background:rgba(229,169,60,.15);position:relative;overflow:hidden;border-radius:2px}
.chain .seg i{position:absolute;inset:0;background:linear-gradient(90deg,#E5A93C,#d9b66e);
  box-shadow:0 0 20px rgba(229,169,60,.6);transform:scaleX(0);transform-origin:left;will-change:transform}
/* 末环蒸发态：节点+标签红化 → 粒子炸开消散 */
.chain .nd.melt .lbl{animation:chain-lbl-melt 1.5s forwards}
@keyframes chain-lbl-melt{0%{color:#FFE7AE}50%{color:#c25a3e;text-shadow:0 0 30px rgba(194,90,62,.8)}100%{color:rgba(194,90,62,0);filter:blur(8px)}}
.chain .pburst{position:absolute;left:50%;top:32%;width:6px;height:6px;border-radius:50%;background:#c25a3e;
  opacity:0;box-shadow:0 0 8px rgba(194,90,62,.8);will-change:transform,opacity}

/* ============================================================
 * 4 项列表卡（v1 新增 · ep03 抽出）
 * 用于 F9 列举 / "没有 X" 类反复否定
 * 玻璃质感 + 暖金边 + 末项红警边框
 * ============================================================ */
.list4{position:absolute;z-index:46;display:flex;flex-direction:column;gap:30px}
.list4 .item{background:linear-gradient(180deg,rgba(22,17,10,.85),rgba(8,6,4,.7));
  border:1.5px solid rgba(229,169,60,.35);border-radius:18px;padding:30px 50px;
  display:flex;align-items:center;gap:30px;
  font-family:"Source Han Serif SC",serif;font-weight:800;color:#f3ead4;letter-spacing:3px;
  box-shadow:0 12px 36px rgba(0,0,0,.6),inset 0 1px 0 rgba(255,252,245,.1);
  text-shadow:0 4px 18px rgba(0,0,0,.8);
  opacity:0;will-change:opacity,transform}
.list4 .item.warn{border-color:#c25a3e;box-shadow:0 12px 36px rgba(194,90,62,.3),inset 0 1px 0 rgba(255,252,245,.1)}
.list4 .item .x{color:#c25a3e;font-weight:900;text-shadow:0 0 24px rgba(194,90,62,.7)}

/* ============================================================
 * Scramble 解码（v1 新增 · ep03 抽出 · 由 JS 驱动文字）
 * 用于 F2 专名 / 用 .gate 三层 text-shadow
 * ============================================================ */
.scramble{font-family:ui-monospace,"SF Mono",Menlo,monospace;font-weight:900;color:#E5A93C;letter-spacing:14px;
  text-shadow:0 0 70px rgba(229,169,60,.78),0 0 150px rgba(229,169,60,.4),0 18px 56px rgba(0,0,0,.82)}

/* ============================================================
 * Odometer 数据对比卡（v1.2 新增 · ep03 抽出）
 *
 * 用于 F4/F9 数据触发：「A 国赞成 vs B 国反对」「X% 通过 / Y% 拒绝」等大数对比。
 *
 * ⭐ 视觉层级范式（ep03 v3.2 用户拍板，沉淀为 odometer 默认规则）：
 *   主数据（200/140px 暖金）→ 单位（30px 弱化贴数字尾）→ 分类（36px 主标签独立行）
 *
 *   错误反例：「国 赞成」「国 反对」单位词和分类词挤一行 → 读不出层级
 *   正确范式：<span class="odo-big">166<em class="odo-unit">国</em></span>
 *            <span class="odo-label">赞成</span>
 *
 * HTML 骨架：
 *   <div class="odo-panel">
 *     <div class="odo-head">联合国大会表决 · 致命性自主武器系统</div>
 *     <div class="odo-row">
 *       <div class="odo-num-grp">
 *         <span class="odo-big">166<em class="odo-unit">国</em></span>
 *         <span class="odo-label">赞成</span>
 *       </div>
 *       <span class="odo-vs">VS</span>
 *       <div class="odo-num-grp">
 *         <span class="odo-small">3<em class="odo-unit warn">国</em></span>
 *         <span class="odo-label warn">反对</span>
 *       </div>
 *     </div>
 *     <div class="odo-bar"><i class="b1" style="flex:0 0 98.2%"></i><i class="b2" style="flex:0 0 1.8%"></i></div>
 *     <div class="odo-kick"><span class="zh">压倒性通过 · 仍非禁令</span><span>UN GA · DEC 2024</span></div>
 *   </div>
 * ============================================================ */
.odo-panel{position:absolute;z-index:45;border-radius:24px;
  background:linear-gradient(165deg,rgba(247,224,174,.12) 0%,rgba(18,22,34,.78) 38%,rgba(14,17,26,.80) 62%,rgba(229,169,60,.10) 100%);
  box-shadow:inset 0 1px 0 rgba(255,252,245,.22), 0 18px 44px rgba(0,0,0,.5);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:24px;padding:36px}
.odo-panel::after{content:"";position:absolute;inset:0;border-radius:24px;padding:3px;
  background:linear-gradient(165deg,#f7e0ae 0%,#9c7a38 28%,#e5a93c 50%,#5d4519 72%,#d9b66e 100%);
  -webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;pointer-events:none}
.odo-panel.inflow{position:relative;left:auto;right:auto;top:auto;bottom:auto;inset:auto}

.odo-head{font-family:"Source Han Serif SC",serif;font-size:36px;color:rgba(255,231,174,.85);letter-spacing:8px;font-weight:700;position:relative;z-index:1;text-shadow:0 4px 18px rgba(0,0,0,.7)}

.odo-row{display:flex;align-items:baseline;gap:48px;font-variant-numeric:tabular-nums;position:relative;z-index:1}
.odo-num-grp{display:flex;flex-direction:column;align-items:center;gap:8px}

.odo-big{font-size:200px;font-weight:900;color:var(--c-gold);letter-spacing:4px;line-height:.9;
  text-shadow:0 0 70px rgba(229,169,60,.7),0 0 150px rgba(229,169,60,.4),0 18px 56px rgba(0,0,0,.82)}
.odo-small{font-size:140px;font-weight:900;color:#fff;letter-spacing:2px;line-height:.9;
  text-shadow:0 0 50px rgba(255,255,255,.3),0 18px 56px rgba(0,0,0,.82)}

/* ⭐ 单位：小字暖金贴数字尾基线对齐，比分类标签小一档、色弱 */
.odo-big .odo-unit,.odo-small .odo-unit{font-family:"Source Han Serif SC",serif;font-style:normal;
  font-size:30px;font-weight:700;letter-spacing:0;margin-left:14px;vertical-align:baseline;
  color:rgba(229,169,60,.7);text-shadow:none}
.odo-small .odo-unit{color:rgba(255,255,255,.55)}
.odo-unit.warn{color:rgba(194,90,62,.75) !important}

/* 分类主标签（独立行，比数字小、比单位大、字号档位明确）*/
.odo-label{font-family:"Source Han Serif SC",serif;font-size:36px;color:#fff;letter-spacing:6px;font-weight:700}
.odo-label.warn{color:var(--c-warn)}

.odo-vs{font-size:60px;color:rgba(255,255,255,.4);letter-spacing:8px;font-weight:700}

.odo-bar{width:82%;height:18px;background:rgba(15,18,24,.7);border-radius:10px;overflow:hidden;display:flex;border:1px solid rgba(229,169,60,.3);position:relative;z-index:1}
.odo-bar .b1{background:linear-gradient(90deg,var(--c-gold),#d9b66e);box-shadow:0 0 30px rgba(229,169,60,.6)}
.odo-bar .b2{background:var(--c-warn);box-shadow:0 0 20px rgba(194,90,62,.7)}

.odo-kick{font-size:24px;color:rgba(229,169,60,.7);letter-spacing:6px;font-weight:700;font-family:ui-monospace,monospace;position:relative;z-index:1;display:flex;flex-direction:column;gap:6px;align-items:center}
.odo-kick .zh{font-family:"Source Han Serif SC",serif;font-size:28px;letter-spacing:8px;color:rgba(229,169,60,.85)}

/* ============================================================
 * Mapcard 地图叙事卡（v1.3 新增 · ep03 抽出）
 *
 * 用于 F2 地名+实物触发：「乌克兰东部巴赫穆特」「土耳其 Kargu-2」「2020 利比亚」等
 * 国家定位+城市坐标叙事。配方 = 真国家轮廓 SVG + zoom 推进 + 箭头 draw-on + 坐标标签。
 *
 * 时序范式（7s 循环 · 抽真实首播节奏）：
 *   0-1.5s   全图稳（识别国家形状）
 *   1.5-3s   zoom 1.55× 围绕目标城市坐标
 *   3-4s     箭头 stroke draw-on（首都 → 目标城市）
 *   4-5s     红点+脉冲环+城市名+经纬度坐标 逐项出
 *   5-7s     停 → 退回全图
 *
 * 国别 path 数据不进 skin（country-specific）：放各项目 assets/maps/<country>.svg
 * 推荐来源：Wikimedia Commons File:Blank_map_of_<Country>.svg 系列（PD by Germanicus 等）
 *
 * 地理坐标→SVG 像素映射（线性近似，在小区域内误差可忽略）：
 *   x_svg = svg_bbox_x_min + (lon - lon_min)/(lon_max - lon_min) * svg_bbox_width
 *   y_svg = svg_bbox_y_min + (lat_max - lat)/(lat_max - lat_min) * svg_bbox_height
 *
 * HTML 骨架：
 *   <div class="mapcard" style="left:280px;top:120px;right:280px;height:840px">
 *     <div class="mapwrap">
 *       <svg viewBox="0 0 2000 1500" preserveAspectRatio="xMidYMid meet">
 *         <defs>
 *           <linearGradient id="ukFlag" ...> 国旗渐变 / 自定义 ID </linearGradient>
 *         </defs>
 *         <g class="map-layer" style="transform-box:fill-box;transform-origin:<tgtX>px <tgtY>px">
 *           <path class="country-fill" style="fill:url(#ukFlag)" d="<country SVG path>"/>
 *           <circle cx="<capX>" cy="<capY>" r="14" fill="rgba(229,169,60,.65)" />
 *           <text class="capital-label" x="..." y="..." text-anchor="end">首都名</text>
 *           <path class="arrow-path" d="M <capX> <capY> Q <ctrlX> <ctrlY> <tgtX> <tgtY>"/>
 *           <polygon class="arrow-head" points="..." />
 *           <circle class="target-ring" cx="<tgtX>" cy="<tgtY>" r="28"/>
 *           <circle class="target-dot" cx="<tgtX>" cy="<tgtY>" r="14"/>
 *           <text class="city-label" x="<tgtX>" y="<tgtY-64>" text-anchor="middle">城市名</text>
 *           <text class="city-en" x="<tgtX>" y="<tgtY+76>" text-anchor="middle">CITY_EN</text>
 *           <text class="coord-label" x="<tgtX>" y="<tgtY+116>" text-anchor="middle">XX.XX°N · YY.YY°E</text>
 *         </g>
 *       </svg>
 *     </div>
 *     <div class="map-lab">国家 · 区域</div>
 *     <div class="map-kicker">COUNTRY · CITY · YEAR</div>
 *   </div>
 *
 * GSAP timeline 集成（成片用，替换 CSS 自循环）：
 *   把 keyframes 拆成节点，按字级时间窗对应 cd-quote 字级时间触发：
 *     - "乌克兰"出字 → 全图稳
 *     - "东部"出字 → zoom 推进
 *     - "巴赫穆特"出字 → 箭头 draw-on + 标签出
 * ============================================================ */
.mapcard{position:absolute;z-index:46;border-radius:24px;overflow:hidden;
  background:linear-gradient(165deg,rgba(247,224,174,.14) 0%,rgba(18,22,34,.80) 38%,rgba(14,17,26,.82) 62%,rgba(229,169,60,.12) 100%);
  box-shadow:inset 0 1px 0 rgba(255,252,245,.22), 0 18px 44px rgba(0,0,0,.5);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:24px;padding:48px}
.mapcard::after{content:"";position:absolute;inset:0;border-radius:24px;padding:3px;
  background:linear-gradient(165deg,#f7e0ae 0%,#9c7a38 28%,#e5a93c 50%,#5d4519 72%,#d9b66e 100%);
  -webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;pointer-events:none}
.mapcard .mapwrap{position:relative;width:1000px;height:750px;overflow:hidden;border-radius:12px;
  background:radial-gradient(ellipse at center,rgba(15,20,30,.4),rgba(8,10,16,.7))}
.mapcard .mapwrap svg{display:block;width:100%;height:100%;filter:drop-shadow(0 8px 24px rgba(0,0,0,.6))}

/* ============================================================
 * 横屏修饰类 · 2026-06-13 ep03 drone-full P0-10/11 沉淀
 * 用法：在卡容器上加 class="landscape"（不动默认值，保留竖屏兼容）
 * 历史来源：drone-full/cards_inject.py mapcard/list4 抽出
 * 单一权威源铁律：横屏适配一律走修饰类，不改默认；新片直接 <div class="list4 landscape"> / <div class="mapwrap landscape">
 * ============================================================ */
.mapcard.landscape .mapwrap,.mapcard .mapwrap.landscape{width:1400px;height:780px}
.list4.landscape{flex-direction:row;gap:32px;flex-wrap:wrap;justify-content:center}
.list4.landscape .item{flex:1 1 calc(50% - 16px);min-width:300px;max-width:580px}

/* 国家轮廓填充（用国旗渐变 ID 覆盖 fill 即可：style="fill:url(#xxFlag)"）*/
.mapcard .country-fill,.mapcard .ukraine-fill{stroke:#E5A93C;stroke-width:4;stroke-linejoin:round}

/* zoom 推进层（包裹所有 svg 内容，按 transform-origin 围绕目标城市缩放）*/
/* v1.4 (2026-06-14): 7s infinite → 5s 1 forwards · arrow 在 50%(2.5s)前画完保持到尾，避免 t_dur=7s 卡 fadeOut 时箭头消失 */
.mapcard .map-layer{animation:mapZoom 5s ease-in-out 1 forwards}
@keyframes mapZoom{0%{transform:scale(1)}60%{transform:scale(1.4)}100%{transform:scale(1.4)}}

/* 箭头 draw-on（首都 → 目标，stroke-dashoffset 描线效果）*/
.mapcard .arrow-path{fill:none;stroke:#c25a3e;stroke-width:9;stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:1400;stroke-dashoffset:1400;
  filter:drop-shadow(0 0 8px rgba(194,90,62,.7));animation:arrowDraw 5s ease-in-out 1 forwards}
.mapcard .arrow-head{fill:#c25a3e;opacity:0;animation:arrowHead 5s ease-in-out 1 forwards;filter:drop-shadow(0 0 12px rgba(194,90,62,.9))}
@keyframes arrowDraw{0%,12%{stroke-dashoffset:1400}50%,100%{stroke-dashoffset:0}}
@keyframes arrowHead{0%,35%{opacity:0}55%,100%{opacity:1}}

/* 目标城市标记（脉冲点+扩散环）+ 标签 */
.mapcard .target-dot{fill:#c25a3e;opacity:0;animation:targetPulse 5s ease-in-out 1 forwards}
.mapcard .target-ring{fill:none;stroke:#c25a3e;stroke-width:3;opacity:0;animation:targetRing 5s ease-in-out 1 forwards}
@keyframes targetPulse{0%,50%{opacity:0;r:14}60%{opacity:1;r:34}70%{opacity:.95;r:24}80%,100%{opacity:.9;r:28}}
@keyframes targetRing{0%,55%{opacity:0;r:28}65%{opacity:.9;r:60}75%{opacity:.3;r:96}100%{opacity:0;r:96}}

.mapcard .city-label{font-family:"Source Han Serif SC",serif;font-weight:900;font-size:64px;fill:#c25a3e;letter-spacing:10px;opacity:0;animation:cityLab 5s ease-in-out 1 forwards}
.mapcard .city-en{font-family:ui-monospace,monospace;font-weight:700;font-size:36px;fill:#c25a3e;letter-spacing:6px;opacity:0;animation:cityLab 5s ease-in-out 1 forwards}
.mapcard .coord-label{font-family:ui-monospace,monospace;font-weight:700;font-size:28px;fill:rgba(229,169,60,.7);letter-spacing:4px;opacity:0;animation:cityLab 5s ease-in-out 1 forwards}
.mapcard .capital-label{font-family:ui-monospace,monospace;font-weight:700;font-size:30px;fill:rgba(229,169,60,.75);letter-spacing:4px}
@keyframes cityLab{0%,60%{opacity:0}75%,100%{opacity:1}}

/* 卡底标签（mapcard 容器外，主标题+kicker）*/
.mapcard .map-lab{font-family:"Source Han Serif SC",serif;font-weight:900;color:#E5A93C;letter-spacing:10px;font-size:54px;
  text-shadow:0 0 40px rgba(229,169,60,.6),0 12px 36px rgba(0,0,0,.7);position:relative;z-index:1}
.mapcard .map-kicker{font-family:ui-monospace,monospace;font-weight:700;color:rgba(229,169,60,.7);letter-spacing:6px;font-size:24px;position:relative;z-index:1}

/* ============================================================
 * 调色相关 · 颜色变量（CSS custom property，可被项目覆盖）
 * ============================================================ */
:root{
  --c-bg:#050608;
  --c-gold:#E5A93C;
  --c-gold-soft:#FFD874;
  --c-gold-deep:#9c7a38;
  --c-warn:#c25a3e;
  --c-paper:#f3ead4;
}

/* ============================================================
 * subjectMini 横屏右下角小窗（2026-06-14 ep03 方案 D 用户钦点）
 * 横屏 1920×1080「切换式」人物层：人物全屏 fade-out → 主舞台素材独立 N 秒 → 右下角 fade-in 小窗
 * 与铁律 14 竖屏「连续缩到右下角」溶解 PIP 互补，不冲突（项目按画幅二选一）
 *
 * 用法（子 comp HTML）：
 *   div.subjectMini 包 video 元素，src=../exports/aroll_12x_subject.webm + muted + playsinline
 *   （注：原本注释里写的真实 video 标签字面串会被 HF 静态 parser 误识别成真 video 元素 → 加载 660MB 撑爆 chrome capture，2026-06-15 实证血泪）
 *
 * GSAP 时序（铁律 18 inline style，不走 className）：
 *   入场：tl.fromTo(".subjectMini", {opacity:0,y:28,scale:.96},
 *                                   {opacity:1,y:0,scale:1, duration:0.32, ease:"power2.out"}, t_in)
 *   出场：tl.to(".subjectMini", {opacity:0,y:28,scale:.96, duration:0.24, ease:"power1.in"}, t_out)
 *
 * 全屏 subjVid（z=20）方案 D 退场/回场：
 *   消失：tl.to("#subjVid", {opacity:0, duration:0.2, ease:"power1.in"}, t_disappear)
 *   回归全屏：tl.to("#subjVid", {opacity:1, duration:0.4, ease:"power2.out"}, t_return)
 *
 * 位置：右 100px 下 100px（抖音横屏 UI 安全区外）；尺寸 320×426（3:4 = 人物舒适比例）
 * ============================================================ */
.subjectMini{position:absolute;right:100px;bottom:100px;width:320px;height:426px;
  border-radius:20px;overflow:hidden;
  border:1.5px solid rgba(229,169,60,.55);
  box-shadow:0 28px 70px rgba(0,0,0,.7),0 0 0 1px rgba(229,169,60,.15);
  background:linear-gradient(165deg,rgba(16,12,7,.5) 0%,rgba(8,6,4,.55) 100%);
  opacity:0;transform:translateY(28px) scale(.96);
  z-index:36;pointer-events:none;will-change:opacity,transform}
.subjectMini > video,.subjectMini > .subjvid-mini{width:100%;height:100%;object-fit:cover;display:block}
.subjectMini::after{content:"";position:absolute;inset:0;border-radius:20px;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(255,217,143,.18)}

/* ============================================================
 * Result 库扩展 v2（2026-06-14 架构重组 · 11→28 补全 17 种组件）
 * 来源：视效自动化蓝图 §8-10 固化 28 件 + SHOT-PLAN ep03 规划
 * 原则：CSS 布局/样式基础在这里；JS 驱动的（counter/scramble/particle/nodenet）
 *        由 gen_full.py 或子 comp inline-JS 实现，CSS 只提供容器和视觉基础
 * ============================================================ */

/* === #12 text-behind 横贯大字（§B 核心招牌 · 藏字法） ===
 * z 分层：baseVid z1 → .tbh z15 → subjVid z20（字夹在背景和人之间）
 * 横屏：y 170-470 / 300px 级横跨全宽
 * 竖屏：top 280-460
 * 藏字法：GSAP translateX 平移让被遮字落在人头投影 x 区间 */
.tbh{position:absolute;z-index:15;left:0;right:0;
  font-family:'Source Han Serif SC','Noto Serif CJK SC',serif;font-weight:900;
  color:rgba(244,247,248,.92);letter-spacing:.08em;line-height:1.1;
  text-shadow:0 4px 24px rgba(0,0,0,.7),0 0 80px rgba(229,169,60,.15);
  pointer-events:none;white-space:nowrap;will-change:transform,opacity}
.tbh.landscape{top:170px;font-size:clamp(120px,16vw,280px)}
.tbh.portrait{top:320px;font-size:clamp(100px,22vw,240px)}

/* === #14 HUD 锁定框（无人机视角扫描+锁定） ===
 * 叠在 i2v 视频层上方（z30）；CSS 四角 L bracket + 扫描线
 * 锁定态：border 变红/金 + brightness 闪 */
.hud{position:absolute;z-index:30;pointer-events:none}
.hud-frame{position:absolute;border:2px solid rgba(111,215,233,.6);
  box-shadow:0 0 12px rgba(111,215,233,.2),inset 0 0 0 1px rgba(111,215,233,.1)}
.hud-frame.locked{border-color:var(--c-warn);box-shadow:0 0 20px rgba(192,90,62,.4)}
.hud-bracket{position:absolute;width:18px;height:18px;
  border:2.5px solid rgba(111,215,233,.8)}
.hud-bracket.tl{top:-1px;left:-1px;border-right:none;border-bottom:none}
.hud-bracket.tr{top:-1px;right:-1px;border-left:none;border-bottom:none}
.hud-bracket.bl{bottom:-1px;left:-1px;border-right:none;border-top:none}
.hud-bracket.br{bottom:-1px;right:-1px;border-left:none;border-top:none}
.hud-scanline{position:absolute;left:0;right:0;height:2px;
  background:linear-gradient(90deg,transparent,rgba(111,215,233,.5),transparent);
  animation:hudScan 3s 1 forwards}
@keyframes hudScan{0%{top:0;opacity:.8}80%{top:100%;opacity:.6}100%{top:100%;opacity:0}}
.hud-label{position:absolute;font-family:'Noto Sans CJK SC',sans-serif;font-size:13px;
  color:rgba(111,215,233,.8);letter-spacing:.05em;padding:2px 8px;
  background:rgba(0,0,0,.4);border:1px solid rgba(111,215,233,.2)}

/* === #15 line draw 自绘线（SVG dasharray 动画） ===
 * 2024→2026 时间线自绘；用 SVG path + stroke-dasharray/dashoffset */
.linedraw{position:absolute;z-index:32;pointer-events:none}
.linedraw path{fill:none;stroke:var(--c-gold);stroke-width:2.5;
  stroke-dasharray:var(--line-len,1000);stroke-dashoffset:var(--line-len,1000);
  animation:lineReveal 2s ease-out 1 forwards}
@keyframes lineReveal{to{stroke-dashoffset:0}}
.linedraw .ld-node{fill:var(--c-gold);r:6;opacity:0;animation:nodeAppear .4s ease-out forwards}
@keyframes nodeAppear{to{opacity:1;r:8}}
.linedraw .ld-label{font-family:'Noto Sans CJK SC',sans-serif;font-size:22px;font-weight:700;
  fill:var(--c-gold);opacity:0;animation:nodeAppear .4s ease-out forwards}

/* === #16 pictograph 清点标记（航拍叠加落标） ===
 * 图标落标 + 计数小卡 */
.picto{position:absolute;z-index:33;pointer-events:none}
.picto-mark{position:absolute;width:48px;height:48px;
  border:2px solid var(--c-warn);border-radius:50%;
  box-shadow:0 0 12px rgba(192,90,62,.4);opacity:0;
  transform:scale(1.5);will-change:transform,opacity}
.picto-count{position:absolute;font-family:'Noto Sans CJK SC',sans-serif;
  font-size:28px;font-weight:900;color:#fff;
  background:rgba(0,0,0,.6);padding:4px 16px;border-radius:4px;
  border:1px solid rgba(229,169,60,.3);
  text-shadow:0 2px 8px rgba(0,0,0,.5)}

/* === #17 erase 擦除重写（「禁止」→「成立论坛」） ===
 * 旧文字 strikethrough + fadeOut → 新文字 fadeIn */
.erase{position:absolute;z-index:34;pointer-events:none;
  font-family:'Source Han Serif SC',serif;font-weight:900;
  text-align:center;line-height:1.3}
.erase-old{color:rgba(244,247,248,.7);text-decoration:line-through;
  text-decoration-color:var(--c-warn);text-decoration-thickness:3px}
.erase-new{color:var(--c-gold);opacity:0;will-change:opacity}

/* === #18 count-up 滚动计数（JS onUpdate 驱动 · CSS 只做容器样式） ===
 * 「37,000」大数字 + 小字标签 */
.countup{position:absolute;z-index:35;pointer-events:none;text-align:center}
.countup-num{font-family:'Noto Sans CJK SC',sans-serif;font-weight:900;
  font-size:clamp(64px,8vw,120px);color:#fff;letter-spacing:.02em;
  text-shadow:0 4px 20px rgba(0,0,0,.6),0 0 40px rgba(229,169,60,.2)}
.countup-label{font-family:'Noto Sans CJK SC',sans-serif;font-size:24px;
  color:rgba(244,247,248,.6);margin-top:8px}

/* === #19 tv_static 雪花闪断（全屏叠加 0.5s 闪插） ===
 * 叠 tv_static.mp4 全屏 z40 闪 0.5s × 2 */
.tvstatic{position:absolute;inset:0;z-index:40;pointer-events:none;
  opacity:0;will-change:opacity}
.tvstatic > video{width:100%;height:100%;object-fit:cover}

/* === #20 typewriter 打字机（制造商原话逐字打出） ===
 * 逐字 span opacity:0→1 stagger */
.typewriter{position:absolute;z-index:34;pointer-events:none;
  font-family:'Source Han Serif SC',serif;font-weight:700;
  color:rgba(244,247,248,.85);line-height:1.6;letter-spacing:.03em;
  text-shadow:0 2px 12px rgba(0,0,0,.5)}
.typewriter .tw-char{opacity:0;will-change:opacity}
.typewriter .tw-cursor{display:inline-block;width:2px;height:1em;
  background:var(--c-gold);margin-left:2px;animation:twBlink .8s step-end infinite}
@keyframes twBlink{50%{opacity:0}}

/* === #21 odo-flip 真翻轮（数字逐位翻牌 · 区别于 odo-panel 平滑滚） ===
 * 每位数字上下翻转 · CSS perspective + rotateX */
.odo-flip{position:absolute;z-index:35;display:flex;gap:4px;pointer-events:none}
.odo-flip-digit{position:relative;width:clamp(40px,5vw,72px);height:clamp(56px,7vw,100px);
  perspective:200px;overflow:hidden}
.odo-flip-digit .face{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-family:'Noto Sans CJK SC',sans-serif;font-weight:900;
  font-size:clamp(36px,4.5vw,64px);color:#fff;
  background:linear-gradient(180deg,rgba(20,18,14,.9) 49%,rgba(12,10,8,.95) 51%);
  border:1px solid rgba(229,169,60,.2);border-radius:6px;
  text-shadow:0 2px 8px rgba(0,0,0,.5);
  backface-visibility:hidden;will-change:transform}

/* === #22 nodenet 节点网络（Canvas/JS 驱动 · CSS 只做容器） ===
 * 认知节点点亮 + 脉冲传导 + 汇聚灯塔
 * 实现：Canvas 2D + mulberry32 PRNG + GSAP onUpdate（见质感规格-5 §三） */
.nodenet{position:absolute;inset:0;z-index:8;pointer-events:none}
.nodenet > canvas{width:100%;height:100%}

/* === #23 particle 粒子收束/爆散（Canvas/JS 驱动） ===
 * 汇聚=顿悟 / 爆散=震撼 / 流动=思维（三情绪原语 · 见质感规格-5 §三）
 * CSS 只给容器 + lighter blend 提示 */
.particle{position:absolute;inset:0;z-index:10;pointer-events:none;
  mix-blend-mode:screen}
.particle > canvas{width:100%;height:100%}

/* === #24 fragment 碎片浮动（记忆碎片飘散） ===
 * 多个小图片/文字片段 absolute 布局 + GSAP float 动效 */
.fragment{position:absolute;z-index:12;pointer-events:none}
.fragment-piece{position:absolute;opacity:0;
  filter:blur(1px);will-change:transform,opacity;
  box-shadow:0 4px 16px rgba(0,0,0,.4);border:1px solid rgba(229,169,60,.1)}

/* === #25 Ken Burns 静图活化（任何静图叠层默认挂） ===
 * 基础：scale 100%→115-120% + 轻微 position 平移 + ease
 * 时长 3-5s 覆盖全程 · 绝不放纯静帧 */
.kenburns{position:absolute;overflow:hidden}
.kenburns > img,.kenburns > video{width:100%;height:100%;object-fit:cover;
  will-change:transform}

/* === #28 linkbreak 连线断裂示意（无人机—操作员连线闪断） ===
 * SVG 线 + dasharray 闪烁 + 断裂点粒子 */
.linkbreak{position:absolute;z-index:32;pointer-events:none}
.linkbreak path{fill:none;stroke:rgba(111,215,233,.5);stroke-width:2;
  stroke-dasharray:8 4}
.linkbreak .lb-break{fill:var(--c-warn);opacity:0;r:4}
.linkbreak .lb-spark{fill:var(--c-gold-soft);opacity:0;r:2}

/* === end v2 expansion === */
