/* ==========================================================================
   岑张皓睿 · UI/UX 作品集 · 全局样式
   身份：编辑部式的系统感（Editorial + System-grade）
     · 全站一条栅格、发丝描边、单色微标签
     · 案例页由 --brand 一组令牌驱动，两个案例共用同一套组件
     · 动效统一走 --dur-* / --ease-* 令牌，并且全部可被 reduced-motion 关停
   字体：思源黑体（Noto Sans SC 可变字体子集），自托管，全站单一字族
   ========================================================================== */

/* ==========================================================================
   自托管字族：思源黑体 / Source Han Sans（此处用其 Google 命名版 Noto Sans SC）
     · SIL OFL 1.1，可商用、可再分发、允许子集化 —— 授权全文见 assets/fonts/LICENSE.txt
     · 291KB 单文件，可变轴 wght 500-800，四档字重全是真字面，不再有合成伪粗体
     · 轴区间收窄到 500-800 且默认 500：不支持可变字体的旧内核（如安卓微信旧 X5）
       只会把全站渲染成正文粗细，而不会退化成 wght=100 的极细字
     · 只含本站实际用字（1141 个字符），新增文案后需重跑（脚本在 design-src/tools/）：
       python design-src/tools/build_sans.py dist <NotoSansSC-VF.ttf>
       跑完把 dist/assets/fonts/ 里的 woff2 复制回 public/ 并 bump 下面的 ?v=
   ========================================================================== */
@font-face {
  font-family: "Noto Sans SC";
  src: url("assets/fonts/noto-sans-sc-vf.woff2?v=2") format("woff2");
  font-weight: 500 800;
  font-style: normal;
  font-display: swap;
}

:root {
  /* 墨色阶 */
  --ink: #0d0e11;
  --ink-2: #4b4f57;
  --ink-3: #71767f;
  --ink-4: #b6bac1;

  /* 底与线 */
  --bg: #fcfcfd;
  --bg-2: #f6f7f9;
  --card: #ffffff;
  --line: #e6e7ec;
  --line-2: #f0f1f4;
  --grid-line: rgba(13, 14, 17, 0.045);

  /* 品牌：Findly 青绿 / VPR 靛蓝 */
  --teal: #12a5a0;
  --teal-deep: #0b6f6b;
  --teal-soft: #eaf7f6;
  --indigo: #4f5ce5;
  --indigo-deep: #3a43b8;
  --indigo-soft: #eff1fe;


  /* 默认品牌（页面未指定时用墨色） */
  --brand: var(--ink);
  --brand-deep: var(--ink);
  --brand-soft: var(--bg-2);
  --brand-line: var(--line);
  --paper: var(--bg);

  /* 圆角 */
  --r-sm: 12px;
  --r-md: 18px;
  --r-lg: 24px;
  --r-xl: 32px;
  --r-pill: 999px;
  --r-nav: 20px;

  /* 阴影：一律从发丝描边起步，避免 border 参与圆角裁切产生锯齿 */
  --sh-1: 0 0 0 1px var(--line), 0 2px 8px rgba(13, 14, 17, 0.03);
  --sh-2: 0 0 0 1px var(--line), 0 14px 32px -18px rgba(13, 14, 17, 0.14);
  --sh-3: 0 0 0 1px var(--line), 0 30px 60px -30px rgba(13, 14, 17, 0.2);

  /* 动效令牌 */
  --dur-micro: 140ms;
  --dur-short: 260ms;
  --dur: 420ms;
  --dur-long: 760ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: cubic-bezier(0.16, 1, 0.3, 1);

  /* 版心 */
  --track: 1600px;
  --track-pad: clamp(24px, 3.4vw, 60px);
  --track-gutter: clamp(20px, 4vw, 56px);

  /* 字族：全站单一字族，思源黑体（见文件头的 @font-face）。
     后面是字体加载失败时的兜底：先平台中文字体，再系统无衬线。
     这里刻意不再列各 OEM 自有字体（OPPO Sans / MiSans / HarmonyOS Sans）——
     目标就是全端一致，混入设备自带字体反而会重新引入差异。 */
  --font-sans: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", -apple-system,
    BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;

  /* 等宽族没有中文字形。若不在这里兜底，mono 元素里的中文会掉到系统宋体，
     混在正文旁边又细又怪。末尾补一组中文无衬线：拉丁/数字仍走前面的等宽族 */
  /* 微标签族：不再引系统等宽族。Consolas / ui-monospace 只有 400，拉丁部分会
     一直卡在 Regular 上发虚；改走同一支中文字族，中英笔画粗细才一致。
     数字对齐由 font-variant-numeric: tabular-nums 保证，不依赖等宽字形。 */
  --font-mono: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", ui-monospace,
    monospace, sans-serif;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font-sans);
  color: var(--ink);
  background: var(--bg);
  font-size: 15px;
  /* 全站字重下限：中文字族的 Regular 在小字与灰字上偏细会发虚，统一起到 Medium */
  font-weight: 500;
  line-height: 1.75;
  font-feature-settings: "tnum";
  /* 刻意不写 -webkit-font-smoothing: antialiased：
     浅色底上灰度抗锯齿会把笔画削细、边缘发虚，交回系统默认（次像素）渲染更实、更锐 */
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

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

/* 全站栅格底：只在页面上缘隐约可见，示意「这页是按栅格排的」 */
.grid-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
  background-size: 80px 80px;
  -webkit-mask-image: radial-gradient(120% 80% at 50% -10%, #000 0%, rgba(0, 0, 0, 0.35) 45%, transparent 78%);
  mask-image: radial-gradient(120% 80% at 50% -10%, #000 0%, rgba(0, 0, 0, 0.35) 45%, transparent 78%);
}

main { position: relative; z-index: 1; }

/* 单色微标签：全站所有 kicker / 数字 / 规格都走这一套 */
.hero-kicker,
.case-hero-kicker,
.proj-kicker,
.proj-state,
.nav-brand .nav-sub,
.figure-caption,
.swatch-code,
.point-card h4 span,
.readiness-item span,
.contact-card-label,
.demo-tip-pill,
.result-card .k {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  /* 微标签多为 11px 大写 + 字距，再轻一点就糊了，统一 SemiBold */
  font-weight: 600;
}
/* 字距一加上去，单词间那个空格就跟字距一样宽了：
   MY ROLE 会读成「M Y R O L E」，Main Flow 糊成一团。
   多词英文标签统一补一层词距，词与词的边界才重新看得出来 */
.poster-facts div span,
.poster-tag,
.anno-cap,
.nav-brand .nav-sub {
  word-spacing: 0.34em;
}

/* ---------- 滚动进度（顶部 2px） ---------- */
.scroll-progress {
  position: fixed;
  inset: 0 0 auto 0;
  height: 2px;
  z-index: 120;
  pointer-events: none;
}
.scroll-progress i {
  display: block;
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--teal), var(--indigo));
  opacity: 0.9;
}

/* ---------- 揭示动画基元 ----------
   用「容器」与「卡片」两条通道，是为了不和组件自己的 hover 过渡打架：
   · 普通容器：opacity + translate（translate 与 transform 是两个属性，互不干扰）
   · 卡片类：只做 opacity 淡入，并把 hover 用的 transform / box-shadow 一并写进 transition，
     否则组件规则会把这里的 transition 整个替换掉，揭示就会「啪」地跳出来，hover 也没有过渡
   html 前缀 + 属性选择器，保证优先级高于任何 .组件 类规则 */
[data-reveal] {
  opacity: 0;
  translate: 0 18px;
  transition:
    opacity var(--dur-long) var(--ease-out) var(--rd, 0ms),
    translate var(--dur-long) var(--ease-out) var(--rd, 0ms);
}
[data-reveal="fade"] {
  translate: none;
  transition:
    opacity var(--dur-long) var(--ease-out) var(--rd, 0ms),
    transform var(--dur-short) var(--ease-out),
    box-shadow var(--dur-short) ease;
}
html [data-reveal] { opacity: 0; }
html [data-reveal].is-in { opacity: 1; translate: none; }
html.no-js [data-reveal],
html.reduced [data-reveal] { opacity: 1; translate: none; }
/* 软换页到达：首屏可见内容也演进来 —— 比滚动揭示短、错峰更紧、略等一拍换页落位，
   慢了就像在加载。滚动揭示（没有这个类时）仍是 --dur-long 的从容节奏 */
body.nav-arrive [data-reveal] {
  transition-duration: var(--dur-short);
  transition-delay: calc(90ms + var(--rd, 0ms) * .5);
}

/* ---------- 版心 ---------- */
.wrap {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 40px;
}
/* 案例页与首页共用的宽轨 */
.track {
  width: calc(100% - 2 * var(--track-gutter));
  max-width: var(--track);
  padding-left: var(--track-pad);
  padding-right: var(--track-pad);
  margin-left: auto;
  margin-right: auto;
  box-sizing: border-box;
}

#work, #overview, #research, #journey, #decisions, #system, #interface, #site, #result {
  scroll-margin-top: 110px;
}

/* ==========================================================================
   顶部悬浮岛导航
   ========================================================================== */
.top-navbar {
  position: fixed;
  top: 18px;
  left: 0;
  right: 0;
  z-index: 100;
  display: flex;
  justify-content: center;
  pointer-events: none;
  transition: transform var(--dur) var(--ease-out), opacity var(--dur-short) var(--ease-out);
}
.top-navbar.nav-hidden { transform: translateY(-96px); opacity: 0; }
.top-nav-wrap {
  pointer-events: none;
  width: calc(100% - 2 * var(--track-gutter));
  max-width: var(--track);
  display: flex;
  align-items: center;
  gap: 12px;
}
.nav-inner,
.nav-island-demo {
  pointer-events: auto;
  height: 58px;
  display: flex;
  align-items: center;
  padding: 0 24px;
  border-radius: var(--r-nav);
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  box-shadow: 0 0 0 1px rgba(13, 14, 17, 0.07), 0 12px 30px -14px rgba(13, 14, 17, 0.16);
  transition: background var(--dur-short) ease, box-shadow var(--dur-short) ease, transform var(--dur-micro) ease;
}
.nav-inner { flex: 1; min-width: 0; justify-content: space-between; }
.nav-island-demo {
  flex-shrink: 0;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2);
  white-space: nowrap;
}
.nav-island-demo::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--teal);
  box-shadow: 0 0 0 3px rgba(18, 165, 160, 0.16);
}
.nav-island-demo:hover,
.nav-island-demo.active { color: var(--ink); transform: translateY(-1px); }
.nav-brand { font-size: 15px; font-weight: 700; letter-spacing: -0.01em; display: flex; align-items: center; gap: 12px; }
.nav-brand .nav-divider { width: 1px; height: 12px; background: var(--line); display: inline-block; }
.nav-brand .nav-sub { font-size: 11.5px; font-weight: 500; color: var(--ink-3); letter-spacing: 0.04em; }
.nav-links { display: flex; align-items: center; gap: 26px; font-size: 13.5px; }
.nav-link { position: relative; color: var(--ink-2); font-weight: 500; transition: color var(--dur-micro) ease; }
.nav-link::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -5px;
  height: 1px;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--dur-short) var(--ease-out);
}
.nav-link:hover, .nav-link.active { color: var(--ink); font-weight: 600; }
.nav-link:hover::after, .nav-link.active::after { transform: scaleX(1); }

/* ==========================================================================
   返回顶部
   ========================================================================== */
.scroll-to-top {
  position: fixed;
  right: 28px;
  bottom: 26px;
  z-index: 98;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(12px);
  border: 1px solid var(--line);
  box-shadow: 0 8px 22px -10px rgba(13, 14, 17, 0.24);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transform: translateY(10px);
  transition: transform var(--dur-short) var(--ease-out), opacity var(--dur-short) ease, box-shadow var(--dur-short) ease;
}
.scroll-to-top.visible { opacity: 1; pointer-events: auto; transform: none; }
.scroll-to-top:hover { transform: translateY(-3px); box-shadow: 0 14px 30px -12px rgba(13, 14, 17, 0.3); }

