/* ============================================================
   言一设计工作室 · YANE DESIGN
   共享设计系统 / Design System
   ------------------------------------------------------------
   基调：极简 · 单强调色 · 发丝线 · 无阴影
   配色：纯白画布 + 墨黑字 + 品牌绿(唯一强调色) + 胡桃木(关键节点)
   字体：中文衬线标题 + 无衬线正文
   栅格：8pt 基准
   动效：慢速淡入 + 极轻位移，克制不弹跳
   ------------------------------------------------------------
   改版记录 2026-10-01 —— 参照 DeepSeek 官方色板重构
     · 画布 #F7F5F0 → #FFFFFF（纯白，对位 DeepSeek #FFFFFF）
     · 强调色 #6B7F6E → #2E8A3C（保留 129° 本色相，饱和度由 9% 提到 50%，
       以对位 DeepSeek 蓝 #4D6BFE 的 99% 饱和度 —— 只换色相不提饱和
       会让人在纯白底上显得发闷）
     · 深色块 #1C1C1A → #0E2511（深绿，对位 DeepSeek #0A0A23）
     · 去阴影 / 去装饰光斑 / 去呼吸动画；按钮圆角 8px、卡片 12px
   ------------------------------------------------------------
   改色只需改本文件顶部这一段，全站自动跟随。

   兼容策略：旧令牌名（--paper / --olive / --ink…）保留为「别名」指向新值，
   全站数百处旧引用因此无需逐个改名。将来若要迁移到新语义名，
   删掉「兼容别名」那一段即可，但必须同步替换所有引用处。
   ============================================================ */

/* ---------- 1. Design Tokens ---------- */
:root {
  /* ===== 画布与面 ===== */
  --bg:            #FFFFFF;   /* 主画布 —— 对位 DeepSeek #FFFFFF */
  --bg-2:          #F5FAF6;   /* 次级面 —— 对位 DeepSeek #F5F7FB */
  --bg-3:          #F9FBF9;   /* 更浅的分区面 */
  --bg-neutral:    #F4F5F4;   /* 中性浅灰，用于无彩底（标签等） */

  /* ===== 文字 ===== */
  --text:          #1A1A1A;   /* 主文字 —— 对位 DeepSeek #1A1A1A */
  --text-2:        #4A4A4A;   /* 次级文字 */
  --text-3:        #8A8A8A;   /* 弱化文字 / 说明 */

  /* ===== 线（发丝级）===== */
  --line:          #E3E7E3;   /* 分隔线 —— 对位 DeepSeek #E5E7EB */
  --line-soft:     #EEF1EE;   /* 更弱的分隔线 */

  /* ===== 品牌强调色（全站唯一）===== */
  --accent:        #2E8A3C;   /* 品牌绿 —— 对位 DeepSeek #4D6BFE */
  --accent-deep:   #246B2E;   /* hover 深 */
  --accent-wash:   #EBF9ED;   /* 淡底 —— 对位 DeepSeek #EAEEFE */
  --accent-line:   #B5E3BC;   /* 描边 */
  --accent-on-dark:#45C458;   /* 深色块上的绿（提亮以保对比）*/

  /* ===== 深色块 ===== */
  --ink-block:     #0E2511;   /* 深绿块 —— 对位 DeepSeek #0A0A23 */

  /* ===== 胡桃木 · 仅用于「关键节点」标记 ===== */
  --walnut:        #A8927A;
  --walnut-deep:   #8C7761;
  --walnut-wash:   #F7F3EC;

  /* ===== 语义色（克制使用）===== */
  --ok:            #3E7A46;
  --warn:          #B08344;
  --muted:         #999999;

  /* ============================================================
     兼容别名 —— 旧令牌名指向新值
     ⚠️ 这一段是给全站旧引用用的过渡层，不要在这里改色值，
        要改颜色请改上面的新令牌。
     ============================================================ */
  --paper:         var(--bg);        /* 原 #F7F5F0 → 纯白 */
  --paper-2:       var(--bg);        /* 卡片面：原即 #FFFFFF，保持 */
  --paper-3:       var(--bg-2);      /* 原 #EFEBE3 分区米白 → 浅绿灰 */
  --ink:           var(--text);      /* 原 #1C1C1A */
  --ink-2:         var(--text-2);    /* 原 #4A4945（去暖调）*/
  --ink-3:         var(--text-3);    /* 原 #8A8880（去暖调）*/
  --olive:         var(--accent);
  --olive-deep:    var(--accent-deep);
  --olive-wash:    var(--accent-wash);

  /* ===== 字体 ===== */
  --font-display: "Source Han Serif SC", "Noto Serif SC", "Songti SC", "STSong", "SimSun", serif;
  --font-body:    "Source Han Sans SC", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", "Hiragino Sans GB", sans-serif;
  --font-latin:   "Optima", "Palatino Linotype", "Georgia", "Times New Roman", serif;

  /* ===== 8pt 栅格 ===== */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px;
  --s9: 96px; --s10: 128px;

  /* ===== 圆角（照 DeepSeek：按钮 8px / 卡片 12px）===== */
  --r-xs: 4px;
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-pill: 999px;

  /* ===== 阴影：极弱，仅用于浮起 ===== */
  --sh-1: 0 1px 2px rgba(16, 24, 16, .04);
  --sh-2: 0 2px 6px rgba(16, 24, 16, .05);
  --sh-3: 0 4px 14px rgba(16, 24, 16, .07);

  /* ===== 浮层背景模糊 / 压暗（弹窗打开时）=====
     遮罩层自身 background 必须是 transparent —— 不铺任何 rgba。
     要压暗就走 backdrop-filter 的 brightness()：它只降明度、不动色相与饱和度，
     是唯一能"变暗但色调不变"的做法；铺黑/灰 rgba 会同时改色相或饱和度。

     2026-10-02 第二次调（用户：模糊减到一半；另加一点压暗、但别太多）：
       模糊全线 ×0.5（10/14/16/26 → 5/7/8/13）；
       新加 --dim —— 此前是纯模糊、零压暗，用户反馈"背景暗度完全没变"，补一点亮度压制。
     ⚠️ 改力度只动这一段，全站四个浮层跟随。 */
  --blur-1:        5px;    /* 保存预览框 .pv */
  --blur-2:        7px;    /* 三栏风格弹窗 .sm */
  --blur-3:        8px;    /* 十轮二选一 .st */
  --blur-beneath:  13px;   /* 叠层时位于下面那层：只加深模糊来拉开前后（不带 brightness，见下）*/
  --dim:           .94;    /* 背景压暗：只降明度、不改色相（1 = 不压暗）*/

  /* ===== 动效：慢速，克制 ===== */
  --ease: cubic-bezier(.22,.61,.36,1);
  --ease-out: cubic-bezier(.16,1,.3,1);
  --dur-fast: .25s;
  --dur: .5s;
  --dur-slow: .9s;

  /* ===== 版心 ===== */
  --wrap: 1200px;
  --wrap-narrow: 880px;
  /* 2026-10-01 导航放大一档：字 14.4→16px、logo 26→32px，76px 会显得挤，加到 86px */
  --nav-h: 86px;
}

/* ---------- 2. Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-wrap: pretty;
}
img, svg, video { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; border: none; background: none; }
input, textarea { font: inherit; color: inherit; }
h1,h2,h3,h4,h5 { margin: 0; font-family: var(--font-display); font-weight: 500; line-height: 1.25; letter-spacing: .01em; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
::selection { background: var(--accent); color: #fff; }

/* ---------- 3. 版心与栅格 ---------- */
.wrap { width: min(100% - 48px, var(--wrap)); margin-inline: auto; }
.wrap-narrow { width: min(100% - 48px, var(--wrap-narrow)); margin-inline: auto; }
.section { padding-block: var(--s9); }
.section-tight { padding-block: var(--s7); }

/* ---------- 4. 排版 ---------- */
.display {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 6vw, 4.6rem);
  line-height: 1.12;
  letter-spacing: .012em;
  font-weight: 500;
}
.h1 { font-size: clamp(1.9rem, 3.6vw, 2.9rem); }
.h2 { font-size: clamp(1.5rem, 2.6vw, 2.1rem); }
.h3 { font-size: clamp(1.15rem, 1.8vw, 1.4rem); }
.lead {
  font-size: clamp(1rem, 1.4vw, 1.125rem);
  color: var(--text-2);
  line-height: 1.75;
}
.eyebrow {
  font-family: var(--font-body);
  font-size: .75rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 500;
}
.eyebrow-latin { font-family: var(--font-latin); }
.muted { color: var(--text-3); }
.serif { font-family: var(--font-display); }
.latin { font-family: var(--font-latin); }

/* 装饰性短横线 */
.rule { height: 1px; background: var(--line); border: 0; margin: 0; }
.rule-ink { height: 1px; background: var(--ink); border: 0; margin: 0; }

/* 章节标题组合 */
.sec-head { margin-bottom: var(--s7); }
.sec-head .eyebrow { display: block; margin-bottom: var(--s3); }
.sec-head h2 { margin-bottom: var(--s3); }
.sec-head p { color: var(--text-2); max-width: 60ch; }

/* ---------- 5. 导航 ---------- */
.nav {
  position: sticky; top: 0; z-index: 100;
  height: var(--nav-h);
  background: rgba(255,255,255,.88);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.nav.is-scrolled { border-bottom-color: var(--line); }
.nav-inner {
  height: var(--nav-h);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s5);
  /* ★ 2026-10-08（用户定）：定位基准 —— 让 .nav-links 能脱离这条 flex 流、钉死在版心正中。
     ⚠️ 这句话是给下面那条绝对定位兜底的，别删。 */
  position: relative;
}
.nav-logo { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.nav-logo img { height: 32px; width: auto; }
.nav-logo .cn {
  font-family: var(--font-display); font-size: 1.0625rem;
  letter-spacing: .18em; color: var(--ink); white-space: nowrap;
}
/* ★ 2026-10-08（用户定）：6 项导航**钉在版心正中**，所有页面同一位置。
   改前：`.nav-inner` 是 justify-content:space-between，导航项落在「logo 右缘 →（登录）左缘」
        这段空档的正中 —— 于是位置随左右两侧内容漂移：
        首页 / 我的需求（右上角有「登录」）偏右约 20px；
        我的家 / 服务流程 / 案例实景 / 工地实况 / 两个详情页（右上无按钮）**被推到最右**。
   改后：脱离 flex 流 + 绝对定位到 50%，logo 贴左、登录贴右都不再影响它。
   ⚠️ `top:50% + translate(-50%,-50%)` 这两个 50% 缺一不可 —— 只写 left 的话，
      元素会退回「静态位置」掉到导航条顶上；只写 left 而漏 top 同理。
   ⚠️ ≤860px 时下面那条 `display:none` 照旧生效（导航收进汉堡），移动端不受影响。
   ⚠️ 验收：.cache/verify-nav.js 第 6 节新增「跨页导航中心 x 一致」断言，别删。 */
.nav-links {
  display: flex; align-items: center; gap: var(--s5);
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
}
.nav-link {
  font-size: 1rem; color: var(--text-2); position: relative;
  padding-block: 6px; transition: color var(--dur-fast) var(--ease);
  white-space: nowrap;
}
.nav-link::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: 0;
  height: 1px; background: var(--accent); transition: right var(--dur) var(--ease-out);
}
.nav-link:hover { color: var(--text); }
.nav-link:hover::after, .nav-link.is-active::after { right: 0; }
.nav-link.is-active { color: var(--text); }
/* 墓碑（2026-10-08）：这里曾有 `.nav-cta`「聊聊我的房子」那颗描边按钮。
   用户口径 —— 首页与我的需求页的右上角**只留一颗深色的「登录」**，CTA 整体退役
   （另一条理由：它在「我的需求」页上是**指向自己的链接**）。
   它没白删：**几何**（r-sm 圆角 / 11+22 内距 / 15px 字）被 `.nav-login` 继承，
   **配色**变成 `.nav-login` 的默认态（＝原来那条 `:hover`）。
   ⚠️ 别再往导航条上加回这颗按钮；DOM 侧也已从 `site.js` 摘掉。 */
.nav-toggle { display: none; width: 40px; height: 40px; align-items: center; justify-content: center; }
.nav-toggle span { display: block; width: 20px; height: 1px; background: var(--ink); position: relative; }
.nav-toggle span::before, .nav-toggle span::after {
  content: ""; position: absolute; left: 0; width: 20px; height: 1px; background: var(--ink);
  transition: transform var(--dur-fast) var(--ease);
}
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after { top: 6px; }

