@import url("./typography.css?v=20260908-1");
/* 子页面共用样式（关于我们 / 动态与文章 / 地形实录）
   与 index.html 同一套牌子色，静态页，无 3D。 */
:root {
  --navy: #1a2238;
  --navy-soft: #3c465e;
  --gold: #a8874a;
  --gold-deep: #8f7139;
  --gold-pale: #c2a166;
  --bg: #f2efe8;
  --bg-deep: #e5e0d2;
  --line: rgba(26, 34, 56, 0.16);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  font-family:var(--tevo-cjk);
  color: var(--navy);
  background: var(--bg);
}
.en { font-family:"Cinzel",Georgia,var(--tevo-cjk); }
.nowrap { white-space: nowrap; }
::selection { background: rgba(168, 135, 74, 0.25); }

/* ── 顶栏（子页常驻实底） ── */
header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.9rem 3.4rem;
  background: rgba(242, 239, 232, 0.88);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: 0 1px 0 var(--line);
  transition: background 0.35s ease, box-shadow 0.35s ease;
}
.wordmark {
  font-size: 1.02rem;
  letter-spacing: 0.3em;
  color: var(--navy);
  text-decoration: none;
  white-space: nowrap;
  display: flex;
  align-items: center;
}
.wordmark .mark { height: 1.6em; width: auto; display: block; margin-right: 0.8em; }
.wordmark span { color: var(--gold); margin-left: 0.6em; }
header ul { display: flex; gap: 2.4rem; list-style: none; }
header ul a {
  color: var(--navy-soft);
  text-decoration: none;
  font-size: 0.92rem;
  white-space: nowrap;
  transition: color 0.25s ease;
}
header ul a:hover { color: var(--gold-deep); }
header ul a.here { color: var(--gold-deep); }

/* ── 顶栏下拉：三个产品 ──
   2026-08-18 Jack：「一般是有个下拉然后蹦出来三个对不对」——对，Palantir 顶栏就是这么做的
   （一个顶级项底下挂 AIP / Foundry / Gotham 几个平台名，另外再单独有一个总览页）。
   宽屏鼠标移上去（或键盘 Tab 进去）展开；窄屏没有 hover，三条直接摊在汉堡菜单里。 */
.has-sub { position: relative; }
.submenu {
  position: absolute;
  top: 100%;
  left: 50%;
  margin-top: 0.9rem;               /* 顶栏自己的下内边距，正好让面板贴着顶栏下沿 */
  transform: translateX(-50%) translateY(8px);
  min-width: 21rem;
  padding: 0.35rem 0;
  background: rgba(242, 239, 232, 0.98);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  border: 1px solid var(--line);
  box-shadow: 0 20px 46px -16px rgba(26, 34, 56, 0.42);
  opacity: 0;
  visibility: hidden;
  /* visibility 不走时长、只走延迟：展开时立刻可见，收起时等淡出走完再藏。
     写成 `visibility 0.22s` 会掉进一个坑——标签页在后台时 CSS 过渡整个冻住，
     离散属性 visibility 永远翻不过去，菜单就再也打不开了。 */
  transition: opacity 0.22s ease, transform 0.34s cubic-bezier(0.16, 1, 0.3, 1), visibility 0s linear 0.22s;
}
/* 鼠标从顶栏挪到面板要跨过那 0.9rem 空隙，中间垫一层透明的桥，不然一松手就收起来 */
.submenu::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: -0.9rem;
  height: 0.9rem;
}
.has-sub:hover .submenu,
.has-sub:focus-within .submenu {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
  transition-delay: 0s;
}
.submenu a {
  display: block;
  padding: 0.95rem 1.5rem;
  text-decoration: none;
  transition: background 0.2s ease;
}
.submenu a + a { border-top: 1px solid var(--line); }
.submenu a:hover { background: rgba(168, 135, 74, 0.09); }
.sm-name {
  display: block;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--navy);
  transition: color 0.2s ease;
}
.submenu a:hover .sm-name { color: var(--gold-deep); }
.sm-note {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--navy-soft);
}
/* 顶栏压在首屏深色画面上时，下拉面板仍然是浅底——面板自己是一块纸，不跟着顶栏变透明 */
body.has-hero header:not(.scrolled) .submenu a .sm-name { color: var(--navy); }
body.has-hero header:not(.scrolled) .submenu a:hover .sm-name { color: var(--gold-deep); }
body.has-hero header:not(.scrolled) .submenu a .sm-note { color: var(--navy-soft); }
@media (prefers-reduced-motion: reduce) {
  .submenu { transition: opacity 0.01s, visibility 0.01s; transform: translateX(-50%); }
}
.btn-nav {
  font-family: inherit;
  font-size: 0.9rem;
  color: #f6f3ec;
  background: var(--navy);
  border: none;
  border-radius: 999px;
  padding: 0.6rem 1.6rem;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition: background 0.25s ease, transform 0.25s ease;
}
.btn-nav:hover { background: #232f4e; transform: translateY(-1px); }

/* 汉堡按钮：宽屏藏起来，窄屏才是唯一的进菜单方式 */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 2.4rem; height: 2.4rem;
  margin-left: 0.9rem;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  height: 1.5px;
  width: 1.35rem;
  background: var(--navy);
  transition: transform 0.3s cubic-bezier(0.16,1,0.3,1), opacity 0.2s ease;
}
header.nav-open .nav-toggle span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
header.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
header.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* ── 满屏首图（关于我们）：深蓝底 + 3D logo，大标题压在左下角 ── */
.phero {
  position: relative;
  height: 100svh;
  min-height: 34rem;
  display: flex;
  align-items: flex-end;
  background: var(--navy);
  overflow: hidden;
}
#stage3d { position: absolute; inset: 0; z-index: 0; }
/* touch-action 只能写 pan-y：写 none 的话手指在首屏上下划会被这层画布吃掉，
   整页第一屏就滚不动了。pan-y = 上下交给浏览器滚页，左右还留给拨转 logo */
