/* ============================================================
   a2e.com.cn 落地页 —— 组件层

   来源：Claude Design 项目「A2E Landing页面重构」的定稿设计稿
   A2E Nav.dc.html（950 行）+ design_handoff_a2e_landing/README.md。
   设计稿是原型，用一套模板运行时写成，本文件是它在 WordPress +
   Gutenberg 环境里的重建，不是搬运。

   落地契约（design/CONSTRAINTS.md 第 8 节）：
   - 命名 .a2e-块__元素--变体，元素只允许一级 __
   - 状态用原生属性（aria-expanded / aria-current / :focus-visible），
     不发明 .is-*
   - 0 个 !important
   - 0 处内联 style 声明；页面里只注入自定义属性（--a2e-ratio / --a2e-media
     / --a2e-rv-i 三个口子），传数据不传声明
   - 0 个裸色值，颜色一律来自 tokens.css

   ------------------------------------------------------------
   两处必须记住的实测结论（退回去就会复现原来的 bug）

   1. 图块 hover 缩放的是 ::before 内容层，不是容器。父级带 mask-image
      时，容器一 transform 就被提升为独立合成层，border-radius 和
      clip-path 的裁剪同时失效，圆角在 hover 瞬间变直角。

   2. 带圆角子块的网格入场只做 fade，不做位移。理由同上：translateY
      也是 transform。瀑布流三列、横屏网格、竖屏网格都因此只淡入。

   ------------------------------------------------------------
   字号补偿：.a2e-display / .a2e-num 两个工具类**带 font-size**
   （1.03em / .96em），且位于 a2e-utilities 层、排在本层之后。组件
   自己规定了字号时复合这两个类，字号会被它们覆盖。所以本文件一律
   直接写 font-family + calc(... * 1.03 / .96)，不复合这两个类。
   ============================================================ */


/* 环形辉光要靠角度做动画，角度必须先注册成 <angle> 类型，
   否则 conic-gradient 的 from 值只能整数跳变。注册是文档级的，
   分层对它没有意义，所以放在层外。 */
@property --a2e-ang {
  syntax: "<angle>";
  inherits: true;
  initial-value: 0deg;
}


