/*! AoyunBuilt — 墙体爆炸图滚动组件样式 wall-explode.css  v3.4 */
.axb-wall { position: relative; display: block; width: 100%; background: #14161a; }
/* 顶部图例带独占一行 + 模型居中其下：flex 列布局（v3.0 是图例绝对定位压在模型左下角） */
.axb-sticky {
  position: sticky; top: 0; height: 100vh; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1.4vh; padding: 1.6vh 0;
}
/* 画布锁死 2600:1300，高度用宽度反推（min(100%,158vh) → 高 ≤79vh，给顶部图例带留位）。
   ⚠️ 不要用 max-height 压：flex 列布局里 max-height 会把画布压扁（比例失真）。 */
.axb-canvas {
  position: relative; width: min(100%, 158vh); aspect-ratio: 2600 / 1300;
  transform-origin: 50% 50%; will-change: transform;
}
.axb-canvas > .axb-layer { position: absolute; inset: 0; }
.axb-canvas > .axb-layer > img { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* 编号徽章（贴在各层阶梯带上） */
.axb-badge {
  position: absolute; transform: translate(-50%, -50%);
  font: 700 clamp(11px, 1.05vw, 19px)/1 "Segoe UI", "Microsoft YaHei", sans-serif;
  color: #fff; background: #2B4C7E; border: 1.5px solid #fff; border-radius: 999px;
  padding: .34em .62em; opacity: 0; transition: opacity .25s linear; pointer-events: none;
  box-shadow: 0 1px 6px rgba(0,0,0,.35);
}

/* 顶部图例带：6 组按行优先排 3 列 ×2 行（与 hero 出图完全一致） */
.axb-legend {
  flex: 0 0 auto; align-self: stretch; box-sizing: border-box;
  background: rgba(12,14,18,.86); border: 1px solid rgba(140,148,160,.30);
  border-radius: .9em; padding: .85em 1.15em;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .3em 1.6em;
  /* ⚠️⚠️ 定高 flex 容器里的 Grid，auto 行会被**压缩到装得下为止** → 两行文字互相重叠。
      Edge headless 实测：01/02/03 那行被 04/05/06 那行的英文压住。必须显式指定行高下限。 */
  grid-auto-rows: min-content;
  align-content: start;
  min-height: min-content;
}
.axb-legend-row { display: flex; align-items: baseline; gap: .7em; margin: 0; min-width: 0; }
.axb-legend-code {
  flex: 0 0 auto;
  font: 700 clamp(11px, 1.0vw, 18px)/1 "Segoe UI", sans-serif; color: #fff;
  background: #2B4C7E; border: 1px solid #fff; border-radius: 999px;
  padding: .3em .55em; min-width: 2.1em; text-align: center;
}
.axb-legend-text { min-width: 0; }
.axb-legend-text b { display: block; font: 600 clamp(11px, .95vw, 17px)/1.35 "Segoe UI", sans-serif; color: #fff; }
.axb-legend-text i { display: block; font: 400 clamp(11px, .9vw, 16px)/1.35 "Microsoft YaHei", sans-serif; color: #c6cace; font-style: normal; }

@media (max-width: 900px) {
  /* 窄屏：图例改单列，并让出更多高度给模型 */
  .axb-legend { grid-template-columns: 1fr; padding: .7em .85em; }
  .axb-canvas { width: min(100%, 140vh); }
}

/* ══════════════════════════════════════════════════════════════════════════
   任务书 14 · Lane A 追加 —— 本轮所有新增样式都写在这里
   （⛔ 不写 assets/css/site.css：该文件由另一路并行任务占用）
   ① 位移过渡：层与徽章同一条曲线，滚动位移变成「轻微跟随」，不再逐帧硬跟
   ② 层表与爆炸图左右并排（.wallgrid）
   ③ 点击联动焦点态（data-focus → .is-focus）
   ══════════════════════════════════════════════════════════════════════════ */

/* ① 位移过渡 —— 徽章与所属层必须用同一条过渡曲线，否则会不同步错位。
      注：.axb-badge 原有的 opacity 淡入保留，所以写成两条过渡而不是覆盖掉 opacity。
      2026-09-21 按 Hank 反馈调参（「丝滑的基础上，速度再快一点，加一点弹性」）：
        · 时长 .45s → .30s（更跟手、位移更快到位）
        · 曲线由纯 ease-out 换成**轻微 overshoot**：终点超出约 5~6% 再回落 → 弹性手感
        · 层与徽章两条曲线必须仍然一致，改一条就要同步另一条 */
.axb-layer { transition: transform .3s cubic-bezier(.32,1.42,.55,1); }
.axb-badge { transition: opacity .25s linear, transform .3s cubic-bezier(.32,1.42,.55,1); }

/* ② 左右并排：左栏＝滚动舞台（组件自身 getBoundingClientRect 驱动的进度逻辑未改），
      右栏＝层表 / 说明卡 / 图注，sticky 跟随；.sec-head 仍在两栏之上、整宽。 */
.wallsec .wallgrid{display:grid;grid-template-columns:minmax(0,1.95fr) minmax(0,1fr);gap:30px;align-items:start;padding:0 var(--gut) 46px}
.wallsec .wallgrid-side{position:sticky;top:88px}
.wallsec .wallgrid-visual .axb-canvas{width:min(100%,96vh)}      /* 覆盖组件默认 min(100%,158vh) */
@media (max-width:1180px){
  /* ⚠️ 2026-09-20 移动端 Phase 3 修正（第二处潜伏 bug）：
     原为 `1fr`，而 `1fr` = `minmax(auto,1fr)`，`auto` 最小值 = 该栅格项的 **min-content**。
     右栏层表（min-content 110px）与图层滑块的 min-content 会把整列撑宽 —— 实测 320 视口下
     文档被撑到 839px（`.wallgrid-visual` 计算 min-width 仍是 auto，宽 824.5px）。
     左栏原本写的是 `minmax(0,1.95fr)`（显式 0 最小值），此处口径不一致。
     改 `minmax(0,1fr)` 才能真正允许收缩。 */
  .wallsec .wallgrid{grid-template-columns:minmax(0,1fr)}
  .wallsec .wallgrid-side{position:static}
  .wallsec .wallgrid-visual .axb-canvas{width:min(100%,140vh)}
}

/* ③ 焦点态：站点 JS 点层表行 → 根节点 data-focus，非选中层压暗。
      transition 里带上 transform，避免选中期间滚动位移又变回逐帧硬跟。 */
.axb-wall[data-focus] .axb-layer{opacity:.30;transition:opacity .35s ease,transform .3s cubic-bezier(.32,1.42,.55,1)}
.axb-wall[data-focus] .axb-layer.is-focus{opacity:1}

/* reduced-motion：组件本身已有 reduce 分支（matchMedia → opt.reduce），过渡同样让位。
   ⚠️ 不新增 data-* 属性，顺着既有分支用媒体查询表达。 */
@media (prefers-reduced-motion: reduce) {
  .axb-wall .axb-layer, .axb-wall .axb-badge,
  .axb-wall[data-focus] .axb-layer { transition: none; }
}

/* 徽章要能点选（组件默认 pointer-events:none，会挡住刚加的 click 处理） */
.axb-badge { pointer-events: auto; }

/* ══════════════════════════════════════════════════════════════════════════
   任务书 24 · Lane B —— 舞台在前 / 徽章锚定「层中心」/ 右列表格并入深色区
   （⛔ 依旧不写 assets/css/site.css：该文件由另一路并行任务占用）
   ══════════════════════════════════════════════════════════════════════════ */

/* ① 图例带挪到舞台「下方」—— 它现在只与舞台相邻，故「图例带 ↔ 舞台」间距＝固定 22px
      （.axb-sticky 的 gap 归零，改由 margin-top 精确表达，不再叠加 1.4vh）。
      图例仍是 6 组、两行三列（原有 grid 规则未动）。 */
.axb-sticky { gap: 0; }
.axb-legend { margin-top: 22px; }

/* ② 徽章基位：水平＝画布中心，垂直＝画布高度的 38%（在窗洞上沿之上）。
      每帧的 left/top 由 update() 按 canvasW / canvasH 写入（与层位移同源），这里只是 CSS 兜底，
      避免 update() 之前闪现在画布左上角；奇偶 ±6px 的纵向交错写在 update() 的 transform 里。 */
.axb-badge { left: 50%; top: 38%; }

/* ③-a 右列表格列宽：三列定宽，第三列（我们怎么控制）自动占满剩余；
        字号 13.5px、行高 1.75、td 内边距 10px 12px。 */
.wallsec .spec { font-size: 13.5px; table-layout: fixed; width: 100%; }
.wallsec .spec th:first-child, .wallsec .spec td.k { width: 54px; padding: 10px 8px; text-align: center; }
.wallsec .spec th:nth-child(2), .wallsec .spec td:nth-child(2) { width: 164px; }
.wallsec .spec td { padding: 10px 12px; line-height: 1.75; }

/* ③-b 深色区表格配色：去掉白底（site.css 里 `.wallsec .spec td.k{background:#FBFCFD}` 一类白底规则
        特异性不高于本文件、且 site.css 先加载 → 本文件后置的同名规则直接生效），
        表格与 .wallsec 的 #14161a 融为一体；选中行仍靠「左侧 3px 钢蓝条 + 轻微提亮」清晰可见。 */
.wallsec .spec th { background: rgba(255,255,255,.07); color: #DCE7F5; border-color: rgba(255,255,255,.12); }
.wallsec .spec td { background: transparent; color: #E6EDF6; border-color: rgba(255,255,255,.10); }
.wallsec .spec td.k { background: rgba(255,255,255,.05); color: #BFD4EA; }
.wallsec .spec tr.sel td { background: rgba(255,255,255,.10); }
.wallsec .spec tr.sel td.k { background: rgba(255,255,255,.14); color: #fff; box-shadow: inset 3px 0 0 0 var(--steel); }
/* 悬停同样不留白：site.css 的 `tr[data-layer]:hover td.k{background:#F1F5F9}` 会在鼠标经过时闪出白块 */
.wallsec .spec tr[data-layer]:hover td.k { background: rgba(255,255,255,.09); color: #fff; }

/* ══════════════════════════════════════════════════════════════════════════
   任务书 34 —— 舞台内容顶对齐（配合任务书 30b：爆炸图整节提到整屋交付页最顶）
   实测（1440×1000，scroll 0）：.axb-sticky 高 100vh，原 justify-content:center
   把画布推到 stage_top+184px（画布 top=777），页面首屏只剩一大片空黑，看不到墙体。
   改为顶对齐 + 9vh 上内边距：
     · 未吸顶时画布 top ≈ stage_top+90（首屏即见墙体上半段）
     · 吸顶后画布 top = 90px，仍在固定导航条（约 64–88px）之下，不被压住
   ══════════════════════════════════════════════════════════════════════════ */
.axb-sticky { justify-content: flex-start; padding: 9vh 0 1.6vh; }

/* ══════════════════════════════════════════════════════════════════════════
   任务书 38 —— 编号永不被层盖住 / 层可点 / 选中后只保留对应编号
   ① .axb-layer 有显式 z-index 1…6，徽章没有 → 编号会被层图盖住（实测 02 被保温棉压住）。
   ② 徽章 opacity 由组件每帧写内联样式，CSS 想盖住必须 !important。
   ══════════════════════════════════════════════════════════════════════════ */
.axb-badge { z-index: 99; }
.axb-layer { cursor: pointer; }
/* 选中态（站点 JS 写入 data-focus）：只保留对应编号，其余编号隐藏 */
.axb-wall[data-focus] .axb-badge { opacity: 0 !important; }
.axb-wall[data-focus] .axb-badge.is-sel { opacity: 1 !important; }

/* ══════════════════════════════════════════════════════════════════════════
   任务书 43 —— 图例瘦身 + 爆炸图放大（用户 rev7 反馈：图例占比太大、留给爆炸图的空间小）
   ⚠️ 画布比例由 wall-explode.js 内联写入（canvas.style.aspectRatio = CANVAS_W/CANVAS_H），
      本文件不能改比例，只负责框内摆放；比例改动 = JS 的 CANVAS_H 1300 → 1700（画布变高）。
   ══════════════════════════════════════════════════════════════════════════ */

/* ① 层图改 cover：画布变高后图片按高度铺满，左右只裁透明边
      （层图 2600×1300 里墙体仅占宽 866px，两边全是空白）。
      效果：墙体渲染 ≈ 293×415 → ≈ 401×568（+37%），不再被 2:1 画布高度锁死。 */
.wallsec .axb-canvas > .axb-layer > img { object-fit: cover; }

/* ② 栏比回退到原值 1.95fr：2.25fr 会把右栏层表压窄（409px）→ 英文长文案换行变多，
      实测表高 1093px > 视口 1000px，第 06 行与图注掉到折线以下。图更大的目标改由画布高度实现。

   ⚠️ 2026-09-20 移动端 Phase 3 修正：本行原为**无条件规则**，且位置又在上方
      `@media (max-width:1180px){.wallsec .wallgrid{grid-template-columns:1fr}}` **之后** ——
      同特异性、后来者胜 → 等于把「窄屏单列」整个覆盖掉，.wallgrid 在任何宽度都是 2 列。
      桌面期看不出来（body 有 min-width:1024，窄屏规则本就不触发）；移动端解除锁定后
      立即暴露为 kit-homes @320 的 7px 横向溢出（右栏层表 min-content 110px > 该列 89px）。
      改为只在 >1180 生效，恢复原作者「窄屏单列」的本意。 */
@media (min-width:1181px){
  .wallsec .wallgrid { grid-template-columns: minmax(0,1.95fr) minmax(0,1fr); }
}

/* ③ 图例瘦身：3 列两行结构不变，徽章/字号/行距/内边距整体降一档（高约 90px → 55px），
      从「压在图上的大卡片」退回「图下的说明条」。 */
.wallsec .axb-legend { margin-top: 14px; padding: .5em .8em; border-radius: .7em; gap: .22em 1.1em; }
.wallsec .axb-legend-row { gap: .5em; align-items: center; }
.wallsec .axb-legend-code { font-size: clamp(10px, .78vw, 14px); padding: .24em .45em; min-width: 1.9em; }
.wallsec .axb-legend-text b { font-size: clamp(11px, .84vw, 15px); line-height: 1.25; }
html[data-lang] .wallsec .axb-legend-text i { font-size: clamp(10.5px, .8vw, 14px); line-height: 1.25; }

/* ── 任务书 44：画布比例再抬高（JS CANVAS_H 1700 → 2000，本文件不能改比例）。
     层图 cover 按高度铺满 → 墙体渲染 ≈ 293×415（原始）→ ≈ 450×638（+54%）。
     栏比已回退见上方 ② 注释。 ── */

/* ══════════════════════════════════════════════════════════════════════════
   移动端 Phase 3 · 增量 4（2026-09-21）—— 窄屏形态：逐层剥离竖屏舞台
   JS 在 ≤900px 时改走 buildPeel()：不建 .axb-sticky / .axb-canvas / .axb-legend，
   改建 .axb-peel（sticky 舞台）＝ 画框 + 编号条 + 读数条 + 收尾卡。
   （原 .axb-swipe / .axb-sl* 横向分层卡规则已随之移除）

   为什么换掉卡片（实测，非偏好）：卡片是 6 张**孤立**的图 —— 看不到层序与层间关系。
   手机上的问题不是「缺装饰」而是「丢了语义」。

   关键量（与 JS 同源；改一处必须同步另一处）：
     · 裁切窗口 866:1227；层图放大 300.231% + 平移 (-33.3462%, -2.8462%)
     · 剥离方向 = 3D 相机真实投影（JS 用 UNIT.y/UNIT.x = 0.1387）
     · 剥离顺序 06→02；**01 不剥**
   ⚠️ 所有位移量按**画框宽**算（JS 的 fw），不乘画布比例 —— 窄屏画布只有 187px 高、
     位移系数 k≈0.14，换不来观感（这正是原卡片形态的立论依据，不要退回画布方案）。
   ══════════════════════════════════════════════════════════════════════════ */
.axb-wall.is-narrow { background: #14161a; }
.axb-peel {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  gap: 12px;
  /* 顶部避让站点吸顶条 .topbar（实测 56px —— 样张里没有这条，落站必须加，否则画框被压住）*/
  padding: calc(56px + 10px + env(safe-area-inset-top)) 16px calc(12px + env(safe-area-inset-bottom));
  overflow: hidden;
}
/* 舞台底纹：极淡工程网格，随剥离度略增强（不抢内容）*/
.axb-peel::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(120,150,190,.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(120,150,190,.055) 1px, transparent 1px);
  background-size: 32px 32px;
  -webkit-mask-image: radial-gradient(ellipse 78% 62% at 50% 44%, #000 42%, transparent 100%);
  mask-image: radial-gradient(ellipse 78% 62% at 50% 44%, #000 42%, transparent 100%);
  opacity: calc(.55 + .45 * var(--axb-peel, 0));
}
/* 画框：锁死裁切窗口比例 866:1227。
   ⚠️ 高宽比不能压扁（子图裁切量按它算）→ 短屏只能整体缩小，用 max-width 同时受
   「可用宽度」和「可用高度」约束；第二行覆盖第一行，不支持 svh 的环境退回 360。 */
.axb-peel-frame {
  position: relative; width: 100%; max-width: 360px;
  max-width: min(360px, calc((100svh - 275px) / 1.417));
  aspect-ratio: 866 / 1227;
  touch-action: pan-y; cursor: grab;
  transform: scale(calc(1 - .035 * var(--axb-peel, 0)));
  transition: transform .35s cubic-bezier(.32,1.42,.55,1);
}
.axb-peel-frame:active { cursor: grabbing; }
.axb-peel-frame > .axb-layer { position: absolute; inset: 0; overflow: hidden; will-change: transform, opacity; }
.axb-peel-frame > .axb-layer > img {
  position: absolute; left: 0; top: 0;
  width: 300.231%; height: auto;
  max-width: none;   /* ⚠️ 必须：site.css 有 img{max-width:100%}，不加会把裁切压回整幅 */
  transform: translate(-33.3462%, -2.8462%);
  -webkit-user-drag: none; user-select: none;
}
/* 编号条（06→01，从外往内）*/
.axb-peel-rail { position: relative; z-index: 20; display: flex; gap: 6px; width: 100%; max-width: 360px; }
.axb-peel-chip {
  -webkit-appearance: none; appearance: none;
  flex: 1 1 0; min-width: 0; min-height: 44px;
  background: rgba(255,255,255,.05); color: rgba(255,255,255,.62);
  border: 1px solid rgba(255,255,255,.12); border-radius: 8px;
  font: 700 12px/1 "Segoe UI", sans-serif; letter-spacing: .02em;
  transition: background .22s, border-color .22s, color .22s, opacity .22s, transform .22s;
}
.axb-peel-chip[data-off="1"] { opacity: .32; }
.axb-peel-chip[data-front="1"] { background: #2B4C7E; border-color: rgba(255,255,255,.42); color: #fff; transform: translateY(-3px); }
.axb-peel-chip.is-sel { border-color: rgba(196,114,74,.9); color: #fff; }
.axb-peel-chip:focus-visible { outline: 2px solid #FFC987; outline-offset: 2px; }
/* 读数条：当前正面层 + 双语层名 + 已剥进度（补的是「窄屏看不到右栏层表」的语义缺口）*/
.axb-peel-hud {
  position: relative; z-index: 20; width: 100%; max-width: 360px;
  display: flex; align-items: center; gap: 10px;
  background: rgba(12,14,18,.86); border: 1px solid rgba(140,148,160,.30);
  border-radius: 10px; padding: 9px 12px;
}
.axb-peel-hcode {
  flex: 0 0 auto; min-width: 2em; text-align: center;
  background: #2B4C7E; color: #fff; border-radius: 4px;
  font: 700 11px/1 "Segoe UI", sans-serif; padding: 5px 6px;
}
.axb-peel-hud .axb-legend-text { flex: 1 1 auto; min-width: 0; }
.axb-peel-hud .axb-legend-text b { font-size: 12.5px; line-height: 1.35; }
.axb-peel-hud .axb-legend-text i { font-size: 11.5px; line-height: 1.4; color: rgba(255,255,255,.66); }
.axb-peel-prog { flex: 0 0 auto; font: 700 11.5px/1 "Segoe UI", sans-serif; color: rgba(255,255,255,.55); }
/* 收尾卡：拆完后淡入 —— ① 只剩 01 石膏板时画面留黑占比大、观感空旷（视觉复核实测）
   ② 手机上要滚 2 屏才能回到装配态 → 给一键回顶。 */
.axb-peel-done {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: calc(132px + env(safe-area-inset-bottom));
  width: min(360px, calc(100% - 32px)); z-index: 22; text-align: center;
  background: rgba(12,14,18,.92); border: 1px solid rgba(140,148,160,.30);
  border-radius: 12px; padding: 12px 14px;
  opacity: 0; pointer-events: none; transition: opacity .3s ease-out;
}
.axb-peel-done[data-on="1"] { opacity: 1; pointer-events: auto; }
.axb-peel-done-t .axb-legend-text b { display: block; font: 400 12.5px/1.5 "Segoe UI", sans-serif; color: rgba(255,255,255,.68); }
.axb-peel-done-t .axb-legend-text i { display: block; font: 400 12.5px/1.5 "Microsoft YaHei", sans-serif; color: rgba(255,255,255,.68); }
.axb-peel-reset {
  -webkit-appearance: none; appearance: none; margin-top: 10px; width: 100%; min-height: 44px;
  background: #2B4C7E; color: #fff; border: 1px solid rgba(255,255,255,.24); border-radius: 9px;
}
.axb-peel-reset .axb-legend-text b { font: 600 13.5px/1 "Segoe UI", sans-serif; }
.axb-peel-reset .axb-legend-text i { font: 600 13.5px/1 "Microsoft YaHei", sans-serif; color: #fff; }
/* 窄屏兜底：320 下 6 个编号按钮被 flex 均分挤到 40px（低于 44 点按标准）。
   ⚠️ 内边距必须收到 2px 才够：墙组件外面还有站点 section 的 gutter（实测 28px），
   两者叠加后 320 屏的可用宽只剩 264px → 6 个目标最多各 40px。
   收内边距 + 收 gap 后可到 44.6px（实测 375 下是 48×44）。 */
@media (max-width: 360px) {
  .axb-peel { padding-left: 2px; padding-right: 2px; }
  .axb-peel-rail { gap: 4px; }
}
/* 短屏横屏兜底：竖排堆叠在 375 高的横屏里会溢出 → 收紧留白换高度 */
@media (orientation: landscape) and (max-height: 560px) {
  .axb-peel { padding-top: calc(56px + 6px); gap: 8px; }
  .axb-peel-frame { max-width: calc((100svh - 190px) / 1.417); }
}