/* 移动端抽屉 */
.nav-drawer {
  position: fixed; left: 0; right: 0; top: var(--nav-h); z-index: 99;
  /* ⚠️ 绝不能用 `inset: var(--nav-h) 0 0 0`！
     .nav 上有 backdrop-filter（毛玻璃），它会为 position:fixed 的子孙**建立包含块**。
     于是 bottom:0 变成贴着 .nav 自己那条 70px 的底边，而不是视口底边 ——
     抽屉被压成 48px 的一条细缝（--nav-h=64 时算出来是 0，彻底看不见），
     手机端菜单等于打不开（2026-10-01 实测 elementFromPoint 命中的是页面正文）。
     改成显式高度，不依赖包含块。dvh 让移动端地址栏收放时高度不跳。 */
  height: calc(100vh - var(--nav-h));
  height: calc(100dvh - var(--nav-h));
  background: var(--bg); padding: var(--s5);
  transform: translateY(-8px); opacity: 0; pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.nav-drawer.is-open { opacity: 1; transform: none; pointer-events: auto; }
.nav-drawer a {
  display: block; padding: var(--s4) 0; border-bottom: 1px solid var(--line-soft);
  font-family: var(--font-display); font-size: 1.25rem;
}
.nav-drawer a .en { display: block; font-family: var(--font-latin); font-size: .72rem; letter-spacing: .2em; color: var(--text-3); margin-top: 2px; }

/* ---------- 6. 按钮 ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 14px 28px; border-radius: var(--r-sm);
  font-size: .9375rem; letter-spacing: .05em;
  border: 1px solid transparent;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--text); color: var(--bg); }
.btn-primary:hover { background: var(--accent); color: #fff; }
.btn-olive { background: var(--accent); color: #fff; }
.btn-olive:hover { background: var(--accent-deep); }
.btn-ghost { border-color: var(--text); color: var(--text); }
.btn-ghost:hover { background: var(--text); color: var(--bg); }
.btn-soft { border-color: var(--line); color: var(--text-2); background: transparent; }
.btn-soft:hover { border-color: var(--accent); color: var(--accent); }
.btn-sm { padding: 9px 18px; font-size: .8125rem; }
.btn-block { width: 100%; }
.btn:disabled { opacity: .45; cursor: not-allowed; }

/* 文字链接（带箭头） */
.tlink {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: .9rem; color: var(--accent);
  border-bottom: 1px solid transparent; padding-bottom: 2px;
  transition: border-color var(--dur-fast) var(--ease), gap var(--dur-fast) var(--ease);
}
.tlink:hover { border-bottom-color: var(--accent); gap: 12px; }
.tlink svg { width: 14px; height: 14px; }

/* ---------- 7. 卡片通用 ---------- */
.card {
  background: var(--bg); border: 1px solid var(--line-soft);
  border-radius: var(--r-md); overflow: hidden;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.card:hover { border-color: var(--line); box-shadow: var(--sh-2); }
.card-link { display: block; }
.card-link:hover { transform: translateY(-2px); }

/* 占位框：规范标注，替代虚假素材 */
.ph {
  position: relative; background: var(--bg-2);
  border: 1px dashed var(--line); border-radius: var(--r-sm);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; color: var(--text-3); text-align: center; overflow: hidden;
}
.ph::before {
  content: ""; position: absolute; inset: 0;
  background-image: linear-gradient(var(--line-soft) 1px, transparent 1px),
                    linear-gradient(90deg, var(--line-soft) 1px, transparent 1px);
  background-size: 24px 24px; opacity: .35; pointer-events: none;
}
.ph > * { position: relative; }
.ph-label { font-size: .75rem; letter-spacing: .08em; }
.ph-ratio { font-family: var(--font-latin); font-size: .7rem; color: var(--muted); }

/* ---------- 7b. 人员架构图（org） ----------
   出现在两处：资料库「我们是谁 · 人员架构」卡片、我的房屋「下一步」区块（业主页）。
   所以放在共享样式表里，改一处两页同步 —— 别再往单个页面的 <style> 里抄一份。

   结构：客户经理（整行）
           └ 一行三列：主案设计师→设计助理 / 项目经理→施工班底 / 材料专员
        带下属的岗位要用 .org-col 包起来（列容器），否则 .org-three 的 flex 等分
        会把子节点摊成同一排、层级看不出来。 */
.org { margin-top: var(--s4); }
.org-row { display: flex; }
.org-top { flex: 1; }
/* 一行三列，每列自身又是一个可以纵向堆叠的容器（岗位 + 它的下属） */
.org-three { gap: var(--s3); align-items: flex-start; }
.org-col { flex: 1; display: flex; flex-direction: column; }
/* ⚠️ 子节点必须钉住自身高度：否则会先被 .org-three 的默认 stretch 拉成等高列，
   再被 .org-col 的纵向 flex 撑满整列 —— 下属格子会变成一根很高的空条。
   用 .org-col > 提升权重来覆盖，不要去改通用的 .org-node。 */
.org-col > .org-node { flex: 0 0 auto; }
.org-node { background: var(--bg-2); border: 1px solid var(--line-soft); border-radius: var(--r-sm); padding: var(--s4); text-align: center; display: flex; flex-direction: column; justify-content: center; }
.org-node strong { font-weight: 500; font-size: .875rem; display: block; }
/* 姓名行（2026-10-09 加）—— 岗位名之下、职责之上。
   ⚠️ 必须显式清掉 `.org-node span` 的 `min-height:3em`：那条是给描述区
      「统一按两行留高」用的，落到姓名行上会让每格白白多出 36px 空白。
      `.org-node span.org-name`(0,2,1) 压得住 `.org-node span`(0,1,1)，与顺序无关。
   ⚠️ 用品牌绿 accent-deep 提一级，让人一眼先看到名字、再看职责。 */
.org-node span.org-name {
  display: block; min-height: 0; margin-top: 5px;
  font-size: .8125rem; font-weight: 500; letter-spacing: .02em;
  color: var(--accent-deep);
  /* ★ 2026-10-17：岗位多人时**每人一行**（JS 在两人之间插 '\n'）。
     pre-line 让那个 '\n' 真的换行，同时保留正常的自动换行能力
     （长名字仍能折，只是 .org-person 的 nowrap 会把它整段挪到下一行）。 */
  white-space: pre-line;
}
/* ★ 2026-10-17：「一个岗位多人」时每人一个 .org-person。
   作用只是**保住一个人名不被拆断**（inline-block + nowrap）——
   换行由上面 pre-line 吃住 '\n' 完成，这里不负责排版。
   ⚠️ 这几行是给 `.org-node span.org-name span.org-person` 用的：
      `.org-node span`(0,1,1) 给所有 span 定了 display:flex / min-height:3em /
      margin-top:4px / color:ink-3 —— 子 span 会继承那套，必须逐项清掉，
      否则每个名字都变成一根 3em 高的块、颜色也退回灰的。
      权重 (0,3,1) 压得住，别删。 */
.org-node span.org-name span.org-person {
  display: inline-block; min-height: 0; margin-top: 0;
  font-size: inherit; font-weight: inherit; letter-spacing: inherit;
  line-height: inherit; color: inherit; white-space: nowrap;
}
/* ★ 2026-10-17：访客态的「待分配」占位（见 site.js 的 YANE_ORG_ANON）。
   为什么要有：未登录时项目团队还没分配，露真人姓名等于把"公司架构"说成
   "您家的服务团队"；但姓名行整段不渲染的话，三列格子会一高一矮、访客也看不出
   "这里将来会有人"。⇒ 保留这一行、只把颜色降下来。
   ⚠️ 只改颜色与字重，**不缩字号、不改行高** —— 换行与格子高度必须和实名态一致，
      否则业主登录那一刻整张图会跳一下。 */
.org-node span.org-name.is-empty {
  font-weight: 400; letter-spacing: .06em; color: var(--ink-3);
}
/* ⚠️ 描述区按「两行」留高：材料专员的职责要写三项、在这一列宽里必然换行成两行，
   不统一的话同排格子会一高一矮（实测 97px vs 79px）。
   定成两行后 6 个格子天然等高，且文字在格子里垂直居中、不会顶在上面。
   用 em 而非 px —— 字号一改（含用户缩放）它跟着走。 */
.org-node span { font-size: .75rem; color: var(--ink-3); display: flex; align-items: center; justify-content: center; min-height: 3em; margin-top: 4px; line-height: 1.5; }
.org-link { display: block; width: 1px; height: 20px; background: var(--line); margin: 0 auto; }
@media (max-width: 640px) {
  /* 窄屏：三列改纵向堆叠，各列恢复自身高度
     ★ 2026-10-17：必须把 align-items 从 flex-start 改回 stretch ——
       基础规则里那条 `align-items: flex-start` 在**横排**时管的是纵向
       （防止子节点被拉伸成高条，见上的注释）；可一旦 flex-direction 变成
       column，它管的就变成**横向**了 ⇒ 每列宽度跟着内容走。
       表现：材料专员的描述最长（「对接材料商 · 统筹材料入场 · 验收材料质量」），
       那一格比上面几格都宽，整列参差不齐（2026-10-17 手机端截图实测）。
       改 stretch 后每列都撑满一行宽，且不影响高度。 */
  .org-three { flex-direction: column; align-items: stretch; }
  .org-col { flex: 0 0 auto; }
}

/* ---------- 7c. 板块页 Halo 区：大标题下的两颗按钮（2026-10-17 用户定 · 五轮定稿） ----------
   演变（四轮都记下来，免得以后改回去）：
     ① 先是「放 Halo 区最右边，上下放、两颗等大」；
     ② 然后「登录放上面」+「太抢眼了，改不显眼的白色或内部透明」；
     ③ 然后「改来放到页面 Halo 大标题下面吧，参考首页，大标题下面的说明文字不要了」
        ⇒ 按钮行**回到文档流**，紧接 `<h1>` 之后，横排、`gap 16`、与标题隔 `48` —— 与首页
        首屏 `.flex gap-4 wrapf mt-7` 同款；同时**页头的 `.lead` 说明段已删**，
        页头只剩「eyebrow → 大标题 → 按钮行」；
     ④ 然后「登录按钮改为绿色」；⑤ 然后「并且改到左边」⇒ 登录在左、预约在右（见下）；
     ⑥ 最后「若已登录，则登录按钮隐藏，预约到店按钮变为绿色外框」⇒ 见下「⑥」那段。
   ★ 左右顺序（第五轮定稿）：**登录在左、预约在右**。
     ④ 之后用户又说「**并且改到左边**」⇒ 绿色那颗登录挪到最左，成为页头第一个可点元素；
        淡色那颗预约退到它右边。绿 + 最左 = 页头的唯一重心，符合「登录是这四页最需要的动作」
        （导航条上没有登录口，客户在任意板块页想登录，第一眼就该看见它）。
     ⚠️ DOM 顺序即视觉顺序（没有 order 之类的反转），改顺序就改 HTML 里两个 button 的前后。
   ★ 配色（以最后一条为准）：
     ② 「太抢眼了，改不显眼的白色，或内部透明」⇒ 两颗都改成透明底 + 发丝描边 + 灰字；
     ④ 2026-10-17 用户再定：「**登录按钮改为绿色**」⇒ 只有【登录】这颗填品牌绿
        （`--accent` 实心 + 白字，悬停 `--accent-deep`），【预约】那颗保持透明。
        这样页头一屏里只有一个绿点，正好落在「登录」上；预约那条仍靠标题下面的位置
        自带存在感，不需要再上色。
   ⚠️ `.page-acts .btn` 那段覆盖**连 background/color 一起写死**是有意的：万一有人给
      这两颗加 `btn-primary`，只压边框会出现「透明底 + 白字」＝彻底看不见。
      ⇒ 所以绿色那颗必须另写 `[data-lg-btn]` 规则（权重 0,3,0 > 0,2,0）才压得回来，
        不能只靠 HTML 上的 `btn-olive` 类（0,1,0，会被那段覆盖吃掉）。
   ⚠️ 这四页的导航条**没有**登录入口，登录按钮只在这一处 —— 它的状态由 site-login.js 的
      renderHub() 统一重画（`[data-lg-btn]`，登录 ↔ 退出登录），页面里别自己写改文案的脚本。
      绿色跟着 `[data-lg-btn]` 走，所以「退出登录」也是同一颗绿按钮，不会掉回灰框。
   ⚠️ 窄屏不特殊处理：横排 + `flex-wrap` 本来就能换行，不需要再写 media query。 */
.page-acts {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--s4); margin-top: var(--s7);
}
.page-acts .btn {
  background: transparent;            /* 内部透明 —— 落在白页头上就是「白色」 */
  border-color: var(--line);
  color: var(--text-2);
}
.page-acts .btn:hover { background: transparent; border-color: var(--text-3); color: var(--text); }
/* ④ 登录这颗：品牌绿实心（全站唯一绿 --accent，别换成别的绿） */
.page-acts .btn[data-lg-btn] {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
.page-acts .btn[data-lg-btn]:hover {
  background: var(--accent-deep); border-color: var(--accent-deep); color: #fff;
}

/* ⑥ 2026-10-17 用户定：**已登录 → 登录按钮隐藏，预约按钮变绿色外框**。
   ① 隐藏：`hidden` 属性本身压不住 `.btn{display:inline-flex}`（UA 的
      `[hidden]{display:none}` 只有 0,1,0），所以这条**必须**在 —— 删了等于「没隐藏」。
      用 display:none（而不是 visibility/opacity）：隐藏后**不留空位**，预约那颗自动补到最左。
   ② 外框：透明底 + `--accent` 描边 + `--accent` 字；悬停给一层极淡的绿底（`--accent-wash`），
      字加深到 `--accent-deep`。⛔ 别做成实心 —— 用户说「**外框**」，实心就成了第二颗登录按钮。
   ③ 状态类 `.is-logged` 由 site-login.js 的 renderHub() 挂在 `.page-acts` 上（四种页面统一），
      ⛔ 页面里别自己写脚本去加。 */
.page-acts .btn[hidden] { display: none; }
.page-acts.is-logged .btn[data-book] {
  background: transparent;
  border-color: var(--accent);
  color: var(--accent);
}
.page-acts.is-logged .btn[data-book]:hover {
  background: var(--accent-wash);
  border-color: var(--accent-deep);
  color: var(--accent-deep);
}

/* ⑦ 已登录态的「退出登录」文字链（2026-10-17 用户认可加回退出入口）。
   为什么不是一颗按钮：页头一屏只该有一个视觉主体（登录态的绿框预约）。
   退出是附带动作，做成带框的按钮会和它并列争注意力，所以走「细下划线文字链」——
   与导航条上 `.nav-user-out` 同一套写法（那里也是「退出不做第二颗按钮」）。
   ⚠️ 不设 display —— 靠 `hidden` 属性隐藏，UA 的 `[hidden]{display:none}` 就能生效；
      但下面仍补一条 `[hidden]`，防止将来有人给它加 display 把隐藏压掉。
   ⚠️ DOM 里它排在预约**之后**：已登录时视觉顺序＝绿框预约 → 退出登录。
   ⚠️ 点击走 site-login.js 的文档级委托（`[data-lg="out"]` → doLogout），
      本段不挂任何脚本。 */
.page-act-out {
  background: none; border: 0; padding: 0 0 1px; margin: 0;
  font-size: .8125rem; letter-spacing: .04em; color: var(--text-3);
  border-bottom: 1px solid var(--line); cursor: pointer;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.page-act-out:hover { color: var(--text-2); border-bottom-color: var(--text-3); }
.page-act-out[hidden] { display: none; }

/* ---------- 7d. 页尾「还有问题想问？」条（2026-10-17 三页共用） ----------
   原样只在 library.html 的 <style> 里（类名 .lib-cta）。2026-10-17 用户要求把这一块
   同时摆到《案例实景》和《材料与标准》两页尾部（替掉那两页原来的预约条），
   三个地方共用 ⇒ 上移到这里当单一来源，类名改成中性的 .cta-inline。
   ⚠️ 页面上别再写第二份 .lib-cta 规则（老类名已退役）。 */
.cta-inline {
  background: var(--bg-2); border-radius: var(--r-md);
  padding: clamp(28px, 4vw, 48px);
  display: flex; justify-content: space-between; align-items: center;
  gap: var(--s6); flex-wrap: wrap;
}

/* ---------- 8. 标签 / 徽章 ---------- */
.tag {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: var(--r-xs);
  font-size: .75rem; letter-spacing: .04em;
  background: var(--bg-neutral); color: var(--text-2);
}
.tag-olive { background: var(--accent-wash); color: var(--accent-deep); }
.tag-walnut { background: var(--walnut-wash); color: var(--walnut-deep); }
.tag-line { background: transparent; border: 1px solid var(--line); }

/* 状态点 */
.dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); flex-shrink: 0; }
.dot-idle { background: var(--muted); }
.dot-warn { background: var(--warn); }
.dot-pulse { animation: none; }   /* 极简：去掉呼吸动画，保留静态圆点 */

/* ---------- 9. 入场动画 ---------- */
.reveal { opacity: 0; transform: translateY(14px); transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out); }
.reveal.is-in { opacity: 1; transform: none; }
.reveal-d1 { transition-delay: .08s; }
.reveal-d2 { transition-delay: .16s; }
.reveal-d3 { transition-delay: .24s; }
.reveal-d4 { transition-delay: .32s; }
/* 2026-10-08 补：首页入口卡由 5 张增至 6 张，错峰到第 6 张需要 d5。 */
.reveal-d5 { transition-delay: .4s; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ---------- 10. 页脚 ---------- */
.footer { border-top: 1px solid var(--line); margin-top: var(--s9); background: var(--bg); }
.footer-grid {
  display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.2fr;
  gap: var(--s7); padding-block: var(--s8) var(--s6);
}
.footer-brand img { height: 24px; margin-bottom: var(--s4); }
.footer h4 { font-family: var(--font-body); font-size: .8125rem; letter-spacing: .14em; color: var(--text); margin-bottom: var(--s4); }
.footer li { margin-bottom: 10px; }
.footer a, .footer p { font-size: .875rem; color: var(--text-2); line-height: 1.65; }
.footer a:hover { color: var(--accent); }
.footer-bottom {
  border-top: 1px solid var(--line-soft); padding-block: var(--s5);
  display: flex; justify-content: space-between; gap: var(--s4); flex-wrap: wrap;
  font-size: .8125rem; color: var(--text-3);
}
.footer-note { font-size: .8125rem; color: var(--text-3); line-height: 1.7; }

/* ---------- 10b. 社媒入口（悬停展开账号菜单） ----------
   2026-10-09 新增。触发器＝一颗 <button>（.tag 小标签 或 .btn 按钮），
   悬停 / Tab 聚焦即弹出账号列表。出现在三处：
     · 页脚「联系我们」          —— .tag，**向上**弹（.soc-up）
     · 案例实景列表工具条        —— .btn-sm.btn-soft，向下弹
     · 案例详情页侧栏 CTA        —— .btn.btn-block，向下弹
   交互**全在 CSS**（:hover + :focus-within），不挂 JS ——
   HTML 由 site.js 的 buildSocial() 生成，挂监听会跟重复渲染打架。

   ⚠️ 方向：默认**向下**弹（top:100%）；页脚必须加 .soc-up 改成向上 ——
      页脚贴着页面底部，向下会在「已滚到底」时顶出视口。
   ⚠️ 菜单紧贴触发器（不留 gap），间距用自身 padding 做 —— 留 gap 的话
      鼠标从按钮移到菜单的路上会离开 .soc，菜单当场收起来。
   ⚠️ 菜单项选择器写成 `.soc .soc-menu a`（0,2,1）而不是 `.soc-menu a`（0,1,1）：
      页脚那几条 `.footer a` / `.footer a:hover` 优先级更高，不抬权重会被它
      覆盖掉（字号变 .875rem、hover 变 var(--accent)）。
   ⚠️ `.soc` 默认 inline-flex；`block:true` 时换 flex，否则 .btn-block
      会被缩成内容宽（撑不满）。 */
.soc { position: relative; display: inline-flex; }
.soc-block { display: flex; }
.soc-block .soc-btn { width: 100%; }
.soc-btn {
  border: 0; cursor: pointer; -webkit-appearance: none; appearance: none;
  font-family: inherit; line-height: inherit;
}
.soc-caret { transition: transform var(--dur-fast) var(--ease); }
.soc:hover .soc-caret, .soc:focus-within .soc-caret { transform: rotate(180deg); }

.soc-menu {
  position: absolute; top: 100%; left: 0; z-index: 30;
  min-width: 100%; padding: 5px 0;
  display: flex; flex-direction: column;
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--r-sm); box-shadow: 0 10px 28px rgba(26, 26, 26, .10);
  opacity: 0; visibility: hidden; transform: translateY(-5px);
  transition: opacity .18s var(--ease), transform .18s var(--ease), visibility 0s .2s;
}
.soc-up .soc-menu { top: auto; bottom: 100%; transform: translateY(5px); }
.soc:hover .soc-menu,
.soc:focus-within .soc-menu {
  opacity: 1; visibility: visible; transform: none; transition-delay: 0s;
}
.soc .soc-menu a {
  display: block; white-space: nowrap;
  padding: 7px 14px; font-size: .8125rem; line-height: 1.5; color: var(--text-2);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.soc .soc-menu a:hover { background: var(--bg-2); color: var(--accent-deep); }
/* 键盘走到菜单里时给个明确落点（.footer a 本身没有 focus 样式） */
.soc .soc-menu a:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ---------- 11. 工具类 ---------- */
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s5); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s5); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s5); }
.flex { display: flex; }
.between { justify-content: space-between; }
.center { align-items: center; }
.col { flex-direction: column; }
.gap-2 { gap: var(--s2); }
.gap-3 { gap: var(--s3); }
.gap-4 { gap: var(--s4); }
.gap-5 { gap: var(--s5); }
.gap-6 { gap: var(--s6); }
.wrapf { flex-wrap: wrap; }
.mt-2 { margin-top: var(--s2); } .mt-3 { margin-top: var(--s3); }
.mt-4 { margin-top: var(--s4); } .mt-5 { margin-top: var(--s5); }
.mt-6 { margin-top: var(--s6); } .mt-7 { margin-top: var(--s7); }
.mb-3 { margin-bottom: var(--s3); } .mb-4 { margin-bottom: var(--s4); }
.mb-5 { margin-bottom: var(--s5); } .mb-6 { margin-bottom: var(--s6); }
.text-center { text-align: center; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ---------- 12. 响应式 ---------- */
@media (max-width: 1024px) {
  .footer-grid { grid-template-columns: 1fr 1fr; gap: var(--s6); }
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
}
/* 2026-10-08：导航新增第 7 项「材料库」之后，窄桌面会被挤到「导航压住左边 logo」。
   原因：861–1080 这一段导航条仍显示，但版心最紧处（861px）只剩 813px，
   绝对居中（left:50% + translate）的导航组放不下，左缘就顶到 logo 上去了。
   解法：这一段逐级收紧导航组的**间距与字号**（只动 .nav-links / .nav-link，
   不碰居中定位 —— 那两条 50% 是另一件事，见第 221 行附近的注释）。
   ⚠️ 860 是「导航收进汉堡」的下界（.nav-links{display:none}），
      本条必须落在 860 之上，别越界。
   ⚠️ 验收：.cache/verify-nav.js 第 6b 节在 1200/1040/960/900/861 五档实测「不撞车」，别删。 */
@media (max-width: 1080px) {
  .nav-links { gap: var(--s4); }
  .nav-link { font-size: .9375rem; }
}
@media (max-width: 920px) {
  .nav-links { gap: var(--s3); }
  .nav-link { font-size: .875rem; }
}
@media (max-width: 860px) {
  /* 2026-10-01 桌面导航放大一档，移动端同步 +6px（64→70）保持观感一致 */
  :root { --nav-h: 70px; --s9: 64px; --s8: 48px; }
  .nav-links { display: none; }
  .nav-toggle { display: flex; }
  /* 原来这里还有一条 `.nav-cta{display:none}` —— 随那颗按钮退役一并删掉（2026-10-08） */
  .grid-3 { grid-template-columns: 1fr; }
  .grid-2 { grid-template-columns: 1fr; }
  .section { padding-block: var(--s7); }
}
@media (max-width: 560px) {
  .wrap, .wrap-narrow { width: min(100% - 32px, var(--wrap)); }
  .grid-4 { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr; gap: var(--s5); }
  .display { font-size: 2.1rem; }
}

/* ============================================================
   登录入口（导航条） + 登录弹窗 —— 全站共用
   ------------------------------------------------------------
   谁在用：index.html（首页）、ai-manager.html（我的需求页），
   由 assets/js/site-login.js 动态注入 DOM，所以**别在页面里手写这些标签**。
   ⚠️ .lm* 这一套原先写在 my-home.html 的内联 <style> 里（两份共用一套 DOM 结构）。
      2026-10-07 上移到本文件当**单一来源** —— my-home 那份内联副本已删。
      改弹窗长相改这里一处，my-home 的页头入口与本模块的导航入口同时生效。
   ============================================================ */

/* ---------- 导航右侧分组 ----------
   ⚠️ 登录入口不能直接当 .nav-inner 的第 5 个孩子 —— 那是 justify-content:space-between，
      多一个直接子节点会把「导航链接」和「右侧按钮」摊成四段。所以收进 .nav-right。 */
.nav-right { display: flex; align-items: center; gap: var(--s4); flex-shrink: 0; }

/* 未登录：「登录」—— 导航右上**唯一**的一颗按钮（2026-10-08 用户定）。
   外形＝原 .nav-cta（r-sm 圆角 / 11+22 内距 / 15px 字 + 同款 1px 描边），
   配色＝原 .nav-cta 的 `:hover`（--text 底 + --bg 字）拿来做默认态 ——
   也就是把那颗按钮「填实」。
   ★ hover 反过来走描边：默认实心 → 悬停镂空，与原按钮是一对反转，
     别改成「再深一档」（--text 已是全站最深的一档字色，没有更深的令牌）。
   ⚠️ 别加回「聊聊我的房子」：右上只留这一颗。 */
.nav-login {
  display: inline-flex; align-items: center;
  padding: 11px 22px;
  border: 1px solid var(--text); border-radius: var(--r-sm);
  font-size: .9375rem; letter-spacing: .04em; white-space: nowrap;
  background: var(--text); color: var(--bg); cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.nav-login:hover { background: transparent; color: var(--text); }

/* ★★ 2026-10-20 用户口径：导航最右边（登录之后）加一颗「**预约到店**」。
   ────────────────────────────────────────────────────────────
   原话：「已登陆的客户进入官网我的家页面时，想要预约还得跑到最下面去，
   帮我在最上面导航栏的最右边新增一个预约的入口」。
   ⇒ 与 `.nav-login` **共用几何**（--r-sm / 11+22 内距 / .9375rem / 1px 描边），
      颜色换成全站唯一的品牌绿实心 —— 这是用户明确要的「显眼」，
      目的是让「约面谈」在首屏就能点，不用滚到页面底部的第二步。
   ★ 于是导航右侧是三颗：深色实心「登录」→ 绿色实心「预约到店」→ 淡灰「内部系统」。
     三档深浅是**刻意的层级**（顾客主动作 → 次动作 → 员工入口），别调平成同一个色。
   ⚠️ 它是 `<button>`（点开弹窗，不是跳页），所以要清掉浏览器默认的 font/边框，
     不能只靠 `.nav-login` 那套 —— 按钮的默认底色和字体与 `<a>` 不同。
   ⚠️ 悬停**加深**而不是镂空：这颗是主行动按钮，镂空会让它在白底上「消失」，
     与旁边那颗登录（悬停镂空）正好相反，看起来是一深一浅两种语言。 */
.nav-book {
  display: inline-flex; align-items: center;
  padding: 11px 22px;
  border: 1px solid var(--accent); border-radius: var(--r-sm);
  font-family: inherit;
  font-size: .9375rem; letter-spacing: .04em; white-space: nowrap;
  background: var(--accent); color: #fff; cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.nav-book:hover { background: var(--accent-deep); border-color: var(--accent-deep); }
/* 手机抽屉里那颗（导航右侧整块在 ≤860px 隐藏，入口挪到抽屉里） */
.nav-drawer-book { margin-top: 12px; }
.nav-drawer-book .nav-book { width: 100%; justify-content: center; }

/* ★★ 2026-10-15 用户口径：导航最右边加一颗「**内部系统**」入口（只在官网首页，
   由 `window.YANE_NAV_OFFICE` 声明 → 见 assets/js/site-login.js 的 navOfficeHtml()）。
   用户原话：「形状和登陆按钮一致，但一定不要显眼，淡淡的有个就行了」。
   ⇒ 与 `.nav-login` **共用几何**（--r-sm 圆角 / 11+22 内距 / .9375rem 字号 / 1px 描边宽），
      但**不填色**：透明底 + 极淡描边（--line-soft）+ 浅灰字（--text-3）；
      悬停才略微加深一档（到 --text-2 / --line），仍然远弱于左边那颗深色实心登录。
   ⚠️ 改 `.nav-login` 的几何时**顺手核一眼这里** —— 两颗要看着是一对（一颗实心、一颗线框）。
   ⚠️ 它是 `<a>`：必须清 `text-decoration`、并保持 `inline-flex` 才能与按钮同基线。
   ⚠️ ≤860px 跟随登录入口一起隐藏（见下面那条 @media：窄屏右侧整体让位给汉堡）。 */
.nav-office {
  display: inline-flex; align-items: center;
  padding: 11px 22px;
  border: 1px solid var(--line-soft); border-radius: var(--r-sm);
  font-size: .9375rem; letter-spacing: .04em; white-space: nowrap;
  background: transparent; color: var(--text-3); text-decoration: none;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.nav-office:hover { color: var(--text-2); border-color: var(--line); }

/* 已登录：姓名 + 退出。姓名给 .nav-user-name（用 --text 比链接更「实」），
   退出给一条细下划线，别做成按钮 —— 导航条上不该出现第二颗有边框的东西。 */
.nav-user { display: inline-flex; align-items: center; gap: 10px; white-space: nowrap; }
.nav-user-name { font-size: .9375rem; color: var(--text); }
.nav-user-meta { font-size: .8125rem; color: var(--text-3); }
.nav-user-out {
  font-size: .8125rem; color: var(--text-3); cursor: pointer;
  border-bottom: 1px solid var(--line); padding-bottom: 1px;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.nav-user-out:hover { color: var(--accent); border-color: var(--accent); }

/* 抽屉里的登录行（≤860px 导航条右侧整体隐藏，只能从抽屉进） */
.nav-drawer-auth { border-top: 1px solid var(--line-soft); padding-top: var(--s4); margin-top: var(--s2); }
/* ⚠️ 2026-10-08：这两条要跟着实心化一起改 —— 原来那句 `color: var(--text)` 会把
   深色底上的字压成**深色**（等于看不见），`.en` 那句 `--text-3` 同理。
   现在是全宽 + 竖排居中，像一颗正经按钮而不是一行文字。 */
.nav-drawer-auth .nav-login {
  width: 100%; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; font-size: 1.05rem; color: var(--bg);
}
.nav-drawer-auth .nav-login .en {
  font-family: var(--font-latin); font-size: .72rem; letter-spacing: .2em;
  color: inherit; opacity: .6;
}
.nav-drawer-auth .nav-user { flex-direction: column; align-items: flex-start; gap: 4px; }
.nav-drawer-auth .nav-user-name { font-size: 1.05rem; }
.nav-drawer-auth .nav-user-out { font-size: .875rem; }

/* ---------- 登录弹窗 ----------
   ⚠️ 遮罩不铺色：透明底 + backdrop-filter blur/brightness，与 .pv/.sm/.st 同一规范。
      铺任何 rgba 都会偏色 —— 用户逐像素在意（见本文件顶部遮罩令牌）。 */
.lm {
  position: fixed; inset: 0; z-index: 300;
  display: flex; align-items: center; justify-content: center;
  padding: var(--s5);
  background: transparent;
  backdrop-filter: blur(var(--blur-1)) brightness(var(--dim));
  -webkit-backdrop-filter: blur(var(--blur-1)) brightness(var(--dim));
  animation: lmIn .22s var(--ease-out) both;
}
.lm[hidden] { display: none; }
@keyframes lmIn { from { opacity: 0; } to { opacity: 1; } }

.lm-box {
  position: relative;
  width: min(100%, 400px);
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-lg);
  padding: clamp(26px, 4vw, 36px);
  box-shadow: var(--sh-3);
  animation: lmBox .3s var(--ease-out) both;
}
@keyframes lmBox { from { opacity: 0; transform: translateY(10px) scale(.99); } to { opacity: 1; transform: none; } }

.lm-close {
  position: absolute; top: 14px; right: 14px;
  width: 32px; height: 32px; border-radius: var(--r-sm);
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-3); cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.lm-close:hover { background: var(--bg-2); color: var(--ink); }

.lm-head { padding-right: 28px; }
.lm-title { font-size: 1.2rem; margin-top: 8px; }
.lm-sub { margin-top: 8px; font-size: .8125rem; color: var(--ink-3); line-height: 1.7; }

.lm-form { margin-top: var(--s5); }
.lm-label { display: block; font-size: .8125rem; color: var(--ink-2); margin-bottom: 6px; }
/* 墓碑（2026-10-08）：`.lm-opt`（「（新客户填一下，我们好建档）」那句选填说明）
   随登录弹窗里的「称呼」输入框一起退役 —— 登录只剩手机号 + 验证码，没有需要加小字说明的字段了。
   别再为「某种选填项」把它加回来。 */
.lm-label + .lm-inp { margin-bottom: var(--s4); }
.lm-inp {
  width: 100%; padding: 11px 13px; font: inherit; font-size: .9375rem;
  color: var(--ink); background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--r-xs);
  transition: border-color var(--dur-fast) var(--ease);
}
.lm-inp::placeholder { color: var(--ink-3); }
.lm-inp:focus { outline: none; border-color: var(--accent); }

.lm-code { display: flex; align-items: center; gap: var(--s2); }
.lm-code .lm-inp { flex: 1; min-width: 0; }
.lm-send {
  flex-shrink: 0; padding: 11px 14px; font: inherit; font-size: .8125rem; color: var(--ink-2);
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--r-xs);
  cursor: pointer; white-space: nowrap; transition: all var(--dur-fast) var(--ease);
}
.lm-send:hover:not(:disabled) { background: var(--bg-2); color: var(--ink); }
.lm-send:disabled { opacity: .55; cursor: default; }

.lm-msg { margin-top: var(--s3); font-size: .8125rem; color: var(--ink-3); line-height: 1.6; }
.lm-msg[hidden] { display: none; }
.lm-msg.is-ok { color: var(--accent-deep); }
.lm-msg.is-err { color: var(--flag); }

.lm-go { width: 100%; margin-top: var(--s4); padding: 13px; font-size: .9375rem; }

@media (max-width: 860px) {
  /* 导航条右侧整体让位给汉堡（原来那颗 .nav-cta 已退役，右上只剩登录这一颗），
     登录入口改从抽屉进。
     ★ 2026-10-15：新加的「内部系统」入口（.nav-office）**跟着一起隐藏** ——
       它在宽屏上是「登录右边那颗很淡的小键」，窄屏右侧没有它的位置；
       员工用电脑进后台，没必要为它在手机导航条上再挤一格。 */
  .nav-login, .nav-user, .nav-office { display: none; }
}

/* ============================================================
   官网侧 · 员工「代看」横幅（2026-10-09）
   ------------------------------------------------------------
   员工从内部系统点「官网视角」进来时，页面**底部**常驻一条深色条，
   说明「这不是你自己的视角，是某位客户的」。可关（退出代看）。

   ⚠️ 为什么放下边不放上边：顶部导航 .nav 是 position:sticky; top:0 且带
      backdrop-filter（会建包含块，与「覆盖层算 100dvh」那套注释同源）——
      在顶部硬插一层得同时改 .nav 与 .nav-drawer 的 top，牵一发动全身。
      底部固定条是**纯增量**：不碰既有布局，只给 body 留出底部内边距。
   ⚠️ 高度由 JS 量出回填 --imp-h（窄屏折行会变高），别在 CSS 里写死。
   ⚠️ 深色块用 --ink-block（既有令牌）；**不用**品牌绿 —— 这不是强调动作，
      是「模式提示」，且深绿底上的绿按钮对比度不够。
   ============================================================ */
.imp-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  gap: var(--s4) var(--s5); flex-wrap: wrap;
  padding: 11px clamp(16px, 4vw, 32px);
  background: var(--ink-block); color: #FFFFFF;
  font-size: .875rem; line-height: 1.5;
  box-shadow: 0 -1px 0 rgba(255,255,255,.08);
}
.imp-bar[hidden] { display: none; }
.imp-ic { width: 18px; height: 18px; flex-shrink: 0; opacity: .72; }
.imp-txt { text-align: center; }
.imp-txt b { font-weight: 600; }
.imp-txt .imp-by { opacity: .68; }
.imp-txt.is-err { color: #F6D9A8; }
.imp-exit {
  flex-shrink: 0; padding: 7px 15px; font: inherit; font-size: .8125rem;
  color: #FFFFFF; background: transparent;
  border: 1px solid rgba(255,255,255,.42); border-radius: var(--r-xs);
  cursor: pointer; white-space: nowrap;
  transition: all var(--dur-fast) var(--ease);
}
.imp-exit:hover:not(:disabled) { background: #FFFFFF; color: var(--ink-block); border-color: #FFFFFF; }
.imp-exit:disabled { opacity: .55; cursor: default; }
/* 底部条占了视口底部 → 给 body 补同样高度的内边距，别让页脚被压住 */
html.imp-on body { padding-bottom: var(--imp-h, 56px); }

/* ============================================================
   预约系统 · 官网侧（标准预约条 + 两步弹窗）  —— 2026-10-09 新增
   ------------------------------------------------------------
   谁在用：assets/js/site-booking.js（动态注入 DOM）。
   ⚠️ 别在页面里手写这些标签 —— DOM 与文案都在脚本里生成：
      文案来自 data.js 的 YANE_BOOKING，电话来自 site.js 的 YANE。
   ⚠️ 遮罩不铺色：透明底 + backdrop-filter blur/brightness，与 .lm/.pv/.sm 同一规范。
      铺任何 rgba 都会偏色（用户逐像素在意，见本文件顶部遮罩令牌）。
   ⚠️ 弹窗打开时给 html 加 .bk-on 锁滚动 —— 内容比一屏高（第 2 步有工地列表），
      不锁的话背景会跟着滚，关掉后位置全乱。
   ============================================================ */

/* ---------- 标准预约条 ----------
   一条细带，给「页上原本没有 CTA」的页面用（我的需求 / 材料库 / 案例实景 / 案例详情）。
   页面只留一个空壳：<div class="book-bar" data-book-bar="材料库"></div>，
   内容由 site-booking.js 按 YANE_BOOKING.bar 填 —— 文案不在各页复制（铁律 1）。 */
.book-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s6); flex-wrap: wrap;
  padding: var(--s5) var(--s6);
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--bg-3);
}
.book-bar-t { display: flex; align-items: baseline; gap: var(--s4); flex-wrap: wrap; }
.book-bar-t b { font-family: var(--font-display); font-size: 1.1875rem; font-weight: 500; }
.book-bar-t span { font-size: .84375rem; color: var(--text-2); }
.book-bar-act { display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap; }
.book-bar-tel {
  font-family: var(--font-latin); font-size: 1.125rem; letter-spacing: .04em;
  color: var(--text); font-variant-numeric: tabular-nums;
}
.book-bar-tel i {
  font-style: normal; font-family: var(--font-body); font-size: .75rem;
  color: var(--text-3); letter-spacing: .04em; display: block; margin-bottom: 1px;
}