/* ==========================================================================
   按钮
   ========================================================================== */
.btn-pill-primary,
.btn-pill-secondary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 26px;
  border-radius: var(--r-pill);
  font-size: 13.5px;
  font-weight: 600;
  transition: transform var(--dur-micro) var(--ease-out), box-shadow var(--dur-short) ease, background-color var(--dur-short) ease, border-color var(--dur-short) ease;
}
.btn-pill-primary { background: var(--ink); color: #fff !important; box-shadow: 0 10px 24px -14px rgba(13, 14, 17, 0.6); }
.btn-pill-primary:hover { transform: translateY(-2px); background: #24252a; box-shadow: 0 16px 32px -14px rgba(13, 14, 17, 0.55); }
.btn-pill-secondary { background: var(--card); border: 1px solid var(--line); color: var(--ink); box-shadow: 0 1px 2px rgba(13, 14, 17, 0.03); }
.btn-pill-secondary:hover { transform: translateY(-2px); border-color: var(--ink-4); box-shadow: var(--sh-2); }
.btn-pill-primary .arw, .btn-pill-secondary .arw { transition: transform var(--dur-short) var(--ease-out); }
.btn-pill-primary:hover .arw, .btn-pill-secondary:hover .arw { transform: translateX(3px); }


@keyframes drift-a { 0%, 100% { transform: translate3d(0, 0, 0) scale(1); } 50% { transform: translate3d(4vw, 3vw, 0) scale(1.1); } }
@keyframes drift-b { 0%, 100% { transform: translate3d(0, 0, 0) scale(1.05); } 50% { transform: translate3d(-5vw, 4vw, 0) scale(0.95); } }
@keyframes drift-c { 0%, 100% { transform: translate3d(0, 0, 0) scale(0.95); } 50% { transform: translate3d(3vw, -4vw, 0) scale(1.12); } }


.hero-kicker {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 22px;
}
.hero-kicker::before { content: ""; width: 28px; height: 1px; background: var(--ink-4); }
.hero-title {
  font-size: clamp(40px, 5.6vw, 76px);
  line-height: 1.04;
  letter-spacing: -0.038em;
  font-weight: 800;
  text-wrap: balance;
}
.hero-title .hero-title-muted {
  display: block;
  margin-top: 16px;
  font-size: clamp(19px, 2.3vw, 30px);
  font-weight: 600;
  line-height: 1.32;
  letter-spacing: -0.015em;
  color: var(--ink-3);
}


/* ==========================================================================
   区块标题：编号 + 发丝规则线
   ========================================================================== */
section { padding: 100px 0; }
.sec-header { margin-bottom: 44px; }
.sec-head-row {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 32px;
}
.sec-title { font-size: clamp(28px, 3.8vw, 46px); font-weight: 800; letter-spacing: -0.03em; line-height: 1.16; }
.sec-subtitle { margin-top: 14px; font-size: 16px; color: var(--ink-2); max-width: 760px; line-height: 1.75; }

/* ==========================================================================
   首页 · 项目卡（小卡 + 结果句）
   ========================================================================== */
.proj-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 22px; }
.proj-card {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: stretch;
  border-radius: var(--r-lg);
  background: var(--card);
  overflow: hidden;
  box-shadow: var(--sh-1);
  transition: transform var(--dur-short) var(--ease-out), box-shadow var(--dur-short) ease;
}
.proj-card:hover { transform: translateY(-4px); box-shadow: var(--sh-3); }
.proj-media {
  position: relative;
  flex-shrink: 0;
  width: 420px;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--bg-2);
}
.proj-media img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 50%;
  transition: transform var(--dur-long) var(--ease-out);
}
.proj-card:hover .proj-media img { transform: scale(1.045); }
/* 悬停跟随的高光：由 JS 写入 --mx / --my */
.proj-card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur-short) ease;
  background: radial-gradient(420px 320px at var(--mx, 50%) var(--my, 0%), rgba(255, 255, 255, 0.5), transparent 62%);
}
.proj-card:hover::after { opacity: 1; }
.proj-body { padding: 26px 28px 28px; display: flex; flex-direction: column; justify-content: center; flex: 1; min-width: 0; }
.proj-topline { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.proj-kicker { font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3); }
/* 项目名：封面下方正文的第一行，先说清这是哪个项目，再谈结果 */
.proj-name { margin-bottom: 10px; font-size: 13px; font-weight: 700; letter-spacing: 0.01em; }
.proj-name.teal { color: var(--teal-deep); }
.proj-name.indigo { color: var(--indigo-deep); }
.proj-name.hub { color: #2563eb; }
.proj-state {
  display: inline-flex; align-items: center; gap: 6px;
  margin-left: auto;
  flex-shrink: 0;
  font-size: 11px; letter-spacing: 0.1em;
  padding: 4px 10px; border-radius: var(--r-pill);
  color: var(--ink-2);
  background: var(--bg-2);
  box-shadow: inset 0 0 0 1px var(--line);
}
.proj-state.live { color: var(--teal-deep); background: var(--teal-soft); box-shadow: inset 0 0 0 1px rgba(18, 165, 160, 0.22); }
.proj-state.live i { width: 5px; height: 5px; border-radius: 50%; background: var(--teal); }
.proj-title { font-size: clamp(20px, 1.7vw, 25px); font-weight: 800; letter-spacing: -0.022em; line-height: 1.32; text-wrap: balance; }
.proj-foot {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 22px; padding-top: 18px;
  border-top: 1px solid var(--line-2);
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: 0.04em; color: var(--ink-3);
}
.proj-foot .meta { display: inline-flex; align-items: baseline; gap: 6px; }
.proj-foot .meta b { font-family: var(--font-sans); color: var(--ink); font-weight: 600; font-size: 12px; }
.proj-foot .go { margin-left: auto; font-family: var(--font-sans); font-size: 12.5px; font-weight: 600; color: var(--ink); display: inline-flex; align-items: center; gap: 6px; }
.proj-foot .go .arw { transition: transform var(--dur-short) var(--ease-out); }
.proj-card:hover .proj-foot .go .arw { transform: translateX(4px); }

.tag {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  padding: 5px 11px;
  border-radius: var(--r-pill);
  background: var(--bg-2);
  box-shadow: inset 0 0 0 1px var(--line);
  color: var(--ink-2);
}
.tag.teal { background: var(--teal-soft); color: var(--teal-deep); box-shadow: inset 0 0 0 1px rgba(18, 165, 160, 0.2); }
.tag.indigo { background: var(--indigo-soft); color: var(--indigo-deep); box-shadow: inset 0 0 0 1px rgba(79, 92, 229, 0.2); }

/* ==========================================================================
   案例页 · 首屏壳（两个案例同一条壳，靠 --brand 换气质）
   ========================================================================== */
.case-hero { position: relative; padding: 96px 0 64px; }
body.case-findly { background: #f7fbfb; }
body.case-vpr { background: #f8f9fd; }
body.case-findly {
  --brand: var(--teal); --brand-deep: var(--teal-deep); --brand-soft: var(--teal-soft);
  --brand-line: rgba(18, 165, 160, 0.2); --paper: #f7fbfb;
}
body.case-vpr {
  --brand: var(--indigo); --brand-deep: var(--indigo-deep); --brand-soft: var(--indigo-soft);
  --brand-line: rgba(79, 92, 229, 0.2); --paper: #f8f9fd;
}
body.case-hub { background: #fdf9f5; }
body.case-hub {
  --brand: #f2793b; --brand-deep: #c7521a; --brand-soft: #fff1e7;
  --brand-line: rgba(242, 121, 59, 0.22); --paper: #fdf9f5;
}

.case-shell {
  position: relative;
  width: calc(100% - 2 * var(--track-gutter));
  max-width: var(--track);
  margin: 0 auto;
  padding: clamp(26px, 2.6vw, 40px) clamp(24px, 3.4vw, 56px) clamp(36px, 3.6vw, 56px);
  border-radius: var(--r-xl);
  overflow: hidden;
  background: linear-gradient(180deg, color-mix(in srgb, var(--brand) 4%, #fff) 0%, color-mix(in srgb, var(--brand) 10%, #fff) 100%);
  box-shadow: inset 0 0 0 1px var(--brand-line), 0 34px 70px -52px color-mix(in srgb, var(--brand-deep) 60%, transparent);
}
.case-shell::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(680px 460px at 94% -8%, color-mix(in srgb, var(--brand) 24%, transparent), transparent 70%),
    radial-gradient(560px 400px at -8% 104%, color-mix(in srgb, var(--brand) 14%, transparent), transparent 72%);
}
.case-shell > * { position: relative; z-index: 1; }

.case-head { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; margin-bottom: 28px; }
/* 返回精选作品：三个案例页统一成 Home Hub 那种白色胶囊
   （白底 + 发丝描边 + 轻投影；悬停改为该页品牌色并向左轻移） */
.case-back-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--ink-2);
  background: var(--card);
  border: 1px solid var(--line);
  padding: 8px 18px;
  border-radius: var(--r-pill);
  box-shadow: 0 2px 8px rgba(13, 14, 17, 0.03);
  transition: color var(--dur-short) ease, border-color var(--dur-short) ease,
              transform var(--dur-short) var(--ease-out), box-shadow var(--dur-short) ease;
}
.case-back-btn svg { width: 14px; height: 14px; }
.case-back-btn:hover {
  color: var(--brand-deep);
  border-color: var(--brand-line);
  transform: translateX(-2px);
  box-shadow: 0 4px 12px color-mix(in srgb, var(--brand) 14%, transparent);
}
.case-hero-kicker {
  display: block;
  width: fit-content;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brand-deep);
}
.case-hero-inner { max-width: 1080px; margin: 0 auto; }
.case-hero-grid { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: clamp(28px, 3.4vw, 56px); align-items: center; }
.case-hero-copy { min-width: 0; }
/* 产品名：结果式标题负责「解决了什么」，名字单独一行交代「这是什么」 */
.case-hero-product {
  display: block;
  font-size: clamp(17px, 1.6vw, 21px);
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--brand-deep);
  margin-bottom: 12px;
}
/* 结果式标题：写解决了什么，而不是产品名 + 品类 */
.case-hero-title {
  font-size: clamp(30px, 3.6vw, 52px);
  font-weight: 800;
  letter-spacing: -0.032em;
  line-height: 1.14;
  text-wrap: balance;
}
.case-hero-lead {
  margin-top: 20px;
  max-width: 44em;
  font-size: clamp(15.5px, 1.5vw, 18px);
  line-height: 1.8;
  color: var(--ink-2);
}
.case-hero-lead b { color: var(--ink); }
.case-hero-visual img {
  width: 100%; height: auto;
  border-radius: var(--r-sm);
  box-shadow: 0 0 0 1px var(--line), 0 26px 50px -34px rgba(13, 14, 17, 0.4);
}
/* VPR 的实机图是一张浅色窗口截图，落在浅色壳上会糊成一片：
   按「窗口」处理，给一圈带品牌色相的描边和更深的投影，边界才立得住 */
body.case-vpr .case-hero-visual img {
  border-radius: 10px;
  box-shadow: 0 0 0 1px rgba(79, 92, 229, 0.2), 0 32px 62px -34px rgba(24, 30, 96, 0.5);
}

/* 四栏项目元信息：我的角色 / 设计约束 / 交付物 / 验证方式 —— 不含时间 */
.case-meta-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  margin-top: 34px;
}
.case-meta-col {
  background: rgba(255, 255, 255, 0.78);
  border-radius: var(--r-md);
  padding: 16px 20px;
  box-shadow: inset 0 0 0 1px var(--brand-line);
}
.case-meta-col span {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brand-deep);
  margin-bottom: 5px;
}
.case-meta-col b { display: block; font-size: 13.5px; font-weight: 600; line-height: 1.6; }


