@keyframes pulseDot {
  0%, 100% { opacity: 0.55; transform: scale(0.85); }
  50%      { opacity: 1;    transform: scale(1.15); }
}
@keyframes heroKen {
  from { transform: scale(1.06) translate3d(0, 0, 0); }
  to   { transform: scale(1.16) translate3d(-1.5%, -1.5%, 0); }
}
@keyframes heroDrift {
  from { transform: translate3d(-2%, -1%, 0) scale(1); }
  to   { transform: translate3d(2%, 2%, 0) scale(1.06); }
}
@keyframes hintSlide {
  0%, 100% { opacity: 0.3; transform: scaleY(0.55); }
  50%      { opacity: 1;   transform: scaleY(1); }
}
@keyframes shutter {
  0%   { opacity: 0; }
  18%  { opacity: 0.5; }
  100% { opacity: 0; }
}
/* ============================================================
   作品集 · 框架版 样式
   ------------------------------------------------------------
   设计手法参考 dengyuanfilm.top 的工程化 CSS 路线（非 WebGL）：
     · backdrop-filter  —— 毛玻璃导航/弹层，暗场里的高级感主要靠它
     · mask-image       —— 边缘渐隐，避免生硬的矩形边界
     · cubic-bezier     —— 自定义缓动，动作"有质感"的关键
     · @keyframes       —— 滚动提示、微光等循环动效
     · spot/radial 渐变 —— 用光斑代替纯色背景，画面不"死"
     · position:sticky  —— 滚动舞台
   分区标题一律留空，内容定好再填。
   ============================================================ */

/* ---------------- 设计变量 ---------------- */
:root {
  --bg: #0a0908;
  --bg-2: #14110c;
  --fg: #f0ece3;
  --fg-dim: rgba(240, 236, 227, 0.62);
  --fg-faint: rgba(240, 236, 227, 0.34);
  --line: rgba(240, 236, 227, 0.1);
  /* 强调色直接取自 dengyuanfilm.top 的设计变量，保证是同一套视觉语言 */
  --accent: #cfa95f;
  /* 金属三档：高光 / 本色 / 暗部。渐变靠这三档拉出金属反光 */
  --accent-hi: #f6e4b4;
  --accent-lo: #8f6f2c;
  /* 轮廓高光与发光 */
  --rim: rgba(255, 245, 214, 0.14);
  --rim-strong: rgba(255, 245, 214, 0.30);
  --glow: rgba(207, 169, 95, 0.30);
  --accent-dim: rgba(207, 169, 95, 0.15);
  --glass: rgba(20, 17, 12, 0.66);

  /* 统一动效语言：同一个缓动贯穿全站，观感才"整" */
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-io: cubic-bezier(0.65, 0, 0.35, 1);

  --pad: clamp(18px, 4vw, 64px);
  --maxw: 1240px;
  --radius: 14px;

  /* ---- 排版尺度 ----
     大标题用 clamp() 而不是固定 px：小屏不溢出、大屏有气势。
     display 给首屏，title 给分区标题，两者差一档，层级才清楚。 */
  --fs-display: clamp(40px, 8.4vw, 104px);
  --fs-title: clamp(26px, 3.4vw, 46px);
  --ls-display: 0.005em;
  --ls-eyebrow: 0.28em;

  /* ---- 间距节奏 ----
     分区上下留白统一走这一档，全站呼吸感一致；改一处就能整体调松紧。 */
  --space-sec: clamp(76px, 10vw, 148px);
  --space-head: clamp(34px, 5vw, 64px);
  --gap-card: clamp(12px, 1.5vw, 20px);

  /* ---- 圆角三档 ----
     大块用 lg、卡片用 md、小件（徽标/按钮）用 pill。
     以前全站一个 14px，大小件一样圆，看着平。 */
  --radius-lg: 18px;
  --radius-md: 14px;
  --radius-sm: 10px;

  /* ---- 阴影三档（暗色底上做纵深，靠这三档而不是纯描边） ---- */
  --sh-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --sh-2: 0 14px 34px rgba(0, 0, 0, 0.42);
  --sh-3: 0 28px 70px rgba(0, 0, 0, 0.55);

  --font: "PingFang SC", "Noto Sans SC", "Microsoft YaHei", "Hiragino Sans GB", system-ui, sans-serif;
  --font-en: "Inter", "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

/* 全站一层极淡的暗角：画面四角收一点，眼睛自然落在中间。
   固定定位 + 不吃指针事件，滚动时不动，像一块滤镜。 */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(120% 90% at 50% 45%, transparent 52%, rgba(6, 5, 4, 0.42) 100%);
}

/* 胶片颗粒：一层很淡的噪点。
   暗色网站最容易显得"平"和"塑料"，加一层颗粒立刻有质感，
   而且不占额外请求（SVG 内联成 data URI）。
   挂 html::after 而不是 body::before —— 后者已被全局光斑占用；
   而且 z-index 要高于内容层，否则被 main 盖住。 */
html::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  opacity: 0.045;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 140px 140px;
}

html {
  scroll-behavior: smooth;
  /* 锚点跳转时留出导航高度，否则标题会被导航盖住 */
  scroll-padding-top: 84px;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* 全局光斑背景：两层径向渐变，避免大片纯色显得廉价 */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(60% 40% at 15% 8%, rgba(207, 169, 95, 0.10), transparent 60%),
    radial-gradient(50% 40% at 88% 92%, rgba(207, 169, 95, 0.08), transparent 62%);
}

main, nav, footer { position: relative; z-index: 1; }

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--pad);
}

/* ---------------- 顶部导航（毛玻璃 + 滚动后收紧） ---------------- */
#nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 16px var(--pad);
  /* 关键手法：毛玻璃 + 细分割线，比纯色导航栏高级 */
  background: rgba(10, 9, 8, 0.34);
  backdrop-filter: blur(14px) saturate(150%);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  border-bottom: 1px solid transparent;
  transition: padding 0.5s var(--ease), background 0.5s var(--ease), border-color 0.5s var(--ease);
}
#nav.is-scrolled {
  padding: 11px var(--pad);
  background: rgba(10, 9, 8, 0.78);
  border-bottom-color: var(--line);
}

.logo {\n  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 9px;
  font-weight: 600;
  letter-spacing: 0.04em;
  font-size: 15px;
}
.logo .dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 12px var(--accent);
  animation: pulseDot 2.6s var(--ease-io) infinite;
}
.logo-sub { color: var(--fg-faint); font-weight: 400; font-size: 0.86em; }

/* 8 个分区后这一行很挤：禁止逐字换行，并收紧间距与字号。
   文字再长也不会把导航挤成两行 —— 宽度不够时整体交给汉堡菜单（见响应式段）。 */
.nav-links { display: flex; gap: 2px; }
.nav-links a {
  position: relative;
  padding: 7px 10px;
  font-size: 13px;
  white-space: nowrap;
  color: var(--fg-dim);
  border-radius: 999px;
  transition: color 0.35s var(--ease), background 0.35s var(--ease);
}
.nav-links a:hover { color: var(--fg); background: rgba(238, 242, 246, 0.06); }
/* 当前所在分区高亮（JS 用 IntersectionObserver 维护） */
.nav-links a.is-current { color: var(--fg); background: var(--accent-dim); }

.nav-right { display: flex; align-items: center; gap: 12px; }

.nav-cta {
  padding: 9px 18px;
  font-size: 13px;
  border-radius: 999px;
  border: 1px solid rgba(207, 169, 95, 0.42);
  color: var(--fg);
  background: rgba(207, 169, 95, 0.08);
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease), transform 0.4s var(--ease);
}
.nav-cta:hover {
  background: rgba(207, 169, 95, 0.18);
  border-color: var(--accent);
  transform: translateY(-1px);
}

.hamburger {
  display: none;
  width: 40px; height: 34px;
  padding: 7px 6px;
  background: none;
  border: 0;
  cursor: pointer;
  flex-direction: column;
  justify-content: space-between;
}
.hamburger span {
  display: block;
  height: 1.5px;
  background: var(--fg);
  transition: transform 0.4s var(--ease), opacity 0.3s var(--ease);
}
.hamburger.is-open span:nth-child(1) { transform: translateY(9px) rotate(45deg); }
.hamburger.is-open span:nth-child(2) { opacity: 0; }
.hamburger.is-open span:nth-child(3) { transform: translateY(-9px) rotate(-45deg); }

/* 移动端全屏菜单 */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 55;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  padding: 0 var(--pad);
  background: rgba(10, 9, 8, 0.94);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.45s var(--ease), visibility 0.45s;
}
.mobile-menu.is-open { opacity: 1; visibility: visible; }
.mobile-menu a {
  font-size: 26px;
  font-weight: 300;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
  transform: translateY(14px);
  opacity: 0;
  transition: transform 0.6s var(--ease), opacity 0.6s var(--ease);
}
.mobile-menu.is-open a { transform: none; opacity: 1; }
/* 菜单项依次进入，比整块淡入更有节奏 */
.mobile-menu.is-open a:nth-child(1) { transition-delay: 0.04s; }
.mobile-menu.is-open a:nth-child(2) { transition-delay: 0.08s; }
.mobile-menu.is-open a:nth-child(3) { transition-delay: 0.12s; }
.mobile-menu.is-open a:nth-child(4) { transition-delay: 0.16s; }
.mobile-menu.is-open a:nth-child(5) { transition-delay: 0.20s; }
.mobile-menu.is-open a:nth-child(6) { transition-delay: 0.24s; }
.mobile-menu.is-open a:nth-child(7) { transition-delay: 0.28s; }

/* ---------------- 通用分区 ----------------
   分区标题走「编辑感」排版：小标题带一道金色短线，标题大一号，
   说明文字右侧对齐，下面压一条发丝分隔线。比堆在一起的居中标题稳。
   ---------------------------------------------------- */
.sec { position: relative; padding: var(--space-sec) 0; }

/* 分区编号：用 CSS 计数器自动生成，不用改 HTML、也不用写进 data.js
   ------------------------------------------------------------
   起始值 **1**：因为**首屏也算第 01 个分区**。
   首屏（#sec1）没有 .sec-head、不会自增，所以从 0 起步的话，
   第一个带标题的分区（作品总览）会显示 01 ——
   但导航里它是 02（01 被首屏占了），于是全站标题编号都比导航少 1。
   设为 1 之后，第一次自增正好得到 02，两边就对上了。
   （注意 counter-reset 是**赋初值**，不是加偏移 —— 写 -1 会得到 00。） */
main { counter-reset: secno 1; }
.sec-head { counter-increment: secno; }

.eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 14px;
  font-family: var(--font-en);
  font-size: 11.5px;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--accent);
}
/* 小金线：让 eyebrow 从"一行字"变成"一个标记" */
.eyebrow::before {
  content: "";
  width: 26px;
  height: 1px;
  flex: none;
  background: linear-gradient(90deg, transparent, var(--accent));
}
/* 编号贴在 eyebrow 左侧 */
.sec-head .eyebrow::after {
  content: counter(secno, decimal-leading-zero);
  order: -1;
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--fg-faint);
  padding-right: 12px;
  border-right: 1px solid var(--line);
}

.sec-title {
  margin: 0 0 18px;
  font-size: var(--fs-title);
  font-weight: 250;
  letter-spacing: 0.01em;
  line-height: 1.18;
}
.sec-desc {
  margin: 0;
  color: var(--fg-dim);
  max-width: 62ch;
  font-size: clamp(13.5px, 1.15vw, 15.5px);
  line-height: 1.75;
}
.sec-body p { color: var(--fg-dim); margin: 0 0 14px; }

/* 标题区：宽屏时"标题在左、说明在右"的两栏编辑排版；窄屏堆叠 */
.sec-head {
  margin-bottom: var(--space-head);
  padding-bottom: clamp(20px, 2.6vw, 34px);
  position: relative;
}
/* 底部分隔线：用伪元素画，滚动入场时从中间展开（比静态 1px 线有仪式感） */
.sec-head::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: linear-gradient(90deg,
    rgba(207, 169, 95, 0.34), rgba(240, 236, 227, 0.12) 26%, rgba(240, 236, 227, 0.12) 74%, rgba(207, 169, 95, 0.34));
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1.1s var(--ease) 0.12s;
}
.sec-head.is-in::after { transform: scaleX(1); }

/* 滚动进入动效的初始态。JS 加 .is-in 后回归正常位置 */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
.reveal.is-in { opacity: 1; transform: none; }

/* 媒体占位块：内容定好之前，先让版式看得见 */
.media-slot {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius);
  overflow: hidden;
  background:
    linear-gradient(135deg, rgba(207, 169, 95, 0.07), rgba(207, 169, 95, 0.05)),
    var(--bg-2);
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
}
.media-slot > span {
  font-size: 11.5px;
  letter-spacing: 0.22em;
  color: var(--fg-faint);
  text-transform: uppercase;
}
/* 需要图片时给 .media-slot 加背景图即可 */
.media-slot.has-media { background-size: cover; background-position: center; }
.media-slot.has-media > span { display: none; }

/* 视频填满整个占位块：定位成绝对层，铺满并裁切 */
.media-slot > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* 用 <img> 而不是背景图时（更利于浏览器缓存与懒加载） */
.media-slot > img.fill {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* 满屏主视觉与滚动舞台：允许更高更宽的画面
   （具体的底图/渐变规则在下面「区块1：开场」里） */
.hero-media {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
}
/* 没填背景媒体时（SITE.heroMedia 为空）整层不占位、不绘制 */
.hero-media:empty { display: none; }

/* ---------------- 首屏工具箱（软件图标） ----------------
   12 个软件：一行六个，两行排完；窄屏逐级降到 4 / 3 列。
   参考图是金色，这里统一改用作品集主题色（--accent）。
   ---------------------------------------------------- */
.toolkit {
  margin-top: clamp(34px, 5vw, 58px);
  width: 100%;
  /* 原来是 1080（比内容栏 1240 还窄一截），
     现在跟内容栏对齐 —— 12 个工具排 6 列 x 2 行，两行排完。 */
  max-width: 1240px;
}
.toolkit-label {
  margin: 0 0 16px;
  font-size: 12px;
  letter-spacing: 0.22em;
  color: var(--fg-faint);
  text-transform: uppercase;
}
.tool-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: clamp(8px, 1.1vw, 14px);
}
.tool {
  padding: clamp(14px, 1.6vw, 20px) 8px;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(240, 236, 227, 0.018);
  transition: border-color 0.5s var(--ease), background 0.5s var(--ease), transform 0.5s var(--ease);
}
.tool:hover {
  transform: translateY(-3px);
  border-color: rgba(207, 169, 95, 0.34);
  background: rgba(207, 169, 95, 0.05);
}

/* 图标底托：跟参考图一样的圆角方块 */
.tool-icon {
  width: clamp(38px, 4.4vw, 50px);
  height: clamp(38px, 4.4vw, 50px);
  margin: 0 auto 12px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: rgba(240, 236, 227, 0.05);
  border: 1px solid var(--line);
  color: var(--accent);
  transition: color 0.5s var(--ease), border-color 0.5s var(--ease);
}
.tool:hover .tool-icon { border-color: rgba(207, 169, 95, 0.4); }
/* 官方 logo：内联 SVG，fill 跟随主题色 */
.tool-icon svg {
  width: 56%;
  height: 56%;
  fill: currentColor;
  display: block;
}
/* 双字母标记：没有官方 logo 的软件，按同一套视觉做 */
.tool-mono {
  font-family: var(--font-en);
  font-size: clamp(14px, 1.6vw, 18px);
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1;
}
/* 蒙版图标：用图片的 alpha 当形状、填主题色 ——
   让彩色 logo（Marvelous 橙色立方、SpeedTree 绿底白树）也能统一成单色，
   而且换主题色时自动跟随，不用重新导出图片。
   注意：蒙版图标**保留**底托底色/描边，与 SVG 那批保持一致。
   用 mask 的长写法而不是简写 —— 简写里放 var() 在部分版本上不生效。 */
.tool-mask {
  width: 66%;
  height: 66%;
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
}
/* 自带配色的位图：原样显示，不套主题色。
   底托底色去掉，免得和图标自身的底色叠成两层。 */
.tool-icon.has-img {
  background: transparent;
  border-color: transparent;
}
.tool-icon.has-img img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.tool h4 {
  margin: 0 0 5px;
  font-size: clamp(11px, 1.05vw, 13.5px);
  font-weight: 500;
  line-height: 1.35;
  color: var(--fg);
}
.tool p {
  margin: 0;
  font-size: clamp(10px, 0.92vw, 11.5px);
  color: var(--fg-faint);
  letter-spacing: 0.04em;
  line-height: 1.4;
}

/* ---------------- 区块1：开场 ---------------- */
.sec-hero {
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding-top: 120px;
  text-align: center;
  overflow: hidden;
}
/* 底图：一张电影感夜景，慢速推近（ken burns），比纯光斑有戏。
   定位/裁切在「满屏主视觉」那节，这里只写画面本身的效果。 */
.hero-fill {
  position: absolute;
  inset: 0;
}
.hero-media video,
.hero-media img,
.hero-fill video,
.hero-fill img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* 压暗是为了托住前景白字，但压太狠就看不出"在动"了。
     0.72 + 下面那层渐变，实测标题依然清晰、背景特效也看得出来。 */
  opacity: 0.72;
}
/* 只在用静态图时做慢速推近（ken burns）；视频本身已经在动了，再加位移会抖 */
.hero-media img,
.hero-fill img {
  transform: scale(1.06);
  animation: heroKen 34s var(--ease-io) infinite alternate;
}
/* 两层叠加：顶部压暗（导航可读）→ 中间留亮（看得见特效在动）→ 底部融进背景；
   再叠一层中心稍亮的径向，避免四角抢戏 */
.hero-media::after,
.hero-fill::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(10, 9, 8, 0.62) 0%, rgba(10, 9, 8, 0.22) 28%, rgba(10, 9, 8, 0.42) 62%, var(--bg) 100%),
    radial-gradient(72% 52% at 50% 45%, transparent 34%, rgba(10, 9, 8, 0.46) 100%);
}

/* 光斑层叠在底图之上，做一层暖色氛围 */
.hero-bg {
  position: absolute;
  inset: -10%;
  z-index: -1;
  background:
    radial-gradient(42% 34% at 50% 42%, rgba(207, 169, 95, 0.16), transparent 62%),
    radial-gradient(34% 30% at 72% 72%, rgba(207, 169, 95, 0.10), transparent 64%);
  animation: heroDrift 22s var(--ease-io) infinite alternate;
}
.hero-inner { max-width: 900px; padding: 0 var(--pad); }

/* 标题：极细字重 + 由上到下渐隐的金属渐变，比纯白字贵一档 */
.hero-title {
  margin: 0 0 22px;
  font-size: var(--fs-display);
  font-weight: 200;
  letter-spacing: var(--ls-display);
  line-height: 1.04;
  background: linear-gradient(180deg, #fffdf8 0%, #f2e6c8 46%, #cbb083 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.hero-lead {
  margin: 0 auto 36px;
  max-width: 46ch;
  color: var(--fg-dim);
  font-size: clamp(14px, 1.6vw, 17.5px);
  letter-spacing: 0.02em;
}
.hero-actions { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }

.btn {
  display: inline-block;
  padding: 13px 30px;
  border-radius: 999px;
  font-size: 14px;
  letter-spacing: 0.04em;
  cursor: pointer;
  border: 1px solid transparent;
  transition: transform 0.4s var(--ease), background 0.4s var(--ease), border-color 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.btn-primary {
  background: linear-gradient(170deg, var(--accent-hi), var(--accent) 46%, var(--accent-lo));
  color: #1a1408;
  font-weight: 600;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 10px 30px rgba(207, 169, 95, 0.24);
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 16px 42px rgba(207, 169, 95, 0.36); }
.btn-ghost {
  border-color: rgba(240, 236, 227, 0.2);
  color: var(--fg-dim);
  background: rgba(10, 9, 8, 0.34);
}
.btn-ghost:hover {
  border-color: rgba(207, 169, 95, 0.5);
  color: var(--fg);
  transform: translateY(-2px);
  background: rgba(207, 169, 95, 0.08);
}

/* 跟随式「返回作品总览」：固定右下角，滚过作品总览后淡入。
   z-index 65 = 在导航（60）之上、遮罩层（80）之下 —— 看大图/全屏播放时不会浮在上面。
   （虽然 JS 里弹层打开时也主动隐藏了，但那是双保险：万一以后遮罩层的层级被调低。） */
.back-to-works {
  position: fixed;
  right: clamp(14px, 2.4vw, 30px);
  bottom: clamp(16px, 3vh, 34px);
  z-index: 65;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 11px 20px 11px 17px;
  border-radius: 999px;
  cursor: pointer;
  font-family: inherit;
  font-size: 13.5px;
  letter-spacing: 0.04em;
  color: var(--fg-dim);
  border: 1px solid rgba(240, 236, 227, 0.18);
  background: rgba(10, 9, 8, 0.62);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: var(--sh-1);
  /* 默认隐藏：往下移 10px + 透明，避免"贴边弹出"的突兀感 */
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease),
              visibility 0.5s var(--ease), background 0.4s var(--ease),
              border-color 0.4s var(--ease), color 0.4s var(--ease);
}
.back-to-works.is-on {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.back-to-works:hover {
  color: var(--fg);
  background: rgba(10, 9, 8, 0.82);
  border-color: rgba(207, 169, 95, 0.5);
}
/* 左箭头用 CSS 画（两条边旋转 45°），不引图标资源 */
.btw-arrow {
  width: 7px;
  height: 7px;
  border-left: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  margin-top: -1px;
  transition: transform 0.4s var(--ease);
}
.back-to-works:hover .btw-arrow { transform: rotate(45deg) translate(-2px, 2px); }

.scroll-hint {
  position: absolute;
  bottom: 30px; left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  font-size: 11px;
  letter-spacing: 0.22em;
  color: var(--fg-faint);
}
.scroll-hint i {
  width: 1px; height: 40px;
  background: linear-gradient(180deg, transparent, var(--accent), transparent);
  animation: hintSlide 2.4s var(--ease-io) infinite;
}

/* ---------------- 区块2：特效作品（1 主 + 4 分件） ----------------
   布局：主视频独占一行铺满内容宽；下方 2×2 放其余四件。
   小屏收成单列，避免每个格子太窄看不清。
   ------------------------------------------------------------ */
.vfx-main { margin-bottom: clamp(12px, 1.6vw, 20px); }

/* 视频格子的统一外壳
   质感做法：外层一圈极淡描边 + 内侧一道 1px 高光（模拟受光边缘）
   + 两档阴影（近距离贴地 + 远距离扩散）。暗底上这套比单层黑阴影立体得多。 */
.vfx-cell {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--line);
  background: #000;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.06), var(--sh-1);
  /* 用 transform 做悬停，避免改尺寸触发重排 */
  transition: transform 0.6s var(--ease), border-color 0.6s var(--ease), box-shadow 0.6s var(--ease);
}
.vfx-cell:hover {
  transform: translateY(-3px);
  border-color: rgba(207, 169, 95, 0.42);
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.12), var(--sh-2), 0 0 30px rgba(207, 169, 95, 0.10);
}
.vfx-cell > video,
.vfx-cell > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* 分件默认只显示静帧；视频层淡入，避免同时解码四条流 */
.vfx-cell > video { opacity: 0; transition: opacity 0.6s var(--ease); }
.vfx-cell.is-playing > video { opacity: 1; }

/* 主视频（特效合集 / Tripo / 虚幻5 / 渲染大赛）是「划到就自动播」的预览，
   松手停在某一帧时也要看得见，所以滚动播放后视频常驻可见。
   分件仍然是鼠标移上去才淡入（悬停预览）。 */
.vfx-main .vfx-cell.is-playing > video,
.game-main .vfx-cell.is-playing > video,
.tripo-main .vfx-cell.is-playing > video,
.render-main .vfx-cell.is-playing > video { opacity: 1; }

.vfx-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(12px, 1.6vw, 20px);
}

/* 角标与文字叠层 */
.vfx-tag {
  position: absolute;
  left: 12px;
  top: 12px;
  z-index: 2;
  padding: 5px 11px;
  border-radius: 999px;
  font-size: 11.5px;
  letter-spacing: 0.1em;
  color: var(--fg);
  background: rgba(14, 12, 9, 0.62);
  border: 1px solid var(--line);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.vfx-meta {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  padding: 34px 14px 12px;
  /* 底部压一层渐变，白字在任何画面上都读得清 */
  background: linear-gradient(180deg, transparent, rgba(10, 9, 8, 0.86));
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.vfx-cell:hover .vfx-meta,
.vfx-main .vfx-cell .vfx-meta,
.game-main .vfx-cell .vfx-meta { opacity: 1; transform: none; }
.vfx-meta h3 { margin: 0 0 3px; font-size: 15px; font-weight: 500; }
.vfx-meta p { margin: 0; font-size: 12px; color: var(--fg-faint); letter-spacing: 0.06em; }

/* 播放指示：一个呼吸的小圆点，暗示"可点开" */
.vfx-play {
  position: absolute;
  right: 12px; top: 12px;
  z-index: 2;
  width: 34px; height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(14, 12, 9, 0.6);
  border: 1px solid var(--line);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: background 0.45s var(--ease), transform 0.45s var(--ease);
}
.vfx-play::after {
  content: "";
  border-left: 9px solid var(--accent);
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  margin-left: 3px;
}
.vfx-cell:hover .vfx-play { background: rgba(207, 169, 95, 0.16); transform: scale(1.08); }

/* ---------------- 区块4：虚幻5游戏作品 ----------------
   一个主视频 + 下方一排时间线剧照。
   剧照是"这一条时间线上挑出来的几个瞬间"，所以默认单行铺开，
   读起来像一条胶片；窄屏才折成 2×2。
   ---------------------------------------------------- */
.game-main { margin-bottom: clamp(16px, 2vw, 26px); }

.stills-label {
  margin: 0 0 12px;
  font-size: 12px;
  letter-spacing: 0.2em;
  color: var(--fg-faint);
  text-transform: uppercase;
}

/* 分区内的子标题：一个 sec 里并了两块内容时用来区分（如"渲染竞赛"下的两场比赛）。
   做成一条带金色短竖线的分节标记，比小标题更"分节"，比大标题轻。 */
.part-label {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: clamp(38px, 5vw, 70px) 0 clamp(16px, 2vw, 24px);
  font-size: clamp(15px, 1.35vw, 18px);
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--fg);
}
.part-label::before {
  content: "";
  width: 3px;
  height: 1.05em;
  flex: none;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--accent-hi), var(--accent-lo));
}
/* 第一条子标题紧跟在大标题下面，不用那么大的上间距 */
.sec-head + .part-label { margin-top: clamp(20px, 2.4vw, 32px); }
/* 静帧区基类：区块3（游戏）和区块4（渲染大赛）共用。
   默认 4 列；竖构图的区块用 .stills--portrait 覆盖成 6 列。
   注意这里用类选择器而不是 #id —— 之前写成 #gameStills，
   结果区块四拿不到 display:grid，整个静帧区退化成竖排。 */
.stills {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(10px, 1.4vw, 18px);
}
.still {
  margin: 0;
  cursor: zoom-in;
}
.still img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius-md);
  border: 1px solid var(--line);
  background: #000;
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.06), var(--sh-1);
  transition: transform 0.6s var(--ease), border-color 0.6s var(--ease), filter 0.6s var(--ease), box-shadow 0.6s var(--ease);
  /* 未悬停时略微压暗，悬停的那张"亮起来"。
     压太多的话这类暗调游戏画面会糊成一片，0.92 是能看出层次的下限。 */
  filter: brightness(0.92);
}
.still:hover img {
  transform: translateY(-3px);
  border-color: rgba(207, 169, 95, 0.42);
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.12), var(--sh-2);
  filter: brightness(1.1);
}
.still figcaption {
  margin-top: 8px;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--fg-faint);
  transition: color 0.4s var(--ease);
}
.still:hover figcaption { color: var(--fg-dim); }

/* ---------------- 区块5：世界渲染大赛-作品 ----------------
   主视频是竖屏（9:16），和另两个区块的横屏不同：
   视频按「高度」定尺寸并居中，宽高比由 CSS 推出来，不用写死宽度。
   ---------------------------------------------------- */
.render-main {
  display: grid;
  place-items: center;         /* 竖屏视频居中，两侧留白是刻意的 */
  margin-bottom: clamp(18px, 2.4vw, 30px);
}
.render-main .vfx-cell {
  aspect-ratio: 9 / 16;
  height: min(74vh, 860px);
  width: auto;
  max-width: 100%;             /* 窄屏时不会溢出 */
}
/* 竖屏视频里，底部渐变说明条占比太大，收窄一点 */
.render-main .vfx-cell .vfx-meta { padding: 40px 14px 14px; }

/* 竖构图静帧：一排六个，是"制作流程"的顺序。
   注意列数要显式覆盖 —— 基类 .stills 是 4 列（区块4 用的），这里 6 张。 */
.stills--portrait { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.stills--portrait .still img { aspect-ratio: 9 / 16; }

/* 获奖证书：两张并排成一行（竖版 A4，比例 1000:1414）。
   按原比例完整显示 —— 证书上有文字，裁切会切掉内容。 */
.stills--certs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.stills--certs .still img { aspect-ratio: 1000 / 1414; }
/* 制作过程：6 张 16:9 横构图，3 列 x 2 行排满。
   基类是 4 列（区块4 用）、证书是 2 列竖版，这里显式覆盖成 3 列。
   用 3 列而不是 4 列：4 列下每张只有 269px，16:9 的软件界面截图会糊到看不清。
   注意：媒体查询必须放在后面 —— 以前把 max-width 规则写在基础规则前，
   结果被基础规则覆盖，怎么调都没反应。 */
.stills--process { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* 紧跟在剧照网格后面的小标题：多给点上边距。
   不加的话"制作过程"会贴着上面证书那排的图注，两个区块看起来是连在一起的
   —— 用相邻兄弟选择器，不用给 HTML 加类，别的地方也自动受益。 */
.stills + .stills-label { margin-top: clamp(30px, 4vw, 52px); }

/* ---------------- 【未使用】作品网格模块 ----------------
   #worksGrid / #filters 已从 index.html 移除（区块三改成了游戏作品），
   样式先留着，想在别的区块启用就把那两段结构加回去。 */
.filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 26px; }
.chip {
  padding: 8px 18px;
  font-size: 13px;
  font-family: inherit;
  color: var(--fg-dim);
  background: rgba(238, 242, 246, 0.04);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  transition: color 0.35s var(--ease), background 0.35s var(--ease), border-color 0.35s var(--ease);
}
.chip:hover { color: var(--fg); border-color: rgba(238, 242, 246, 0.28); }
.chip.is-active {
  color: #0a0908;
  background: var(--accent);
  border-color: var(--accent);
  font-weight: 600;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 18px;
}
.card {
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-2);
  border: 1px solid var(--line);
  cursor: pointer;
  transition: transform 0.55s var(--ease), border-color 0.55s var(--ease), box-shadow 0.55s var(--ease);
}
.card:hover {
  transform: translateY(-5px);
  border-color: rgba(207, 169, 95, 0.32);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
}
.card-media { aspect-ratio: 16 / 9; border-radius: 0; border: 0; }
.card:hover .card-media { transform: scale(1.04); }
.card-media { transition: transform 0.7s var(--ease); }
.card-body { padding: 16px 18px 20px; }
.card-title { margin: 0 0 5px; font-size: 16px; font-weight: 500; }
.card-meta { margin: 0; font-size: 12.5px; color: var(--fg-faint); letter-spacing: 0.06em; }
/* 筛选时用缩放淡出，而不是直接 display:none，观感更连贯 */
.card.is-hidden {
  display: none;
}

/* ---------------- 【未使用】分组 + 横向画廊 ---------------- */
.group-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 22px;
  margin-bottom: clamp(40px, 6vw, 76px);
}
.group-media { aspect-ratio: 3 / 2; margin-bottom: 16px; }
.group-idx {
  margin: 0 0 7px;
  font-family: var(--font-en);
  font-size: 11.5px;
  letter-spacing: 0.2em;
  color: var(--accent);
}
.group-title { margin: 0 0 9px; font-size: 19px; font-weight: 500; }
.group-desc { margin: 0; color: var(--fg-dim); font-size: 14.5px; }

.rail-wrap { margin-top: 10px; }
.rail-label {
  margin: 0 0 14px;
  font-size: 12px;
  letter-spacing: 0.2em;
  color: var(--fg-faint);
  text-transform: uppercase;
}
.rail {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  padding-bottom: 14px;
  /* 滚动吸附 + 隐藏滚动条，横向浏览手感更顺 */
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  /* 两端渐隐：用 mask 代替生硬的裁切边缘 */
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
}
.rail::-webkit-scrollbar { display: none; }
.rail-item {
  flex: 0 0 auto;
  width: clamp(190px, 26vw, 320px);
  aspect-ratio: 3 / 4;
  scroll-snap-align: center;
  cursor: pointer;
  transition: transform 0.55s var(--ease), border-color 0.55s var(--ease);
}
.rail-item:hover { transform: translateY(-4px); border-color: rgba(207, 169, 95, 0.32); }

/* ---------------- 区块6：视觉效果（两小 + 一大） ----------------
   前两个并排，第三个带 .vfx-cell--wide 横跨整行。
   ------------------------------------------------------------ */
.visual-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(12px, 1.6vw, 20px);
}
.vfx-cell--wide { grid-column: 1 / -1; }

/* ---------------- 【未使用】并列双栏模块 ----------------
   .duo-grid 的 HTML 已移除（区块六改成了视觉效果），
   样式与 main.js 的渲染逻辑都留着，想启用把那两段结构加回去即可。 */
.duo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: clamp(22px, 4vw, 50px);
}
.duo-media { aspect-ratio: 16 / 10; margin-bottom: 18px; }
.duo-title { margin: 0 0 10px; font-size: 20px; font-weight: 500; }
.duo-desc { margin: 0 0 18px; color: var(--fg-dim); font-size: 14.5px; }
.facts { list-style: none; margin: 0; padding: 0; }
.facts li {
  display: flex;
  gap: 14px;
  padding: 9px 0;
  border-top: 1px solid var(--line);
  font-size: 13.5px;
}
.facts b { color: var(--fg-faint); font-weight: 400; min-width: 66px; }
.facts span { color: var(--fg-dim); }

/* ---------------- 区块7：三维作品（3 图 + 2 视频） ----------------
   两行各两个，最后一个雕刻作品横跨整行。
   图和视频共用 .vfx-cell，图片那类挂 .vfx-cell--img：
   藏掉播放三角（那是视频的暗示），换成放大光标。
   ------------------------------------------------------------ */
.threed-grid {
  display: grid;
  /* 9 个条目 -> 3 列 x 3 行，正好三排齐整（用户要求 3*3）。
     格子居中：justify-items 让每格在自己那一列里居中，
     否则格子比列宽时会被挤到左边贴边（这个 bug 用户报过）。
     文案仍旧左对齐（.vfx-meta 自带 text-align: left）。 */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  justify-items: center;
  gap: clamp(12px, 1.3vw, 18px);
  /* 宽度收回内容宽度以内 —— **不要超过分区标题下面那条横线**。
     横线就是 .sec-head::after，宽度 = .wrap 内容宽（上限 1240px）。
     之前用 100vw 撑出 wrap，三维区比横线宽出去一大截、格子被撑到 577px，
     用户反馈"太大了"。现在既不撑宽、也不用负 margin，跟着 wrap 走即可。
     3 列 x 约 340px，整块居中、比横线略窄一点（看着更收）。 */
  /* 上限从 1080 提到 1560：跟全站新的内容栏宽一致。
     原来卡 1080 是当时"太大了"的反馈；现在栏宽整体提到 1560，
     它跟着走才不会比别的分区窄一截。 */
  max-width: 1560px;
  margin: 0 auto;
}
/* 三维区的封面统一是 4:3，所以格子也要 4:3，否则 object-fit:cover 会把封面裁掉。
   （.vfx-cell 默认 16:9，那是给特效/视觉区的视频用的） */
.threed-grid .vfx-cell { aspect-ratio: 4 / 3; }
.vfx-cell--img { cursor: zoom-in; }
.vfx-cell--img .vfx-play { display: none; }
/* ---------------- 区块8：联系 ----------------
   收尾区，整站最简单的一块，所以更要"干净 + 有点光"：
   标题后面叠一层很淡的金色光晕，二维码卡片按"白卡 + 金边"处理。
   ---------------------------------------------------- */
.sec-cta { text-align: center; position: relative; }

/* 标题后的光晕：用伪元素画，不占文档流 */
.cta-head { position: relative; max-width: 660px; margin: 0 auto clamp(38px, 5.4vw, 68px); }
.cta-head::before {
  content: "";
  position: absolute;
  left: 50%; top: 42%;
  width: min(760px, 120%);
  height: 320px;
  transform: translate(-50%, -50%);
  pointer-events: none;
  background: radial-gradient(50% 50% at 50% 50%, rgba(207, 169, 95, 0.16), transparent 70%);
}
.cta-head > * { position: relative; }

.cta-title {
  margin: 0 0 16px;
  font-size: clamp(26px, 4.2vw, 48px);
  font-weight: 200;
  line-height: 1.24;
  letter-spacing: 0.01em;
  /* 和首屏标题同一套金属渐变，首尾呼应 */
  background: linear-gradient(180deg, #fffdf8 0%, #f2e6c8 52%, #cbb083 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.cta-desc {
  margin: 0 auto;
  max-width: 46ch;
  color: var(--fg-dim);
  font-size: clamp(13.5px, 1.15vw, 15.5px);
  line-height: 1.75;
}
/* 收尾区的 eyebrow 居中显示（其他分区是左对齐的两栏排版） */
.sec-cta .eyebrow { justify-content: center; }
.sec-cta .eyebrow::after { display: none; }

/* ---------------- 教育背景 / 求职意向（联系区上方一条信息带） ----------------
   做成 <dl> 的两栏：左边是小号灰色标签，右边是值。
   一条一条之间用发丝线分开，信息密度高但不吵。 */
.cta-facts {
  max-width: 780px;
  margin: 0 auto clamp(34px, 4.6vw, 58px);
  padding: clamp(18px, 2.2vw, 26px) clamp(18px, 2.4vw, 30px);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012));
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.06);
  text-align: left;
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: clamp(16px, 2.4vw, 34px);
  row-gap: clamp(12px, 1.5vw, 18px);
  align-items: baseline;
}
.cta-facts:empty { display: none; }
.cta-facts dt {
  font-size: 12px;
  letter-spacing: 0.14em;
  color: var(--fg-faint);
  white-space: nowrap;
}
.cta-facts dd {
  margin: 0;
  font-size: clamp(13.5px, 1.15vw, 15px);
  line-height: 1.7;
  color: var(--fg);
  padding-top: clamp(12px, 1.5vw, 18px);
  border-top: 1px solid transparent;
}
/* 第一行不加分隔线，后面的每条都加一条发丝线 */
.cta-facts dt:not(:first-of-type) + dd { border-top-color: var(--line); }
/* 第一行的 dt 也要跟着对齐，否则标签会比内容低一截 */
.cta-facts dd:first-of-type { padding-top: 0; border-top: 0; }
.cta-facts dd b { font-weight: 500; }
/* 备注（毕业时间 / 届别）跟在校名后面，弱点、小一号 */
.cta-facts dd i {
  display: inline-block;
  margin-left: 10px;
  font-style: normal;
  font-size: 12.5px;
  color: var(--accent);
}

.qr-row {
  display: flex;
  gap: clamp(18px, 3.4vw, 48px);
  justify-content: center;
  align-items: flex-start;   /* 三张卡片比例不同，顶部对齐，不要拉伸 */
  flex-wrap: wrap;
  margin-bottom: clamp(30px, 5vw, 56px);
}
.qr { text-align: center; }
/* 二维码卡片是竖版（含 logo / 昵称），三张比例都不一样。
   统一"高度"而不是宽度：卡片等高，宽度按各自比例自然不同，
   这样下面的名字和说明才能对齐。裁成正方形会把卡片上的标识切掉。 */
.qr-slot {
  height: clamp(230px, 30vh, 360px);
  margin-bottom: 16px;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--line);
  background: #fff;          /* 兜底白底：万一图没铺满，扫码仍然可靠 */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px;              /* 白卡内退一点，二维码不贴边 */
  box-shadow: var(--sh-2);
  transition: transform 0.6s var(--ease), border-color 0.6s var(--ease),
              box-shadow 0.6s var(--ease);
}
.qr:hover .qr-slot {
  transform: translateY(-5px);
  border-color: rgba(207, 169, 95, 0.5);
  box-shadow: var(--sh-3), 0 0 26px rgba(207, 169, 95, 0.14);
}
.qr-slot img { display: block; height: 100%; width: auto; max-width: 100%; border-radius: 6px; }
.qr h4 { margin: 0 0 6px; font-size: 15px; font-weight: 500; }
.qr p { margin: 0; font-size: 13px; color: var(--fg-faint); }

/* ---------------- 页脚 ---------------- */
footer {
  padding: 30px var(--pad);
  text-align: center;
  font-size: 12.5px;
  color: var(--fg-faint);
  border-top: 1px solid var(--line);
}

/* ---------------- 覆盖层：看图 / 详情 / 闪光 / 进度 ---------------- */
.shutter-flash {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: #fff;
  opacity: 0;
  pointer-events: none;
}
.shutter-flash.is-fire { animation: shutter 0.42s var(--ease); }

.lightbox, .modal, .vlightbox {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  background: rgba(8, 7, 6, 0.9);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.42s var(--ease), visibility 0.42s;
}
.lightbox.is-open, .modal.is-open, .vlightbox.is-open { opacity: 1; visibility: visible; }

/* 视频全屏层 */
.vl-stage {
  width: min(94vw, 1500px);
  display: grid;
  justify-items: center;
  gap: 14px;
}
.vl-stage video {
  width: 100%;
  max-height: 80vh;
  border-radius: 12px;
  background: #000;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
}
.vl-caption {
  margin: 0;
  font-size: 13px;
  letter-spacing: 0.14em;
  color: var(--fg-dim);
}
.vl-close {
  position: absolute;
  top: 22px; right: 26px;
  width: 42px; height: 42px;
  font-size: 26px;
  line-height: 1;
  color: var(--fg-dim);
  background: rgba(240, 236, 227, 0.06);
  border: 1px solid var(--line);
  border-radius: 50%;
  cursor: pointer;
  transition: color 0.35s var(--ease), background 0.35s var(--ease), transform 0.35s var(--ease);
}
.vl-close:hover { color: #fff; background: rgba(240, 236, 227, 0.14); transform: rotate(90deg); }

.lb-stage { max-width: min(92vw, 1200px); max-height: 80vh; }
.lb-stage img { max-height: 80vh; border-radius: 10px; object-fit: contain; }
.lb-hint {
  position: absolute;
  bottom: 22px;
  font-size: 12px;
  color: var(--fg-faint);
  letter-spacing: 0.1em;
}
.lb-close, .modal-close {
  position: absolute;
  top: 22px; right: 26px;
  width: 42px; height: 42px;
  font-size: 26px;
  line-height: 1;
  color: var(--fg-dim);
  background: rgba(238, 242, 246, 0.06);
  border: 1px solid var(--line);
  border-radius: 50%;
  cursor: pointer;
  transition: color 0.35s var(--ease), background 0.35s var(--ease), transform 0.35s var(--ease);
}
.lb-close:hover, .modal-close:hover { color: #fff; background: rgba(238, 242, 246, 0.14); transform: rotate(90deg); }
.lb-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 50px; height: 66px;
  font-size: 32px;
  color: var(--fg-dim);
  background: rgba(238, 242, 246, 0.05);
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  transition: color 0.35s var(--ease), background 0.35s var(--ease);
}
.lb-nav:hover { color: #fff; background: rgba(238, 242, 246, 0.14); }
.lb-prev { left: 22px; }
.lb-next { right: 22px; }

.modal-box {
  width: min(92vw, 620px);
  max-height: 86vh;
  overflow-y: auto;
  padding: 26px;
  border-radius: 18px;
  background: var(--glass);
  border: 1px solid var(--line);
  transform: translateY(16px) scale(0.98);
  transition: transform 0.5s var(--ease);
}
.modal.is-open .modal-box { transform: none; }
.modal-media { aspect-ratio: 16 / 9; margin-bottom: 18px; }
.modal-box h3 { margin: 0 0 10px; font-size: 20px; font-weight: 500; }
.modal-box p { margin: 0; color: var(--fg-dim); font-size: 14.5px; }

.progress-bar {
  position: fixed;
  top: 0; left: 0;
  z-index: 70;
  height: 2px;
  width: 0;
  background: var(--accent);
  box-shadow: 0 0 10px rgba(207, 169, 95, 0.55);
}

/* ============================================================
   金属质感层 —— 放在响应式断点之前，靠后者优先覆盖上面的基础样式。
   ------------------------------------------------------------
   金属感靠三件事叠出来，单靠一个金色是不够的：
     1) 渐变：高光 -> 本色 -> 暗部，模拟光打在金属上的斜面反射
     2) 轮廓高光：元素上沿一条 1px 亮边（inset 0 1px 0），像金属倒角
     3) 发光：低透明度的金色外发光，让强调元素"亮起来"而不刺眼
   注意发光不能太重，否则就从"高级"滑到"土味霓虹"。
   ============================================================ */

/* ---- 标签文字：烫金效果 ---- */
.eyebrow,
.toolkit-label,
.stills-label,
.rail-label {
  background-image: linear-gradient(100deg,
    var(--accent-hi) 0%, var(--accent) 46%, var(--accent-lo) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--accent);
  /* 极淡的光晕，让字像是被光照亮 */
  filter: drop-shadow(0 0 10px rgba(207, 169, 95, 0.22));
}

/* ---- 主按钮：金属块 ---- */
.btn-primary {
  background: linear-gradient(158deg,
    var(--accent-hi) 0%, var(--accent) 44%, #b0893d 78%, var(--accent-lo) 100%);
  color: #241b08;
  text-shadow: 0 1px 0 rgba(255, 248, 226, 0.34);
  box-shadow:
    inset 0 1px 0 rgba(255, 250, 232, 0.62),   /* 上沿倒角高光 */
    inset 0 -1px 0 rgba(90, 68, 24, 0.30),      /* 下沿阴影 */
    0 6px 22px rgba(207, 169, 95, 0.20),        /* 外发光 */
    0 0 0 1px rgba(255, 240, 200, 0.16);        /* 极细描边 */
}
.btn-primary:hover {
  box-shadow:
    inset 0 1px 0 rgba(255, 250, 232, 0.75),
    inset 0 -1px 0 rgba(90, 68, 24, 0.30),
    0 10px 34px rgba(207, 169, 95, 0.34),
    0 0 0 1px rgba(255, 240, 200, 0.24);
}

/* ---- 次要按钮：金属描边 ---- */
.btn-ghost {
  border-color: rgba(207, 169, 95, 0.34);
  box-shadow: inset 0 1px 0 var(--rim), 0 0 14px rgba(207, 169, 95, 0.07);
}
.btn-ghost:hover {
  border-color: var(--rim-strong);
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.24), 0 0 22px rgba(207, 169, 95, 0.16);
}

/* ---- 导航当前项 ---- */
.nav-links a.is-current {
  background: linear-gradient(160deg, rgba(246, 228, 180, 0.20), rgba(143, 111, 44, 0.16));
  color: var(--accent-hi);
  box-shadow: inset 0 1px 0 var(--rim), 0 0 16px rgba(207, 169, 95, 0.14);
}

/* ---- 顶部进度条：一道金属光 ---- */
.progress-bar {
  background: linear-gradient(90deg, var(--accent-lo), var(--accent), var(--accent-hi));
  box-shadow: 0 0 12px rgba(207, 169, 95, 0.55), 0 0 3px rgba(255, 245, 214, 0.6);
}

/* ---- 工具箱图标底托：金属小方块 ---- */
.tool-icon {
  background: linear-gradient(170deg,
    rgba(255, 244, 212, 0.085) 0%, rgba(255, 244, 212, 0.02) 52%, rgba(0, 0, 0, 0.16) 100%);
  border-color: rgba(207, 169, 95, 0.26);
  box-shadow: inset 0 1px 0 var(--rim), 0 0 14px rgba(207, 169, 95, 0.08);
}
.tool-icon svg,
.tool-mask {
  filter: drop-shadow(0 0 5px rgba(207, 169, 95, 0.45));
}
/* 蒙版图标必须和 SVG / 双字母那批同色：统一用 --accent。
   之前这里写的是 --accent-hi（更亮更浅的米白），
   导致 Marvelous Designer 和 SpeedTree 两个图标比周围明显发白。 */
.tool-mask { background-color: var(--accent); }
.tool-icon.has-img,
.tool-icon.has-img img { filter: none; }   /* 官方彩色图标不加滤镜，免得变色 */

/* ---- 卡片 / 视频格：金属倒角 + 悬停发光 ---- */
.tool,
.vfx-cell,
.still img,
.qr-slot {
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.07);
}
.tool:hover {
  border-color: rgba(207, 169, 95, 0.4);
  background: linear-gradient(170deg, rgba(246, 228, 180, 0.09), rgba(143, 111, 44, 0.05));
  box-shadow: inset 0 1px 0 var(--rim-strong), 0 0 24px rgba(207, 169, 95, 0.14);
}
.vfx-cell:hover {
  border-color: rgba(207, 169, 95, 0.42);
  box-shadow: inset 0 1px 0 var(--rim), 0 14px 40px rgba(0, 0, 0, 0.5), 0 0 26px rgba(207, 169, 95, 0.14);
}
.still:hover img {
  border-color: rgba(207, 169, 95, 0.42);
  box-shadow: inset 0 1px 0 var(--rim), 0 0 26px rgba(207, 169, 95, 0.16);
}
.qr:hover .qr-slot {
  border-color: rgba(207, 169, 95, 0.42);
  box-shadow: 0 0 26px rgba(207, 169, 95, 0.18);
}

/* ---- 大标题：极淡的金属描边光 ---- */
.hero-title,
.sec-title,
.cta-title {
  text-shadow: 0 0 34px rgba(207, 169, 95, 0.16);
}

/* ---- 视频播放指示：金属圆钮 ---- */
.vfx-play {
  background: linear-gradient(165deg, rgba(255, 244, 212, 0.14), rgba(143, 111, 44, 0.12));
  border-color: rgba(207, 169, 95, 0.3);
  box-shadow: inset 0 1px 0 var(--rim), 0 0 14px rgba(207, 169, 95, 0.16);
}
.vfx-play::after { border-left-color: var(--accent-hi); }

/* ============================================================
   ★ 排版精修（追加层）
   ------------------------------------------------------------
   全部追加在文件末尾，靠选择器优先级覆盖，不改动上面的既有规则。
   想回退：删掉本块到文件末尾的内容即可。
   ============================================================ */

/* ---------------- 1) 分区编号：01~08 做成金属标记 ----------------
   原来是一行灰色小字贴在 eyebrow 左边，太轻、和其它小字混在一起。
   改成：两侧金色短标 + 金属渐变数字，成为一个"章节编号"标记。 */
.sec-head .eyebrow::after {
  font-family: var(--font-en);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.16em;
  padding-right: 14px;
  padding-left: 14px;
  border-right: 1px solid rgba(207, 169, 95, 0.28);
  border-left: 1px solid rgba(207, 169, 95, 0.28);
  /* 金属渐变字（和首屏标题同一套质感） */
  background: linear-gradient(180deg, var(--accent-hi) 0%, var(--accent) 55%, var(--accent-lo) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* 背景裁切文字时 text-shadow 无效，得用 drop-shadow */
  filter: drop-shadow(0 1px 6px rgba(207, 169, 95, 0.28));
}

/* ---------------- 2) 分区横线：中央加一道淡金光晕 ----------------
   横线本身已有渐变 + 滚动展开。这里在它下面叠一层模糊金线，
   让线"发光"而不是一条硬边。 */
.sec-head::before {
  content: "";
  position: absolute;
  left: 18%; right: 18%; bottom: -2px;
  height: 5px;
  background: radial-gradient(ellipse at center,
    rgba(207, 169, 95, 0.22), rgba(207, 169, 95, 0) 72%);
  filter: blur(3px);
  opacity: 0;
  transition: opacity 1.4s var(--ease) 0.5s;
  pointer-events: none;
}
.sec-head.is-in::before { opacity: 1; }

/* ---------------- 3) eyebrow 小金线：加长 + 末端光点 ---------------- */
.eyebrow::before {
  width: 34px;
  background: linear-gradient(90deg, transparent, rgba(207, 169, 95, 0.55) 55%, var(--accent-hi));
  position: relative;
}

/* ---------------- 4) part-label 分节标：渐变竖线 + 圆头 ---------------- */
.part-label::before {
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--accent-hi), var(--accent) 50%, rgba(207, 169, 95, 0));
}

/* ---------------- 5) 视频 / 图片卡片：内描边 + 信息区加深 + 悬停轮廓光 ----------------
   暗色底上，卡片靠"内描边"才有厚度；悬停给一圈很淡的金色外光。 */
.vfx-cell {
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.07),
              inset 0 0 0 1px rgba(255, 245, 214, 0.03),
              var(--sh-1);
  transition: transform 0.6s var(--ease), border-color 0.6s var(--ease),
              box-shadow 0.6s var(--ease);
}
.vfx-cell:hover {
  border-color: rgba(207, 169, 95, 0.42);
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.14),
              inset 0 0 0 1px rgba(207, 169, 95, 0.12),
              var(--sh-2),
              0 0 34px rgba(207, 169, 95, 0.13);
}
/* 信息条：底部渐变加深一档，白字压得住 */
.vfx-meta {
  background: linear-gradient(180deg,
    rgba(10, 9, 8, 0) 0%,
    rgba(10, 9, 8, 0.62) 42%,
    rgba(10, 9, 8, 0.92) 100%);
}

/* ---------------- 6) 剧照格：和卡片统一语言 ---------------- */
.still img {
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.07),
              inset 0 0 0 1px rgba(255, 245, 214, 0.03),
              var(--sh-1);
}
.still:hover img {
  border-color: rgba(207, 169, 95, 0.4);
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.12),
              var(--sh-2),
              0 0 26px rgba(207, 169, 95, 0.1);
}

/* ---------------- 7) 二维码卡片：不要刺眼的白块 ----------------
   原来是接近纯白的卡片，在暗场里像三个洞。压暗成暖灰白 + 金色描边 + 光晕，
   保留可扫性（对比度仍够），但不再跳。 */
.qr img,
.qr-row img {
  border-radius: var(--radius-md);
  border: 1px solid rgba(207, 169, 95, 0.22);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5),
              0 0 0 6px rgba(240, 236, 227, 0.03);
  filter: brightness(0.9) contrast(1.04) saturate(0.96);
  transition: filter 0.5s var(--ease), box-shadow 0.5s var(--ease),
              border-color 0.5s var(--ease), transform 0.5s var(--ease);
}
.qr:hover img,
.qr-row img:hover {
  filter: brightness(1) contrast(1.05);
  border-color: rgba(207, 169, 95, 0.5);
  box-shadow: 0 22px 50px rgba(0, 0, 0, 0.55),
              0 0 30px rgba(207, 169, 95, 0.16);
  transform: translateY(-4px);
}

/* ---------------- 8) 联系区资料卡：顶部一道金色高光 ---------------- */
.cta-facts {
  position: relative;
  overflow: hidden;
}
.cta-facts::before {
  content: "";
  position: absolute;
  top: 0; left: 12%; right: 12%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(207, 169, 95, 0.55), transparent);
}

/* ---------------- 9) 浮动「作品总览」按钮：金色描边 + 悬停发光 ---------------- */
.back-to-works {
  border-color: rgba(207, 169, 95, 0.26);
}
.back-to-works.is-on {
  box-shadow: var(--sh-1), 0 0 0 1px rgba(207, 169, 95, 0.08);
}
.back-to-works:hover {
  box-shadow: var(--sh-2), 0 0 26px rgba(207, 169, 95, 0.22);
}

/* ---------------- 10) 滚动条：细金条 ----------------
   默认那条亮白滚动条在暗场里非常跳。 */
* { scrollbar-width: thin; scrollbar-color: rgba(207, 169, 95, 0.32) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: rgba(255, 255, 255, 0.02); }
::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, rgba(207, 169, 95, 0.42), rgba(143, 111, 44, 0.42));
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg, rgba(207, 169, 95, 0.62), rgba(143, 111, 44, 0.62));
  background-clip: padding-box;
}

/* ============================================================
   ★ 排版精修 第二轮：首屏工具箱 + 卡片纵深 + 导航态
   ============================================================ */

/* ---------------- 工具卡：名字尽量不折行 ----------------
   "Substance 3D Painter" / "Marvelous Designer" 在 6 列里放不下会断成两行，
   一排卡高低不齐。用**流体字号**（按视口缩放）+ 收紧字距 + 减小左右内边距，
   给文字腾出空间；再加 hyphens/nowrap 控制断词。 */
.tool {
  padding: clamp(14px, 1.6vw, 20px) 6px;
  /* 卡片加一层极淡的纵向渐变，暗场里不再是一块平色 */
  background: linear-gradient(180deg,
    rgba(240, 236, 227, 0.028) 0%,
    rgba(240, 236, 227, 0.012) 58%,
    rgba(240, 236, 227, 0.004) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.05);
}
.tool h4 {
  /* 11 ~ 12.6px 之间随视口走，比固定 13.5px 更不容易折行 */
  font-size: clamp(10.5px, 0.82vw, 12.6px);
  letter-spacing: -0.005em;
  line-height: 1.3;
  /* 长英文单词不要从中间断开（Substance / Marvelous） */
  hyphens: none;
  overflow-wrap: normal;
  word-break: keep-all;
}
.tool:hover {
  background: linear-gradient(180deg,
    rgba(207, 169, 95, 0.075) 0%,
    rgba(207, 169, 95, 0.03) 60%,
    rgba(207, 169, 95, 0.012) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.1),
              0 12px 28px rgba(0, 0, 0, 0.34);
}
/* 图标底托：静止时也有一点内高光，别是一块死灰 */
.tool-icon {
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.08);
  transition: color 0.5s var(--ease), border-color 0.5s var(--ease),
              box-shadow 0.5s var(--ease), background 0.5s var(--ease);
}
.tool:hover .tool-icon {
  background: rgba(207, 169, 95, 0.1);
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.14),
              0 0 18px rgba(207, 169, 95, 0.16);
}

/* ---------------- 卡片纵深：给主要卡片叠一层顶部微光 ----------------
   纯描边在暗场里显平；加一条顶部高光带就有"受光"的感觉。 */
.vfx-cell::before,
.still::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 38%;
  background: linear-gradient(180deg, rgba(255, 245, 214, 0.055), transparent);
  pointer-events: none;
  z-index: 1;
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}
.vfx-cell:hover::before { opacity: 1; }
/* .still 需要定位上下文才能用绝对定位的伪元素 */
.still { position: relative; }
.still::before { border-radius: var(--radius-md); }

/* ---------------- 导航当前项：加一条底部金线 ----------------
   原来只有暗金底，区域感偏弱；补一条短金线做"当前位置"的锚。 */
.nav-links a.is-current {
  position: relative;
  color: var(--fg);
}
.nav-links a.is-current::after {
  content: "";
  position: absolute;
  left: 50%; bottom: 2px;
  transform: translateX(-50%);
  width: 16px; height: 1.5px;
  border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--accent-hi), transparent);
}

/* ---------------- 首屏 lead：和主标题拉开层级 ----------------
   副标题原来紧贴大字，字号偏小；加一点字距和亮度让它站得住。 */
.hero-lead {
  letter-spacing: 0.015em;
  color: rgba(240, 236, 227, 0.78);
}

/* ---------------- 剧照 / 卡片图注：悬停时带一点金 ----------------
   图注从灰变金，和整站的强调色呼应。 */
.still:hover figcaption { color: rgba(207, 169, 95, 0.92); }
.vfx-cell:hover .vfx-meta h3 { color: var(--accent-hi); }
.vfx-meta h3 { transition: color 0.5s var(--ease); }

/* ============================================================
   ★ 第三轮：手机端横向溢出修复 + 收尾
   ============================================================ */

/* 根因：首屏背景是"放大铺满"的绝对定位元素，比视口宽。
   所在分区不裁剪的话，整个页面会被撑宽（实测手机端多出 25px）。
   给首屏自己加裁剪 —— 比在 body 上兜底更对症。 */
.sec-hero { overflow: hidden; }

/* 兜底：暗场站到处是放大的装饰元素（光斑 / 放大背景 / 超宽渐变），
   以后再出现类似溢出也不会撑破页面。
   用 overflow-x: clip 而不是 hidden —— clip 不产生滚动容器，
   不会影响 position:fixed 的导航 / 浮动按钮 / 全屏弹层。 */
html, body { overflow-x: clip; }
@media (min-width: 900px){
  .sec-head {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    column-gap: clamp(28px, 5vw, 80px);
    align-items: end;
  }
  .sec-head > .eyebrow { grid-column: 1 / -1; }
  .sec-head > .sec-title { grid-column: 1; margin-bottom: 0; }
  .sec-head > .sec-desc { grid-column: 2; padding-bottom: 4px; }}
@media (max-width: 900px){
  .tool-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .stills { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stills--portrait { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .stills--process { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .threed-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .about-grid { grid-template-columns: 1fr; }
  .about-media .media-slot { aspect-ratio: 16 / 10; }}
@media (max-width: 560px){
  .tool-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .threed-grid { grid-template-columns: 1fr; }}
@media (prefers-reduced-motion: reduce){
  .back-to-works { transition: opacity 0.2s linear, visibility 0.2s linear; transform: none; }
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .hero-bg, .logo .dot, .scroll-hint i { animation: none; }}
@media (max-width: 640px){
  .back-to-works {
    right: 12px;
    bottom: calc(14px + env(safe-area-inset-bottom, 0px));
    padding: 10px 16px 10px 14px;
    font-size: 12.5px;
  }
  .vfx-grid { grid-template-columns: 1fr; }
  .stills--certs { grid-template-columns: 1fr; }
  .stills--process { grid-template-columns: 1fr; }
  .stills--portrait { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .visual-grid { grid-template-columns: 1fr; }
  .cta-facts { grid-template-columns: 1fr; row-gap: 4px; }
  .cta-facts dt { margin-top: 12px; }
  .cta-facts dd { padding-top: 0; border-top: 0; }
  .cta-facts dd:not(:last-of-type) { padding-bottom: 10px; border-bottom: 1px solid var(--line); }}
@media (max-width: 620px){
  .threed-grid { grid-template-columns: 1fr; }}
@media (max-width: 820px){
  .threed-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }}
@media (max-width: 1200px){
  .nav-links, .nav-cta { display: none; }
  .hamburger { display: flex; }}
@media (max-width: 520px){
  .stats { gap: 26px; }
  .lb-nav { width: 42px; height: 56px; font-size: 26px; }
  .lb-prev { left: 8px; }
  .lb-next { right: 8px; }
  .qr { width: 100%; max-width: 260px; }}
@supports not (overflow: clip){
  html, body { overflow-x: hidden; }}


/* ============================================================
   作品总览 · 手风琴（按 superahram.top 的手法重做）
   ------------------------------------------------------------
   参考站的做法（逐条对应）：
     · flex 比例展开          flex:1 -> .is-open flex:5.4
     · 未选中图去色压暗        grayscale(1) brightness(.55)
       选中图恢复彩色并微放大   grayscale(0) brightness(.95) scale(1.035)
     · 独立渐变遮罩元素        .ov-shade
     · 收起态标题竖排          writing-mode: vertical-rl
       选中态转横排、字号跳档
     · 左上角编号常驻          .ov-no
     · 「进入分区 ↗」仅选中出现 .ov-open
     · 底部页脚栏收口          .ov-foot

   保持自己视觉语言的地方（不照抄）：
     · 配色仍是黑 + 金，不换成参考的米白/墨绿纸感
     · 展开宽按 4:3 走（高度 600 -> 800px），封面内容尽量完整不被裁；
       参考用的是竖图 cover，裁掉无妨，但我这边是界面截图，裁了会丢信息
     · 保留悬停播放预览视频（参考没有这个能力）
   ============================================================ */

/* ---------- 轨道 ----------
   从内容宽度里放出来占满整屏（只留页边距）。
   对称算法：宽度和 margin 都用视口单位，滚动条差额一起抵消。 */
.ov-rail {
  display: flex;
  gap: clamp(8px, 0.9vw, 14px);
  align-items: stretch;
  height: clamp(560px, 68vh, 860px);
  /* 宽度跟随内容栏（不再撑满视口）。
     曾经用 `calc(100vw - 2*var(--pad))` + 负 margin 出血到整屏，
     结果它是全站唯一突破内容栏 1240 的区块 ——
     在 2048 屏上轨道 1920、别的分区 1240，差 680px，
     看起来就是"没对齐"而不是"有气势"。已收回。 */
  width: 100%;
  max-width: none;
  margin-left: 0;
  margin-right: 0;
}

/* ---------- 单条 ----------
   flex:1 让它按比例分配宽度 —— 这是参考最核心的一招，
   比"写死宽度 + transition width"更顺，且窗口缩放时比例恒定。 */
.ov-item {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: #12100c;
  cursor: pointer;
  outline: none;
  isolation: isolate;
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.05), var(--sh-1);
  transition: flex-grow 0.72s var(--ease), border-color 0.5s var(--ease),
              box-shadow 0.6s var(--ease);
}

.ov-item > img,
.ov-item > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -2;
  /* 参考：静止是黑白压暗的，选中才上色 —— 一排放一起时对比非常干净 */
  filter: grayscale(1) brightness(0.55);
  transform: scale(1);
  transition: filter 0.55s var(--ease), transform 0.8s var(--ease),
              opacity 0.7s var(--ease);
}

/* 预览视频只在展开时淡入（保留原有能力） */
.ov-item > video { opacity: 0; }
.ov-item.is-open > video { opacity: 1; }

/* 悬停时先"活"一点，但不上满色 —— 真正的上色留给选中态 */
.ov-item:hover:not(.is-open) > img {
  filter: grayscale(0.55) brightness(0.72);
}

.ov-item.is-open > img,
.ov-item.is-open > video {
  filter: grayscale(0) brightness(0.95);
  transform: scale(1.035);          /* 参考的 1.035：几乎看不出，但画面"活" */
}

/* ---------- 渐变遮罩 ----------
   参考做成独立元素，收起/展开可以给不同渐变，互不干扰。 */
.ov-shade {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(9, 14, 14, 0.28) 0%,
    rgba(9, 14, 14, 0) 35%,
    rgba(5, 11, 10, 0.60) 75%,
    rgba(5, 10, 9, 0.92) 100%);
  transition: background 0.6s var(--ease), opacity 0.6s var(--ease);
}

/* 选中态：底部压得更实，托住要出现的标题/副标题/按钮 */
.ov-item.is-open .ov-shade {
  background: linear-gradient(180deg,
    rgba(9, 14, 14, 0.12) 0%,
    rgba(9, 14, 14, 0) 30%,
    rgba(5, 11, 10, 0.68) 68%,
    rgba(5, 10, 9, 0.96) 100%);
}

/* ---------- 左上角编号（常驻） ----------
   参考用等宽字体、字距 2px；我沿用等宽 + 金色，落在自己的体系里。 */
.ov-no {
  position: absolute;
  top: 18px;
  left: 18px;
  z-index: 2;
  font-family: var(--font-en);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.18em;
  color: rgba(240, 236, 227, 0.62);
  transition: color 0.5s var(--ease);
}
.ov-item.is-open .ov-no { color: var(--accent); }

/* ---------- 文字带 ---------- */
.ov-body {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  padding: 16px 16px 18px;
}

/* ---------- 收起态：标题竖排（参考的关键手法） ----------
   竖排让窄条"有内容"，而不是一条空白的图。
   底部对齐、从下往上读，像书脊。 */
.ov-item:not(.is-open) .ov-body {
  top: auto;
  bottom: 22px;
  padding: 0 0 0 0;
  display: flex;
  justify-content: center;
}
.ov-item:not(.is-open) .ov-anim { display: block; }
.ov-item:not(.is-open) .ov-title {
  writing-mode: vertical-rl;
  text-orientation: mixed;
  white-space: nowrap;
  margin: 0;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.14em;
  color: rgba(240, 236, 227, 0.9);
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.9));
}

/* ---------- 选中态：横排 + 字号跳档 ---------- */
.ov-item.is-open { flex-grow: 5.4; border-color: rgba(207, 169, 95, 0.5); }
.ov-item.is-open {
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.16), var(--sh-3),
              0 0 44px rgba(207, 169, 95, 0.14);
}
.ov-item.is-open .ov-body {
  bottom: 0;
  padding: 16px 22px 22px;
  background: none;
  display: block;
}
.ov-item.is-open .ov-anim { display: block; }
.ov-item.is-open .ov-title {
  writing-mode: horizontal-tb;
  white-space: normal;
  margin: 0;
  font-size: clamp(22px, 2.4vw, 34px);   /* 参考 25->38；我按 1080 基准收一档 */
  font-weight: 500;
  letter-spacing: 0.1em;
  line-height: 1.25;
  color: var(--fg);
}

/* 副标题与链接：只在选中态出现（参考同理） */
.ov-sub {
  margin: 10px 0 0;
  font-size: clamp(12px, 1vw, 13.5px);
  line-height: 1.6;
  color: rgba(240, 236, 227, 0.72);
  white-space: nowrap;
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  transition: opacity 0.45s var(--ease) 0.06s, max-height 0.45s var(--ease) 0.06s;
}
.ov-item.is-open .ov-sub { opacity: 1; max-height: 3em; }

/* ---------- 「进入分区 ↗」：仅在选中条出现（参考手法） ---------- */
.ov-open {
  display: none;
}
.ov-item.is-open .ov-open {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid rgba(207, 169, 95, 0.32);
  max-width: 420px;
  font-size: 11.5px;
  letter-spacing: 0.14em;
  color: var(--accent-hi);
  white-space: nowrap;
}
.ov-open-a {
  font-size: 19px;
  line-height: 1;
  transition: transform 0.45s var(--ease);
}
.ov-item.is-open:hover .ov-open-a { transform: translate(3px, -3px); }

/* 次级入口（有的条目要指到多个分区） */
.ov-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  transition: opacity 0.45s var(--ease) 0.1s, max-height 0.45s var(--ease) 0.1s;
}
.ov-item.is-open .ov-links { opacity: 1; max-height: 4em; }
.ov-links a {
  padding: 5px 11px;
  border: 1px solid rgba(207, 169, 95, 0.32);
  border-radius: 999px;
  font-size: 11.5px;
  color: var(--fg-dim);
  background: rgba(14, 12, 9, 0.62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: color 0.4s var(--ease), border-color 0.4s var(--ease),
              background 0.4s var(--ease);
}
.ov-links a:hover {
  color: var(--accent-hi);
  border-color: rgba(207, 169, 95, 0.6);
  background: rgba(207, 169, 95, 0.16);
}

.ov-item:focus-visible { border-color: rgba(207, 169, 95, 0.7); }

/* ---------- 底部页脚栏（参考的收口手法） ---------- */
.ov-foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 20px;
  margin-top: 14px;
  width: 100%;
  max-width: none;
  margin-left: 0;
  margin-right: 0;
  font-family: var(--font-en);
  font-size: 9.5px;
  letter-spacing: 0.22em;
  color: rgba(240, 236, 227, 0.34);
  text-transform: uppercase;
}

/* ---------- 中等屏：高度降一档，展开比例调大一点 ---------- */
@media (max-width: 1400px) {
  .ov-rail { height: 520px; }
  .ov-item.is-open { flex-grow: 4.8; }
  .ov-item:not(.is-open) .ov-title { font-size: 14px; }
}

/* ---------- 窄屏 / 触屏：改成竖排堆叠，点一下展开 ----------
   参考在这里也是把竖条改成横向滚动；我改成竖排是因为
   手机上一排窄条竖排标题可读性差，点击目标也太小。 */
@media (max-width: 900px) {
  .ov-rail {
    height: auto;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    max-width: none;
    margin-left: 0;
    margin-right: 0;
  }
  .ov-item {
    flex: none;
    height: 150px;
    transition: height 0.6s var(--ease), border-color 0.5s var(--ease);
  }
  .ov-item.is-open { height: 340px; }

  /* 竖排标题在横条里不合适，改回横排 */
  .ov-item:not(.is-open) .ov-body {
    position: absolute;
    inset: auto 0 0 0;
    bottom: 0;
    padding: 40px 16px 14px;
    display: block;
  }
  .ov-item:not(.is-open) .ov-title {
    writing-mode: horizontal-tb;
    font-size: 15px;
    letter-spacing: 0.06em;
  }
  .ov-sub, .ov-links { opacity: 1; max-height: 4em; }
  .ov-item.is-open .ov-title { font-size: 22px; }

  .ov-foot {
    width: 100%;
    margin-left: 0;
    margin-right: 0;
    font-size: 9px;
    letter-spacing: 0.16em;
  }
}

@media (max-width: 560px) {
  .ov-item { height: 130px; }
  .ov-item.is-open { height: 300px; }
  .ov-item.is-open .ov-title { font-size: 19px; }
  .ov-sub { white-space: normal; }
}

@media (prefers-reduced-motion: reduce) {
  .ov-item, .ov-item > img, .ov-item > video { transition: none !important; }
}


/* ---------- 手风琴精修 A：展开态的金色短标 ----------
   标题上方一道从左侧 0->1 生长的金线，是整站已有的语汇
   （分区标题的下划线、收起态的图注都是这个套路），
   加在这里让本区块与全站连成一套，也拉开与参考站的差异。 */
.ov-item.is-open .ov-anim { position: relative; padding-top: 16px; }
.ov-item.is-open .ov-anim::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 46px; height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--accent-hi), var(--accent), rgba(207, 169, 95, 0));
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.7s var(--ease) 0.12s;
}
.ov-item.is-open.is-in .ov-anim::before,
.ov-item.is-open .ov-anim::before { transform: scaleX(1); }

/* 收起态不需要这条线 */
.ov-item:not(.is-open) .ov-anim { padding-top: 0; }
.ov-item:not(.is-open) .ov-anim::before { display: none; }

/* ---------- 手风琴精修 B：竖排标题居中 ----------
   参考是贴左下；窄条居中更像"书脊"，而且五条宽度一致时居中最整齐。 */
.ov-item:not(.is-open) .ov-body {
  left: 0; right: 0;
  display: flex;
  justify-content: center;   /* 横轴居中（竖排文字里横轴 = 文字列方向） */
  align-items: flex-end;     /* 底对齐，从下往上读 */
  padding: 0 0 24px;
}
.ov-item:not(.is-open) .ov-anim { display: flex; justify-content: center; }

/* 竖排标题的字距略收，避免长名字顶到卡片外 */
.ov-item:not(.is-open) .ov-title { letter-spacing: 0.1em; }

/* ---------- 手风琴精修 C：展开态下边距更从容 ---------- */
.ov-item.is-open .ov-body { padding: 18px 26px 24px; }
.ov-item.is-open .ov-open { margin-top: 18px; max-width: 460px; }

/* ---------- 手风琴精修 D：选中条的金色发丝（沿用旧版的收尾手法） ---------- */
.ov-item.is-open::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  z-index: 3;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
}


/* ---------- 手风琴修正：窄屏折叠态不要露出副标题/链接 ----------
   前面的 @media(900px) 里写了无条件的 `.ov-sub, .ov-links { opacity:1 }`，
   导致没展开的条也显示副标题和链接、和标题挤在一起。
   这里显式覆盖：收起态归零，只有 .is-open 才显示。 */
@media (max-width: 900px) {
  .ov-item:not(.is-open) .ov-sub,
  .ov-item:not(.is-open) .ov-links {
    opacity: 0 !important;
    max-height: 0 !important;
    overflow: hidden !important;
    margin: 0 !important;
  }
  .ov-item.is-open .ov-sub { opacity: 1 !important; max-height: 3em !important; }
  .ov-item.is-open .ov-links { opacity: 1 !important; max-height: 4em !important; }

  /* 收起态：只有编号 + 标题，压在底部渐变上 */
  .ov-item:not(.is-open) .ov-body { padding: 46px 16px 14px; }
  .ov-item:not(.is-open) .ov-title { font-size: 16px; letter-spacing: 0.08em; }
}

/* ---------- 语义化修正：工具名 / 二维码名从 h4 改成 span ----------
   原来是 h4，导致文档大纲从 h1 直接跳到 h4。它们只是标签文字，
   换成 span 后视觉完全不变，大纲恢复正常。 */
.tool .tool-name,
.tool h4 {
  display: block;
  margin: 0 0 5px;
  font-size: clamp(10.5px, 0.82vw, 12.6px);
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.3;
  color: var(--fg);
  hyphens: none;
  overflow-wrap: normal;
  word-break: keep-all;
}

.qr .qr-name,
.qr h4 {
  display: block;
  margin: 14px 0 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--fg);
}

.qr .qr-note,
.qr p {
  color: var(--fg-dim);
}


/* ============================================================
   版式定稿：克制比例 + 单点出血
   ------------------------------------------------------------
   用户反馈"太大了，看的时候有点不方便"，据此定稿：

   内容栏回到 1240px —— 大屏上一屏能同时看到"一个主媒体 + 若干卡片"，
   滚动节奏舒服；这也是作品集/摄影站常用的阅读宽度。
   **只有作品总览的手风琴保持全宽**：它是第一屏的总览、是刻意的引导，
   也让整站有一个呼吸口，而不是每个区块一样宽（一样宽反而平）。

   高级感不再靠"放大"，改从这几处来（见下）。
   ============================================================ */
:root { --maxw: 1240px; }

/* 分区标题区：底对齐改顶对齐。
   原来 align-items:end 让右边那句短说明贴着标题底线，
   看起来就像"说明和标题不在一条线上"。参考站是顶对齐。 */
@media (min-width: 900px) {
  .sec-head { align-items: start; }
  .sec-head > .sec-desc { margin-top: 4px; }
}

/* ---------------- 高级感 · 一：统一比例 ----------------
   同一个分区里所有卡片同高同比例，参差感最伤质感。
   顺手把三维区恢复 3×3（用户明确要 3*3，我此前擅自加列是错的）。 */
.threed-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (min-width: 1560px) {
  /* 宽屏也不改列数：3×3 是定版 */
  .threed-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.vfx-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* ---------------- 高级感 · 二：文字的呼吸 ----------------
   正文行高与段距拉开一档；行长收在 60ch 左右最好读。
   这比"把字放大"更能提升质感。 */
.sec-desc {
  line-height: 1.85;
  max-width: 58ch;
  letter-spacing: 0.002em;
}
.vfx-meta p,
.still figcaption {
  line-height: 1.7;
  letter-spacing: 0.01em;
}

/* ---------------- 高级感 · 三：分区留白 ----------------
   分区之间的上下留白再给足一点，让内容块彼此独立、不挤在一起。 */
.sec { padding-top: var(--space-sec); padding-bottom: var(--space-sec); }

/* ---------------- 高级感 · 四：卡片的静止状态不加噪 ----------------
   静止时只保留极淡的内描边，所有"亮"都留给悬停/选中，
   这样一屏里有主次，不花。 */
.vfx-cell,
.still img {
  transition: transform 0.55s var(--ease), border-color 0.5s var(--ease),
              box-shadow 0.55s var(--ease), filter 0.5s var(--ease);
}

/* ---------------- 高级感 · 五：工具箱回到 6 列 x 2 行 ----------------
   1240 栏宽下 6 列每格约 190px，"两行排完"的原始意图。
   长名字靠收紧字距把行数压到最少（此前已调过字号）。 */
@media (min-width: 1100px) {
  .tool-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}
@media (min-width: 1500px) {
  .tool-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}


/* ============================================================
   作品总览：收回内容栏宽度
   ------------------------------------------------------------
   用户第二次指出"作品这个还是全屏"。
   此前它用 `width: calc(100vw - 2*var(--pad))` + 负 margin 撑满整个视口，
   在 2048 屏上轨道宽 1920，而其他分区内容栏只有 1240 —— 差 680px，
   是全站唯一突破内容栏的区块，所以"看起来和别人不一样"。

   改成跟随内容栏：宽度用 100%，去掉负 margin。
   高度沿用 600px（展开条会随之变窄，比例更收敛）。
   ============================================================ */
.ov-rail {
  width: 100%;
  max-width: none;
  margin-left: 0;
  margin-right: 0;
}

.ov-foot {
  width: 100%;
  max-width: none;
  margin-left: 0;
  margin-right: 0;
}

/* 展开比例略调：轨道变窄后 5.4 倍会让展开条相对更宽，
   收到 4.2 让"展开 vs 收起"的对比仍然明显但不夸张 */
.ov-item.is-open { flex-grow: 4.2; }
@media (max-width: 1400px) {
  .ov-item.is-open { flex-grow: 3.8; }
}


/* ============================================================
   版式精修：借参考站的手法（保留自己的单页滚动）
   ------------------------------------------------------------
   用户："参考那个人的感觉我还能优化些什么，我感觉他的看上去好一点，
         但是不方便（不是下滑是点击）"

   他"看上去好一点"主要来自这几项（都很便宜，不靠内容量）：
     ① 字重 450 —— 不是 250（太飘）也不是 700（太憨）
     ② 标题字距 .08em
     ③ 行高 1.9+
     ④ 顶部阅读进度条
     ⑤ 细横线夹出的信息带
     ⑥ 锚点偏移（跳转后标题不被顶栏挡）
     ⑦ 低饱和配色
   这七项都借过来了。**没有借他的多页结构** —— 那正是"点击不方便"的来源，
   单页滚动是我们相对他的优势，要留着。
   ============================================================ */

/* ---------- ① ② 字重与字距 ----------
   原来 .sec-title 是 font-weight: 250、letter-spacing: 0.01em。
   250 在暗底上会"发飘"（笔画太细、边缘被背景吃掉），
   450 是衬线/无衬线都稳的中间值，也是参考站的取值。 */
.sec-title {
  font-weight: 450;
  letter-spacing: 0.06em;
  line-height: 1.22;
}
/* 首屏大标题同理，但字重略收（字号越大越不能重），字距给足 */
.hero-title {
  font-weight: 350;
  letter-spacing: 0.04em;
}

/* ---------- ③ 行高给足 ----------
   正文 1.75 -> 1.92，说明文字 1.75 -> 1.9。
   中文在暗底上比英文更需要行距，行高不够会显得"挤成一坨"。 */
.sec-desc { line-height: 1.92; }
.sec-body p, .modal p, .cta-desc { line-height: 1.9; }

/* ---------- ⑦ 低饱和配色 ----------
   参考站正文不是纯白，而是带灰绿的 #a6b0a4 / #b9c0b9。
   纯白在暗底上对比过强、看久了累；略降饱和更"稳"。
   我这里保持自己的暖调，但把亮度压下来一档。 */
:root {
  --fg: #ece7dd;                       /* 原 #f0ece3，压一点 */
  --fg-dim: rgba(236, 231, 221, 0.68);
  --line: rgba(236, 231, 221, 0.11);
}

/* ---------- ⑥ 锚点偏移 ----------
   跳转到某个分区时，标题会被吸顶导航挡住一点。
   加 scroll-margin-top 让滚动停在标题上方留出顶栏高度。 */
main [id] { scroll-margin-top: 96px; }
@media (max-width: 720px) { main [id] { scroll-margin-top: 76px; } }

/* ---------- ④ 阅读进度条 ----------
   顶部 2px 金线，跟着滚动 scaleX 伸缩。
   用 transform 而不是 width：不触发重排，滚动时不掉帧。
   平时（在顶部）淡出，滚动起来才显形。 */
.reading-progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: 200;
  pointer-events: none;
  transform-origin: left center;
  transform: scaleX(0);
  background: linear-gradient(90deg, var(--accent-lo), var(--accent), var(--accent-hi));
  box-shadow: 0 0 10px rgba(207, 169, 95, 0.45);
  opacity: 0;
  transition: opacity 0.4s var(--ease);
}
.reading-progress.is-on { opacity: 1; }

/* ---------- ⑤ 细横线夹出的信息带 ----------
   参考站在首屏下面有一条上下都用细线夹住的信息带：
   左边是栏目名，右边是一排快捷入口。
   这种"编辑排版"的横带比单纯堆卡片更显秩序。
   我放在作品总览的页脚栏上（原本只有一行小字，太轻）。 */
.ov-foot {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 13px 0;
  margin-top: 16px;
}

/* ---------- 卡片标题也给一点字重 ----------
   参考站的 h2/h3/h4 都是 450，不是 500/700。
   统一到这个值，整站的"笔势"才一致。 */
.vfx-meta h3 { font-weight: 450; letter-spacing: 0.02em; }
.still figcaption { letter-spacing: 0.03em; }
.tool .tool-name { font-weight: 500; }


/* ============================================================
   优化 · 首屏信息带
   ------------------------------------------------------------
   参考站的"编辑排版横带"：上下各一条细线夹住内容，中间分栏。
   放在首屏的价值：HR 在第一屏就能看到"求职意向 / 学历 / 可实习"，
   不用往下翻 —— 对求职作品集这是最直接的一项优化。

   细节：
     · 上下细线用 border，不用额外元素
     · 左栏是标签（小字、弱色），右栏是内容（略亮）—— 层次靠对比不是靠字号
     · 只在宽屏分两栏；窄屏堆叠成上下两行
   ============================================================ */
.hero-band {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(16px, 3vw, 52px);
  width: 100%;
  max-width: 720px;
  margin: clamp(26px, 3.4vw, 42px) auto 0;
  padding: clamp(13px, 1.5vw, 18px) 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  text-align: left;
}

.hb-cell {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
}

.hero-band .hb-k {
  margin: 0;
  font-family: var(--font-en);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  color: var(--fg-faint);
  white-space: nowrap;
}

.hero-band .hb-v {
  margin: 0;
  font-size: clamp(12.5px, 1.05vw, 14px);
  line-height: 1.5;
  color: rgba(240, 236, 227, 0.86);
  min-width: 0;
}

.hero-band .hb-note {
  margin-left: 9px;
  font-style: normal;
  font-size: 11.5px;
  color: var(--accent);
  white-space: nowrap;
}

/* 窄屏：堆叠，标签与内容同一行、两条上下排 */
@media (max-width: 720px) {
  .hero-band {
    grid-template-columns: 1fr;
    gap: 11px;
    max-width: none;
    padding: 13px 2px;
  }
  .hero-band .hb-k { font-size: 10px; letter-spacing: 0.12em; }
  .hero-band .hb-v { font-size: 12px; }
  .hero-band .hb-note { display: block; margin: 3px 0 0; }
}

/* ============================================================
   优化 · 卡片信息层次
   ------------------------------------------------------------
   原来标题 15px/500 与说明 11.5px 之间只差一档，整块看着平。
   拉开：标题加重加字距，说明降一档并收窄行距 —— 层次靠对比。
   ============================================================ */
.vfx-meta h3 {
  font-weight: 450;
  letter-spacing: 0.03em;
}
.vfx-meta p {
  font-size: 11.5px;
  letter-spacing: 0.02em;
  color: rgba(240, 236, 227, 0.52);
}

/* ============================================================
   优化 · 区块内小节导航（参考站的 project-outline）
   ------------------------------------------------------------
   参考站在每个项目页顶部有一条横带，列出本页各小节、可点跳转。
   我们是单页站，所以做成**每个分区的"内含条目"索引**：
   不换页、不额外加载，只是跳到本分区内对应位置。
   仅在有多个条目的分区生成（特效 5 条、三维 9 条、游戏 1 条）。
   ============================================================ */
.sec-outline {
  display: flex;
  align-items: center;
  gap: clamp(10px, 1.6vw, 22px);
  flex-wrap: wrap;
  margin: calc(-1 * clamp(10px, 1.4vw, 20px)) 0 clamp(18px, 2.4vw, 30px);
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
}
.sec-outline .so-label {
  font-family: var(--font-en);
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--fg-faint);
  white-space: nowrap;
}
.sec-outline a {
  position: relative;
  font-size: 12px;
  color: var(--fg-dim);
  white-space: nowrap;
  transition: color 0.35s var(--ease);
}
.sec-outline a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -3px;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.4s var(--ease);
}
.sec-outline a:hover { color: var(--accent-hi); }
.sec-outline a:hover::after { transform: scaleX(1); }


/* 小节导航跳转后的短暂高亮：让人知道"跳到了哪一条"。
   用 outline 而不是 box-shadow，避免和卡片自己的阴影打架。 */
.vfx-cell.is-flash,
.still.is-flash {
  animation: flashTarget 1.25s var(--ease);
}
@keyframes flashTarget {
  0%   { outline: 2px solid rgba(207, 169, 95, 0);    outline-offset: 6px; }
  18%  { outline: 2px solid rgba(207, 169, 95, 0.75); outline-offset: 6px; }
  100% { outline: 2px solid rgba(207, 169, 95, 0);    outline-offset: 6px; }
}
@media (prefers-reduced-motion: reduce) {
  .vfx-cell.is-flash, .still.is-flash { animation: none; }
}


/* ============================================================
   联系区 · 二维码排定稿
   ------------------------------------------------------------
   决定：联系区**只用二维码一种形态**，不用链接卡。
   理由：二维码是统一的视觉形态 —— 等高同宽一排，一眼就懂"扫我"；
   混进文字链接会让这一排变参差。
   外部主页（B 站 / 抖音）走底部的按钮排，两个用途分开，互不干扰。

   原来每张卡的宽度由"图片自身比例 + max-width:260px"决定，
   图片比例不同卡片就参差（实测 78px / 91px 宽）。
   这里统一成固定宽度上限 + 等高，一排几张都整齐。
   ============================================================ */
.qr {
  width: clamp(150px, 15vw, 210px);
  max-width: 210px;
}

/* 二维码卡的白底槽：统一高度已经有一档了，
   这里只把圆角/描边再收一下，让一排四张"成组" */
.qr-slot { border-radius: 12px; }

/* 间距：4 张时要能放下，所以比原来紧一点 */
.qr-row { gap: clamp(14px, 2.2vw, 34px); }

/* 窄屏：两张一行排两行，不要挤成一条 */
@media (max-width: 760px) {
  .qr-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 22px 16px;
    justify-items: center;
  }
  .qr { width: 100%; max-width: 190px; }
}


/* ============================================================
   三项改动的样式
   ============================================================ */

/* ---------- ① 顶部导航的编号小标 ----------
   和首屏 / 手风琴 / 分区标题的 01~08 是同一套体系，
   把顶部导航也拉进这个体系（原来只有纯文字，像另一套东西）。
   用等宽数字：宽度一致，一排导航项才能对齐整齐。 */
.nav-links a .nav-no,
.mobile-menu a .nav-no {
  font-family: var(--font-en);
  font-style: normal;
  font-variant-numeric: tabular-nums;
  font-size: 9.5px;
  letter-spacing: 0.06em;
  margin-right: 7px;
  color: var(--fg-faint);
  transition: color 0.35s var(--ease);
}
/* 悬停 / 当前项：编号转金，和已有的金色下划线一起指示"位置" */
.nav-links a:hover .nav-no { color: rgba(207, 169, 95, 0.8); }
.nav-links a.is-current .nav-no {
  color: var(--accent-hi);
  filter: drop-shadow(0 0 6px rgba(207, 169, 95, 0.4));
}

/* 移动菜单里的编号：字号大一点、间距宽一点（那边是竖排大项） */
.mobile-menu a .nav-no {
  font-size: 11px;
  margin-right: 12px;
  opacity: 0.7;
}

/* ---------- ② 按钮里的图标 / 箭头 ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
}
.btn-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  flex: none;
}
.btn-ico svg {
  width: 100%;
  height: 100%;
  fill: currentColor;      /* 跟着按钮文字色，悬停一起变金 */
  display: block;
}
/* 外链箭头：原来只是文字里的 ↗，现在单独成元素，可以单独动 */
.btn-arrow {
  font-size: 13px;
  line-height: 1;
  opacity: 0.75;
  transition: transform 0.4s var(--ease), opacity 0.4s var(--ease);
}
.btn:hover .btn-arrow {
  opacity: 1;
  transform: translate(2px, -2px);
}

/* ---------- ③ 首屏按钮排 ---------- */
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  margin-top: clamp(22px, 2.8vw, 34px);
}
/* 首屏只有一个按钮时不要显得孤零零：给足横向内边距，
   让它像个"入口"而不是普通小按钮 */
.hero-actions .btn {
  padding: 11px 26px;
  font-size: 13.5px;
  letter-spacing: 0.04em;
}


/* ============================================================
   ① 统一的跳转偏移
   ------------------------------------------------------------
   实测：顶栏导航（CSS scroll-margin-top: 96px）和首屏按钮 /
   小节导航（JS 偏移 84 / 110px）是三套值，落点差了近 100px，
   同一个站两种跳转手感不一致。

   现在抽成一个变量，CSS 与 JS 共读（JS 侧见 main.js 的 jumpOffset()）。
   数值从 96 收到 88：分区标题上方原本留了约 300px 空白（`.sec` 自身
   的 padding-top 叠加所致），收一点让标题更靠近导航底边，
   视线不用往下找。
   ============================================================ */
:root { --jump-offset: 88px; }

main [id] { scroll-margin-top: var(--jump-offset); }
@media (max-width: 720px) { main [id] { scroll-margin-top: 76px; } }

/* ============================================================
   ② 配色：给金色配一个深青绿（少量使用）
   ------------------------------------------------------------
   金色是暖、黄、高饱和的。它最搭的**不是另一种暖色**，
   而是**深冷色**做对照 —— 暖金压在冷深底上会更"跳"、更贵，
   这是奢侈/珠宝/酒店那一路的经典配法；参考站用的也正是这一路
   （墨绿 #171b1b、苍绿系文字）。

   用量原则：金色仍是唯一主色。深青绿只做"第二强调"：
     · 卡片悬停时的冷色微光
     · 二维码卡的背衬（白卡在暖光下偏黄，用一点冷色中和）
     · 作品总览未选中条的压色（去色压暗时偏冷，选中转暖金，
       冷暖对撞让"选中"更明显）
   ============================================================ */
:root {
  /* 深青绿三档。低饱和是关键 —— 一旦饱和度高就变成"赛博绿"，
     和暖金的贵气完全对冲。 */
  --jade: #2f4f4a;          /* 本色：用于背衬 */
  --jade-hi: #6fb3a4;        /* 高光：用于极细的描边/光点 */
  --jade-dim: rgba(47, 79, 74, 0.5);
}

/* 卡片悬停：金色描边之外，补一层冷色微光。
   冷暖同时出现，比纯金色光更有层次。 */
.vfx-cell:hover,
.still:hover img {
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.14),
              inset 0 0 0 1px rgba(207, 169, 95, 0.12),
              var(--sh-2),
              0 0 30px rgba(207, 169, 95, 0.12),
              0 0 54px rgba(111, 179, 164, 0.10);
}

/* 二维码白卡：在暖金环境里偏黄，衬一层冷色底中和 */
.qr-slot {
  background: linear-gradient(180deg, #fbfaf6 0%, #eef1ee 100%);
  box-shadow: var(--sh-2), 0 0 0 1px var(--jade-dim) inset;
}

/* 作品总览未选中条：去色时略偏冷，选中转暖金 —— 冷暖对撞更醒目 */
.ov-item:not(.is-open) > img {
  filter: grayscale(1) brightness(0.55) sepia(0.12) hue-rotate(150deg);
}

/* 极少量：二维码卡的描边用青绿高光的一半透明，替代纯金描边，
   避免三张白卡全被金色包住显得"满" */
.qr img,
.qr-row img {
  border-color: rgba(111, 179, 164, 0.22);
}
.qr:hover img,
.qr-row img:hover {
  border-color: rgba(207, 169, 95, 0.5);
}


/* 「分区内某个部分」作为跳转目标时的额外上方留白。
   `.part-label` 自带 margin-top: clamp(38px,5vw,70px)，
   而 `.sec-head` 没有 —— 用同一套偏移会让它贴着吸顶导航（实测只剩 1px）。
   这里给一个补偿值，JS 侧由 jumpExtraFor() 读取。 */
:root { --jump-offset-extra: 56px; }

/* 顺带：被跳转到时给"部分标签"一个更明显的焦点反馈
   （它没有卡片的描边，is-flash 要换成文字/线的处理） */
.part-label.is-flash {
  animation: flashPart 1.25s var(--ease);
}
@keyframes flashPart {
  0%   { color: var(--fg); }
  20%  { color: var(--accent-hi); text-shadow: 0 0 18px rgba(207, 169, 95, 0.5); }
  100% { color: var(--fg); }
}
@media (prefers-reduced-motion: reduce) {
  .part-label.is-flash { animation: none; }
}


/* ============================================================
   ① 视频灯箱：版本切换（节选 / 原片）
   ============================================================ */
.vl-versions {
  display: none;                 /* 单版本时完全不占位 */
  gap: 8px;
  justify-content: center;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.vl-versions.is-on { display: flex; }

.vl-ver {
  padding: 7px 18px;
  border: 1px solid rgba(240, 236, 227, 0.22);
  border-radius: 999px;
  background: rgba(14, 12, 9, 0.72);
  color: rgba(240, 236, 227, 0.72);
  font-family: inherit;
  font-size: 12.5px;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease),
              background 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.vl-ver:hover {
  color: var(--fg);
  border-color: rgba(207, 169, 95, 0.45);
}
/* 当前播放那一档：金色底 + 内高光，与站内其他"选中"语言一致 */
.vl-ver.is-current {
  color: var(--accent-hi);
  border-color: rgba(207, 169, 95, 0.7);
  background: linear-gradient(160deg, rgba(246, 228, 180, 0.2), rgba(143, 111, 44, 0.16));
  box-shadow: inset 0 1px 0 var(--rim), 0 0 16px rgba(207, 169, 95, 0.16);
}
.vl-ver:focus-visible {
  outline: 2px solid var(--accent-hi);
  outline-offset: 3px;
}

/* ============================================================
   ② 渲染竞赛的导航条：滚动跟随
   ------------------------------------------------------------
   这一区很长（并了两场比赛），跟随之后随时能切到另一场。
   其他分区的 outline 不跟随 —— 内容短，跟随反而占掉一行高度。

   为什么需要这些额外声明：
     · `top` 要避开吸顶导航（实测导航底边在 y=66，取 86 留缝）
     · 跟随时必须有不透明底 + z-index，否则内容会透过来
     · 原来是"贴在分区标题下"的静态条，sticky 之后要把
       负上边距归零，否则起粘时会跳一下
   ============================================================ */
.sec-outline.is-sticky {
  position: sticky;
  top: 86px;
  z-index: 40;
  background: rgba(10, 9, 8, 0.9);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  margin-top: 0;
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}
@media (max-width: 900px) {
  .sec-outline.is-sticky { top: 70px; padding: 9px 10px; }
}


/* ============================================================
   视觉区：宽屏 4 列
   ------------------------------------------------------------
   用户反馈"大广赛太大了"+"和大广赛、蔚蓝重启放一排"。
   原来 .visual-grid 固定 2 列，条目一多就拉成很长的竖列。
   宽屏给 4 列：单条变小、一屏能看全，也更像"节选一览"。

   分档（和站内其他网格同一套思路：宽屏加列，不加尺寸）：
     <900px   1 列（手机）
     900~1300 2 列
     >=1300   3 列
     >=1700   4 列
   ============================================================ */
@media (min-width: 1300px) {
  .visual-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1700px) {
  .visual-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
/* 4 列时格子变小，说明文字的字号收一档，免得挤 */
@media (min-width: 1700px) {
  .visual-grid .vfx-meta h3 { font-size: 14px; }
  .visual-grid .vfx-meta p { font-size: 11px; }
}


/* ============================================================
   作品详情层
   ------------------------------------------------------------
   外面卡片播原片；点进去是这个全屏层，里面有：
     · 大播放器（默认原片，带声）
     · 「完整原片 / 各节选」切换按钮排
     · 节选缩略图网格（点哪个切哪个）

   沿用站内覆盖层的观感（和视频灯箱、看图器一致）：
   深色毛玻璃底 + 居中舞台 + 右上角关闭。
   ============================================================ */
.detail {
  position: fixed;
  inset: 0;
  z-index: 120;              /* 高于吸顶导航（100），低于看图器（130） */
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: clamp(16px, 3vh, 40px) clamp(14px, 3vw, 48px);
  background: rgba(6, 6, 7, 0.9);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.4s var(--ease), visibility 0.4s var(--ease);
}
.detail.is-open { opacity: 1; visibility: visible; }

.dt-inner {
  width: 100%;
  max-width: 1400px;
  transform: translateY(14px);
  transition: transform 0.5s var(--ease);
}
.detail.is-open .dt-inner { transform: translateY(0); }

.dt-close {
  position: fixed;
  top: clamp(14px, 2.4vh, 26px);
  right: clamp(14px, 2.4vw, 32px);
  width: 42px; height: 42px;
  border-radius: 50%;
  border: 1px solid rgba(240, 236, 227, 0.22);
  background: rgba(14, 12, 9, 0.72);
  color: var(--fg);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease),
              background 0.35s var(--ease);
}
.dt-close:hover {
  color: var(--accent-hi);
  border-color: rgba(207, 169, 95, 0.6);
  background: rgba(207, 169, 95, 0.14);
}

/* ---- 头部：标题 / 说明 ---- */
.dt-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  margin-bottom: 14px;
  padding-right: 56px;       /* 给关闭按钮让位 */
}
.dt-eyebrow {
  margin: 0 0 6px;
  font-family: var(--font-en);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
}
.dt-title {
  margin: 0;
  font-size: clamp(20px, 2.2vw, 30px);
  font-weight: 450;
  letter-spacing: 0.04em;
  color: var(--fg);
}
.dt-meta {
  margin: 0;
  font-size: 12.5px;
  letter-spacing: 0.06em;
  color: var(--fg-faint);
}

/* ---- 大播放器 ---- */
.dt-stage {
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--line);
  background: #000;
  box-shadow: var(--sh-3), inset 0 1px 0 rgba(255, 245, 214, 0.07);
}
.dt-stage video {
  display: block;
  width: 100%;
  max-height: 66vh;
  background: #000;
  object-fit: contain;
}

/* ---- 切换按钮排 ---- */
.dt-switch {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
  margin: 16px 0 0;
}
.dt-btn {
  padding: 7px 18px;
  border: 1px solid rgba(240, 236, 227, 0.2);
  border-radius: 999px;
  background: rgba(14, 12, 9, 0.72);
  color: rgba(240, 236, 227, 0.72);
  font-family: inherit;
  font-size: 12.5px;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease),
              background 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.dt-btn:hover {
  color: var(--fg);
  border-color: rgba(207, 169, 95, 0.45);
}
.dt-btn.is-current {
  color: var(--accent-hi);
  border-color: rgba(207, 169, 95, 0.7);
  background: linear-gradient(160deg, rgba(246, 228, 180, 0.2), rgba(143, 111, 44, 0.16));
  box-shadow: inset 0 1px 0 var(--rim), 0 0 16px rgba(207, 169, 95, 0.16);
}

/* ---- 节选缩略图网格 ---- */
.dt-cuts { margin-top: clamp(20px, 3vh, 34px); }
.dt-cuts-label {
  margin: 0 0 12px;
  font-size: 11.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-faint);
}
.dt-cuts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
}
.dt-cut {
  position: relative;
  display: block;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: #000;
  cursor: pointer;
  transition: border-color 0.4s var(--ease), box-shadow 0.4s var(--ease),
              transform 0.4s var(--ease);
}
.dt-cut img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
.dt-cut-cap {
  display: block;
  padding: 8px 10px;
  font-size: 12px;
  color: rgba(240, 236, 227, 0.78);
  background: rgba(10, 9, 8, 0.9);
  text-align: left;
}
.dt-cut:hover {
  transform: translateY(-3px);
  border-color: rgba(207, 169, 95, 0.5);
  box-shadow: var(--sh-2), 0 0 22px rgba(207, 169, 95, 0.14);
}
.dt-cut.is-current {
  border-color: rgba(207, 169, 95, 0.85);
  box-shadow: 0 0 0 1px rgba(207, 169, 95, 0.5), var(--sh-2);
}
.dt-cut.is-current .dt-cut-cap { color: var(--accent-hi); }

@media (max-width: 720px) {
  .dt-cuts-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .dt-head { padding-right: 0; margin-bottom: 10px; }
  .dt-stage video { max-height: 42vh; }
}


/* ============================================================
   视觉区筛选条
   ------------------------------------------------------------
   用户："条码可以改成点一下就只有这一个作品，然后加一个全部的条码"
   （"条码"应为"标签"）
   点一下只显示该分类；「全部」恢复。计数从实际条目算。
   它取代了原来这一区的"本区条目"导航 —— 两个条子功能重叠、会挤两行。
   ============================================================ */
.wf-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: calc(-1 * clamp(6px, 1vw, 14px)) 0 clamp(18px, 2.4vw, 30px);
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}

.wf-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 15px;
  border: 1px solid rgba(240, 236, 227, 0.18);
  border-radius: 999px;
  background: rgba(14, 12, 9, 0.6);
  color: rgba(240, 236, 227, 0.72);
  font-family: inherit;
  font-size: 12.5px;
  letter-spacing: 0.05em;
  cursor: pointer;
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease),
              background 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.wf-btn:hover {
  color: var(--fg);
  border-color: rgba(207, 169, 95, 0.45);
}
/* 选中的那一档：金色底 + 内高光，和站内其他"选中"语言一致 */
.wf-btn.is-on {
  color: var(--accent-hi);
  border-color: rgba(207, 169, 95, 0.7);
  background: linear-gradient(160deg, rgba(246, 228, 180, 0.2), rgba(143, 111, 44, 0.16));
  box-shadow: inset 0 1px 0 var(--rim), 0 0 16px rgba(207, 169, 95, 0.14);
}
.wf-label { line-height: 1; }
/* 计数：等宽数字，用弱一档的颜色，不抢标签 */
.wf-count {
  font-family: var(--font-en);
  font-variant-numeric: tabular-nums;
  font-size: 10.5px;
  opacity: 0.62;
}
.wf-btn.is-on .wf-count { opacity: 0.85; }
.wf-btn:focus-visible {
  outline: 2px solid var(--accent-hi);
  outline-offset: 3px;
}

/* ============================================================
   视觉区：3 列（6 个作品 -> 3x2 对齐）
   ------------------------------------------------------------
   用户："排版你3*2，对其一下"
   原来是 2 列，6 条会排成 3 行且大小不均；3 列正好两排。
   分档（宽屏加列，不加尺寸）：
     <820px   1 列
     820~1200 2 列
     >=1200   3 列
   ============================================================ */
@media (min-width: 820px) {
  .visual-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1200px) {
  .visual-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* 3 列时格子变小，说明文字字号收一档，免得挤 */
@media (min-width: 1200px) {
  .visual-grid .vfx-meta h3 { font-size: 14.5px; }
  .visual-grid .vfx-meta p  { font-size: 11px; }
}


/* ============================================================
   游戏履历
   ------------------------------------------------------------
   招聘方常问"玩什么游戏"（品类理解 / 审美基准）。
   游戏墙是 1390x3015 的细长图（1:2.17），直接铺满会占掉两屏，
   所以用「左文字 + 右限高滚动框」的两栏：
     · 桌面：左 1fr 右 1.15fr
     · 窄屏：改成上下堆叠
   框加 tabindex="0"，否则键盘用户滚不动它。
   ============================================================ */
.play-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(20px, 3.2vw, 46px);
  align-items: start;
}

/* ---- 左：数据 + 代表作 ---- */
.play-stats {
  display: flex;
  gap: clamp(22px, 3vw, 44px);
  margin-bottom: clamp(20px, 2.6vw, 30px);
}
.play-stat { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; }
.play-stat .ps-v {
  font-family: var(--font-en);
  font-size: clamp(30px, 3.6vw, 46px);
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.01em;
  background: linear-gradient(150deg, #f6e4b4, #cfa955 55%, #8f6f2c);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 10px rgba(207, 169, 95, 0.22));
}
.play-stat .ps-u {
  font-family: var(--font-en);
  font-size: 14px;
  color: var(--accent);
}
.play-stat .ps-k {
  flex-basis: 100%;
  margin-top: 6px;
  font-size: 11.5px;
  letter-spacing: 0.18em;
  color: var(--fg-faint);
}

.play-sub {
  margin: 0 0 12px;
  font-size: 11.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-faint);
}
.play-titles {
  list-style: none;
  margin: 0 0 clamp(18px, 2.4vw, 26px);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.play-titles li {
  padding: 6px 13px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12.5px;
  letter-spacing: 0.03em;
  color: rgba(240, 236, 227, 0.8);
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease),
              background 0.35s var(--ease);
}
.play-titles li:hover {
  color: var(--accent-hi);
  border-color: rgba(207, 169, 95, 0.45);
  background: rgba(207, 169, 95, 0.07);
}
.play-note {
  margin: 0;
  font-size: 12px;
  line-height: 1.85;
  color: var(--fg-faint);
}

/* ---- 右：游戏墙（限高滚动） ---- */
.play-frame {
  position: relative;
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow-y: auto;
  overflow-x: hidden;
  /* 限高：约 3/4 屏。细长图在框内滚动查看，不拖长整页 */
  max-height: clamp(360px, 74vh, 780px);
  background: #0b0b0c;
  box-shadow: var(--sh-2), inset 0 1px 0 rgba(255, 245, 214, 0.06);
  /* 滚动条也做成暗色，别在暗底上突然一根白条 */
  scrollbar-width: thin;
  scrollbar-color: rgba(207, 169, 95, 0.4) transparent;
  overscroll-behavior: contain;
}
.play-frame:focus-visible {
  outline: 2px solid var(--accent-hi);
  outline-offset: 3px;
}
.play-frame img {
  display: block;
  width: 100%;
  height: auto;
}
.play-frame::-webkit-scrollbar { width: 8px; }
.play-frame::-webkit-scrollbar-track { background: transparent; }
.play-frame::-webkit-scrollbar-thumb {
  background: rgba(207, 169, 95, 0.35);
  border-radius: 4px;
}
.play-frame::-webkit-scrollbar-thumb:hover { background: rgba(207, 169, 95, 0.6); }

/* 框下方一行小提示（图被裁在框内，提示可滚动） */
.play-frame-hint {
  position: sticky;
  bottom: 0;
  display: block;
  padding: 8px 12px;
  font-size: 11px;
  letter-spacing: 0.14em;
  color: var(--fg-faint);
  background: linear-gradient(to top, rgba(8, 8, 9, 0.94), rgba(8, 8, 9, 0));
  text-align: right;
  pointer-events: none;
}

/* ---- 窄屏：改上下堆叠 ---- */
@media (max-width: 900px) {
  .play-layout { grid-template-columns: 1fr; }
  .play-frame { max-height: 58vh; }
}


/* ============================================================
   作品总览手风琴里「游戏履历」那一格的内容
   ------------------------------------------------------------
   原来是独立分区（sec9）+ 两栏布局，用户觉得突兀，
   改成并进手风琴 —— 和"特效合集/渲染竞赛/虚幻5游戏"这些
   类型分组并列，不再单独占一个分区。
   收起态必须完全藏起来（否则窄条上会漏出文字）。
   ============================================================ */
.ov-play {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* 压在封面/视频上，加一层底色保证可读 */
  position: relative;
  z-index: 3;
}

/* 收起 / 未选中时彻底隐藏 */
.ov-item:not(.is-open) .ov-play {
  opacity: 0 !important;
  max-height: 0 !important;
  overflow: hidden !important;
  margin: 0 !important;
  pointer-events: none;
}

.ov-play-stats {
  display: flex;
  gap: 22px;
  align-items: baseline;
}
.ov-play .play-stat { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; }
.ov-play .ps-v {
  font-family: var(--font-en);
  font-size: clamp(22px, 2.2vw, 32px);
  font-weight: 300;
  line-height: 1;
  background: linear-gradient(150deg, #f6e4b4, #cfa955 55%, #8f6f2c);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.75));
}
.ov-play .ps-u {
  font-family: var(--font-en);
  font-size: 12px;
  color: var(--accent);
}
.ov-play .ps-k {
  flex-basis: 100%;
  margin-top: 4px;
  font-size: 10.5px;
  letter-spacing: 0.16em;
  color: rgba(240, 236, 227, 0.62);
}

.ov-play-label {
  margin: 0;
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(240, 236, 227, 0.5);
}
.ov-play-titles {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.ov-play-titles li {
  padding: 4px 11px;
  border: 1px solid rgba(240, 236, 227, 0.22);
  border-radius: 999px;
  font-size: 11.5px;
  color: rgba(240, 236, 227, 0.86);
  background: rgba(8, 8, 9, 0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  white-space: nowrap;
}
.ov-play-note {
  margin: 0;
  font-size: 11px;
  line-height: 1.7;
  color: rgba(240, 236, 227, 0.5);
  max-width: 52ch;
}


/* ============================================================
   手风琴「游戏履历」那一格 —— 收尾修正
   ------------------------------------------------------------
   ① 展开时隐藏「进入分区」：
      前面有 `.ov-item.is-open .ov-open { display:flex }`（行 2034），
      我的 `display:none` 特异性相同但更靠前，被它覆盖。
      这里用 `.ov-item.is-open .ov-open` + 额外一层选择器提高特异性。
   ② 面板很窄（手风琴展开那一格），原来 22~32px 的数字会撑破、和封面重叠。
      改成两列、字号收小。
   ============================================================ */
.ov-item.is-open .ov-body .ov-open,
.ov-item.is-open .ov-open { display: none !important; }

.ov-play {
  max-width: 100%;
  margin-top: 14px;
}
.ov-play-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 18px;
  max-width: 260px;
}
.ov-play .ps-v { font-size: 20px; }
.ov-play .ps-u { font-size: 10.5px; }
.ov-play .ps-k { font-size: 9.5px; letter-spacing: 0.12em; margin-top: 2px; }
.ov-play-label { font-size: 9.5px; letter-spacing: 0.16em; }
.ov-play-titles { gap: 5px; max-width: 300px; }
.ov-play-titles li { padding: 3px 9px; font-size: 10.5px; }
.ov-play-note { font-size: 10px; line-height: 1.6; max-width: 34ch; }


/* 游戏履历面板：底色做足（原来 0.72~0.86 太透，游戏墙会透上来把字迹搅浑） */
.ov-play {
  z-index: 6;
  background: linear-gradient(180deg, rgba(8, 8, 9, 0.93), rgba(8, 8, 9, 0.97));
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.55);
}
/* 数字用背景裁切做渐变 -> 本身是透明的，压在花背景上必须靠阴影拉开 */
.ov-play .ps-v {
  filter: drop-shadow(0 2px 10px rgba(0, 0, 0, 0.9));
}
.ov-play-stats { gap: 12px 26px; }


/* ============================================================
   详情页：节选「分组」
   ------------------------------------------------------------
   一个条目里可以有多组节选（如蘑菇的「白天 / 晚上」）。
   切换按钮排里插一个分组标签；缩略图网格里插一行组标题。
   ============================================================ */
.dt-switch-group {
  align-self: center;
  padding: 0 4px 0 8px;
  font-size: 10.5px;
  letter-spacing: 0.18em;
  color: var(--fg-faint);
  border-left: 2px solid rgba(207, 169, 95, 0.45);
}
.dt-switch-group:first-of-type { border-left: none; }

.dt-cuts-group {
  grid-column: 1 / -1;          /* 组标题独占一行 */
  margin: 10px 0 2px;
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
}
.dt-cuts-group:first-child { margin-top: 0; }

/* ============================================================
   作品总览第 6 格：游戏履历
   ------------------------------------------------------------
   这一格在收起态只有 ~174px 宽，展开后也不宽。
   之前面板内容把它撑到看不出/被裁，看着像"这一格没了"。
   给它一个最小宽度，并把内容再收一档。
   ============================================================ */
.ov-item.is-open[data-target="sec9"] { flex: 5.2; min-width: 500px; }
@media (max-width: 1200px) {
  .ov-item.is-open[data-target="sec9"] { min-width: 0; }
}
.ov-play { min-width: 0; }
.ov-play-titles { max-width: 100%; }
.ov-play-note { max-width: 100%; }
.ov-play-stats { max-width: 100%; grid-template-columns: repeat(2, minmax(70px, 1fr)); }


/* ============================================================
   游戏履历：完整游戏墙
   ------------------------------------------------------------
   用户要求"展示完整点"。手风琴那格只露封面一角，所以这里整张放出来。
   两栏：左数据/代表作，右完整游戏墙（限高可滚）。
   图有 4338px 高，容器限高后首屏能看到顶部、往下滚看更多 ——
   这样"首屏有东西看"和"内容完整"两头都占。
   ============================================================ */
.ov-play-full {
  margin-top: clamp(20px, 3vw, 40px);
  padding-top: clamp(18px, 2.4vw, 28px);
  border-top: 1px solid var(--line);
}

.opf-head {
  display: flex;
  align-items: baseline;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: clamp(14px, 2vw, 22px);
}
.opf-title {
  margin: 0;
  font-size: clamp(17px, 1.6vw, 22px);
  font-weight: 450;
  letter-spacing: 0.05em;
  color: var(--fg);
}
.opf-meta {
  margin: 0;
  font-size: 12.5px;
  letter-spacing: 0.06em;
  color: var(--fg-faint);
}

.opf-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
  gap: clamp(18px, 3vw, 44px);
  align-items: start;
}

/* 左：数据 + 代表作 */
.opf-stats {
  display: flex;
  gap: clamp(20px, 2.6vw, 40px);
  margin-bottom: clamp(16px, 2vw, 24px);
}
.opf-stats .play-stat { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; }
.opf-stats .ps-v {
  font-family: var(--font-en);
  font-size: clamp(28px, 3.2vw, 40px);
  font-weight: 300;
  line-height: 1;
  background: linear-gradient(150deg, #f6e4b4, #cfa955 55%, #8f6f2c);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 10px rgba(207, 169, 95, 0.2));
}
.opf-stats .ps-u { font-family: var(--font-en); font-size: 13px; color: var(--accent); }
.opf-stats .ps-k {
  flex-basis: 100%; margin-top: 5px; font-size: 11px;
  letter-spacing: 0.18em; color: var(--fg-faint);
}

.opf-label {
  margin: 0 0 10px;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--fg-faint);
}
.opf-titles {
  list-style: none; margin: 0 0 clamp(14px, 2vw, 20px); padding: 0;
  display: flex; flex-wrap: wrap; gap: 7px;
}
.opf-titles li {
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  color: rgba(240, 236, 227, 0.82);
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease);
}
.opf-titles li:hover { color: var(--accent-hi); border-color: rgba(207, 169, 95, 0.45); }
.opf-note { margin: 0; font-size: 12px; line-height: 1.8; color: var(--fg-faint); }

/* 右：完整游戏墙 */
.opf-frame {
  position: relative;
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow-y: auto;
  overflow-x: hidden;
  max-height: clamp(420px, 72vh, 820px);
  background: #0b0b0c;
  box-shadow: var(--sh-2), inset 0 1px 0 rgba(255, 245, 214, 0.06);
  scrollbar-width: thin;
  scrollbar-color: rgba(207, 169, 95, 0.4) transparent;
  overscroll-behavior: contain;
}
.opf-frame:focus-visible { outline: 2px solid var(--accent-hi); outline-offset: 3px; }
.opf-frame img { display: block; width: 100%; height: auto; }
.opf-frame::-webkit-scrollbar { width: 8px; }
.opf-frame::-webkit-scrollbar-track { background: transparent; }
.opf-frame::-webkit-scrollbar-thumb {
  background: rgba(207, 169, 95, 0.35); border-radius: 4px;
}
.opf-frame::-webkit-scrollbar-thumb:hover { background: rgba(207, 169, 95, 0.6); }
.opf-hint {
  position: sticky; bottom: 0; display: block;
  padding: 8px 12px; text-align: right;
  font-size: 11px; letter-spacing: 0.14em; color: var(--fg-faint);
  background: linear-gradient(to top, rgba(8, 8, 9, 0.94), rgba(8, 8, 9, 0));
  pointer-events: none;
}

@media (max-width: 900px) {
  .opf-body { grid-template-columns: 1fr; }
  .opf-frame { max-height: 56vh; }
}


/* ============================================================
   ① 手风琴「游戏履历」那一格里的完整游戏墙
   ------------------------------------------------------------
   用户："你刚刚做的放到手风琴里面"
   这一格展开后只有 ~527px 宽，所以游戏墙做成
   "限高 + 可滚 + 首屏露出封面墙顶部"，展开即可看到。
   ============================================================ */
.ov-play-full-mini {
  position: relative;
  z-index: 5;
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

/* 收起态必须完全藏住（否则窄条上会漏出内容） */
.ov-item:not(.is-open) .ov-play-full-mini {
  opacity: 0 !important;
  max-height: 0 !important;
  overflow: hidden !important;
  margin: 0 !important;
  pointer-events: none;
}

.opf-mini-stats { display: flex; gap: 16px; align-items: baseline; }
.opf-mini-stats .play-stat { display: flex; align-items: baseline; gap: 3px; flex-wrap: wrap; }
.opf-mini-stats .ps-v {
  font-family: var(--font-en);
  font-size: 19px;
  font-weight: 300;
  line-height: 1;
  background: linear-gradient(150deg, #f6e4b4, #cfa955 55%, #8f6f2c);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.8));
}
.opf-mini-stats .ps-u { font-family: var(--font-en); font-size: 10.5px; color: var(--accent); }
.opf-mini-stats .ps-k {
  flex-basis: 100%; margin-top: 2px; font-size: 9px;
  letter-spacing: 0.14em; color: rgba(240, 236, 227, 0.58);
}

.opf-mini-titles {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 4px; max-width: 100%;
}
.opf-mini-titles li {
  padding: 3px 8px;
  border: 1px solid rgba(240, 236, 227, 0.22);
  border-radius: 999px;
  font-size: 10px;
  color: rgba(240, 236, 227, 0.86);
  background: rgba(8, 8, 9, 0.6);
  white-space: nowrap;
}

/* 游戏墙本体：限高可滚；面板窄，所以高度别太大 */
.opf-mini-frame {
  position: relative;
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow-y: auto;
  overflow-x: hidden;
  max-height: clamp(220px, 34vh, 360px);
  background: #0b0b0c;
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.06);
  scrollbar-width: thin;
  scrollbar-color: rgba(207, 169, 95, 0.4) transparent;
  overscroll-behavior: contain;
}
.opf-mini-frame:focus-visible { outline: 2px solid var(--accent-hi); outline-offset: 2px; }
.opf-mini-frame img { display: block; width: 100%; height: auto; }
.opf-mini-frame::-webkit-scrollbar { width: 6px; }
.opf-mini-frame::-webkit-scrollbar-thumb {
  background: rgba(207, 169, 95, 0.4); border-radius: 3px;
}
.opf-mini-hint {
  position: sticky; bottom: 0; display: block;
  padding: 5px 8px; text-align: right;
  font-size: 9.5px; letter-spacing: 0.12em; color: rgba(240, 236, 227, 0.5);
  background: linear-gradient(to top, rgba(8, 8, 9, 0.94), rgba(8, 8, 9, 0));
  pointer-events: none;
}

/* ============================================================
   ② 联系区：「我玩的游戏」
   ------------------------------------------------------------
   用户："联系那留位置加上我玩的游戏"
   同一张完整游戏墙，这里两栏放（左数据、右墙）。
   ============================================================ */
.cta-play {
  margin-top: clamp(24px, 3.2vw, 44px);
  padding-top: clamp(20px, 2.6vw, 30px);
  border-top: 1px solid var(--line);
  text-align: left;
}
.ctap-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: clamp(12px, 1.8vw, 20px);
}
.ctap-title {
  margin: 0;
  font-size: clamp(16px, 1.5vw, 20px);
  font-weight: 450; letter-spacing: 0.05em; color: var(--fg);
}
.ctap-link {
  font-size: 12.5px; letter-spacing: 0.06em;
  color: var(--fg-dim);
  text-decoration: none;
  border-bottom: 1px solid rgba(207, 169, 95, 0.35);
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease);
}
.ctap-link:hover { color: var(--accent-hi); border-color: var(--accent-hi); }

.ctap-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr);
  gap: clamp(16px, 2.6vw, 40px);
  align-items: start;
}
.ctap-stats { display: flex; gap: clamp(18px, 2.4vw, 36px); margin-bottom: 14px; }
.ctap-stats .play-stat { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; }
.ctap-stats .ps-v {
  font-family: var(--font-en);
  font-size: clamp(24px, 2.6vw, 34px);
  font-weight: 300; line-height: 1;
  background: linear-gradient(150deg, #f6e4b4, #cfa955 55%, #8f6f2c);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 2px 10px rgba(207, 169, 95, 0.2));
}
.ctap-stats .ps-u { font-family: var(--font-en); font-size: 12px; color: var(--accent); }
.ctap-stats .ps-k {
  flex-basis: 100%; margin-top: 4px; font-size: 10.5px;
  letter-spacing: 0.16em; color: var(--fg-faint);
}
.ctap-titles {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 6px;
}
.ctap-titles li {
  padding: 4px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 11.5px;
  color: rgba(240, 236, 227, 0.8);
}

.ctap-frame {
  position: relative; margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow-y: auto; overflow-x: hidden;
  max-height: clamp(340px, 60vh, 700px);
  background: #0b0b0c;
  box-shadow: var(--sh-2), inset 0 1px 0 rgba(255, 245, 214, 0.06);
  scrollbar-width: thin;
  scrollbar-color: rgba(207, 169, 95, 0.4) transparent;
  overscroll-behavior: contain;
}
.ctap-frame:focus-visible { outline: 2px solid var(--accent-hi); outline-offset: 3px; }
.ctap-frame img { display: block; width: 100%; height: auto; }
.ctap-frame::-webkit-scrollbar { width: 8px; }
.ctap-frame::-webkit-scrollbar-thumb {
  background: rgba(207, 169, 95, 0.35); border-radius: 4px;
}
.ctap-hint {
  position: sticky; bottom: 0; display: block;
  padding: 7px 11px; text-align: right;
  font-size: 10.5px; letter-spacing: 0.14em; color: var(--fg-faint);
  background: linear-gradient(to top, rgba(8, 8, 9, 0.94), rgba(8, 8, 9, 0));
  pointer-events: none;
}

@media (max-width: 900px) {
  .ctap-body { grid-template-columns: 1fr; }
  .ctap-frame { max-height: 52vh; }
}

/* ============================================================
   ③ 联系区落点
   ------------------------------------------------------------
   sec8 用的是居中版式（没有 .sec-head），原来 jumpToSection 回落到
   整个 section，落点离导航只有 22px —— 比别的分区紧，看着"偏上"。
   JS 已改成落在 [data-jump-anchor]（.cta-head），这里给一点补偿，
   让它和其它分区的 85px 一致。
   ============================================================ */
#sec8 [data-jump-anchor] { scroll-margin-top: var(--jump-offset-extra); }


/* 手风琴里那个游戏墙的限高：用更高特异性确保生效
   （.ov-item.is-open 那一族规则会覆盖普通类选择器） */
.ov-item.is-open .opf-mini-frame,
.ov-item .ov-play-full-mini .opf-mini-frame {
  max-height: clamp(200px, 30vh, 320px);
}


/* ============================================================
   联系区：左右两栏
   ------------------------------------------------------------
   用户："这一块可以弄小点和联系放一块，可以一个左边一个右边"
   左 = 联系信息（教育/求职 + 二维码）
   右 = 我玩的游戏（缩到和左栏协调的一档，游戏墙限高可滚）
   ============================================================ */
.cta-split {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: clamp(20px, 3vw, 48px);
  align-items: start;
  margin-top: clamp(18px, 2.4vw, 30px);
}
.cta-col { min-width: 0; }

/* ---- 右栏：我玩的游戏（覆盖掉之前"整块+上边框"的写法）---- */
.cta-split .cta-play {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}
/* 之前那层网格（数据 | 墙）在这里改成竖排，让右栏更紧凑 */
.cta-split .ctap-body { display: block; }

.cta-split .ctap-head { margin-bottom: 10px; }
.cta-split .ctap-title { font-size: 15px; }
.cta-split .ctap-link { font-size: 11.5px; }

/* 数据：横排两个，字号收小 */
.cta-split .ctap-stats {
  display: flex;
  gap: 16px;
  margin-bottom: 10px;
}
.cta-split .ctap-stats .ps-v { font-size: 22px; }
.cta-split .ctap-stats .ps-u { font-size: 11px; }
.cta-split .ctap-stats .ps-k { font-size: 9.5px; letter-spacing: 0.14em; margin-top: 3px; }

/* 代表作：小胶囊，最多显示出两三行 */
.cta-split .ctap-titles { gap: 5px; margin-bottom: 12px; }
.cta-split .ctap-titles li { padding: 3px 9px; font-size: 10.5px; }

/* 游戏墙：收小一档，限高可滚 */
.cta-split .ctap-frame {
  max-height: clamp(300px, 46vh, 520px);
  border-radius: var(--radius-sm);
}
.cta-split .ctap-hint { font-size: 9.5px; padding: 6px 9px; }

@media (max-width: 1000px) {
  .cta-split { grid-template-columns: 1fr; }
  .cta-split .ctap-frame { max-height: 46vh; }
}


/* ============================================================
   配色：金（主）+ 青玉（副）
   ------------------------------------------------------------
   用户："配色可以优化下，除了金色加点其他颜色"
   规则：**按面积分工**，不是均匀撒色 ——
     金   ：最重要的那一个（选中态、关键数字、主按钮、标题高亮）
     青玉 ：结构与状态（编号、标签、悬停描边、面板底纹）
   青玉用的是站内已有的 --jade / --jade-hi，只是之前基本没用起来。
   ============================================================ */
:root {
  /* 青玉系：从已有的 jade 派生，补足"文字级 / 描边级 / 底纹级"三档 */
  --jade:      #2f4f4a;
  --jade-hi:   #6fb3a4;
  --jade-text: #86c3b4;                     /* 文字可读的那一档 */
  --jade-line: rgba(111, 179, 164, 0.34);   /* 描边 */
  --jade-veil: rgba(47, 79, 74, 0.16);      /* 底纹 */
  --jade-glow: rgba(111, 179, 164, 0.16);   /* 微光 */
}

/* ---- ① 分区编号 + eyebrow 的小金线 -> 青玉 ---- */
.sec-head .eyebrow::after {
  color: var(--jade-text) !important;
  border-left-color: var(--jade-line) !important;
  border-right-color: var(--jade-line) !important;
}
.eyebrow::before {
  background: linear-gradient(90deg, transparent, var(--jade-hi) 70%, var(--jade-line)) !important;
}
.sec-outline .so-label,
.stills-label,
.part-label::before {
  color: var(--jade-text) !important;
}

/* ---- ② 标签筛选胶囊：悬停/计数走青玉（选中态仍是金） ---- */
.wf-btn { border-color: rgba(240, 236, 227, 0.16); }
.wf-btn:hover {
  border-color: var(--jade-line) !important;
  color: var(--fg) !important;
  background: var(--jade-veil);
}
.wf-count { color: var(--jade-text); opacity: 0.78; }
.wf-btn.is-on .wf-count { color: inherit; opacity: 0.9; }

/* ---- ③ 卡片悬停描边：金 -> 青玉（金留给"选中/当前"） ---- */
.vfx-cell:hover {
  border-color: var(--jade-line) !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 245, 214, 0.12),
    var(--sh-2),
    0 0 30px var(--jade-glow) !important;
}
.vfx-cell.is-playing { border-color: var(--jade-line); }

/* 标签在卡片悬停时也跟青玉，避免同一张卡上金青各说各话 */
.vfx-cell:hover .vfx-meta h3 { color: var(--jade-text) !important; }

/* ---- ④ 手风琴非选中格：冷调里加一点青，和选中格的金形成冷暖对比 ---- */
.ov-item > video,
.ov-item > img { filter: grayscale(1) brightness(0.52) contrast(1.06) !important; }
.ov-item.is-open > video,
.ov-item.is-open > img {
  filter: grayscale(0) brightness(0.95) saturate(1.04) !important;
}
/* 收起态的编号用青玉（它是"图录的锚点"，不是重点，不该用金） */
.ov-item .ov-no { color: var(--jade-text) !important; opacity: 0.85; }
.ov-item.is-open .ov-no { color: var(--accent-hi) !important; opacity: 1; }

/* ---- ⑤ 联系区：右栏面板加一层极淡的青底纹，和左栏的白卡片区分开 ---- */
.cta-split .cta-play {
  padding: clamp(14px, 1.8vw, 22px);
  border: 1px solid var(--jade-line);
  border-radius: var(--radius-md);
  background: linear-gradient(170deg, var(--jade-veil), rgba(10, 10, 11, 0.5) 70%);
}
.cta-split .ctap-title { color: var(--fg); }
.cta-split .ctap-link {
  color: var(--jade-text);
  border-bottom-color: var(--jade-line);
}
.cta-split .ctap-link:hover { color: var(--jade-hi); border-bottom-color: var(--jade-hi); }

/* ---- ⑥ 免责声明：弱化，但别淡到看不见 ---- */
.ctap-disclaimer {
  margin: 10px 0 0;
  font-size: 11px;
  line-height: 1.7;
  color: rgba(240, 236, 227, 0.46);
  border-left: 2px solid var(--jade-line);
  padding-left: 9px;
}


/* ============================================================
   技能与制作流程
   ------------------------------------------------------------
   金（主）+ 青玉（副）分工：
     等级条填充 = 青玉（结构/量度）
     档位数字   = 金（少数重点）
     流程步骤号 = 青玉
   ============================================================ */
.skills-block {
  margin-top: clamp(26px, 3.4vw, 48px);
  padding-top: clamp(20px, 2.6vw, 32px);
  border-top: 1px solid var(--line);
}

.sk-head { margin-bottom: clamp(16px, 2.2vw, 26px); }
.sk-title {
  margin: 6px 0 8px;
  font-size: clamp(17px, 1.7vw, 23px);
  font-weight: 450;
  letter-spacing: 0.05em;
  color: var(--fg);
}
.sk-desc {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.8;
  color: var(--fg-dim);
}

.sk-groups {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(18px, 2.6vw, 40px);
  margin-bottom: clamp(22px, 3vw, 36px);
}
.sk-group { min-width: 0; }
.sk-group-label {
  margin: 0 0 12px;
  padding-bottom: 8px;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--jade-text);
  border-bottom: 1px solid var(--jade-line);
}
.sk-item { margin-bottom: 13px; }
.sk-item-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}
.sk-name {
  font-size: 12.5px;
  color: rgba(240, 236, 227, 0.9);
}
.sk-level {
  font-family: var(--font-en);
  font-variant-numeric: tabular-nums;
  font-size: 10.5px;
  color: var(--accent);
  white-space: nowrap;
}
/* 等级条：底槽暗，填充青玉；不用金色，避免和"档位数字"抢 */
.sk-bar {
  height: 3px;
  border-radius: 2px;
  background: rgba(240, 236, 227, 0.1);
  overflow: hidden;
  margin-bottom: 5px;
}
.sk-fill {
  display: block;
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--jade), var(--jade-hi));
}
.sk-note {
  display: block;
  font-size: 11px;
  line-height: 1.6;
  color: rgba(240, 236, 227, 0.42);
}

/* 制作流程：横向 7 步，窄屏换行 */
.sk-pipeline {
  list-style: none;
  margin: 0;
  padding: clamp(14px, 1.8vw, 20px) 0 0;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 10px clamp(8px, 1.2vw, 18px);
  counter-reset: none;
}
.sk-step {
  display: flex;
  align-items: baseline;
  gap: 7px;
  padding: 6px 12px;
  border: 1px solid var(--jade-line);
  border-radius: 999px;
  background: var(--jade-veil);
  white-space: nowrap;
}
.sk-step-no {
  font-family: var(--font-en);
  font-variant-numeric: tabular-nums;
  font-size: 10px;
  color: var(--jade-hi);
}
.sk-step-name {
  font-size: 12px;
  color: var(--fg);
}
.sk-step-note {
  font-size: 10.5px;
  color: rgba(240, 236, 227, 0.42);
}

@media (max-width: 900px) {
  .sk-groups { grid-template-columns: 1fr; gap: 22px; }
  .sk-step-note { display: none; }
}


/* ============================================================
   ① 工具箱分层
   ------------------------------------------------------------
   用户："首页的创作工具这里感觉也可以优化一下"
   原来 12 个图标等大平铺 —— 12 张卡片信息量相同，但实际熟练度差很多。
   改成：core 3 个出大卡（作品里能对应到），其余出小胶囊。
   依据是"有没有作品支撑"，不是自评。
   ============================================================ */
.tool-grid.has-tiers {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: stretch;
}
.tool-grid.has-tiers .tool--core {
  flex: 0 0 auto;
  width: min(210px, 30%);
  padding: 18px 16px;
  border-color: rgba(207, 169, 95, 0.35);
  background: linear-gradient(165deg, rgba(207, 169, 95, 0.07), rgba(12, 11, 10, 0.6));
}
.tool-grid.has-tiers .tool--core .tool-icon { font-size: 30px; }
.tool-grid.has-tiers .tool--core .tool-icon svg,
.tool-grid.has-tiers .tool--core .tool-icon img { width: 34px; height: 34px; }
.tool-grid.has-tiers .tool--core .tool-name { font-size: 13.5px; }
.tool-grid.has-tiers .tool--core .tool-note { color: var(--accent); opacity: 0.85; }

/* 小胶囊：只留图标 + 名字，说明放 title 里 */
.tool-grid.has-tiers .tool--mini {
  flex: 0 0 auto;
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
  width: auto;
  min-width: 0;
  padding: 8px 13px 8px 10px;
  border-radius: 999px;
  border-color: var(--jade-line);
  background: var(--jade-veil);
  transition: border-color 0.35s var(--ease), background 0.35s var(--ease);
}
.tool-grid.has-tiers .tool--mini:hover {
  border-color: var(--jade-hi);
  background: rgba(47, 79, 74, 0.26);
}
.tool-grid.has-tiers .tool--mini .tool-icon { font-size: 15px; }
.tool-grid.has-tiers .tool--mini .tool-icon svg,
.tool-grid.has-tiers .tool--mini .tool-icon img { width: 18px; height: 18px; }
.tool-grid.has-tiers .tool--mini .tool-name { font-size: 12px; white-space: nowrap; }
/* 胶囊里不显示说明文字 —— 太长了 */
.tool-grid.has-tiers .tool--mini .tool-note { display: none; }

@media (max-width: 900px) {
  .tool-grid.has-tiers .tool--core { width: calc(50% - 5px); }
}

/* ============================================================
   ② 能力卡（替代原来的技能评分）
   ============================================================ */
.sk-groups.is-caps {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(12px, 1.8vw, 20px);
}
.cap {
  position: relative;
  padding: clamp(14px, 1.8vw, 20px);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: linear-gradient(168deg, rgba(24, 30, 29, 0.5), rgba(11, 11, 12, 0.62));
  transition: border-color 0.4s var(--ease), box-shadow 0.4s var(--ease),
              transform 0.4s var(--ease);
}
.cap:hover {
  transform: translateY(-2px);
  border-color: var(--jade-line);
  box-shadow: var(--sh-2), 0 0 26px var(--jade-glow);
}
.cap-title {
  margin: 0 0 8px;
  font-size: clamp(15px, 1.4vw, 18px);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--accent-hi);
}
.cap-what {
  margin: 0 0 10px;
  font-size: 12.5px;
  line-height: 1.85;
  color: rgba(240, 236, 227, 0.82);
}
.cap-tools {
  margin: 0 0 12px;
  font-size: 11px;
  line-height: 1.7;
  color: var(--jade-text);
}
.cap-link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  letter-spacing: 0.05em;
  color: var(--fg-dim);
  text-decoration: none;
  border-bottom: 1px solid rgba(207, 169, 95, 0.35);
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease);
}
.cap-link::after { content: "\2197"; font-size: 12px; }
.cap-link:hover { color: var(--accent-hi); border-color: var(--accent-hi); }

@media (max-width: 820px) {
  .sk-groups.is-caps { grid-template-columns: 1fr; }
}


/* ============================================================
   联系区：压缩到一个版面能看完
   ------------------------------------------------------------
   用户："联系我这一块我不想太复杂，我希望一个页面能看完"
        "首页也太长了，一个页面能看完最好"
   做法：留白/字号整体收一档；能力卡从 2x2 改一行 4 个；
        游戏墙压矮；二维码缩小。
   ============================================================ */
.sec-cta { padding-top: clamp(48px, 6vw, 76px); padding-bottom: clamp(40px, 5vw, 64px); }
.sec-cta .cta-head { margin-bottom: clamp(14px, 1.8vw, 22px); }
.sec-cta .cta-title { font-size: clamp(24px, 2.6vw, 36px); }
.sec-cta .cta-desc { font-size: 12.5px; line-height: 1.7; }

/* 能力卡区块：减少上下留白 */
.sec-cta .skills-block {
  margin-top: clamp(16px, 2vw, 26px);
  padding-top: clamp(14px, 1.8vw, 22px);
}
.sec-cta .sk-head { margin-bottom: clamp(10px, 1.4vw, 16px); }
.sec-cta .sk-title { font-size: clamp(15px, 1.4vw, 19px); }
.sec-cta .sk-desc { font-size: 11.5px; }
/* 能力卡：2x2 -> 一行 4 个 */
.sec-cta .sk-groups.is-caps { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.sec-cta .cap { padding: 12px 13px; }
.sec-cta .cap-title { font-size: 14px; margin-bottom: 6px; }
.sec-cta .cap-what { font-size: 11.5px; line-height: 1.7; margin-bottom: 8px; }
.sec-cta .cap-tools { font-size: 10px; margin-bottom: 9px; }
.sec-cta .cap-link { font-size: 11px; }
/* 流程胶囊：更紧凑 */
.sec-cta .sk-pipeline { padding-top: clamp(10px, 1.4vw, 14px); gap: 7px 8px; }
.sec-cta .sk-step { padding: 4px 10px; }
.sec-cta .sk-step-name { font-size: 11px; }
.sec-cta .sk-step-note { font-size: 10px; }

/* 游戏墙压矮：一屏内能露出关键信息，想看全在框内滚 */
.sec-cta .cta-split .ctap-frame { max-height: clamp(240px, 34vh, 380px); }
.sec-cta .cta-split .ctap-stats .ps-v { font-size: 20px; }
.sec-cta .ctap-titles { margin-bottom: 9px; }

/* 二维码缩小一档 */
.sec-cta .qr-row { gap: clamp(10px, 1.4vw, 18px); }
.sec-cta .qr-card, .sec-cta .qr-row > * { max-width: 168px; }

/* 按钮区收到最近 */
.sec-cta .cta-actions { margin-top: clamp(16px, 2vw, 24px); }

@media (max-width: 1200px) {
  .sec-cta .sk-groups.is-caps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 820px) {
  .sec-cta .sk-groups.is-caps { grid-template-columns: 1fr; }
}

/* ============================================================
   工具箱：不太会用的工具标灰（用户："我 houdini 其实不太会用"）
   ============================================================ */
.tool--mini.is-grey,
.tool--grey {
  opacity: 0.5;
  filter: grayscale(1);
  border-color: rgba(240, 236, 227, 0.12) !important;
  background: rgba(255, 255, 255, 0.02) !important;
}
.tool--mini.is-grey .tool-name,
.tool--grey .tool-name { color: rgba(240, 236, 227, 0.6); }
.tool--mini.is-grey .tool-note,
.tool--grey .tool-note { color: rgba(240, 236, 227, 0.34); }
.tool--mini.is-grey:hover,
.tool--grey:hover { opacity: 0.72; }
/* 灰色项右上角一个小注记，说明"会用一点" */
.tool--mini.is-grey::after {
  content: "基础";
  margin-left: 2px;
  padding: 1px 5px;
  font-size: 9px;
  border-radius: 999px;
  color: rgba(240, 236, 227, 0.5);
  border: 1px solid rgba(240, 236, 227, 0.16);
}

/* ============================================================
   工具箱整体收紧（用户："首页也太长了"）
   ============================================================ */
.tool-grid.has-tiers { gap: 8px; }
.tool-grid.has-tiers .tool--core { padding: 14px 13px; }
.tool-grid.has-tiers .tool--core .tool-icon { font-size: 26px; }
.tool-grid.has-tiers .tool--core .tool-icon svg,
.tool-grid.has-tiers .tool--core .tool-icon img,
.tool-grid.has-tiers .tool--core .tool-mask { width: 28px; height: 28px; }
.tool-grid.has-tiers .tool--core .tool-name { font-size: 12.5px; }
.tool-grid.has-tiers .tool--mini { padding: 6px 11px 6px 9px; }
.tool-grid.has-tiers .tool--mini .tool-icon { font-size: 13px; }
.tool-grid.has-tiers .tool--mini .tool-icon svg,
.tool-grid.has-tiers .tool--mini .tool-icon img,
.tool-grid.has-tiers .tool--mini .tool-mask { width: 16px; height: 16px; }
.tool-grid.has-tiers .tool--mini .tool-name { font-size: 11.5px; }


/* ============================================================
   紧凑层-B：把联系区压进一屏（1920x1080 目标 < 990px）
   ============================================================ */
.sec-cta { padding-top: clamp(40px, 5vw, 60px) !important; padding-bottom: clamp(30px, 4vw, 48px) !important; }

/* 头部再收 */
.sec-cta .cta-head { margin-bottom: 12px !important; }
.sec-cta .cta-desc { max-width: 46ch; }

/* 能力卡：收成一行的紧凑卡 */
.sec-cta .sk-head { margin-bottom: 8px !important; }
.sec-cta .sk-groups.is-caps { gap: 8px !important; }
.sec-cta .cap { padding: 10px 11px !important; }
.sec-cta .cap-title { font-size: 13px !important; margin-bottom: 5px !important; }
.sec-cta .cap-what { font-size: 11px !important; line-height: 1.6 !important; margin-bottom: 6px !important; }
.sec-cta .cap-tools { font-size: 9.5px !important; margin-bottom: 7px !important; }
.sec-cta .cap-link { font-size: 10.5px !important; }

/* 流程胶囊：一行放下 */
.sec-cta .sk-pipeline { padding-top: 10px !important; gap: 6px !important; margin-bottom: 0 !important; }
.sec-cta .sk-step { padding: 3px 8px !important; gap: 5px !important; }
.sec-cta .sk-step-no { font-size: 9px !important; }
.sec-cta .sk-step-name { font-size: 10.5px !important; }
.sec-cta .sk-step-note { font-size: 9.5px !important; }

/* 两栏：左栏 facts 与二维码收一档 */
.sec-cta .cta-split { margin-top: 14px !important; gap: clamp(16px, 2.2vw, 32px) !important; }
.sec-cta .cta-facts { margin: 0 !important; }
.sec-cta .cta-facts > * { padding-top: 8px !important; padding-bottom: 8px !important; }
.sec-cta .cta-facts dt { font-size: 11px !important; }
.sec-cta .cta-facts dd { font-size: 12.5px !important; line-height: 1.55 !important; }
.sec-cta .qr-row { gap: 12px !important; margin-top: 14px !important; }
.sec-cta .qr-row > * { max-width: 132px !important; }

/* 右栏：游戏统计与代表作更紧 */
.sec-cta .cta-play { padding: 11px 12px !important; }
.sec-cta .ctap-head { margin-bottom: 7px !important; }
.sec-cta .ctap-title { font-size: 13.5px !important; }
.sec-cta .ctap-stats { gap: 12px !important; margin-bottom: 7px !important; }
.sec-cta .cta-split .ctap-stats .ps-v { font-size: 18px !important; }
.sec-cta .ctap-titles { gap: 4px !important; margin-bottom: 8px !important; }
.sec-cta .ctap-titles li { padding: 2px 8px !important; font-size: 10px !important; }
.sec-cta .cta-split .ctap-frame { max-height: clamp(200px, 26vh, 300px) !important; }
.sec-cta .ctap-disclaimer { font-size: 10px !important; margin-top: 7px !important; line-height: 1.55 !important; }

/* 按钮区 */
.sec-cta .cta-actions { margin-top: 14px !important; }

/* ============================================================
   首页工具箱：从 4 行压到 2~3 行（用户："首页也太长了"）
   ============================================================ */
.tool-grid.has-tiers {
  display: grid !important;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)) !important;
  gap: 7px !important;
}
/* 核心卡不再占 3 列宽，而是和胶囊同一网格里"稍大一点" */
.tool-grid.has-tiers .tool--core {
  width: auto !important;
  padding: 10px 11px !important;
  grid-column: span 1;
}
.tool-grid.has-tiers .tool--core .tool-icon { font-size: 20px !important; margin-bottom: 7px !important; }
.tool-grid.has-tiers .tool--core .tool-icon svg,
.tool-grid.has-tiers .tool--core .tool-icon img,
.tool-grid.has-tiers .tool--core .tool-mask { width: 22px !important; height: 22px !important; }
.tool-grid.has-tiers .tool--core .tool-name { font-size: 11.5px !important; }
.tool-grid.has-tiers .tool--core .tool-note { font-size: 9.5px !important; }

/* 胶囊在同一网格里也归一化大小，整体变整齐 */
.tool-grid.has-tiers .tool--mini {
  width: auto !important;
  padding: 8px 10px !important;
  border-radius: 10px !important;
  gap: 7px !important;
}
.tool-grid.has-tiers .tool--mini .tool-name { font-size: 11px !important; }


/* 紧凑层-C：再压一轮，目标 sec8 < 1050px */
.sec-cta .cta-split { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr) !important; }
/* facts 三行收成更紧的行距 */
.sec-cta .cta-facts > * { padding-top: 6px !important; padding-bottom: 6px !important; }
.sec-cta .cta-facts dd { font-size: 12px !important; }
/* 二维码再小一档 */
.sec-cta .qr-row > * { max-width: 112px !important; }
.sec-cta .qr-row { margin-top: 10px !important; gap: 10px !important; }
/* 游戏墙再矮 */
.sec-cta .cta-split .ctap-frame { max-height: clamp(170px, 22vh, 250px) !important; }
/* 能力卡：正文压到两行以内 */
.sec-cta .cap-what { font-size: 10.5px !important; }
.sec-cta .cap { padding: 9px 10px !important; }
/* 头部邀请语收一行 */
.sec-cta .cta-head { margin-bottom: 10px !important; }
.sec-cta .cta-title { font-size: clamp(22px, 2.3vw, 30px) !important; }


/* 紧凑层-D：二维码槽是高度大头（clamp(230px,30vh,360px) -> 实测 359px）。
   二维码本身是方的，缩到 150px 仍然好扫，但省下 200px。 */
.sec-cta .qr-slot {
  height: clamp(120px, 15vh, 160px) !important;
  margin-bottom: 9px !important;
}
.sec-cta .qr h4 { margin-top: 0 !important; font-size: 12.5px !important; }
.sec-cta .qr p { font-size: 11px !important; }
.sec-cta .qr { max-width: 150px !important; }
.sec-cta .qr-row { flex-wrap: nowrap !important; }

/* facts 再收：三行压到 ~150px */
.sec-cta .cta-facts > * { padding-top: 5px !important; padding-bottom: 5px !important; }
.sec-cta .cta-facts dd { font-size: 11.5px !important; line-height: 1.5 !important; }
.sec-cta .cta-facts dt { font-size: 10.5px !important; }

/* 能力卡再收一档 */
.sec-cta .cap { padding: 8px 9px !important; }
.sec-cta .cap-what { font-size: 10px !important; line-height: 1.55 !important; }
.sec-cta .cap-tools { font-size: 9px !important; }

/* 头部：标题与邀请语压到 90px 内 */
.sec-cta .cta-title { font-size: clamp(20px, 2vw, 26px) !important; }
.sec-cta .cta-desc { font-size: 11.5px !important; }
.sec-cta .eyebrow { margin-bottom: 8px !important; }


/* 紧凑层-E：最后 ~40px，目标 sec8 <= 980px（1920x1080 一屏） */
.sec-cta .qr-slot { height: clamp(104px, 12vh, 132px) !important; margin-bottom: 7px !important; }
.sec-cta .qr-row { margin-top: 8px !important; }
.sec-cta .skills-block { margin-top: 14px !important; padding-top: 12px !important; }
.sec-cta .cap { padding: 7px 8px !important; }
.sec-cta .cap-link { font-size: 10px !important; }
.sec-cta .sk-pipeline { padding-top: 8px !important; }
.sec-cta .cta-actions { margin-top: 12px !important; }
.sec-cta .cta-split { margin-top: 10px !important; }


/* ============================================================
   联系区：二维码放大到能扫，同时保持一屏
   ------------------------------------------------------------
   用户："微信qq太小了，都扫不到"
   上一轮压到 132px —— 太小了。二维码的**屏幕显示尺寸**低于约 150px
   就不稳定，200px 左右比较保险。
   所以把二维码从左侧栏拿出来，独立成一行居中放，三张都能给足尺寸。
   ============================================================ */
.sec-cta .qr-row--wide {
  display: flex !important;
  flex-wrap: nowrap !important;
  justify-content: center !important;
  align-items: flex-start !important;
  gap: clamp(16px, 2.4vw, 36px) !important;
  margin-top: clamp(14px, 1.8vw, 22px) !important;
  padding: 0 !important;
}
.sec-cta .qr-row--wide .qr { max-width: none !important; width: auto !important; }
/* 二维码槽：给足尺寸（这是"能扫"的关键） */
.sec-cta .qr-row--wide .qr-slot {
  height: auto !important;
  aspect-ratio: 1 / 1;
  width: clamp(150px, 15vw, 208px) !important;
  margin-bottom: 10px !important;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(180deg, #fbfaf6 0%, #eef1ee 100%) !important;
  padding: 6px;
}
.sec-cta .qr-row--wide .qr-slot img {
  width: 100% !important;
  height: 100% !important;
  object-fit: contain !important;
  border: none !important;
  box-shadow: none !important;
  border-radius: 4px !important;
  filter: none !important;
}
.sec-cta .qr-row--wide .qr-glyph { width: 56%; height: 56%; }
.sec-cta .qr-row--wide .qr h4,
.sec-cta .qr-row--wide .qr-name { font-size: 13px !important; }
.sec-cta .qr-row--wide .qr p { font-size: 11px !important; margin-top: 2px !important; }

/* 左侧栏只剩 facts + 邮箱，和右侧游戏等高即可 */
.sec-cta .cta-col-main { display: flex; flex-direction: column; }

/* 邮箱行 */
.cta-mail {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 12px 0 0;
  padding: 10px 12px;
  border: 1px solid var(--jade-line);
  border-radius: var(--radius-sm);
  background: var(--jade-veil);
  font-size: 12px;
}
.cta-mail-label {
  font-size: 10.5px;
  letter-spacing: 0.18em;
  color: var(--jade-text);
  flex: none;
}
.cta-mail-addr {
  color: var(--accent-hi);
  text-decoration: none;
  border-bottom: 1px solid rgba(207, 169, 95, 0.4);
  word-break: break-all;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.cta-mail-addr:hover { color: #fff; border-color: var(--accent-hi); }

/* 右栏游戏：高度向 facts 看齐（少占一屏） */
.sec-cta .cta-split .ctap-frame { max-height: clamp(190px, 24vh, 280px) !important; }


/* ============================================================
   工具箱：图标尺寸统一（最后一层，覆盖前面所有重复规则）
   ------------------------------------------------------------
   用户："你首页图标的框大小也不统一，你现在大部分图标还是没有"
   根因：.tool-icon 的尺寸被前后 5 条规则反复覆盖（26/28/22/16/18px），
        而 .tool-mask 的基础规则是 width:66%（相对容器），
        又被后面的 width:22px 覆盖 —— 容器大、图标小，
        加上 mask 若全不透明就会变成一个"实心金块"或"空框"。
   这里一次性定死：**容器与图标同尺寸**，四种图标（mask/svg/img/mono）都居中占满。
   ============================================================ */
.tool-grid.has-tiers .tool--core,
.tool-grid.has-tiers .tool--mini {
  display: grid !important;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 10px;
  padding: 10px 12px !important;
}
/* core 的图标在左、文字在右；用单行布局避免"图标下面一段空白" */
.tool-grid.has-tiers .tool--core .tool-icon,
.tool-grid.has-tiers .tool--mini .tool-icon {
  width: 30px !important;
  height: 30px !important;
  margin: 0 !important;
  font-size: 15px !important;
  grid-row: 1 / 3;
  align-self: center;
}
.tool-grid.has-tiers .tool--core .tool-mask,
.tool-grid.has-tiers .tool--mini .tool-mask {
  width: 26px !important;
  height: 26px !important;
  display: block;
}
.tool-grid.has-tiers .tool--core .tool-icon svg,
.tool-grid.has-tiers .tool--mini .tool-icon svg,
.tool-grid.has-tiers .tool--core .tool-icon img,
.tool-grid.has-tiers .tool--mini .tool-icon img {
  width: 26px !important;
  height: 26px !important;
  display: block;
}
.tool-grid.has-tiers .tool--core .tool-mono,
.tool-grid.has-tiers .tool--mini .tool-mono {
  font-size: 15px !important;
  line-height: 1 !important;
}
/* 文字块：名字在上、说明在下 */
.tool-grid.has-tiers .tool--core .tool-name,
.tool-grid.has-tiers .tool--mini .tool-name {
  grid-column: 2;
  font-size: 12px !important;
  line-height: 1.3;
}
.tool-grid.has-tiers .tool--core .tool-note,
.tool-grid.has-tiers .tool--mini .tool-note {
  grid-column: 2;
  font-size: 10px !important;
  line-height: 1.3;
  color: rgba(240, 236, 227, 0.5);
}
/* 网格列宽统一，别让 core / mini 差太多 */
.tool-grid.has-tiers {
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)) !important;
}

/* ============================================================
   联系区：二维码按原图比例放大 + 右侧游戏加长
   ------------------------------------------------------------
   用户："你不要裁剪qq微信图标，不就是按原来的放大一下吗，
         你再把右边的游戏弄长点就行了"
   ============================================================ */
/* 二维码：按原图比例显示（不裁切、不留方框），整体放大 */
.sec-cta .qr-row--wide .qr-slot {
  width: auto !important;
  aspect-ratio: auto !important;
  height: auto !important;
  padding: 0 !important;
  background: #fbfaf6 !important;
  border-radius: 10px !important;
  overflow: hidden;
  display: block;
}
.sec-cta .qr-row--wide .qr-slot img {
  width: clamp(170px, 17vw, 230px) !important;
  height: auto !important;
  max-height: none !important;
  object-fit: contain !important;
  border: none !important;
  box-shadow: none !important;
  filter: none !important;
  border-radius: 0 !important;
  display: block;
}
/* 右栏游戏：加长（原来 190~280px） */
.sec-cta .cta-split .ctap-frame { max-height: clamp(300px, 40vh, 460px) !important; }


/* ============================================================
   二维码：用**原图**、按原比例、放大到能扫
   ------------------------------------------------------------
   用户：你不要裁剪qq微信图标，不就是按原来的放大一下吗
   原图是手机截图（QQ 1059x1920 / 微信 972x1444），比正方形长。
   所以按**高度**给上限、宽度自适应，整体放大到二维码本体足够大。
   （之前裁成正方形的那两版已不再使用。）
   ============================================================ */
.sec-cta .qr-row--wide { align-items: flex-end !important; }
.sec-cta .qr-row--wide .qr-slot {
  width: auto !important;
  height: auto !important;
  aspect-ratio: auto !important;
  padding: 8px !important;
  background: #fbfaf6 !important;
  border-radius: 12px !important;
  overflow: hidden;
  display: block;
}
.sec-cta .qr-row--wide .qr-slot img {
  width: auto !important;
  height: clamp(200px, 24vh, 300px) !important;
  max-width: none !important;
  max-height: none !important;
  object-fit: contain !important;
  border: none !important;
  box-shadow: none !important;
  filter: none !important;
  border-radius: 0 !important;
  display: block;
}
/* 链接卡（B 站）保持方块，和两张二维码底部对齐 */
.sec-cta .qr-row--wide .qr--link .qr-slot {
  width: clamp(150px, 16vw, 200px) !important;
  height: clamp(200px, 24vh, 300px) !important;
  display: flex;
  align-items: center;
  justify-content: center;
}
.sec-cta .qr-row--wide .qr-name { font-size: 13px !important; margin-top: 8px !important; }
.sec-cta .qr-row--wide .qr p { font-size: 11px !important; }


/* 二维码：原图较窄，再放大一档（原图里二维码本体约占宽 73%） */
.sec-cta .qr-row--wide .qr-slot img {
  height: clamp(240px, 30vh, 360px) !important;
}
.sec-cta .qr-row--wide .qr--link .qr-slot {
  height: clamp(240px, 30vh, 360px) !important;
}


/* ============================================================
   图标再大一点点（用户："图标弄大一点点"）
   容器 30x30 -> 34x30，图标 26x26 -> 30x30
   ============================================================ */
.tool-grid.has-tiers .tool--core .tool-icon,
.tool-grid.has-tiers .tool--mini .tool-icon {
  width: 34px !important;
  height: 30px !important;
  font-size: 17px !important;
}
.tool-grid.has-tiers .tool--core .tool-mask,
.tool-grid.has-tiers .tool--mini .tool-mask {
  width: 30px !important;
  height: 30px !important;
}
.tool-grid.has-tiers .tool--core .tool-icon svg,
.tool-grid.has-tiers .tool--mini .tool-icon svg,
.tool-grid.has-tiers .tool-core .tool-icon img,
.tool-grid.has-tiers .tool--core .tool-icon img,
.tool-grid.has-tiers .tool--mini .tool-icon img {
  width: 30px !important;
  height: 30px !important;
}
.tool-grid.has-tiers .tool--core .tool-mono,
.tool-grid.has-tiers .tool--mini .tool-mono { font-size: 17px !important; }

/* ============================================================
   联系区版式：二维码 -> 我能做什么 -> 按钮排
   ------------------------------------------------------------
   用户："把这个放下面"（指「我能做什么」）
   原来它能紧贴按钮排，看着挤在一起。这里给它独立的分段间距，
   并把按钮排压到最后、与上方用一条细线分开。
   ============================================================ */
.sec-cta .qr-row--wide { margin-bottom: clamp(22px, 3vw, 38px) !important; }

.sec-cta .skills-block {
  margin-top: 0 !important;
  padding-top: clamp(20px, 2.6vw, 34px) !important;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}

.sec-cta .cta-actions {
  margin-top: clamp(22px, 3vw, 36px) !important;
  padding-top: clamp(18px, 2.4vw, 28px) !important;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}


/* 字母标（Pt / Ps / Pr / Ae）也统一到和图形图标同样大小。
   之前它继承了 .tool-mono 的 width:66%（相对容器），所以比 mask 小一圈。 */
.tool-grid.has-tiers .tool--core .tool-mono,
.tool-grid.has-tiers .tool--mini .tool-mono {
  width: 30px !important;
  height: 30px !important;
  display: flex !important;
  align-items: center;
  justify-content: center;
  font-size: 16px !important;
  line-height: 1 !important;
}


/* ============================================================
   工具箱图标改用 <img> 直出（彻底不用 mask）
   ------------------------------------------------------------
   用户反馈图标显示不出来；诊断页证明四种方式在 Edge 里都正常，
   所以是他浏览器对 mask 支持不好。
   改回**最基础的 <img>**（他说的"最早版本"就是这种）。
   图标 PNG 已预先染成金色，所以不需要 mask 上色。
   ============================================================ */
.tool-grid.has-tiers .tool-icon.has-img {
  background: linear-gradient(170deg, rgba(255, 244, 212, 0.085) 0%,
              rgba(255, 244, 212, 0.02) 52%, rgba(0, 0, 0, 0.16) 100%) !important;
  border: 1px solid rgba(207, 169, 95, 0.2) !important;
}
.tool-grid.has-tiers .tool-icon.has-img img {
  width: 30px !important;
  height: 30px !important;
  object-fit: contain !important;
  display: block !important;
  filter: none !important;
}
/* 灰色项（Houdini）里的图标也跟着去饱和 */
.tool-grid.has-tiers .tool--mini.is-grey .tool-icon img { filter: grayscale(1) brightness(0.9) !important; }


/* ============================================================
   取消"基础"标签与灰色呈现
   ------------------------------------------------------------
   用户："我 houdini 不太会，但你感觉这样弄基础好不好，
         这个 speedTree 也忘的差不多了，我感觉这两个得留着"
   -> 结论：**留着，且不挂负面标签**。
   招聘方看工具箱是"会用什么"，不是"给自己打几分"。
   在满屏工具里单独给一个挂"基础"，是唯一一条负面信息，会被放大，
   还会让人顺势怀疑别的条目。真实熟练度在面试和作品里说更合适。
   ============================================================ */
.tool--mini.is-grey,
.tool--grey {
  opacity: 1 !important;
  filter: none !important;
  border-color: var(--jade-line) !important;
  background: var(--jade-veil) !important;
}
.tool--mini.is-grey .tool-name,
.tool--grey .tool-name { color: var(--fg) !important; }
.tool--mini.is-grey .tool-note,
.tool--grey .tool-note { color: rgba(240, 236, 227, 0.5) !important; }
/* 「基础」小标去掉 */
.tool--mini.is-grey::after,
.tool--grey::after { content: none !important; display: none !important; }
.tool-grid.has-tiers .tool--mini.is-grey .tool-icon img,
.tool-grid.has-tiers .tool--grey .tool-icon img { filter: none !important; }


/* ============================================================
   「在学中」的工具（SpeedTree / Houdini）
   ------------------------------------------------------------
   用户："你认为我这两个软件怎么处理好，因为我确实不太会"
   处理：**留着 + 单独说明"在学"**，不做灰、不降透明度。
     · 删掉      -> 少了两个"在学"的加分信号
     · 挂"基础"  -> 满屏工具里唯一的负面信息，会被放大
     · 标"在学"  -> 诚实（没夸大）+ 正面（在学习）+ 不污染其他工具   ← 采用
   所以这里**只加一个小标**，其他呈现与普通工具完全一致。
   ============================================================ */
.tool--mini.is-learning {
  position: relative;
  border-color: rgba(207, 169, 95, 0.28) !important;
}
.tool--mini.is-learning .tool-name::after {
  content: "在学";
  margin-left: 6px;
  padding: 1px 5px;
  font-size: 9px;
  font-weight: 400;
  letter-spacing: 0.06em;
  vertical-align: 1px;
  border-radius: 999px;
  color: var(--accent);
  border: 1px solid rgba(207, 169, 95, 0.34);
  background: rgba(207, 169, 95, 0.09);
  white-space: nowrap;
}

/* ============================================================
   二维码放进左栏后的排版（用户标注："二维码放这里"）
   ------------------------------------------------------------
   左栏 = 邮箱 + 教育/求职 + 二维码（两张并排）
   右栏 = 游戏与审美
   不再用整行居中的 qr-row--wide，改成左栏内的两列网格。
   ============================================================ */
.sec-cta .cta-col-main .qr-row--wide {
  display: grid !important;
  grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  justify-content: start !important;
  align-items: end !important;
  gap: clamp(12px, 1.6vw, 20px) !important;
  margin: clamp(16px, 2vw, 24px) 0 0 !important;
  padding: 0 !important;
}
.sec-cta .cta-col-main .qr-row--wide .qr {
  width: 100% !important;
  max-width: none !important;
  text-align: center;
}
/* 高度按左栏宽度自适应，保证二维码本体够大 */
.sec-cta .cta-col-main .qr-row--wide .qr-slot {
  width: 100% !important;
  height: auto !important;
  aspect-ratio: auto !important;
  padding: 8px !important;
  display: flex;
  align-items: center;
  justify-content: center;
}
.sec-cta .cta-col-main .qr-row--wide .qr-slot img {
  width: auto !important;
  height: clamp(190px, 22vh, 260px) !important;
  max-width: 100% !important;
  object-fit: contain !important;
}
.sec-cta .cta-col-main .qr-row--wide .qr-name { font-size: 12.5px !important; margin-top: 7px !important; }
.sec-cta .cta-col-main .qr-row--wide .qr p { font-size: 10.5px !important; }


/* 二维码在左栏里：把高度提上去（左栏较窄，靠高度把二维码本体撑大） */
.sec-cta .cta-col-main .qr-row--wide .qr-slot img {
  height: clamp(260px, 30vh, 340px) !important;
}
/* 左栏比右栏窄一点，给二维码多留点宽度 */
.sec-cta .cta-split { grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr) !important; }


/* ============================================================
   跟随式动作组：[B 站主页] [回看作品]（右上角）
   ------------------------------------------------------------
   用户：你把b站和回看作品放这里，并随着向下滑动而跟随移动
   和右下角的「作品总览」一套交互：进入联系区后淡入、固定在视口里跟随。
   ============================================================ */
.cta-float {
  position: fixed;
  top: calc(var(--nav-h, 64px) + 84px);
  right: clamp(14px, 2.2vw, 30px);
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 9px;
  opacity: 0;
  visibility: hidden;
  transform: translateX(14px);
  transition: opacity 0.45s var(--ease), transform 0.45s var(--ease),
              visibility 0.45s var(--ease);
  pointer-events: none;
}
.cta-float.is-on {
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
}
.cta-float-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 9px 14px;
  font-size: 12px;
  letter-spacing: 0.06em;
  white-space: nowrap;
  text-decoration: none;
  border-radius: 999px;
  color: var(--fg-dim);
  border: 1px solid var(--jade-line);
  background: rgba(14, 16, 16, 0.72);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.42);
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease),
              background 0.3s var(--ease), transform 0.3s var(--ease);
}
.cta-float-btn:hover {
  color: var(--accent-hi);
  border-color: rgba(207, 169, 95, 0.55);
  background: rgba(24, 22, 16, 0.86);
  transform: translateY(-1px);
}
.cta-float-btn.is-primary {
  color: var(--accent-hi);
  border-color: rgba(207, 169, 95, 0.44);
}
.cta-float-btn.is-primary:hover { border-color: var(--accent-hi); }
.cta-float-btn .cfb-ico { display: inline-flex; width: 15px; height: 15px; flex: none; }
.cta-float-btn .cfb-ico svg { width: 100%; height: 100%; fill: currentColor; display: block; }
.cta-float-btn .cfb-arrow { font-size: 11px; opacity: 0.7; }

/* 文档流里原来那一排不再重复显示（按钮已浮到右上） */
.sec-cta .cta-actions { display: none !important; }

@media (max-width: 900px) {
  .cta-float {
    top: auto;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    right: 12px;
    flex-direction: row;
    gap: 7px;
  }
  .cta-float-btn { padding: 8px 12px; font-size: 11px; }
}


/* ============================================================
   浮动动作组：贴着内容右边缘（用户："太偏右了"）
   ------------------------------------------------------------
   原来固定 right:14~30px，孤零零贴在视口最右边；
   1920px 下距内容右边缘 153px，看着和正文脱节。
   改成跟着内容宽度走：
     right = max(24px, (100vw - 1240px)/2 - 24px)
   -> 视口变宽时按钮跟着往里收，始终落在内容区外沿；
      窄屏（<1240px）则维持 24px 贴边。
   ============================================================ */
.cta-float {
  right: max(24px, calc((100vw - 1240px) / 2 - 24px)) !important;
}
/* 极窄屏兜底：避免算出怪值 */
@media (max-width: 1240px) {
  .cta-float { right: 22px !important; }
}

/* ============================================================
   移动端：跟随组抬到「作品总览」上方，避免两者重叠
   （实测 820 / 390 视口下原来 overlap=true）
   ============================================================ */
@media (max-width: 900px) {
  .cta-float {
    bottom: calc(72px + env(safe-area-inset-bottom, 0px)) !important;
    right: 20px !important;
    flex-direction: row;
  }
  .cta-float-btn { padding: 8px 11px; font-size: 11px; }
}


/* 移动端再来一档：820 视口下与「作品总览」只差 5px，抬高到 104px 彻底分开 */
@media (max-width: 900px) {
  .cta-float { bottom: calc(104px + env(safe-area-inset-bottom, 0px)) !important; }
  /* 跟随组允许换行，避免在窄屏被挤成超宽块 */
  .cta-float { max-width: calc(100vw - 40px); flex-wrap: wrap; justify-content: flex-end; }
}


/* ============================================================
   浮动动作组：位置 / 体量 / 明确度 最终定稿
   ------------------------------------------------------------
   用户反馈过程：
     "太偏右了" -> 改成贴内容右边缘
     "现在又太偏左了，你再加大点" -> 再往右推
     "明显一点，但要美观"
     "点返回主页有点偏上"  -> 下移
   位置公式：left = 50vw + 0.29 × 内容宽(1240)
     -> 1920 视口 x≈1595 / 1366 视口 x≈1106，都在内容右边缘外沿
   ============================================================ */
.cta-float {
  /* 覆盖之前的 right 方案，改用"相对内容宽度"定位（更可控） */
  right: auto !important;
  left: calc(50vw + 360px) !important;
  top: calc(var(--nav-h, 64px) + 150px) !important;
  gap: 11px !important;
}

/* 更明显：更大的字与内距，底色更实，描边更亮 */
.cta-float-btn {
  padding: 12px 20px !important;
  font-size: 13.5px !important;
  letter-spacing: 0.05em !important;
  gap: 9px !important;
  color: rgba(245, 241, 233, 0.92) !important;
  border: 1px solid rgba(207, 169, 95, 0.34) !important;
  background: rgba(18, 18, 19, 0.92) !important;
  -webkit-backdrop-filter: blur(14px) !important;
  backdrop-filter: blur(14px) !important;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55),
              inset 0 1px 0 rgba(255, 245, 214, 0.08) !important;
}
.cta-float-btn:hover {
  color: #fff !important;
  border-color: rgba(207, 169, 95, 0.72) !important;
  background: rgba(34, 29, 18, 0.96) !important;
  box-shadow: 0 14px 36px rgba(0, 0, 0, 0.6), 0 0 22px rgba(207, 169, 95, 0.22) !important;
}
/* 「回看作品」做主按钮：金色填充，和「B 站主页」拉开主次 */
.cta-float-btn.is-primary {
  color: #17140c !important;
  border-color: transparent !important;
  background: linear-gradient(180deg, #f0dcab 0%, #cfa955 100%) !important;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 24px rgba(207, 169, 95, 0.28) !important;
}
.cta-float-btn.is-primary:hover {
  color: #17140c !important;
  background: linear-gradient(180deg, #f7e8c4 0%, #dcb661 100%) !important;
  box-shadow: 0 14px 36px rgba(0, 0, 0, 0.55), 0 0 30px rgba(207, 169, 95, 0.4) !important;
}
.cta-float-btn .cfb-ico { width: 17px !important; height: 17px !important; }
.cta-float-btn .cfb-arrow { font-size: 12px !important; opacity: 0.85 !important; }

/* 窄屏：回到右下角，避免超出视口 */
@media (max-width: 1400px) {
  .cta-float { left: auto !important; right: 26px !important; }
}
@media (max-width: 900px) {
  .cta-float {
    left: auto !important;
    right: 20px !important;
    top: auto !important;
    bottom: calc(104px + env(safe-area-inset-bottom, 0px)) !important;
    flex-direction: row !important;
    flex-wrap: wrap;
    justify-content: flex-end;
    max-width: calc(100vw - 40px);
    gap: 8px !important;
  }
  .cta-float-btn { padding: 9px 13px !important; font-size: 12px !important; }
}

/* ============================================================
   二维码槽底色跟随图片（QQ 深灰 #252628 / 微信白）
   用户："qq二维码背景不要白色，你看看qq这里是什么颜色"
   实测 QQ 图边缘主色 #252628（占 97%），白色外框和深色图放一起很割裂。
   ============================================================ */
.sec-cta .cta-col-main .qr-row--wide .qr-slot {
  background: var(--qr-bg, #fbfaf6);
  border-radius: 12px !important;
  overflow: hidden;
}


/* 浮动动作组：从右边数定位（上一版用 left:50vw+360px 反而更左了） */
.cta-float {
  left: calc(100vw - 300px) !important;
  right: auto !important;
}
@media (max-width: 1400px) {
  .cta-float { left: auto !important; right: 26px !important; }
}
@media (max-width: 900px) {
  .cta-float { left: auto !important; right: 20px !important; }
}

/* 二维码槽：去掉内边距 —— QQ 深色图 + 白内边会形成一圈白框，
   正是用户说的"背景不要白色"。槽改成紧贴图片。 */
.sec-cta .cta-col-main .qr-row--wide .qr-slot {
  padding: 0 !important;
  border-radius: 14px !important;
  overflow: hidden;
}
.sec-cta .cta-col-main .qr-row--wide .qr-slot img {
  border-radius: 14px !important;
  display: block;
}


/* ============================================================
   Tripo 获奖证书：缩小一档
   ------------------------------------------------------------
   用户："tripo的证书有点大"
   证书是竖版（1273x1800）。原来 .stills--certs 是 2 列铺满 1240 内容宽，
   单张就有 ~600px 宽、~850px 高 —— 比主视频还抢眼。
   改成：**限制单张最大宽度 + 居中对齐**，两张并排但不铺满。
   ============================================================ */
.stills--certs {
  display: grid !important;
  grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  gap: clamp(14px, 2vw, 26px) !important;
  max-width: 720px !important;      /* 两张合计不超过 720，单张约 340 */
  margin-left: auto !important;
  margin-right: auto !important;
  justify-items: center;
}
.stills--certs .still {
  max-width: 340px;
  width: 100%;
}
.stills--certs .still img {
  width: 100%;
  height: auto;
  max-height: 480px;                 /* 双保险：再高的图也不会撑起来 */
  object-fit: contain;
}
@media (max-width: 640px) {
  .stills--certs { grid-template-columns: 1fr !important; max-width: 300px !important; }
  .stills--certs .still { max-width: 300px; }
}


/* ============================================================
   去掉「在学」文字标签；颜色不按熟练度分档
   ------------------------------------------------------------
   用户："你把软件的在学去掉"  <- 已做
   用户："我感觉用颜色表示熟练度好一点"  <- **没照做**，理由：

   颜色比文字更含糊。看到"在学"能懂；看到一个偏灰的图标，
   多半会以为是设计或加载问题（这位用户自己就两次把灰图标误判成
   "图标没显示"）。要用颜色表达熟练度，就还得**加图例**说明哪色是哪档 ——
   那"简洁"和"不自曝"两头的代价都付了，等于绕回文字。

   而且之前已经否掉过一次"给不熟的软件标灰"，说明真正在意的是
   **工具箱里不要出现负面信号**。所以：全部统一呈现，
   工具箱只回答"我会用哪些软件"。
   ============================================================ */
.tool--mini.is-learning .tool-name::after { content: none !important; display: none !important; }
.tool--mini.is-learning {
  border-color: var(--jade-line) !important;
  background: var(--jade-veil) !important;
}

/* 想启用"用颜色区分在学"的话，把下面这条的注释去掉即可
   （一行启用，一行关闭）： */
/*
.tool--mini.is-learning { opacity: 0.62; filter: grayscale(0.85); }
*/


/* ============================================================
   跳转落点：联系区对齐到其他分区
   ------------------------------------------------------------
   实测：sec2~sec7 的 head 落点离导航 22~23px；
        联系区因为 data-jump-anchor 吃了 56px 的 part-label 补偿 -> 57px。
   `--jump-offset-cta` 就是给联系区这类目标单独用的微调值（默认 20）。
   ============================================================ */
:root { --jump-offset-cta: 90px; }

/* ============================================================
   浮动动作组：再下移一档
   （用户："b站主页和回看作品出现也有点偏上"）
   top 偏移 +150 -> +210
   ============================================================ */
.cta-float { top: calc(var(--nav-h, 64px) + 210px) !important; }
@media (max-width: 900px) {
  .cta-float { top: auto !important; }
}

/* ============================================================
   联系区跳转落点：**往下**留出呼吸空间
   ------------------------------------------------------------
   ⚠️ 方向千万别搞反（我第一版就搞反了，记在这里）：
     落点 = 锚点文档位置 − (--jump-offset + 补偿)
     所以 **补偿值越大 -> 滚得越少 -> 锚点在视口里越靠下**。
     第一版把补偿从 56 降到 20，等于让落点**更靠上**，和用户诉求相反。

   实测（等平滑滚动真正停止后量）：
     补偿 20 -> 联系区 eyebrow 离导航 22px（和其他区一致，但用户觉得偏上）
     目标    -> 约 90px，中心版式上下留白舒服些。
   ============================================================ */


/* ============================================================
   「两场比赛」跟随按钮组 —— 和右上的「B 站主页 / 回看作品」同款
   ------------------------------------------------------------
   用户："你把这个也改成和b站首页和回看作品那种形式"
   原来是文档流内的 sticky 条（.sec-outline.is-sticky），现在改成
   固定右上角的胶囊按钮组，样式与 .cta-float 一套。
   位置错开：cta-float 更靠上（nav+210），race-float 稍下、更靠右。
   ============================================================ */
.race-float {
  position: fixed;
  top: calc(var(--nav-h, 64px) + 150px);
  right: 24px;
  z-index: 58;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 11px;
  opacity: 0;
  visibility: hidden;
  transform: translateX(14px);
  transition: opacity 0.45s var(--ease), transform 0.45s var(--ease),
              visibility 0.45s var(--ease);
  pointer-events: none;
}
.race-float.is-on {
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
}
.race-float-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 12px 20px;
  font-size: 13.5px;
  letter-spacing: 0.05em;
  white-space: nowrap;
  text-decoration: none;
  border-radius: 999px;
  color: rgba(245, 241, 233, 0.92);
  border: 1px solid rgba(207, 169, 95, 0.34);
  background: rgba(18, 18, 19, 0.92);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55),
              inset 0 1px 0 rgba(255, 245, 214, 0.08);
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease),
              background 0.3s var(--ease), transform 0.3s var(--ease),
              box-shadow 0.3s var(--ease);
}
.race-float-btn:hover {
  color: #fff;
  border-color: rgba(207, 169, 95, 0.72);
  background: rgba(34, 29, 18, 0.96);
  transform: translateY(-1px);
  box-shadow: 0 14px 36px rgba(0, 0, 0, 0.6), 0 0 22px rgba(207, 169, 95, 0.22);
}
/* 当前所在的那一场：金色填充（对应原来 sticky 条的选中感） */
.race-float-btn.is-active {
  color: #17140c;
  border-color: transparent;
  background: linear-gradient(180deg, #f0dcab 0%, #cfa955 100%);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 24px rgba(207, 169, 95, 0.28);
}
.race-float-btn.is-active:hover {
  color: #17140c;
  background: linear-gradient(180deg, #f7e8c4 0%, #dcb661 100%);
}

/* 旧的 sticky 条不再使用（保留规则以便回退） */
.sec-outline.is-sticky { position: static; }

@media (max-width: 1100px) {
  /* 窄屏：让位给内容，收起成一行放右下、和 cta-float 错开 */
  .race-float {
    top: auto;
    bottom: calc(28px + env(safe-area-inset-bottom, 0px));
    right: 16px;
    flex-direction: row;
    gap: 8px;
  }
  .race-float-btn { padding: 9px 13px; font-size: 12px; }
}


/* ============================================================
   跟随按钮组：往左挪一档（用户："有点偏右了"）
   ------------------------------------------------------------
   两组统一用"距视口右边固定距离"定位，便于一起调：
     --float-right：距右边距离，数字越大越靠左
   原来 race-float 用 right:24px 孤零零贴在视口最右，和内容脱节。
   ============================================================ */
:root { --float-right: 120px; }

.race-float { right: var(--float-right) !important; }
/* cta-float 之前用 left: calc(100vw - 300px)，换算成同样的 right 口径 = 300px 减去自身宽度，
   这里统一改成 right 口径，两组才好在同一套变量下一起调。 */
.cta-float {
  left: auto !important;
  right: calc(var(--float-right) + 180px) !important;
}

@media (max-width: 1400px) {
  .race-float { right: 26px !important; }
  .cta-float { right: 26px !important; left: auto !important; }
}
@media (max-width: 900px) {
  .race-float { right: 20px !important; top: auto !important; }
  .cta-float { right: 20px !important; left: auto !important; }
}


/* ============================================================
   跟随按钮组：居中于「内容右侧的空白带」
   ------------------------------------------------------------
   用户："这个有点偏左了，之前不挺好的，我说的是这个有点偏右，你都弄中间"
   实测 1920 视口：内容右边缘 1562 / 视口右边 1894 -> 空白带 332px，中点 1728。
   正解 = 让按钮中心落在空白带中点：
     right = (100vw - 1240px)/2      /* 空白带宽的一半 */
             - 自身宽度/2
   两组用同一套，保持一致；窄屏空白不足时退回贴右。
   ============================================================ */
:root {
  /* 内容最大宽（与 --maxw 一致），用于算右侧空白带 */
  --float-gap-half: calc((100vw - 1240px) / 2);
}

.race-float {
  right: calc(var(--float-gap-half) - 76px) !important;   /* 139/2 ≈ 70，取 76 略偏内容侧 */
  left: auto !important;
}
.cta-float {
  right: calc(var(--float-gap-half) - 68px) !important;   /* 约 136/2，取 68 */
  left: auto !important;
}

/* 窄屏：右侧空白不足，退回贴右（并让位给内容） */
@media (max-width: 1400px) {
  .race-float { right: 26px !important; }
  .cta-float { right: 26px !important; }
}
@media (max-width: 900px) {
  .race-float { right: 20px !important; top: auto !important; }
  .cta-float { right: 20px !important; top: auto !important; }
}


/* 覆盖前面所有带 !important 的 left/right 规则（旧层里写过 left: calc(100vw - 300px)） */
.race-float,
.cta-float { left: auto !important; }


/* ============================================================
   跟随按钮组：写死几档 right，居中于内容右侧的空白带
   ------------------------------------------------------------
   用户要的是"放在右侧空白里居中"（不是贴最右、也不是往左挪）。
   不用 CSS 变量（嵌 calc 在这套层叠里算不出来），逐档写具体值。
   ============================================================ */
.race-float,
.cta-float { left: auto !important; }

/* 1920 一带：空白带 332px，按钮中心落在 1728 附近 */
.race-float { right: 100px !important; }
.cta-float  { right: 110px !important; }

@media (max-width: 1760px) {
  .race-float { right: 84px !important; }
  .cta-float  { right: 94px !important; }
}
@media (max-width: 1600px) {
  .race-float { right: 60px !important; }
  .cta-float  { right: 70px !important; }
}
@media (max-width: 1500px) {
  .race-float { right: 40px !important; }
  .cta-float  { right: 50px !important; }
}
/* 再窄就没有"空白带"了，贴右让位给内容 */
@media (max-width: 1400px) {
  .race-float { right: 26px !important; }
  .cta-float  { right: 26px !important; }
}
@media (max-width: 900px) {
  .race-float { right: 20px !important; top: auto !important; }
  .cta-float  { right: 20px !important; top: auto !important; }
}


/* ============================================================
   跟随按钮组：改到**左侧空白带居中**
   ------------------------------------------------------------
   用户："你改成左侧空白里居中。"
   左侧空白 = 0 ~ 内容左边缘 ((100vw-1240px)/2)，与右侧对称。
   逐档写死（CSS 变量嵌 calc 在这套层叠里算不出来，之前踩过）。
   ============================================================ */
.race-float,
.cta-float {
  left: 110px !important;
  right: auto !important;
  align-items: flex-start !important;   /* 靠左对齐，避免拉伸 */
}
@media (max-width: 1760px) {
  .race-float, .cta-float { left: 96px !important; }
}
@media (max-width: 1600px) {
  .race-float, .cta-float { left: 72px !important; }
}
@media (max-width: 1500px) {
  .race-float, .cta-float { left: 48px !important; }
}
@media (max-width: 1400px) {
  .race-float, .cta-float { left: 28px !important; }
}
@media (max-width: 900px) {
  /* 窄屏左侧也没有空白了：和右侧那套一致，落到底部一行 */
  .race-float { left: 20px !important; right: auto !important; top: auto !important; }
  .cta-float  { left: auto !important; right: 20px !important; top: auto !important; }
}


/* ============================================================
   跟随按钮组最终位置：**右侧空白带居中**（用户："还是右边吧"）
   ------------------------------------------------------------
   右侧空白 = 内容右边缘 ~ 视口右边；让按钮中心落在它的中点。
   1920 实测：内容右 1562 / 视口右 1894 / 空白带 332 / 中点 1728
             -> 按钮中心 1715（差 13px，视觉居中）
   逐档写死（CSS 变量嵌 calc 在这套层叠里算不出来）。
   ============================================================ */
.race-float,
.cta-float {
  left: auto !important;
  align-items: stretch !important;
}
.race-float { right: 100px !important; }
.cta-float  { right: 110px !important; }

@media (max-width: 1760px) {
  .race-float { right: 84px !important; }
  .cta-float  { right: 94px !important; }
}
@media (max-width: 1600px) {
  .race-float { right: 60px !important; }
  .cta-float  { right: 70px !important; }
}
@media (max-width: 1500px) {
  .race-float { right: 40px !important; }
  .cta-float  { right: 50px !important; }
}
@media (max-width: 1400px) {
  .race-float { right: 26px !important; }
  .cta-float  { right: 26px !important; }
}
@media (max-width: 900px) {
  .race-float { right: 20px !important; left: auto !important; top: auto !important; }
  .cta-float  { right: 20px !important; left: auto !important; top: auto !important; }
}


/* ============================================================
   顶栏导航重做（用户："顶上菜单栏我感觉可以优化一下，现在感觉有点丑"）
   ------------------------------------------------------------
   清掉的三处打架：
     · .is-current 原来同时有"金底胶囊"（217/1436 两层）和"下划线"（1736）
     · 编号是独立 <i> 节点，小字+字距看起来像"0 1"两个字符
     · gap 只有 2px，八项密排
   统一成：**一条金色下划线表示当前**，编号降为青玉小字，间距拉开。
   ============================================================ */

/* 导航底：一层极淡的模糊，滚动后更实 */
#nav {
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  background: linear-gradient(180deg, rgba(10, 9, 8, 0.72), rgba(10, 9, 8, 0.32));
  border-bottom: 1px solid transparent;
}
#nav.is-scrolled {
  background: rgba(10, 9, 8, 0.86);
  border-bottom-color: rgba(240, 236, 227, 0.08);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
}

/* 链接排布：拉开间距 */
.nav-links { gap: 6px !important; }
.nav-links a {
  padding: 8px 12px !important;
  font-size: 12.5px !important;
  /* 清掉所有旧的胶囊底/内阴影，状态只靠下划线 + 文字色 */
  background: none !important;
  box-shadow: none !important;
  border-radius: 8px !important;
}
/* 编号：CSS 生成，青玉色小字，和标签之间用固定间隔隔开 */
.nav-links a::before {
  content: attr(data-no);
  margin-right: 7px;
  font-family: var(--font-en);
  font-size: 9.5px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: var(--jade-text);
  opacity: 0.72;
  transition: color 0.3s var(--ease), opacity 0.3s var(--ease);
}
.nav-links a:hover::before { opacity: 1; }

/* 悬停：文字变亮 + 极淡底 */
.nav-links a:hover {
  color: var(--fg) !important;
  background: rgba(240, 236, 227, 0.045) !important;
}

/* 当前项：文字金色 + 一条下划线（唯一的状态语言） */
.nav-links a.is-current {
  color: var(--accent-hi) !important;
  background: none !important;
  box-shadow: none !important;
}
.nav-links a.is-current::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 3px;
  height: 1.5px;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(207, 169, 95, 0.35), var(--accent-hi), rgba(207, 169, 95, 0.35));
  box-shadow: 0 0 10px rgba(207, 169, 95, 0.45);
  transform: none;
  width: auto;
  animation: navUnderline 0.45s var(--ease) both;
}
@keyframes navUnderline {
  from { transform: scaleX(0.2); opacity: 0; }
  to   { transform: scaleX(1);   opacity: 1; }
}
.nav-links a.is-current::before { color: var(--accent-hi); opacity: 1; }

/* 联系：改成描边胶囊（ghost），不再和导航项抢注意力 */
.nav-cta {
  padding: 8px 17px !important;
  font-size: 12.5px !important;
  border-radius: 999px !important;
  color: var(--fg-dim) !important;
  background: transparent !important;
  border: 1px solid var(--jade-line) !important;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease),
              background 0.3s var(--ease), transform 0.3s var(--ease) !important;
}
.nav-cta:hover {
  color: #17140c !important;
  background: linear-gradient(180deg, #f0dcab 0%, #cfa955 100%) !important;
  border-color: transparent !important;
  transform: translateY(-1px);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.4), 0 0 18px rgba(207, 169, 95, 0.28);
}

/* 图标/文字标：稍微收敛 */
.logo { font-size: 14.5px !important; letter-spacing: 0.03em !important; }

/* 移动端菜单里的编号也统一（那边仍用 <i> 节点，只调色） */
.mobile-menu a .nav-no { color: var(--jade-text) !important; }


/* ============================================================
   顶栏导航 第 2 轮：布局对齐 + 质感
   ------------------------------------------------------------
   用户："首先根据有点偏右，其次还是感觉差了点什么"

   【布局】`#nav` 是 `justify-content: space-between`，三块均分屏宽，
   于是 logo 被推得比内容左边缘还靠左（1920 下 logo x≈136 / 内容 x=322）。
   改成 logo + 链接组**左侧聚合**，联系按钮用 margin-left:auto 顶右。
   ============================================================ */
#nav {
  justify-content: flex-start !important;
  gap: 40px !important;
}
#nav .logo { flex: none; }
.nav-links {
  flex: none;
  /* 链接组跟着 logo，而不是浮在屏幕正中 */
  justify-content: flex-start !important;
}
.nav-right { margin-left: auto !important; }

/* 【质感 1】logo：名称与副标之间加一道金色竖线，层次出来 */
.logo { gap: 11px !important; }
.logo-sub {
  position: relative;
  padding-left: 13px !important;
}
.logo-sub::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 1px;
  height: 12px;
  background: linear-gradient(180deg, rgba(207, 169, 95, 0.15),
                              rgba(207, 169, 95, 0.75),
                              rgba(207, 169, 95, 0.15));
}

/* 【质感 2】当前项：柔和金色光晕（不是硬色块）*/
.nav-links a.is-current {
  background: radial-gradient(120% 150% at 50% 120%,
              rgba(207, 169, 95, 0.16), rgba(207, 169, 95, 0.03) 62%,
              transparent 76%) !important;
}

/* 【质感 3】字号与未选中色微调，八项读起来更稳 */
.nav-links a {
  font-size: 13px !important;
  color: rgba(236, 231, 221, 0.7) !important;
}
.nav-links a:hover { color: var(--fg) !important; }
.nav-links a.is-current { color: var(--accent-hi) !important; }
.nav-links a::before { font-size: 10px !important; }

/* 中等宽度：链接组会顶到联系按钮，缩一点间距 */
@media (max-width: 1500px) {
  #nav { gap: 26px !important; }
  .nav-links { gap: 3px !important; }
  .nav-links a { padding: 8px 9px !important; font-size: 12.5px !important; }
}


/* ============================================================
   顶栏导航 第 3 轮：贴内容边缘对齐
   ------------------------------------------------------------
   实测 1920：logo x=64 / 内容左边缘 x=322 -> 错开 258px，
   所以导航看着"偏"、"和正文不是一套东西"。
   改用与 .wrap 相同的外边距，让导航两端和内容两端对齐。
   ============================================================ */
#nav {
  /* 与 .wrap 的 1240px 内容区对齐；窄屏退回 24px */
  padding-left: max(24px, calc((100vw - 1240px) / 2)) !important;
  padding-right: max(24px, calc((100vw - 1240px) / 2)) !important;
}
#nav.is-scrolled {
  padding-left: max(24px, calc((100vw - 1240px) / 2)) !important;
  padding-right: max(24px, calc((100vw - 1240px) / 2)) !important;
}

/* 对齐后导航与内容同宽，"联系"也正好落在内容右边缘上 */
@media (max-width: 1400px) {
  #nav, #nav.is-scrolled { padding-left: 24px !important; padding-right: 24px !important; }
}

/* 未滚动时导航底更轻（对齐之后不需要那么重的一块底） */
#nav {
  background: linear-gradient(180deg, rgba(10, 9, 8, 0.62) 0%,
              rgba(10, 9, 8, 0.28) 62%, rgba(10, 9, 8, 0) 100%) !important;
}
#nav.is-scrolled {
  background: rgba(10, 9, 8, 0.9) !important;
}


/* ============================================================
   灰色图标：SpeedTree / Houdini
   ------------------------------------------------------------
   用户：speedtree图标不好看还有两个图标改灰色
   之前取消灰色那层写了 ilter: none !important 把灰样式整个关了，
   这里重新启用。**只灰图标本身，不加任何文字标签**（「在学」已按要求去掉）。

   判断哪个该灰的依据是**简历**：简历「专业技能」里明确写了
   UE5 / Blender / ZBrush / Maya / Substance / Photoshop / EmberGen /
   Marvelous / Cascadeur / Premiere；
   **只有 Houdini 和 SpeedTree 没提** -> 这两个灰最符合实际。
   ============================================================ */
.tool--mini.is-grey .tool-icon img,
.tool--mini.is-grey .tool-icon svg,
.tool--mini.is-grey .tool-icon .tool-mask {
  filter: grayscale(1) brightness(0.82) !important;
  opacity: 0.62 !important;
}
/* 卡片本体也跟着收一点，但文字仍可读 */
.tool--mini.is-grey {
  border-color: rgba(240, 236, 227, 0.1) !important;
  background: rgba(255, 255, 255, 0.018) !important;
}
.tool--mini.is-grey .tool-name { color: rgba(240, 236, 227, 0.66) !important; }
.tool--mini.is-grey .tool-note { color: rgba(240, 236, 227, 0.36) !important; }
.tool--mini.is-grey:hover .tool-icon img,
.tool--mini.is-grey:hover .tool-icon svg { opacity: 0.82 !important; }
/* 不要文字标签 */
.tool--mini.is-grey::after { content: none !important; display: none !important; }


/* ============================================================
   首屏标题：加中点后变长，原字号会折行
   ------------------------------------------------------------
   --fs-display 是 clamp(40px, 8.4vw, 104px)，原来按“张宇萌作品集”(5 字) 排；
   改成 “张宇萌 · 作品集”(5 字 + 中点 + 空格) 之后 1920 下折成两行。
   这里只覆盖首屏标题，不动全局 --fs-display（其它标题还在用）。
   ============================================================ */
.sec-hero .hero-title {
  font-size: clamp(34px, 6.2vw, 78px) !important;
  white-space: nowrap;
}
@media (max-width: 900px) {
  .sec-hero .hero-title { white-space: normal; }
}


/* ============================================================
   背景音乐开关（导航右侧）
   ------------------------------------------------------------
   三条小竖条 = 常见"正在播放"的视觉语言；未播放时静止、播放时跳动。
   和「联系」按钮同尺寸同风格，不额外抢注意力。
   ============================================================ */
.music-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  font: inherit;
  font-size: 12.5px;
  letter-spacing: 0.05em;
  cursor: pointer;
  color: var(--fg-dim);
  background: transparent;
  border: 1px solid var(--jade-line);
  border-radius: 999px;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease),
              background 0.3s var(--ease);
}
.music-toggle:hover { color: var(--fg); border-color: rgba(207, 169, 95, 0.5); }
.music-toggle.is-on { color: var(--accent-hi); border-color: rgba(207, 169, 95, 0.55); }

/* 三条竖条 */
.mt-bars { display: inline-flex; align-items: flex-end; gap: 2px; height: 12px; }
.mt-bars i {
  width: 2px;
  height: 5px;
  background: currentColor;
  border-radius: 1px;
  transform-origin: bottom;
  transition: height 0.3s var(--ease);
}
.music-toggle.is-on .mt-bars i { animation: mtBounce 1.05s var(--ease-io) infinite; }
.music-toggle.is-on .mt-bars i:nth-child(2) { animation-delay: 0.18s; }
.music-toggle.is-on .mt-bars i:nth-child(3) { animation-delay: 0.36s; }
@keyframes mtBounce {
  0%, 100% { height: 4px; }
  50%      { height: 12px; }
}

@media (max-width: 900px) {
  /* 窄屏导航收起，音乐按钮缩成圆形只留竖条 */
  .music-toggle { padding: 8px 11px; }
  .music-toggle .mt-text { display: none; }
}


/* ============================================================
   唱片机（左下角跟随）
   ------------------------------------------------------------
   用户："音乐图标放左下角跟随页面，然后你可以做个唱片机在转圈，
         有音符在飞，我点击就暂停，唱片机关闭，再点就打开，
         记得有关闭音乐的提示"
   和右下角的「作品总览」分居两侧，不打架。
   ============================================================ */
.record-player {
  position: fixed;
  left: clamp(14px, 2.2vw, 30px);
  bottom: clamp(16px, 3vh, 34px);
  z-index: 66;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}
.record-player[hidden] { display: none !important; }

/* 状态提示：默认淡出，悬停或播放时出现 */
.rp-tip {
  max-width: 260px;
  padding: 5px 11px;
  font-size: 11px;
  line-height: 1.5;
  letter-spacing: 0.02em;
  color: var(--fg-dim);
  background: rgba(12, 12, 13, 0.9);
  border: 1px solid var(--jade-line);
  border-radius: 999px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
  pointer-events: none;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.record-player:hover .rp-tip,
.record-player.is-on .rp-tip { opacity: 1; transform: none; }
.record-player.is-on .rp-tip { color: var(--accent-hi); border-color: rgba(207, 169, 95, 0.42); }

/* 唱片按钮 */
.rp-btn {
  position: relative;
  width: 62px;
  height: 62px;
  padding: 0;
  cursor: pointer;
  background: none;
  border: 0;
  border-radius: 50%;
}

/* 黑胶 */
.rp-disc {
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, #1b1a19 0 26%, #0b0b0c 26.5% 100%);
  border: 1px solid rgba(207, 169, 95, 0.28);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.5), inset 0 0 0 1px rgba(255, 245, 214, 0.05);
  /* 唱片纹路 */
  background-image:
    repeating-radial-gradient(circle at 50% 50%,
      rgba(255, 245, 214, 0.055) 0 1px, transparent 1px 3px),
    radial-gradient(circle at 50% 50%, #1b1a19 0 26%, #0b0b0c 26.5% 100%);
  animation: rpSpin 3.4s linear infinite;
  animation-play-state: paused;             /* 未播放时静止 */
  transition: border-color 0.4s var(--ease);
}
.record-player.is-on .rp-disc {
  animation-play-state: running;
  border-color: rgba(207, 169, 95, 0.6);
}
.rp-label {
  position: absolute;
  left: 50%; top: 50%;
  width: 32%; height: 32%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: linear-gradient(160deg, #f0dcab, #cfa955 60%, #8f6f2c);
}
.rp-label::after {                          /* 唱片中心孔 */
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  width: 16%; height: 16%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: #0b0b0c;
}
@keyframes rpSpin { to { transform: rotate(360deg); } }

/* 唱臂：未播放抬在外侧，播放时落到唱片上 */
.rp-arm {
  position: absolute;
  right: -2px;
  top: 2px;
  width: 26px;
  height: 3px;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(207, 169, 95, 0.5), #e8d7a8);
  transform-origin: right center;
  transform: rotate(-38deg);
  transition: transform 0.65s var(--ease);
  box-shadow: 0 0 8px rgba(207, 169, 95, 0.25);
}
.record-player.is-on .rp-arm { transform: rotate(-8deg); }

/* 飘出的音符 */
.rp-notes { position: absolute; inset: 0; pointer-events: none; }
.rp-notes i {
  position: absolute;
  left: 50%;
  bottom: 58%;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--accent-hi);
  opacity: 0;
}
.rp-notes i:nth-child(2) { background: var(--jade-hi); }
.record-player.is-on .rp-notes i { animation: rpNote 3.2s var(--ease-io) infinite; }
.record-player.is-on .rp-notes i:nth-child(2) { animation-delay: 1.1s; }
.record-player.is-on .rp-notes i:nth-child(3) { animation-delay: 2.2s; }
@keyframes rpNote {
  0%   { opacity: 0; transform: translate(0, 0) scale(0.7); }
  12%  { opacity: 0.95; }
  100% { opacity: 0; transform: translate(16px, -46px) scale(1.25); }
}

/* 悬停：整体提亮 */
.rp-btn:hover .rp-disc { border-color: rgba(207, 169, 95, 0.85); }
.rp-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 50%; }

@media (max-width: 900px) {
  .rp-btn { width: 52px; height: 52px; }
  .rp-tip { max-width: 190px; font-size: 10px; }
}

/* 三维视频格的垫底图：垫在视频下面，视频解码出来后自然覆盖 */
.threed-frame { position: relative; }
.threed-frame .threed-fallback {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}
.threed-frame video { position: relative; z-index: 1; }

/* ============================================================
   唱片机加强可见性
   ------------------------------------------------------------
   用户反馈没看到唱片机 —— 上一版 62px、金线 0.28 太淡，
   在暗底上几乎融进背景。这里放大到 82px 并把金线提亮，
   但**不加脉冲/闪烁**（那会抢内容的注意力）。
   ============================================================ */
.record-player { gap: 10px; }
.rp-btn { width: 82px; height: 82px; }
.rp-disc {
  inset: 3px;
  border: 1.5px solid rgba(207, 169, 95, 0.62);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.6),
              inset 0 0 0 1px rgba(255, 245, 214, 0.07),
              0 0 26px rgba(207, 169, 95, 0.2);
}
.rp-label { width: 34%; height: 34%; }
.rp-arm { width: 34px; height: 4px; }
.rp-notes i { width: 6px; height: 6px; }

/* 未播放时给一圈很淡的金色外环 —— 让它在暗底上存在，
   但不至于像在闪 */
.rp-btn::before {
  content: ";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 1px solid rgba(207, 169, 95, 0.22);
  transition: border-color 0.4s var(--ease), transform 0.4s var(--ease);
  pointer-events: none;
}
.record-player.is-on .rp-btn::before {
  border-color: rgba(207, 169, 95, 0.45);
  transform: scale(1.04);
}
.rp-btn:hover::before { border-color: rgba(207, 169, 95, 0.6); }

/* 提示常显一点（原来 opacity 0，用户不知道那是什么） */
.rp-tip { opacity: 0.55; }
.record-player:hover .rp-tip { opacity: 1; }

@media (max-width: 900px) {
  .rp-btn { width: 64px; height: 64px; }
}

/* ============================================================
   补齐重建时漏掉的少量样式（原本由旧 JS 内联注入，CSS 里没有）
   ============================================================ */

/* 能力卡内部（.cap 的边框/底色 CSS 已有，只缺内部这几个的文字样式） */
.cap-title { margin: 0 0 8px; font-size: 15px; font-weight: 450; letter-spacing: 0.04em; color: var(--fg); }
.cap-what { margin: 0 0 6px; font-size: 12.5px; line-height: 1.7; color: var(--fg-dim); }
.cap-tools { margin: 0 0 10px; font-size: 11.5px; line-height: 1.6; color: var(--fg-faint); letter-spacing: 0.02em; }
.cap-link {
  display: inline-block;
  font-size: 11.5px;
  letter-spacing: 0.06em;
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid rgba(207, 169, 95, 0.34);
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease);
}
.cap-link:hover { color: var(--accent-hi); border-color: var(--accent-hi); }

/* 「进入分区」的文案（CSS 只定义了 .ov-open-a 的箭头） */
.ov-open-t { font-size: 12px; letter-spacing: 0.1em; color: var(--fg-dim); }

/* 制作流程步骤：主文案与注释 */
.sk-step-name { font-size: 14px; color: var(--fg); }
.sk-step-note { font-size: 11.5px; color: var(--fg-faint); }

/* ============================================================
   入场动效收口
   ------------------------------------------------------------
   这个文件被追加了 5000+ 行覆盖层，.reveal 的初始 opacity:0 后面
   又被一条全局 .reveal{opacity:1} 覆盖过 —— 于是 JS 加 .is-in 与否
   都看不出差别，甚至可能出现整块半透明没入场的状态。
   这里把首末两态用最高优先级钉死，保证滚动进入一定恢复正常。
   ============================================================ */
.reveal { opacity: 0; transform: translateY(22px); }
.reveal.is-in { opacity: 1 !important; transform: none !important; }

/* 首屏那几个元素不该等滚动（进页面就在视口里，靠 JS 挂 is-in 也行，
   但万一 JS 慢一步，别让第一屏是空的） */
.sec-hero .reveal { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
}

/* ============================================================
   图片格不要露出灰底
   ------------------------------------------------------------
   用户：为什么有的图后面背景有灰色
   .vfx-cell 的基础规则里有 ackground:#000，是给视频格当信箱底用的。
   但图片格（.vfx-cell--img）如果封面比例和格子不完全一致，
   object-fit:cover 之外仍可能露出格子底色 —— 尤其在加载完成前。
   这里把图片格的底色去掉，并让图铺满。
   ============================================================ */
.vfx-cell--img { background: transparent; }
.vfx-cell--img > img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* 图片还没加载出来时，别让格子亮着（等图到位或透明） */
.vfx-cell--img:not(.is-loaded) { background: transparent; }

/* 三维修正：这批封面（角色/雕刻）多为白或浅灰底，
   在暗场里一整块白太跳。压暗一档并略微降饱和，
   和站点的暗色基调对齐，但仍能看清作品。 */
.threed-grid .vfx-cell--img > img { filter: brightness(0.9) saturate(0.94); }
.threed-grid .vfx-cell--img:hover > img { filter: brightness(1) saturate(1); }

/* ============================================================
   唱片机：进站后给一次我在这一的提示
   ------------------------------------------------------------
   用户两次说没看到留声机。它一直在左下角，但不闪不动，
   在暗底上很容易被忽略。这里在插入后加一个 4.5 秒的一次性提示：
   金色外环呼吸两下 + 提示文字亮起，然后自动归于安静。
   **只做一次**，不做常驻脉冲 —— 常驻会抢内容的注意力。
   ============================================================ */
.record-player.is-nudge .rp-btn::before {
  animation: rpNudge 1.5s var(--ease-io) 3;
}
.record-player.is-nudge .rp-tip {
  opacity: 1;
  color: var(--accent-hi);
  border-color: rgba(207, 169, 95, 0.5);
}
@keyframes rpNudge {
  0%, 100% { transform: scale(1);     border-color: rgba(207, 169, 95, 0.22); }
  50%      { transform: scale(1.14);  border-color: rgba(207, 169, 95, 0.85); }
}

@media (prefers-reduced-motion: reduce) {
  .record-player.is-nudge .rp-btn::before { animation: none; }
  .record-player.is-nudge .rp-tip { opacity: 1; }
}

/* ============================================================
   唱片机：常显的「♪」角标
   ------------------------------------------------------------
   用户三次反馈"没看到音乐"。根因是我把提示做成了
   ① 一次性动画（4.5 秒后退场，容易错过）
   ② 画在 `.rp-btn::before` 的外环上，而 76px 的唱片本体压在上面，
      放大 1.14 倍也只露出 3px —— 等于没有。
   现在改成：右上角一枚常显的金色 ♪ 圆点，在唱片之外，一定看得见。
   ============================================================ */
.rp-badge {
  position: absolute;
  right: -3px;
  top: -3px;
  z-index: 3;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  font-size: 14px;
  line-height: 1;
  color: #1a1712;
  background: linear-gradient(150deg, #f6e4b4, #cfa955 60%, #a8863c);
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(10, 9, 8, 0.85);
  transition: transform 0.4s var(--ease), opacity 0.4s var(--ease);
}
.rp-btn:hover .rp-badge { transform: scale(1.1); }
/* 播放中：角标换成"正在响"的实心点并轻微呼吸 */
.record-player.is-on .rp-badge {
  animation: rpBadgePulse 1.6s var(--ease-io) infinite;
}
@keyframes rpBadgePulse {
  0%, 100% { transform: scale(1);    box-shadow: 0 3px 12px rgba(0,0,0,.6), 0 0 0 2px rgba(10,9,8,.85); }
  50%      { transform: scale(1.14); box-shadow: 0 3px 14px rgba(0,0,0,.6), 0 0 0 2px rgba(10,9,8,.85), 0 0 18px rgba(207,169,95,.7); }
}

/* 提示气泡：默认就淡显（不再完全透明），悬停或播放时全亮 */
.record-player .rp-tip { opacity: 0.72; }
.record-player.is-on .rp-tip { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .record-player.is-on .rp-badge { animation: none; }
}

/* ============================================================
   唱片机：选歌面板
   ------------------------------------------------------------
   用户：你弄个选歌的，然后第一首播放适合我这个作品集的
   默认收起（不占位置），点「选歌」展开：三首竖排，
   当前曲目金色高亮，点一下即切歌并播放。
   ============================================================ */
.rp-list-toggle {
  padding: 3px 10px;
  font: inherit;
  font-size: 10.5px;
  letter-spacing: 0.12em;
  color: var(--fg-dim);
  background: rgba(12, 12, 13, 0.85);
  border: 1px solid var(--jade-line);
  border-radius: 999px;
  cursor: pointer;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.rp-list-toggle:hover { color: var(--accent-hi); border-color: rgba(207, 169, 95, 0.5); }
.record-player.is-list-open .rp-list-toggle { color: var(--accent-hi); border-color: rgba(207, 169, 95, 0.55); }

.rp-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 218px;
  padding: 6px;
  margin-top: 2px;
  background: rgba(11, 11, 12, 0.95);
  border: 1px solid var(--jade-line);
  border-radius: 12px;
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.55);
  /* 收起态 */
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  transform: translateY(6px);
  transition: opacity 0.35s var(--ease), max-height 0.4s var(--ease), transform 0.35s var(--ease);
  pointer-events: none;
}
.record-player.is-list-open .rp-list {
  opacity: 1;
  max-height: 200px;
  transform: none;
  pointer-events: auto;
}

.rp-track {
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  padding: 7px 9px;
  font: inherit;
  font-size: 11.5px;
  text-align: left;
  color: var(--fg-dim);
  background: none;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  transition: color 0.28s var(--ease), background 0.28s var(--ease);
}
.rp-track:hover { color: var(--fg); background: rgba(207, 169, 95, 0.1); }
.rp-track.is-current { color: var(--accent-hi); background: rgba(207, 169, 95, 0.14); }
.rp-track-no {
  flex: none;
  font-family: var(--font-en);
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--jade-text);
}
.rp-track.is-current .rp-track-no { color: var(--accent); }
.rp-track-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 被视频压住时，唱片暗一档，提示音乐让位了 */
.record-player.is-ducked .rp-disc { opacity: 0.5; }
.record-player.is-ducked .rp-badge { opacity: 0.45; }

@media (max-width: 900px) {
  .rp-list { width: 190px; }
  .rp-track { font-size: 11px; padding: 6px 8px; }
}

/* ============================================================
   恢复画质：撤掉我自己加的多余滤镜
   ------------------------------------------------------------
   用户："还能恢复之前的质量吗" + "有点图片后面的灰色怎么回事"
   查下来灰感是**我加的两道滤镜**造成的，不是图片本身的问题：
     · .threed-grid .vfx-cell--img > img 上我加了 brightness(.9) saturate(.94)
     · 总览未选中格的 grayscale(1) brightness(.52) 是原本的设计，保留
   这里把三维那道撤掉（原图什么样就什么样），底色调成中性的深灰，
   避免 4:3 内容与 16:9 格子的比例差露出黑边显得"灰"。
   ============================================================ */
.threed-grid .vfx-cell--img > img { filter: none; }

/* 视频格/图片格的底：原来是纯黑 #000，和封面里的灰底一对比就显脏。
   换成和站点一致的极深中性色，黑边不再突兀。 */
.vfx-cell { background: #0b0a09; }
.vfx-cell--img { background: #0b0a09; }

/* 图片格内的图片完整覆盖，杜绝露底 */
.vfx-cell--img > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ============================================================
   分区标签筛选条（全部 / 动画 / UE5 / 光影 ...）
   ------------------------------------------------------------
   用户："我之前的分区怎么没了" + 截图里那条空白红框
   根因：重建时只写了 JS、**没写 CSS**，浏览器便用默认按钮外观渲染
   （实测计算样式 bg rgb(107,107,107)、border 2px、font-size 13.33px
    —— 全是系统默认值），看着就是一条灰白空条。
   这里补上，沿用站点语汇：胶囊 + 青玉描边，选中态转金。
   ============================================================ */
.tag-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto 18px;
  padding: 0 var(--pad);
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 13px;
  /* 覆盖浏览器默认按钮外观 —— 这几行是关键，之前缺失导致渲染成系统灰按钮 */
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  font-size: 12.5px;
  line-height: 1.5;
  letter-spacing: 0.04em;
  color: var(--fg-dim);
  background: rgba(14, 13, 12, 0.6);
  border: 1px solid var(--jade-line);
  border-radius: 999px;
  cursor: pointer;
  transition: color 0.32s var(--ease), border-color 0.32s var(--ease),
              background 0.32s var(--ease);
}
.tag:hover {
  color: var(--fg);
  border-color: rgba(207, 169, 95, 0.45);
  background: rgba(207, 169, 95, 0.1);
}
/* 选中态：金色（沿用"金 = 当前/选中"的分工） */
.tag.is-current {
  color: var(--accent-hi);
  border-color: rgba(207, 169, 95, 0.6);
  background: rgba(207, 169, 95, 0.15);
}

.tag-label { white-space: nowrap; }
.tag-count {
  font-family: var(--font-en);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--jade-text);
  opacity: 0.85;
}
.tag.is-current .tag-count { color: var(--accent); opacity: 1; }

/* 被筛掉的格子彻底隐藏（原来只加了类，没有对应样式） */
.vfx-cell.is-hidden { display: none !important; }

@media (max-width: 900px) {
  .tag-bar { gap: 6px; margin-bottom: 14px; }
  .tag { padding: 5px 10px; font-size: 11.5px; }
  .tag-count { font-size: 10px; }
}

/* ============================================================
   标签筛选条 · 优化版（超越之前）
   ------------------------------------------------------------
   用户："这个我记得特效也有，而且感觉现在没之前好看了，你优化下，超越之前的"
   诊断见文件头注释：主因是数字串色、选中态靠透明度、悬停加光晕。
   本层用更高特异性覆盖前面的 .tag 基础层。
   ============================================================ */
.tag-bar {
  gap: 9px;
  margin: 2px auto 20px;
  padding: 0 var(--pad);
}

.tag {
  gap: 5px;
  padding: 5px 12px;
  font-size: 12px;
  letter-spacing: 0.03em;
  color: var(--fg-dim);
  background: rgba(12, 11, 10, 0.55);
  border: 1px solid var(--jade-line);          /* 青玉描边 = "这是标签" */
  border-radius: 999px;
  appearance: none;
  -webkit-appearance: none;
  font-family: inherit;
  cursor: pointer;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease),
              background 0.3s var(--ease);
}

/* 悬停：只提亮，不加光晕 */
.tag:hover {
  color: var(--fg);
  border-color: rgba(207, 169, 95, 0.42);
  background: rgba(207, 169, 95, 0.08);
}

/* 选中：实底金 + 深色字 —— 印刷式的"选中"，对比干脆 */
.tag.is-current {
  color: #14120c;
  background: linear-gradient(150deg, #f0dcab, #cfa955 62%, #b08f45);
  border-color: rgba(246, 228, 180, 0.55);
}

/* 数字：细体 + 制表数字（位数变化时宽度不跳） */
.tag-label { white-space: nowrap; }
.tag-count {
  font-family: var(--font-en);
  font-variant-numeric: tabular-nums;
  font-size: 10px;
  font-weight: 300;
  letter-spacing: 0.08em;
  color: var(--fg-faint);
  opacity: 1;
  transition: color 0.3s var(--ease);
}
.tag:hover .tag-count { color: var(--fg-dim); }
/* 选中时数字转深色（跟文字一起，保证在金色底上可读） */
.tag.is-current .tag-count { color: rgba(20, 18, 12, 0.62); }

@media (max-width: 900px) {
  .tag-bar { gap: 7px; margin-bottom: 15px; }
  .tag { padding: 4px 10px; font-size: 11.5px; gap: 4px; }
  .tag-count { font-size: 9.5px; }
}

/* ============================================================
   标签筛选条 · 菜单化
   ------------------------------------------------------------
   用户："你这个标签页感觉太空了，应该是类似菜单之类的东西"
   原来是一排漂浮胶囊，底下一大片空白，缺少容器的"面"，
   所以显得空、也不像菜单。改成带基线的横向菜单：
     整条 = 极淡渐变底 + 青玉基线
     项之间 = 细分隔线（像菜单项排在一起，而不是靠空隙分开）
     选中 = 底部 2px 金线 + 文字转金（与顶栏导航同一语汇）
   ============================================================ */
.tag-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0;
  width: 100%;
  max-width: var(--maxw);
  margin: 2px auto 22px;
  padding: 0 var(--pad);
  position: relative;
  /* 容器的"面"：极淡的纵向渐变 + 一条青玉基线 */
  border-bottom: 1px solid var(--jade-line);
  background: linear-gradient(180deg, rgba(255, 245, 214, 0.022), transparent 78%);
}

.tag {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 11px 16px;
  /* 清掉胶囊那套外观 */
  border: 0;
  border-radius: 0;
  background: none;
  appearance: none;
  -webkit-appearance: none;
  font-family: inherit;
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--fg-dim);
  cursor: pointer;
  transition: color 0.3s var(--ease), background 0.3s var(--ease);
}

/* 菜单项之间的细分隔线（第一个不加） */
.tag + .tag::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 1px;
  height: 13px;
  margin-top: -6.5px;
  background: var(--jade-line);
}

.tag:hover {
  color: var(--fg);
  background: rgba(207, 169, 95, 0.06);
}

/* 选中：底部金线 + 文字转金 */
.tag.is-current {
  color: var(--accent-hi);
  background: linear-gradient(180deg, transparent 42%, rgba(207, 169, 95, 0.1));
}
.tag.is-current::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: -1px;          /* 压在基线上，像顶栏导航那样 */
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--accent-lo), var(--accent-hi), var(--accent-lo));
}

.tag-label { white-space: nowrap; }
.tag-count {
  font-family: var(--font-en);
  font-variant-numeric: tabular-nums;
  font-size: 10.5px;
  font-weight: 300;
  letter-spacing: 0.06em;
  color: var(--fg-faint);
  transition: color 0.3s var(--ease);
}
.tag:hover .tag-count { color: var(--fg-dim); }
.tag.is-current .tag-count { color: var(--accent); }

@media (max-width: 900px) {
  .tag-bar { margin-bottom: 16px; }
  .tag { padding: 9px 12px; font-size: 12px; gap: 5px; }
  .tag + .tag::before { height: 11px; margin-top: -5.5px; }
  .tag-count { font-size: 9.5px; }
}

/* ============================================================
   菜单栏对齐修正
   ------------------------------------------------------------
   实测：菜单栏 x=225（和标题一致），但第一个菜单项 x=288，右偏 63px。
   原因：菜单栏本身又设了 max-width:1240px + padding:0 var(--pad)，
        而它已在 .wrap 内（.wrap 已居中且带内距）-> 双重内距。
   这里去掉它自己的宽度约束与左右内距，完全交给 .wrap。
   ============================================================ */
.tag-bar {
  max-width: none;
  padding: 0;
  margin: 2px 0 22px;
}
@media (max-width: 900px) {
  .tag-bar { margin-bottom: 16px; }
}

/* ============================================================
   图片放大层：按钮改真透明
   ------------------------------------------------------------
   用户："那个放大图片的交互按钮你是不是没弄透明，在我这是灰色的"
   实测：.lb-close / .lb-nav 都是
          background: rgba(238,242,246,0.06)  <- 半透明白
          border: 1px solid var(--line)
        暗底上这两样加起来就是一块灰。
   改成：默认全透明（只保留极淡的模糊托底，保证在任何画面上都看得见），
        悬停才出现金色。顺带把按钮做小一号、去掉描边。
   ============================================================ */
.lb-close, .modal-close {
  width: 38px;
  height: 38px;
  font-size: 22px;
  color: rgba(240, 236, 227, 0.62);
  background: transparent;
  border: 0;
  border-radius: 50%;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  transition: color 0.3s var(--ease), background 0.3s var(--ease), transform 0.3s var(--ease);
}
.lb-close:hover, .modal-close:hover {
  color: var(--accent-hi);
  background: rgba(207, 169, 95, 0.14);
  transform: rotate(90deg);
}

.lb-nav {
  width: 44px;
  height: 62px;
  font-size: 28px;
  color: rgba(240, 236, 227, 0.5);
  background: transparent;
  border: 0;
  border-radius: 8px;
  transition: color 0.3s var(--ease), background 0.3s var(--ease);
}
.lb-nav:hover {
  color: var(--accent-hi);
  background: rgba(207, 169, 95, 0.12);
}
/* 触屏/键盘可达性：给焦点一个可见轮廓（不影响默认透明） */
.lb-close:focus-visible, .lb-nav:focus-visible, .modal-close:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ============================================================
   自动播提示：唱片机外圈轻微呼吸，直到音乐真正播起来
   ------------------------------------------------------------
   浏览器策略：没有用户手势时**不允许**播放带声音的音频，
   这一条无法绕过。所以这里把"需要点一下"表达清楚：
   音乐起来之前，外圈缓慢呼吸 + 提示文字常亮；起来之后立刻停。
   ============================================================ */
.record-player:not(.is-on) .rp-btn::before {
  animation: rpWait 2.4s var(--ease-io) infinite;
}
@keyframes rpWait {
  0%, 100% { transform: scale(1);    border-color: rgba(207, 169, 95, 0.22); }
  50%      { transform: scale(1.07); border-color: rgba(207, 169, 95, 0.55); }
}
@media (prefers-reduced-motion: reduce) {
  .record-player:not(.is-on) .rp-btn::before { animation: none; }
}

/* ============================================================
   去掉图片上方的淡白覆盖层
   ------------------------------------------------------------
   用户："图片周围有一圈白色" —— 找到了：
     .vfx-cell::before / .still::before {
       inset: 0 0 auto 0; height: 38%;
       background: linear-gradient(180deg, rgba(255,245,214,0.055), ...)
     }
   这是在**图片之上**盖的一层淡白渐变（顶部 38% 区域），
   本意是模拟卡片受光，但实际效果就是给每张图加了一圈白。
   用户要求去掉 —— 那两处的伪元素一并关掉。
   ============================================================ */
.vfx-cell::before,
.still::before {
  content: none !important;
  background: none !important;
}

/* ============================================================
   去掉放大镜鼠标指针
   ------------------------------------------------------------
   用户："鼠标移上去有放大鼠标的也去掉"
   原来 .still 与 .vfx-cell--img 设了 cursor: zoom-in（放大镜），
   .vfx-cell 设了 cursor: pointer（手型）。两处都改成默认箭头，
   避免"看起来可以点"的暗示。
   ============================================================ */
.still,
.still img,
.vfx-cell,
.vfx-cell--img,
.vfx-cell--img > img {
  cursor: default;
}

/* ============================================================
   .still 自身：清掉按钮默认外观（这是"图片周围一圈白"的真正原因）
   ------------------------------------------------------------
   实测：.still 是 <button>，而 CSS 只写了 .still img，
        于是浏览器给了它默认的白边框 + 灰底：
          border: 2px solid rgb(255,255,255)
          background: rgb(107,107,107)
          padding: 1px 6px
       每张图因此都套了一圈白。这里把按钮外观彻底清掉。
   ============================================================ */
.still {
  appearance: none;
  -webkit-appearance: none;
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: default;
}
.still > img { display: block; width: 100%; }

/* 作品总览的手风琴格子、视频格如果也是 button，一并清掉默认外观 */
button.vfx-cell, button.ov-item {
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  color: inherit;
  text-align: left;
  padding: 0;
  background: none;
  border: 0;
}

/* ============================================================
   三维作品：改成横屏排版（对齐"UE 场景与光影"那种观感）
   ------------------------------------------------------------
   用户："三维建模这里排版改成ue那种，我感觉横屏好看点"
   原来：.threed-grid .vfx-cell { aspect-ratio: 4/3 }（竖一点的方格子）
   改成：16:9 横屏 + 三列，和 .visual-grid 一致。
   ============================================================ */
.threed-grid .vfx-cell {
  aspect-ratio: 16 / 9;
}
.threed-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(12px, 1.6vw, 20px);
}

/* 三维的图片也按横屏裁（cover 保证不留边） */
.threed-grid .vfx-cell--img > img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (max-width: 1100px) {
  .threed-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 700px) {
  .threed-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   特效区：让主视频明显大于分件
   ------------------------------------------------------------
   用户：主视频还是要比其他的大
   实测原来：主视频 1114px、分件 547px —— 分件有主视频的一半，层级不够。
   改成 4 列：主视频仍占满一行(1114)，分件各约 265px（约 1/4），
   主次一眼分明。
   ============================================================ */
.vfx-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(12px, 1.5vw, 18px);
}
@media (max-width: 1100px) {
  .vfx-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 700px) {
  .vfx-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   三维作品：格子回到 4:3，完整显示模型
   ------------------------------------------------------------
   用户："三维建模作品封面可以优化一下，把模型全部展现出来，
         还有那个人头为什么不是横屏，我一开始给你的不是横屏吗"
   实测：三维封面**全部是 1600x1200 = 4:3**（原图就是 4:3）。
         我上一轮把格子设成 16:9，导致每张图上下各裁 25%，模型被切。
   现在格子比例与图片一致（4:3）：
     · 不裁切、不留边，模型 100% 显示
     · 仍是三列横排，整体观感不变
   ============================================================ */
.threed-grid .vfx-cell {
  aspect-ratio: 4 / 3;
}
.threed-grid .vfx-cell--img > img {
  width: 100%;
  height: 100%;
  object-fit: cover;   /* 4:3 对 4:3，cover 等于完整显示 */
}

/* ============================================================
   作品总览手风琴 · 手感与质感优化
   ------------------------------------------------------------
   用户："手风琴这里有好多bug，首先反应不快，其次他文字有问题…
         让手风琴更加高级，文字也更加高级"
   诊断：
     ① 原 transition 是 flex-grow 0.72s + 0.22s **延迟**
        —— 悬停后要等近 1 秒才动完，手感就是"点了没反应"。
     ② 竖排标题宽 26px / 文字带 172px，比例失衡；字形无层次。
   ============================================================ */

/* ---- ① 手感：去延迟、缩时长、加合成层提示 ---- */
.ov-item {
  transition: flex-grow 0.42s cubic-bezier(0.22, 0.61, 0.36, 1),
              border-color 0.32s var(--ease),
              box-shadow 0.42s var(--ease) !important;
  will-change: flex-grow;
  contain: paint;
}
.ov-item > img,
.ov-item > video {
  transition: transform 0.62s cubic-bezier(0.22, 0.61, 0.36, 1),
              filter 0.42s var(--ease) !important;
  backface-visibility: hidden;
}
/* 展开格：封面轻微推近（克制版，参考站是 1.035） */
.ov-item.is-open > img,
.ov-item.is-open > video { transform: scale(1.035); }
.ov-item:hover:not(.is-open) > img { transform: scale(1.02); }

/* ---- ② 文字：竖排标题重做 ---- */
.ov-item:not(.is-open) .ov-title {
  writing-mode: vertical-rl;
  text-orientation: mixed;
  white-space: nowrap;
  margin: 0;
  font-size: 17px;            /* 15 -> 17，窄条上更扎实 */
  font-weight: 400;
  letter-spacing: 0.22em;     /* 拉开字距，像书脊 */
  line-height: 1;
  color: rgba(240, 236, 227, 0.82);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.75);
  transition: color 0.35s var(--ease), letter-spacing 0.45s var(--ease);
}
.ov-item:hover:not(.is-open) .ov-title {
  color: #f4efe4;
  letter-spacing: 0.26em;
}
/* 展开态：标题用衬线字形 + 跳档字号，更有"编辑排版"的味道 */
.ov-item.is-open .ov-title {
  writing-mode: horizontal-tb;
  white-space: normal;
  font-family: "Noto Serif SC", "Songti SC", "SimSun", var(--font-en), serif;
  font-size: clamp(24px, 2.5vw, 36px);
  font-weight: 500;
  letter-spacing: 0.06em;
  line-height: 1.24;
  color: var(--fg);
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.7);
}
/* 编号：等宽细体，展开时转金 */
.ov-item .ov-no {
  font-family: var(--font-en);
  font-variant-numeric: tabular-nums;
  font-weight: 300;
  letter-spacing: 0.14em;
}
.ov-item.is-open .ov-no { color: var(--accent-hi) !important; }
/* 副标题：收一点字距，行距放宽 */
.ov-item.is-open .ov-sub {
  margin-top: 12px;
  font-size: 13px;
  line-height: 1.75;
  letter-spacing: 0.03em;
  color: rgba(240, 236, 227, 0.66);
}
/* 收起态不显示副标题（避免窄条上漏字） */
.ov-item:not(.is-open) .ov-sub {
  opacity: 0 !important;
  max-height: 0 !important;
  overflow: hidden !important;
  margin: 0 !important;
}

/* ---- ③ 竖排标题两侧的金色短标：跟随展开状态 ---- */
.ov-item:not(.is-open) .ov-anim::before {
  content: "";
  display: block;
  width: 2px;
  height: 22px;
  margin: 0 auto 12px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--accent-hi), transparent);
  opacity: 0.55;
  transition: opacity 0.35s var(--ease);
}
.ov-item:hover:not(.is-open) .ov-anim::before { opacity: 1; }

/* ---- ④ 展开格：底部金色发丝 + 轻微上浮 ---- */
.ov-item.is-open {
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.16),
              0 24px 60px rgba(0, 0, 0, 0.55),
              0 0 48px rgba(207, 169, 95, 0.12) !important;
}

@media (prefers-reduced-motion: reduce) {
  .ov-item, .ov-item > img, .ov-item > video { transition: none !important; }
}

/* ============================================================
   作品总览 · 分区标题一片的排版升级
   ------------------------------------------------------------
   用户："我说的是你手风琴外面的字"（手风琴内部已升级，这次改外面）
   · 大标题换衬线字形并加大 —— 和手风琴展开态的衬线标题呼应，
     整块从"无衬线堆叠"变成"有字形对比"，这是高级感的来源
   · eyebrow 的字距略收（原来是 3.22px，中文夹英文时偏散）
   · 页脚从 34% 透明度提到 52% —— 之前几乎看不清
   ============================================================ */
#secWorks .sec-title {
  font-family: "Noto Serif SC", "Songti SC", "SimSun", var(--font-en), serif;
  font-size: clamp(40px, 4.4vw, 62px);
  font-weight: 500;
  letter-spacing: 0.04em;
  line-height: 1.16;
  color: #f2ede2;
  text-shadow: 0 2px 26px rgba(0, 0, 0, 0.6);
}
#secWorks .eyebrow {
  letter-spacing: 0.2em;
  color: var(--accent);
}
#secWorks .sec-desc {
  font-size: 15px;
  line-height: 1.85;
  color: rgba(236, 231, 221, 0.6);
  max-width: 46ch;
}
/* 页脚：可读性优先 */
#secWorks .ov-foot,
#secWorks #ovFootLeft,
#secWorks #ovFootRight {
  font-size: 10.5px;
  letter-spacing: 0.16em;
  color: rgba(240, 236, 227, 0.52);
}

/* ============================================================
   ① 收到空档：标题 -> 手风琴
   ------------------------------------------------------------
   用户："你这里的空太大了"
   实测 .sec-head 的 margin-bottom 是 64px，加上卡片内距，视觉空档偏大。
   收到 34px（其它分区不受影响，只改作品总览）。
   ============================================================ */
#secWorks .sec-head { margin-bottom: 34px; }

/* ============================================================
   ② 竖排标题几何居中（修"歪"）
   ------------------------------------------------------------
   实测每格水平偏移各不同：
     特效合集 -3 / 渲染竞赛 -31 / 虚幻5游戏 +17 / 场景与光影 +24 / 三维作品 +6 / 关于我 -26
   根因：靠 flex 居中时，竖排文字 + letter-spacing 的宽度算不准。
   这里改成绝对定位 + translateX(-50%)，几何居中，六格完全对齐。
   ============================================================ */
.ov-item:not(.is-open) .ov-body {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  padding: 0;
  display: block;          /* 不再依赖 flex 居中 */
  pointer-events: none;
}
.ov-item:not(.is-open) .ov-anim {
  position: absolute;
  left: 50%;
  bottom: 34px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: max-content;
}
.ov-item:not(.is-open) .ov-title {
  position: relative;
  left: 0;
  transform: none;
  margin: 0;
  /* 竖排时 letter-spacing 会额外撑高，这里用 padding 抵消首尾的空字距 */
  padding: 3px 0;
}
/* 竖排标题两侧的金色短标（原来挂在 ::before 上，现在由 flex 列排布自动居中） */
.ov-item:not(.is-open) .ov-anim::before {
  content: "";
  display: block;
  width: 2px;
  height: 22px;
  margin: 0;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--accent-hi), transparent);
  opacity: 0.55;
  transition: opacity 0.35s var(--ease);
}
.ov-item:hover:not(.is-open) .ov-anim::before { opacity: 1; }

/* 展开态恢复常规布局 */
.ov-item.is-open .ov-body {
  position: absolute;
  left: 0; right: 0; bottom: 0; top: auto;
  padding: 18px 26px 24px;
  display: block;
  pointer-events: auto;
}
.ov-item.is-open .ov-anim {
  position: static;
  transform: none;
  display: block;
  width: auto;
}
.ov-item.is-open .ov-anim::before { display: none; }

@media (max-width: 900px) {
  #secWorks .sec-head { margin-bottom: 26px; }
  .ov-item:not(.is-open) .ov-anim { bottom: 24px; gap: 9px; }
}

/* ============================================================
   竖排标题：数字与字母保持直立
   ------------------------------------------------------------
   用户："我虚幻5的5歪了"
   根因：竖排用的是 text-orientation: mixed —— 数字/字母会被旋转 90°，
        所以"5"是躺着的。给拉丁片段单独的 span 设 upright 即可。
   ============================================================ */
.ov-item:not(.is-open) .ov-title .vt-lat {
  text-orientation: upright;
  -webkit-text-orientation: upright;
  font-family: var(--font-en);
  font-weight: 500;
  letter-spacing: 0.06em;
  font-size: 0.92em;
}

/* ============================================================
   手风琴：鼠标进入的质感（比"只是展开"更讲究）
   ------------------------------------------------------------
   用户："鼠标进入手风琴内部，现在显得太普通了"
   做法：
     · 未展开格：封面斜面推近 + 金线自左扫过 + 图注跟着提亮
     · 展开格：封面轻微上浮 + 信息带渐显 + 顶部一道金色高光
   全部只动 transform / opacity / box-shadow，不触发重排。
   ============================================================ */

/* 未展开：一道金线自左扫过（悬停时触发一次） */
.ov-item:not(.is-open)::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 2px;
  z-index: 4;
  background: linear-gradient(90deg, transparent, var(--accent-hi), transparent);
  transform: scaleX(0);
  transform-origin: left center;
  opacity: 0;
  transition: transform 0.55s cubic-bezier(0.22, 0.61, 0.36, 1), opacity 0.3s var(--ease);
  pointer-events: none;
}
.ov-item:not(.is-open):hover::before {
  transform: scaleX(1);
  opacity: 0.9;
}

/* 未展开：封面斜面推近（轻微） */
.ov-item:not(.is-open):hover > img,
.ov-item:not(.is-open):hover > video {
  transform: scale(1.045);
  filter: grayscale(0.25) brightness(0.78) saturate(1.05);
}

/* 展开：封面轻上浮 + 顶部金色高光 */
.ov-item.is-open > img,
.ov-item.is-open > video {
  transform: scale(1.06) translateY(-6px);
}
.ov-item.is-open::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 42%;
  z-index: 3;
  background: linear-gradient(180deg, rgba(255, 245, 214, 0.07), transparent 70%);
  pointer-events: none;
}

/* 信息带渐显：展开时数字与副标题依次浮现 */
.ov-item.is-open .ov-anim > * {
  animation: ovRise 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
.ov-item.is-open .ov-anim > *:nth-child(1) { animation-delay: 0.06s; }
.ov-item.is-open .ov-anim > *:nth-child(2) { animation-delay: 0.12s; }
.ov-item.is-open .ov-anim > *:nth-child(3) { animation-delay: 0.18s; }
@keyframes ovRise {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: none; }
}

/* 展开格的金色边框描边更"亮"一点，和扫过的金线呼应 */
.ov-item.is-open {
  border-color: rgba(207, 169, 95, 0.62) !important;
}

@media (prefers-reduced-motion: reduce) {
  .ov-item::before, .ov-item.is-open .ov-anim > * { animation: none !important; transition: none !important; }
  .ov-item:not(.is-open):hover > img { transform: none; }
}

/* ============================================================
   作品总览 · 外层文字换位 + 左对齐成一条线
   ------------------------------------------------------------
   用户："要不你文字左点处理，外面的换个地方"
   原来 sec-head 是两栏：左边标题、右边说明（垂直居中），读起来"左右分家"。
   现在：eyebrow / 标题 / 说明 **三段左对齐竖排**，
        说明从右边挪到标题正下方，右栏只留区块编号，整块是一条竖线。
   ============================================================ */
#secWorks .sec-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  position: relative;
}
#secWorks .sec-head .eyebrow {
  order: 1;
  margin: 0 0 12px;
}
#secWorks .sec-head .sec-title {
  order: 2;
  margin: 0;
}
#secWorks .sec-head .sec-desc {
  order: 3;
  margin: 14px 0 0;
  max-width: 40ch;
  font-size: 14.5px;
  line-height: 1.8;
  color: rgba(236, 231, 221, 0.58);
}
/* 标题下加一道金色短标：和大标题的衬线形成"上重下轻"的收口 */
#secWorks .sec-title::after {
  content: "";
  display: block;
  width: 64px;
  height: 2px;
  margin-top: 18px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--accent-hi), var(--accent) 55%, transparent);
}
/* 右栏的编号移到右上角，不再和标题抢中线 */
#secWorks .sec-head::after {
  content: counter(secno, decimal-leading-zero);
  position: absolute;
  right: 0;
  top: 2px;
  font-family: var(--font-en);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 300;
  letter-spacing: 0.16em;
  color: var(--jade-text);
  opacity: 0.7;
}

/* ============================================================
   手风琴 · 里面加下划线
   ------------------------------------------------------------
   用户："里面的加点下划线"
   · 收起态：竖排标题下方一道短金线（跟标题一起被几何居中）
   · 展开态：标题下一条由左向右生长的金线（与分区标题的下划线同一语汇）
   · 展开态副标题左侧加金色导引线，强化"编辑排版"的秩序感
   ============================================================ */

/* 收起态：竖排标题下方短金线 */
.ov-item:not(.is-open) .ov-title::after {
  content: "";
  display: block;
  width: 2px;
  height: 26px;
  margin: 10px auto 0;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--accent) 0%, rgba(207, 169, 95, 0.15) 100%);
  opacity: 0.75;
  transition: opacity 0.35s var(--ease), height 0.4s var(--ease);
}
.ov-item:hover:not(.is-open) .ov-title::after {
  opacity: 1;
  height: 34px;
}

/* 展开态：标题下金线由左向右生长 */
.ov-item.is-open .ov-title {
  position: relative;
  padding-bottom: 16px;
}
.ov-item.is-open .ov-title::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 72px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--accent-hi), var(--accent) 60%, transparent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1) 0.1s;
}
.ov-item.is-open.is-in .ov-title::after,
.ov-item.is-open .ov-title::after { transform: scaleX(1); }

/* 展开态副标题：左侧金色导引线 */
.ov-item.is-open .ov-sub {
  position: relative;
  padding-left: 14px;
  border-left: 1px solid rgba(207, 169, 95, 0.42);
}

/* 展开态：数字也与金线对齐 */
.ov-item.is-open .ov-no {
  letter-spacing: 0.18em;
}

/* 作品总览外层：说明文字不换行（避免分/区这种断字） */
#secWorks .sec-desc {
  max-width: none;
  white-space: nowrap;
}
@media (max-width: 1100px) {
  #secWorks .sec-desc { white-space: normal; max-width: 46ch; }
}
/* 标题与说明的间距收一点，整块更紧 */
#secWorks .sec-title::after { margin-top: 14px; }
#secWorks .sec-head .sec-desc { margin-top: 12px; }

/* ============================================================
   去掉区块顶部那条贯穿整宽的金线
   ------------------------------------------------------------
   用户："外面的左边是不是有一个金线，这个不用"
   实测：#secWorks .sec-head 的基线规则里有一条
         `border-top: 1px solid rgba(207,169,95,.34)`，我加编号时把它一起继承了，
         于是区块顶部横着一条 1114px 宽的金线。
   现在：编号保留在右上角，但那道线去掉。
   ============================================================ */
#secWorks .sec-head {
  border-top: 0 !important;
  border-bottom: 0 !important;
}
#secWorks .sec-head::after {
  border: 0 !important;
  background: none !important;
  width: auto !important;
  height: auto !important;
}

/* 修正：编号伪元素尺寸——上一版写 width:auto 被 flex 容器撑满了（1114x195） */
#secWorks .sec-head::after {
  width: 44px !important;
  height: 16px !important;
  line-height: 16px;
  flex: none;
  text-align: right;
  background: none !important;
  border: 0 !important;
}

/* ============================================================
   去掉手风琴预览文字旁边那道金线
   ------------------------------------------------------------
   用户："金线是手风琴预览页文字左边的那个"
   —— 就是我加在 .ov-title::after 上的短金线（收起态在竖排标题下方、
      展开态在标题下由左向右生长）。两处都去掉。
   ============================================================ */
.ov-item:not(.is-open) .ov-title::after,
.ov-item.is-open .ov-title::after {
  content: none !important;
  display: none !important;
  background: none !important;
}
/* 展开态标题下方不再需要留白 */
.ov-item.is-open .ov-title { padding-bottom: 0; }

/* ============================================================
   ① 工具箱：卡片高度统一
   ------------------------------------------------------------
   用户："创作工具这里你同意一下长宽，我感觉有的扁有的长"
   实测：宽度都是 175px（一致），但**高度 81px / 52px 两档** ——
        核心卡有说明文字所以高，小胶囊没有说明所以矮，看着一个扁一个长。
   改法：给所有卡片一个统一的最小高度，两档高度对齐。
   ============================================================ */
.tool-grid.has-tiers .tool,
.tool-grid.has-tiers .tool--core,
.tool-grid.has-tiers .tool--mini {
  min-height: 62px;
  align-items: center;
}
/* 内容垂直居中，图标与文字在同一中线上 */
.tool-grid.has-tiers .tool {
  display: grid !important;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 10px;
  align-items: center;
}
.tool-grid.has-tiers .tool .tool-icon { grid-row: 1 / span 2; margin: 0 !important; }
.tool-grid.has-tiers .tool .tool-name { align-self: end; }
.tool-grid.has-tiers .tool .tool-note { align-self: start; }
/* 没有说明文字的胶囊：名字垂直居中 */
.tool-grid.has-tiers .tool--mini:not(:has(.tool-note)) .tool-name { align-self: center; }

/* ============================================================
   ③ 美观细节：悬停质感 + 层次
   ------------------------------------------------------------ */
/* 工具箱卡片：悬停时轻微上浮 + 金色发丝扫过（和手风琴手法一致） */
.tool-grid.has-tiers .tool {
  position: relative;
  overflow: hidden;
  transition: transform 0.34s cubic-bezier(0.22,0.61,0.36,1),
              border-color 0.34s var(--ease), box-shadow 0.4s var(--ease),
              background 0.34s var(--ease);
}
.tool-grid.has-tiers .tool::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent-hi), transparent);
  transform: scaleX(0);
  transform-origin: left center;
  opacity: 0;
  transition: transform 0.5s cubic-bezier(0.22,0.61,0.36,1), opacity 0.3s var(--ease);
  pointer-events: none;
}
.tool-grid.has-tiers .tool:hover {
  transform: translateY(-2px);
  border-color: rgba(207, 169, 95, 0.42);
  background: rgba(207, 169, 95, 0.045);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.4), 0 0 22px rgba(207, 169, 95, 0.1);
}
.tool-grid.has-tiers .tool:hover::before { transform: scaleX(1); opacity: 1; }

/* 分区小标题（stills-label / part-label）：字距与颜色统一到一套 */
.stills-label, .part-label {
  letter-spacing: 0.22em !important;
  color: var(--jade-text) !important;
  opacity: 0.9;
}

/* 静帧图注：悬停时轻微右移，暗示可点 */
.still { transition: transform 0.3s var(--ease); }
.still:hover { transform: translateY(-2px); }

/* 网格节奏：三维与 UE 场景的间隙统一，视觉密度一致 */
.threed-grid, .visual-grid { gap: clamp(12px, 1.5vw, 18px); }

@media (prefers-reduced-motion: reduce) {
  .tool-grid.has-tiers .tool, .still { transition: none !important; }
  .tool-grid.has-tiers .tool:hover { transform: none; }
}

/* ============================================================
   工具箱：所有卡片统一高度
   ------------------------------------------------------------
   用户：创作工具这里你同意一下长宽，我感觉有的扁有的长
   实测：宽都是 175（一致），高度是 81 / 52 两档 ——
        核心卡有说明文字所以是双行，小胶囊只有单行。
   改法：网格行固定 66px + 卡片 height:100%，全部拉平。
        卡片内为三行布局（图标跨行 / 名字 / 说明），文字溢出用省略号收住，
        鼠标悬停仍有完整提示（title 属性里带着）。
   ============================================================ */
.tool-grid.has-tiers {
  grid-auto-rows: 66px;
}
.tool-grid.has-tiers .tool,
.tool-grid.has-tiers .tool--core,
.tool-grid.has-tiers .tool--mini {
  height: 100%;
  min-height: 0;
  overflow: hidden;
  display: grid !important;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: auto auto;
  column-gap: 10px;
  row-gap: 1px;
  align-content: center;
  align-items: center;
  padding: 8px 11px !important;
}
.tool-grid.has-tiers .tool .tool-icon {
  grid-row: 1 / span 2;
  margin: 0 !important;
  align-self: center;
}
.tool-grid.has-tiers .tool .tool-name {
  grid-column: 2;
  grid-row: 1;
  align-self: end;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tool-grid.has-tiers .tool .tool-note {
  grid-column: 2;
  grid-row: 2;
  align-self: start;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 没有说明文字的卡片：名字在垂直方向居中 */
.tool-grid.has-tiers .tool--mini:not(:has(.tool-note)) .tool-name { align-self: center; }
/* :has 不支持时（老浏览器）至少不塌 */
@supports not selector(:has(*)) {
  .tool-grid.has-tiers .tool--mini .tool-name { align-self: center; }
}

/* 工具箱：列宽加大，让长名字（Substance 3D Painter / Marvelous Designer）不被截 */
.tool-grid.has-tiers { grid-template-columns: repeat(auto-fill, minmax(264px, 1fr)) !important; }
/* 名字与说明的字号各收半档，给长名字腾空间 */
.tool-grid.has-tiers .tool .tool-name { font-size: 11.5px !important; letter-spacing: -0.005em; }
.tool-grid.has-tiers .tool .tool-note { font-size: 9.5px !important; }
@media (max-width: 1200px) {
  .tool-grid.has-tiers { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)) !important; }
}

/* 工具箱最终尺寸：4 列 x 3 行，卡片统一 66px 高
   （试过 196px / 264px 两档，auto-fill 会跳到 3 列 / 2 列，反而更差；
     回到 168px 档，长名字用字号解决，不再截断） */
.tool-grid.has-tiers { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)) !important; }
.tool-grid.has-tiers .tool .tool-name { font-size: 10.6px !important; letter-spacing: -0.008em; }
.tool-grid.has-tiers .tool .tool-note { font-size: 9px !important; letter-spacing: 0; }
/* 名字允许两行（不再用省略号），因为卡片高度已固定、多余部分裁掉也不影响 */
.tool-grid.has-tiers .tool .tool-name { white-space: normal; line-height: 1.25; max-height: 2.5em; }

/* ============================================================
   工具箱：所有 12 个软件都显示说明文字
   ------------------------------------------------------------
   用户："为什么就3个软件有这种介绍，其他的软件呢"
   查证：data.js 里 **12 个软件全都有 note**，
        是 CSS 第 4177 行 `.tool--mini .tool-note { display: none }`
        把小胶囊的说明关掉了（当时理由："胶囊里不显示说明文字 —— 太长了"）。
   现在卡片已统一成 175x66，说明放得下，全部放开。
   ============================================================ */
.tool-grid.has-tiers .tool--mini .tool-note {
  display: block !important;
  opacity: 1 !important;
  color: rgba(240, 236, 227, 0.52) !important;
}
/* 说明允许两行，行高收紧；超出裁掉（悬停有完整提示） */
.tool-grid.has-tiers .tool .tool-note {
  white-space: normal !important;
  overflow: hidden;
  max-height: 2.6em;
  line-height: 1.3 !important;
}

/* ============================================================
   导航栏静音开关
   ------------------------------------------------------------
   用户："你能弄一个点进去鼠标自动在音乐那点一下，并且不影响hr体验吗"
   · 音乐：用户第一次交互（点/滚/按键/触摸）就会立刻响起 ——
     浏览器不允许"无手势的带声音播放"，这是能做到的最优解。
   · 这个开关给 HR 一个顺手的位置：想安静看就点一下。
   ============================================================ */
.nav-mute {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: 4px;
  padding: 0;
  font: inherit;
  font-size: 13px;
  line-height: 1;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--jade-line);
  border-radius: 50%;
  cursor: pointer;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease),
              background 0.3s var(--ease);
}
.nav-mute:hover { border-color: rgba(207, 169, 95, 0.5); background: rgba(207, 169, 95, 0.1); }
/* 播放中：显示 ♪ */
.nav-mute .nm-off { display: none; }
/* 已静音：显示 ✕，整体转灰 */
.nav-mute.is-muted { color: var(--fg-faint); border-color: var(--jade-line); }
.nav-mute.is-muted .nm-on { display: none; }
.nav-mute.is-muted .nm-off { display: inline; }

@media (max-width: 900px) {
  .nav-mute { width: 26px; height: 26px; font-size: 12px; }
}

/* ============================================================
   首屏间距收紧
   ------------------------------------------------------------
   用户："大标题和下面的空的太大了，你缩小点"
   实测：副标题->信息带 42px、信息带->按钮 34px、按钮->工具箱 58px，
        首屏总高 971px 超过一屏（视口 907px）。
   收紧后节奏均匀（约 20~34px），并让首屏落进一屏。
   ============================================================ */
#sec1 .hero-title { margin-bottom: 14px; }
#sec1 .hero-lead { margin-bottom: 24px; }
#sec1 .hero-band { margin-top: 26px !important; }
#sec1 .hero-actions { margin-top: 22px !important; }
#sec1 .toolkit { margin-top: 34px !important; }
/* 信息带、按钮自己内部也收紧一点 */
#sec1 .hero-band { padding-top: 14px !important; padding-bottom: 14px !important; }
/* 工具箱标题到卡片的距离 */
#sec1 .toolkit .toolkit-head { margin-bottom: 12px !important; }

@media (max-height: 820px) {
  #sec1 .hero-title { margin-bottom: 10px; }
  #sec1 .hero-lead { margin-bottom: 16px; }
  #sec1 .hero-band { margin-top: 18px !important; }
  #sec1 .hero-actions { margin-top: 16px !important; }
  #sec1 .toolkit { margin-top: 24px !important; }
}

/* ============================================================
   首屏：再收一档间距，留出底部呼吸
   ------------------------------------------------------------
   实测收紧后 sec1 高 907px == 视口高，最底"继续往下"贴边。
   目标收到 ~880px，同时节奏更均匀（10 / 20 / 18 / 26）。
   ============================================================ */
#sec1 .hero-title { margin-bottom: 10px !important; }
#sec1 .hero-lead { margin-bottom: 20px !important; }
#sec1 .hero-band { margin-top: 18px !important; }
#sec1 .hero-actions { margin-top: 18px !important; }
#sec1 .toolkit { margin-top: 26px !important; }

/* ============================================================
   主次关系修正：信息带的"值"不该比标题还亮
   ------------------------------------------------------------
   原来 .hb-v 是 rgba(240,236,227,.86) 接近纯白，
   比标题下方的副标题（.hero-lead 用 --fg-dim）还亮 ——
   视觉上"求职意向 UE5 特效师"跳到了标题前面。
   压到 .72，让标题与副标题重新占据第一层级。
   ============================================================ */
#sec1 .hero-band .hb-v { color: rgba(240, 236, 227, 0.72) !important; }
#sec1 .hero-band .hb-k { color: rgba(134, 195, 180, 0.78) !important; }  /* 键用青玉色，与金色值区分 */

/* 工具箱说明文字：9px -> 10px，颜色提一档（暗底上更好读） */
.tool-grid.has-tiers .tool .tool-note {
  font-size: 10px !important;
  color: rgba(240, 236, 227, 0.58) !important;
}

/* ============================================================
   首屏：真正把"大空"收掉
   ------------------------------------------------------------
   用户："大标题和下面的空的太大了，你缩小点"
   根因：.sec-hero 是 min-height:100svh + place-items:center + padding-top:120px，
        内容被垂直居中，压段间距只会被分摊回上下空白 —— 所以看着没变。
   改法：内容贴顶（align-items:start）+ 减小 padding-top。
   ============================================================ */
.sec-hero {
  padding-top: 76px !important;
  padding-bottom: 36px !important;
  align-items: start !important;
  justify-items: center;
}
@media (max-width: 900px) {
  .sec-hero { padding-top: 62px !important; padding-bottom: 26px !important; }
}
@media (max-height: 820px) {
  .sec-hero { padding-top: 56px !important; padding-bottom: 22px !important; }
}

/* ============================================================
   分区标题 -> 内容：统一收掉过大的空
   ------------------------------------------------------------
   用户截图指出："特效作品"标题到下面筛选菜单之间一大条空。
   实测 .sec-head 的 margin-bottom 是 64px。
   （之前只给 #secWorks 收过 64 -> 34，其他分区分歧，这次统一。）
   ============================================================ */
.sec .sec-head { margin-bottom: 34px !important; }
/* 筛选菜单紧跟在标题后，也别加额外上边距 */
.sec .tag-bar { margin-top: 0 !important; }
/* 分区自身的内距略收，长页面滚动更顺 */
.sec { padding-top: clamp(84px, 9vw, 124px) !important; padding-bottom: clamp(64px, 7vw, 96px) !important; }

@media (max-width: 900px) {
  .sec .sec-head { margin-bottom: 24px !important; }
  .sec { padding-top: clamp(64px, 10vw, 88px) !important; padding-bottom: clamp(48px, 8vw, 72px) !important; }
}

/* ============================================================
   美术提升 · 统一视觉语言
   ============================================================ */

/* ---------- ② 文字色：收敛到一套白 + 4 个层级 ----------
   审查发现两套几乎相同的白（236,231,221 / 240,236,227）各做了 6~7 档透明度，
   是肉眼分不出的灰阶噪音。统一成 240,236,227 的 4 档：
     主文 .94 ｜ 次要 .70 ｜ 弱 .52 ｜ 极弱 .34
   注意：金色 / 玉色不动（它们是强调色，不是灰阶）。 */
:root {
  --ink-1: rgba(240, 236, 227, 0.94);   /* 主文：标题、重要值 */
  --ink-2: rgba(240, 236, 227, 0.70);   /* 次要：说明、副标题 */
  --ink-3: rgba(240, 236, 227, 0.52);   /* 弱：图注、元信息 */
  --ink-4: rgba(240, 236, 227, 0.34);   /* 极弱：脚注、页码 */
}

/* 把旧的两套白统一过来（按使用场景分派层级） */
.sec .sec-title, .hero-title { color: var(--ink-1); }
.sec .sec-desc, .still figcaption, .ov-item.is-open .ov-sub { color: var(--ink-2); }
.tool-grid.has-tiers .tool .tool-note, .stills-label, .part-label { color: var(--ink-3); }
#secWorks #ovFootLeft, #secWorks #ovFootRight, .ov-foot { color: var(--ink-4); }

/* ---------- ① 字号：收敛到 7 档阶梯 ----------
   11.5 -> 11（原来的 11px 也是 11，合并）
   12.5 -> 12 / 13.5 -> 13（消除 0.5px 级噪音）
   15.5 -> 15 / 17.5 -> 17
   这样字号种数从 29 降到 ~12，且每档都有明确用途。 */
.sec .sec-desc { font-size: 15px !important; }
.still figcaption { font-size: 12px !important; }
.tool-grid.has-tiers .tool .tool-name { font-size: 11px !important; }
.tag, .tag-bar .tag { font-size: 12px !important; }
.ov-item.is-open .ov-sub { font-size: 13px !important; }
.hero-lead { font-size: clamp(14px, 1.5vw, 17px) !important; }
.eyebrow { font-size: 11px !important; }

/* ---------- ③ 标题行结构统一 ----------
   secWorks 之前被我改成 flex 单栏（标题+说明上下堆叠），
   而其它分区是 grid 两栏（左标题、右说明）—— 结构不一致。
   这里让 secWorks 回到与其它分区一致的**左标题 + 右说明**，
   但保留它更大的衬线标题（它是总览，理应更重）。 */
#secWorks .sec-head {
  display: grid !important;
  grid-template-columns: minmax(0, 1fr) minmax(0, 44ch);
  align-items: end;
  column-gap: clamp(24px, 4vw, 64px);
  border-top: 0 !important;
}
#secWorks .sec-head .eyebrow { order: 0; margin: 0 0 12px; }
#secWorks .sec-head .sec-title { order: 0; margin: 0; }
#secWorks .sec-head .sec-desc {
  order: 0;
  margin: 0 0 6px;
  max-width: none;
  white-space: normal;
  text-align: right;
  align-self: end;
}
#secWorks .sec-head::after { display: none !important; }   /* 去掉绝对定位的编号 */
#secWorks .sec-title::after { margin-top: 14px; }
#secWorks .sec-head { margin-bottom: 34px !important; }

/* 各分区标题行也统一：说明右对齐到底部，与标题基线呼应 */
.sec .sec-head { align-items: end; }
.sec .sec-head .sec-desc { text-align: right; margin-bottom: 6px; }

@media (max-width: 900px) {
  #secWorks .sec-head { grid-template-columns: 1fr !important; }
  #secWorks .sec-head .sec-desc { text-align: left; margin-top: 10px; }
  .sec .sec-head .sec-desc { text-align: left; }
}

/* ============================================================
   ① 分区标题下方的空再收一档
   ------------------------------------------------------------
   用户："任务2还可以再缩短点"
   34px -> 20px（窄屏 16px）。标题行本身已紧凑，这里只收标题与内容的距离。
   ============================================================ */
.sec .sec-head { margin-bottom: 20px !important; }
#secWorks .sec-head { margin-bottom: 20px !important; }
@media (max-width: 900px) {
  .sec .sec-head { margin-bottom: 16px !important; }
  #secWorks .sec-head { margin-bottom: 16px !important; }
}

/* ============================================================
   ② 手风琴改矮
   ------------------------------------------------------------
   用户："手风琴可以矮一点"
   原来 617px —— 在 1000px 高的视口里占了 2/3，偏压。
   收到 ~490px（约 0.49x 视口），既保持面板感又不压迫。
   用 clamp 跟视口联动：矮屏也不会溢出。
   ============================================================ */
.ov-rail {
  height: clamp(420px, 50vh, 520px) !important;
}
@media (max-width: 900px) {
  .ov-rail { height: clamp(340px, 46vh, 420px) !important; }
}
/* 竖排标题的起点跟着面板高度重算，底部留白保持一致 */
.ov-item:not(.is-open) .ov-anim { bottom: clamp(24px, 4vh, 34px); }
/* 展开态内距也略收，矮面板里文字不挤 */
.ov-item.is-open .ov-body { padding: 16px 22px 20px; }
.ov-item.is-open .ov-title { font-size: clamp(21px, 2.2vw, 30px); }

/* 分区标题行：说明列放宽，避免两行折行（44ch 已够放把鼠标停在任意一格…） */
#secWorks .sec-head { grid-template-columns: minmax(0, 1fr) minmax(0, 44ch) !important; }

/* ==========================================================================
   整体高级感升级
   --------------------------------------------------------------------------
   诊断：全站"平"（都是同一个边框盒子）、排版缺光学处理、标题一律居中、
        页面无材质、亮色内容破坏色调、间距节奏均匀。
   下面按这 6 条逐项处理。所有改动只影响视觉，不动结构。
   ========================================================================== */

/* ---------- ① 材质：胶片噪点 + 边缘暗角 ----------
   纯平色块会显得"廉价"，加一层几乎看不见的噪点，质感立刻不同。
   噪点用 SVG feTurbulence 生成（不增加任何图片请求）。 */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9998;
  pointer-events: none;
  opacity: 0.038;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}
/* 暗角：四周轻微压暗，把视线收到中间（电影镜头感） */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9997;
  pointer-events: none;
  background: radial-gradient(120% 90% at 50% 45%,
              transparent 45%, rgba(0, 0, 0, 0.28) 100%);
}
@media (prefers-reduced-motion: reduce) { /* 无动画，无需处理 */ }

/* ---------- ② 排版：光学字距 + 字号阶梯 ----------
   原则：字越大越收紧（-0.02em），字越小越放开（+0.16em）。
   这是印刷排版的基本功，也是"高级感"最直接的来源。 */
.sec .sec-title,
.hero-title {
  letter-spacing: -0.015em !important;
  font-feature-settings: "palt" 1, "kern" 1;   /* 中日文比例字距 + 字偶距 */
}
.hero-title { letter-spacing: -0.028em !important; }

.eyebrow,
.stills-label,
.part-label,
.hero-band .hb-k {
  letter-spacing: 0.2em !important;
  font-feature-settings: "tnum" 1;
}
.sec .sec-desc { letter-spacing: 0.012em; line-height: 1.85; }
.hero-lead { letter-spacing: 0.02em !important; line-height: 1.7; }

/* 正文数字统一等宽，避免跳动 */
.tag, .rp-tip, .ov-no, .hb-v, .ctap-stats {
  font-variant-numeric: tabular-nums;
}

/* ---------- ③ 卡面：分层材质替代扁平边框 ----------
   原来所有卡片都是 `1px solid var(--line)` + 纯色底 —— 就是"平"的来源。
   改成三件事叠加：渐变底（模拟受光）+ 发丝边（1px 但带明暗变化）+ 顶部高光。 */
.vfx-cell,
.still,
.tool-grid.has-tiers .tool,
.ov-item {
  border-color: rgba(240, 236, 227, 0.075) !important;
  background-image: linear-gradient(168deg,
      rgba(255, 245, 214, 0.030) 0%,
      rgba(255, 245, 214, 0.008) 32%,
      rgba(0, 0, 0, 0.10) 100%) !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 245, 214, 0.06),
    0 1px 2px rgba(0, 0, 0, 0.35) !important;
  transition: border-color 0.45s var(--ease), box-shadow 0.5s var(--ease),
              transform 0.45s var(--ease) !important;
}
/* 悬停：受光加强 + 轻微抬起（不要缩放，缩放在栅格里会显得脏） */
.vfx-cell:hover,
.still:hover,
.tool-grid.has-tiers .tool:hover {
  border-color: rgba(207, 169, 95, 0.34) !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 245, 214, 0.12),
    0 10px 30px rgba(0, 0, 0, 0.5),
    0 0 34px rgba(207, 169, 95, 0.07) !important;
}

/* ---------- ④ 分区标题行：编辑排版的"脊线" ----------
   原来标题行一律居中/两栏，缺少秩序。
   加一条左侧金色脊线 + 序号，形成统一的"栏目语言"。 */
.sec .sec-head {
  position: relative;
  padding-left: 18px;
}
.sec .sec-head::before {
  content: "";
  position: absolute;
  left: 0;
  top: 2px;
  bottom: 2px;
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(180deg,
      var(--accent-hi) 0%, var(--accent) 42%, rgba(207, 169, 95, 0.06) 100%);
  opacity: 0.85;
}
/* 标题下方那条金线：收到 48px，更像排版装饰而不是下划线 */
.sec .sec-title::after,
#secWorks .sec-title::after {
  width: 48px !important;
  height: 1px !important;
  margin-top: 16px !important;
  background: linear-gradient(90deg, var(--accent), rgba(207, 169, 95, 0.05)) !important;
}
/* 序号：等宽细体，压在脊线顶端 */
.sec .sec-head .eyebrow::first-letter { color: var(--accent); }

/* 分区之间用一条会淡出的发丝线分隔（替代硬边） */
.sec + .sec::before {
  content: "";
  display: block;
  height: 1px;
  margin: 0 0 clamp(48px, 6vw, 84px);
  background: linear-gradient(90deg,
      transparent, rgba(240, 236, 227, 0.10) 22%,
      rgba(240, 236, 227, 0.10) 78%, transparent);
}

/* ---------- ⑤ 色调收敛：把跳出黑金体系的亮色内容拉回来 ----------
   游戏墙是彩色截图（红蓝），在整站黑金里非常跳。
   轻微降饱和 + 压暗，保留可辨识度，但服从整体色调。 */
#ctaPlayWall,
.cta-col.cta-play img,
.ov-play img,
.pf-mini-frame img,
.opf-mini-frame img {
  filter: saturate(0.72) brightness(0.9) contrast(1.03);
  transition: filter 0.6s var(--ease);
}
#ctaPlayWall:hover,
.cta-col.cta-play:hover img {
  filter: saturate(0.95) brightness(0.96) contrast(1.02);
}
/* 二维码的白底太扎眼：压到接近暗调，只用很轻的降级 */
.cta-col img[src*="qr"],
.ov-qr img {
  filter: brightness(0.94) saturate(0.9);
}

/* ---------- ⑥ 节奏：内距分级，让疏密有变化 ----------
   原来各分区内距基本一致，读起来"平"。
   首屏、总览给更多空间（它们是"高潮"），中间分区收紧（"推进"）。 */
#sec1   { padding-top: clamp(64px, 7vw, 96px) !important; }
#secWorks { padding-top: clamp(96px, 11vw, 148px) !important; padding-bottom: clamp(64px, 8vw, 104px) !important; }
#sec8   { padding-top: clamp(88px, 10vw, 132px) !important; padding-bottom: clamp(96px, 12vw, 160px) !important; }

/* 细腻一点：卡片圆角统一到 2px 一档（大圆角显廉价，小圆角显精密） */
.vfx-cell, .still img, .tool-grid.has-tiers .tool, .ov-item { border-radius: 3px !important; }
.lightbox .lb-stage img { border-radius: 3px; }

/* ============================================================
   联系区标题行：居中 -> 左对齐（与其它分区统一）
   ------------------------------------------------------------
   其它分区都是"左标题 + 右说明"，只有联系区整体居中；
   加上金色脊线后错位更明显。统一成左对齐，保持编辑排版的秩序。
   ============================================================ */
#sec8 .sec-head {
  text-align: left !important;
  align-items: start !important;
}
#sec8 .sec-head > * { text-align: left !important; margin-left: 0 !important; }
#sec8 .sec-title { text-align: left !important; }
#sec8 .sec-desc {
  text-align: left !important;
  margin-left: 0 !important;
  max-width: 52ch;
}
/* 联系区的脊线保持和其它分区同高 */
#sec8 .sec-head::before { top: 3px; bottom: 3px; }

/* 联系区的两栏内容也统一左起点 */
#sec8 .cta-wrap, #sec8 .contact-grid, #sec8 .wrap { text-align: left; }

/* 工具名字号收到 10.5px —— 11px 时 "Substance 3D Painter" 会折成两行，
   加上说明就是三行，卡片里偏挤。10.5px 刚好单行放下。 */
.tool-grid.has-tiers .tool .tool-name { font-size: 10.5px !important; }

/* ==========================================================================
   滚动驱动效果（CSS animation-timeline）
   --------------------------------------------------------------------------
   用户："鼠标滚轮往下划太单调了"
   全部用浏览器原生的滚动时间线驱动 —— 没有 scroll 事件监听，不会卡。
   老浏览器被 @supports 挡掉，退化为静态，不会出错。
   ========================================================================== */

/* ---------- ⑥ 滚动进度条：加分段刻度（所有浏览器都生效）---------- */
.scroll-progress::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    90deg,
    transparent 0, transparent calc(12.5% - 1px),
    rgba(0, 0, 0, 0.55) calc(12.5% - 1px), rgba(0, 0, 0, 0.55) 12.5%);
  pointer-events: none;
}

@supports (animation-timeline: view()) {

  /* ---------- ① 首屏滚出：缩小 + 淡出 + 模糊 ---------- */
  .hero-inner {
    animation: heroExit linear both;
    animation-timeline: scroll(root);
    animation-range: 0 70vh;
  }
  @keyframes heroExit {
    to {
      opacity: 0;
      transform: scale(0.93) translateY(-26px);
      filter: blur(5px);
    }
  }
  /* 首屏背景视频反向放大，形成纵深 */
  .hero-media, .hero-fill {
    animation: heroMedia linear both;
    animation-timeline: scroll(root);
    animation-range: 0 100vh;
  }
  @keyframes heroMedia {
    to { transform: scale(1.10); opacity: 0.55; }
  }

  /* ---------- ② 媒体"落定"：进入视口时从 1.06 缩到 1 ----------
     注意：只加在**容器**上，避免和图片自身的悬停过渡打架。 */
  .vfx-cell,
  .still,
  .tool-grid.has-tiers .tool,
  .ov-item {
    animation: settle linear both;
    animation-timeline: view();
    animation-range: entry 8% entry 68%;
  }
  @keyframes settle {
    from { opacity: 0; transform: translateY(22px) scale(0.965); }
    to   { opacity: 1; transform: none; }
  }

  /* ---------- ③ 图片擦除显示：clip-path 自下而上揭开 ---------- */
  .vfx-cell > img,
  .vfx-cell > video,
  .still img {
    animation: wipe linear both;
    animation-timeline: view();
    animation-range: entry 12% entry 62%;
  }
  @keyframes wipe {
    from { clip-path: inset(100% 0 0 0); filter: brightness(0.5); }
    to   { clip-path: inset(0 0 0 0);   filter: brightness(1); }
  }

  /* ---------- ④ 栅格错落：同排依次进入 ---------- */
  .vfx-grid > :nth-child(2n),
  .threed-grid > :nth-child(2n),
  .visual-grid > :nth-child(2n),
  .stills > :nth-child(2n) { animation-range: entry 16% entry 76%; }
  .vfx-grid > :nth-child(3n),
  .threed-grid > :nth-child(3n),
  .visual-grid > :nth-child(3n),
  .stills > :nth-child(3n) { animation-range: entry 22% entry 82%; }
  .vfx-grid > :nth-child(4n),
  .threed-grid > :nth-child(4n),
  .visual-grid > :nth-child(4n),
  .stills > :nth-child(4n) { animation-range: entry 28% entry 88%; }

  /* ---------- ⑤ 分区标题视差：轻微上移，制造层间速度差 ---------- */
  .sec .sec-head {
    animation: headDrift linear both;
    animation-timeline: view();
    animation-range: entry 0% exit 30%;
  }
  @keyframes headDrift {
    from { transform: translateY(30px); opacity: 0.35; }
    to   { transform: translateY(-26px); opacity: 1; }
  }

  /* 长页面里的静帧图注也做轻微视差，读起来有层次 */
  .stills-label, .part-label {
    animation: labelDrift linear both;
    animation-timeline: view();
    animation-range: entry 0% exit 40%;
  }
  @keyframes labelDrift {
    from { transform: translateX(-14px); opacity: 0; }
    to   { transform: translateX(0);     opacity: 1; }
  }
}

/* ---------- ⑦ 首页强化 ---------- */

/* 标题入场：从下往上 + 轻微放大，比直接出现有仪式感 */
@keyframes heroTitleIn {
  from { opacity: 0; transform: translateY(26px) scale(0.985); letter-spacing: 0.02em; }
  to   { opacity: 1; transform: none; letter-spacing: -0.028em; }
}
.hero-title { animation: heroTitleIn 1.05s cubic-bezier(0.16, 1, 0.3, 1) both; }

@keyframes heroLeadIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
.hero-lead { animation: heroLeadIn 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.18s both; }

/* 信息带：逐行浮现 */
@keyframes bandIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.hero-band > * { animation: bandIn 0.8s cubic-bezier(0.16, 1, 0.3, 1) both; }
.hero-band > *:nth-child(1) { animation-delay: 0.30s; }
.hero-band > *:nth-child(2) { animation-delay: 0.38s; }
.hero-band > *:nth-child(3) { animation-delay: 0.46s; }
.hero-band > *:nth-child(4) { animation-delay: 0.54s; }

/* 工具箱：卡片依次浮现（14 张也要有顺序感） */
@keyframes toolIn {
  from { opacity: 0; transform: translateY(14px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}
.tool-grid .tool { animation: toolIn 0.7s cubic-bezier(0.16, 1, 0.3, 1) both; }
.tool-grid .tool:nth-child(1)  { animation-delay: 0.46s; }
.tool-grid .tool:nth-child(2)  { animation-delay: 0.50s; }
.tool-grid .tool:nth-child(3)  { animation-delay: 0.54s; }
.tool-grid .tool:nth-child(4)  { animation-delay: 0.58s; }
.tool-grid .tool:nth-child(5)  { animation-delay: 0.62s; }
.tool-grid .tool:nth-child(6)  { animation-delay: 0.66s; }
.tool-grid .tool:nth-child(7)  { animation-delay: 0.70s; }
.tool-grid .tool:nth-child(8)  { animation-delay: 0.74s; }
.tool-grid .tool:nth-child(9)  { animation-delay: 0.78s; }
.tool-grid .tool:nth-child(10) { animation-delay: 0.82s; }
.tool-grid .tool:nth-child(11) { animation-delay: 0.86s; }
.tool-grid .tool:nth-child(12) { animation-delay: 0.90s; }

/* eyebrow 前面那条小横线：入场时向右生长 */
@keyframes ruleGrow {
  from { transform: scaleX(0); opacity: 0; }
  to   { transform: scaleX(1); opacity: 1; }
}
.hero-eyebrow::before,
.eyebrow::before {
  transform-origin: left center;
  animation: ruleGrow 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.10s both;
}

/* "继续往下"提示：呼吸 + 下滑线 */
@keyframes cueBreathe {
  0%, 100% { opacity: 0.42; transform: translateY(0); }
  50%      { opacity: 0.95; transform: translateY(6px); }
}
.hero-scroll, .scroll-cue, .hero-cue {
  animation: cueBreathe 2.6s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}

/* 尊重系统的"减少动效"设置 */
@media (prefers-reduced-motion: reduce) {
  .hero-title, .hero-lead, .hero-band > *, .tool-grid .tool,
  .hero-eyebrow::before, .eyebrow::before,
  .hero-scroll, .scroll-cue, .hero-cue { animation: none !important; }
}

/* ==========================================================================
   修正：滚动视差不能加在"跳转锚点"上
   --------------------------------------------------------------------------
   回归发现 `跳转到渲染竞赛有落点` 偏差 30px（belowNav: -30）。
   原因：.sec-head 是 jumpToSection 的落点锚点，而它自身带了滚动位移，
        getBoundingClientRect() 随滚动变化 -> 落点算歪。
   修法：视差移到子元素；锚点元素只做淡入、不做位移。
   ========================================================================== */
@supports (animation-timeline: view()) {

  /* 取消 .sec-head 自身的滚动视差 */
  .sec .sec-head {
    animation: none !important;
    transform: none !important;
  }
  /* 视差改到子元素（子元素 transform 不影响父元素 border box） */
  .sec .sec-head .sec-title,
  .sec .sec-head .eyebrow {
    animation: headChildDrift linear both;
    animation-timeline: view();
    animation-range: entry 0% exit 26%;
  }
  @keyframes headChildDrift {
    from { transform: translateY(22px); opacity: 0.25; }
    to   { transform: translateY(-14px); opacity: 1; }
  }

  /* 任何"跳转锚点"元素：只淡入，绝不位移 */
  [data-jump-anchor],
  [data-part-anchor],
  [data-jump-anchor] * {
    animation: anchorFade linear both !important;
    animation-timeline: view() !important;
    animation-range: entry 10% entry 60% !important;
  }
  @keyframes anchorFade {
    from { opacity: 0.2; }
    to   { opacity: 1; }
  }
  /* 锚点自身绝不能有 transform（否则 getBoundingClientRect 会漂） */
  [data-jump-anchor],
  [data-part-anchor] {
    transform: none !important;
  }
}

/* ==========================================================================
   手风琴：修复"瞬间弹开" + 悬停动态
   --------------------------------------------------------------------------
   实测 .ov-item 的 transition 里 flex-grow 被覆盖掉了（我上一轮加卡面材质时
   写了一条带 !important 的 transition），导致展开没有过渡、直接弹出。
   这里把 flex-grow 明确加回来，并把展开做得更从容。
   ========================================================================== */
.ov-item {
  transition:
    flex-grow 0.62s cubic-bezier(0.22, 0.61, 0.36, 1),
    border-color 0.4s var(--ease),
    box-shadow 0.5s var(--ease),
    transform 0.5s var(--ease) !important;
}

/* 展开/收起时，栅格里其它格子也跟着"让位"，整体更连贯 */
.ov-item.is-open {
  transition:
    flex-grow 0.62s cubic-bezier(0.22, 0.61, 0.36, 1),
    border-color 0.4s var(--ease),
    box-shadow 0.6s var(--ease),
    transform 0.5s var(--ease) !important;
}

/* ---------- 未展开：悬停动态 ---------- */
/* 封面缓慢推近（比原来的 1.02 明显一些，但不夸张）*/
.ov-item:not(.is-open):hover > img,
.ov-item:not(.is-open):hover > video {
  transform: scale(1.07);
  filter: grayscale(0.15) brightness(0.86) saturate(1.1);
  transition: transform 0.9s cubic-bezier(0.22, 0.61, 0.36, 1),
              filter 0.6s var(--ease) !important;
}
/* 标题：字距拉开 + 上浮一点点 */
.ov-item:not(.is-open):hover .ov-anim {
  transform: translateY(-4px);
  transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
}
/* 序号在悬停时点亮成金 */
.ov-item:not(.is-open):hover .ov-no { color: var(--accent-hi) !important; }

/* ---------- 展开：内容依次浮现（加强版）---------- */
@keyframes ovTitleIn {
  from { opacity: 0; transform: translateY(16px); filter: blur(3px); }
  to   { opacity: 1; transform: none;            filter: blur(0); }
}
@keyframes ovLineGrow {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
.ov-item.is-open .ov-title {
  animation: ovTitleIn 0.62s cubic-bezier(0.16, 1, 0.3, 1) 0.12s both;
}
.ov-item.is-open .ov-no {
  animation: ovTitleIn 0.5s cubic-bezier(0.16, 1, 0.3, 1) 0.06s both;
}
.ov-item.is-open .ov-sub {
  animation: ovTitleIn 0.55s cubic-bezier(0.16, 1, 0.3, 1) 0.20s both;
}
/* 展开格底部一道金光扫过，收口 */
.ov-item.is-open .ov-body::after {
  content: "";
  display: block;
  width: 64px;
  height: 1px;
  margin-top: 14px;
  border-radius: 1px;
  background: linear-gradient(90deg, var(--accent), transparent);
  transform-origin: left center;
  animation: ovLineGrow 0.7s cubic-bezier(0.22, 0.61, 0.36, 1) 0.30s both;
}

/* ---------- 预览视频：悬停时淡入（原来是硬切）---------- */
.ov-item > video {
  opacity: 0;
  transition: opacity 0.55s var(--ease), transform 0.9s cubic-bezier(0.22, 0.61, 0.36, 1),
              filter 0.6s var(--ease) !important;
}
.ov-item > video.is-ready { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .ov-item, .ov-item > video, .ov-item:not(.is-open):hover .ov-anim { transition: none !important; }
  .ov-item.is-open .ov-title, .ov-item.is-open .ov-no,
  .ov-item.is-open .ov-sub, .ov-item.is-open .ov-body::after { animation: none !important; }
}

/* ==========================================================================
   时间线节选：可点击跳转的静帧
   --------------------------------------------------------------------------
   有 `at` 的静帧右上角显示时间点（如 00:58），悬停时提示"点击跳转到该时间"。
   ========================================================================== */
.still--jump { position: relative; cursor: pointer; }
.still--jump .still-at {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 3;
  padding: 2px 7px;
  font-family: var(--font-en);
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
  color: #0b0a09;
  background: linear-gradient(160deg, var(--accent-hi), var(--accent));
  border-radius: 999px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.still--jump:hover .still-at {
  transform: scale(1.08);
  box-shadow: 0 2px 14px rgba(207, 169, 95, 0.5);
}
/* 悬停时图片上浮 + 金色描边，暗示"可点" */
.still--jump:hover img {
  border-color: rgba(207, 169, 95, 0.55) !important;
  filter: brightness(1.06);
}
/* 底部提示条：悬停时出现 */
.still--jump::after {
  content: "跳到 " attr(aria-label);
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  padding: 5px 8px;
  font-size: 10.5px;
  letter-spacing: 0.04em;
  color: rgba(240, 236, 227, 0.9);
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.82));
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
  pointer-events: none;
}
.still--jump:hover::after { opacity: 1; transform: none; }

/* ==========================================================================
   ① 全屏视频层里的时间线跳转按钮
   ========================================================================== */
.vl-mark {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  margin: 0 8px 8px 0;
  padding: 6px 12px;
  font: inherit;
  color: rgba(240, 236, 227, 0.82);
  background: rgba(240, 236, 227, 0.05);
  border: 1px solid var(--jade-line);
  border-radius: 999px;
  cursor: pointer;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease),
              background 0.3s var(--ease), transform 0.3s var(--ease);
}
.vl-mark:hover {
  color: #fff;
  border-color: rgba(207, 169, 95, 0.6);
  background: rgba(207, 169, 95, 0.14);
  transform: translateY(-1px);
}
.vl-mark-at {
  font-family: var(--font-en);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: var(--accent-hi);
  letter-spacing: 0.04em;
}
.vl-mark-cap { font-size: 12px; letter-spacing: 0.02em; }

/* ==========================================================================
   ② 首页布局上移 -> 加回上留白，让整块更居中
   --------------------------------------------------------------------------
   用户："我感觉你首页布局有点上"
   上一轮为了收掉大空把 padding-top 压到 76px，结果内容偏上、下面空。
   改为按视口高度给留白，视觉重心回到中间偏上（视线落点更舒服）。
   ========================================================================== */
.sec-hero {
  padding-top: clamp(104px, 13vh, 176px) !important;
  padding-bottom: clamp(48px, 7vh, 92px) !important;
}
@media (max-height: 820px) {
  .sec-hero {
    padding-top: clamp(72px, 10vh, 110px) !important;
    padding-bottom: clamp(32px, 5vh, 56px) !important;
  }
}
/* 首屏内部节奏也松半档，避免挤在上半屏 */
#sec1 .hero-lead { margin-bottom: 26px !important; }
#sec1 .hero-band { margin-top: 24px !important; }
#sec1 .hero-actions { margin-top: 24px !important; }
#sec1 .toolkit { margin-top: 34px !important; }

/* ==========================================================================
   ① 全屏层的时间线按钮：让容器显形
   --------------------------------------------------------------------------
   实测 #vlightboxVersions 是 display:none —— 按钮渲染了却 0x0 看不见。
   ========================================================================== */
#vlightboxVersions.has-marks {
  display: flex !important;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0;
  margin-top: 14px;
  max-width: min(92vw, 900px);
}

/* ==========================================================================
   ② 图标 1:1
   --------------------------------------------------------------------------
   实测底托是 34x30（1.133），不是正方形 —— 图标源文件本身都是 1:1，
   是 CSS 给的尺寸不方。这里统一成正方形并放大。
   ========================================================================== */
.tool-grid.has-tiers .tool .tool-icon {
  width: 42px !important;
  height: 42px !important;
  border-radius: 11px !important;
}
.tool-grid.has-tiers .tool .tool-icon svg,
.tool-grid.has-tiers .tool .tool-icon img,
.tool-grid.has-tiers .tool .tool-icon.has-img img,
.tool-grid.has-tiers .tool .tool-mask {
  width: 38px !important;
  height: 38px !important;
  object-fit: contain !important;
}
.tool-grid.has-tiers .tool .tool-mono {
  width: 38px !important;
  height: 38px !important;
  display: grid !important;
  place-items: center;
  font-size: 19px !important;
}

/* ==========================================================================
   ③ 工具箱放大：4 列 -> 3 列，卡片更高，文字更大
   --------------------------------------------------------------------------
   用户："首页还是感觉太空了，把工具放大点"
   ========================================================================== */
.tool-grid.has-tiers {
  grid-template-columns: repeat(auto-fill, minmax(258px, 1fr)) !important;
  grid-auto-rows: 96px !important;
  gap: 10px !important;
}
.tool-grid.has-tiers .tool,
.tool-grid.has-tiers .tool--core,
.tool-grid.has-tiers .tool--mini {
  padding: 12px 16px !important;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 14px !important;
}
.tool-grid.has-tiers .tool .tool-name {
  font-size: 14px !important;
  letter-spacing: 0 !important;
  line-height: 1.3 !important;
  max-height: none !important;
  white-space: normal !important;
}
.tool-grid.has-tiers .tool .tool-note {
  font-size: 11.5px !important;
  color: rgba(240, 236, 227, 0.6) !important;
  line-height: 1.35 !important;
  max-height: 2.7em !important;
}
/* 工具箱标题也跟着大一档 */
#sec1 .toolkit .toolkit-head,
#sec1 .toolkit > p:first-child { font-size: 12.5px; letter-spacing: 0.2em; }

@media (max-width: 1100px) {
  .tool-grid.has-tiers { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)) !important;
                         grid-auto-rows: 86px !important; }
  .tool-grid.has-tiers .tool .tool-name { font-size: 12.5px !important; }
}
@media (max-width: 700px) {
  .tool-grid.has-tiers { grid-template-columns: 1fr 1fr !important; grid-auto-rows: 84px !important; }
  .tool-grid.has-tiers .tool .tool-icon { width: 36px !important; height: 36px !important; }
  .tool-grid.has-tiers .tool .tool-icon svg,
  .tool-grid.has-tiers .tool .tool-icon img,
  .tool-grid.has-tiers .tool-mask { width: 32px !important; height: 32px !important; }
}

/* 工具箱列宽修正：258px 在 900px 容器里只排到 2 列（6 行太高）。
   改 240px -> 3 列 x 4 行，卡片 250x96（比原来 175x66 大 60%）。 */
.tool-grid.has-tiers {
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)) !important;
}

/* 工具箱改**显式 3 列**（auto-fill 会随容器宽跳列数，不可预测）
   3 列 x 4 行，卡片约 250x92 —— 比原来 175x66 明显大一圈，填掉首页的空。 */
.tool-grid.has-tiers {
  grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  grid-auto-rows: 92px !important;
  gap: 10px !important;
}
@media (max-width: 900px) {
  .tool-grid.has-tiers { grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
                         grid-auto-rows: 84px !important; }
}
@media (max-width: 560px) {
  .tool-grid.has-tiers { grid-template-columns: 1fr !important; grid-auto-rows: 80px !important; }
}

/* 继续往下提示：原为绝对定位在首屏底部，工具箱放大后压到了卡片上。
   改成跟随流式排版，排在工具箱下方。 */
.scroll-hint {
  position: static !important;
  margin: 30px auto 0 !important;
  left: auto !important;
  right: auto !important;
  bottom: auto !important;
  transform: none !important;
  display: flex !important;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

/* ==========================================================================
   ③ 全屏层跳转按钮：从视频上方挪到下方
   --------------------------------------------------------------------------
   用户："游戏全屏跳转你可以改成下面"
   .vl-stage 里的顺序是：版本容器 -> video -> caption。
   我的跳转按钮放在版本容器里，所以显示在视频上方。
   这里用 flex order 把它排到视频下面（只对带 has-marks 的生效，
   不影响"版本切换"原本的位置）。
   ========================================================================== */
.vl-stage { display: flex; flex-direction: column; }
.vl-stage #vlightboxVideo { order: 1; }
.vl-stage #vlightboxVersions.has-marks { order: 2; }
.vl-stage .vl-caption { order: 3; }

/* ==========================================================================
   ② 跳转按钮排成一排（原来会折成两排）
   --------------------------------------------------------------------------
   用户："蘑菇你跳转改成一排，现在是两排"
   ========================================================================== */
.vl-stage #vlightboxVersions.has-marks {
  flex-wrap: nowrap !important;
  justify-content: center;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.vl-stage #vlightboxVersions.has-marks::-webkit-scrollbar { display: none; }
.vl-stage #vlightboxVersions.has-marks .vl-mark {
  flex: 0 0 auto;
  margin: 0 6px 0 0;
}
/* 详情层里的节选按钮也排成一排（蘑菇那两组） */
.dt-cuts, .dt-cut-row, [class*="dt-cuts"] {
  flex-wrap: nowrap !important;
  overflow-x: auto;
  scrollbar-width: none;
}
.dt-cuts::-webkit-scrollbar, [class*="dt-cuts"]::-webkit-scrollbar { display: none; }

/* ==========================================================================
   ① 详情层"节选"：分组左右并排
   --------------------------------------------------------------------------
   用户："你节选这里把晚上改到白天的右边"
   实测 .dt-cuts-grid 是 grid，两组（白天/晚上）上下堆叠。
   用 auto-fit：两组时并排；只有一组时自动铺满（不影响其它条目）。
   ========================================================================== */
.dt-cuts-grid {
  display: grid !important;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)) !important;
  gap: clamp(16px, 2.2vw, 32px) !important;
  align-items: start;
}
.dt-cuts-grid > * { min-width: 0; }

/* ==========================================================================
   ② 全屏层跳转按钮：居中
   --------------------------------------------------------------------------
   实测容器 max-width:900px 但 stage 宽 1480px，
   没有 auto 外边距 -> 贴左（左偏 0 / 右余量 580）。
   ========================================================================== */
.vl-stage #vlightboxVersions.has-marks {
  margin-left: auto !important;
  margin-right: auto !important;
  margin-top: 14px !important;
  width: 100% !important;
  max-width: min(92vw, 900px) !important;
}

/* ==========================================================================
   蘑菇"节选"：白天 / 晚上 左右并排（精确只对"两组"生效）
   --------------------------------------------------------------------------
   用户："你节选这里把晚上改到白天的右边"
   结构是扁平的：[分组标签][节选][分组标签][节选]，且标签占满整行。
   用 :has() 精确匹配"两组"的形状，只改这类；单组条目（大广赛等）不受影响。
   ========================================================================== */
.dt-cuts-grid:has(> .dt-cuts-group + .dt-cut + .dt-cuts-group) {
  grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  column-gap: clamp(18px, 2.4vw, 36px) !important;
  row-gap: 10px !important;
}
/* 只在这一形态下，让分组标签不再占整行（各占一列） */
.dt-cuts-grid:has(> .dt-cuts-group + .dt-cut + .dt-cuts-group) > .dt-cuts-group {
  grid-column: auto !important;
}
/* 两组各自的节选也各占一列 */
.dt-cuts-grid:has(> .dt-cuts-group + .dt-cut + .dt-cuts-group) > .dt-cut {
  grid-column: auto !important;
}

/* 蘑菇两组：改用【列优先】排列
   grid-auto-flow: row 会排成 [白天标签|白天图] / [晚上标签|晚上图]，
   不是要的效果。改成 column + 两行固定，就得到：
     第1列 = 白天（标签 + 图）
     第2列 = 晚上（标签 + 图）   ← 正是晚上在白天的右边 */
.dt-cuts-grid:has(> .dt-cuts-group + .dt-cut + .dt-cuts-group) {
  grid-auto-flow: column !important;
  grid-template-rows: auto auto !important;
  grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
}

/* 蘑菇两组并排后，每列 682px 把节选图也撑大了（用户：太大了）。
   保持左右并排，但把节选卡片限回原来的尺寸（约 320px）。 */
.dt-cuts-grid:has(> .dt-cuts-group + .dt-cut + .dt-cuts-group) > .dt-cut {
  max-width: 320px !important;
  width: 100% !important;
}
.dt-cuts-grid:has(> .dt-cuts-group + .dt-cut + .dt-cuts-group) > .dt-cut img {
  width: 100% !important;
  height: auto !important;
}

/* ==========================================================================
   手机端修复（放在文件最后 —— 必须晚于所有断点与 !important 规则）
   --------------------------------------------------------------------------
   问题：作品总览在手机上说明文字一个字一行、手风琴卡片消失。
   根因：后面追加的 `grid-template-columns: 1fr 44ch !important`
        覆盖了手机端"改单列"的媒体查询，44ch 的第二列把第一列挤没了。
   ========================================================================== */
@media (max-width: 900px) {

  /* --- 分区标题行：一律单列，说明左对齐 --- */
  .sec .sec-head,
  #secWorks .sec-head {
    display: flex !important;
    flex-direction: column !important;
    align-items: flex-start !important;
    grid-template-columns: none !important;
    gap: 0 !important;
  }
  .sec .sec-head .sec-title,
  #secWorks .sec-head .sec-title {
    order: 1;
    font-size: clamp(30px, 8.5vw, 44px) !important;
    text-align: left !important;
  }
  .sec .sec-head .sec-desc,
  #secWorks .sec-head .sec-desc {
    order: 2;
    margin: 12px 0 0 !important;
    max-width: none !important;
    width: 100% !important;
    white-space: normal !important;
    text-align: left !important;
  }
  .sec .sec-head .eyebrow,
  #secWorks .sec-head .eyebrow { order: 0; margin-bottom: 10px !important; }

  /* --- 手风琴：手机上是纵向列表，容器必须让它自然撑开 --- */
  .ov-rail {
    height: auto !important;
    max-height: none !important;
  }
  .ov-item:not(.is-open) { height: 96px !important; }
  .ov-item.is-open { height: 300px !important; }
  /* 竖排标题在手机上不适用（横过来更易读） */
  .ov-item:not(.is-open) .ov-title {
    writing-mode: horizontal-tb !important;
    letter-spacing: 0.02em !important;
    font-size: 15px !important;
  }
  .ov-item:not(.is-open) .ov-body {
    position: static !important;
    display: flex !important;
    align-items: center;
    gap: 12px;
  }
  .ov-item:not(.is-open) .ov-anim { position: static !important; transform: none !important; }

  /* --- 触屏点击目标：导航静音键、选歌键放大到 44px 以上 --- */
  .nav-mute { width: 40px !important; height: 40px !important; font-size: 16px !important; }
  .rp-list-toggle { min-height: 40px !important; padding: 10px 16px !important; }
  .rp-btn { min-width: 64px; min-height: 64px; }

  /* --- 全屏跳转胶囊：允许横向滚动，别挤成两行 --- */
  .vl-stage #vlightboxVersions.has-marks { justify-content: flex-start !important; }
  .vl-mark { min-height: 38px; }
}

@media (max-width: 560px) {
  /* 更窄的屏：工具箱单列、证书单列 */
  .tool-grid.has-tiers { grid-template-columns: 1fr !important; grid-auto-rows: 78px !important; }
  .stills--certs { grid-template-columns: 1fr !important; }
}

/* 手机端收尾：
   ① 那条金色竖标是竖排标题用的（在标题上方），横排后跑到卡片中间，隐藏它
   ② 音乐播放器固定左下角会压住卡片，手机上缩小并降低存在感
   ③ 手风琴卡片加左右内距，标题与序号不再贴边 */
@media (max-width: 900px) {
  .ov-item:not(.is-open) .ov-anim::before { display: none !important; }
  .ov-item:not(.is-open) .ov-body { padding: 0 16px !important; }
  .ov-item:not(.is-open) .ov-no { margin-right: 12px; }
  .record-player { transform: scale(0.82); transform-origin: left bottom; }
  .record-player .rp-list { max-height: 40vh; }
}

/* ==========================================================================
   手机端优化（文件末尾 —— 必须晚于所有断点与 !important，否则会被覆盖）
   ========================================================================== */
@media (max-width: 900px) {

  /* ---------- ① 首屏顶部让开导航栏 ----------
     实测 eyebrow top=64、navBottom=73 —— 被压住 9px。
     导航高约 73，给 96 的留白才真正让开。 */
  .sec-hero {
    padding-top: 96px !important;
    padding-bottom: 44px !important;
  }
  #sec1 .hero-title { font-size: clamp(30px, 9vw, 44px) !important; margin-bottom: 10px !important; }
  #sec1 .hero-lead { font-size: 14px !important; line-height: 1.6 !important; margin-bottom: 20px !important; }
  /* 信息带：手机竖排，键值上下排更省宽度 */
  #sec1 .hero-band {
    grid-template-columns: 1fr !important;
    gap: 12px !important;
    margin-top: 18px !important;
    padding: 12px 2px !important;
  }
  #sec1 .hero-actions { margin-top: 18px !important; }
  #sec1 .toolkit { margin-top: 26px !important; }

  /* ---------- ② 工具箱：单列 -> 两列，卡片压扁 ----------
     单列时 gridH=1046px；两列约 470px，省一半滚动。 */
  .tool-grid.has-tiers {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    grid-auto-rows: 72px !important;
    gap: 8px !important;
  }
  .tool-grid.has-tiers .tool,
  .tool-grid.has-tiers .tool--core,
  .tool-grid.has-tiers .tool--mini {
    padding: 8px 10px !important;
    column-gap: 9px !important;
  }
  .tool-grid.has-tiers .tool .tool-icon {
    width: 34px !important; height: 34px !important; border-radius: 9px !important;
  }
  .tool-grid.has-tiers .tool .tool-icon svg,
  .tool-grid.has-tiers .tool .tool-icon img,
  .tool-grid.has-tiers .tool .tool-icon.has-img img,
  .tool-grid.has-tiers .tool .tool-mask { width: 30px !important; height: 30px !important; }
  .tool-grid.has-tiers .tool .tool-mono { width: 30px !important; height: 30px !important; font-size: 15px !important; }
  .tool-grid.has-tiers .tool .tool-name { font-size: 11.5px !important; line-height: 1.25 !important; }
  .tool-grid.has-tiers .tool .tool-note { font-size: 9.5px !important; line-height: 1.25 !important; max-height: 2.6em !important; }

  /* ---------- ③ 音乐播放器：手机上缩到 0.66 ---------- */
  .record-player { transform: scale(0.66) !important; transform-origin: left bottom !important; }
  .record-player .rp-tip { font-size: 10px !important; }
  .record-player .rp-list { max-height: 34vh !important; }

  /* ---------- ④ 各分区内距：手机收紧 ---------- */
  .sec { padding-top: clamp(56px, 9vw, 76px) !important; padding-bottom: clamp(44px, 7vw, 64px) !important; }
  #secWorks { padding-top: clamp(64px, 9vw, 84px) !important; }
  #sec8 { padding-top: clamp(60px, 9vw, 80px) !important; padding-bottom: clamp(64px, 10vw, 96px) !important; }

  /* ---------- 网格间隙收紧 ---------- */
  .vfx-grid, .threed-grid, .visual-grid, .stills { gap: 10px !important; }
  .stills--process { grid-template-columns: 1fr !important; }

  /* ---------- 全屏视频层：手机上按钮可横滑 ---------- */
  .vl-stage { max-width: 96vw !important; }
  .vl-stage #vlightboxVersions.has-marks {
    max-width: 96vw !important;
    justify-content: flex-start !important;
    padding: 0 4px 4px !important;
  }
  .vl-mark { padding: 8px 12px !important; min-height: 38px; }
  .vl-close { width: 40px !important; height: 40px !important; font-size: 22px !important; top: 10px; right: 10px; }

  /* ---------- 详情层（作品详情）手机上铺满 ---------- */
  .dt-cuts-grid { grid-template-columns: 1fr !important; }
  .detail .dt-body, .detail .dt-inner { padding: 16px !important; }
}

/* 更窄的屏（小屏手机） */
@media (max-width: 420px) {
  .tool-grid.has-tiers { grid-auto-rows: 76px !important; }
  #sec1 .hero-title { font-size: clamp(26px, 9.5vw, 38px) !important; }
}

/* 手机端首屏顶部被压住的真正原因：
   .sec-hero 是 display:grid + place-items:center。
   当内容(1048px)比视口(751px)高时，居中会让内容【向上溢出】，
   把 padding-top 顶掉 —— 所以 eyebrow 一直在 64px、被导航栏压住。
   place-items 是简写，必须用同样晚的位置显式覆盖 align-items/justify-items。 */
@media (max-width: 900px) {
  .sec-hero {
    place-items: start center !important;
    align-items: start !important;
    align-content: start !important;
    justify-items: center !important;
    padding-top: 92px !important;
  }
}
@media (max-height: 820px) {
  .sec-hero {
    place-items: start center !important;
    align-items: start !important;
    align-content: start !important;
    padding-top: 88px !important;
  }
}

/* 手机端：直接给首屏内容容器加上内距 —— 不依赖 .sec-hero 的 padding
   （实测 sec-hero 的 padding-top 被 grid 居中/其它规则吃掉，改了不生效）。
   加在内层容器上一定能推开。 */
@media (max-width: 900px) {
  #sec1 .hero-inner { padding-top: 40px !important; }
}

/* 手机端：右下角三个浮动元素阶梯排列，消除重叠
   实测(483x751)：
     #backToWorks  bottom 14  高40  -> 占 14~54
     .race-float   bottom 28  高41  -> 占 28~69   ← 和返回按钮重叠 92x26px
     .cta-float    bottom 104 高41  -> 占 104~145
   改成分层：返回按钮 14 / race 66 / cta 120，互不接触。 */
@media (max-width: 900px) {
  #backToWorks { right: 14px !important; bottom: 14px !important; }
  .race-float {
    right: 14px !important;
    bottom: calc(66px + env(safe-area-inset-bottom, 0px)) !important;
    left: auto !important;
    top: auto !important;
  }
  .cta-float {
    right: 14px !important;
    bottom: calc(120px + env(safe-area-inset-bottom, 0px)) !important;
    left: auto !important;
    top: auto !important;
  }
  /* 手机上这两个组缩小一点，别占太多横向空间 */
  .cta-float, .race-float { transform: scale(0.9); transform-origin: right bottom; }
  .cta-float a, .cta-float button, .race-float a, .race-float button {
    padding: 8px 12px !important; font-size: 12px !important;
  }
}

/* ==========================================================================
   菜单打开时：隐藏所有浮动交互层
   --------------------------------------------------------------------------
   用户："打开菜单的时候有音乐什么的交互界面挡住了"
   菜单打开时 body 会加 .menu-open（setupMobileMenu），据此全部隐藏，
   避免音乐播放器 / 浮动按钮压在菜单条目上。
   ========================================================================== */
body.menu-open .record-player,
body.menu-open .cta-float,
body.menu-open .race-float,
body.menu-open #backToWorks,
body.menu-open .scroll-hint {
  display: none !important;
  pointer-events: none !important;
}
/* 菜单本身压在最上层，保证条目可点 */
body.menu-open .mobile-menu,
#mobileMenu.is-open {
  z-index: 200 !important;
}

/* ==========================================================================
   手机端菜单：让 ✕ 关闭按钮露出来
   --------------------------------------------------------------------------
   实测菜单打开时 nav z-index=60 / menu=200，
   汉堡位置的最顶层元素是 .mobile-menu —— ✕ 被菜单盖住，看起来"没有退出按钮"。
   修：菜单打开时把导航栏提到最上层（高于菜单）。
   ========================================================================== */
body.menu-open #nav,
body.menu-open nav#nav {
  z-index: 300 !important;
  position: fixed !important;
  top: 0; left: 0; right: 0;
}
/* 菜单本身留出顶部空间，避免第一项被导航栏压住 */
body.menu-open .mobile-menu,
#mobileMenu.is-open {
  padding-top: 88px !important;
  z-index: 200 !important;
}
/* 关闭按钮再明确一点：放大点击区域并提亮 */
body.menu-open .hamburger,
.hamburger.is-open {
  z-index: 310 !important;
  position: relative;
  width: 44px !important;
  height: 44px !important;
}
body.menu-open .hamburger span,
.hamburger.is-open span {
  background: var(--accent-hi) !important;
  height: 2px !important;
  border-radius: 2px;
}

/* ==========================================================================
   联系区：加了两行自我评价后，左列变高把二维码挤下去、右列显空
   --------------------------------------------------------------------------
   实测 .cta-facts 从 ~215px 涨到 320px，左列比右列高 -> 右边一大块空。
   收紧左列纵向节奏：行内距减小 + 二维码行上边距减小。
   ========================================================================== */
.cta-split { align-items: start; }

/* 信息行：上下内距各收 4~5px（5 行共省约 40~50px） */
.cta-facts > * {
  padding-top: 8px !important;
  padding-bottom: 8px !important;
}
.cta-facts { row-gap: 0 !important; }

/* 二维码行：贴近信息卡，别留一大截空隙 */
.qr-row {
  margin-top: 14px !important;
  gap: 16px !important;
}
/* 二维码卡片的高度压一档（仍保证可扫：图片高度不低于 190px） */
.qr-row > * { min-height: 0 !important; }
.qr-row img { max-height: 218px !important; width: auto !important; }

/* 右列（游戏墙）保持自然高度，不再被拉伸出空白 */
.cta-split > :nth-child(2) { align-self: start; }

@media (max-width: 900px) {
  /* 手机上单列堆叠，不需要收紧 */
  .cta-facts > * { padding-top: 10px !important; padding-bottom: 10px !important; }
  .qr-row { margin-top: 18px !important; }
  .qr-row img { max-height: none !important; }
}

/* ==========================================================================
   联系区右栏动作组：B站主页 / 回看作品 / 下载简历
   --------------------------------------------------------------------------
   用户："这里还有一个空，你把b站主页回看作品放这里，然后再加一个下载简历"
   放在游戏墙下方，填掉右栏底部原本的空白。
   ========================================================================== */
.ctap-actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-top: clamp(16px, 2vw, 24px);
}
.ctap-act {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 12px 14px;
  text-decoration: none;
  border: 1px solid rgba(240, 236, 227, 0.12);
  border-radius: 4px;
  background-image: linear-gradient(168deg,
      rgba(255, 245, 214, 0.030), rgba(0, 0, 0, 0.10));
  transition: border-color .35s var(--ease), background .35s var(--ease),
              transform .35s var(--ease), box-shadow .4s var(--ease);
}
.ctap-act:hover {
  border-color: rgba(207, 169, 95, 0.5);
  transform: translateY(-2px);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.42), 0 0 22px rgba(207, 169, 95, 0.10);
}
.ctap-act-k {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--fg);
  letter-spacing: 0.02em;
}
.ctap-act-n {
  font-size: 11px;
  color: rgba(240, 236, 227, 0.5);
  letter-spacing: 0.02em;
}
/* 主按钮（下载简历）：金色 */
.ctap-act--primary {
  border-color: rgba(207, 169, 95, 0.42);
  background-image: linear-gradient(168deg,
      rgba(207, 169, 95, 0.14), rgba(207, 169, 95, 0.03));
}
.ctap-act--primary .ctap-act-k { color: var(--accent-hi); }
.ctap-act--primary:hover { border-color: var(--accent); }

/* 浮动动作组被隐藏时（联系区可见） */
.cta-float.is-hidden {
  opacity: 0 !important;
  pointer-events: none !important;
  transform: translateY(8px);
}

@media (max-width: 900px) {
  .ctap-actions { grid-template-columns: 1fr; gap: 8px; }
  .ctap-act { flex-direction: row; align-items: baseline; gap: 10px; padding: 13px 14px; }
}

/* ==========================================================================
   二维码：点击放大
   --------------------------------------------------------------------------
   用户："qq微信我感觉可以加一个放大的，因为太小可能扫不到"
   点二维码 -> 进全屏放大层（复用看图 lightbox），扫码更稳。
   ========================================================================== */
.qr--zoom { cursor: zoom-in; }
.qr--zoom .qr-slot {
  transition: border-color .35s var(--ease), box-shadow .4s var(--ease),
              transform .35s var(--ease);
}
.qr--zoom:hover .qr-slot {
  border-color: rgba(207, 169, 95, 0.55) !important;
  transform: translateY(-2px);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.45), 0 0 24px rgba(207, 169, 95, 0.12);
}
.qr--zoom:focus-visible .qr-slot { outline: 2px solid var(--accent); outline-offset: 3px; }

/* "点击放大"提示：平时很淡，悬停才明显（不抢二维码本身） */
.qr-zoom-hint {
  display: block;
  margin-top: 6px;
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-align: center;
  color: var(--accent);
  opacity: 0.42;
  transition: opacity .35s var(--ease);
}
.qr--zoom:hover .qr-zoom-hint { opacity: 1; }
@media (max-width: 900px) {
  .qr-zoom-hint { opacity: 0.8; }   /* 触屏没有悬停，直接显示 */
}

/* ==========================================================================
   修手机端菜单 ✕ 只显示一半
   --------------------------------------------------------------------------
   我上次为触屏把 .hamburger 放大到 44x44，但"变 ✕"的位移量仍是按原尺寸调的：
     原: 高34 + padding7  -> 内容高 20px，线间距 7.75px，位移 ±9px 正好中心交叉
     改: 高44 + padding7  -> 内容高 30px，线间距 12.75px，±9px 不够 -> 半个 ✕
   修法：保留 44x44 的点击区域，上下内距加到 12px，让内容区回到 20px。
   ========================================================================== */
@media (max-width: 900px) {
  body.menu-open .hamburger,
  .hamburger.is-open {
    width: 44px !important;
    height: 44px !important;
    padding: 12px 9px !important;      /* 44 - 24 = 20px 内容高，与原尺寸一致 */
    justify-content: space-between !important;
  }
  .hamburger.is-open span:nth-child(1) { transform: translateY(9px) rotate(45deg) !important; }
  .hamburger.is-open span:nth-child(2) { opacity: 0 !important; }
  .hamburger.is-open span:nth-child(3) { transform: translateY(-9px) rotate(-45deg) !important; }
}

/* ==========================================================================
   手机端：首屏不做"滑出模糊"
   --------------------------------------------------------------------------
   .hero-inner 挂着 heroExit（scroll 0->70vh：淡出 + 缩小 + blur(5px)）。
   桌面端首屏≈一屏高，滑过时工具箱早已出画面；
   手机端首屏≈1050px（工具箱在首屏内），滑到工具箱时首屏正糊在中段
   —— 用户反馈"手机往下划到这里有模糊，看不清软件"。
   修法：手机端关掉首屏的淡出/模糊，只留极轻微的位移，保证工具箱清晰。
   ========================================================================== */
@media (max-width: 900px) {
  .hero-inner {
    animation: none !important;
    opacity: 1 !important;
    filter: none !important;
    transform: none !important;
  }
  /* 背景视频的缓慢放大保留（不影响阅读），但别淡得太狠 */
  .hero-media, .hero-fill { opacity: 1 !important; }
}

/* ==========================================================================
   滚动动效加强（用户："你往下划的时候多做点动效"）
   --------------------------------------------------------------------------
   全部基于 animation-timeline（滚动驱动），不挂 JS 滚动监听 -> 不卡顿。
   幅度都克制：位移 8~22px，纯位移 + 透明度，不做翻转/旋转。
   ========================================================================== */
@supports (animation-timeline: view()) {

  /* ---------- ① 分区大标题：字距由紧到松 + 上浮 ---------- */
  .sec .sec-head .sec-title,
  #secWorks .sec-head .sec-title {
    animation: titleIn linear both;
    animation-timeline: view();
    animation-range: entry 5% entry 55%;
  }
  @keyframes titleIn {
    from { opacity: 0.15; letter-spacing: -0.02em; transform: translateY(20px); }
    to   { opacity: 1;    letter-spacing: 0.01em;  transform: none; }
  }

  /* ---------- ② 分区说明：比标题晚一拍 ---------- */
  .sec .sec-head .sec-desc,
  #secWorks .sec-head .sec-desc {
    animation: descIn linear both;
    animation-timeline: view();
    animation-range: entry 18% entry 68%;
  }
  @keyframes descIn {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
  }

  /* ---------- ③ 卡片错峰进入 ---------- */
  .qr, .ctap-act, .ctap-stats, .ps-cell, .sk-group {
    animation: cardIn linear both;
    animation-timeline: view();
    animation-range: entry 10% entry 60%;
  }
  @keyframes cardIn {
    from { opacity: 0; transform: translateY(22px) scale(0.985); }
    to   { opacity: 1; transform: none; }
  }
  /* 逐个小延迟，形成错峰（不依赖 JS） */
  .tool-grid.has-tiers .tool:nth-child(1)  { animation-range: entry 4%  entry 48%; }
  .tool-grid.has-tiers .tool:nth-child(2)  { animation-range: entry 7%  entry 51%; }
  .tool-grid.has-tiers .tool:nth-child(3)  { animation-range: entry 10% entry 54%; }
  .tool-grid.has-tiers .tool:nth-child(4)  { animation-range: entry 13% entry 57%; }
  .tool-grid.has-tiers .tool:nth-child(5)  { animation-range: entry 16% entry 60%; }
  .tool-grid.has-tiers .tool:nth-child(6)  { animation-range: entry 19% entry 63%; }
  .tool-grid.has-tiers .tool:nth-child(7)  { animation-range: entry 22% entry 66%; }
  .tool-grid.has-tiers .tool:nth-child(8)  { animation-range: entry 25% entry 69%; }
  .tool-grid.has-tiers .tool:nth-child(9)  { animation-range: entry 28% entry 72%; }
  .tool-grid.has-tiers .tool:nth-child(10) { animation-range: entry 31% entry 75%; }
  .tool-grid.has-tiers .tool:nth-child(11) { animation-range: entry 34% entry 78%; }
  .tool-grid.has-tiers .tool:nth-child(12) { animation-range: entry 37% entry 81%; }

  /* ---------- ④ 图片轻微视差（比容器慢一点，产生纵深） ---------- */
  .vfx-cell img, .still img, .threed-cell img, .visual-cell img {
    animation: imgDrift linear both;
    animation-timeline: view();
    animation-range: cover 0% cover 100%;
  }
  @keyframes imgDrift {
    from { transform: translateY(-9px) scale(1.03); }
    to   { transform: translateY(9px)  scale(1.03); }
  }

  /* ---------- ⑤ 分区金线：进入展开、离开收拢 ---------- */
  .sec .sec-head::after,
  #secWorks .sec-head::after {
    animation: ruleGrowOut linear both;
    animation-timeline: view();
    animation-range: cover 0% cover 100%;
  }
  @keyframes ruleGrowOut {
    from { transform: scaleX(0.25); opacity: 0.2; }
    35%  { transform: scaleX(1);    opacity: 1; }
    to   { transform: scaleX(1);    opacity: 0.35; }
  }

  /* ---------- ⑥ 已移除 ----------
     本来在分区容器 (.sec-inner/.wrap) 上做入场位移，但它会**移动跳转落点**
     （实测"跳转到渲染竞赛"落点偏 7px），和之前 sec-head 那次是同一个坑：
     跳转锚点链路上不做 transform。这条故意留空，避免以后被再加回来。 */
}

/* 手机上幅度再收小一点，避免和触屏滚动打架 */
@media (max-width: 900px) {
  @supports (animation-timeline: view()) {
    .sec .sec-head .sec-title,
    #secWorks .sec-head .sec-title { animation-range: entry 3% entry 42%; }
    .qr, .ctap-act, .sk-group      { animation-range: entry 6% entry 48%; }
    .vfx-cell img, .still img      { animation: none; }   /* 手机不做图片视差，省性能 */
    /* 分区容器不做位移（会动跳转落点） */
  }
}

/* ==========================================================================
   首屏：加黑色蒙层 + 分区说明的排版优化
   --------------------------------------------------------------------------
   用户："可以在混剪前面叠加一层黑色的，因为看上去有点糊，下掩盖一下"
        "你优化一下文字和文字排版"
   ① 蒙层：混剪是 4K 降到 1080p 的背景层，本身颗粒感偏重，
      压一层渐变黑后文字更清楚、画面也更"沉"。
   ② 排版：说明文字行高放宽、按语义断行（text-wrap: pretty），避免孤字。
   ========================================================================== */
/* ---- 黑色蒙层：中间略透、四周更暗，让标题区最清楚 ---- */
.hero-media::after,
.hero-fill::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  background:
    radial-gradient(120% 92% at 50% 42%,
      rgba(6, 6, 8, 0.30) 0%,
      rgba(6, 6, 8, 0.58) 52%,
      rgba(5, 5, 7, 0.86) 100%),
    linear-gradient(180deg,
      rgba(6, 6, 8, 0.72) 0%,
      rgba(6, 6, 8, 0.34) 26%,
      rgba(6, 6, 8, 0.42) 68%,
      rgba(5, 5, 7, 0.92) 100%);
}
/* 手机上再压深一点（小屏文字更小，需要更高对比） */
@media (max-width: 900px) {
  .hero-media::after,
  .hero-fill::after {
    background:
      radial-gradient(130% 90% at 50% 42%,
        rgba(6, 6, 8, 0.42) 0%,
        rgba(6, 6, 8, 0.70) 55%,
        rgba(5, 5, 7, 0.90) 100%),
      linear-gradient(180deg,
        rgba(6, 6, 8, 0.80) 0%,
        rgba(6, 6, 8, 0.46) 28%,
        rgba(6, 6, 8, 0.54) 70%,
        rgba(5, 5, 7, 0.94) 100%);
  }
}

/* ---- 分区说明排版：行高、断行、可读宽度 ---- */
.sec .sec-head .sec-desc,
#secWorks .sec-head .sec-desc {
  line-height: 1.95 !important;
  text-wrap: pretty;
  max-width: 44ch;
}
/* 中文正文用 pretty 断行，避免把标点或单字甩到下一行 */
.sec-desc, .hero-lead, .ctap-disclaimer { text-wrap: pretty; }

/* 首屏副标题：断行优化
   原来 '…27届应届生 · 主投 UE5 技能特效' 被从"主/投"中间断开，很难看。
   balance 让两行长度接近；再加上标点/词组不断行。 */
.hero-lead {
  text-wrap: balance;
  max-width: 46ch;
  margin-left: auto;
  margin-right: auto;
  line-height: 1.7;
}

/* ==========================================================================
   作品总览右上角说明：加下划线
   --------------------------------------------------------------------------
   用户："可以在文字下面加下划线"
   用 text-decoration 而不是 border-bottom —— 跟随文字长度，不会拉满整行，
   金色细线 + 留出偏移量，当作一个设计小细节而不是"链接"。
   ========================================================================== */
#secWorks .sec-head .sec-desc {
  text-decoration: underline;
  text-decoration-color: rgba(207, 169, 95, 0.55);
  text-decoration-thickness: 1px;
  text-underline-offset: 7px;
  text-decoration-skip-ink: none;
}
/* 悬停时线更亮一点，像是一个可交互的提示 */
#secWorks .sec-head .sec-desc:hover {
  text-decoration-color: var(--accent);
}
/* 手机上断行后下划线会跟着每一行，改为只在整块下面画一条更干净 */
@media (max-width: 900px) {
  #secWorks .sec-head .sec-desc {
    text-decoration: none;
    padding-bottom: 8px;
    border-bottom: 1px solid rgba(207, 169, 95, 0.4);
  }
}

/* ==========================================================================
   作品总览说明的下划线 —— 笔触质感版
   --------------------------------------------------------------------------
   用户："你下划线不高级，你换个颜色，然后有笔触或者渐变的感觉"
   做法：不用 text-decoration（那是一条死板等宽的线）。
   改用两层叠出来的"毛笔收笔"效果：
     · 主笔触：金色渐变（两端淡出）+ clip-path 让上下边缘起伏 -> 像手写的一笔
     · 底下垫一层模糊光晕 -> 像墨晕，让线条有厚度
   宽度用 width: fit-content + margin-left: auto，线只跟文字一样长。
   ========================================================================== */
#secWorks .sec-head .sec-desc {
  text-decoration: none !important;
  position: relative;
  display: block;
  width: fit-content;
  max-width: min(100%, 46ch);
  margin-left: auto;        /* 保持右对齐 */
  padding-bottom: 14px;
}
/* 主笔触 */
#secWorks .sec-head .sec-desc::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 4px;
  height: 3px;
  background-image: linear-gradient(90deg,
    rgba(207, 169, 95, 0)     0%,
    rgba(207, 169, 95, 0.34)  9%,
    rgba(246, 228, 180, 0.95) 30%,
    rgba(226, 190, 118, 0.88) 48%,
    rgba(207, 169, 95, 0.72)  68%,
    rgba(143, 111, 44, 0.40)  87%,
    rgba(207, 169, 95, 0)    100%);
  /* 上下边缘起伏 -> 笔锋的粗细变化 */
  clip-path: polygon(
    0 44%, 7% 16%, 19% 50%, 33% 20%, 47% 54%,
    62% 22%, 76% 48%, 89% 26%, 100% 46%,
    100% 74%, 89% 66%, 76% 82%, 62% 60%,
    47% 86%, 33% 56%, 19% 82%, 7% 68%, 0 62%);
}
/* 墨晕：垫在下面的模糊光，让这一笔有"渗"的感觉 */
#secWorks .sec-head .sec-desc::before {
  content: "";
  position: absolute;
  left: 3%;
  right: 3%;
  bottom: 1px;
  height: 8px;
  border-radius: 50%;
  background: radial-gradient(58% 120% at 34% 50%,
      rgba(207, 169, 95, 0.26), rgba(207, 169, 95, 0.06) 58%, transparent 78%);
  filter: blur(3.5px);
  pointer-events: none;
}
/* 悬停：整体更亮 */
#secWorks .sec-head .sec-desc:hover::after { filter: brightness(1.22); }
#secWorks .sec-head .sec-desc:hover::before { opacity: 1.3; }

/* 手机上文字会断行，笔触跟着一个 block 走会显得很长 —— 收短一点 */
@media (max-width: 900px) {
  #secWorks .sec-head .sec-desc {
    width: 100%;
    padding-bottom: 12px;
  }
  #secWorks .sec-head .sec-desc::after { left: 0; right: 42%; }
  #secWorks .sec-head .sec-desc::before { right: 40%; }
}

/* ==========================================================================
   分区说明：排版统一 + 下划线换副色
   --------------------------------------------------------------------------
   实测：说明块 right=1209，标题行右边缘 1339 —— 差 130px，所以显得"偏左"。
         根因是 44ch 的 max-width 没配 margin-left:auto（只有 #secWorks 有）。
   用户："这些文字的排版太怪了，一句话没讲完就到下一行了，位置也偏左"
        "你下划线换个颜色，换成副色"
   ========================================================================== */

/* ---- ① 说明栏放宽：44ch -> 560px，一行能放下更多字 ---- */
.sec .sec-head {
  grid-template-columns: minmax(0, 1fr) minmax(0, 560px) !important;
}

/* ---- ② 所有说明一律贴右边缘（与 #secWorks 一致）---- */
.sec .sec-head .sec-desc,
#secWorks .sec-head .sec-desc {
  margin-left: auto !important;
  margin-right: 0 !important;
  max-width: 100% !important;
  text-align: right !important;
  line-height: 1.92 !important;
  text-wrap: pretty;
  line-break: strict;
}

/* ---- ③ 下划线：金色 -> 副色（青玉 jade）---- */
#secWorks .sec-head .sec-desc::after {
  background-image: linear-gradient(90deg,
    rgba(111, 179, 164, 0)     0%,
    rgba(111, 179, 164, 0.34)  9%,
    rgba(134, 195, 180, 0.95) 30%,
    rgba(111, 179, 164, 0.88) 48%,
    rgba(79, 142, 128, 0.72)  68%,
    rgba(47, 79, 74, 0.45)    87%,
    rgba(111, 179, 164, 0)    100%);
}
#secWorks .sec-head .sec-desc::before {
  background: radial-gradient(58% 120% at 34% 50%,
      rgba(111, 179, 164, 0.28), rgba(111, 179, 164, 0.07) 58%, transparent 78%);
}
#secWorks .sec-head .sec-desc:hover {
  text-decoration-color: var(--jade-hi);
}

/* ---- ④ 手机：单列，说明左对齐更好读（右对齐在窄屏很折腾眼睛）---- */
@media (max-width: 900px) {
  .sec .sec-head {
    grid-template-columns: 1fr !important;
  }
  .sec .sec-head .sec-desc,
  #secWorks .sec-head .sec-desc {
    margin-left: 0 !important;
    text-align: left !important;
    max-width: none !important;
    width: 100% !important;
  }
}