/* ---------- 弹窗外壳 ---------- */
.bk {
  /* 上下留白抽成令牌：.bk-box 要靠它算「最多能长多高」（见下）——
     写死两处迟早对不上，改一处就够。 */
  --bk-pad-t: clamp(16px, 6vh, 64px);
  --bk-pad-b: var(--s5);
  position: fixed; inset: 0; z-index: 320;
  display: flex; align-items: flex-start; justify-content: center;
  padding: var(--bk-pad-t) var(--s5) var(--bk-pad-b);
  overflow-y: auto; overscroll-behavior: contain;
  background: transparent;
  backdrop-filter: blur(var(--blur-1)) brightness(var(--dim));
  -webkit-backdrop-filter: blur(var(--blur-1)) brightness(var(--dim));
  animation: bkIn .22s var(--ease-out) both;
}
.bk[hidden] { display: none; }
@keyframes bkIn { from { opacity: 0; } to { opacity: 1; } }
html.bk-on { overflow: hidden; }

.bk-box {
  position: relative;
  width: min(100%, 620px);
  margin: auto 0;
  /* ★ 2026-10-09 改：白框不再无限长高 —— 封顶到视口内。
     「看工地」那条要选阶段 + 挑工地 + 定时间 + 填联系，实测内容高 1740px，
     而笔记本视口才 900 —— 提交按钮掉到**视口下面 840px**，业主得先盲滚一段
     才看得见要提交，甚至以为没这个按钮。
     现在：白框封顶 → 头（标题）与脚（上一步 / 提交预约）钉住不动，
     中间 .bk-body 自己滚。永远看得见"跳到哪一步了"和"怎么提交"。 */
  max-height: calc(100dvh - var(--bk-pad-t) - var(--bk-pad-b));
  background: var(--bg);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-3);
  animation: bkBox .3s var(--ease-out) both;
}
/* 内容槽 —— 头 / 身 / 脚（.bk-head / .bk-body / .bk-foot）的父层。
   它负责把三块**竖着排开**，并让中间那块成为唯一的滚动区。
   ⚠️ 2026-10-09 踩过：这一层原先叫 .bk-slot —— 与「时段按钮」的 .bk-slot
      重名，被那套 flex 横排 + 边框 + 内距接走，三块并成一行：
      标题被压成竖排、提交按钮溢出到白框外。
      （那套按钮样式已于 2026-10-21 随「上午/下午」一起撤掉，教训照样成立：
        .bk-* 前缀很密，新加一层前先确认名字没被谁占着。）
   ⚠️ 必须保留 min-height:0 —— flex 子项默认 min-height:auto，
      不给 0 的话中间那块撑破父容器、滚动条根本不出来（经典 flex 坑）。 */