/* 指标条 */
.metrics-strip {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 14px;
  margin-top: 34px;
  padding: 22px 26px;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.74);
  box-shadow: inset 0 0 0 1px var(--brand-line);
}
.metric-item { padding: 4px 0; min-width: 0; }
.metric-value {
  font-family: var(--font-mono);
  font-size: clamp(20px, 1.7vw, 26px);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--brand-deep);
}
.metric-label { margin-top: 5px; font-size: 11.5px; line-height: 1.5; color: var(--ink-3); }

/* ==========================================================================
   案例页 · 正文
   ========================================================================== */
.case-content-wrap {
  width: calc(100% - 2 * var(--track-gutter));
  max-width: var(--track);
  padding: var(--track-pad);
  margin: 0 auto;
  padding-top: 72px;
  padding-bottom: 90px;
}
.content-block { margin-bottom: 88px; }
/* 全局那条 section { padding:100px 0 } 是给首页整段留白用的；
   案例页的区块节奏由 margin-bottom 控制，若再叠上 200px 内边距，
   每两块之间就会空出 276px——这里显式清零 */
.content-block, .poster { padding-top: 0; padding-bottom: 0; }
.content-block > :first-child { margin-top: 0; }
.content-block:last-child { margin-bottom: 0; }
.block-title {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: clamp(20px, 1.9vw, 26px);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin-bottom: 22px;
}
.block-title::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.persona-card, .point-card {
  background: var(--card);
  border-radius: var(--r-md);
  padding: 22px 24px;
  box-shadow: var(--sh-1);
  transition: transform var(--dur-short) var(--ease-out), box-shadow var(--dur-short) ease;
}
.persona-card:hover, .point-card:hover { transform: translateY(-3px); box-shadow: var(--sh-2); }
.persona-card b { display: block; font-size: 15px; font-weight: 700; margin-bottom: 8px; }
.persona-card p, .point-card p { font-size: 13.5px; line-height: 1.78; color: var(--ink-2); }
.point-card h4 {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  font-size: 15px; font-weight: 700; margin-bottom: 7px;
}
.point-card h4 span { flex-shrink: 0; font-size: 11px; letter-spacing: 0.1em; color: var(--ink-3); }

/* 产品红线 / 设计原则条 */
.redline-band {
  margin-top: 18px;
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 20px 26px;
  border-radius: var(--r-md);
  background: var(--brand-soft);
  box-shadow: inset 0 0 0 1px var(--brand-line);
}
.redline-band b {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--brand-deep);
  padding-top: 3px;
}
.redline-band p { font-size: 14px; line-height: 1.78; color: var(--ink); }

/* 用户旅程：胶囊 + 箭头 */
.flow-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 0; margin: 0 0 8px; }
.flow-step {
  padding: 9px 18px;
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: 13px;
  font-weight: 600;
  transition: transform var(--dur-short) var(--ease-out);
}
.flow-step:hover { transform: translateY(-2px); }
.flow-step.active { background: var(--brand); color: #fff; box-shadow: none; }
.flow-arrow { padding: 0 10px; color: var(--ink-4); font-family: var(--font-mono); font-size: 12px; }


/* 设计资产档案卡 */
.artifact-card {
  background: var(--card);
  border-radius: var(--r-md);
  padding: 22px 24px;
  box-shadow: var(--sh-1);
  margin-top: 20px;
}

/* Before / After 对比 */
.ba-compare { margin-top: 20px; display: grid; grid-template-columns: minmax(0, 1fr) 48px minmax(0, 1fr); align-items: stretch; }

/* 配图 */
.showcase-figure {
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--card);
  box-shadow: var(--sh-1);
  margin-top: 22px;
}
.showcase-figure img { width: 100%; height: auto; }
.figure-caption {
  font-size: 11.5px;
  line-height: 1.7;
  color: var(--ink-3);
  padding: 12px 20px;
  border-top: 1px solid var(--line-2);
}

.fig-grid-3 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; margin-top: 22px; }
.fig-grid-3 .showcase-figure { margin-top: 0; }
.fig-grid-3 .showcase-figure:first-child { grid-column: 1 / -1; }


/* 色彩体系 */
.swatches-wrap { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 16px; }
.swatch-item { width: 118px; }
.swatch-color { height: 60px; border-radius: var(--r-sm); box-shadow: inset 0 0 0 1px rgba(13, 14, 17, 0.07); }
.swatch-label { margin-top: 7px; font-size: 11.5px; line-height: 1.5; color: var(--ink-2); }
.swatch-code { display: block; font-size: 11px; color: var(--ink-3); }

/* 原型试玩横幅 */
.live-sandbox-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 20px;
  margin-top: 34px;
  padding: 24px 28px;
  border-radius: var(--r-md);
  background: var(--card);
  box-shadow: var(--sh-1);
}
.sandbox-info h4 { font-size: 16px; font-weight: 700; }
.sandbox-info p { margin-top: 4px; font-size: 13.5px; color: var(--ink-2); }
/* 首屏里的横幅：文案占一列、按钮钉在右列，避免换行后右侧留空 */
.hero-demo-banner { margin-top: 0; }

/* 下一个案例 */
.next-project-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 22px;
  margin-top: 70px;
  padding: 28px 32px;
  border-radius: var(--r-lg);
  background: linear-gradient(180deg, color-mix(in srgb, var(--brand) 3%, #fff), color-mix(in srgb, var(--brand) 10%, #fff));
  box-shadow: inset 0 0 0 1px var(--brand-line);
}
.result-card { background: var(--card); border-radius: var(--r-md); padding: 22px 24px; box-shadow: var(--sh-1); }
.result-card .k { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); }
.result-card .v { margin-top: 10px; font-family: var(--font-mono); font-size: 30px; font-weight: 700; letter-spacing: -0.02em; color: var(--brand-deep); line-height: 1; }
.result-card .v small { font-family: var(--font-sans); font-size: 13px; font-weight: 600; color: var(--ink-2); margin-left: 6px; letter-spacing: 0; }
.result-card .d { margin-top: 10px; font-size: 12.5px; line-height: 1.72; color: var(--ink-2); }


.fh-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 32px; }


.about-story p { font-size: 15.5px; line-height: 1.9; color: var(--ink-2); margin-bottom: 16px; }
.about-story p:first-of-type { font-size: 18px; line-height: 1.8; color: var(--ink); font-weight: 500; }
.about-story b { color: var(--ink); }
.about-quote {
  margin: 26px 0;
  padding: 20px 24px;
  border-radius: var(--r-md);
  background: var(--card);
  box-shadow: var(--sh-1);
  font-size: 15px;
  line-height: 1.8;
  color: var(--ink);
}
/* 关于我 · 工具磁贴：品牌图标 + 名称，整卡可点跳官网（新标签页） */
.tool-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; }
.tool-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 28px 16px 22px;
  border-radius: var(--r-md);
  background: var(--card);
  box-shadow: var(--sh-1);
  text-decoration: none;
  transition: transform var(--dur-short) var(--ease-out), box-shadow var(--dur-short) var(--ease-out);
}
.tool-tile:hover { transform: translateY(-3px); box-shadow: var(--sh-2); }
.tool-tile svg { width: 36px; height: 36px; display: block; }
.tool-tile span { font-size: 13px; font-weight: 600; color: var(--ink-2); letter-spacing: 0.01em; }
@media (max-width: 720px) {
  .tool-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ==========================================================================
   联系方式
   ========================================================================== */
.contact-hero { padding: 148px 0 56px; border-bottom: 1px solid var(--line); }
.contact-hero-inner { max-width: 900px; margin: 0 auto; }
.contact-cards-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; margin-top: 44px; }
.contact-card-box {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 34px 24px;
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--sh-1);
  text-align: center;
  transition: transform var(--dur-short) var(--ease-out), box-shadow var(--dur-short) ease;
}
.contact-card-box:hover { transform: translateY(-4px); box-shadow: var(--sh-3); }
.contact-icon-bubble {
  width: 50px; height: 50px;
  border-radius: 50%;
  background: var(--bg-2);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 18px;
  color: var(--ink);
}
.contact-icon-bubble svg { width: 21px; height: 21px; stroke: currentColor; }
.contact-card-label { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 9px; }
.contact-card-val { font-size: 17px; font-weight: 700; margin-bottom: 9px; user-select: all; }
a.contact-link, button.contact-action {
  display: inline-block;
  color: inherit;
  background: none;
  border: none;
  padding: 0;
  border-bottom: 1px dashed var(--line);
  cursor: pointer;
  transition: color var(--dur-micro) ease, border-color var(--dur-micro) ease;
}
a.contact-link:hover, button.contact-action:hover, button.contact-action.copied { color: var(--teal); border-bottom-color: var(--teal); }
.contact-card-hint { font-size: 12.5px; line-height: 1.6; color: var(--ink-2); }
.readiness-banner {
  margin: 44px 0 72px;
  padding: 30px 34px;
  border-radius: var(--r-lg);
  background: var(--bg-2);
  box-shadow: inset 0 0 0 1px var(--line);
}
.readiness-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.readiness-item span { display: block; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 5px; }
.readiness-item b { display: block; font-size: 14px; font-weight: 700; }

/* ==========================================================================
   可交互演示工作台
   ========================================================================== */
.page-demo .case-hero { padding: 128px 0 20px; border-bottom: 1px solid var(--line); }
.demo-page-switcher-wrap { margin-top: 22px; }
.demo-tab-switcher {
  display: inline-flex;
  padding: 4px;
  border-radius: var(--r-pill);
  background: var(--bg-2);
  box-shadow: inset 0 0 0 1px var(--line);
  gap: 4px;
}
.demo-tab-btn {
  padding: 8px 22px;
  border: none;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: color var(--dur-short) ease, background-color var(--dur-short) ease, box-shadow var(--dur-short) ease;
}
.demo-tab-btn:hover { color: var(--ink); }
.demo-tab-btn.active { background: var(--card); color: var(--ink); box-shadow: 0 2px 8px -3px rgba(13, 14, 17, 0.24); }
.demo-view-panel { display: none; }
.demo-view-panel.active { display: block; margin-top: 20px; }
.demo-tips-strip { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-bottom: 20px; }
.demo-tip-pill { font-size: 11px; padding: 5px 13px; border-radius: var(--r-pill); background: var(--card); box-shadow: inset 0 0 0 1px var(--line); color: var(--ink-2); }
.demo-tip-pill b { font-family: var(--font-sans); color: var(--ink); font-weight: 600; margin-right: 6px; }
.demo-stage-wrap { max-width: 1560px; padding: 0 24px 90px; }
.demo-phone-box { display: flex; justify-content: center; padding: 10px 0 20px; }
/* 机身处：苹果官方 iPhone 16 Pro 机身图（已擦灵动岛），iframe 精确落在屏幕孔径里；
   与案例页真机图同一机身。drop-shadow 沿机身透明剪影投影，不用矩形 box-shadow */