#stage3d canvas { width: 100%; height: 100%; display: block; cursor: grab; touch-action: pan-y; }
#stage3d canvas:active { cursor: grabbing; }
/* 首屏视频：默认藏着，JS 确认视频真能播了才亮出来（并把 3D 收掉） */
.phero-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 0;
  display: none;
}
html.hero-video-on .phero-video { display: block; }
html.hero-video-on #stage3d { display: none; }
/* 视频画面比纯色底亮，整屏再压一层深蓝，白字才稳稳压得住 */
html.hero-video-on .phero::before {
  content: "";
  position: absolute; inset: 0;
  background: rgba(19, 25, 42, 0.42);
  z-index: 1;
  pointer-events: none;
}
/* 底部压一层渐变，保证大字压在画面上永远读得清 */
.phero::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 46%;
  background: linear-gradient(to top, rgba(19, 25, 42, 0.92), rgba(19, 25, 42, 0));
  z-index: 1;
  pointer-events: none;
}
/* 选择器要压得过 .shell 的 padding 简写，否则底部留白会被清成 0 */
.phero .phero-in { position: relative; z-index: 2; width: 100%; padding-bottom: 5.5rem; }
.phero h1 {
  color: #f6f3ec;
  font-size: clamp(2.8rem, 7.6vw, 6rem);
  line-height: 1.1;
  letter-spacing: 0.02em;
  margin-bottom: 1.6rem;
}
.phero .phero-sub {
  color: rgba(246, 243, 236, 0.82);
  font-size: clamp(1rem, 1.5vw, 1.14rem);
  line-height: 1.95;
  max-width: 40em;
}
.phero .scroll-hint {
  position: absolute;
  right: 3.4rem; bottom: 2.2rem;
  z-index: 2;
  font-size: 0.78rem;
  letter-spacing: 0.24em;
  color: rgba(246, 243, 236, 0.6);
}
/* 首图这一屏顶栏不垫底、字改浅色；滚过去才变回常驻实底 */
body.has-hero header:not(.scrolled) {
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: none;
}
body.has-hero header:not(.scrolled) .wordmark { color: #f6f3ec; }
/* 深色视频首屏上，藏蓝的 logo 图标会隐形，跟字一起翻成米白 */
body.has-hero header:not(.scrolled) .wordmark .mark { filter: brightness(0) invert(0.95); }
body.has-hero header:not(.scrolled) ul a { color: rgba(246, 243, 236, 0.78); }
body.has-hero header:not(.scrolled) ul a:hover,
body.has-hero header:not(.scrolled) ul a.here { color: var(--gold-pale); }
body.has-hero header:not(.scrolled) .btn-nav { color: var(--navy); background: #f6f3ec; }
body.has-hero header:not(.scrolled) .btn-nav:hover { background: #ffffff; }
body.has-hero header:not(.scrolled) .nav-toggle span { background: #f6f3ec; }

/* ── 版式 ── */
main { padding: 9.5rem 0 6rem; }
body.has-hero main { padding-top: 7rem; }
.shell { max-width: 72rem; margin: 0 auto; padding: 0 3.4rem; }
.shell-narrow { max-width: 52rem; margin: 0 auto; padding: 0 3.4rem; }

.rule { width: 3.4rem; height: 2px; background: var(--gold); margin-bottom: 2.4rem; }
h1 {
  font-size: clamp(2.2rem, 4.6vw, 3.6rem);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0.01em;
  text-wrap: balance;
  margin-bottom: 1.4rem;
}
h2 {
  font-size: clamp(1.6rem, 3vw, 2.3rem);
  font-weight: 600;
  line-height: 1.4;
  text-wrap: balance;
}
.gold { color: var(--gold-deep); }
.kicker {
  font-size: 0.8rem;
  letter-spacing: 0.22em;
  color: var(--gold-deep);
  margin-bottom: 1.6rem;
}
p.lead {
  font-size: clamp(1.1rem, 1.9vw, 1.35rem);
  line-height: 2;
  color: var(--navy);
  margin-bottom: 2rem;
}
.prose p {
  font-size: 1.02rem;
  line-height: 2.1;
  color: var(--navy-soft);
  margin-bottom: 1.8rem;
  max-width: 68ch;
}
.prose p strong { color: var(--navy); }
.more {
  display: inline-block;
  margin-top: 0.6rem;
  color: var(--gold-deep);
  text-decoration: none;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--gold);
  padding-bottom: 0.2rem;
}
.more:hover { color: var(--navy); border-color: var(--navy); }

/* ── 定性句：一句话说清我们是什么，比正文重一档 ── */
.claim {
  font-size: clamp(1.35rem, 2.4vw, 1.85rem);
  font-weight: 600;
  line-height: 1.75;
  max-width: 24em;
  text-wrap: balance;
  margin-bottom: 2.6rem;
}

/* ── 图位：照片还没有，先摆一个明摆着是待补的框，不装作有内容 ── */
.photo-slot {
  margin-top: 4.5rem;
  border: 1px dashed rgba(168, 135, 74, 0.55);
  background: rgba(168, 135, 74, 0.05);
  aspect-ratio: 16 / 9;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  text-align: center;
  padding: 1.5rem;
}
.photo-slot .slot-title { font-size: 0.82rem; letter-spacing: 0.22em; color: var(--gold-deep); }
.photo-slot .slot-note { font-size: 0.9rem; color: var(--navy-soft); line-height: 1.9; max-width: 26em; }
.photo-slot img { width: 100%; height: 100%; object-fit: cover; display: block; }
figure.photo-slot figcaption {
  font-size: 0.86rem;
  color: var(--navy-soft);
}

/* ── 关于我们：分屏。深浅交替，中间那屏整幅深蓝，
      正文没图的时候靠色块和名单排版撑住，不靠照片 ── */
body.has-hero main.abt-split { padding-top: 0; }
.abt { padding: 7.5rem 0; }
.abt.dark { background: var(--navy); }
.abt.dark .prose p { color: rgba(246, 243, 236, 0.78); }
.abt.dark .prose p strong { color: #f6f3ec; }
.abt-lead {
  font-size: clamp(1.2rem, 2.2vw, 1.7rem);
  font-weight: 600;
  line-height: 1.85;
  color: #f6f3ec;
  text-wrap: pretty;
}
.abt-note {
  margin-top: 2.6rem;
  font-size: 0.98rem;
  line-height: 2;
  color: rgba(246, 243, 236, 0.66);
  max-width: 40em;
}
/* 六所学校排成名单：一行一所，右边补上学校的英文缩写。
   原来右边放的是城市（NEW YORK / HONG KONG / …），2026-08-17 Jack 说「后面写学校的英文名缩写好了」——
   城市那版有两行都是 HONG KONG，看着像排重了；缩写一行一个、不重样，而且认得出的人一眼就认出来。
   名单本身就是版面，不需要图也不空 */
.schools {
  list-style: none;
  margin: 2.2rem 0 0;
  padding: 0;
  border-top: 1px solid rgba(246, 243, 236, 0.16);
}
.schools li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.2rem;
  padding: 1.05rem 0;
  border-bottom: 1px solid rgba(246, 243, 236, 0.16);
}
.schools .s-name {
  font-size: clamp(1.05rem, 2.1vw, 1.5rem);
  color: #f6f3ec;
  letter-spacing: 0.01em;
}
.schools .s-abbr {
  font-size: 0.74rem;
  letter-spacing: 0.2em;
  color: var(--gold-pale);
  white-space: nowrap;
}

/* 三条能力：不做成一排一模一样的卡片，用通栏横条 + 细线分隔 */
.points { list-style: none; margin: 0; padding: 0; }
.points li {
  display: grid;
  grid-template-columns: 9rem 1fr;
  gap: 0 2.6rem;
  padding: 2.4rem 0;
  border-top: 1px solid var(--line);
}
.points li:last-child { border-bottom: 1px solid var(--line); }
.points .p-key {
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--gold-deep);
  padding-top: 0.42rem;
}
.points p {
  font-size: 1.02rem;
  line-height: 2.1;
  color: var(--navy-soft);
  max-width: 60ch;
}
@media (max-width: 720px) {
  .points li { grid-template-columns: 1fr; gap: 0.7rem; padding: 2rem 0; }
  .points .p-key { padding-top: 0; }
}

/* 三条清单末尾已经有一条线了，收尾区再来一条就是两条线夹一段空白，去掉后者 */
.abt .page-close { margin-top: 4.5rem; padding-top: 0; border-top: none; }

/* 通栏图位：现场照到了放这儿，横图铺满正文宽度 */
.band { margin-top: 4rem; }
/* height:auto 是必须的：<img> 上写了 width/height 属性，浏览器会当成 CSS 高度用，
   把它压过 aspect-ratio，图就按原始像素高度撑开了 */
.band img { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; display: block; }
.band figcaption {
  margin-top: 0.9rem;
  font-size: 0.85rem;
  color: var(--navy-soft);
}
.abt.dark .band figcaption { color: rgba(246, 243, 236, 0.6); }

/* ── 人像墙：一人一张，不拼合照 ── */
.team { margin-top: 5.5rem; }
.team-head {
  font-size: clamp(1.15rem, 1.9vw, 1.45rem);
  font-weight: 600;
  letter-spacing: 0.01em;
  padding-bottom: 1.4rem;
  border-bottom: 1px solid var(--line);
}
.team-grid {
  list-style: none;
  margin: 2.4rem 0 0;
  padding: 0;
  display: grid;
  /* 不写断点：一行塞得下几个由容器宽度自己定，手机自然掉到两列，人加到 13 个也不用改 */
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: 2.2rem 1.6rem;
}
.m-photo {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--bg-deep);
  border: 1px solid var(--line);
}
/* 来源参差是必然的（自拍、证件照、随手拍），统一去色再压一层品牌蓝，
   参差就变成风格；鼠标停上去恢复本色，手机上看到的就是统一那版 */
.m-photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  filter: grayscale(1) contrast(1.04);
  transition: filter 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.m-photo::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--navy);
  mix-blend-mode: color;
  opacity: 0.18;
  pointer-events: none;
  transition: opacity 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.member:hover .m-photo img { filter: none; }
.member:hover .m-photo::after { opacity: 0; }
/* 还没放照片时的占位：明摆着是空的，不装作有内容 */
.m-photo .ph {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-family:"Cinzel",Georgia,var(--tevo-cjk);
  font-size: 1.5rem;
  color: rgba(168, 135, 74, 0.6);
  border: 1px dashed rgba(168, 135, 74, 0.5);
  background: rgba(168, 135, 74, 0.05);
}
.m-name {
  margin: 0.85rem 0 0.2rem;
  font-size: 0.98rem;
  font-weight: 600;
  color: var(--navy);
}
.m-role { margin: 0; font-size: 0.85rem; color: var(--navy-soft); line-height: 1.7; }
@media (prefers-reduced-motion: reduce) {
  .m-photo img, .m-photo::after { transition: none; }
}