.bk-pane { display: flex; flex-direction: column; min-height: 0; max-height: inherit; }
@keyframes bkBox { from { opacity: 0; transform: translateY(10px) scale(.995); } to { opacity: 1; transform: none; } }

/* ---------- 头 ---------- */
/* 与脚一样钉住（flex:0 0 auto）—— 滚动只发生在中间那块 */
.bk-head { flex: 0 0 auto; padding: var(--s7) var(--s7) 0; display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s5); }
.bk-head > div { min-width: 0; }
.bk-title { font-size: 1.4375rem; margin-top: 8px; }
.bk-sub { font-size: .84375rem; color: var(--text-2); margin-top: 8px; line-height: 1.7; }
.bk-x {
  width: 32px; height: 32px; flex: 0 0 32px; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-3); border: 1px solid var(--line); background: none; cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.bk-x:hover { background: var(--bg-2); color: var(--text); }

/* ---------- 体 ---------- */
/* 中间那块＝**唯一滚动区**（见 .bk-box 的注释）。
   ⚠️ 它必须有 min-height:0，否则 flex 里滚不动。 */
.bk-body {
  padding: var(--s6) var(--s7) var(--s5);
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
}
/* ---------- 脚 ---------- */
/* 钉在白框底部：业主滚到哪一步都看得见「上一步 / 提交预约」。
   顶边一道发丝线 —— 中间在滚、脚不动，得让人看出这是"粘住的那条"。 */