.frame-phone {
  position: relative;
  width: 450px;
  max-width: 100%;
  aspect-ratio: 1350 / 2760;
}
.frame-phone iframe {
  display: block;
  position: absolute;
  left: 5.3333%;    /* 孔径 x=72 / 1350 */
  top: 2.5%;        /* 孔径 y=69 / 2760 */
  width: 89.3333%;  /* 孔径 w=1206 / 1350 */
  height: 95%;      /* 孔径 h=2622 / 2760 */
  border: none;
  background: #fff;
}
.frame-phone::after {
  content: "";
  position: absolute;
  inset: 0;
  background: url(assets/findly/frame-iphone16pro.png) center / 100% 100% no-repeat;
  pointer-events: none;
  z-index: 2;
  filter: drop-shadow(0 26px 40px rgba(2, 80, 92, 0.28));
}
/* iframe 里的原型是独立文档，绘制前那一下最容易「闪」。先给舞台底色、就绪后再淡入 */
.frame-phone iframe, .frame-desktop iframe { opacity: 0; transition: opacity 340ms var(--ease-out); }
.frame-phone iframe.is-ready, .frame-desktop iframe.is-ready { opacity: 1; }
.demo-desktop-box { display: flex; justify-content: center; padding: 6px 0 16px; }
.frame-desktop {
  width: 100%;
  max-width: 1440px;
  border-radius: 14px;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 0 0 1px var(--line), 0 30px 60px -30px rgba(20, 28, 40, 0.35);
}
.frame-desktop iframe { display: block; width: 100%; height: auto; aspect-ratio: 8 / 5; border: none; background: #fff; }

/* ==========================================================================
   响应式
   ========================================================================== */
@media (max-width: 960px) {
  
  
  
  .metrics-strip { grid-template-columns: repeat(3, minmax(0, 1fr)); padding: 20px 22px; }
  .case-meta-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .case-hero-grid { grid-template-columns: minmax(0, 1fr); gap: 36px; align-items: start; }
  .fig-grid-3 { grid-template-columns: minmax(0, 1fr); }
  
  
  
  
  
}

@media (max-width: 720px) {
  body { font-size: 14.5px; }
  .wrap { padding: 0 20px; }
  .track { width: calc(100% - 24px); padding-left: 18px; padding-right: 18px; }
  /* 手机端导航改由「侧栏 → 底部图标栏」承担（见文件末尾的手机导航块），
     顶部悬浮岛整条收起，避免姓名与链接两行长期压住页首 */
  .top-navbar { display: none; }
  .nav-brand .nav-sub, .nav-brand .nav-divider, .nav-links { display: none; }
  /* 精选作品卡：窄屏退回上图下文 */
  .proj-card { flex-direction: column; }
  .proj-media { width: 100%; }
  section { padding: 68px 0; }
  
  .hero-title { font-size: clamp(32px, 9.5vw, 44px); }
  .hero-title .hero-title-muted { font-size: 18px; }
  
  .proj-body { padding: 22px 20px 24px; }
  .metrics-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 18px; }
  .case-meta-grid{ grid-template-columns: minmax(0, 1fr); }
  .case-shell { border-radius: var(--r-lg); padding: 22px 18px 32px; }
  .block-title { font-size: 19px; }
  .ba-compare { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .contact-cards-grid { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .contact-hero { padding: 118px 0 40px; }
  .readiness-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .live-sandbox-banner { flex-direction: column; align-items: flex-start; }
  .next-project-card { padding: 22px 20px; }
  .scroll-to-top { display: none; }
  .demo-tab-switcher { width: 100%; justify-content: center; }
  .demo-tab-btn { flex: 1; padding: 7px 8px; font-size: 11.5px; text-align: center; }
  /* 机身图与 iframe 都是百分比定位，窄屏随 max-width:100% 自然等比缩小 */
  .demo-stage-wrap { padding: 0 16px 150px; }
  .demo-desktop-box { justify-content: flex-start; overflow-x: auto; }
  .frame-desktop { flex: 0 0 1440px; max-width: none; }
  .frame-desktop iframe { width: 1440px; height: 900px; aspect-ratio: auto; }
}

/* ==========================================================================
   降级：尊重系统「减少动效」
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  [data-reveal] { opacity: 1 !important; translate: none !important; }
  
  
}

/* ==========================================================================
   跨页过渡（View Transitions）
   支持的浏览器在站内跳转时得到一次柔和的整体切换，不支持的浏览器静默降级为普通跳转
   ========================================================================== */
@view-transition { navigation: auto; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 240ms; animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}

/* ==========================================================================
   打印
   ========================================================================== */
@media print {
  .top-navbar, .scroll-to-top, .live-sandbox-banner,
  .scroll-progress, .grid-bg { display: none !important; }
  body { background: #fff; font-size: 12px; }
  .wrap, .track { max-width: none; padding: 0; width: 100%; }
  [data-reveal] { opacity: 1 !important; translate: none !important; }
  .poster { break-inside: avoid; }
  .wall-item, .twin, .icon-cell { break-inside: avoid; }
}

/* ==========================================================================
   案例页视觉组件（v3）
   目标：让每一屏都有一张真实截图 + 一句说明，并把设计决定直接标在图上
   素材全部来自两个可运行原型导出，不用生成图充当界面
   ========================================================================== */

/* ---------- 1. 封面海报（作品集封面页，含角色/平台/类型元信息） ---------- */
.poster {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  background: #eef7f7;
}
.poster-bg {
  position: absolute;
  inset: 0;
  background: url("assets/findly-ambient.webp") center / cover no-repeat;
  z-index: 0;
}
/* 底图只当氛围：朝左下渐隐到纸色，保证文字区始终干净 */
.poster::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.3) 0%, rgba(255, 255, 255, 0.72) 52%, var(--paper, #f7fbfb) 100%);
}
.poster-inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr);
  gap: clamp(28px, 3.6vw, 64px);
  align-items: center;
  padding-top: clamp(96px, 9vw, 132px);
  padding-bottom: clamp(40px, 4vw, 64px);
}
.poster-tag {
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brand-deep);
  margin: 16px 0 18px;
}
.poster-tag::before { content: ""; width: 26px; height: 1px; background: var(--brand); }
.poster-title {
  font-size: clamp(42px, 5.6vw, 82px);
  font-weight: 800;
  /* 之前 -0.042em 的负字距把 Findly 的字形挤到一起了：
     d 的碗贴上 n、l 和 y 直接叠住。收回到 -0.02em */
  letter-spacing: -0.02em;
  line-height: 1.14;
}
.poster-title em {
  font-style: normal;
  background: linear-gradient(135deg, #31cbbb, #04869d);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.poster-claim {
  margin-top: 20px;
  max-width: 24em;
  font-size: clamp(16px, 1.6vw, 19px);
  line-height: 1.8;
  color: var(--ink-2);
}
.poster-claim b { color: var(--ink); font-weight: 700; }
/* 元信息表：封面就交代清楚「谁做的 / 什么角色 / 什么类型 / 交了什么东西」 */
.poster-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 22px 44px;
  margin-top: 34px;
  padding-top: 26px;
  border-top: 1px solid rgba(18, 165, 160, 0.28);
}
.poster-facts div span {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--brand-deep);
  margin-bottom: 7px;
}
.poster-facts div b { font-size: 13.5px; font-weight: 600; line-height: 1.55; }
.poster-chips { display: flex; align-items: center; gap: 8px; margin-top: 26px; }
.poster-chips i {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08), 0 1px 3px rgba(13, 14, 17, 0.1);
}
.poster-chips span {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--ink-3);
  margin-left: 4px;
}
/* 两台手机：主屏 + 次级屏错位叠放，比单张图更有"在用"的感觉 */
.poster-visual { position: relative; display: flex; align-items: flex-end; justify-content: center; }
.poster-visual::before {
  content: "";
  position: absolute;
  width: 78%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(18, 165, 160, 0.32), transparent 68%);
  filter: blur(34px);
  z-index: 0;
}
.poster-phone { position: relative; z-index: 1; }
.poster-phone img {
  width: 100%;
  height: auto;
  filter: drop-shadow(0 30px 44px rgba(2, 80, 92, 0.3));
}
.poster-phone.main { width: min(262px, 44%); }
.poster-phone.side { width: min(198px, 33%); margin-left: -34px; margin-bottom: -18px; }
.wall-item { margin: 0; }

/* ---------- 3. 图上标注：编号圆点 + 右侧说明 ---------- */
.anno {
  display: grid;
  grid-template-columns: minmax(0, 336px) minmax(0, 1fr);
  gap: clamp(24px, 3vw, 52px);
  align-items: center;
  width: 100%;
  max-width: 1180px;
  margin: 26px auto 0;
}
.anno-stage { position: relative; max-width: 336px; margin: 0 auto; }
.anno-stage img {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 26px 36px rgba(2, 80, 92, 0.28));
}
/* 图下小注：补齐左列高度，也顺手说明这张图是 12 屏里的第几屏 */
.anno-cap {
  margin-top: 14px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--ink-3);
  text-align: center;
}
.anno-list { list-style: none; display: flex; flex-direction: column; gap: 18px; }
.anno-list li { display: grid; grid-template-columns: 27px minmax(0, 1fr); gap: 14px; align-items: start; }
.anno-list .n {
  width: 27px;
  height: 27px;
  border-radius: 50%;
  background: var(--brand-soft);
  color: var(--brand-deep);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: inset 0 0 0 1px var(--brand-line);
}
.anno-list h4 { font-size: 14.5px; font-weight: 700; margin-bottom: 4px; letter-spacing: -0.01em; }
.anno-list p { font-size: 13px; line-height: 1.72; color: var(--ink-2); }


.twin { margin: 0; display: flex; flex-direction: column; align-items: center; }
.twin img {
  display: block;
  width: 100%;
  max-width: 240px;
  height: auto;
  filter: drop-shadow(0 18px 26px rgba(2, 80, 92, 0.24));
}
.twin figcaption { margin-top: 12px; max-width: 260px; text-align: center; }

.twin p { margin-top: 4px; font-size: 12.5px; line-height: 1.62; color: var(--ink-3); }


/* ---------- 5. 图标墙 ---------- */
.icon-wall {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(86px, 1fr));
  gap: 12px;
  margin-top: 24px;
}
.icon-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  padding: 14px 6px 12px;
  border-radius: 16px;
  background: var(--card);
  box-shadow: var(--sh-1);
  transition: transform var(--dur-short) var(--ease-out), box-shadow var(--dur-short) ease;
}
.icon-cell:hover { transform: translateY(-4px); box-shadow: var(--sh-2); }
.icon-cell img { width: 48px; height: 48px; }
.icon-cell b { font-size: 11px; font-weight: 500; color: var(--ink-2); }

/* ---------- 组件响应式 ---------- */
@media (max-width: 1080px) {
  .poster-inner { grid-template-columns: minmax(0, 1fr); gap: 34px; }
  .poster-visual { justify-content: flex-start; }
  .poster-phone.main { width: min(240px, 46%); }
  .poster-phone.side { width: min(180px, 34%); }
  
  .anno { grid-template-columns: minmax(0, 1fr); gap: 22px; align-items: start; }
  .anno-cap { text-align: left; }
  
}