/* ── 收尾：一句话 + 按钮 ── */
.page-close {
  margin-top: 7rem;
  padding-top: 3.2rem;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.6rem 2.4rem;
  justify-content: space-between;
}
.page-close p {
  font-size: clamp(1.05rem, 1.7vw, 1.28rem);
  font-weight: 600;
  line-height: 1.85;
  max-width: 26em;
  text-wrap: balance;
}
/* 喂搜索引擎/AI 的实体纠偏话：机器照样读得到，人扫过去不硌眼 */
.fine-print {
  margin-top: 3.2rem;
  font-size: 0.82rem;
  line-height: 1.9;
  color: color-mix(in oklab, var(--navy-soft) 62%, transparent);
  max-width: 42em;
}
.btn-solid {
  font-family: inherit;
  font-size: 0.98rem;
  color: #f6f3ec;
  background: var(--navy);
  border-radius: 999px;
  padding: 0.85rem 2.1rem;
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.25s ease, transform 0.25s ease;
}
.btn-solid:hover { background: #232f4e; transform: translateY(-1px); }

/* ── 条目列表（动态页 / 案例页共用） ── */
.entry {
  padding: 2.6rem 0;
  border-top: 1px solid var(--line);
  display: grid;
  grid-template-columns: 11rem 1fr;
  gap: 2rem;
}
.entry:last-child { border-bottom: 1px solid var(--line); }
.entry .when {
  font-size: 0.86rem;
  color: var(--navy-soft);
  line-height: 1.9;
}
.entry .when .who { display: block; color: var(--gold-deep); font-size: 0.8rem; letter-spacing: 0.06em; }
.entry h3 {
  font-size: 1.3rem;
  font-weight: 600;
  line-height: 1.5;
  margin-bottom: 0.7rem;
}
.entry .tags {
  display: block;
  font-size: 0.78rem;
  font-weight: 400;
  letter-spacing: 0.12em;
  color: var(--gold-deep);
  margin-bottom: 0.8rem;
}
.entry p { color: var(--navy-soft); line-height: 2; max-width: 62ch; }

/* ── 案例页分组 ── */
.group { margin-top: 4.5rem; }
.group .head { display: flex; align-items: baseline; gap: 1.4rem; margin-bottom: 0.6rem; }
.group .head h2 { margin-bottom: 0; }
.group .head .tags { font-size: 0.78rem; letter-spacing: 0.12em; color: var(--gold-deep); }
.group > .line { color: var(--navy-soft); line-height: 2; margin-bottom: 1.4rem; }

/* 现场实录小卡 */
.mini-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 0; border-top: 1px solid var(--line); }
.mini {
  padding: 1.8rem 1.6rem 1.8rem 0;
  border-bottom: 1px solid var(--line);
}
.mini .tag { font-size: 0.72rem; letter-spacing: 0.18em; color: var(--gold-deep); display: block; margin-bottom: 0.7rem; }
.mini h3 { font-size: 1.06rem; font-weight: 600; margin-bottom: 0.5rem; }
.mini p { font-size: 0.94rem; color: var(--navy-soft); line-height: 1.9; }

/* ── 页脚 ── */
footer {
  border-top: 1px solid var(--line);
  margin-top: 6rem;
  padding-top: 2.2rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem 2.6rem;
  justify-content: space-between;
  font-size: 0.82rem;
  letter-spacing: 0.12em;
  color: var(--navy-soft);
}
footer nav { display: flex; gap: 1.8rem; flex-wrap: wrap; letter-spacing: 0.04em; }
footer nav a { color: var(--navy-soft); text-decoration: none; }
footer nav a:hover { color: var(--gold-deep); }

/* ── 进场 ── */
.js .reveal { opacity: 0; transform: translateY(26px); filter: blur(8px); transition: opacity 0.9s cubic-bezier(0.16,1,0.3,1), transform 0.9s cubic-bezier(0.16,1,0.3,1), filter 0.9s cubic-bezier(0.16,1,0.3,1); }
.js .reveal.in { opacity: 1; transform: none; filter: none; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; filter: none; transition: none; }
}

/* 截图排查模式（?flat）：把跟视口高度绑死的首图钉成固定高度，好出整页长图 */
html.flat .phero { height: 34rem; min-height: 0; }
html.flat #stage3d { display: none; }
html.flat .phero-video { display: none; }

/* ── 手机 ── */
@media (max-width: 900px) {
  .nav-toggle { display: flex; }
  /* 菜单收进汉堡里：点开才从顶栏底下滑出来 */
  header ul {
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column;
    gap: 0;
    padding: 0 1.4rem 0.8rem;
    /* 必须不透明：底下是 3D 深蓝 logo 和深色大标题，留 3% 透明度就会隐隐透上来 */
    background: var(--bg);
    box-shadow: 0 14px 28px -18px rgba(26, 34, 56, 0.5), 0 1px 0 var(--line);
    display: none;
  }
  header.nav-open ul { display: flex; }
  header ul li + li { border-top: 1px solid var(--line); }
  header ul a { display: block; padding: 1.05rem 0; font-size: 1rem; }
  /* 窄屏没有 hover：三条产品直接摊开在汉堡菜单里，缩进一格表示从属 */
  .submenu {
    position: static;
    transform: none;
    margin: 0;
    min-width: 0;
    padding: 0;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: none;
    box-shadow: none;
    opacity: 1;
    visibility: visible;
  }
  .submenu::before { display: none; }
  .submenu a { padding: 0.85rem 0 0.85rem 1.2rem; border-top: 1px solid var(--line); }
  .sm-name { font-size: 0.92rem; }
  .sm-note { font-size: 0.76rem; }
}
@media (max-width: 720px) {
  header { padding: 0.9rem 1.4rem; }
  /* 品牌字和按钮都得收一档，不然三样东西在窄屏挤不下、按钮会被顶出屏幕 */
  .wordmark { font-size: 0.88rem; }
  .wordmark .mark { margin-right: 0.6em; }
  .btn-nav { padding: 0.45rem 1.1rem; font-size: 0.84rem; }
  .nav-toggle { margin-left: 0.5rem; }
  .shell, .shell-narrow { padding: 0 1.4rem; }
  main { padding-top: 7.5rem; }
  body.has-hero main { padding-top: 4.5rem; }
  .entry { grid-template-columns: 1fr; gap: 0.6rem; }
  .mini { padding-right: 0; }
  .phero .phero-in { padding-bottom: 3.6rem; }
  .phero .scroll-hint { right: 1.4rem; bottom: 1.4rem; }
  .photo-slot { aspect-ratio: 4 / 3; }
  .page-close { gap: 1.8rem; }
}
/* 小屏（iPhone 一档）：品牌字的宽字距太吃宽度，收窄一点，别把按钮挤出屏幕 */
@media (max-width: 480px) {
  header, header.scrolled { padding-left: 1.1rem; padding-right: 1.1rem; }
  .wordmark { font-size: 0.8rem; letter-spacing: 0.13em; }
  .btn-nav { padding: 0.42rem 0.95rem; font-size: 0.8rem; }
  /* 320 宽的老 iPhone 上汉堡会贴到按钮上，两边各留一点缝 */
  .nav-toggle { margin-left: 0.35rem; margin-right: 0.45rem; }
}

/* ══════════════════════════════════════════════════════════════
   关于我们 · 动效
   只干两件事：让页面活起来、把眼睛往下带。
   不做粒子、不做视差、不做鼠标跟随、不做逐字弹出。

   一条铁规矩：所有 opacity:0 的起手式都锁在 .js 里。
   JS 没跑、被拦、或者爬虫抓页面时，整页照常显示，绝不白屏。
   ══════════════════════════════════════════════════════════════ */