@layer a2e-components {

  /* ==========================================================
     0 · 页面根：局部 token 与动效降级开关
     ========================================================== */

  /* token 里没有的版式值补在这里。命名前缀 --a2e- 与设计系统的
     token 区分开：这些是落地页局部量，不进 tokens.css 的注册表。 */
  .a2e-lp {
    /* 动效四开关。reduce 时整体改写，不逐条覆盖 —— 逐条覆盖要么
       用 !important（禁），要么写在别的层里（会反转层序）。 */
    --a2e-motion:   running;
    --a2e-lift:     1.06;
    --a2e-dur:      .28s;
    --a2e-logo-dur: .72s;

    /* 版式 */
    --a2e-gutter:   var(--s-6);   /* 页面左右留白 32px */
    --a2e-nav-h:    72px;
    --a2e-gap:      14px;         /* 横滚卡与六宫格的栏距 */
    --a2e-gap-tile: var(--s-2);   /* 作品图块的栏距 8px */
    --a2e-card-w:   300px;        /* 横滚卡宽，断点里改 */

    /* 缓动。设计稿里出现 27 次，抽出来免得写歪一处。 */
    --a2e-ease:     cubic-bezier(.2, .7, .3, 1);
    --a2e-ease-ind: cubic-bezier(.4, 0, .2, 1);
    --a2e-ease-flip: cubic-bezier(.65, 0, .35, 1);

    position: relative;
    min-height: 100vh;
    /* !! 必须是 clip 不是 hidden。overflow-x:hidden 会把这里变成滚动容器，
       里面所有 position:sticky 都改为相对它吸附 —— 实测 /news/ 的控制条和
       月份头直接失效（滚到 top:-40 还在跑）。clip 只裁不滚，sticky 照常。
       另外 hidden 会把 overflow-y 从 visible 提成 auto，clip 不会。 */
    overflow-x: clip;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-sans);
    -webkit-font-smoothing: antialiased;
  }

  /* 落地页第一个区块是 .a2e-sec--first，自带 96px 给 fixed 导航让位。
     别的页面第一个元素可能是公告条这类通栏元素，用这个修饰类让位。 */
  .a2e-lp--offset { padding-top: var(--a2e-nav-h); }

  .a2e-lp *,
  .a2e-lp *::before,
  .a2e-lp *::after { box-sizing: border-box; }

  /* !! 必须用 :where() 把作用域降权到 0。写成 .a2e-lp a 的话特异性是
     (0,1,1)，会压过所有 (0,1,0) 的按钮类 —— 实测后果是 .a2e-btn--solid-text
     的文字被改回 --text，白底上 #EBEBEB 对 #EBEBEB，对比度 1.0，整个
     按钮消失；mint / amber 底的 CTA 与整个 mint 页脚也一起掉到不可读。
     这就是「变体换底色必须同时换 --*-on」那条约束的反面：底色对了，
     文字色被一条通则悄悄抢走。 */
  :where(.a2e-lp) a { color: var(--text); text-decoration: none; }
  :where(.a2e-lp) a:hover { color: var(--accent); }

  .a2e-lp :focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
  }

  @media (prefers-reduced-motion: reduce) {
    .a2e-lp {
      --a2e-motion:   paused;
      --a2e-lift:     1;
      --a2e-dur:      .01s;
      --a2e-logo-dur: .01s;
    }
  }


  /* ==========================================================
     1 · keyframes
     设计稿的 @keyframes a2eReel 没有任何调用点，未移植。
     ========================================================== */

  @keyframes a2eRing { to { --a2e-ang: 360deg; } }

  @keyframes a2eLogoGlow {
    0%, 100% { filter: drop-shadow(0 0 12px color-mix(in srgb, transparent, var(--accent) 22%)); }
    50%      { filter: drop-shadow(0 0 22px color-mix(in srgb, transparent, var(--accent) 52%)); }
  }

  @keyframes a2eRec {
    0%, 100% { opacity: 1;   box-shadow: 0 0 8px color-mix(in srgb, transparent, var(--danger) 70%); }
    50%      { opacity: .38; box-shadow: 0 0 0  color-mix(in srgb, transparent, var(--danger) 0%); }
  }

  @keyframes a2eBreathe {
    0%, 100% { opacity: .62; }
    50%      { opacity: 1; }
  }

  @keyframes a2eGridDrift { to { background-position: 88px 88px, 88px 88px; } }

  @keyframes a2eDrop {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
  }

  @keyframes a2eDotFill {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
  }


  /* ==========================================================
     2 · 进入视口错峰入场
     初始隐藏写在 CSS 里而不是由 JS 注入行内样式：一来契约禁止行内
     声明，二来 JS 是 defer 的，等它跑起来元素已经画过一次了，会闪。
     ========================================================== */

  .a2e-lp [data-reveal] {
    opacity: 0;
    transition:
      opacity   .52s var(--a2e-ease),
      transform .52s var(--a2e-ease);
    /* 同组兄弟递增 70ms，最多 7 档；序号由 JS 注入自定义属性。 */
    transition-delay: calc(var(--a2e-rv-i, 0) * 70ms);
  }

  .a2e-lp [data-reveal="rise"] { transform: translateY(14px); }

  .a2e-lp [data-reveal][data-reveal-shown] {
    opacity: 1;
    transform: none;
  }

  /* 两条兜底：关掉动效的人、以及 JS 没跑起来的场合，都必须直接可见。 */
  @media (prefers-reduced-motion: reduce) {
    .a2e-lp [data-reveal] { opacity: 1; transform: none; transition: none; }
  }
  @media (scripting: none) {
    .a2e-lp [data-reveal] { opacity: 1; transform: none; transition: none; }
  }


  /* ==========================================================
     3 · 按钮三档（设计稿共 27 处）

     实心 CTA  亮度 .18s + 同色 30% 柔光 .28s + 上浮 1px
     描边/幽灵  描边转 --glass-border、底升 --surface-2、字与图标转 accent
     文字/标签  只转文字色（chips 同时底升一级）

     柔光颜色跟随按钮本色：mint 30% / amber 30% / 白 24%。
     居中定位的按钮上浮必须保留 translateX(-50%)，否则会跳回左边。
     ========================================================== */

  .a2e-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
    white-space: nowrap;
    font-family: inherit;
    line-height: 1;
    cursor: pointer;
    border: 0;
    border-radius: var(--r-sm);
  }

  /* --- 实心 --- */
  .a2e-btn--solid {
    padding: 12px 22px;
    background: var(--accent);
    color: var(--accent-on);
    font-size: var(--fs-sm);
    letter-spacing: .02em;
    transition:
      filter     .18s ease,
      box-shadow .28s ease,
      transform  .28s var(--a2e-ease);
  }
  .a2e-btn--solid:hover {
    color: var(--accent-on);
    filter: brightness(1.06);
    box-shadow: 0 0 30px color-mix(in srgb, transparent, var(--accent) 30%);
    transform: translateY(-1px);
  }

  /* amber 变体：换底色必须同时换 --*-on 文字色。 */
  .a2e-btn--solid-warn {
    background: var(--warn);
    color: var(--warn-on);
  }
  .a2e-btn--solid-warn:hover {
    color: var(--warn-on);
    box-shadow: 0 0 30px color-mix(in srgb, transparent, var(--c-amber) 30%);
  }

  /* 白底：亮度往下压而不是往上提，否则纯白提不动。 */
  .a2e-btn--solid-text {
    padding: 13px 26px;
    background: var(--c-text);
    color: var(--c-ink);
    font-size: 15px;
    letter-spacing: .01em;
  }
  .a2e-btn--solid-text:hover {
    color: var(--c-ink);
    filter: brightness(.96);
    box-shadow: 0 0 30px color-mix(in srgb, transparent, var(--c-text) 24%);
  }

  /* --- 描边 / 幽灵 --- */
  .a2e-btn--ghost {
    padding: var(--s-2) var(--s-3);
    border: 1px solid var(--line);
    background: transparent;
    color: var(--text);
    font-size: var(--fs-sm);
    transition:
      border-color .18s ease,
      background   .18s ease,
      color        .18s ease;
  }
  .a2e-btn--ghost:hover {
    border-color: var(--glass-border);
    background: var(--surface-2);
    color: var(--accent);
  }

  /* 图标按钮：正方形，点击目标不小于 38px，移动端 42px。 */
  .a2e-btn--icon {
    justify-content: center;
    width: 38px;
    height: 38px;
    flex: none;
    padding: 0;
  }

  /* info 变体，Seedance 2.5 那块在用。warn 版保留给真正的警告语义。 */
  .a2e-btn--solid-info {
    background: var(--info);
    color: var(--info-on);
  }
  .a2e-btn--solid-info:hover {
    color: var(--info-on);
    box-shadow: 0 0 30px color-mix(in srgb, transparent, var(--c-peri) 30%);
  }

  .a2e-btn--edge-info {
    padding: 11px 20px;
    border: 1px solid color-mix(in srgb, transparent, var(--c-peri) 55%);
    background: color-mix(in srgb, var(--c-void), var(--c-peri) 16%);
    color: var(--c-peri);
    font-size: var(--fs-sm);
    transition:
      border-color .18s ease,
      background   .18s ease,
      transform    .28s var(--a2e-ease);
  }
  .a2e-btn--edge-info:hover {
    color: var(--c-peri);
    background: color-mix(in srgb, var(--c-void), var(--c-peri) 26%);
    border-color: color-mix(in srgb, transparent, var(--c-peri) 80%);
  }

  /* amber 描边：留给警告语义的场合。 */
  .a2e-btn--edge-warn {
    padding: 11px 20px;
    border: 1px solid color-mix(in srgb, transparent, var(--c-amber) 55%);
    background: color-mix(in srgb, var(--c-void), var(--c-amber) 16%);
    color: var(--c-amber);
    font-size: var(--fs-sm);
    transition:
      border-color .18s ease,
      background   .18s ease,
      transform    .28s var(--a2e-ease);
  }
  .a2e-btn--edge-warn:hover {
    color: var(--c-amber);
    background: color-mix(in srgb, var(--c-void), var(--c-amber) 26%);
    border-color: color-mix(in srgb, transparent, var(--c-amber) 80%);
  }

  /* --- 文字 / 标签 --- */
  .a2e-btn--label {
    padding: 9px 16px;
    background: var(--surface);
    color: var(--text-mute);
    font-size: 15px;
    transition: background .18s ease, color .18s ease;
  }
  .a2e-btn--label:hover {
    background: var(--surface-2);
    color: var(--accent);
  }

  /* --- 居中悬浮定位 --- */
  .a2e-btn--center {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
  }
  .a2e-btn--center:hover { transform: translateX(-50%) translateY(-1px); }

  .a2e-btn__icon { flex: none; }


  /* ==========================================================
     4 · 导航
     ========================================================== */

  .a2e-nav {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: var(--z-pop);
    height: var(--a2e-nav-h);
  }

  /* 玻璃底单独一层：滚过 12px 才淡入，透明度由 JS 注入 --a2e-frost。

     !! 这里**故意不复合 .a2e-glass**。那个工具类在 a2e-utilities 层、
        排在本层之后，它的 border 简写、border-radius 和 box-shadow 会
        把组件层的覆盖压掉 —— 导航条只要一条下边框，四边描边和圆角都
        不要，压不掉就得动 !important。所以直接读同一批 glass token 自己
        画，连带把工具类里那两个必需的降级也一起搬过来。 */
  .a2e-nav__glass {
    position: absolute;
    inset: 0;
    background: var(--g-bg, var(--glass-bg));
    -webkit-backdrop-filter: var(--g-filter, blur(var(--glass-blur)) saturate(var(--glass-sat)));
            backdrop-filter: var(--g-filter, blur(var(--glass-blur)) saturate(var(--glass-sat)));
    border-bottom: 1px solid var(--line);
    opacity: var(--a2e-frost, 0);
    transition: opacity .32s ease;
  }
  /* 无障碍要求的降级，同时也是老浏览器的兜底：没有这两条，
     不支持 backdrop-filter 的浏览器会得到一块透明不可读的面板。 */
  @media (prefers-reduced-transparency: reduce) {
    .a2e-nav__glass { --g-bg: var(--surface); --g-filter: none; }
  }
  @supports not (backdrop-filter: blur(1px)) {
    .a2e-nav__glass { --g-bg: var(--surface); --g-filter: none; }
  }

  .a2e-nav__inner {
    position: relative;
    height: 100%;
    padding: 0 var(--a2e-gutter);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-5);
  }

  /* --- 品牌 --- */
  .a2e-nav__brand {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: none;
    color: var(--accent);
  }
  .a2e-nav__brand:hover { color: var(--accent); }

  /* 两件事互不干扰：常驻微光走 filter，hover 翻转走 transform。
     顺时针 180° 后字母 a 变成 e —— 这是品牌梗，不要改成别的角度。 */
  .a2e-nav__logo {
    width: 48px;
    height: 48px;
    flex: none;
    display: block;
    filter: drop-shadow(0 0 16px color-mix(in srgb, transparent, var(--accent) 40%));
    animation: a2eLogoGlow 5s ease-in-out infinite;
    animation-play-state: var(--a2e-motion, running);
    transform: rotate(var(--a2e-logo-rot, 0deg));
    transition: transform var(--a2e-logo-dur, .72s) var(--a2e-ease-flip);
  }
  .a2e-nav__brand:hover .a2e-nav__logo { --a2e-logo-rot: 180deg; }

  .a2e-nav__brand-text {
    display: flex;
    flex-direction: column;
    gap: 3px;
  }
  .a2e-nav__brand-name {
    font-size: var(--fs-base);
    line-height: 1;
    letter-spacing: .01em;
    color: var(--text);
  }
  .a2e-nav__brand-tag {
    font-size: 11px;
    line-height: 1;
    letter-spacing: .14em;
    color: var(--text-mute);
  }

  /* --- 主项与指示器 --- */
  .a2e-nav__links {
    position: relative;
    display: flex;
    align-items: center;
    gap: 2px;
  }

  /* 位置由 JS 注入两个自定义属性；离开导航区滑回当前页那一项。
     预览态（hover 到非当前项）透明度 .72，用来和当前页区分。 */
  .a2e-nav__indicator {
    position: absolute;
    bottom: -6px;
    left: var(--a2e-ind-x, 0);
    width: var(--a2e-ind-w, 0);
    height: 2px;
    border-radius: 2px;
    background: var(--accent);
    box-shadow:
      0 0 10px color-mix(in srgb, transparent, var(--accent) 55%),
      0 0 22px color-mix(in srgb, transparent, var(--accent) 30%);
    opacity: var(--a2e-ind-o, 0);
    pointer-events: none;
    transition:
      left    .34s var(--a2e-ease-ind),
      width   .34s var(--a2e-ease-ind),
      opacity .2s ease;
  }

  .a2e-nav__group { position: relative; }

  .a2e-nav__item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 9px 15px;
    border-radius: var(--r-sm);
    font-size: 15px;
    line-height: 1;
    letter-spacing: .01em;
    color: var(--text);
    opacity: .84;
    transition: opacity .18s ease;
  }
  .a2e-nav__item:hover,
  .a2e-nav__item[aria-current="page"] { opacity: 1; color: var(--text); }

  .a2e-nav__caret { opacity: .6; flex: none; }

  /* --- 下拉 --- */
  .a2e-menu {
    position: absolute;
    top: calc(100% + var(--s-3));
    left: 50%;
    transform: translateX(-50%);
    min-width: 250px;
    padding: 10px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-pop);
    display: flex;
    flex-direction: column;
    gap: 2px;
    opacity: 0;
    visibility: hidden;
    transition: opacity .18s ease, visibility .18s ease;
  }
  .a2e-menu--wide { min-width: 270px; }
  .a2e-menu--narrow { min-width: 210px; }

  /* 开合用原生 :hover / :focus-within，不发明状态类，键盘也能打开。 */
  .a2e-nav__group:hover > .a2e-menu,
  .a2e-nav__group:focus-within > .a2e-menu {
    opacity: 1;
    visibility: visible;
    animation: a2eDrop .22s ease both;
    animation-play-state: var(--a2e-motion, running);
  }

  .a2e-menu__item {
    display: block;
    padding: 9px var(--s-3);
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
    color: var(--text);
  }
  .a2e-menu__item:hover { background: var(--surface-2); color: var(--text); }

  .a2e-menu__desc {
    display: block;
    margin-top: 3px;
    font-size: var(--fs-xs);
    color: var(--text-mute);
  }

  /* --- 产品 mega 菜单 ---
     结构照搬 /app 左侧菜单：5 个分组 + 底部快速链接。

     用 position: fixed 而不是 absolute —— 面板要按视口居中、宽到接近版心，
     而它的定位祖先 .a2e-nav__group 只有一个导航项那么宽。导航条本身也是
     fixed，所以两者对齐关系稳定。DOM 上它仍是 group 的子节点，
     :hover / :focus-within 照常生效。 */
  .a2e-mega {
    position: fixed;
    top: var(--a2e-nav-h);
    /* !! 居中不能用 left:50% + translateX(-50%)。开合时套的 a2eDrop
       关键帧里有 transform: translateY()，`animation-fill-mode: both`
       会让它在结束帧把整个 transform 覆盖掉，translateX(-50%) 随之作废，
       面板直接从「产品」那一项开始往右铺、冲出视口。
       改成 left/right 归零 + margin-inline:auto，居中不占用 transform。
       （同一个坑在 .a2e-btn--center 上出现过一次，那里是靠在 hover 规则里
       重述 translateX(-50%) 解决的。） */
    left: 0;
    right: 0;
    margin-inline: auto;
    width: min(1280px, calc(100vw - var(--s-6) * 2));
    max-height: calc(100vh - var(--a2e-nav-h) - var(--s-5));
    overflow-y: auto;
    padding: var(--s-5);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-pop);
    opacity: 0;
    visibility: hidden;
    transition: opacity .18s ease, visibility .18s ease;
  }
  .a2e-nav__group:hover > .a2e-mega,
  .a2e-nav__group:focus-within > .a2e-mega {
    opacity: 1;
    visibility: visible;
    animation: a2eDrop .22s ease both;
    animation-play-state: var(--a2e-motion, running);
  }

  /* 悬停桥。导航项底边到面板顶边之间有一段空隙，鼠标穿过时会同时离开
     两者，菜单闪一下就关。用一条透明的 ::after 把这段接上。
     常规下拉的空隙是 12px，mega 的到 72px 导航条底边约 22px，取 24px 够用。 */
  .a2e-nav__group::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    height: var(--s-5);
  }

  .a2e-mega__cols {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: var(--s-5) var(--s-3);
  }

  /* 列本身不需要样式，但要在 CSS 里有定义 —— 自查脚本会把「HTML 用了、
     CSS 没定义」的类名报出来，那通常意味着写错了类名。 */
  .a2e-mega__col { min-width: 0; }

  .a2e-mega__title {
    display: block;
    margin-bottom: var(--s-2);
    padding-inline: var(--s-2);
    font-size: var(--fs-xs);
    letter-spacing: .08em;
    color: var(--text-mute);
  }

  .a2e-mega__item {
    display: block;
    padding: 7px var(--s-2);
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
    line-height: 1.35;
    color: var(--text);
  }
  .a2e-mega__item:hover { background: var(--surface-2); color: var(--text); }

  /* 线上那两种角标：🔥 是热门、NEW 是新上。用 accent 描边的小胶囊，
     不占一行、不抢标题。 */
  .a2e-mega__flag {
    margin-left: 5px;
    padding: 1px 5px;
    border-radius: var(--r-full);
    background: color-mix(in srgb, transparent, var(--accent) 14%);
    color: var(--accent);
    font-size: 10px;
    letter-spacing: .04em;
    vertical-align: 1px;
  }

  /* 分组条目多的（视频 24 项、图片 22 项）在菜单里只列前 8 个，
     其余收进这一条。导航不该是站点地图。 */
  .a2e-mega__all {
    display: block;
    margin-top: var(--s-1);
    padding: 7px var(--s-2);
    font-size: var(--fs-xs);
    color: var(--text-mute);
  }
  .a2e-mega__all:hover { color: var(--accent); }

  .a2e-mega__foot {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    margin-top: var(--s-5);
    padding-top: var(--s-4);
    border-top: 1px solid var(--line-soft);
  }

  /* --- 语言切换 --- */
  .a2e-lang {
    position: relative;
    margin-left: 10px;
    padding-left: var(--s-3);
    border-left: 1px solid var(--line-soft);
  }
  .a2e-lang__btn { opacity: .86; gap: 7px; }
  .a2e-lang__btn:hover { opacity: 1; }
  .a2e-lang__menu {
    left: auto;
    right: 0;
    transform: none;
    min-width: 150px;
    padding: var(--s-2);
  }
  /* --- 汉堡与移动面板 --- */
  .a2e-nav__burger { display: none; width: 42px; height: 42px; }

  .a2e-mobile {
    position: fixed;
    top: var(--a2e-nav-h);
    left: var(--s-3);
    right: var(--s-3);
    z-index: calc(var(--z-pop) - 1);
    max-height: calc(100vh - 96px);
    overflow-y: auto;
    padding: var(--s-4);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-pop);
    display: none;
  }
  /* 开合状态挂在触发按钮的 aria-expanded 上，不发明 .is-open。 */
  .a2e-nav__burger[aria-expanded="true"] ~ .a2e-mobile {
    display: block;
    animation: a2eDrop .22s ease both;
    animation-play-state: var(--a2e-motion, running);
  }

  .a2e-mobile__link {
    display: block;
    padding: var(--s-3) var(--s-1);
    font-size: 17px;
    color: var(--text);
    transition: color .18s ease;
  }
  .a2e-mobile__link:hover { color: var(--accent); }

  .a2e-mobile__chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    padding: 0 var(--s-1) var(--s-3);
  }
  .a2e-mobile__chip {
    padding: 7px var(--s-3);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    font-size: 13px;
    color: var(--text-mute);
    transition: border-color .18s ease, background .18s ease, color .18s ease;
  }
  .a2e-mobile__chip:hover {
    border-color: var(--glass-border);
    background: var(--surface-2);
    color: var(--accent);
  }

  .a2e-mobile__rule { height: 1px; background: var(--line-soft); }
  .a2e-mobile__rule--last { margin-bottom: var(--s-3); }

  .a2e-mobile__langs { display: flex; gap: var(--s-2); }
  .a2e-mobile__langs .a2e-btn { flex: 1; justify-content: center; padding: 10px; }


  /* ==========================================================
     5 · 版式基元
     ========================================================== */

  /* 区块间距统一 32px。原来有 --tail(32) / --gap(64) / --end(120) 三档，
     每个区块挑一档，结果是节奏全靠手感、两个页面还对不齐。现在一个值，
     三个修饰类已删除。--first（给 fixed 导航让位）与 --flush（去左右留白）
     不是间距档位，保留。 */
  .a2e-sec { padding: 0 var(--a2e-gutter) var(--s-6); }
  .a2e-sec--first { padding-top: 96px; }
  .a2e-sec--flush { padding-left: 0; padding-right: 0; }

  /* 标题组与内容之间同样给 32px。之前是 18px，标题几乎贴着下面的网格。 */
  .a2e-sec__head { margin-bottom: var(--s-6); }

  /* Quicksand 比 Lexend Deca 小 ~3%，补偿直接乘进字号 —— 不复合
     .a2e-display，那个工具类会把这里的 font-size 覆盖掉。 */
  .a2e-sec__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: calc(var(--fs-xl) * 1.03);
    line-height: var(--lh-tight);
    letter-spacing: -.01em;
    color: var(--accent);
  }
  .a2e-sec__title--sky   { color: var(--c-sky); }
  .a2e-sec__title--rose  { color: var(--c-rose); }
  .a2e-sec__title--amber { color: var(--c-amber); }

  .a2e-sec__sub {
    margin: 7px 0 0;
    font-size: var(--fs-sm);
    line-height: var(--lh-body);
    color: var(--text-mute);
  }

  .a2e-frame { position: relative; }



  /* ==========================================================
     6 · 功能横向滚动卡
     ========================================================== */

  .a2e-rail {
    display: flex;
    gap: var(--a2e-gap);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    /* 锚住起点。线上旧版加载时 scrollLeft=25、首卡 x=-11，标题左边
       被裁掉约 1.5 个汉字；加上这条之后实测 x=16、scrollLeft=0。 */
    scroll-padding-inline-start: var(--a2e-gutter);
    padding: var(--s-1) var(--a2e-gutter) var(--s-2);
    scrollbar-width: none;
  }
  .a2e-rail::-webkit-scrollbar { display: none; }

  .a2e-rail__card {
    flex: 0 0 auto;
    width: var(--a2e-card-w);
    aspect-ratio: 16 / 9;
    scroll-snap-align: start;
    position: relative;
    border-radius: var(--r-md);
    overflow: hidden;
    cursor: pointer;
  }

  /* 单色底走 .a2e-tone / .a2e-tone--dk 两个工具类，颜色由页面注入
     --tone。跨色渐变没有对应工具类（方向不能做成参数），所以写成
     组件变体；全站只有三处需要，不值得再造一个工具类。 */
  .a2e-rail__card--fresh { background: var(--grad-fresh); }

  /* 横滚卡的真实媒体。卡片本身不动，只有这层随 hover 轻微放大。 */
  .a2e-rail__media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transform: scale(var(--a2e-media-z, 1));
    transition: transform var(--a2e-dur, .28s) var(--a2e-ease);
  }
  .a2e-rail__card:hover { --a2e-media-z: var(--a2e-lift, 1.06); }

  /* 底部压暗，让白字压在任何底色上都读得出来。 */
  .a2e-rail__scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, transparent 40%, color-mix(in srgb, transparent, var(--c-void) 92%));
  }

  .a2e-rail__body {
    position: absolute;
    inset: auto 0 0 0;
    padding: 18px 20px;
    /* 可点区是铺满整卡的 scrim <a>，文案层不能把它挡住。 */
    pointer-events: none;
  }
  .a2e-rail__title {
    margin: 0;
    font-size: var(--fs-base);
    letter-spacing: .01em;
    color: var(--c-text);
  }
  .a2e-rail__desc {
    margin: 5px 0 0;
    font-size: 13px;
    line-height: 1.5;
    color: color-mix(in srgb, transparent, var(--c-text) 74%);
  }

  .a2e-rail__nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--s-4);
    margin-top: 26px;
  }

  .a2e-rail__dots {
    display: flex;
    align-items: center;
    gap: var(--s-2);
  }

  .a2e-rail__dot-wrap {
    position: relative;
    display: flex;
    align-items: center;
  }

  .a2e-rail__dot {
    width: 7px;
    height: 7px;
    flex: none;
    padding: 0;
    border: 0;
    border-radius: var(--r-xs);
    overflow: hidden;
    position: relative;
    cursor: pointer;
    background: color-mix(in srgb, transparent, var(--c-text) 26%);
    transition: width .32s var(--a2e-ease-ind), background .2s ease;
  }
  .a2e-rail__dot[aria-current="true"] {
    width: 34px;
    background: color-mix(in srgb, transparent, var(--c-text) 18%);
  }

  /* 停留进度：横向填充。时长由 JS 注入，非当前点不画。 */
  .a2e-rail__fill { display: none; }
  .a2e-rail__dot[aria-current="true"] .a2e-rail__fill {
    display: block;
    position: absolute;
    inset: 0;
    background: var(--accent);
    transform-origin: left;
    transform: scaleX(0);
    animation: a2eDotFill var(--a2e-dwell, 5000ms) linear forwards;
    animation-play-state: var(--a2e-motion, running);
  }
  /* 自动轮播关掉时没有进度可言，直接铺满。 */
  .a2e-rail__dots[data-autoplay="off"] .a2e-rail__fill {
    animation: none;
    transform: scaleX(1);
  }

  .a2e-rail__tip {
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    white-space: nowrap;
    padding: 6px 10px;
    font-size: var(--fs-xs);
    line-height: 1.2;
    border-radius: var(--r-sm);
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--line);
    box-shadow: var(--shadow-pop);
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    transition: opacity .16s ease, visibility .16s ease;
  }
  .a2e-rail__dot:hover + .a2e-rail__tip,
  .a2e-rail__dot:focus-visible + .a2e-rail__tip {
    opacity: 1;
    visibility: visible;
  }


  /* ==========================================================
     7 · 推广大卡 + 六宫格功能卡
     ========================================================== */

  .a2e-quick {
    display: flex;
    flex-wrap: wrap;
    gap: var(--a2e-gap);
    align-items: stretch;
  }

  .a2e-quick__grid {
    flex: 1 1 300px;
    min-width: 0;
    display: grid;
    align-content: start;
    grid-template-columns: 1fr;
    grid-auto-rows: minmax(98px, auto);
    gap: var(--a2e-gap);
  }

  /* --- 推广大卡（violet，唯一能挨着亮色的隔断色）--- */
  .a2e-promo {
    flex: 1 1 100%;
    max-width: 100%;
    min-width: 0;
    min-height: 210px;
    position: relative;
    border-radius: var(--r-md);
    overflow: hidden;
    background: linear-gradient(160deg, var(--c-violet), color-mix(in srgb, var(--c-violet), black 34%));
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: 26px;
    cursor: pointer;
  }
  .a2e-promo__badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 11px;
    border-radius: var(--r-sm);
    background: color-mix(in srgb, transparent, var(--c-text) 16%);
    font-size: var(--fs-xs);
    letter-spacing: .04em;
    color: var(--c-text);
  }
  .a2e-promo__title {
    margin: 20px 0 0;
    font-family: var(--font-display);
    font-size: calc(var(--fs-2xl) * 1.03);
    line-height: 1.3;
    letter-spacing: -.01em;
    color: var(--c-text);
    text-wrap: balance;
  }
  .a2e-promo__cta { align-self: flex-start; }

  /* --- 功能卡 --- */
  .a2e-feat {
    position: relative;
    padding: var(--s-3) 14px;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--surface);
    display: grid;
    grid-template-rows: auto auto;
    align-content: start;
    row-gap: 10px;
    transition:
      border-color .2s ease,
      background   .2s ease,
      box-shadow   .3s ease;
  }

  /* 流动 border 辉光：conic-gradient 铺满 + mask-composite 挖空中心，
     剩下 1px 的环。角度靠 @property 注册过的 --a2e-ang 做动画。
     非 hover 时 paused —— 六张卡各转一圈的合成开销不该常驻。 */
  .a2e-feat::before {
    content: "";
    position: absolute;
    inset: -1px;
    border-radius: calc(var(--r-md) + 1px);
    padding: 1px;
    background: conic-gradient(from var(--a2e-ang, 0deg),
      transparent 0deg 195deg,
      color-mix(in srgb, transparent, var(--accent) 92%) 300deg,
      transparent 352deg);
    mask: linear-gradient(#000, #000) content-box, linear-gradient(#000, #000);
    mask-composite: exclude;
    -webkit-mask: linear-gradient(#000, #000) content-box, linear-gradient(#000, #000);
    -webkit-mask-composite: xor;
    opacity: var(--a2e-ring, 0);
    transition: opacity .22s ease;
    animation: a2eRing 2.4s linear infinite;
    animation-play-state: var(--a2e-ring-play, paused);
    pointer-events: none;
  }
  .a2e-feat:hover,
  .a2e-feat:focus-visible {
    border-color: var(--glass-border);
    background: var(--surface-2);
    box-shadow: var(--glow-tight);
    --a2e-ring: 1;
    --a2e-ring-play: var(--a2e-motion, running);
  }

  /* 渐变底的两张卡：渐变不能用 color-mix() 提亮（只接受 <color>，
     对 gradient 静默失效），改用 filter。 */
  .a2e-feat--grad {
    border-color: transparent;
    background: var(--grad-fresh);
    transition: filter .2s ease, box-shadow .3s ease;
  }
  .a2e-feat--grad:hover {
    border-color: transparent;
    background: var(--grad-fresh);
    filter: brightness(1.06);
  }

  .a2e-feat--alt {
    border-color: color-mix(in srgb, transparent, var(--c-text) 14%);
    background: linear-gradient(180deg, var(--c-violet), color-mix(in srgb, var(--c-violet), black 30%));
    transition: filter .2s ease, box-shadow .3s ease;
  }
  .a2e-feat--alt:hover {
    border-color: color-mix(in srgb, transparent, var(--c-text) 14%);
    background: linear-gradient(180deg, var(--c-violet), color-mix(in srgb, var(--c-violet), black 30%));
    filter: brightness(1.1);
  }

  .a2e-feat__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
  }
  .a2e-feat__icon { flex: none; stroke: var(--text); }
  .a2e-feat--grad .a2e-feat__icon { stroke: var(--c-navy); }
  .a2e-feat--alt  .a2e-feat__icon { stroke: var(--c-text); }

  .a2e-feat__tag {
    flex: none;
    padding: var(--s-1) 9px;
    border-radius: var(--r-sm);
    background: color-mix(in srgb, transparent, var(--c-text) 12%);
    color: var(--text);
    font-size: 11px;
    letter-spacing: .04em;
  }
  /* 亮底上的标签换成 navy 底 + text 字，跟着变体走。 */
  .a2e-feat--grad .a2e-feat__tag { background: var(--c-navy); color: var(--c-text); }
  .a2e-feat--alt  .a2e-feat__tag { background: color-mix(in srgb, transparent, var(--c-text) 18%); color: var(--c-text); }
  .a2e-feat__tag--alt { background: var(--alt); color: var(--alt-on); }

  .a2e-feat__title {
    margin: 0;
    font-size: var(--fs-base);
    letter-spacing: .01em;
    color: var(--text);
  }
  .a2e-feat__desc {
    margin: 6px 0 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--text-mute);
  }
  /* 亮底：文字色一律 --c-navy；violet 底：--c-text。分界在亮度 0.2。 */
  .a2e-feat--grad .a2e-feat__title { color: var(--c-navy); }
  .a2e-feat--grad .a2e-feat__desc  { color: color-mix(in srgb, transparent, var(--c-navy) 76%); }
  .a2e-feat--alt  .a2e-feat__title { color: var(--c-text); }
  .a2e-feat--alt  .a2e-feat__desc  { color: color-mix(in srgb, transparent, var(--c-text) 76%); }


  /* ==========================================================
     8 · 实时数字人 2.0 面板
     ========================================================== */

  .a2e-model {
    position: relative;
    overflow: hidden;
    border-radius: var(--r-lg);
    background: var(--c-ink);
  }

  /* 背景网格漂移：走一个格距（88px）再无缝接回。
     background-position 的起始值必须显式写出来，两层渐变各一份，
     否则动画起点是 auto，第一帧会跳。 */
  .a2e-model__grid {
    position: absolute;
    inset: 0;
    background-image:
      repeating-linear-gradient(90deg,  var(--line-soft) 0 1px, transparent 1px 88px),
      repeating-linear-gradient(180deg, var(--line-soft) 0 1px, transparent 1px 88px);
    background-position: 0 0, 0 0;
    opacity: .55;
    pointer-events: none;
    animation: a2eGridDrift 14s linear infinite;
    animation-play-state: var(--a2e-motion, running);
  }

  /* 边框辉光呼吸：整层透明度 .62 ↔ 1。辉光单独一层是为了能只对它做
     动画 —— 画在 .a2e-model 身上的话呼吸会把整块内容一起淡掉。
     !! 圆角必须跟着写一遍。inset 阴影是按**这一层自己**的边框盒画的，
     这层没圆角就按直角画，父级的 overflow:hidden 再把四个角上那截切掉，
     那条 2px 亮边在圆角处就断开了。绿色的 .a2e-agent 没这个问题是因为
     它的 inset 阴影直接画在带圆角的元素上。 */
  .a2e-model__glow {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    z-index: 2;
    pointer-events: none;
    animation: a2eBreathe 4.2s ease-in-out infinite;
    animation-play-state: var(--a2e-motion, running);
    box-shadow:
      inset 0 0 0 2px color-mix(in srgb, var(--c-peri), white 30%),
      inset 0 0 26px 6px var(--c-peri),
      inset 0 0 70px 6px color-mix(in srgb, transparent, var(--c-peri) 72%),
      inset 0 0 130px 10px color-mix(in srgb, transparent, var(--c-peri) 30%),
      inset 0 0 190px 16px color-mix(in srgb, transparent, var(--c-peri) 12%);
  }

  .a2e-model__body {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-6);
    padding: var(--s-6);
  }
  .a2e-model__col {
    flex: 1 1 100%;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding: var(--s-2) 0;
  }
  /* 主色从 amber 换成 --info(peri)。语义上也更对：这块是「即将上线」的
     预告，不是警告。peri 与 amber 一样配 --c-navy（7.06 AAA），
     所以换底色不用改文字色 —— 但这条只在这个模块成立，别推广。 */
  .a2e-model__badge {
    display: inline-flex;
    align-self: flex-start;
    align-items: center;
    gap: 7px;
    padding: 6px var(--s-3);
    border-radius: var(--r-sm);
    background: var(--info);
    color: var(--info-on);
    font-size: var(--fs-xs);
    letter-spacing: .12em;
  }
  .a2e-model__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: calc(var(--fs-3xl) * 1.03);
    line-height: 1.2;
    letter-spacing: -.02em;
    color: var(--text);
  }
  .a2e-model__desc {
    margin: 0;
    max-width: 330px;
    font-size: var(--fs-sm);
    line-height: var(--lh-body);
    color: var(--text-mute);
  }
  .a2e-model__cta { align-self: flex-start; margin-top: 6px; }

  .a2e-model__wall {
    flex: 1 1 420px;
    min-width: 0;
    display: flex;
    align-items: flex-start;
  }
  .a2e-model__stage {
    position: relative;
    width: 100%;
    height: 380px;
  }
  .a2e-model__tiles {
    position: absolute;
    inset: 0;
    overflow: hidden;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-rows: auto;
    align-content: start;
    gap: clamp(8px, 1.1vw, 16px);
    -webkit-mask-image: linear-gradient(180deg, #000 58%, transparent 96%);
            mask-image: linear-gradient(180deg, #000 58%, transparent 96%);
  }
  /* 换成真实 <img>/<video> 之后必须补宽高约束：它们有固有尺寸，不写
     width 就会按 1280×720 把网格撑破（占位 <div> 时代没有这个问题）。 */
  .a2e-model__tile {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    display: block;
    border-radius: var(--r-md);
  }
  .a2e-model__tile--fresh { background: var(--grad-fresh); }
  .a2e-model__tile--cool  { background: var(--grad-cool); }
  .a2e-model__more { bottom: var(--s-2); }


  /* ==========================================================
     9 · SHOWREEL 取景框
     ========================================================== */

  .a2e-reel {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 3;
    min-height: 300px;
    overflow: hidden;
    border-radius: var(--r-lg);
    background: linear-gradient(180deg, var(--c-violet), color-mix(in srgb, var(--c-violet), black 45%));
  }
  .a2e-reel:hover { --a2e-reel-on: 1; }

  /* 边框辉光呼吸 —— 与实时数字人 2.0 面板（.a2e-model__glow）同一套做法，
     只换颜色：那边是 --c-peri，这里跟取景框自己的 violet 底呼应，用 --c-violet。

     !! 圆角必须 inherit 一遍。inset 阴影按**这一层自己**的边框盒画，
        这层没圆角就按直角画，父级的 overflow:hidden 再把四角那截切掉，
        2px 亮边在圆角处就断开了 —— 与 .a2e-model__glow 注释里记的是同一个坑。

     !! 提亮幅度比 peri 那版大（描边 white 34% vs 30%，第二层也补了一次提亮）。
        violet 相对亮度 0.121，peri 是 0.351；同样的配方压在这块
        violet → violet+black45% 的底上会糊成一团，边缘辨不出来。 */
  .a2e-reel__glow {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    z-index: 2;
    pointer-events: none;
    animation: a2eBreathe 4.2s ease-in-out infinite;
    animation-play-state: var(--a2e-motion, running);
    box-shadow:
      inset 0 0 0 2px color-mix(in srgb, var(--c-violet), white 34%),
      inset 0 0 26px 6px color-mix(in srgb, var(--c-violet), white 12%),
      inset 0 0 70px 6px color-mix(in srgb, transparent, var(--c-violet) 72%),
      inset 0 0 130px 10px color-mix(in srgb, transparent, var(--c-violet) 30%),
      inset 0 0 190px 16px color-mix(in srgb, transparent, var(--c-violet) 12%);
  }

  /* SHOWREEL 的真实片子。铺满取景框，四角标记与文案压在它上面。 */
  .a2e-reel__media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }

  .a2e-reel__vignette {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(108% 82% at 50% 50%,
      transparent 52%,
      color-mix(in srgb, transparent, var(--c-void) 46%) 80%,
      color-mix(in srgb, transparent, var(--c-void) 80%) 100%);
    box-shadow: inset 0 0 70px 18px color-mix(in srgb, transparent, var(--c-void) 55%);
  }

  /* 四角取景标记：hover 整个取景框各自向外顶 4px。符号按角位，
     所以四个方向各写一条，只差正负号。 */
  .a2e-reel__corner {
    position: absolute;
    width: 34px;
    height: 34px;
    opacity: calc(.85 + var(--a2e-reel-on, 0) * .15);
    pointer-events: none;
    transition: opacity .3s ease, transform .3s var(--a2e-ease);
  }
  .a2e-reel__corner--tl {
    top: 22px; left: 22px;
    border-left: 2px solid var(--accent);
    border-top: 2px solid var(--accent);
    transform: translate(calc(var(--a2e-reel-on, 0) * -4px), calc(var(--a2e-reel-on, 0) * -4px));
  }
  .a2e-reel__corner--tr {
    top: 22px; right: 22px;
    border-right: 2px solid var(--accent);
    border-top: 2px solid var(--accent);
    transform: translate(calc(var(--a2e-reel-on, 0) * 4px), calc(var(--a2e-reel-on, 0) * -4px));
  }
  .a2e-reel__corner--bl {
    bottom: 22px; left: 22px;
    border-left: 2px solid var(--accent);
    border-bottom: 2px solid var(--accent);
    transform: translate(calc(var(--a2e-reel-on, 0) * -4px), calc(var(--a2e-reel-on, 0) * 4px));
  }
  .a2e-reel__corner--br {
    bottom: 22px; right: 22px;
    border-right: 2px solid var(--accent);
    border-bottom: 2px solid var(--accent);
    transform: translate(calc(var(--a2e-reel-on, 0) * 4px), calc(var(--a2e-reel-on, 0) * 4px));
  }

  .a2e-reel__slug,
  .a2e-reel__spec {
    position: absolute;
    top: 24px;
    padding: 5px 10px;
    border-radius: var(--r-sm);
    font-family: var(--font-num);
    font-size: calc(var(--fs-xs) * .96);
    font-variant-numeric: tabular-nums;
    letter-spacing: .06em;
  }
  .a2e-reel__slug {
    left: var(--a2e-reel-inset, 20px);
    display: flex;
    align-items: center;
    gap: var(--s-2);
    background: color-mix(in srgb, transparent, var(--c-void) 55%);
    color: var(--c-text);
  }
  .a2e-reel__spec {
    right: var(--a2e-reel-inset, 20px);
    background: var(--accent);
    color: var(--accent-on);
  }

  .a2e-reel__rec {
    width: 7px;
    height: 7px;
    flex: none;
    border-radius: var(--r-full);
    background: var(--danger);
    animation: a2eRec 1.6s ease-in-out infinite;
    animation-play-state: var(--a2e-motion, running);
  }

  .a2e-reel__body {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--s-3);
    text-align: center;
    padding: 0 40px;
    pointer-events: none;
  }
  .a2e-reel__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: clamp(calc(var(--fs-xl) * 1.03), 4.2vw, calc(var(--fs-4xl) * 1.03));
    line-height: 1.2;
    letter-spacing: -.02em;
    color: var(--c-text);
    text-wrap: balance;
  }
  .a2e-reel__desc {
    margin: 0;
    max-width: 520px;
    font-size: var(--fs-sm);
    line-height: var(--lh-body);
    color: color-mix(in srgb, transparent, var(--c-text) 78%);
  }


  /* ==========================================================
     10 · 作品图块（瀑布流 / 横屏网格 / 竖屏网格 共用）

     !! 缩放的是 ::before 内容层。容器保持不动，overflow:hidden +
        圆角始终有效，内容溢出被裁掉 —— 换成真实图片或视频时这也
        正是该有的行为。不要改回容器缩放。
     ========================================================== */

  .a2e-work {
    position: relative;
    margin: 0;
    /* 每件作品的画幅由页面注入 --a2e-ratio（16/9、9/16、3/4、1/1、4/5），
       这是传数据不是传声明。两个等比网格在下面按整组统一改写。 */
    aspect-ratio: var(--a2e-ratio, 16 / 9);
    border-radius: var(--r-xs);
    overflow: hidden;
    cursor: pointer;
  }

  /* 垫在媒体下面的一层。

     !! 这里曾经是「单向明度渐变 + 页面注入 --tone」，是占位色块时代的产物，
        意思是海报解码前底下是品牌色而不是黑洞。全组换成真素材之后它变成了
        纯粹的害处：图块高度是分数（实测 183.23px），视频纹理和背景的亚像素
        snapping 对不齐，每块底边就透出一条薄荷绿细线。唇形同步那面看不见，
        只是因为最后一排正好被渐隐吃掉了 —— 不是没有。

        中性底之后同一条缝仍然存在，但和画面同色系，看不出来。
        --tone / --a2e-work--dk / --fresh / --cool 一并删掉，
        生成的 HTML 里已经一个都不用了。 */
  .a2e-work::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--a2e-media, var(--surface-2));
    transform: scale(var(--a2e-media-z, 1));
    filter: brightness(var(--a2e-media-b, 1));
    transition:
      transform var(--a2e-dur, .28s) var(--a2e-ease),
      filter    var(--a2e-dur, .28s) ease;
  }

  .a2e-work:hover {
    --a2e-media-z: var(--a2e-lift, 1.06);
    --a2e-media-b: 1.08;
  }

  /* 真实素材层。渐变占位在 ::before，媒体盖在它上面 —— poster 还没解码
     出来的那一瞬间底下是品牌色而不是黑洞。

     !! 缩放的是这一层，不是 .a2e-work 容器。理由和占位那版完全一样：
        父级带 mask-image 时容器一 transform 就被提升为独立合成层，
        border-radius 的裁剪当场失效。换成真视频之后这条更要紧，
        因为裁不住的是一整帧画面。 */
  .a2e-work__media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transform: scale(var(--a2e-media-z, 1));
    filter: brightness(var(--a2e-media-b, 1));
    transition:
      transform var(--a2e-dur, .28s) var(--a2e-ease),
      filter    var(--a2e-dur, .28s) ease;
  }

  /* 整块可点，铺在媒体之上。可访问名由它自己的 aria-label 提供 ——
     图注（.a2e-work__cap，带彩点的「XX演示」小标签）已整体移除，
     那是纯装饰，遮住画面下缘、每块都重复同一句话。 */
  .a2e-work__hit {
    position: absolute;
    inset: 0;
    z-index: 1;
  }
  /* --- 瀑布流 ---
     !! 试过 CSS 多列（columns: 2/3/4），不行：定高容器里多列是**逐列
        填满**，不是按最矮列填。12 件作品高矮差三倍，第一列放完一张
        16:9 就塞不下下一张 9:16，直接留出半列空洞。设计稿用的是
        「每次投给当前最矮的列」，那个必须知道各件的高度，只能用 JS。

     所以 HTML 里是一份扁平列表（没 JS 也能看，只是变成单列），
     列数写成 --a2e-gallery-n 交给断点，JS 读它来分列。 */
  /* 取景框和它下面的瀑布流是同一个区块的两层，中间给一个标准间距。
     区块之间的 32px 由 .a2e-sec 管，这条只管区块内部。 */
  .a2e-reel + .a2e-frame { margin-top: var(--s-6); }

  .a2e-gallery__cols {
    --a2e-gallery-n: 2;
    display: flex;
    align-items: flex-start;
    gap: var(--a2e-gap-tile);
    height: 620px;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 180px), transparent calc(100% - 8px));
            mask-image: linear-gradient(180deg, #000 calc(100% - 180px), transparent calc(100% - 8px));
  }
  .a2e-gallery__col {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--a2e-gap-tile);
  }
  .a2e-gallery__cta { bottom: 34px; }

  /* --- 横屏 / 竖屏网格 --- */
  .a2e-works {
    display: grid;
    gap: var(--a2e-gap-tile);
    grid-auto-rows: min-content;
    align-content: start;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(180deg, #000 58%, color-mix(in srgb, #000, transparent 45%) 82%, transparent 100%);
            mask-image: linear-gradient(180deg, #000 58%, color-mix(in srgb, #000, transparent 45%) 82%, transparent 100%);
  }
  .a2e-works--wide { grid-template-columns: 1fr; aspect-ratio: 1 / 2.05; }
  .a2e-works--tall { grid-template-columns: repeat(2, minmax(0, 1fr)); aspect-ratio: 1 / 1.36; }
  .a2e-works--wide .a2e-work { aspect-ratio: 16 / 9; }
  .a2e-works--tall .a2e-work { aspect-ratio: 9 / 16; }
  .a2e-works__cta { bottom: var(--s-3); }


  /* ==========================================================
     11 · A2E 智能体
     ========================================================== */

  .a2e-agent {
    position: relative;
    overflow: hidden;
    border-radius: var(--r-lg);
    min-height: 340px;
    aspect-ratio: 4 / 5;
    background: var(--c-ink);
    box-shadow:
      inset 0 0 0 2px color-mix(in srgb, var(--c-mint), white 30%),
      inset 0 0 26px 6px var(--c-mint),
      inset 0 0 70px 6px color-mix(in srgb, transparent, var(--c-mint) 72%),
      inset 0 0 130px 10px color-mix(in srgb, transparent, var(--c-mint) 30%),
      inset 0 0 190px 16px color-mix(in srgb, transparent, var(--c-mint) 12%);
  }

  /* 上下两片透视网格，往中间收。 */
  .a2e-agent__plane {
    position: absolute;
    left: -30%;
    right: -30%;
    height: 56%;
    pointer-events: none;
    background-image:
      repeating-linear-gradient(90deg,  color-mix(in srgb, transparent, var(--c-mint) 30%) 0 1px, transparent 1px 84px),
      repeating-linear-gradient(180deg, color-mix(in srgb, transparent, var(--c-mint) 30%) 0 1px, transparent 1px 62px);
  }
  .a2e-agent__plane--floor {
    bottom: 0;
    transform: perspective(460px) rotateX(64deg);
    transform-origin: bottom center;
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 60%);
            mask-image: linear-gradient(180deg, transparent, #000 60%);
  }
  .a2e-agent__plane--ceil {
    top: 0;
    transform: perspective(460px) rotateX(-64deg);
    transform-origin: top center;
    -webkit-mask-image: linear-gradient(0deg, transparent, #000 60%);
            mask-image: linear-gradient(0deg, transparent, #000 60%);
  }

  .a2e-agent__body {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--s-4);
    text-align: center;
    padding: 0 40px;
  }
  /* ---- 线上 banner 搬过来的装饰图 ----
     位置沿用线上那套百分比（.a2e-supercomputer__* 的取值），因为两边
     画幅几乎一样：线上 banner 是 1408/429 ≈ 3.28，这块面板 16/5 = 3.2。

     !! 这几张是为**紫色**banner 切的图，卡片本身带紫灰底。放在 mint
        面板上不会破，但色调是原来那套。要完全贴合 mint 得让设计重新导出。

     没有搬过来的是 bg-bg.webp —— 线上那张紫色透视网格背景。这块面板
     已经有自己的 mint 网格（.a2e-agent__plane），再叠一层紫的就冲突了。 */
  .a2e-agent__logo {
    display: block;
    width: min(37%, 560px);
    max-width: 560px;
    height: auto;
    aspect-ratio: 527 / 108;
    object-fit: contain;
    margin-bottom: var(--s-2);
  }

  .a2e-agent__deco {
    position: absolute;
    z-index: 1;
    display: none;          /* 1024 以下不出现，和原来那三张卡一致 */
    height: auto;
    max-width: none;
    pointer-events: none;
    user-select: none;
  }
  .a2e-agent__deco--creative    { top: 30%;    left: 7.24%;  width: 13%; }
  .a2e-agent__deco--visualizing { top: 15.85%; left: 67.9%;  width: 8.17%; }
  .a2e-agent__deco--marketing   { top: 14%;    right: 6%;    width: 10%; }
  .a2e-agent__deco--production  { bottom: 0;   left: 74%;    width: 13%; }

  /* 宽屏走单行，窄了自己折。不设 max-width —— 换行交给可用宽度决定，
     由 .a2e-agent__body 的 padding-inline 划出中间安全区（见断点一节）。
     真折行时 balance 让两行长度接近。 */
  .a2e-agent__title {
    margin: 0 auto;
    font-family: var(--font-display);
    font-size: clamp(calc(var(--fs-xl) * 1.03), 3.6vw, calc(var(--fs-4xl) * 1.03));
    line-height: 1.15;
    letter-spacing: -.03em;
    color: var(--c-text);
    text-wrap: balance;
  }
  .a2e-agent__desc {
    margin: 0 auto;
    max-width: 46ch;
    font-size: var(--fs-md);
    line-height: var(--lh-body);
    color: color-mix(in srgb, transparent, var(--c-text) 80%);
    text-wrap: balance;
  }
  .a2e-agent__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s-3);
    margin-top: 10px;
  }
  /* 深底上的描边按钮：这块面板底色是 --c-ink，比 --surface 还深，
     幽灵按钮默认的 --line 描边在这里几乎看不见，提到 glass-border。 */
  .a2e-agent__alt {
    padding: 13px 22px;
    border-color: var(--glass-border);
    font-size: 15px;
  }

  /* ==========================================================
     12 · 探索更多
     ========================================================== */

  .a2e-more { text-align: center; }
  .a2e-more__title {
    margin: 0 0 var(--s-6);
    font-family: var(--font-display);
    font-size: clamp(calc(var(--fs-xl) * 1.03), 3.4vw, calc(var(--fs-3xl) * 1.03));
    line-height: 1.15;
    letter-spacing: -.02em;
    color: var(--c-text);
  }
  .a2e-more__tags {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    max-width: 1080px;
    margin: 0 auto;
  }


  /* ==========================================================
     13 · 页脚（mint 底，文字一律 --accent-on）
     ========================================================== */

  .a2e-foot {
    background: var(--accent);
    color: var(--accent-on);
    padding: 64px var(--a2e-gutter) 28px;
  }
  /* 页脚是站点地图：8 列产品分组，条目数从 3 到 24 不等，
     所以列高必然参差，align-items: start 让它们顶部对齐。 */
  /* 手机单列：每一列都是可折叠的一段。768 起摊开成多列，
     1280 起回到设计稿那种「标题占左列 + 内容列在右」的排法。 */
  .a2e-foot__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s-4) var(--s-5);
    align-items: start;
  }
  .a2e-foot__head {
    grid-column: 1 / -1;
    margin: 0;
    max-width: 340px;
    text-wrap: balance;
    font-family: var(--font-display);
    font-size: clamp(calc(28px * 1.03), 3.2vw, calc(46px * 1.03));
    line-height: 1.08;
    letter-spacing: -.03em;
    color: var(--accent-on);
  }
  .a2e-foot__nav {
    display: flex;
    flex-direction: column;
    gap: 11px;
  }

  /* 折叠状态挂在原生 checkbox 上，不发明 .is-open。
     !! 不用 <details>：它关闭时内容盒子宽度是 0，桌面端没法用 CSS 强制
        展开，而我们正需要「手机折叠、桌面常开」。 */
  .a2e-foot__toggle {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
  }
  .a2e-foot__toggle:focus-visible + .a2e-foot__title {
    outline: 2px solid var(--accent-on);
    outline-offset: 2px;
  }

  .a2e-foot__links {
    display: flex;
    flex-direction: column;
    gap: 11px;
  }

  .a2e-foot__title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: var(--fs-sm);
    line-height: 1;
    letter-spacing: .04em;
    color: color-mix(in srgb, transparent, var(--accent-on) 66%);
  }
  /* 折叠指示箭头。只在手机出现，展开时转 180°。 */
  .a2e-foot__title::after {
    content: "";
    width: 8px;
    height: 8px;
    margin-left: var(--s-2);
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform .22s ease;
  }
  .a2e-foot__toggle:checked + .a2e-foot__title::after {
    transform: rotate(-135deg) translate(-2px, -2px);
  }
  .a2e-foot__link {
    font-size: 15px;
    line-height: 1.15;
    color: var(--accent-on);
  }
  .a2e-foot__link:hover { color: var(--accent-on); text-decoration: underline; }

  .a2e-foot__bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-4) 28px;
    margin-top: 72px;
  }
  .a2e-foot__meta {
    font-size: var(--fs-sm);
    color: color-mix(in srgb, transparent, var(--accent-on) 78%);
  }
  .a2e-foot__social { display: flex; flex-wrap: wrap; gap: 26px; }
  .a2e-foot__social .a2e-foot__link { font-size: var(--fs-sm); }


  /* ==========================================================
     14 · 断点

     设计稿实际用了三个阈值：768、1024、1280。交接 README 只写了
     768 / 1280 两个 —— 1024 处理的是六宫格 2→3 列、智能体浮层卡
     的显隐、以及推广大卡的基准宽度。以源文件为准，已在 NOTES 里
     标出这处出入待设计确认。
     ========================================================== */

  /* ==========================================================
     12 · 列表页（/case/）
     ========================================================== */

  /* 面包屑不在这一节 —— 它是四套模板共用的，规则统一在「页内容器与面包屑」
     一节。这里原有一份重复定义，2026-08-05 已删，见那一节的说明。 */

  .a2e-count { margin: 14px 0 0; font-size: var(--fs-sm); color: var(--text-mute); }
  .a2e-count__n { color: var(--accent); }

  /* 控制条吸顶在导航下方。
     !! z-index 必须低于导航（--z-pop: 20）。「产品」大菜单是导航的子节点、
        在导航那个层叠上下文里，控制条一旦 >= 20 就会盖住展开的面板一角。 */
  .a2e-ctrl-sec {
    position: sticky;
    top: var(--a2e-nav-h);
    z-index: calc(var(--z-pop) - 2);
  }
  .a2e-ctrl {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-3);
    padding: 14px 0;
    background: var(--bg);
    border-bottom: 1px solid var(--line-soft);
  }
  /* tab 横向可滚，窄屏放不下 4 个中文作者名。滚动条藏掉。 */
  .a2e-ctrl__tabs {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    overflow-x: auto;
    max-width: 100%;
    padding: 2px;
    scrollbar-width: none;
  }
  .a2e-ctrl__tabs::-webkit-scrollbar { display: none; }

  .a2e-tab {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    flex: none;
    min-height: 38px;
    padding: 9px 14px;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--text-mute);
    font-family: inherit;
    font-size: var(--fs-sm);
    cursor: pointer;
    transition: border-color .18s ease, background .18s ease, color .18s ease;
  }
  .a2e-tab:hover { border-color: var(--glass-border); background: var(--surface-2); color: var(--text); }
  /* 状态走原生属性，不发明 .is-active。 */
  .a2e-tab[aria-current="true"] {
    border-color: transparent;
    background: var(--accent);
    color: var(--accent-on);
  }
  .a2e-tab__n { font-size: 11px; opacity: .72; }

  .a2e-case__empty { margin: var(--s-6) 0 0; text-align: center; color: var(--text-mute); }

  /* 案例格的作者名。落地页那批图注删掉了（每块重复同一句话），
     这里保留是因为**每块的作者不一样**，是真信息不是装饰。 */
  .a2e-case__cap {
    position: absolute;
    inset: auto 0 0 0;
    z-index: 2;
    padding: 34px var(--s-3) 11px;
    font-size: var(--fs-xs);
    color: var(--c-text);
    background: linear-gradient(180deg,
      transparent,
      color-mix(in srgb, transparent, var(--c-void) 62%) 46%,
      color-mix(in srgb, transparent, var(--c-void) 92%));
    pointer-events: none;
  }
  /* 整块可点这次是 button 不是 a（不跳页，开浮层），所以要清掉按钮默认样式。 */
  .a2e-case__open {
    border: 0;
    padding: 0;
    background: transparent;
    cursor: pointer;
  }

  /* --- 浮层预览 --- */
  .a2e-preview {
    position: fixed;
    inset: 0;
    z-index: 260;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--s-4);
  }
  .a2e-preview[hidden] { display: none; }
  .a2e-preview__scrim {
    position: absolute;
    inset: 0;
    background: color-mix(in srgb, transparent, var(--c-void) 78%);
  }
  .a2e-preview__card {
    position: relative;
    display: grid;
    grid-template-columns: 1fr;
    width: 100%;
    max-width: 420px;
    max-height: 88vh;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--surface);
    box-shadow: var(--shadow-pop);
    animation: a2eDrop .22s ease both;
  }
  .a2e-preview__media { background: var(--c-void); }
  /* 案例全是 9:16。给个视口上限，不然竖视频在矮屏上会顶出卡片。 */
  .a2e-preview__video {
    display: block;
    width: 100%;
    max-height: 56vh;
    aspect-ratio: 9 / 16;
    object-fit: contain;
  }
  .a2e-preview__side {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--s-3);
    padding: var(--s-4);
    overflow-y: auto;
  }
  .a2e-preview__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-3); }
  .a2e-preview__author {
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--fs-lg);
    line-height: var(--lh-tight);
    color: var(--text);
  }
  .a2e-preview__meta { margin: 6px 0 0; font-size: var(--fs-xs); color: var(--text-mute); }
  .a2e-preview__caption { margin: 0; font-size: var(--fs-sm); line-height: var(--lh-body); color: var(--text-mute); }
  /* 原平台链接。用 accent 而不是正文色 —— 它是这一层里唯一的外跳动作，
     要和「上一条 / 下一条」那两个站内按钮区分开。 */
  .a2e-preview__origin {
    display: inline-flex;
    align-items: center;
    gap: var(--s-1);
    align-self: flex-start;
    font-size: var(--fs-sm);
    color: var(--accent);
  }
  .a2e-preview__origin:hover { text-decoration: underline; }
  .a2e-preview__origin[hidden] { display: none; }

  .a2e-preview__nav { display: flex; gap: var(--s-2); margin-top: auto; }
  .a2e-preview__x {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--text);
    cursor: pointer;
    transition: border-color .18s ease, color .18s ease;
  }
  .a2e-preview__x:hover { border-color: var(--glass-border); color: var(--accent); }

  /* 浮层开着时锁滚动。属性挂在 <html> 上，由 JS 写原生属性。 */
  :root[data-a2e-lock] { overflow: hidden; }


  @media (min-width: 768px) {
    .a2e-lp { --a2e-card-w: 360px; }

    .a2e-nav__burger { display: none; }
    .a2e-nav__links  { display: flex; }
    .a2e-mobile,
    .a2e-nav__burger[aria-expanded="true"] ~ .a2e-mobile { display: none; }

    .a2e-promo       { flex: 0 0 300px; }
    .a2e-quick__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    .a2e-model__col   { flex: 0 0 340px; }
    .a2e-model__tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .a2e-model__stage { height: 460px; }

    .a2e-reel { aspect-ratio: 16 / 9; --a2e-reel-inset: 74px; }
    .a2e-reel__corner { display: block; }

    .a2e-gallery__cols { --a2e-gallery-n: 3; height: 760px; }

    .a2e-works--wide { grid-template-columns: repeat(2, minmax(0, 1fr)); aspect-ratio: 1 / .93; }
    .a2e-works--tall { grid-template-columns: repeat(3, minmax(0, 1fr)); aspect-ratio: 1 / .9; }

    .a2e-agent { aspect-ratio: 5 / 2; }

    .a2e-foot__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    /* 摊开之后标题不再是折叠头：箭头收掉，鼠标也别变成手型。 */
    .a2e-foot__title::after { display: none; }
    .a2e-foot__title { cursor: default; justify-content: flex-start; }
  }

  @media (min-width: 768px) {
    /* 浮层两栏：竖视频左、文案右。420px 单栏在宽屏上太窄。 */
    .a2e-preview__card { grid-template-columns: minmax(0, 320px) minmax(0, 1fr); max-width: 760px; }
    .a2e-preview__video { max-height: 76vh; }
    .a2e-cta { padding: 56px 40px; }
  }

  @media (min-width: 1024px) {
    .a2e-promo       { flex: 0 0 340px; }
    .a2e-quick__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }

    /* 装饰图从这个断点开始出现。实测中间安全区是面板宽的 63.8%
       （左图占到 20.2%、右图从 84% 开始），文字区取 60% 留出余量。
       用百分比而不是固定 px：装饰图本身也是按百分比定位的，会一起缩。 */
    /* 页脚 3 列时高到 1600px（视频 24 条和图片 22 条各占一行的高度），
       4 列能让它们并排到同一行，整体矮下来约 600px。 */
    .a2e-foot__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }

    .a2e-agent__deco { display: block; }
    .a2e-agent__body { padding-inline: 20%; }
  }

  @media (min-width: 1280px) {
    .a2e-lp { --a2e-card-w: 512px; }

    .a2e-promo { flex: 0 0 512px; }

    .a2e-model__tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); }

    .a2e-reel { aspect-ratio: 21 / 9; }

    .a2e-gallery__cols { --a2e-gallery-n: 4; }

    .a2e-works--wide { grid-template-columns: repeat(4, minmax(0, 1fr)); aspect-ratio: 1 / .46; }
    .a2e-works--tall { grid-template-columns: repeat(5, minmax(0, 1fr)); aspect-ratio: 1 / .54; }

    .a2e-agent { aspect-ratio: 16 / 5; }

    /* 回到设计稿的排法：标题占左边一列，内容列在右边。
       设计稿当时是 4 个内容列，现在按分组是 5 个。 */
    .a2e-foot__grid { grid-template-columns: minmax(200px, 1fr) repeat(5, minmax(0, 1fr)); }
    .a2e-foot__head { grid-column: auto; }
  }

  /* 移动端点击目标不小于 44px。 */
  @media (max-width: 767px) {
    /* 页脚每列折叠。全量 5 列在手机上摊开有 70 多条，光「视频」就 24 条。 */
    .a2e-foot__links { display: none; }
    .a2e-foot__toggle:checked ~ .a2e-foot__links { display: flex; }
    .a2e-foot__nav {
      padding-bottom: var(--s-3);
      border-bottom: 1px solid color-mix(in srgb, transparent, var(--accent-on) 16%);
    }
    .a2e-foot__title {
      padding-block: var(--s-3);   /* 点击目标凑够 44px */
      cursor: pointer;
    }

    .a2e-nav__burger { display: flex; width: 44px; height: 44px; }
    .a2e-nav__links  { display: none; }
    .a2e-lp { --a2e-card-w: calc(100vw - 64px); }
    .a2e-mobile__link { padding-block: var(--s-3); }
  }
}