@media (max-width: 720px) {
  .poster-facts { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .anno-list li { grid-template-columns: 23px minmax(0, 1fr); gap: 11px; }
  .anno-list .n { width: 23px; height: 23px; font-size: 11px; }
  .icon-wall { grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 9px; }
  .icon-cell { padding: 11px 4px 9px; border-radius: 13px; }
  .icon-cell img { width: 40px; height: 40px; }
  .icon-cell b { font-size: 11px; }
}


/* 案例页 · 界面全景在窄屏改为两列 */
@media (max-width: 760px) {
  
  .icon-wall { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ==========================================================================
   主页集群 · 青蓝浅色主题（theme-cyan）
   --------------------------------------------------------------------------
   作用范围：index / about / contact / demo 四页的 <body class="... theme-cyan">。
   三个案例页 body 上没有 theme-cyan，因此读不到本段任何一条规则——
   所有对「共享外壳类」的改动都包在 body.theme-cyan 作用域内，刻意如此。
   令牌是 CSS 变量、随选择器级联，所以：:root 的墨色值不动，案例页照旧。
   ========================================================================== */
body.theme-cyan {
  /* 底与面：极浅青调纸面 */
  --bg: #f4fafd;
  --bg-2: #eaf4f9;
  --card: #ffffff;
  --line: #dceaf2;
  --line-2: #eaf3f8;
  --grid-line: rgba(14, 116, 160, 0.055);

  /* 墨色阶：冷调而非中性 */
  --ink: #0e1a24;
  --ink-2: #4a5c6b;
  --ink-3: #5f7383;
  --ink-4: #afc2cd;

  /* 青蓝品牌 */
  --cyan: #12a9c9;
  --blue: #2e6be0;
  --brand: #12a9c9;
  --brand-deep: #0a6e8e;
  --brand-soft: #e4f5fb;
  --brand-line: rgba(18, 169, 201, 0.22);
  --paper: var(--bg);

  /* 毛玻璃 */
  --glass: rgba(255, 255, 255, 0.62);
  --glass-strong: rgba(255, 255, 255, 0.84);
  --glass-line: rgba(255, 255, 255, 0.78);
  --glass-edge: rgba(18, 120, 160, 0.1);
  --glass-shadow: 0 26px 56px -34px rgba(10, 80, 110, 0.34);
}

/* 环境底：固定一层极淡的青蓝光晕，给中部的毛玻璃提供「可模糊」的内容，
   否则浅色页面上的玻璃会退化成一张纯白卡 */
body.theme-cyan::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(1100px 720px at 86% -10%, rgba(18, 169, 201, 0.11), transparent 62%),
    radial-gradient(920px 640px at -8% 22%, rgba(46, 107, 224, 0.09), transparent 60%),
    radial-gradient(900px 700px at 50% 118%, rgba(18, 169, 201, 0.07), transparent 66%);
}

/* ---------- 共享外壳：仅在本主题内改成青蓝 ---------- */
body.theme-cyan .nav-island-demo::before { background: var(--cyan); box-shadow: 0 0 0 3px rgba(18, 169, 201, 0.16); }
body.theme-cyan .nav-link::after { background: var(--cyan); }
body.theme-cyan .nav-inner,
body.theme-cyan .nav-island-demo { box-shadow: 0 0 0 1px var(--glass-edge), 0 12px 30px -16px rgba(10, 80, 110, 0.22); }
body.theme-cyan .scroll-to-top { box-shadow: 0 8px 22px -10px rgba(10, 80, 110, 0.28); }
body.theme-cyan .scroll-progress i { background: linear-gradient(90deg, var(--cyan), var(--blue)); }
body.theme-cyan .btn-pill-primary {
  background: linear-gradient(135deg, var(--cyan) 0%, var(--blue) 100%);
  box-shadow: 0 12px 26px -14px rgba(46, 107, 224, 0.62);
}
body.theme-cyan .btn-pill-primary:hover { background: linear-gradient(135deg, #0f98b6 0%, #2454c4 100%); box-shadow: 0 18px 34px -14px rgba(46, 107, 224, 0.6); }
body.theme-cyan .btn-pill-secondary { background: var(--glass-strong); backdrop-filter: blur(14px) saturate(150%); -webkit-backdrop-filter: blur(14px) saturate(150%); }
body.theme-cyan .btn-pill-secondary:hover { border-color: rgba(18, 169, 201, 0.4); }


body.theme-cyan .hero-kicker { color: var(--brand-deep); }
body.theme-cyan .hero-kicker::before { background: var(--cyan); }


/* ---------- 沉浸式首屏舞台：整屏氛围 + 浮起的玻璃卡 ---------- */
body.theme-cyan .hero-stage {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  /* 底部多留一截：首屏展开态的侧栏是一条横贯底部的导航，正文要让开它 */
  padding: 124px 0 190px;
  display: flex;
  align-items: center;
  overflow: hidden;
  isolation: isolate;
}
.stage-scene { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
/* 天光：青蓝自上方压下来，越往下越接近纸色，保证浮起的玻璃卡有东西可模糊 */
.stage-scene::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(1200px 760px at 82% 2%, rgba(18, 169, 201, 0.32), transparent 60%),
    radial-gradient(1000px 720px at 10% 16%, rgba(46, 107, 224, 0.24), transparent 62%),
    linear-gradient(180deg, #e4f5fc 0%, #edf9ff 38%, #f5fcfe 68%, var(--bg) 100%);
}
/* 层叠山脊：越远越淡，纯 clip-path，不引外链图 */
.ridge { position: absolute; bottom: -2px; display: block; }
.ridge.r3 {
  left: -12%; right: -12%; height: 58%;
  background: linear-gradient(180deg, rgba(46, 107, 224, 0.17), rgba(46, 107, 224, 0.04));
  clip-path: polygon(0 70%, 9% 46%, 19% 62%, 30% 34%, 41% 58%, 52% 30%, 63% 54%, 74% 36%, 85% 60%, 94% 42%, 100% 62%, 100% 100%, 0 100%);
}
.ridge.r2 {
  left: -12%; right: -12%; height: 44%;
  background: linear-gradient(180deg, rgba(18, 169, 201, 0.21), rgba(18, 169, 201, 0.06));
  clip-path: polygon(0 74%, 12% 52%, 26% 70%, 38% 44%, 52% 66%, 66% 42%, 80% 64%, 91% 50%, 100% 68%, 100% 100%, 0 100%);
}
.ridge.r1 {
  left: -12%; right: -12%; height: 30%;
  background: linear-gradient(180deg, rgba(10, 110, 142, 0.17), rgba(10, 110, 142, 0.05));
  clip-path: polygon(0 80%, 15% 58%, 32% 78%, 48% 50%, 64% 74%, 80% 54%, 100% 76%, 100% 100%, 0 100%);
}
/* 漂浮光晕 */
.orb { position: absolute; border-radius: 50%; filter: blur(64px); opacity: 0.5; }
.orb.o1 { width: 30vw; height: 30vw; right: 4%; top: 4%; background: rgba(18, 169, 201, 0.4); animation: drift-a 24s ease-in-out infinite; }
.orb.o2 { width: 22vw; height: 22vw; left: 2%; top: 24%; background: rgba(46, 107, 224, 0.34); animation: drift-b 29s ease-in-out infinite; }
.orb.o3 { width: 26vw; height: 26vw; left: 44%; bottom: -8%; background: rgba(46, 190, 214, 0.3); animation: drift-c 33s ease-in-out infinite; }

body.theme-cyan .stage-inner { position: relative; z-index: 1; text-align: center; }

/* 身份行：圆形徽标 + 名字与角色（替代真人头像，不依赖照片） */
.stage-id { display: inline-flex; align-items: center; gap: 16px; }
.stage-avatar {
  width: 74px; height: 74px; flex: 0 0 auto;
  border-radius: 50%;
  display: grid; place-items: center;
  font-size: 22px; font-weight: 800; letter-spacing: -0.02em; color: #fff;
  background: linear-gradient(135deg, var(--cyan), var(--blue));
  box-shadow: 0 16px 34px -14px rgba(46, 107, 224, 0.65), inset 0 0 0 3px rgba(255, 255, 255, 0.55);
}
.stage-name { text-align: left; }
.stage-name b { display: block; font-size: clamp(22px, 2.4vw, 28px); font-weight: 800; letter-spacing: -0.02em; color: var(--ink); }
.stage-name > span { display: block; margin-top: 3px; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-2); }

/* 浮起的玻璃卡 */
.glass-card {
  background: rgba(255, 255, 255, 0.58);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.7), 0 26px 56px -34px rgba(10, 80, 110, 0.34);
}
.stage-cards { display: grid; grid-template-columns: 1fr 1.08fr; gap: 18px; max-width: 1080px; margin: 36px auto 0; text-align: left; }
.stage-quote { position: relative; padding: 24px 28px 20px; border-radius: var(--r-lg); }
.stage-quote .q-mark { display: block; font-size: 40px; line-height: 0.55; color: var(--cyan); font-weight: 800; }
.stage-quote p { margin-top: 8px; font-size: 15.5px; line-height: 1.75; color: var(--ink); font-weight: 500; }
/* 引号成对：开头是左上角那个大引号，收尾引号是同款装饰件、锚在卡片右下角，
   与开引号斜向对应。旧写法把它放在文字流里（block + text-align:right），
   垂直位置会随随机语录的行数上下浮动 —— 那就是"后引号偶尔偏了"的原因。
   改成相对卡片绝对定位后，跟抽出哪条语录无关，恒定在右下角。 */
.stage-quote p::after {
  content: "”";
  position: absolute;
  right: 30px;
  bottom: 16px;
  font-size: 40px;
  line-height: 1;
  color: var(--cyan);
  font-weight: 800;
}
.stage-quote .q-by { display: block; margin-top: 12px; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); }
.stage-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px; padding: 16px; border-radius: var(--r-lg); }
.stage-facts > div { padding: 11px 14px; border-radius: var(--r-sm); }
.stage-facts span { display: block; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 4px; }
.stage-facts b { font-size: 13px; font-weight: 700; color: var(--ink); white-space: nowrap; }
/* 窄一点的桌面上事实卡列宽放不下不换行时，退回换行优先于溢出 */
@media (max-width: 1080px) {
  .stage-facts b { white-space: normal; }
}

/* 首屏磁贴已由侧栏的展开态取代，相关样式一并移除 */

@media (max-width: 900px) {
  .stage-cards { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 720px) {
  body.theme-cyan .hero-stage { padding: 112px 0 92px; min-height: 0; }
  .stage-id { flex-direction: column; gap: 12px; }
  .stage-name { text-align: center; }
  .stage-facts { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- 玻璃案例卡 ---------- */
body.theme-cyan .proj-card {
  background: var(--glass);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  box-shadow: inset 0 0 0 1px var(--glass-line), var(--glass-shadow);
}
body.theme-cyan .proj-card:hover { box-shadow: inset 0 0 0 1px var(--glass-line), 0 34px 66px -34px rgba(10, 80, 110, 0.44); }
body.theme-cyan .proj-media { background: var(--bg-2); }
body.theme-cyan .proj-state.live { color: var(--brand-deep); background: var(--brand-soft); box-shadow: inset 0 0 0 1px var(--brand-line); }
body.theme-cyan .proj-state.live i { background: var(--cyan); }
body.theme-cyan .proj-foot .go { color: var(--brand-deep); }

/* ---------- 玻璃 CTA 横幅（共享类，作用域内改） ---------- */
body.theme-cyan .live-sandbox-banner {
  background: var(--glass);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  box-shadow: inset 0 0 0 1px var(--glass-line), 0 30px 60px -38px rgba(10, 80, 110, 0.36);
}

/* ---------- 关于我：去人像，玻璃化 ---------- */
body.theme-cyan .case-hero { padding: 144px 0 60px; }
body.theme-cyan .about-solo { max-width: 900px; }
body.theme-cyan .about-quote {
  background: var(--glass);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  box-shadow: inset 0 0 0 1px var(--glass-line), 0 24px 50px -34px rgba(10, 80, 110, 0.32);
}
/* ---------- 联系方式：玻璃卡 ---------- */
body.theme-cyan .contact-card-box {
  background: var(--glass);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  box-shadow: inset 0 0 0 1px var(--glass-line), 0 24px 50px -34px rgba(10, 80, 110, 0.32);
}
body.theme-cyan .contact-card-box:hover { box-shadow: inset 0 0 0 1px var(--glass-line), 0 34px 66px -34px rgba(10, 80, 110, 0.42); }
body.theme-cyan .contact-icon-bubble { background: var(--brand-soft); color: var(--brand-deep); }
body.theme-cyan .readiness-banner { background: var(--glass); backdrop-filter: blur(18px) saturate(150%); -webkit-backdrop-filter: blur(18px) saturate(150%); box-shadow: inset 0 0 0 1px var(--glass-line); }

/* ---------- 演示工作台外壳（尺寸不动，只换皮） ---------- */
body.theme-cyan .demo-tab-switcher { background: var(--glass-strong); backdrop-filter: blur(16px) saturate(150%); -webkit-backdrop-filter: blur(16px) saturate(150%); box-shadow: inset 0 0 0 1px var(--glass-edge); }
body.theme-cyan .demo-tab-btn.active { color: var(--brand-deep); }
body.theme-cyan .demo-tip-pill { background: var(--glass-strong); backdrop-filter: blur(14px) saturate(150%); -webkit-backdrop-filter: blur(14px) saturate(150%); box-shadow: inset 0 0 0 1px var(--glass-edge); }
body.theme-cyan .frame-desktop { box-shadow: 0 0 0 1px var(--glass-edge), 0 40px 80px -44px rgba(10, 80, 110, 0.42); }

/* ---------- 揭示动效升级：模糊淡入（只给主页专属元素用） ---------- */
[data-reveal="blur"] {
  translate: 0 14px;
  filter: blur(7px);
  transition:
    opacity var(--dur-long) var(--ease-out) var(--rd, 0ms),
    translate var(--dur-long) var(--ease-out) var(--rd, 0ms),
    filter var(--dur-long) var(--ease-out) var(--rd, 0ms),
    transform var(--dur-short) var(--ease-out),
    box-shadow var(--dur-short) ease;
}
html [data-reveal="blur"] { opacity: 0; }
html [data-reveal="blur"].is-in { opacity: 1; translate: none; filter: none; }
html.no-js [data-reveal="blur"],
html.reduced [data-reveal="blur"] { opacity: 1; translate: none; filter: none; }

/* ---------- 载入动画（首页服务端直出，首帧就在场） ----------
   默认不显示：head 里的内联脚本在本会话第一次整载时给 html 加 .loader-armed，
   它才显示。这样"先加载、后放开场"从第一帧就成立——
   重复访问更不会出现"先看到主页、再闪一下加载层"。 */
.page-loader {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  place-items: center;
  background: var(--bg);
  transition: opacity 520ms var(--ease-out), visibility 520ms linear;
}
html.loader-armed .page-loader { display: grid; }
.page-loader.done { opacity: 0; visibility: hidden; pointer-events: none; }
.page-loader-ring {
  width: 46px; height: 46px;
  border-radius: 50%;
  background: conic-gradient(from 0deg, rgba(18, 169, 201, 0), var(--cyan), var(--blue));
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 4px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 4px));
  animation: pl-spin 900ms linear infinite;
}
@keyframes pl-spin { to { transform: rotate(1turn); } }
html.reduced .page-loader { display: none; }

/* ==========================================================================
   左侧导航轨（由 site.js 注入，body 获得 has-rail 后才生效）
   桌面端取代顶部悬浮岛导航；窄屏回落原顶栏。
   因为隐藏顶栏的规则挂在 has-rail 下，脚本不跑时导航照旧存在。
   着色走各页的 --brand：首页青蓝、Findly 青绿、VPR 靛蓝、Home Hub 亮蓝。
   ========================================================================== */
.side-rail {
  display: none;
  position: fixed;
  left: 18px;
  top: 18px;
  z-index: 100;
  width: 66px;
  height: 476px;
  transform: translateX(0);
  border-radius: 24px;
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.74), 0 20px 46px -24px rgba(10, 80, 110, 0.34);
  /* 位置与尺寸用显式值，才能整体过渡（auto 无法过渡） */
  transition: left 560ms var(--ease-out), top 560ms var(--ease-out),
              width 560ms var(--ease-out), height 560ms var(--ease-out),
              transform 560ms var(--ease-out), border-radius 560ms var(--ease-out);
}
/* 品牌、分隔线、每一项都绝对定位到容器左上角，实际位置由 transform 驱动；
   横向展开 ↔ 竖排收起因此是连续位移，而不是换布局跳一下 */
.rail-brand,
.rail-sep,
.rail-item {
  position: absolute;
  left: 0;
  top: 0;
  transition: transform 560ms var(--ease-out), width 560ms var(--ease-out),
              height 560ms var(--ease-out), padding 560ms var(--ease-out),
              border-radius 560ms var(--ease-out), opacity 260ms var(--ease-out),
              color 220ms var(--ease-out), filter 260ms var(--ease-out);
}
/* 首帧不播动画：注入完成、状态定好之后再去掉 rail-init */
body.rail-init .side-rail,
body.rail-init .rail-brand,
body.rail-init .rail-sep,
body.rail-init .rail-item,
body.rail-init .rail-ic,
body.rail-init .rail-ic svg,
body.rail-init .wrap,
body.rail-init .track,
body.rail-init .demo-stage-wrap { transition: none !important; }
/* 悬停底色不用 background 过渡：background-color 的插值既容易发脏，也不走合成层。
   改成一层 ::before 圆底做 opacity + scale，全程在合成层上，鼠标划过才真的顺。 */
.rail-brand {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: #fff;
  background: linear-gradient(135deg, var(--brand), var(--brand-deep));
  box-shadow: 0 10px 22px -12px color-mix(in srgb, var(--brand) 72%, transparent);
  transform: translate(11px, 12px);
}
/* 悬停不再动 transform —— 那是驱动展开/收起的通道，改投影与亮度 */
.rail-brand:hover {
  box-shadow: 0 16px 30px -14px color-mix(in srgb, var(--brand) 80%, transparent);
  filter: brightness(1.06);
}
.rail-sep {
  width: 22px;
  height: 1px;
  background: var(--line);
  transform: translate(22px, 63px);
}
.rail-nav { display: block; }
.rail-item {
  isolation: isolate;                 /* 让 ::before 的 z-index:-1 留在本元素内 */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  color: var(--ink-2);
  transform: translate(11px, calc(70px + var(--i) * 50px));
}
.rail-item::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: color-mix(in srgb, var(--brand) 14%, transparent);
  opacity: 0;
  transform: scale(0.7);
  transition: opacity 260ms var(--ease-out), transform 260ms var(--ease-out),
              background-color 260ms var(--ease-out), box-shadow 260ms var(--ease-out);
}
.rail-ic {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  transition: background-color 260ms var(--ease-out),
              color 260ms var(--ease-out), margin 560ms var(--ease-out);
}
/* 图标固定显示成 24px：正好是 viewBox 的 1 倍，路径坐标与像素一一对应；
   描边在 JS 里加了 vector-effect="non-scaling-stroke" 并固定为 2px，
   所以不会被非整数缩放渲染成 1.83px 那样的次像素线而发虚 */