.bk-foot {
  flex: 0 0 auto;
  padding: var(--s5) var(--s7) var(--s6);
  border-top: 1px solid var(--line-soft);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4); flex-wrap: wrap;
}
.bk-foot-act { display: flex; align-items: center; gap: var(--s3); }
.bk-steps { display: flex; align-items: center; gap: 7px; }
.bk-steps i { width: 22px; height: 3px; border-radius: 2px; background: var(--line); display: block; }
.bk-steps i.on { background: var(--accent); }
.bk-steps span { font-size: .75rem; color: var(--text-3); margin-left: 6px; letter-spacing: .04em; }

/* ---------- 第 1 步 · 类型卡 ---------- */
.bk-kinds { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); }
.bk-kind {
  border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 22px 22px 20px; text-align: left; background: var(--bg);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.bk-kind.on { border-color: var(--accent); background: var(--accent-wash); box-shadow: inset 0 0 0 1px var(--accent-line); }
.bk-ic { width: 38px; height: 38px; border-radius: var(--r-sm); background: var(--bg-2); display: flex; align-items: center; justify-content: center; margin-bottom: 14px; }
.bk-kind.on .bk-ic { background: var(--bg); }
.bk-ic svg { width: 20px; height: 20px; stroke: var(--text-2); }
.bk-kind.on .bk-ic svg { stroke: var(--accent); }
.bk-kind h4 { font-size: 1.0625rem; }
.bk-kind p { font-size: .8125rem; color: var(--text-2); margin-top: 8px; line-height: 1.65; min-height: 63px; }
.bk-dur {
  display: block; font-size: .75rem; color: var(--text-3); letter-spacing: .04em;
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line-soft);
}
.bk-kind.on .bk-dur { border-top-color: var(--accent-line); color: var(--accent-deep); }

/* ---------- 区块 ---------- */
.bk-blk { margin-bottom: var(--s6); }
.bk-blk-h { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; margin-bottom: 12px; }
.bk-blk-h h4 { font-size: .9375rem; font-family: var(--font-body); font-weight: 500; }
.bk-blk-h span { font-size: .75rem; color: var(--text-3); }