@keyframes rise-mask {
  from { opacity: 0; transform: translateY(0.36em); clip-path: inset(0 0 108% 0); }
  to   { opacity: 1; transform: none;               clip-path: inset(0 0 -30% 0); }
}
@keyframes rise-soft {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
/* 往下点一下就停，2.6 秒一轮。不是装饰，是告诉人这页还有下文 */
@keyframes hint-nudge {
  0%, 72%, 100% { transform: translateY(0); }
  86%           { transform: translateY(7px); }
}

/* ① 首屏：标题从一条线底下升出来（clip-path 遮罩），不是常见的整块淡入。
      大字用排版的方式出场，才配得上衬线体；淡入是 SaaS 弹窗的动作。

   动画挂在 .phero.in 上、不是直接挂在 .phero 上：直接挂就是「进页面演一次」，
   滚下去再滚回顶部不会再演。加上 .in 之后由观察器控制，滚回来重演一遍。
   起手式 opacity:0 单独写在下面，免得 .in 还没加上时大字先闪一下。 */
.js .phero h1,
.js .phero .phero-sub,
.js .phero .scroll-hint { opacity: 0; }

.js .phero.in h1          { animation: rise-mask 1.05s cubic-bezier(0.16, 1, 0.3, 1) 0.25s both; }
.js .phero.in .phero-sub  { animation: rise-soft 0.9s  cubic-bezier(0.16, 1, 0.3, 1) 0.62s both; }
.js .phero.in .scroll-hint {
  animation: rise-soft 0.9s cubic-bezier(0.16, 1, 0.3, 1) 1.15s both,
             hint-nudge 2.6s ease-in-out 2.2s infinite;
}

/* ② 定性句：跟首屏大字同一套遮罩，滚到才升起来。全页最大的字，个性就落在这儿 */
.js .claim.reveal {
  opacity: 0;
  transform: none;
  filter: none;
  clip-path: inset(0 0 108% 0);
  transition: opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1),
              clip-path 1.15s cubic-bezier(0.16, 1, 0.3, 1);
}
.js .claim.reveal.in { opacity: 1; clip-path: inset(0 0 -30% 0); }

/* ③ 配图：慢慢从 1.05 收回原尺寸，底边同时收上来一点。
      不做视差——视差一滚就晕，这个只在进场时动一次，之后完全静止 */
.js .band.reveal { opacity: 1; transform: none; filter: none; }
.js .band.reveal img {
  opacity: 0;
  transform: scale(1.05);
  clip-path: inset(0 0 8% 0);
  transition: opacity 1.1s cubic-bezier(0.16, 1, 0.3, 1),
              transform 1.5s cubic-bezier(0.16, 1, 0.3, 1),
              clip-path 1.2s cubic-bezier(0.16, 1, 0.3, 1);
}
.js .band.reveal.in img { opacity: 1; transform: none; clip-path: inset(0 0 0 0); }

/* ④ 院校名单：一行一行铺开，横线跟着从左边划过去。
      六所学校整块一起淡入是浪费——名单这个形式本身就该有节奏。
      分隔线改用 ::after 才能做划入；border 动不了。 */
.schools li { position: relative; border-bottom: none; }
.schools li::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: rgba(246, 243, 236, 0.16);
  transform-origin: left center;
}
.schools li:nth-child(1) { --d: 0.00s; }
.schools li:nth-child(2) { --d: 0.08s; }
.schools li:nth-child(3) { --d: 0.16s; }
.schools li:nth-child(4) { --d: 0.24s; }
.schools li:nth-child(5) { --d: 0.32s; }
.schools li:nth-child(6) { --d: 0.40s; }
.js .schools.reveal { opacity: 1; transform: none; filter: none; }
.js .schools.reveal li {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.75s cubic-bezier(0.16, 1, 0.3, 1) var(--d),
              transform 0.75s cubic-bezier(0.16, 1, 0.3, 1) var(--d);
}
.js .schools.reveal li::after {
  transform: scaleX(0);
  transition: transform 0.95s cubic-bezier(0.16, 1, 0.3, 1) var(--d);
}
/* 缩写晚半拍再亮，一行里就有了先后，像逐条念出来 */
.js .schools.reveal .s-abbr {
  opacity: 0;
  transition: opacity 0.7s ease-out calc(var(--d) + 0.3s);
}
.js .schools.reveal.in li       { opacity: 1; transform: none; }
.js .schools.reveal.in li::after { transform: scaleX(1); }
.js .schools.reveal.in .s-abbr  { opacity: 1; }

/* ⑤ 三条能力：整行不淡入，改成金线先划过去，再出引导词、再出正文。
      三行同样的淡入是流水线；这样每一条都像被逐条划重点。 */
.points li { position: relative; }
.points li::before {
  content: "";
  position: absolute; top: -1px; left: 0; right: 0; height: 1px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left center;
}
.js .points li.reveal { opacity: 1; transform: none; filter: none; }
.js .points li.reveal::before { transition: transform 1s cubic-bezier(0.16, 1, 0.3, 1); }
.js .points li.reveal .p-key,
.js .points li.reveal p {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);
}
.js .points li.reveal.in::before { transform: scaleX(1); }
.js .points li.reveal.in .p-key  { opacity: 1; transform: none; transition-delay: 0.16s; }
.js .points li.reveal.in p       { opacity: 1; transform: none; transition-delay: 0.26s; }

/* ⑥ 按钮里的箭头：hover 往右挪一点。按钮不改成文字链——文字链没人点 */
.btn-solid .ar {
  display: inline-block;
  margin-left: 0.5rem;
  transition: transform 0.32s cubic-bezier(0.16, 1, 0.3, 1);
}
.btn-solid:hover .ar { transform: translateX(4px); }

/* ⑦ 用户在系统里关了动效就全部收掉：内容直接就位，不是放慢，是不放 */
@media (prefers-reduced-motion: reduce) {
  .js .phero h1,
  .js .phero .phero-sub,
  .js .phero .scroll-hint { animation: none; opacity: 1; transform: none; clip-path: none; }
  .js .claim.reveal,
  .js .claim.reveal.in { opacity: 1; clip-path: none; transition: none; }
  .js .band.reveal img,
  .js .schools.reveal li,
  .js .schools.reveal .s-abbr,
  .js .points li.reveal .p-key,
  .js .points li.reveal p { opacity: 1; transform: none; clip-path: none; transition: none; }
  .js .schools.reveal li::after,
  .js .points li.reveal::before { transform: scaleX(1); transition: none; }
  .btn-solid .ar { transition: none; }
}

/* ══════════════════════════════════════════════════════════════
   关于我们 · 2026-08-17 重排：从头黑到尾，最后一屏才亮
   原来是「浅-深-浅」，首屏视频那股电影感一往下滚就断在米白文档上。
   现在深色一路铺到底，收尾那屏浅底，靠明暗差把「收」这个动作做出来。
   ══════════════════════════════════════════════════════════════ */

/* 幽灵大字要被切在屏幕外，所以这一层必须裁剪 */
.abt { position: relative; overflow: hidden; }
.abt > .shell-narrow, .abt > .shell { position: relative; z-index: 1; }

/* 连着几屏同样是深色，中间那道 padding 会叠成两倍，去掉上面那半 */
.abt.dark + .abt.dark { padding-top: 0; }



/* 出血图：撑满整个屏幕宽，不跟正文栏收窄。深底上压一张亮屏照片，全页对比最强的一处 */
.band.bleed { margin-top: 4.5rem; margin-bottom: 0; width: 100%; }
.band.bleed img { border-radius: 0; }

/* ── 从业背景屏 ──
   这块原来是四个大数字（13/30/6/5）。两轮反馈之后整个换掉了，两条都记下来：
   ① 2026-08-17 Jack：「怪怪的，有点没 get 到」——那时数字是高低错开排的（学抖音那条
      「不对齐也很高级」）。在会动的视频背景上这套不成立，错落读起来像没排齐。
   ② 同日 Jack：「那几个数字很奇怪，是无意义的数字，除了院校之外的 data 都不突出，
      13 位成员也就是个普通小公司，5 个城市更奇怪」——问题不在排版在内容，于是整屏换成
      核心骨干的从业背景。四行字，一行一条，中间用发丝线断开。
   数字那套样式（.figs / .f-num / .f-lab）随内容一起删了；要回退见
   docs/回退-about-静态版-2026-08-17.md。 */
.backs {
  list-style: none;
  margin: 3.2rem 0 0;
  padding: 0;
  border-top: 1px solid rgba(246, 243, 236, 0.18);
}
.backs li {
  padding: 1.5rem 0;
  border-bottom: 1px solid rgba(246, 243, 236, 0.18);
}
.b-name {
  display: block;
  font-size: clamp(1.45rem, 3.2vw, 2.4rem);
  line-height: 1.25;
  letter-spacing: 0.01em;
  color: #f6f3ec;
  text-wrap: balance;
}

/* ── 名单屏：说明文字留在左边，名单整个推到右边。
      三屏用同一根居中窄栏是「没吸引力」的主因之一，这屏故意不居中。 ── */
.split {
  display: grid;
  grid-template-columns: 1fr 1.45fr;
  gap: 0 4.5rem;
  margin-top: 3.4rem;
  align-items: start;
}
.split .abt-note { margin-top: 0; max-width: none; }
.split .schools { margin-top: 0; }