.rail-ic svg {
  width: 24px;
  height: 24px;
  stroke: currentColor;
  shape-rendering: geometricPrecision;
  transition: transform 260ms var(--ease-out);
}
/* 标签只在首屏展开态出现，收起态直接不渲染，避免溢出 */
.rail-label { display: none; font-size: 12.5px; font-weight: 600; color: inherit; }
.rail-item:hover { color: var(--brand-deep); }
.rail-item:hover::before { opacity: 1; transform: scale(1); }
.rail-item:hover .rail-ic svg { transform: translateY(-1px) scale(1.06); }
.rail-item.active { color: var(--brand-deep); }
.rail-item.active::before {
  opacity: 1;
  transform: scale(1);
  background: var(--brand-soft);
  box-shadow: inset 0 0 0 1px var(--brand-line);
}
.rail-tip {
  position: absolute;
  left: calc(100% + 12px);
  top: 50%;
  white-space: nowrap;
  font-size: 11.5px;
  font-weight: 600;
  color: #fff;
  background: rgba(14, 26, 36, 0.92);
  padding: 5px 10px;
  border-radius: 8px;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-50%) translateX(-6px) scale(0.96);
  transition: opacity 200ms var(--ease-out), transform 260ms var(--ease-out);
}
.rail-item:hover .rail-tip,
.rail-item:focus-visible .rail-tip { opacity: 1; transform: translateY(-50%) translateX(0) scale(1); }

/* Home Hub 的 body 是 case-hub-modern，缺一组品牌令牌，这里补上给它自己的侧栏 */
body.case-hub-modern {
  --brand: #2563eb;
  --brand-deep: #1d4ed8;
  --brand-soft: #eff6ff;
  --brand-line: rgba(37, 99, 235, 0.2);
}

/* 够宽才用左轨取代顶栏；两个都显示会同时出现两套导航 */
@media (min-width: 1280px) {
  body.has-rail .side-rail { display: flex; }
  body.has-rail .top-navbar { display: none; }
  /* 主页集群：给正文容器让出「左侧」侧栏的宽度，免得文字被轨道压住。
     展开态（rail-hero）侧栏在画面底部居中，不占左侧，所以那时候不加。
     只加左内边距、不动 main，所以氛围舞台这类通栏背景仍是全幅。 */
  body.theme-cyan.has-rail .wrap,
  body.theme-cyan.has-rail .track,
  body.theme-cyan.has-rail .demo-stage-wrap { transition: padding-left 560ms var(--ease-out); }
  body.theme-cyan.has-rail:not(.rail-hero) .wrap { padding-left: calc(40px + 84px); }
  body.theme-cyan.has-rail:not(.rail-hero) .track { padding-left: calc(var(--track-pad) + 84px); }
  body.theme-cyan.has-rail:not(.rail-hero) .demo-stage-wrap { padding-left: calc(24px + 84px); }
}

/* ==========================================================================
   首屏展开态：横向、居中、带说明
   滚过首屏后 body.rail-hero 被移除，回到左上角的竖排图标轨。两态之间会变的
   属性（位置、尺寸、圆角、内边距）都在上面的过渡里，所以是连续「飞」过去。
   ========================================================================== */
body.rail-hero .side-rail {
  left: 50%;
  top: calc(100vh - 172px);
  top: calc(100svh - 172px);
  width: min(864px, calc(100vw - 72px));
  height: 120px;
  transform: translateX(-50%);
  border-radius: 28px;
}
/* 品牌与分隔线让位：向上淡出，把整条让给入口 */
body.rail-hero .rail-brand { opacity: 0; pointer-events: none; transform: translate(11px, -30px) scale(0.7); }
body.rail-hero .rail-sep { opacity: 0; transform: translate(22px, -30px) scaleX(0.4); }
/* 展开态仍是侧栏的简约语言：放大图标 + 一行短标签，
   不加卡片底、不加描述行，靠留白而不是靠信息量 */
body.rail-hero .rail-item {
  width: 96px;
  height: 94px;
  padding: 10px 8px;
  border-radius: 20px;
  transform: translate(calc(12px + var(--i) * 106px), 13px);
}
body.rail-hero .rail-ic {
  margin-bottom: 10px;
}
/* 标签跟随展开浮出。但只在「形态真的在变」时才播（.rail-anim 由 JS 临时挂上）：
   首次加载若也播，到达页会先只有一排图标、0.3s 后标签才冒出来，像是又加载了一次 */
body.rail-hero .rail-label { display: block; white-space: nowrap; }
body.rail-hero.rail-anim .rail-label { animation: rail-text-in 320ms var(--ease-out) 300ms both; }
@keyframes rail-text-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
body.rail-hero .rail-tip { display: none; }

@media (prefers-reduced-motion: reduce) {
  .side-rail, .rail-brand, .rail-sep, .rail-item, .rail-item::before,
  .rail-ic, .rail-ic svg, .rail-tip { transition: none; }
  .rail-item::before { transform: scale(1); }
  .rail-item:hover .rail-ic svg { transform: none; }
  body.rail-hero .rail-label { animation: none; }
}

/* 底栏删除后，窄屏只剩顶栏这一条导航，所以不再让它随滚动隐藏，
   否则滚到下半页就没有任何导航入口了。仅作用于 <1280px。 */
@media (max-width: 1279px) {
  .top-navbar.nav-hidden { transform: none; opacity: 1; }
}

/* ==========================================================================
   精选作品独立页（work.html）
   本页没有首屏，所以第一栏要自己让开固定顶栏的高度
   ========================================================================== */
.works-page { padding: 148px 0 0; }
.works-cta { padding: 58px 0 130px; }

/* ==========================================================================
   跨页时侧栏的接力动画
   离开：侧栏先飞向目标页的形态（site.js 切 .rail-hero），内容同步淡出；
   到达：侧栏已在正确位置，只做内容淡入 —— 两页之间于是是连着的。
   时长与 site.js 里的 NAV_LEAVE_MS（400ms）对齐。
   ========================================================================== */