/* ============================================================
   模型详情页（预告形态）
   来源：Claude Design「A2E 模型详情页.dc.html」

   这一批组件不属于落地页，但共用同一个 @layer a2e-components ——
   它们是 a2e 的组件层，不是某一个页面的样式表。文件名叫 landing.css
   是历史原因。
   ============================================================ */

@layer a2e-components {

  @keyframes a2eMarquee {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-50%, 0, 0); }
  }

  /* ---- 公告跑马灯 ---- */
  .a2e-ticker {
    display: block;
    padding: 11px 0;
    overflow: hidden;
    background: linear-gradient(90deg, var(--c-violet), color-mix(in srgb, var(--c-violet), black 30%));
    border-top: 1px solid var(--line-soft);
    border-bottom: 1px solid var(--line-soft);
  }
  .a2e-ticker:hover { --a2e-mq-play: paused; }

  /* 跑马灯轨道必须含两份完全相同的内容：关键帧走 -50%，正好是一份的宽度，
     所以第二份接上第一份的位置，循环看不出接缝。第二份对辅助技术隐藏。 */
  .a2e-marquee__track {
    display: flex;
    width: max-content;
    animation-name: a2eMarquee;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    animation-duration: var(--a2e-mq-dur, 60s);
    animation-direction: var(--a2e-mq-dir, normal);
    /* 两级兜底：hover 暂停 → 全局动效开关 → running */
    animation-play-state: var(--a2e-mq-play, var(--a2e-motion, running));
  }
  .a2e-ticker__group {
    display: flex;
    align-items: center;
    gap: 40px;
    padding-right: 40px;
  }
  .a2e-ticker__item {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    white-space: nowrap;
    font-size: 13px;
    letter-spacing: .04em;
    color: var(--c-text);
  }
  .a2e-ticker__dot {
    width: 5px;
    height: 5px;
    border-radius: var(--r-full);
    background: var(--accent);
  }

  /* ---- 页内容器与面包屑 ---- */
  .a2e-wrap {
    max-width: 1320px;
    margin: 0 auto;
    padding-inline: var(--a2e-gutter);
  }

  /* !! 这套规则原先在「12 · 列表页」章节还有一份完全重复的副本，且那份是
        **退化**的：`margin: 26px 0 0` 的简写把下边距归零（原意只是加上边距），
        font-size 写成裸值 13px，`a` 的 transition 也丢了。同层后写的胜出，
        于是面包屑与其下方 chip 的实测间距为 0 —— 两个盒子 y 坐标完全重合。
        2026-08-05 合并成这一份，列表页那份已删。改之前先确认没有第二处定义。 */
  .a2e-crumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-2);
    margin: 26px 0 22px;
    font-size: var(--fs-xs);
    line-height: 1;
    color: var(--text-mute);
  }
  .a2e-crumb a { color: var(--text-mute); transition: color .18s ease; }
  .a2e-crumb a:hover { color: var(--accent); }
  .a2e-crumb__sep { opacity: .5; }
  .a2e-crumb__here { color: var(--text); }

  /* ---- 模型 Hero：通栏背景视频 ----
     参考 dreamina 的 Seedance 2.5 首屏：一条全幅循环视频铺底，文案压在上面。

     !! 文字压在任意视频帧上，对比度不能靠运气。所以中间必有一层
        --c-ink 的径向 scrim（中心 88%），底边再渐变到 --bg 与页面接上。
        实测封面在文案区的平均亮度 → 见 NOTES；换素材后要重测。 */
  .a2e-mhero__bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
  .a2e-mhero__scrim {
    position: absolute;
    inset: 0;
    pointer-events: none;
    /* !! 这层的密度直接决定文字读不读得出来，改之前先看这两个数：

       对**本条素材**（标题区实测均值 119）：
         55% ink → 合成色 57 → 亮度 .0409 → --text 对它 9.69  ✔ AAA
       对**纯白帧**这个理论最坏情况：
         55% ink → 合成色 118 → 亮度 .1812 → --text 对它 3.81  ✗ 不达 AA

       也就是说：**这个亮度是为当前素材调的，不再是对任意素材都成立的
       上界。** 换视频素材必须重测标题区的平均亮度（做法见 NOTES）。
       上一版 68% 是按纯白帧取的，安全但画面发闷。

       另外：这里能放到 55%，前提是 hero 里的文字全部是不透明的
       --c-text。之前那版用 88% 透明度，同样亮度下会再掉一档。 */
    background:
      linear-gradient(180deg, transparent 0, transparent 64%, var(--bg) 100%),
      radial-gradient(92% 86% at 50% 46%,
        color-mix(in srgb, transparent, var(--c-ink) 55%) 0 42%,
        color-mix(in srgb, transparent, var(--c-ink) 62%) 76%,
        color-mix(in srgb, transparent, var(--c-ink) 72%) 100%);
  }

  /* 视频底上不用 --text-mute（对 55% ink 只有 1.9），也不用半透明 ——
     全部走不透明的 --c-text，把对比度的余量留给 scrim。 */
  .a2e-mhero--full .a2e-mhero__sub,
  .a2e-mhero--full .a2e-mhero__others-title,
  .a2e-mhero--full .a2e-pill {
    color: var(--c-text);
  }
  .a2e-mhero--full .a2e-pill { border-color: color-mix(in srgb, transparent, var(--c-text) 30%); }
  .a2e-mhero--full .a2e-pill:hover { color: var(--accent); border-color: var(--glass-border); }
  /* 通栏形态下辉光只留一圈内边，不再画描边（没有卡片边界了）。 */
  .a2e-mhero--full .a2e-mhero__glow {
    box-shadow: inset 0 0 160px 20px color-mix(in srgb, transparent, var(--accent) 10%);
  }
  /* hero 铺到屏幕最顶，导航条浮在它上面（顶部时导航是透明的，
     正好透出视频）。所以文案要自己让开导航那 72px。 */
  .a2e-mhero--full .a2e-mhero__body {
    padding: calc(var(--a2e-nav-h) + 48px) var(--a2e-gutter) 72px;
  }

  /* ---- 模型 Hero ---- */
  .a2e-mhero {
    position: relative;
    padding: 40px 22px 44px;
    border-radius: var(--r-xl);
    overflow: hidden;
    background: var(--c-ink);
    box-shadow: inset 0 0 0 1px var(--line);
  }

  /* !! 必须排在 .a2e-mhero 之后。两者特异性都是 (0,1,0)，同分时靠文档
     顺序定胜负 —— 放在前面的话，基类的 border-radius / padding /
     box-shadow 会把这里的覆盖压掉，页面上就是「通栏 hero 带圆角」。 */
  .a2e-mhero--full {
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    /* 满屏。用 100svh 而不是 100vh —— 移动端浏览器的地址栏会伸缩，
       100vh 在收起状态下会把底部内容顶出屏幕。 */
    min-height: 100svh;
    display: grid;
    place-items: center;
  }
  /* 呼吸辉光：整层透明度 .62 ↔ 1，与实时数字人面板同一条 keyframe。 */
  .a2e-mhero__glow {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    animation: a2eBreathe 4.2s ease-in-out infinite;
    animation-play-state: var(--a2e-motion, running);
    box-shadow:
      inset 0 0 0 1px color-mix(in srgb, transparent, var(--accent) 40%),
      inset 0 0 90px 10px color-mix(in srgb, transparent, var(--accent) 12%);
  }
  .a2e-mhero__body {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 20px;
    max-width: 760px;
    margin: 0 auto;
  }
  .a2e-mhero__badge {
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
    padding: 6px 13px;
    border-radius: var(--r-full);
    background: color-mix(in srgb, transparent, var(--accent) 14%);
    box-shadow: inset 0 0 0 1px var(--glass-border);
    font-size: var(--fs-xs);
    line-height: 1;
    letter-spacing: .1em;
    color: var(--accent);
  }
  .a2e-mhero__badge-dot {
    width: 6px;
    height: 6px;
    border-radius: var(--r-full);
    background: var(--accent);
  }
  .a2e-mhero__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: clamp(calc(var(--fs-3xl) * 1.03), 5.4vw, calc(var(--fs-5xl) * 1.03));
    line-height: 1.06;
    letter-spacing: -.03em;
    color: var(--text);
    text-wrap: balance;
  }
  .a2e-mhero__sub {
    margin: 0;
    max-width: 56ch;
    font-size: var(--fs-md);
    line-height: var(--lh-body);
    color: var(--text-mute);
    text-wrap: pretty;
  }
  .a2e-mhero__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s-3);
    margin-top: var(--s-1);
  }
  .a2e-mhero__others {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s-2);
    width: 100%;
    margin-top: var(--s-3);
    padding-top: 18px;
    border-top: 1px solid var(--line-soft);
  }
  .a2e-mhero__others-title {
    width: 100%;
    margin-bottom: var(--s-1);
    font-family: var(--font-num);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    letter-spacing: .08em;
    color: var(--text-mute);
  }

  /* 胶囊形的次级入口。与 .a2e-btn--ghost 的区别只有圆角与内边距，
     但它成排出现且不承担主行动，所以单独一个类而不是加变体。 */
  .a2e-pill {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: var(--s-2) 14px;
    border: 1px solid var(--line);
    border-radius: var(--r-full);
    font-size: 13px;
    color: var(--text-mute);
    white-space: nowrap;
    transition: border-color .18s ease, background .18s ease, color .18s ease;
  }
  .a2e-pill:hover {
    border-color: var(--glass-border);
    background: var(--surface-2);
    color: var(--accent);
  }

  /* ---- 作品墙：两行反向跑马灯 ---- */
  .a2e-showcase { position: relative; }
  .a2e-showcase__row {
    display: flex;
    overflow: hidden;
    padding: 6px 0;
  }
  .a2e-showcase__row:hover { --a2e-mq-play: paused; }
  .a2e-showcase__group {
    display: flex;
    gap: var(--s-3);
    padding-right: var(--s-3);
  }
  .a2e-showcase__tile {
    flex: none;
    width: 220px;
  }
  /* 边缘渐隐用一层 --bg 渐变盖上去，**不用 mask-image** ——
     轨道本身是 transform，父级一带 mask 就会把子级提升为独立合成层，
     圆角裁剪当场失效（落地页图块上踩过这个坑）。 */
  .a2e-showcase__fade {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 90px;
    pointer-events: none;
  }
  .a2e-showcase__fade--l { left: 0;  background: linear-gradient(90deg, var(--bg), transparent); }
  .a2e-showcase__fade--r { right: 0; background: linear-gradient(270deg, var(--bg), transparent); }

  /* ---- 核心能力：图文交替 ---- */
  .a2e-caps {
    display: flex;
    flex-direction: column;
    gap: 44px;
  }
  .a2e-cap {
    display: grid;
    grid-template-columns: 1fr;
    gap: 18px;
    align-items: center;
  }
  .a2e-cap__text { min-width: 0; order: 2; }
  .a2e-cap__media {
    position: relative;
    margin: 0;
    min-width: 0;
    order: 1;
    aspect-ratio: 16 / 9;
    border-radius: var(--r-md);
    overflow: hidden;
  }
  .a2e-cap__idx {
    font-family: var(--font-num);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    letter-spacing: .1em;
    color: var(--accent);
  }
  .a2e-cap__title {
    margin: var(--s-3) 0 0;
    font-family: var(--font-display);
    font-size: calc(var(--fs-xl) * 1.03);
    line-height: var(--lh-tight);
    letter-spacing: -.01em;
    color: var(--text);
    text-wrap: balance;
  }
  .a2e-cap__desc {
    margin: var(--s-3) 0 0;
    max-width: 46ch;
    font-size: var(--fs-sm);
    line-height: var(--lh-body);
    color: var(--text-mute);
    text-wrap: pretty;
  }
  .a2e-cap__tags {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    margin-top: var(--s-4);
  }
  .a2e-cap__tag {
    padding: 6px 11px;
    border-radius: var(--r-sm);
    background: var(--surface);
    font-size: var(--fs-xs);
    color: var(--text-mute);
  }

  /* ---- 更多模型 ---- */
  .a2e-models {
    display: grid;
    grid-template-columns: 1fr;
    gap: 14px;
    margin-bottom: 22px;
  }
  .a2e-mcard {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--surface);
    overflow: hidden;
    transition: border-color .18s ease, background .18s ease;
  }
  .a2e-mcard:hover {
    border-color: var(--glass-border);
    background: var(--surface-2);
    color: var(--text);
  }
  /* 缩略图自身不给圆角，靠父级 overflow:hidden 裁 —— 上下都贴边，
     自己带圆角会在卡片角上露出一线底色。 */
  .a2e-mcard__thumb {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
  }
  .a2e-mcard__body {
    display: flex;
    flex-direction: column;
    gap: var(--s-2);
    padding: var(--s-4);
  }
  .a2e-mcard__name { font-size: var(--fs-md); color: var(--text); }
  .a2e-mcard__desc {
    font-size: 13px;
    line-height: var(--lh-body);
    color: var(--text-mute);
  }

  /* --- 时间流（/news/）--- */
  .a2e-stream[hidden] { display: none; }

  /* 月份头吸顶在控制条下方。控制条自己是 sticky top:var(--a2e-nav-h)，
     所以这里要再加上它的高度，否则两条会叠在一起。

     !! z-index 必须低于控制条（--z-pop - 2 = 18），更要低于导航（--z-pop = 20）。
        原先这里硬编码了 20，与导航同级 —— 同 z-index 时由文档顺序定胜负，
        而正文排在导航之后，于是月份头**盖住了展开的「产品」大菜单**
        （2026-08-06 用户目测发现，截图里「2026 年 2 月」压在菜单上）。
        上面 .a2e-ctrl-sec 那条注释早就写明了这个约束，这里当时没跟上。
        改用 token 相对值，以后调 --z-pop 时整组一起动。 */
  .a2e-stream__month {
    position: sticky;
    top: calc(var(--a2e-nav-h) + 66px);
    z-index: calc(var(--z-pop) - 3);
    margin: var(--s-6) 0 var(--s-4);
    padding: 7px 0;
    background: var(--bg);
    font-size: var(--fs-sm);
    letter-spacing: .06em;
    color: var(--text-mute);
  }
  .a2e-stream__list { margin: 0; padding: 0; list-style: none; }

  .a2e-stream__item {
    position: relative;
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--s-2);
    padding: 0 0 var(--s-5) var(--s-5);
  }
  /* 轴线。画在每条的左侧，最后一条截断在圆点处 —— 不截的话线会拖到
     底部空白里，看着像还有一条没加载出来。 */
  .a2e-stream__item::before {
    content: "";
    position: absolute;
    left: 5px;
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--line);
  }
  .a2e-stream__item:last-child::before { bottom: auto; height: 14px; }
  .a2e-stream__dot {
    position: absolute;
    left: 0;
    top: 7px;
    width: 11px;
    height: 11px;
    border-radius: var(--r-full);
    background: var(--accent);
    /* 描边用页面底色，让圆点把轴线"咬断" */
    box-shadow: 0 0 0 3px var(--bg);
  }
  .a2e-stream__date { font-size: var(--fs-xs); color: var(--text-mute); }
  .a2e-stream__body { min-width: 0; }
  .a2e-stream__title {
    margin: 0;
    font-size: var(--fs-md);
    line-height: var(--lh-tight);
    color: var(--text);
  }
  .a2e-stream__title a { transition: color .18s ease; }
  .a2e-stream__title a:hover { color: var(--accent); }
  .a2e-stream__desc {
    margin: 7px 0 0;
    font-size: var(--fs-sm);
    line-height: var(--lh-body);
    color: var(--text-mute);
  }
  /* 缩略图窄屏隐藏 —— 220px 的图挤进 375px 视口只会把标题压成两三个字一行。 */
  .a2e-stream__thumb { display: none; }


  /* ==========================================================
     13 · 文章详情页
     ========================================================== */

  /* 文章页整体收窄。落地页版心是 1320，但长文页不该用满 ——
     标题、封面、正文三者要左对齐成一条边，否则正文限在 760px、
     上面的标题却铺到 1320，右边会空出三百多像素的"缺口"。
     200(目录) + 56(gap) + 760(正文) = 1016，取 1040 留一点余量。 */
  .a2e-article { max-width: 1040px; }
  .a2e-lp--article .a2e-sec { max-width: calc(1040px + var(--a2e-gutter) * 2); margin-inline: auto; }

  .a2e-chip {
    display: inline-flex;
    align-items: center;
    padding: 5px 11px;
    border-radius: var(--r-sm);
    background: var(--surface-2);
    font-size: var(--fs-xs);
    color: var(--text-mute);
  }

  .a2e-article__head { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-3); }
  .a2e-article__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: clamp(var(--fs-2xl), 4vw, var(--fs-4xl));
    line-height: 1.12;
    letter-spacing: -.03em;
    color: var(--text);
    text-wrap: balance;
  }
  .a2e-article__lede {
    margin: 0;
    max-width: 62ch;
    font-size: var(--fs-md);
    line-height: var(--lh-body);
    color: var(--text-mute);
  }
  .a2e-article__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-2);
    font-size: var(--fs-xs);
    color: var(--text-mute);
  }
  .a2e-article__dot { opacity: .5; }
  .a2e-copy {
    padding: 5px 11px;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--text-mute);
    font-family: inherit;
    font-size: var(--fs-xs);
    cursor: pointer;
    transition: border-color .18s ease, color .18s ease;
  }
  .a2e-copy:hover { border-color: var(--glass-border); color: var(--accent); }
  /* 复制成功的反馈走原生属性，文案在 CSS 里 —— JS 只翻属性不写文字。 */
  .a2e-copy[data-copied] { color: var(--accent); border-color: var(--accent); }
  .a2e-copy[data-copied]::after { content: " ✓"; }

  .a2e-article__cover {
    margin: var(--s-6) 0 0;
    overflow: hidden;
    border-radius: var(--r-md);
    background: var(--surface-2);
  }
  .a2e-article__cover img { width: 100%; height: auto; display: block; }

  .a2e-article__body { display: grid; grid-template-columns: 1fr; gap: var(--s-6); margin-top: var(--s-6); }

  /* --- 侧边目录 --- */
  /* 28 篇里 16 篇正文完全没有小标题，那些页面这一块整个不渲染，
     正文用 --wide 占满。所以别把两列写死在 .a2e-article__body 上。 */
  .a2e-toc__toggle {
    display: block;
    width: 100%;
    min-height: 48px;
    padding: 0 var(--s-3);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: transparent;
    color: var(--text);
    font-family: inherit;
    font-size: var(--fs-sm);
    text-align: left;
    cursor: pointer;
  }
  .a2e-toc__list {
    display: none;
    margin: var(--s-2) 0 0;
    padding: 0 0 0 var(--s-3);
    list-style: none;
    border-left: 1px solid var(--line);
  }
  .a2e-toc__toggle[aria-expanded="true"] + .a2e-toc__list { display: block; }
  .a2e-toc__item a {
    display: block;
    padding: 7px 0 7px var(--s-3);
    margin-left: calc(var(--s-3) * -1 - 1px);
    border-left: 2px solid transparent;
    font-size: var(--fs-sm);
    line-height: var(--lh-tight);
    color: var(--text-mute);
    transition: color .18s ease, border-color .18s ease;
  }
  .a2e-toc__item a:hover { color: var(--text); }
  .a2e-toc__item[aria-current="true"] a { border-left-color: var(--accent); color: var(--accent); }

  /* --- 正文元素全集 ---
     作用域收在 .a2e-prose 里。WP 输出的是 Gutenberg 的类名，
     这里只按标签选，不依赖 wp-block-* —— 那批类名会随编辑器版本变。 */
  .a2e-prose { min-width: 0; color: var(--text); font-size: var(--fs-md); line-height: var(--lh-body); }
  .a2e-prose > * { margin: 0 0 var(--s-4); }
  .a2e-prose > :last-child { margin-bottom: 0; }
  .a2e-prose h2, .a2e-prose h3, .a2e-prose h4 {
    margin: var(--s-6) 0 var(--s-3);
    font-family: var(--font-display);
    line-height: var(--lh-tight);
    letter-spacing: -.01em;
    color: var(--text);
    /* 锚点跳转要留出吸顶导航的高度，否则标题会被导航压住。 */
    scroll-margin-top: calc(var(--a2e-nav-h) + 38px);
  }
  .a2e-prose h2 { font-size: var(--fs-xl); }
  .a2e-prose h3 { font-size: var(--fs-lg); }
  .a2e-prose h4 { font-size: var(--fs-md); color: var(--text-mute); }
  .a2e-prose p { margin: 0 0 var(--s-4); }
  .a2e-prose a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
  .a2e-prose strong { color: var(--text); }
  .a2e-prose ul, .a2e-prose ol { margin: 0 0 var(--s-4); padding-left: 1.4em; }
  .a2e-prose li { margin: 0 0 var(--s-2); }
  .a2e-prose li::marker { color: var(--text-mute); }
  .a2e-prose blockquote {
    margin: var(--s-5) 0;
    padding: var(--s-2) 0 var(--s-2) var(--s-4);
    border-left: 2px solid var(--accent);
    color: var(--text-mute);
  }
  .a2e-prose code {
    padding: 2px 6px;
    border-radius: var(--r-xs);
    background: var(--surface-2);
    font-family: var(--font-num);
    font-size: .92em;
  }
  /* 代码块横向滚动 —— 窄屏下不换行，让它自己滚，别把版心撑破。 */
  .a2e-prose pre {
    overflow-x: auto;
    padding: var(--s-4);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: var(--surface);
    font-family: var(--font-num);
    font-size: var(--fs-sm);
    line-height: 1.6;
  }
  .a2e-prose pre code { padding: 0; background: none; }
  /* 表格同理，套一层滚动容器由 JS 加不了（正文是 WP 出的），
     所以直接给 table 一个 display:block + overflow。 */
  .a2e-prose table {
    display: block;
    overflow-x: auto;
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-sm);
  }
  .a2e-prose th, .a2e-prose td {
    padding: 10px var(--s-3);
    border: 1px solid var(--line-soft);
    text-align: left;
  }
  .a2e-prose th { background: var(--surface-2); color: var(--text); }
  .a2e-prose img { max-width: 100%; height: auto; border-radius: var(--r-sm); display: block; }
  .a2e-prose figure { margin: var(--s-5) 0; }
  .a2e-prose figcaption { margin-top: var(--s-2); font-size: var(--fs-xs); color: var(--text-mute); }
  /* WP 会给块级元素塞内联 style（对齐、字号、颜色）。契约禁的是**我们**
     写内联，编辑器出的那些管不了，但可以把最伤的两类压回来。 */
  .a2e-prose [style*="max-width"] { max-width: 100% !important; }

  /* --- 提示框（三档）---
     设计稿「正文元素全集」里列了三档提示框，此前一直没落地。信息页
     （用户协议 / 隐私政策）各有一个「【提示条款】/【特别提示】」的强调段，
     原先只是个 h4，与普通小标题无异，读者扫不到。

     色位沿用时间流变更类型那套，不新造：
       note  --info(peri)    一般说明
       warn  --warn(amber)   需要注意
       key   --accent(mint)  必读条款
     左边一条 3px 竖线 + 同色 8% 的底，亮色只出现在竖线上，
     不铺满整块 —— 大面积亮底配深字在长文里刺眼。 */
  .a2e-note {
    margin: var(--s-5) 0;
    padding: var(--s-4) var(--s-4) var(--s-4) var(--s-5);
    border-left: 3px solid var(--info);
    border-radius: 0 var(--r-sm) var(--r-sm) 0;
    background: color-mix(in srgb, var(--info) 8%, transparent);
  }
  .a2e-note > :first-child { margin-top: 0; }
  .a2e-note > :last-child { margin-bottom: 0; }
  .a2e-note__t {
    margin: 0 0 var(--s-2);
    font-size: var(--fs-sm);
    font-weight: 600;
    line-height: var(--lh-tight);
    color: var(--info);
  }
  .a2e-note--warn { border-left-color: var(--warn); background: color-mix(in srgb, var(--warn) 8%, transparent); }
  .a2e-note--warn .a2e-note__t { color: var(--warn); }
  .a2e-note--key  { border-left-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }
  .a2e-note--key .a2e-note__t { color: var(--accent); }

  /* --- 视觉隐藏（工具类）---
     给屏幕阅读器与搜索引擎留语义，但不占视觉空间。原先隐私政策页是把这
     一整套写成内联 style，光 !important 就 9 个（position/width/height/
     padding/margin/clip/white-space/border）—— 内联样式压不过任何选择器，
     只能靠 !important 自保。收成类之后一个都不需要。

     !! 用 clip-path 而不是老的 clip:rect()，且保留 1px 尺寸而非
        display:none —— 后者会让屏幕阅读器一起跳过，语义就白留了。 */
  .a2e-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  /* --- 上一篇 / 下一篇 --- */
  .a2e-pn-row { display: grid; grid-template-columns: 1fr; gap: var(--s-3); margin-top: var(--s-7); }
  .a2e-pn {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: var(--s-4);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    transition: border-color .18s ease, background .18s ease;
  }
  .a2e-pn:hover { border-color: var(--glass-border); background: var(--surface); }
  .a2e-pn__k { font-size: var(--fs-xs); color: var(--text-mute); }
  .a2e-pn__t { font-size: var(--fs-sm); line-height: var(--lh-tight); color: var(--text); }
  .a2e-pn--next { text-align: right; }

  /* --- 相关文章 / 教程列表卡片 --- */
  .a2e-rel-row { display: grid; grid-template-columns: 1fr; gap: var(--s-4); }
  /* !! 卡片内部用 subgrid，让「媒体 / 日期 / 标题」三行跨卡片对齐。
        封面画幅不统一时这是必须的：学习教程那 8 张里 MCP 那张是 3.76:1、
        其余是 2.38:1，媒体高度差 58px，用 flex 排的话后两行整体上移
        58px，一眼就看出没对齐。subgrid 让每一行取同排最高的那个，
        图片仍按自己的比例渲染、不裁切。
        降级：不支持 subgrid 的浏览器回退成普通 grid，即当前这种未对齐
        的样子 —— 不会坏，只是不齐。Chrome 117+ / Safari 16+ / FF 71+。 */
  .a2e-rel {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 3;
    gap: var(--s-2);
    min-width: 0;
  }
  /* 画幅同 .a2e-work 一样由页面注入，默认 16/9。相关文章那三张是 16:9，
     学习教程列表的封面实测全是 760×320（2.38:1）与 768×204（3.76:1）——
     塞进 16:9 会把横条上下各裁掉约三成。这已是第三次撞上「设计稿的画幅
     假设与真实素材不符」（落地页瀑布流、/case/ 都栽过），所以不写死。 */
  .a2e-rel__media {
    display: block;
    aspect-ratio: var(--a2e-ratio, 16 / 9);
    overflow: hidden;
    border-radius: var(--r-sm);
    background: var(--surface-2);
  }
  .a2e-rel__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform var(--a2e-dur, .28s) var(--a2e-ease);
  }
  .a2e-rel:hover .a2e-rel__media img { transform: scale(var(--a2e-lift, 1.06)); }
  .a2e-rel__cat { font-size: var(--fs-xs); color: var(--text-mute); }
  .a2e-rel__title {
    font-size: var(--fs-sm);
    line-height: var(--lh-tight);
    color: var(--text);
    transition: color .18s ease;
  }
  .a2e-rel:hover .a2e-rel__title { color: var(--accent); }


  /* ---- 底部 CTA，四套模板共用 ----
     两种排布：列表页是「标题在左、按钮在右」一行摊开；模型详情页是居中一柱。
     !! 一度写成两条同名 .a2e-cta（一条在列表页那节、一条在这里），
        特异性相同、靠文档顺序决胜，结果列表页那版被这版整个盖掉。
        合成基类 + --center 变体。 */
  .a2e-cta {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 22px;
    padding: 34px 22px;
    border-radius: var(--r-lg);
    background: linear-gradient(180deg, var(--c-violet), color-mix(in srgb, var(--c-violet), black 30%));
  }
  .a2e-cta--center {
    flex-direction: column;
    justify-content: center;
    text-align: center;
    gap: 18px;
  }
  .a2e-cta__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: clamp(var(--fs-xl), 3.2vw, var(--fs-3xl));
    line-height: 1.15;
    letter-spacing: -.02em;
    color: var(--c-text);
    text-wrap: balance;
  }
  .a2e-cta--center .a2e-cta__title {
    max-width: 22ch;
    font-size: clamp(calc(var(--fs-xl) * 1.03), 4vw, calc(var(--fs-4xl) * 1.03));
    line-height: 1.1;
  }
  .a2e-cta__go { white-space: nowrap; }
  .a2e-cta__desc {
    margin: 0;
    max-width: 48ch;
    font-size: var(--fs-sm);
    line-height: var(--lh-body);
    color: color-mix(in srgb, transparent, var(--c-text) 78%);
  }

  /* ---- 次级区块标题 ----
     比主区块的 h2 小一档，用裸 token 而不是 clamp。设计稿刻意这么分的。 */
  .a2e-sec__title--sub {
    display: block;
    margin-bottom: var(--s-6);
    font-size: calc(var(--fs-xl) * 1.03);
    color: var(--text);
  }

  /* ---- 模型详情页的断点 ----
     只有一档 768（设计稿把 1024/1280 的差异改用 flex 换行表达）。 */
  /* 内容装得下的那一面（图生视频 12 块，内容 566px）。
     唇形同步是 16 块、内容 1801px，被固定高 760px 裁掉大半，底部渐隐是
     「下面还有」的提示；这一面没得裁，直接套 760px 会在底下空出 194px，
     渐隐落在空气里、按钮浮在空气上。

     所以高度改成跟内容走，遮罩照旧。渐隐会吃掉最后一排的下缘 ——
     这是**要的**，唇形同步那面就是这个样子。
     !! 别再往下加 padding 当「渐隐跑道」。试过 48px 和 104px：盒底被推到
        所有内容之下，渐隐落在空气里，按钮也从图块上掉下去、和上面完全分开。
        按钮是 bottom:34px 的绝对定位，盒底在哪它就在哪。 */
  .a2e-gallery__cols--fit {
    height: auto;
  }

  /* 文生图只有 6 块。断点在 1280 以上给的是 4 列，6 块分成 2/2/1/1，
     底边参差得离谱；压到 3 列正好每列 2 块。
     !! 必须裹在 min-width:1280 里 —— 1024–1279 本来就是 3 列，
        写在外面会把移动端的 2 列也顶成 3 列。 */
  @media (min-width: 1280px) {
    .a2e-gallery__cols--trio { --a2e-gallery-n: 3; }
  }

  @media (min-width: 768px) {
    /* 文章页：目录左栏 200px + 正文。没有目录的那 16 篇走 --wide 单列。 */
    .a2e-article__body { grid-template-columns: 200px minmax(0, 1fr); gap: var(--s-7); }
    .a2e-article__body--wide { grid-template-columns: minmax(0, 1fr); }
    /* !! 目录必须自己能滚。文章页那 12 篇最多 8 条小标题，一屏放得下；
          信息页不一样 —— 用户协议 23 条、隐私政策 18 条，按每条约 30px 算
          就是 690px / 540px，笔记本上直接超出视口，sticky 会把末尾几条
          永久推到屏幕外点不到。留 76px 给上下留白。 */
    .a2e-toc {
      position: sticky;
      top: calc(var(--a2e-nav-h) + 38px);
      align-self: start;
      max-height: calc(100vh - var(--a2e-nav-h) - 76px);
      overflow-y: auto;
      overscroll-behavior: contain;
    }
    .a2e-toc__toggle { display: none; }
    .a2e-toc__list { display: block; }
    /* 中文一行约 40 字。再宽扫读时回行会找错位置。 */
    .a2e-prose { max-width: 760px; }

    .a2e-pn-row { grid-template-columns: 1fr 1fr; }
    .a2e-rel-row { grid-template-columns: repeat(3, minmax(0, 1fr)); }

    /* 时间流三列：日期 128px / 轴 22px / 内容。缩略图在最右侧。 */
    .a2e-stream__item {
      grid-template-columns: 128px 1fr auto;
      align-items: start;
      gap: 0 var(--s-4);
      padding-left: 0;
    }
    .a2e-stream__item::before { left: 139px; }
    .a2e-stream__dot { left: 134px; top: 6px; }
    .a2e-stream__date { padding-top: 2px; text-align: right; }
    .a2e-stream__thumb {
      display: block;
      width: 220px;
      aspect-ratio: 16 / 9;
      overflow: hidden;
      border-radius: var(--r-xs);
      background: var(--surface-2);
    }
    /* 特色图原始比例很杂（2.38 x17 / 1.78 x6 / 1.33 / 3.76 / 1.0），
       统一裁进 16:9 盒。 */
    .a2e-stream__thumb img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      display: block;
      transition: transform var(--a2e-dur, .28s) var(--a2e-ease);
    }
    .a2e-stream__thumb:hover img { transform: scale(var(--a2e-lift, 1.06)); }

    .a2e-mhero { padding: 76px 64px; }
    /* 断点里的这条排在 --full 之后，同样会把它的 padding:0 压掉，
       所以要在这里再声明一次。同一个坑的第二处。 */
    .a2e-mhero--full { padding: 0; }
    .a2e-showcase__tile { width: 300px; }

    .a2e-caps { gap: 72px; }
    .a2e-cap {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
      gap: 48px;
    }
    .a2e-cap__text  { order: 1; }
    .a2e-cap__media { order: 2; }
    /* 奇偶行左右互换 */
    .a2e-cap:nth-child(even) .a2e-cap__text  { order: 2; }
    .a2e-cap:nth-child(even) .a2e-cap__media { order: 1; }

    .a2e-models { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .a2e-cta { padding: 64px 40px; }
  }
}