@media (max-width: 860px) {
  .backs li { padding: 1.15rem 0; }
  .split { grid-template-columns: 1fr; gap: 2.2rem; }
}

/* 四行逐条落下来，不是四条一起淡入 */
.backs li:nth-child(1) { --d: 0.00s; }
.backs li:nth-child(2) { --d: 0.09s; }
.backs li:nth-child(3) { --d: 0.18s; }
.backs li:nth-child(4) { --d: 0.27s; }
.js .backs li.reveal {
  transition-delay: var(--d);
  filter: none;
}

/* ══════════════════════════════════════════════════════════
   产品与解决方案（solutions.html）
   2026-08-18 Jack：「这个逻辑是不是有问题，我们应该给产品和解决方案那里单开一页吧」——
   在这之前顶栏那一项是跳首页锚点的，等于点了个栏目名却落到别的页中间，确实不成立。
   这一页和首页那三屏分工不同：首页负责「一眼看懂是什么」，这一页负责
   「对不对得上我、边界在哪」。所以顺序是先认卡点、再看方案，每个方案里
   做什么 → 给谁 → 边界，边界那段单独给了分量。
   ══════════════════════════════════════════════════════════ */

/* ── 先认卡点：三条通栏，不做成三张一模一样的卡片 ── */
.pick {
  list-style: none;
  margin: 2rem 0 0;
  padding: 0;
  border-top: 1px solid var(--line);
}
.pick li {
  padding: 2rem 0;
  border-bottom: 1px solid var(--line);
}
.pick .pick-q {
  display: block;
  font-size: clamp(1.15rem, 2vw, 1.45rem);
  font-weight: 600;
  color: var(--navy);
  margin-bottom: 0.7rem;
}
.pick p {
  font-size: 1rem;
  line-height: 1.95;
  color: var(--navy-soft);
  max-width: 46em;
  margin-bottom: 0.9rem;
}

/* ── 单个方案 ── */
.sol {
  margin-top: 6.5rem;
  padding-top: 3.4rem;
  border-top: 2px solid var(--navy);
}
.sol-name {
  font-size: 0.82rem;
  letter-spacing: 0.22em;
  color: var(--gold-deep);
  margin-bottom: 1.1rem;
}
.sol h2 { margin-bottom: 0.8rem; }
.sol-sub {
  font-size: clamp(1.02rem, 1.6vw, 1.2rem);
  line-height: 1.9;
  color: var(--navy-soft);
  max-width: 42em;
  margin-bottom: 1.5rem;
}
/* H.OS 是当前主推，产品名单独拎出来给一层重量——另外两个方案的标题里没有这一层。
   谁排第一、谁的名字最大，是这一页最先被读到的信息 */
.sol h2 .pname {
  display: inline-block;
  font-size: 1.3em;
  letter-spacing: 0.03em;
  margin-bottom: 0.15em;
}
/* ── 能力标签：这套系统覆盖到哪儿，扫一眼就知道 ──
   不做成小圆角药丸，就是一排细线方块，和下面 .do 那几条横线同一套语言 */
.caps {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin: 0 0 2.6rem;
  padding: 0;
}
.caps li {
  font-size: 0.88rem;
  line-height: 1;
  letter-spacing: 0.03em;
  padding: 0.64rem 0.78rem;
  color: var(--navy);
  background: var(--bg-deep);
  border: 1px solid var(--line);
}
.do {
  list-style: none;
  margin: 0 0 2.8rem;
  padding: 0;
}
.do li {
  padding: 1.15rem 0;
  border-top: 1px solid var(--line);
  font-size: 1.02rem;
  line-height: 2;
  color: var(--navy);
  max-width: 52em;
}
.do li:last-child { border-bottom: 1px solid var(--line); }

/* 「给谁」和「边界」并排。边界那块压一层浅底，是全页唯一有底色的东西——
   我们和「AI 什么都能干」那套说法的分界线就在这儿，值得多给一点分量。
   （不用左边那条竖色条：那是最偷懒的做法。） */
.sol-two {
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  gap: 1.6rem;
  align-items: start;
}
.who, .limit { padding: 1.6rem 1.8rem; }
.who { background: var(--bg-deep); }
.limit { background: var(--navy); }
.w-key, .l-key {
  display: block;
  font-size: 0.76rem;
  letter-spacing: 0.22em;
  margin-bottom: 0.8rem;
}
.w-key { color: var(--gold-deep); }
.l-key { color: var(--gold-pale); }
.who p { font-size: 0.98rem; line-height: 1.95; color: var(--navy-soft); }
.limit p { font-size: 0.98rem; line-height: 1.95; color: rgba(246, 243, 236, 0.82); }
.limit p .gold { color: var(--gold-pale); }

/* ── 收尾：三个方案同一套进场方式 ── */
.sol-close {
  margin-top: 7rem;
  padding-top: 3.2rem;
  border-top: 1px solid var(--line);
}
.sol-close h2 { margin-bottom: 1.4rem; }
.sol-close p {
  font-size: 1.02rem;
  line-height: 2.1;
  color: var(--navy-soft);
  max-width: 58em;
  margin-bottom: 1.4rem;
}

@media (max-width: 860px) {
  .sol-two { grid-template-columns: 1fr; }
  .sol { margin-top: 4.5rem; padding-top: 2.4rem; }
  .who, .limit { padding: 1.4rem 1.5rem; }
}

/* ── 方案页的画面卡：直接复用首页那三张手搓的产品界面示意
   （2026-08-18 Jack 问「动画啊背景图啊产品图啊啥的」——
   方案页要的是「这东西长什么样」，不是背景气氛。首页早就有三张现成的，
   之前一张没用上，等于白做。搬过来，左右交替排，滚到才走动画。
   注意：这仍然是**示意**，不是真截图。真截图能拿到之后应该替掉，见文案总表 A-0n。） */
/* 画面卡（示意产品界面） */
.pvisual { position: relative; }
.vcard {
  background: rgba(255, 254, 251, 0.94);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 1.6rem 1.7rem 1.5rem;
  box-shadow: 0 24px 60px rgba(26, 34, 56, 0.10);
}
.vchip {
  position: absolute;
  top: -0.85rem; left: 1.5rem;
  background: var(--navy);
  color: #f2efe8;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  padding: 0.38rem 0.9rem;
  border-radius: 6px;
  box-shadow: 0 8px 20px rgba(26, 34, 56, 0.25);
}
.vhead {
  display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
  font-size: 0.94rem; font-weight: 600; color: var(--navy);
  margin-bottom: 0.6rem;
}
.vtag { font-size: 0.74rem; font-weight: 400; letter-spacing: 0.06em; color: var(--gold-deep); white-space: nowrap; }
.vrow {
  display: flex; align-items: center; gap: 0.9rem;
  padding: 0.75rem 0;
  border-top: 1px solid rgba(26, 34, 56, 0.07);
  font-size: 0.88rem; color: var(--navy-soft);
}
.vrow .grow { flex: 1; height: 4px; border-radius: 2px; background: rgba(26, 34, 56, 0.08); position: relative; overflow: hidden; }
.vrow .grow i { position: absolute; top: 0; bottom: 0; left: 0; width: var(--w, 60%); background: var(--gold); border-radius: 2px; }
.vrow strong { color: var(--navy); font-weight: 600; }
.vrow em { font-style: normal; font-size: 0.78rem; color: var(--gold-deep); white-space: nowrap; }
.vline {
  padding: 0.75rem 0;
  border-top: 1px solid rgba(26, 34, 56, 0.07);
  font-size: 0.88rem; color: var(--navy);
}
.vline span { display: block; font-size: 0.78rem; color: var(--navy-soft); margin-top: 0.25rem; }
.vfoot { display: flex; justify-content: flex-end; gap: 0.7rem; margin-top: 1.1rem; }
.vbtn {
  font-size: 0.82rem;
  padding: 0.45rem 1.05rem;
  border-radius: 999px;
  background: var(--navy);
  color: #f2efe8;
}
.vbtn.ghost { background: none; border: 1px solid var(--line); color: var(--navy-soft); }
.vgate {
  margin-top: 1.1rem;
  padding: 0.65rem 0.9rem;
  border: 1px dashed var(--gold);
  border-radius: 8px;
  font-size: 0.82rem;
  color: var(--gold-deep);
  text-align: center;
  letter-spacing: 0.04em;
}