main { transition: opacity 300ms var(--ease-out); }
body.rail-leaving main { opacity: 0; pointer-events: none; }
/* 到达时首屏从右侧飞入。只动「第一屏那一个 section」——若给整页 main 加位移动画，
   浏览器要为整篇文档建一个合成层（案例页长达 9000px），那正是卡顿的来源 */
body.page-enter main > section:first-of-type { animation: page-side-in 560ms var(--ease-out) both; }
@keyframes page-side-in { from { opacity: 0; translate: 44px 0; } to { opacity: 1; translate: none; } }
body.rail-leaving .side-rail,
body.rail-leaving .rail-brand,
body.rail-leaving .rail-sep,
body.rail-leaving .rail-item,
body.rail-leaving .rail-ic { transition-duration: 400ms; }
/* 离开时总时长只有 400ms，标签不能还用 300ms 延迟，否则跳转那一刻才浮出一半，
   到新页面又突然补齐，反而会「跳」一下 */
body.rail-leaving.rail-hero .rail-label { animation: rail-text-in 200ms var(--ease-out) 140ms both; }

/* ==========================================================================
   首页开场
   类名直接写在 index.html 的 body 上，所以从第一帧就处在起始态，不会先闪一下再播。
   这是一段编排好的整体入场（约 1s）：氛围 → 身份 → 主张 → 说明 → 两块玻璃卡 →
   底部侧栏，依次落位。与案例页那种「几十个元素逐个浮现」不同，它是完整的一段。
   只动 opacity 与 translate，不碰 transform，避免和定位用的 transform 打架。
   ========================================================================== */
body.hero-intro .stage-scene { animation: hi-fade 900ms var(--ease-out) both; }
body.hero-intro .ridge { animation: hi-ridge 1000ms var(--ease-out) both; }
body.hero-intro .ridge.r2 { animation-delay: 80ms; }
body.hero-intro .ridge.r1 { animation-delay: 160ms; }
body.hero-intro .stage-id { animation: hi-rise 640ms var(--ease-out) 140ms both; }
body.hero-intro .stage-quote { animation: hi-rise 720ms var(--ease-out) 440ms both; }
body.hero-intro .stage-facts { animation: hi-rise 720ms var(--ease-out) 520ms both; }

/* 首次整载时，载入动画（.page-loader）还在场：把开场整段先按住，
   等 loader 开始淡出再放开（由 site.js 的 releaseHeroIntro 移除 .hi-hold）。
   旧做法是摘掉 .hero-intro 再 560ms 后加回来 —— 内容会先亮一遍再重播，
   就是「进站像刷新了两次」的来源；现在只暂停、不摘类，放开后是连续的一段。 */
body.hero-intro.hi-hold .stage-scene,
body.hero-intro.hi-hold .ridge,
body.hero-intro.hi-hold .stage-id,
body.hero-intro.hi-hold .stage-quote,
body.hero-intro.hi-hold .stage-facts { animation-play-state: paused; }

@keyframes hi-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes hi-ridge { from { opacity: 0.2; translate: 0 48px; } to { opacity: 1; translate: none; } }
@keyframes hi-rise { from { opacity: 0; translate: 26px 0; } to { opacity: 1; translate: none; } }

/* ==========================================================================
   关于我 / 联系页：首屏不用大字
   标题降到与站内区块标题同一量级，靠行距和留白撑版面而不是靠字号。
   只作用于这两页（body.page-about / body.page-contact），案例页的
   .case-hero-title 与 demo 页的同名类不受影响。
   ========================================================================== */
body.page-about .case-hero-title,
body.page-contact .hero-title {
  font-size: clamp(21px, 2.1vw, 28px);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.36;
}
body.page-contact .hero-title .hero-title-muted {
  margin-top: 10px;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.65;
}
/* 字号收小后，首屏顶部留白也一起收一点，免得看起来空 */
body.page-about .case-hero { padding: 130px 0 40px; }
body.page-contact .contact-hero { padding: 130px 0 44px; }
/* 关于我页：内容列收窄居中
   自述栏（about-solo）与编号区块（工具方式）原先贴着 1600px
   版心的左侧，和居中的 1080px hero 错位；统一收进 1080px 并水平居中，
   长文行宽落在 900px 舒适区 */
body.page-about .case-content-wrap .content-block {
  max-width: 1080px;
  margin-left: auto;
  margin-right: auto;
}
body.page-about .about-solo { margin-inline: auto; }


/* ==========================================================================
   VPR 案例首屏：顶留白收紧
   .case-hero 的 96px 顶部内边距本是为「让开固定顶栏」而留，但宽屏下顶栏
   已被左侧导航轨取代，这 96px 就成了纯空白；顺带把返回按钮那行的下边距
   收一点。窄屏（<1280）顶栏仍在，所以保留足够高度不与它重叠。
   ========================================================================== */
body.case-vpr .case-hero { padding: 86px 0 60px; }
body.case-vpr .case-head { margin-bottom: 22px; }
@media (min-width: 1280px) {
  body.case-vpr .case-hero { padding: 48px 0 60px; }
}

/* ==========================================================================
   案例页组件 v4 · Findly 视觉向 Home Hub 靠拢（f- 前缀，case-findly 专用）
   章节头 = 徽标 + 大标题 + 一句导语（与 hub-section-header 同构）；
   吸顶章节导航（与 hub-subnav 同构，品牌色用 Findly 青绿）；结尾复盘卡。
   ========================================================================== */
.f-subnav {
  position: sticky;
  top: 16px;
  z-index: 80;
  margin: -6px 0 44px;
  pointer-events: none;
}
.f-subnav-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  overflow-x: auto;
  padding: 6px 12px;
  pointer-events: auto;
  scrollbar-width: none;
}
.f-subnav-inner::-webkit-scrollbar { display: none; }
.f-subnav-pill {
  flex: none;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-2, #3E4450);
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(2, 80, 92, 0.10);
  border-radius: 999px;
  padding: 8px 15px;
  text-decoration: none;
  transition: color 0.2s ease, background 0.2s ease, border-color 0.2s ease;
}
.f-subnav-pill:hover { color: var(--brand-deep); border-color: rgba(2, 80, 92, 0.3); }
.f-subnav-pill.active {
  background: var(--brand);
  border-color: var(--brand);
  color: #FFFFFF;
}

.f-section-header { margin: 0 0 clamp(26px, 3.4vw, 40px); }
.f-badge {
  display: inline-block;
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 0.16em;
  color: #0B8F8A;
  background: #E4F5F2;
  border-radius: 999px;
  padding: 6px 14px;
  text-transform: uppercase;
}
.f-section-title {
  margin: 14px 0 10px;
  font-size: clamp(23px, 2.6vw, 31px);
  font-weight: 800;
  color: #14161A;
  letter-spacing: -0.01em;
  line-height: 1.32;
}
.f-section-lead {
  font-size: 15.5px;
  max-width: 640px;
  color: #5B626C;
  line-height: 1.72;
  margin: 0;
}

.f-footer-deck {
  background: #FFFFFF;
  border-radius: 28px;
  padding: clamp(36px, 5vw, 64px) clamp(24px, 4vw, 48px);
  text-align: center;
  border: 1px solid rgba(0, 0, 0, 0.05);
  box-shadow: 0 24px 60px rgba(2, 80, 92, 0.08);
  margin-top: clamp(48px, 6vw, 80px);
}
.f-footer-deck h3 {
  font-size: clamp(21px, 2.4vw, 28px);
  font-weight: 800;
  color: #14161A;
  margin: 16px 0 12px;
  letter-spacing: -0.01em;
}
.f-footer-deck p {
  font-size: 14.5px;
  color: #5B626C;
  max-width: 560px;
  margin: 0 auto;
  line-height: 1.75;
}
.f-footer-actions {
  display: flex;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 26px;
}

/* ==========================================================================
   案例页组件 v5 · Findly 去卡片化：编辑化排版（无框、少底色、留白呼吸）
   f-points   编号索引行（细线分隔，替代 point-grid 白卡）
   f-editorial 双栏纯文字（替代 persona 卡）
   f-callout  左缘细线引言（替代 redline-band 色带）
   f-metrics  无框大数字条（竖细线分隔，替代 result 卡）
   f-ledger   中缝对照账目（替代 ba-compare 双卡）
   ========================================================================== */