/* ---------- 阶段 chips ---------- */
.bk-stgs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.bk-stg {
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 11px 12px;
  text-align: center; background: var(--bg);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.bk-stg b { display: block; font-size: .875rem; font-weight: 500; }
.bk-stg i { font-style: normal; font-size: .71875rem; color: var(--text-3); display: block; margin-top: 3px; font-variant-numeric: tabular-nums; }
.bk-stg.on { border-color: var(--accent); background: var(--accent-wash); }
.bk-stg.on b { color: var(--accent-deep); }
.bk-stg.on i { color: var(--accent); }
.bk-stg.off { background: var(--bg-neutral); border-color: var(--line-soft); cursor: default; }
.bk-stg.off b, .bk-stg.off i { color: #B4BAB4; }

/* ---------- 工地行 ---------- */
.bk-sites { border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
.bk-siterow {
  display: flex; align-items: center; gap: var(--s4); width: 100%;
  padding: 14px 16px; border-bottom: 1px solid var(--line-soft);
  background: var(--bg); text-align: left; cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.bk-siterow:last-child { border-bottom: none; }
.bk-siterow:hover { background: var(--bg-3); }
.bk-siterow.on { background: var(--accent-wash); }
.bk-th {
  width: 52px; height: 40px; border-radius: var(--r-sm); background: var(--bg-2);
  flex: 0 0 52px; display: flex; align-items: center; justify-content: center;
  font-size: .625rem; color: var(--text-3); letter-spacing: .08em;
}
.bk-tx { flex: 1; min-width: 0; }
.bk-tx b { font-size: .875rem; font-weight: 500; display: block; }
.bk-tx > span { font-size: .75rem; color: var(--text-3); display: block; margin-top: 3px; }
.bk-prog { display: block; height: 4px; border-radius: 2px; background: var(--line-soft); margin-top: 8px; overflow: hidden; }
.bk-prog i { display: block; height: 100%; background: var(--accent); border-radius: 2px; }
.bk-pct { font-size: .75rem; color: var(--text-2); font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.bk-tick { width: 18px; height: 18px; border-radius: 50%; border: 1px solid var(--line); flex: 0 0 18px; }
.bk-siterow.on .bk-tick { background: var(--accent); border-color: var(--accent); }
.bk-empty { padding: 20px 16px; font-size: .8125rem; color: var(--text-3); line-height: 1.7; }

.bk-hint { font-size: .75rem; color: var(--text-3); margin-top: 10px; line-height: 1.65; display: flex; gap: 7px; align-items: flex-start; }
.bk-hint svg { width: 13px; height: 13px; flex: 0 0 13px; margin-top: 4px; stroke: var(--text-3); }
.bk-softout {
  margin-top: 14px; padding: 12px 16px; border-radius: var(--r-sm);
  background: var(--bg-2); display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
}
.bk-softout span { font-size: .78125rem; color: var(--text-2); }
.bk-softout a { font-size: .78125rem; color: var(--accent); display: inline-flex; align-items: center; gap: 6px; }

/* ---------- 日期 / 时段 ---------- */
.bk-dates { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; }
.bk-dt {
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 10px 0;
  text-align: center; line-height: 1.35; background: var(--bg);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.bk-dt b { display: block; font-size: .6875rem; color: var(--text-3); font-weight: 400; letter-spacing: .06em; }
.bk-dt strong { display: block; font-size: 1rem; font-weight: 500; font-variant-numeric: tabular-nums; margin-top: 2px; }
.bk-dt i { display: block; font-style: normal; font-size: .65625rem; color: #C2C7C2; margin-top: 2px; }
.bk-dt.on { border-color: var(--accent); background: var(--accent-wash); }
.bk-dt.on b, .bk-dt.on i { color: var(--accent); }
.bk-dt.on strong { color: var(--accent-deep); }

/* ---------- 到访时间：时 / 分两列滚轮（2026-10-21 取代「上午 / 下午」） ----------
   ★ 用户口径：像设闹钟一样，两个滚轮，刻度 5 分钟。
   ⚠️ .bk-wi 的 height（44）与 site-booking.js 的 WH_ITEM 必须一致 ——
      滚轮是拿 scrollTop ÷ 44 取下标来定时刻的，改一个不改另一个，
      选出来的时间会整体偏一格。
   ⚠️ 两列都要 padding: 44px 0，第一格与最后一格才滚得到中线；
      该值 = (132 − 44) / 2，改高度时一起改。 */
.bk-time {
  margin-top: 12px; border: 1px solid var(--line); border-radius: var(--r-sm);
  overflow: hidden; background: var(--bg);
}
.bk-wheels { position: relative; display: flex; align-items: center; height: 132px; }
/* 中线选中带（纯视觉，不挡点击） */
.bk-wheels::before {
  content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 44px;
  transform: translateY(-50%); pointer-events: none;
  border-top: 1px solid var(--accent-line); border-bottom: 1px solid var(--accent-line);
  background: var(--accent-wash);
}
.bk-wheel {
  position: relative; z-index: 1; flex: 1 1 0; height: 100%; overflow-y: auto;
  padding: 44px 0; scroll-snap-type: y mandatory; scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.bk-wheel::-webkit-scrollbar { display: none; }
.bk-wheel[data-w="h"] .bk-wi { padding-right: 22px; text-align: right; }
.bk-wheel[data-w="m"] .bk-wi { padding-left: 22px; text-align: left; }
.bk-wi {
  display: block; width: 100%; height: 44px; line-height: 44px; padding: 0;
  border: 0; background: none; font: inherit; font-size: 1.0625rem;
  color: var(--text-3); font-variant-numeric: tabular-nums;
  scroll-snap-align: center; cursor: pointer;
  transition: color var(--dur-fast) var(--ease);
}
.bk-wi.on { color: var(--accent-deep); font-weight: 600; }
.bk-wsep {
  position: relative; z-index: 1; flex: 0 0 auto; padding-bottom: 3px;
  font-size: 1.0625rem; color: var(--text-3);
}
.bk-time-f {
  display: flex; align-items: baseline; gap: 8px; padding: 10px 16px;
  border-top: 1px solid var(--line-soft); background: var(--bg-3);
}
.bk-time-f span { font-size: .75rem; color: var(--text-3); }
.bk-time-f b { font-size: .9375rem; color: var(--accent-deep); font-variant-numeric: tabular-nums; }
.bk-time-f i { margin-left: auto; font-style: normal; font-size: .6875rem; color: var(--text-3); }

/* ---------- 表单 ---------- */
.bk-divider { height: 1px; background: var(--line-soft); margin: var(--s5) 0; }
.bk-two { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); }
.bk-fld { margin-bottom: var(--s4); }
.bk-fld label { display: block; font-size: .75rem; color: var(--text-2); margin-bottom: 6px; letter-spacing: .04em; }
.bk-inp {
  width: 100%; min-height: 46px; border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 12px 14px; font-size: .9375rem; background: var(--bg); color: var(--text);
  transition: border-color var(--dur-fast) var(--ease);
}
.bk-inp::placeholder { color: #B4BAB4; }
.bk-inp:focus { outline: none; border-color: var(--accent); }
.bk-area { height: 66px; resize: vertical; line-height: 1.6; }

.bk-note {
  border: 1px solid var(--accent-line); background: var(--accent-wash); border-radius: var(--r-sm);
  padding: 12px 16px; font-size: .78125rem; color: var(--accent-deep);
  display: flex; gap: 9px; align-items: flex-start; margin-bottom: var(--s5); line-height: 1.65;
}
.bk-note svg { width: 14px; height: 14px; flex: 0 0 14px; margin-top: 3px; stroke: var(--accent); }
.bk-prefill {
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 14px 16px;
  display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: var(--s5);
}
.bk-who b { font-size: .875rem; font-weight: 500; display: block; }
.bk-who span { font-size: .78125rem; color: var(--text-3); font-variant-numeric: tabular-nums; display: block; margin-top: 3px; }
.bk-edit { font-size: .78125rem; color: var(--accent); background: none; border: none; cursor: pointer; padding: 0; }
/* ⚠️ --flag 只在 ai-manager.html 的 :root 里定义 —— 预约弹窗是全站挂的，
   别的页面拿不到它，所以带一个同值兜底（就是这个色号，别改成别的红）。 */
.bk-err { font-size: .8125rem; color: var(--flag, #A3473C); margin-top: var(--s3); line-height: 1.6; }

/* ---------- 成功态 ---------- */
/* ⚠️ 成功态没有 .bk-head / .bk-foot，整块就是内容槽的唯一子元素 ——
   它是 .bk-pane 这个 flex 列里唯一能滚的那一块（顶到视口上限时自己滚，
   不然小屏上「知道了」会被挤出视口）。 */
.bk-done {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: clamp(36px, 6vw, 52px) clamp(22px, 5vw, 40px) clamp(32px, 5vw, 44px); text-align: center;
}
.bk-ok {
  width: 60px; height: 60px; border-radius: 50%; background: var(--accent-wash);
  display: flex; align-items: center; justify-content: center; margin: 0 auto 22px;
}
.bk-ok svg { width: 28px; height: 28px; stroke: var(--accent); }
.bk-done .bk-title { font-size: 1.5625rem; }
.bk-done-desc { font-size: .875rem; color: var(--text-2); margin-top: 12px; line-height: 1.75; }
.bk-recap {
  margin: 26px auto 0; max-width: 440px; border: 1px solid var(--line);
  border-radius: var(--r-md); overflow: hidden; text-align: left;
}
.bk-r {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 13px 18px; border-bottom: 1px solid var(--line-soft); font-size: .84375rem;
}
.bk-r:last-child { border-bottom: none; }
.bk-r span { color: var(--text-3); flex: 0 0 auto; }
.bk-r b { font-weight: 500; text-align: right; }
.bk-callbox {
  margin: 22px auto 0; max-width: 440px; border: 1px solid var(--accent-line);
  background: var(--accent-wash); border-radius: var(--r-md); padding: 20px 22px; text-align: left;
}
.bk-callbox p { font-size: .8125rem; color: var(--accent-deep); line-height: 1.7; }
.bk-callbox a {
  display: flex; align-items: center; gap: 11px; margin-top: 14px;
  font-family: var(--font-latin); font-size: 1.625rem; letter-spacing: .05em;
  color: var(--accent-deep); font-variant-numeric: tabular-nums;
}
.bk-callbox a svg { width: 22px; height: 22px; flex: 0 0 22px; stroke: var(--accent); }
.bk-done-act { display: flex; justify-content: center; gap: var(--s3); flex-wrap: wrap; margin-top: 26px; }

/* ---------- 窄屏 ---------- */
@media (max-width: 640px) {
  /* ⚠️ 上下留白改小 → 令牌跟着改，白框的 max-height 才会跟着变
     （.bk-box 的封顶高度是从这两枚令牌算的，别只改 padding 不改令牌） */
  .bk { --bk-pad-t: var(--s4); --bk-pad-b: var(--s4); padding: var(--s4); }
  .bk-head { padding: var(--s6) var(--s5) 0; }
  .bk-body { padding: var(--s5) var(--s5) var(--s4); }
  .bk-foot { padding: var(--s4) var(--s5) var(--s5); }
  .bk-kinds, .bk-two { grid-template-columns: 1fr; }
  .bk-stgs { grid-template-columns: repeat(2, 1fr); }
  .bk-dates { grid-template-columns: repeat(4, 1fr); }
  .bk-kind p { min-height: 0; }
  .book-bar { padding: var(--s5); }
}

/* ============================================================
   13. 图片灯箱（全站共用）   —— 2026-10-10
   ============================================================
   ★ 用在三处：案例详情 / 工地详情 / 材料与标准（工艺标准区）。
   ★ 标记（.lightbox + #lb-close / #lb-prev / #lb-next / #lb-img / #lb-cap）
     各页自己写一份（就那么几行，带各自的注释）；**样式只在本处一份** ——
     2026-10-10 把 case-detail / site-detail 页面里的两份副本收拢到这里，
     改样子只改这一段，别再去页面里抄第二份。
   ★ 交互（由各页脚本接）：点图开；关＝✕ / Esc / 点大图以外的遮罩；
     翻＝‹ › / ← →。`<a>` 的 href 仍留原图地址 ⇒ 禁 JS、Ctrl/中键点
     照样能开原图（脚本只劫持「普通左键」那一下）。
   ★ 遮罩是**不透明深色**，不是本站浮层那套 blur + brightness ——
     看整页 slide 需要一块干净的黑底（图多为白底页，白底上放白字按钮会看不见）。
     所以这一处**不用** --blur-* / --dim 令牌，属有意为之。
   ★ 图靠 max-height 84vh 收在中间 ⇒ 底部图注(24px)与左上计数器都不会压到图上，
     白字恒落在深色遮罩上，不必再加阴影。
   ★★ 放大档 `.is-1x`（点图切换）—— 2026-10-11 补，**这条不能删**：
      「点开看大图」里**放大**那一步，旧方案是交给浏览器新标签（原生可缩可拖）。
      换成弹窗后必须自己补上，否则这一趟反而更看不清 ——
      工艺图在页面上本就通栏 1200px，fit 态在 1440 视口下只有 ~1300px，只大 10%；
      竖屏手机上更糟，图宽与页面上**一模一样**，点开等于没点。
      ⇒ 给一个 1:1 原始像素档（工艺册图是 1600×900），超出屏幕时遮罩自己滚。
   ------------------------------------------------------------ */
.lightbox {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(14, 37, 17, .94);
  display: flex; align-items: center; justify-content: center;
  padding: 5vh 5vw;
  /* ⚠️ 遮罩本身**不滚** —— 滚动交给里面的 .lb-stage。
     若让遮罩自己当滚动容器，绝对定位的 ✕ / ‹ › / 图注会跟着内容一起滚走，
     放大档一拖动就找不着关闭键（绝对定位子元素随滚动容器一起位移）。 */
  overflow: hidden;
}
/* ⚠️ 必须有这一行：上面那句 display:flex 会盖掉 [hidden] 默认的 display:none，
   删掉它灯箱一进页面就亮着、关不掉（踩坑记录见铁律「[hidden] 被 display 盖」）。 */
.lightbox[hidden] { display: none; }
/* 滚动层（放大档才真的会滚）—— 只有支持放大的页面写这一层，见下 .lightbox--zoom。
   inset:0 的包含块是遮罩的 **padding box** ⇒ 留白由 .lightbox 的 padding 出，
   这里不必再补 padding（补了就是双份）。 */
.lb-stage {
  position: absolute; inset: 0;
  display: flex;              /* 配合 .lb-img 的 margin:auto 居中 */
  overflow: auto;
  overscroll-behavior: contain;   /* 图滚到头别把后面那层页面也带着滚 */
}
.lb-img {
  /* ⚠️ 居中只能靠 margin:auto，**不能**靠 justify-content:center ——
     flex 里内容一旦溢出，justify-content 会把左边/上边**裁掉且滚不回去**
     （滚动范围从内容起点算，居中的超宽内容左半边直接不可达）。
     margin:auto 在溢出时自动退化为 0，两头都滚得到。 */
  margin: auto;
  display: block;
  max-width: 100%; max-height: 84vh;
  object-fit: contain; border-radius: var(--r-sm);
  -webkit-user-drag: none;   /* 放大后要拖动滚动，别让浏览器把图当可拖拽对象 */
}
/* 放大档（1:1 原始像素）—— 放开两条 max-*，图按自然尺寸铺开，超出即滚 */
.lb-img.is-1x { max-width: none; max-height: none; }
/* ★ 只有**支持点图放大**的页面才给放大镜光标（materials 给 #lightbox 加 .lightbox--zoom）。
   ⚠️ 别提到 .lb-img 上：案例 / 工地两页的灯箱不做放大，挂了 zoom-in 光标
      却点不动，是明确的假承诺。 */
.lightbox--zoom .lb-img { cursor: zoom-in; }
.lightbox--zoom .lb-img.is-1x { cursor: zoom-out; }
/* 控件与图注浮在滚动层之上（.lb-stage 也是定位元素，DOM 顺序靠后就会盖住控件） */
.lb-close, .lb-prev, .lb-next, .lb-cap, .lb-idx { z-index: 2; }
.lb-close {
  position: absolute; top: 20px; right: 26px;
  font-size: 2rem; color: #fff; line-height: 1; opacity: .7;
  transition: opacity var(--dur-fast) var(--ease);
}
.lb-close:hover, .lb-close:focus-visible { opacity: 1; }
.lb-prev, .lb-next {
  position: absolute; top: 50%; transform: translateY(-50%);
  font-size: 2.5rem; color: #fff; opacity: .55; padding: 0 18px;
  transition: opacity var(--dur-fast) var(--ease);
}
.lb-prev { left: 8px; }
.lb-next { right: 8px; }
.lb-prev:hover, .lb-prev:focus-visible, .lb-next:hover, .lb-next:focus-visible { opacity: 1; }
.lb-cap {
  position: absolute; bottom: 24px; left: 0; right: 0;
  text-align: center; color: rgba(255, 255, 255, .78); font-size: .875rem;
}
/* 「一册多页」连播时的图注：最多两行，超了打点（工艺标准区用）。
   ⚠️ 别改成 white-space:nowrap + ellipsis —— 居中的单行一旦溢出，
      浏览器只裁右边、左边会直接切掉半个字（不给省略号）。 */
.lb-cap--clamp {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; padding-inline: 6vw;
}
/* 连播计数器（左上角）—— 与页内「N 页」同口径，等宽数字防跳 */
.lb-idx {
  position: absolute; top: 26px; left: 26px;
  font-family: var(--font-latin); font-size: .8125rem; letter-spacing: .08em;
  color: rgba(255, 255, 255, .6); font-variant-numeric: tabular-nums;
}

/* ★★ 放大档（1:1）下控件必须自带底衬 —— 2026-10-11（截图里抓到的，不是想出来的）：
   fit 态图被 84vh 收在中间，四角留出深色遮罩，白字控件落得稳稳的；
   但切到 1:1 后图**铺满整个视口**，控件的背景变成**图片内容本身** ——
   这张 slide 是米白底，白色的 ‹ › 和 ✕ 几乎看不见（实测截图里只剩一道浅影）。
   ⇒ 只在放大档给按钮加半透明深色圆底、给文字加投影，其余两页灯箱不受影响
      （它们不做放大，永远停在 fit 态，四角恒是遮罩）。 */
.lightbox.is-zoomed .lb-close,
.lightbox.is-zoomed .lb-prev,
.lightbox.is-zoomed .lb-next {
  background: rgba(14, 37, 17, .62);
  border-radius: 999px;
  opacity: .92;
}
/* ✕ 是单个字符，得自己撑成圆 —— 左右箭头里有 padding，天然是胶囊形 */
.lightbox.is-zoomed .lb-close {
  display: grid; place-items: center;
  width: 44px; height: 44px; padding: 0;
  font-size: 1.5rem;
}
.lightbox.is-zoomed .lb-close:hover,
.lightbox.is-zoomed .lb-close:focus-visible,
.lightbox.is-zoomed .lb-prev:hover,
.lightbox.is-zoomed .lb-next:hover { opacity: 1; }
.lightbox.is-zoomed .lb-idx { text-shadow: 0 1px 4px rgba(0, 0, 0, .7); }
/* 图注另给一条**字幕式暗底**：文字投影压在米白 slide 上仍偏淡（截图里确认过），
   而且工序名是有用信息，值得一整条底。做成向上渐隐的底条，不切图。
   ⚠️ 只在放大档加 —— fit 态四角本就是深遮罩，再加一层会有脏边。 */
.lightbox.is-zoomed .lb-cap {
  bottom: 0; padding: 14px 0 22px;
  background: linear-gradient(to top, rgba(14, 37, 17, .74), rgba(14, 37, 17, 0));
  color: rgba(255, 255, 255, .9);
  text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
  /* ⚠️ 这里**别改 display** —— 上面的 .lb-cap--clamp 靠 display:-webkit-box
      才有多行钳位；底下加个 background 与它并不冲突。 */
}

/* 窄屏：按钮缩小往边上贴，图给足宽，别让控件吃掉画面 */
@media (max-width: 640px) {
  .lightbox { padding: 4vh 3vw; }
  .lb-img { max-width: 100%; max-height: 78vh; }
  .lb-prev, .lb-next { font-size: 1.75rem; padding: 0 8px; }
  .lb-close { top: 12px; right: 14px; font-size: 1.75rem; }
  .lb-idx { top: 16px; left: 16px; font-size: .75rem; }
  .lb-cap { bottom: 14px; font-size: .8125rem; }
}

/* ============================================================
   14. 预览工具条（官网详情页共用）   —— 2026-10-14
   ------------------------------------------------------------
   「官网视角」预览态顶部那条淡绿工具条。原来只长在 site-detail.html 的
   局部 <style> 里；2026-10-14 案例侧也要预览（case-detail.html 原来**没有**预览态，
   导致列表卡片上「官网视角」在未上线时只能置灰），两份抄的话改一处必忘另一处
   ⇒ 收进共享样式表，与第 13 节灯箱同一个套路。
   ⚠️ 用到的变量（--accent-wash / --wrap / --ink-2 / --bg-neutral …）都由本表的
      :root 提供，两个页面都能直接用。
   ⚠️ **只搬样式，不搬行为**：工具条里那两段「摄像头已接入 / 未接入」的切换
      是**工地侧独有**的（案例没有摄像头），它的标记与事件留在 site-detail.html。
   ============================================================ */
.pv-bar { position: sticky; top: 0; z-index: 60; background: var(--accent-wash); border-bottom: 1px solid var(--accent-line); }
.pv-in { width: min(100% - 48px, var(--wrap)); margin-inline: auto; display: flex; align-items: center; justify-content: space-between; gap: var(--s5); padding-block: 13px; flex-wrap: wrap; }
.pv-l, .pv-r { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; }
.pv-tag { flex: 0 0 auto; padding: 3px 8px; border-radius: 4px; background: var(--bg); border: 1px solid var(--accent-line); color: var(--accent-deep); font-size: .75rem; letter-spacing: .06em; }
.pv-txt { font-size: .875rem; color: var(--ink-2); }
.pv-txt.pv-bad { color: var(--warn); }
.pv-state { font-size: .8125rem; color: var(--accent-deep); }
.pv-state.is-off { color: var(--ink-3); }
/* 「你正在看的是哪一份」（工作区 / 待审版 / 官网正在显示的版）。
   三种排版一样、内容可能不同 ⇒ 必须标出来，否则会看混。浅灰小字，不抢状态标。 */
.pv-src { font-size: .8125rem; color: var(--ink-3); }
/* 两段切换（照画布 S7）：一颗浅底胶囊里放两段，选中的白底 + 绿描边 */
.pv-segs { display: inline-flex; align-items: center; gap: 0; padding: 3px; border-radius: 8px; background: var(--bg-neutral); }
.pv-seg { padding: 4px 12px; border: 1px solid transparent; border-radius: 6px; background: transparent;
  color: var(--ink-3); font-size: .75rem; font-family: inherit; cursor: pointer; transition: all .15s var(--ease); }
.pv-seg:hover { color: var(--accent-deep); }
.pv-seg.is-on { background: var(--bg); border-color: var(--accent-line); color: var(--accent-deep); font-weight: 500; }
.pv-hint { font-size: .75rem; color: var(--ink-3); }
.pv-back { flex: 0 0 auto; padding: 7px 14px; border-radius: var(--r-sm); background: var(--bg); border: 1px solid var(--accent-line); color: var(--accent-deep); font-size: .8125rem; text-decoration: none; }
.pv-back:hover { border-color: var(--accent); }

/* ============================================================
   6. 业主端「五个板块」（2026-10-17 新增）
   ------------------------------------------------------------
   来源：Ardot 画布 733424413486992 / page 160:1
         · 内页导航 = 161:355（高 64 · 底线 1px）
         · AI 折叠条 = 161:4（白底 · 圆角 22 · 两行）
         · 板块卡   = 161:18/26/35/44/53（12 栅格 8+4 / 4+4+4）
   ⚠️ 这一节只用 token，不写死颜色 —— 改色只动顶部令牌区。
   ⚠️ 板块的文案与链接不在 CSS/HTML 里，一律来自 data.js 的
      window.YANE_SECTIONS（铁律 1）。
   ============================================================ */

/* ---------- 6.1 内页导航（板块页专用 · 替代全站导航） ----------
   ★★ 2026-10-17 第三次改（用户定）：「我的家子页面的导航栏太小气了，
      参考主页的导航改造一下」。
   ------------------------------------------------------------
   病根不是配色，是**量级与语言不一致**：内页导航当时是 64px 高 / 13px 字 /
   淡绿胶囊高亮；主页 `.nav` 是 86px 高 / 16px 字 / 绿色 1px 下划线。
   两个页面来回一点，导航条突然矮 22px、字小 3px、还换了一套高亮语言，
   观感就是「缩水的次级工具条」。
   ⇒ 本节现在**整套复刻 `.nav` / `.nav-link` 的几何与交互**，只保留两处属于
     内页的东西：左边那颗「返回主页」、右边那行「当前项目」。
   改了什么（逐条对账）：
     · 高度      64px  → `var(--nav-h)`（86px；≤860px 自动跟到 70px）
     · 背景      白 .92 → .88（与 `.nav` 同一个值）
     · 底线      常驻 1px → 默认透明、`.is-scrolled` 才出现
                （`bindMyNavScroll()` 早就在切这个类，之前 CSS 根本没接）
     · tab 字号  13px  → 16px（1rem），间距 8px → `--s5`
     · tab 高亮  胶囊底 → 1px 绿色下划线，hover 自左向右展开，
                与 `.nav-link::after` 一字不差的写法
     · tab 定位  紧跟「返回主页」往左排 → 绝对居中钉在版心正中
                （与 `.nav-links` 同一条 `left:50% / top:50% / translate`；
                 主页那条注释里踩过的「两个 50% 缺一不可」照样适用）
     · 返回主页  灰底块 → 1px 描边 + `--r-sm` + 13px 字，hover 转绿
     · 项目名    12px → 13px
   ⚠️ class 名一个没改 —— `.mynav*` 由 `site.js` 的 `myNavHtml()` 生成，
      5 个板块页（待办 / 需求 / 资金 / 进度 / 资料）同时生效，DOM 不用重画。
   ⚠️ 副产品（是修正，不是副作用）：`ai-manager.html` 的 `.yan-col` 一直写着
      `top: calc(var(--nav-h) + 24px)` / `height: calc(100vh - var(--nav-h) - 72px)`，
      也就是**按 86px 算**；可导航实际只有 64px，那栏一直多留 22px 顶空、
      还矮 22px。现在导航真长到 86px，两边对上了。
   ⚠️ 5 格 tab 的**顺序与条数**仍由 `data.js` 的 `YANE_SECTIONS` 决定（铁律 1），
      本次只动外观，一条都没加、没删、没重排。 */

.mynav {
  position: sticky; top: 0; z-index: 100;
  height: var(--nav-h);
  background: rgba(255,255,255,.88);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.mynav.is-scrolled { border-bottom-color: var(--line); }
.mynav-inner {
  height: var(--nav-h);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s5);
  /* ⚠️ 定位基准：给下面 .mynav-tabs 的绝对居中兜底，别删（同 .nav-inner 那条）。 */
  position: relative;
}
.mynav-left { display: flex; align-items: center; gap: var(--s4); min-width: 0; }
.mynav-back {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px; border-radius: var(--r-sm);
  border: 1px solid var(--line-soft); background: transparent; color: var(--text-2);
  font-size: .875rem; text-decoration: none; white-space: nowrap;
  transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.mynav-back:hover { border-color: var(--accent); color: var(--accent-deep); }
.mynav-back svg { width: 13px; height: 13px; flex: 0 0 auto; }
/* 墓碑（2026-10-17）：这里曾有 `.mynav-sep`（「返回主页」与 tab 之间一根 1px 竖线）。
   tab 改成钉在版心正中后，左下角只剩「返回主页」一颗，那根竖线右边没有内容可分开，
   留着就是凭空一条悬空的短线（实测很脏）。⇒ 规则降级为 `display:none`，
   但 **DOM 里那个 span 保留不删** —— `myNavHtml()` 仍在输出它，
   删 CSS 不删 DOM 才是安全的；万一以后 tab 回到左侧贴排，去掉这条就复原。 */
.mynav-sep { display: none; }
.mynav-tabs {
  display: flex; align-items: center; gap: var(--s5);
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
}
.mynav-tab {
  font-size: 1rem; color: var(--text-2); position: relative;
  padding-block: 6px;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease);
}
.mynav-tab::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: 0;
  height: 1px; background: var(--accent); transition: right var(--dur) var(--ease-out);
}
.mynav-tab:hover { color: var(--text); }
.mynav-tab:hover::after, .mynav-tab.is-active::after { right: 0; }
.mynav-tab.is-active { color: var(--text); }
.mynav-proj {
  font-size: .8125rem; color: var(--text-3); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 34ch;
}

/* 6.1b 内页导航的响应式 —— 与 `.nav-links` 逐档同步收紧（收敛逻辑同第 543 行那条注释）：
   861–1080 这一段 5 格 tab 仍居中显示，靠缩间距/字号保证不撞左右两侧；
   ≤860 起放弃居中，改回「返回主页 + 可横滚的 tab」单行 ——
   这条导航没有汉堡可收（它就是板块页唯一的路由），只能横滚，不能隐藏。 */
@media (max-width: 1080px) {
  .mynav-tabs { gap: var(--s4); }
  .mynav-tab { font-size: .9375rem; }
}
@media (max-width: 920px) {
  .mynav-tabs { gap: var(--s3); }
  .mynav-tab { font-size: .875rem; }
  .mynav-proj { max-width: 18ch; }
}
@media (max-width: 860px) {
  .mynav-tabs {
    position: static; transform: none;
    flex: 1 1 auto; min-width: 0;
    overflow-x: auto; scrollbar-width: none;
  }
  .mynav-tabs::-webkit-scrollbar { display: none; }
  .mynav-proj { display: none; }
  .mynav-back { padding: 7px 12px; font-size: .8125rem; }
}
/* ≤560（手机竖屏）：5 格 tab 横滚也放不下，而这条导航**没有汉堡可收**
   —— 它就是板块页唯一的路由。省出宽度最快的办法是让「返回主页」退成
   36×36 的纯箭头（390 宽实测：文字版吃掉 99px，5 格只剩 228px，只能看到
   三格半；收成箭头后剩 290px，'项目进度' 整条露出来）。
   ★ 用 font-size:0 藏文字而不是删 DOM：屏幕阅读器与搜索引擎仍读得到
     「返回主页」这个链接名，`myNavHtml()` 一个字也不用改。
   ★ 点击区仍是 36×36（>最小 32px 触控目标），不算缩水。 */
@media (max-width: 560px) {
  .mynav-back {
    width: 36px; height: 36px; padding: 0; gap: 0;
    justify-content: center; font-size: 0;
  }
}

/* ---------- 6.2 AI 折叠条（小言） ---------- */
.aibar-sec { padding-top: var(--s7); }
.aibar {
  display: flex; flex-direction: column; gap: 14px;
  padding: 18px 18px 14px;
  border: 1px solid var(--line); border-radius: 22px;
  background: var(--bg);
  box-shadow: 0 8px 24px rgba(0,0,0,.06);
}
.aibar-row { display: flex; align-items: center; gap: 12px; }
.aibar-ico {
  width: 28px; height: 28px; flex: 0 0 auto;
  border-radius: 8px; background: var(--accent-wash);
  display: grid; place-items: center; color: var(--accent);
}
.aibar-ico svg { width: 16px; height: 16px; }
.aibar-tip {
  flex: 1 1 auto; min-width: 0;
  font-size: .875rem; color: var(--text-3); line-height: 1.5;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.aibar-open {
  flex: 0 0 auto; padding: 6px 12px; border-radius: 999px;
  background: var(--bg-2); border: 0;
  font-family: inherit; font-size: .75rem; font-weight: 500;
  color: var(--accent-deep); cursor: pointer;
}
.aibar-open:hover { background: var(--accent-wash); }
.aibar-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.aibar-chips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.aibar-chip {
  padding: 6px 12px; border-radius: 999px;
  background: var(--bg-3); border: 1px solid var(--line);
  font-family: inherit; font-size: .75rem; color: var(--text-2); cursor: pointer;
}
.aibar-chip:hover { border-color: var(--accent-line); color: var(--accent-deep); }
.aibar-send {
  width: 34px; height: 34px; flex: 0 0 auto;
  border-radius: 999px; border: 0; background: var(--accent);
  display: grid; place-items: center; color: #fff; cursor: pointer;
}
.aibar-send:hover { background: var(--accent-deep); }
.aibar-send svg { width: 16px; height: 16px; }

/* ---------- 6.3 五个板块卡 ---------- */
.sect-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; padding: var(--s7) 0 18px; }
.sect-title { font-family: var(--font-display); font-size: 1.25rem; color: var(--text); }
.sect-note { font-size: .75rem; color: var(--text-3); }
.sect-grid { display: grid; grid-template-columns: repeat(12, minmax(0,1fr)); gap: 20px; }
.sect-card {
  grid-column: span 4;
  display: flex; flex-direction: column; gap: 12px;
  padding: 24px; border-radius: 12px;
  background: var(--bg); border: 1px solid var(--line);
  text-decoration: none; color: inherit;
  transition: border-color var(--dur-fast) var(--ease);
}
.sect-card.is-big { grid-column: span 8; min-height: 196px; }
.sect-card:hover { border-color: var(--accent-line); }
.sect-ico {
  width: 40px; height: 40px; flex: 0 0 auto;
  border-radius: 10px; background: var(--bg-2);
  display: grid; place-items: center; color: var(--accent);
}
.sect-ico svg { width: 20px; height: 20px; }
.sect-name { font-family: var(--font-display); font-size: 1.25rem; color: var(--text); }
.sect-sum { flex: 1 1 auto; font-size: .8125rem; line-height: 1.69; color: var(--text-3); }
.sect-status { font-size: .8125rem; font-weight: 500; color: var(--accent); }

/* ---------- 6.3b 板块卡 · 访客态（2026-10-17 第二次改版） ----------
   未登录 / 未交意向金时这张卡墙也露出来，五张卡分两种形态：
     · 能进（data.js 的 guestOpen）→ .sect-go：绿字 + 箭头，与 .sect-status 同一档，
       但鼠标移上去箭头会走 3px —— 它是"入口"，不是"状态"。
     · 锁住 → .is-locked：图标底由浅绿降成中性灰、卡底一枚灰锁「登录后查看」。
       卡仍是白底实线描边、**不用虚线也不压暗**：这是"预告"，不是"坏掉的占位"，
       虚线和灰罩会让整页像加载失败。
   ⚠️ 锁定卡是 <button>（不是 <a>，见 site.js buildSectionCards 的注释），
      所以要把浏览器默认的按钮样式归零 —— 否则字体、内边距、底色全都跟 <a> 不一样，
      五张卡会一眼看出"三种东西"。 */
.sect-go {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: .8125rem; font-weight: 500; color: var(--accent);
}
.sect-go svg {
  width: 13px; height: 13px; flex: 0 0 auto;
  transition: transform var(--dur-fast) var(--ease);
}
.sect-card:hover .sect-go svg { transform: translateX(3px); }
.sect-lock {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: .8125rem; color: var(--text-3);
  transition: color var(--dur-fast) var(--ease);
}
.sect-lock svg { width: 13px; height: 13px; flex: 0 0 auto; }
.sect-card.is-locked:hover { background: var(--bg-3); }
.sect-card.is-locked:hover .sect-lock { color: var(--accent-deep); }
.sect-card.is-locked .sect-ico { background: var(--bg-neutral); color: var(--text-3); }
button.sect-card {
  font: inherit; text-align: left; cursor: pointer;
  margin: 0; /* button 在部分浏览器有默认外边距 */
}

/* ★ 2026-10-17（用户定）：「五个板块也是」—— 主推卡常亮。
   谁亮：data.js 里标了 `featured: true` 的那张（目前只有「我的需求」），
        且**只在访客态**（site.js 里是 `o.guest && s.featured`）。
   为什么只有一张：它是五张里唯一"现在就该点"的入口，也是四步里第 01 步的落点；
        五张全加底＝一张都没被突出。
   ★ 底色用 --accent-wash、描边 --accent-line（浅的那一档）：
     与 .sect-lock 的灰、普通卡的白拉开一层，但不至于抢过页面里唯一的实心绿（导航那颗登录）。
   ★ 图标底必须改成 --bg：原本 .sect-ico 是 --bg-2（#F5FAF6），
     放到 #EBF9ED 的浅绿卡上几乎看不出边界，图标会像"糊"在底上。
   ⚠️ hover 只加深描边、**不改底色** —— 改成 --bg-3 会让这张卡在鼠标移上去时"熄灭"，
      等于高亮只在静止时成立，反而更怪。 */
.sect-card.is-featured { background: var(--accent-wash); border-color: var(--accent-line); }
.sect-card.is-featured .sect-ico { background: var(--bg); }
.sect-card.is-featured:hover { background: var(--accent-wash); border-color: var(--accent); }
.sect-card.is-featured .sect-points { color: var(--text-2); }

/* 访客态主卡的要点行（四步回看 / 随时补充提交 / 保留每次修改）
   —— 只是"这里有什么"，不带手型、不挂 hover；
   margin-top:auto 把这些推到卡底：同行最高的卡决定卡片高度，
   内容短的主卡若留在中部，底下会空一大块，看着像没做完。 */
.sect-points {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: .75rem; color: var(--text-3);
  margin-top: auto;
}
.sect-points > span { display: inline-flex; align-items: center; gap: 10px; }
.sect-points > span + span::before {
  content: ""; width: 3px; height: 3px; border-radius: 999px;
  background: var(--line); display: inline-block;
}

@media (max-width: 1100px) {
  .sect-card, .sect-card.is-big { grid-column: span 6; min-height: 0; }
}
@media (max-width: 760px) {
  .sect-card, .sect-card.is-big { grid-column: span 12; }
  /* 原来这里还有三条 `.mynav-*`（gap 10 / tab 横滚 / 藏项目名）。
     2026-10-17 改造后整套搬到 6.1b 的 ≤860 断点里 —— 那里才是内页导航
     的翻脸点（与官网导航收进汉堡的 860 同一条线），920/1080 还有两档收紧。
     留在这里会变成第二处真源：两边数值一旦不同，760 以下就用的是旧的。 */
  .aibar-tip { white-space: normal; }
}

/* ===================================================================
   资料槽（.doc-*）—— 2026-10-17 从 my-home.html 内联样式整块搬到这里
   -------------------------------------------------------------------
   为什么搬：「合同与图纸」那段已从「我的家」迁到「我的资料」（my-docs.html），
     样式跟着功能走 —— 内联在旧页面里就是死代码，而且新页面还要再抄一份。
   搬了什么（一字未改，历史沿革原样带上）：
     .doc-list / .doc-row / .doc-ico / .doc-txt / .doc-meta / .doc-act / .doc-dl
     ＋ .doc-row.is-ready 三态（绿图标 / 整行可点 / hover）＋ 两处断点。
   不动的：`.doc-icons`（未交客户的「六样资料」预告图标）仍留在
     my-progress.html 的内联样式里 —— 那是另一件事，不是文件下载。
   ★ 业主视图六份资料**排成一排**：设计合同 / 施工图 / 效果图 / 报价单 /
     施工合同 / 施工保险。
     · 2026-10-05：图纸拆成「效果图 / 施工图」→ 四列变五列；
     · 2026-10-08：施工合同后加「施工保险」→ 五列变六列。
     六张一排时一列约 199px（1200 版心，gap 1px），最长标题「施工保险」放得下；
     再窄就靠断点降列（≤1024 三列 / ≤640 两列），别硬塞成 7 列。
   ⚠️ 列数只在下面 `.doc-list` 一处写（引导视图的 `.doc-icons` 已于 2026-10-17
      从「我的家」删除）。
   ⚠️ 这个注释块只能有**一个**收尾符号（写在最后一行）：中间多写一个会提前闭合注释，
      后面那半段就成了注释外的垃圾 CSS，解析器会把它当选择器一直吞到下一个左花括号，
      **整条 .doc-list 规则随之消失**（症状：六张卡竖成一列、lefts 全相等、零报错）。
      2026-10-08 加槽时就踩过这一脚。
   =================================================================== */
.doc-list {
  display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 1px;
  background: var(--line-soft); border: 1px solid var(--line-soft);
  border-radius: var(--r-md); overflow: hidden;
}
.doc-row {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--s4);
  background: var(--bg); padding: var(--s5); min-width: 0;
}
.doc-ico {
  flex: 0 0 auto; width: 38px; height: 38px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-sm); background: var(--bg-2); color: var(--ink-2);
}
.doc-ico svg { width: 20px; height: 20px; }
.doc-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; width: 100%; }
.doc-txt strong { font-size: .9375rem; font-weight: 500; color: var(--ink); }
.doc-meta { font-size: .8125rem; line-height: 1.5; color: var(--ink-3); }
/* 下载入口（2026-10-04 接通 GET /api/site/files/:fid/raw）。
   ★ margin-top:auto 把按钮推到卡片**贴底**：六张卡的标题长短不一，
     不贴底的话六枚「下载」会在不同高度上参差。
   ★ 只在有文件的行渲染（renderDocs 里 is-ready 才填 innerHTML），
     空态行的 .doc-act 里没有内容，自然不占位。 */
.doc-act { display: flex; align-items: center; gap: var(--s4); margin-top: auto; padding-top: var(--s2); }
.doc-dl {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: .8125rem; letter-spacing: .04em; color: var(--accent);
  border-bottom: 1px solid transparent; transition: border-color var(--dur-fast) var(--ease);
}
.doc-dl:hover { border-bottom-color: var(--accent); }
.doc-dl svg { width: 13px; height: 13px; }
/* ★ 2026-10-11：act 里现在有两颗（预览＝button、下载＝a）。
   button 自带浏览器默认底色/边框/内边距 → 必须显式归零，否则两颗长得不一样。 */
button.doc-dl {
  background: none; border: 0; padding: 0; margin: 0; cursor: pointer;
  border-bottom: 1px solid transparent; font: inherit;
  font-size: .8125rem; letter-spacing: .04em; color: var(--accent);
}
button.doc-dl:hover { border-bottom-color: var(--accent); }
/* 有文件时：图标转品牌绿，告知「这份是齐的」 */
.doc-row.is-ready .doc-ico { background: var(--accent-wash); color: var(--accent); }
.doc-row.is-ready .doc-meta { color: var(--ink-2); }
/* ★ 2026-10-11：有文件的行**整行可点**（开预览灯箱）→ 给手型与一点反馈，
   否则业主根本不知道这一行能点（原先只有右下角那颗「下载」是入口）。 */
.doc-row.is-ready { cursor: pointer; transition: background var(--dur-fast) var(--ease); }
.doc-row.is-ready:hover { background: var(--bg-2); }
.doc-row.is-ready:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* 断点：六列在平板上会把 meta 挤成一条窄缝 → 退三列（六份 = 3 + 3）；
   手机上三列只剩约 100px，文件名必然折三行 → 退两列。 */
@media (max-width: 1024px) {
  .doc-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .doc-row { padding: var(--s4); gap: var(--s3); }
  .doc-ico { width: 32px; height: 32px; }
  .doc-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