/* 方案块改成两栏：文字一边，画面一边，逐块左右对调 */
.sol-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
  gap: 2.6rem 4.5rem;
  align-items: start;
}
.sol:nth-of-type(even) .sol-body .sol-text { order: 2; }
.sol:nth-of-type(even) .sol-body .pvisual { order: 1; }
.sol .pvisual { position: sticky; top: 7.5rem; }
.sol .do { margin-bottom: 2rem; }
.sol .sol-two { grid-template-columns: 1fr; gap: 1rem; }

/* 卡里的数据条滚到了才长出来——「这东西在工作」，不是装饰 */
.js .vrow .grow i { width: 0; transition: width 1.1s cubic-bezier(0.16, 1, 0.3, 1) var(--gd, 0s); }
.js .pvisual.in .vrow .grow i { width: var(--w, 60%); }
.vrow:nth-of-type(1) { --gd: 0.05s; }
.vrow:nth-of-type(2) { --gd: 0.18s; }
.vrow:nth-of-type(3) { --gd: 0.31s; }
@media (prefers-reduced-motion: reduce) {
  .js .vrow .grow i { width: var(--w, 60%); transition: none; }
}
@media (max-width: 980px) {
  .sol-body { grid-template-columns: 1fr; gap: 2.6rem; }
  .sol:nth-of-type(even) .sol-body .sol-text { order: 1; }
  .sol:nth-of-type(even) .sol-body .pvisual { order: 2; }
  .sol .pvisual { position: static; }
}

/* ── 方案页顶屏（2026-08-18 下午改）─────────────────────────────
   Jack：「一开始只是酒店房间，然后你拉下来就有 vr 效果了」。
   所以这一节做得比一屏高，里面钉住一屏：多出来的那一截高度就是「长出来」的行程。
   滚了多少 → js/suite.js 写成 --p（0 ＝ 一间空房间，1 ＝ 工作台全部落位），
   下面每一样东西什么时候出现，全部读这一个数，改节奏不用碰脚本。

   窄屏、以及系统开了减弱动效的：不长，就是一张图加一段字（见最下面那段媒体查询）。
   场景本身的样式在 css/spatial.css，和 suite.html 共用一份。 ── */
.sol-top {
  position: relative;
  height: 250vh;          /* 一屏钉住 + 一屏半的行程 */
  background: #05080f;
}
.sol-pin {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
}
/* 场景铺满这块钉住的屏。cam 自己那句 opacity:0 交给 JS 点亮——
   这一页不能这么干：万一脚本没跑起来，整屏连字都看不见。
   改成用纯 CSS 动画淡入，脚本挂了也还剩「一张图 + 一段字」。

   ⚠️ 淡入必须加在 .cam 上，不能加在 .world 上。
   .world 是 preserve-3d 的容器，一旦它自己带上半透明（哪怕只是动画期间），
   浏览器就把整层压平：照片挂在 z=-980 也会按 1:1 画，纵深、透视、视差全没了。
   .cam 只提供 perspective，自己是 flat 的，加动画不影响里面的三维。
   fill 用 backwards 不用 both：动完就交还给正常值，不留合成层。 */
.sol-pin .cam.sol-cam {
  height: 100%; min-height: 0;
  opacity: 1;
  animation: solWorldIn 1.3s ease 0.15s backwards;
}
.sol-cam { --p: 0; }
@keyframes solWorldIn { from { opacity: 0; } to { opacity: 1; } }

/* 每样东西自己的出场窗口：--dly 什么时候开始，--sp 用多长一段行程走完。
   算出来的 --pp 就是这一样东西自己的 0→1。 */
.sol-cam [data-panel], .sol-cam .core, .sol-cam .links {
  --pp: clamp(0, calc((var(--p) - var(--dly, 0)) / var(--sp, 0.4)), 1);
}
/* 面板：从很深的地方飞进来。位移交给变量，过渡留一点点阻尼，
   所以它是「跟着你的手滚」，不是硬绑在滚动条上一格一格跳。 */
.sol-cam [data-panel] {
  opacity: var(--pp);
  --hz: calc(-460px * (1 - var(--pp)));
  pointer-events: none;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.4s ease, filter 0.5s ease;
}
/* 还没长出来的时候不接鼠标，免得点到一块看不见的玻璃 */
.sol-cam.is-live [data-panel] { pointer-events: auto; }
@media (hover: hover) and (pointer: fine) {
  .sol-cam [data-panel]:hover { --hz: calc(68px - 460px * (1 - var(--pp))); }
}
.sol-cam .deck  { --dly: 0.20; --sp: 0.42; }
.sol-cam .rail  { --dly: 0.30; --sp: 0.40; }
.sol-cam .notes { --dly: 0.34; --sp: 0.40; }
.sol-cam .edge-card { --dly: 0.42; --sp: 0.40; }

/* 中枢：最先亮的一样，从更深处升上来。
   淡入放在环和光晕上，不放在 .core 上——.core 是 3D 容器，
   给它半透明会把里面三个环压成一个平面，装完那一刻会「啪」地弹一下。 */
/* 这一页顶上压着一条顶栏，中枢得比 suite.html 那页站低一点，别顶到字上去 */
.sol-cam .core {
  --cy: -238px;
  --dly: 0.06; --sp: 0.34;
  transform: translate3d(var(--cx), var(--cy), calc(var(--cz) - 520px * (1 - var(--pp))));
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1), filter 0.5s ease;
}
.sol-cam .c-halo, .sol-cam .c-ring { opacity: var(--pp); }
/* 连线最后接上：工作台都到位了，中枢才开始往三个岗位发东西 */
.sol-cam .links { --dly: 0.60; --sp: 0.30; }
.sol-cam .link { opacity: calc(0.85 * var(--o, 1) * var(--pp)); }

/* 压暗层。字还在的时候压得重（白字要压得住），字走了就松开，把房间还回去 */
.sol-scrim {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(6, 10, 20, 0.82) 0%, rgba(6, 10, 20, 0) 26%),
    linear-gradient(90deg, rgba(6, 10, 20, 0.9) 0%, rgba(6, 10, 20, 0.6) 44%,
                           rgba(6, 10, 20, 0.12) 76%, rgba(6, 10, 20, 0.34) 100%);
  opacity: clamp(0.34, calc(1 - 1.5 * var(--p)), 1);
}

/* 标题这一段：房间亮起来的时候它在，工作台开始进场就交棒退场 */
.sol-copy {
  position: absolute; inset: 0; z-index: 4;
  display: flex; align-items: center;
  pointer-events: none;
  opacity: clamp(0, calc((0.40 - var(--p)) / 0.28), 1);
  transform: translate3d(0, calc(-54px * clamp(0, calc((var(--p) - 0.12) / 0.3), 1)), 0);
}
.sol-copy .shell { width: 100%; }
.sol-copy-in {
  max-width: 46rem;
  pointer-events: auto;
  animation: solCopyIn 1s cubic-bezier(0.16, 1, 0.3, 1) 0.3s both;
}
/* ⚠️ 这条是修真 bug（2026-08-19）：标题这一段在 --p 到 0.40 就已经淡成全透明了，
   但「透明」不等于「不在」—— 它照样是最上面那一层，鼠标点下去先被它接走。
   于是工作台上的 H.OS 那张卡怎么点都没反应。
   .sol-cam 在 --p > 0.5 时挂上 is-live（面板这时候才开始接鼠标），
   拿它当开关，让标题这一段在同一刻彻底退出去。滚回去它自己会回来。 */
.sol-cam.is-live .sol-copy { visibility: hidden; pointer-events: none; }
/* 摊平的那一版没有「滚着长出来」这回事，标题就是页面的开头，不能藏。
   现在窄屏下 is-live 本来也上不去，但这条是保险：横过来的短屏、或者以后
   顶屏内容变多，都可能让那段进度算出大于 0.5 来。 */
@media (max-width: 1080px), (max-height: 620px), (prefers-reduced-motion: reduce) {
  .sol-cam.is-live .sol-copy { visibility: visible; pointer-events: none; }
  .sol-cam.is-live .sol-copy-in { pointer-events: auto; }
}
@keyframes solCopyIn { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }
/* ── 顶屏第一眼的旗舰产品那一行（2026-08-19）──
   电脑上：一行带下划线的金色链接，压在正文下面，往下拉时随整段一起退场，
   把入口交给工作台上那张 H.OS 主卡。手机上：换成下面那个实心按钮。
   同一屏永远只出现一个 H.OS 入口。 */