.f-editorial {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(24px, 3.4vw, 56px);
  margin-bottom: 36px;
}
.f-editorial h4 {
  margin: 0 0 12px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.14em;
  color: #0B8F8A;
  text-transform: uppercase;
}
.f-editorial p {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.78;
  color: #3E4450;
}
.f-editorial p b { color: #14161A; }
@media (max-width: 760px) { .f-editorial { grid-template-columns: 1fr; } }

.f-points { border-top: 1px solid rgba(20, 22, 26, 0.1); }
.f-point-row {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 18px;
  padding: 19px 0;
  border-bottom: 1px solid rgba(20, 22, 26, 0.1);
  align-items: baseline;
}
.f-point-row .n {
  font-family: var(--font-mono, ui-monospace, "SF Mono", Consolas, monospace);
  font-size: 13px;
  font-weight: 800;
  color: #0B8F8A;
  letter-spacing: 0.06em;
}
.f-point-row h4 { margin: 0; font-size: 16px; font-weight: 800; color: #14161A; }
.f-point-row h4 span {
  margin-left: 10px;
  font-size: 11.5px;
  font-weight: 700;
  color: #0B8F8A;
  background: #E4F5F2;
  padding: 2px 9px;
  border-radius: 999px;
  vertical-align: 2px;
  letter-spacing: 0.02em;
}
.f-point-row p { margin: 6px 0 0; font-size: 13.5px; color: #5B626C; line-height: 1.72; }
@media (max-width: 760px) { .f-point-row { grid-template-columns: 44px 1fr; gap: 12px; } }

.f-callout { border-left: 3px solid #12A5A0; padding: 3px 0 3px 18px; margin-top: 34px; }
.f-callout b {
  display: block;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.12em;
  color: #0B8F8A;
}
.f-callout p { margin: 5px 0 0; font-size: 14.5px; color: #3E4450; line-height: 1.7; }

.f-metrics {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid rgba(20, 22, 26, 0.1);
  border-bottom: 1px solid rgba(20, 22, 26, 0.1);
}
.f-metric { padding: 28px 30px; border-left: 1px solid rgba(20, 22, 26, 0.1); min-width: 0; }
.f-metric:first-child { border-left: 0; padding-left: 0; }
.f-metric .v {
  font-size: clamp(36px, 4vw, 48px);
  font-weight: 800;
  color: #12A5A0;
  letter-spacing: -0.02em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.f-metric .v small { font-size: 15px; font-weight: 800; margin-left: 4px; color: #0B8F8A; }
.f-metric .k { display: block; margin-top: 12px; font-size: 13.5px; font-weight: 800; color: #14161A; }
.f-metric p { margin: 6px 0 0; font-size: 12.5px; color: #717885; line-height: 1.66; }
@media (max-width: 760px) {
  .f-metrics { grid-template-columns: 1fr; }
  .f-metric { border-left: 0; padding: 20px 0; border-top: 1px solid rgba(20, 22, 26, 0.1); }
  .f-metric:first-child { border-top: 0; }
}

.f-ledger {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 clamp(32px, 5vw, 80px);
  margin-top: 48px;
}
.f-ledger::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 4px;
  bottom: 4px;
  width: 1px;
  background: rgba(20, 22, 26, 0.12);
}
.f-ledger-col h5 {
  margin: 0 0 12px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.f-ledger-col.before h5 { color: #9AA0AA; }
.f-ledger-col.after h5 { color: #0B8F8A; }
.f-ledger-col ul { list-style: none; margin: 0; padding: 0; }
.f-ledger-col li {
  position: relative;
  padding: 10px 0 10px 20px;
  font-size: 14px;
  line-height: 1.6;
  color: #3E4450;
  border-bottom: 1px dashed rgba(20, 22, 26, 0.1);
}
.f-ledger-col li:last-child { border-bottom: 0; }
.f-ledger-col.before li { color: #868C97; }
.f-ledger-col li::before { position: absolute; left: 0; font-weight: 800; }
.f-ledger-col.before li::before { content: "—"; color: #C4C9D1; }
.f-ledger-col.after li::before { content: "→"; color: #12A5A0; }
@media (max-width: 760px) {
  .f-ledger { grid-template-columns: 1fr; gap: 30px; }
  .f-ledger::before { display: none; }
}

/* ==========================================================================
   案例页组件 v6 · VPR 去卡片化：规格书式编辑排版（v- 前缀，case-vpr 专用）
   与 Findly 的 f- 体系刻意区分：等宽字 kicker、右对齐词条的规格定义行、
   下划线页签、方角小 chips、真中性炭灰深色结尾卡——呼应桌面工具气质。
   ========================================================================== */
.v-subnav {
  position: sticky;
  top: 16px;
  z-index: 80;
  margin: -6px 0 46px;
  pointer-events: none;
}
.v-subnav-inner {
  display: flex;
  justify-content: center;
  gap: clamp(16px, 2.2vw, 34px);
  overflow-x: auto;
  padding: 10px 12px;
  pointer-events: auto;
  scrollbar-width: none;
  border-bottom: 1px solid rgba(31, 36, 48, 0.12);
}
.v-subnav-inner::-webkit-scrollbar { display: none; }
.v-subnav-link {
  flex: none;
  position: relative;
  font-family: var(--font-mono, ui-monospace, "SF Mono", Consolas, monospace);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #6B7280;
  text-decoration: none;
  padding: 6px 2px 11px;
}
.v-subnav-link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: transparent;
  transition: background 0.2s ease;
}
.v-subnav-link:hover { color: #1F2430; }
.v-subnav-link.active { color: #1F2430; }
.v-subnav-link.active::after { background: #4F5CE5; }

.v-section-header { margin: 0 0 clamp(26px, 3.4vw, 40px); }
.v-kicker {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 0 14px;
  font-family: var(--font-mono, ui-monospace, "SF Mono", Consolas, monospace);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: #4F5CE5;
}
.v-kicker::after { content: ""; flex: 0 0 44px; height: 1px; background: #4F5CE5; opacity: 0.45; }
.v-section-title {
  margin: 0 0 10px;
  font-size: clamp(23px, 2.6vw, 31px);
  font-weight: 800;
  color: #14161A;
  letter-spacing: -0.01em;
  line-height: 1.32;
}
.v-section-lead { font-size: 15.5px; max-width: 660px; color: #5B626C; line-height: 1.72; margin: 0; }

/* 规格定义行：右对齐靛蓝词条 + 说明。无框、无分隔线，只靠对齐与留白。 */
.v-spec { display: grid; grid-template-columns: 1fr 1fr; gap: 4px clamp(32px, 4.5vw, 72px); margin: 0; }
.v-spec-row {
  display: grid;
  grid-template-columns: 118px 1fr;
  gap: 18px;
  padding: 15px 0;
  align-items: start;
}
.v-spec-row dt {
  margin: 0;
  font-size: 14.5px;
  font-weight: 800;
  color: #4F5CE5;
  text-align: right;
  line-height: 1.55;
}
.v-spec-row dd { margin: 0; font-size: 14px; color: #3E4450; line-height: 1.78; }
@media (max-width: 900px) { .v-spec { grid-template-columns: 1fr; } }
@media (max-width: 640px) { .v-spec-row { grid-template-columns: 92px 1fr; gap: 12px; } }

.v-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; }
.v-chips span {
  font-size: 12px;
  font-weight: 600;
  color: #3E4450;
  background: rgba(79, 92, 229, 0.06);
  border: 1px solid rgba(79, 92, 229, 0.18);
  border-radius: 6px;
  padding: 5px 12px;
}
.v-chips-note { font-size: 13px; color: #717885; line-height: 1.7; margin: 0 0 34px; }

.v-deck {
  background: #141414;
  color: #E8E8E8;
  border-radius: 28px;
  padding: clamp(40px, 5.4vw, 72px) clamp(24px, 4vw, 56px);
  text-align: center;
  margin-top: clamp(48px, 6vw, 84px);
}
.v-deck .v-kicker { justify-content: center; color: #8B94FF; margin-bottom: 6px; }
.v-deck .v-kicker::after { display: none; }
.v-deck h3 {
  font-size: clamp(21px, 2.4vw, 28px);
  font-weight: 800;
  color: #FFFFFF;
  margin: 0 0 12px;
  letter-spacing: -0.01em;
}
.v-deck p { font-size: 14.5px; color: #A7ADB8; max-width: 580px; margin: 0 auto; line-height: 1.75; }
.v-deck-actions { display: flex; justify-content: center; gap: 12px; flex-wrap: wrap; margin-top: 28px; }
.v-deck .btn-pill-primary { background: #6270F0; }
.v-deck .btn-pill-secondary { background: transparent; color: #E8E8E8; border-color: rgba(232, 232, 232, 0.28); }
.v-deck .btn-pill-secondary:hover { border-color: rgba(232, 232, 232, 0.6); }

/* ==========================================================================
   案例页组件 v7 · Findly 状态对照轮播（f-fan，形态与 hub-fan 同源）
   中央 1 屏全尺寸 + 两侧 52% 环形队列；裸 UI 无手机框，圆角与投影由容器给出。
   无 JS 兜底：容器默认换行网格，site.js 加 .f-fan--ready 后才进入轮播形态。
   ========================================================================== */
.f-fan {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  margin-top: 6px;
}
.f-fan-item {
  flex: 0 0 calc((100% - 3 * 20px) / 4);
  padding: 10px;
  background: #FFFFFF;
  border: 1px solid rgba(0, 0, 0, 0.06);
  border-radius: 18px;
  cursor: pointer;
}
.f-fan-shot { display: block; border-radius: 12px; overflow: hidden; }
.f-fan-shot img { width: 100%; height: auto; display: block; }
.f-fan-hint,
.f-fan-caption { display: none; }

.f-fan--ready {
  display: block;
  position: relative;
  max-width: 1260px;
  margin: 6px auto 0;
  overflow: hidden;
}
.f-fan--ready .f-fan-item {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--fan-w);
  margin: calc(var(--fan-h) / -2) 0 0 calc(var(--fan-w) / -2);
  padding: 0;
  background: none;
  border: 0;
  border-radius: 16px;
  z-index: 1;
  transition: transform 0.65s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.4s ease, visibility 0s;
}
.f-fan--ready .f-fan-item.is-off {
  opacity: 0;
  visibility: hidden;
  transition: transform 0.65s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.4s ease, visibility 0s linear 0.4s;
}
.f-fan--ready .f-fan-item.is-active { z-index: 2; cursor: default; }
.f-fan--ready .f-fan-item:focus-visible {
  outline: 2px solid #12A5A0;
  outline-offset: 4px;
}
.f-fan--ready .f-fan-shot {
  border-radius: 16px;
  background: #F3F8F8;
  box-shadow: 0 10px 28px rgba(2, 80, 92, 0.10);
  transition: box-shadow 0.4s ease, transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}
.f-fan--ready .f-fan-item.is-active .f-fan-shot {
  box-shadow: 0 28px 64px rgba(2, 80, 92, 0.18);
}
.f-fan--ready .f-fan-shot img {
  width: var(--fan-w);
  height: var(--fan-h);
}
.f-fan--ready .f-fan-item:not(.is-active):hover .f-fan-shot {
  transform: translateY(-8px);
  box-shadow: 0 18px 40px rgba(2, 80, 92, 0.14);
}
.f-fan--ready + .f-fan-hint {
  display: block;
  margin: 14px 0 0;
  text-align: center;
  font-size: 12.5px;
  color: #717885;
}
.f-fan--ready ~ .f-fan-caption {
  display: flex;
  align-items: baseline;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  margin: 18px 0 0;
}
.f-fan-cap-num {
  font-size: 13px;
  font-weight: 800;
  color: #0B8F8A;
  font-variant-numeric: tabular-nums;
}
.f-fan-cap-title { font-size: 15px; font-weight: 800; color: #14161A; }
.f-fan-cap-tag {
  font-size: 11px;
  font-weight: 700;
  color: #0B8F8A;
  background: #E4F5F2;
  padding: 2px 7px;
  border-radius: 6px;
}
.f-fan-cap-desc { font-size: 12.5px; color: #717885; }
.f-fan-caption > * { transition: opacity 0.18s ease, transform 0.18s ease; }
.f-fan-caption.is-swap > * { opacity: 0; transform: translateY(5px); }

@media (max-width: 1040px) { .f-fan-item { flex-basis: calc((100% - 2 * 20px) / 3); } }
@media (max-width: 720px)  { .f-fan-item { flex-basis: calc((100% - 20px) / 2); } }
@media (max-width: 480px)  { .f-fan-item { flex-basis: 100%; } }

@media (prefers-reduced-motion: reduce) {
  .f-fan-item,
  .f-fan-shot,
  .f-fan-caption > * { transition: none !important; }
}

/* ==========================================================================
   手机端导航：顶部悬浮岛收起，侧栏改用「底部图标栏」
   —— 复用侧栏同一套图标、激活底色与玻璃质感，不新造图形；
      手机上不放标签（8 项等分时「Findly 寻物」最长会溢出行宽），
      所在位置由激活态（品牌色 + 浅底胶囊）表达。
   注意：body.rail-hero 的底栏形态是顶层规则（不限宽度），
   首页（首屏 rail-hero）在手机上会被它接管，所以下面用同权重选择器一并覆盖。
   桌面（≥1280 与 721–1279 顶栏形态）完全不动。
   ========================================================================== */
@media (max-width: 720px) {
  body.has-rail .side-rail,
  body.rail-hero .side-rail {
    display: block;
    left: 10px;
    right: 10px;
    top: auto;
    bottom: calc(10px + env(safe-area-inset-bottom, 0px));
    width: auto;
    height: auto;
    transform: none;
    border-radius: 20px;
    transition: none;
  }
  body.has-rail .rail-brand,
  body.rail-hero .rail-brand,
  body.has-rail .rail-sep,
  body.rail-hero .rail-sep { display: none; }        /* 头像与姓名不再常驻 */

  .rail-nav {
    display: grid;
    grid-template-columns: repeat(8, minmax(0, 1fr));
    align-items: center;
    padding: 6px 4px;
  }
  body.has-rail .rail-item,
  body.rail-hero .rail-item {
    position: relative;
    transform: none;
    width: auto;
    height: 46px;
    padding: 0;
    border-radius: 14px;
    transition: color 220ms var(--ease-out);
  }
  .rail-item::before { transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out); }
  .rail-item:hover .rail-ic svg { transform: none; }
  body.rail-hero .rail-ic { margin-bottom: 0; }
  .rail-ic, .rail-ic svg { width: 22px; height: 22px; }
  .side-rail .rail-label,
  body.rail-hero .rail-label { display: none; }
  body.rail-hero.rail-anim .rail-label { animation: none; }
  .rail-tip { display: none; }

  /* 页尾给出图标栏的高度，返回顶部按钮上移让开 */
  main { padding-bottom: 86px; }
  body.theme-cyan .hero-stage { padding-bottom: 8px; }
  .scroll-to-top { bottom: 96px; right: 20px; }
}

/* ==========================================================================
   手机端排版与触控微调（同属 ≤720px，桌面不受影响）
   ========================================================================== */
@media (max-width: 720px) {
  /* 关于我 / 联系页首屏标题：桌面取值 28px，手机落在 21px 下限，层级偏弱 */
  body.page-about .case-hero-title,
  body.page-contact .hero-title { font-size: 25px; }
  /* 精选作品卡的整行链接、联系方式的点击行补足触控高度 */
  .proj-foot .go { min-height: 44px; padding: 0 2px; }
  .contact-card-val { min-height: 44px; display: inline-flex; align-items: center; }
}