.sol-hero-go { display: none; }
.sol-hero-flag {
  display: inline-flex; align-items: baseline; gap: 0.5rem;
  margin-top: 1.55rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid rgba(194, 161, 102, 0.42);
  color: var(--gold-pale); text-decoration: none;
  font-size: 1.02rem; line-height: 1.5;
  transition: color 0.28s ease, border-color 0.28s ease;
}
/* 名字比这行别的字大一档：整行还是安静的一句话，但「H.OS」自己跳出来。
   不做成第二个大标题——那一屏只讲一件事，标题已经占掉了。 */
.sol-hero-flag b { font-size: 1.32rem; font-weight: 600; letter-spacing: 0.04em; color: #f0e2c4; }
.sol-hero-flag i { font-style: normal; transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1); }
.sol-hero-flag:hover { color: #f6f3ec; border-bottom-color: var(--gold-pale); }
.sol-hero-flag:hover i { transform: translateX(4px); }
.sol-hero-flag:focus-visible { outline: 2px solid var(--gold-pale); outline-offset: 5px; }
.sol-copy .kicker { color: var(--gold-pale); }
.sol-copy .rule { background: var(--gold-pale); }
.sol-copy h1 { color: #f6f3ec; font-size: clamp(2.05rem, 3.4vw, 2.9rem); }
.sol-copy .gold { color: var(--gold-pale); }
.sol-copy p.lead { color: rgba(246, 243, 236, 0.86); }

/* 底下的提示换两次：先是「往下拉」，装完了变成「往下看三个方案」 */
/* 两句提示叠在同一格里交叉淡入淡出。用 grid 不用绝对定位：
   绝对定位的那句会被短的那句挤成三个字宽，中文就竖着断了。 */
.sol-cue {
  position: absolute; left: 50%; bottom: 1.7rem; z-index: 5;
  transform: translateX(-50%);
  pointer-events: none;
  display: grid; justify-items: center;
  font-size: 0.72rem; letter-spacing: 0.24em;
  color: rgba(246, 243, 236, 0.52);
}
.sol-cue span {
  grid-area: 1 / 1;
  white-space: nowrap;
  display: flex; flex-direction: column; align-items: center; gap: 0.6rem;
  transition: opacity 0.4s ease;
}
.sol-cue .cue-a { opacity: clamp(0, calc((0.16 - var(--p)) / 0.14), 1); }
.sol-cue .cue-b { opacity: clamp(0, calc((var(--p) - 0.86) / 0.12), 1); }
.sol-cue i {
  display: block; width: 1px; height: 2rem;
  background: linear-gradient(180deg, rgba(194, 161, 102, 0), var(--gold-pale));
  animation: solCue 2.6s ease-in-out infinite;
  transform-origin: top;
}
@keyframes solCue {
  0%, 100% { transform: scaleY(0.45); opacity: 0.4; }
  50%      { transform: scaleY(1);    opacity: 1; }
}

/* 场景里几块面板在这一页的写法（suite.html 那页有自己的一套，互不影响） */
.sol-cam .rail { --px: -536px; --py: 6px; --pz: -180px; --ry: 21deg; --rx: 2deg; width: 220px; }
.sol-cam .rail .r-key {
  display: block; padding: 4px 12px 9px;
  font-size: 10.5px; letter-spacing: 0.14em;
  color: rgba(194, 161, 102, 0.95);
  font-family:var(--tevo-cjk);
}
/* --py 从 58 挪到 74（2026-08-19）：底下那行文字做成真按钮之后工作台高了近 30px，
   右上角那块 notes 的下沿正好压到工作台上沿。工作台整体往下坐一点，间距就回来了。 */
.sol-cam .deck { --px: 14px; --py: 74px; --pz: 40px; --ry: -1deg; }

/* ── 工作台上 H.OS 是主卡，02/03 是辅助（2026-08-18 晚）──
   要传达的不是「我们有三个东西」，是「我们有一个旗舰产品，同时能往企业平台扩」。
   所以给 01 三样重量：格子更宽、产品名更大、在空间里往人跟前站一步。
   只在这一页生效——suite.html 那版三块还是等宽的。
   ⚠️ 主卡里只放「H.OS」一个词，不再叠一行类别名：叠上去这块会高出 30px，
   整个工作台跟着长高，极端视角下右边那块面板就压到它了。类别名在下面正文里有。
   总宽没变，所以左右两块面板的位置不受影响；连线端点是按布局位置量的，
   不受 transform 影响，会自己跟过来。 */
.sol-cam .deck .mods { grid-template-columns: 1.42fr 1fr 1fr; }
.sol-cam .mod-lead {
  background: rgba(255, 255, 255, 0.085);
  border-color: rgba(194, 161, 102, 0.34);
  transform: translateZ(18px);
}
 /* 用 .mod.mod-lead 而不是 .mod-lead：下面还有一条 .sol-cam .mod .m-name，
     同级别的话靠先后顺序决定胜负，这里必须稳赢 */
.sol-cam .mod.mod-lead .m-name {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 0.03em;
  line-height: 1.1;
  color: #f6f3ec;
}
.sol-cam .deck .d-head h1 { font-size: 18px; }
/* 这一页的三块不是「点开看详情」，是通往下面三节的入口，所以整块就是一个链接 */
.sol-cam .mod { display: block; color: inherit; text-decoration: none; }
.sol-cam .mod .m-go {
  display: block; margin-top: 10px;
  font-size: 11px; color: rgba(194, 161, 102, 0.95);
  font-family:var(--tevo-cjk);
}
/* 这一页左边没有 suite.html 那条长导航压着，右边这块得自己往里收：
   镜头转到最右的时候，原来的位置正好贴到屏幕边 */
.sol-cam .notes { --px: 522px; --py: -240px; --pz: -234px; --ry: -23deg; --rx: 3deg; width: 234px; }
.sol-cam .edge-card { --px: -458px; --py: 258px; --pz: 232px; --ry: 9deg; --rx: -6deg; }

/* ── 窄屏 / 开了减弱动效：不长了，就是一张图加一段字 ──
   下面那三节本来就把三个方案写全了，这里少一块浮空面板不丢任何信息。 */
@media (max-width: 1080px), (max-height: 620px), (prefers-reduced-motion: reduce) {
  .sol-top { height: auto; }
  .sol-pin { position: relative; height: auto; overflow: hidden; }
  .sol-pin .cam.sol-cam {
    position: relative; height: auto; min-height: 88svh;
    display: flex; align-items: center;
    padding: 0; perspective: none; background: #05080f;
  }
  .sol-pin .cam.sol-cam { animation: none; }
  .sol-cam .world, .sol-cam .rig {
    position: absolute; inset: 0; display: block; margin: 0; max-width: none;
    transform: none !important; transform-style: flat;
  }
  .sol-cam .env {
    position: absolute; inset: 0; width: 100%; height: 100%;
    transform: none; opacity: 1;
  }
  .sol-cam [data-panel], .sol-cam .core, .sol-cam .links,
  .sol-cam .motes, .sol-cam .glow, .sol-cam .pool, .sol-cam .air { display: none; }
  .sol-copy {
    position: relative; z-index: 4; width: 100%;
    opacity: 1; transform: none;
    padding: 7rem 0 5rem;
  }
  .sol-cue { display: none; }
  /* 手机上没有工作台，旗舰产品得自己有个入口——换成实心按钮，手指点得中 */
  .sol-hero-flag { display: none; }
  .sol-hero-go {
    display: inline-flex; align-items: center; margin-top: 1.6rem;
    padding: 0.72rem 1.25rem; border-radius: 999px;
    background: var(--gold-pale); color: #101725;
    font-size: 0.9rem; font-weight: 600; text-decoration: none;
    transition: background 0.25s ease, transform 0.12s ease;
  }
  .sol-hero-go:active { background: #d8bd84; transform: scale(0.97); }
  .sol-scrim { opacity: 1; background: linear-gradient(180deg,
    rgba(6, 10, 20, 0.8) 0%, rgba(6, 10, 20, 0.38) 34%, rgba(6, 10, 20, 0.6) 100%); }
}
/* 手机上标题要再收一档，不然「不是三套软件」会断在「三套」后面 */
@media (max-width: 560px) {
  .sol-copy h1 { font-size: clamp(1.6rem, 6.6vw, 2.2rem); }
  .sol-copy { padding: 6rem 0 4.5rem; }
}
@media (prefers-reduced-motion: reduce) {
  .sol-copy-in { animation: none; opacity: 1; transform: none; }
  .sol-cue i { animation: none; transform: scaleY(1); }
}

/* 方案页顶屏是满屏图，main 不能再垫上边距 */
body.sol-page main { padding-top: 0; }

/* 工作台那块玻璃上的标题和三个名字：只走样式，不占文档骨架
   （这一页真正的 h1 是顶上那段，h2 是下面三节，别让一块视觉索引抢走） */
.sol-cam .deck .d-title {
  font-size: 18px; font-weight: 600; letter-spacing: 0.01em;
  margin: 0; line-height: 1.2;
}
.sol-cam .mod .m-name { display: block; font-size: 14.5px; font-weight: 600; line-height: 1.35; }
/* 连线的过渡要自己写一份：spatial.css 里那句带 1.3 秒延迟，
   那是给 suite.html 的开页进场用的，跟着滚动走的话会慢一整拍 */
.sol-cam .link { transition: opacity 0.5s ease; }

/* ── 点 H.OS 离场（2026-08-19）──
   从大厅走进 H.OS 那一下：这一屏压暗、镜头往前推半步，落地页那边从黑里推出来。
   两段接上才是"穿过去"。CSS 只管这半段，另半段在 css/hos.css 的 .hos-pin::after。 */
/* ═══════ 点 H.OS：不是「跳走」，是「这一层收起来，另一层点起来」 ═══════
   ⚠️ 2026-08-19 重写。原来这里把整屏 opacity→0 + brightness(0.5) + scale(1.09)，
   淡成一片黑再跳页。那恰恰是客户点名不要的那种感觉：「离开了当前环境」。

   现在反过来。这 0.56 秒里：
     · 房间一动不动，也不压暗 —— 它是接下来那一页的第一帧，不能变
     · 只有工作台上那几块玻璃往深处退回去（--hz: -320px），
       和它们当初飞进来的方向正好相反，读起来是「这一层收起来了」
     · 房间同时极轻微地往前推 0.028 —— hos.html 落地后会从 1.028 继续往前推到 1.062，
       两页的推镜是接着的一镜，不是两段
   下一页画的是同一张 suite.jpg、同一个 z=-980、同一套灯光，所以那一刀看不出来。 */
body.is-entering { overflow: hidden; }

body.is-entering .sol-cam [data-panel] {
  transition: opacity 0.4s ease, transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
  opacity: 0;
  --hz: -320px;
}
/* 房间：只推，不暗、不淡。scale 是独立属性，和 .env 自己那条 transform 叠加，不打架 */
body.is-entering .sol-cam .env {
  transition: scale 0.85s cubic-bezier(0.4, 0, 0.2, 1);
  scale: 1.028;
}
/* 还没往下拉就点了（顶屏那行「旗舰产品 H.OS」）：工作台本来就还没进场，
   这时候要退场的是标题那一段，不然它会硬切 */
body.is-entering .sol-copy,
body.is-entering .sol-cue { transition: opacity 0.36s ease; opacity: 0; }
body.is-entering > main > .shell { transition: opacity 0.4s ease; opacity: 0; }
body.is-entering header { transition: opacity 0.4s ease; opacity: 0; }
/* ⚠️ 这一条是修一个真的会被看见的接缝。.sol-scrim 常态是 clamp(.34, 1 − 1.5·--p, 1)：
   拉到底才是 .34，而顶屏那两个「旗舰产品 H.OS」入口是在 --p = 0 上点的，那时它是 1.0
   —— 房间被压得很暗。hos.html 那边没有对应的层，于是切过去房间会整个亮一大档，
   一眼就知道换页了。这半秒里把它统一锁到 .28（= hos 首帧的值），
   顺带把「灯慢慢亮起来」这一下并进离场动作里。 */
body.is-entering .sol-scrim { transition: opacity 0.5s cubic-bezier(0.4, 0, 0.2, 1); opacity: 0.28; }
@media (prefers-reduced-motion: reduce) {
  body.is-entering .sol-cam [data-panel],
  body.is-entering .sol-cam .env,
  body.is-entering .sol-copy,
  body.is-entering .sol-cue,
  body.is-entering > main > .shell,
  body.is-entering header { transition: none; opacity: 1; transform: none; filter: none; scale: 1; }
}

/* ═══════ 工作台上那三块：按真按钮的规矩来（2026-08-19，Jack：「点击逻辑要更像真实 UI」）═══════

   原来这三块是从 suite.html 抄过来的「点一下就地展开」的卡片，
   所以右上角挂着一个「＋」。可这一页它们根本不展开——它们是跳走的：
   01 跳到 hos.html，02/03 跳到本页下面两节。「＋」在这儿是句假话。

   一个能点的东西，人要在四个时刻都收到回应：
     看见（这是个按钮）→ 悬停（我瞄准了）→ 按下（我按到了）→ 松开（它在动了）
   下面这一段就是把这四下补齐。 */

/* ── 看见：右上角的「＋」换成箭头 ──
   ＋＝就地展开，→＝会走到别处。这一页是后者。 */
.sol-cam .m-plus { transition: opacity 0.3s ease, transform 0.35s cubic-bezier(0.16, 1, 0.3, 1); }
.sol-cam .m-plus::before { width: 10px; margin: -0.5px 0 0 -5px; }
.sol-cam .m-plus::after {
  width: 6px; height: 6px; margin: -3px 0 0 -1px;
  background: none;
  border-top: 1px solid var(--gp); border-right: 1px solid var(--gp);
  transform: rotate(45deg);
}
.sol-cam .mod:hover .m-plus { transform: translateX(3px); }
.sol-cam .mod:active .m-plus { transform: translateX(5px); }

/* ── 看见 ②：底下那行字做成真按钮 ──
   一行光秃秃的「进入 H.OS 运营中枢 →」看着像说明文字，不像能按的东西。
   给它边框、给它底、给它一个圈——人一眼就知道这是个按钮。
   主卡（H.OS）用实心金：整页只有这一个实心按钮，主次一目了然。 */
.sol-cam .mod .m-go {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 9px; padding: 5px 12px;
  border: 1px solid rgba(194, 161, 102, 0.4);
  border-radius: 999px;
  background: rgba(194, 161, 102, 0.07);
  font-size: 10.5px; line-height: 1.15;
  color: rgba(194, 161, 102, 0.98);
  transition: background 0.28s ease, border-color 0.28s ease, color 0.28s ease, transform 0.2s ease;
}
.sol-cam .mod:hover .m-go {
  background: rgba(194, 161, 102, 0.18);
  border-color: rgba(194, 161, 102, 0.78);
  color: #f6f3ec;
}
.sol-cam .mod-lead .m-go {
  background: var(--gold-pale); border-color: var(--gold-pale);
  color: #101725; font-weight: 600;
}
.sol-cam .mod-lead:hover .m-go {
  background: #d8bd84; border-color: #d8bd84; color: #101725;
}

/* ── 按下：整块往回压一下 ──
   悬停是 translateZ(34px)（浮起来），按下就得比悬停低，人才觉得「按进去了」。
   过渡时间压到 0.08s：按下的反馈必须是即时的，慢一帧就不像按钮了。 */
.sol-cam .mod:active,
.sol-cam .mod.is-press {
  transform: translateZ(12px) scale(0.985);
  transition-duration: 0.08s;
  background: rgba(255, 255, 255, 0.12);
}
.sol-cam .mod:active .m-go,
.sol-cam .mod.is-press .m-go { transform: scale(0.97); }

/* ── 松开：这一下开始走了 ──
   点 H.OS 之后整页要压暗 0.6 秒再跳（body.is-entering）。这 0.6 秒里
   得让被点的那块自己亮着、往前站，不然人会以为「我是不是没点上」。
   .is-going 由 solutions.html 里那段 [data-enter] 的脚本挂上。 */
.sol-cam .mod.is-going {
  transform: translateZ(58px) scale(1.02);
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(194, 161, 102, 0.85);
  transition: transform 0.55s cubic-bezier(0.16, 1, 0.3, 1), background 0.3s ease, border-color 0.3s ease;
}
.sol-cam .mod.is-going .m-go { transform: none; }
/* 被点的那块往前，其余的往后退开 —— 和 is-focus 是同一套语言 */
.sol-cam .mods.has-going .mod:not(.is-going) { opacity: 0.28; filter: blur(2px); }

/* 键盘也要有：Tab 到这块的时候，人得看得见自己站在哪 */
.sol-cam .mod:focus-visible { outline: 2px solid var(--gp); outline-offset: 4px; }

@media (prefers-reduced-motion: reduce) {
  .sol-cam .mod:active, .sol-cam .mod.is-going { transform: none; }
  .sol-cam .m-plus, .sol-cam .mod .m-go { transition: none; }
}
