/* ============================================================
 * 全站统一顶栏底栏组件 (nav-v2 + site-footer)
 * 从 V2 预览页抽出，全站所有页面统一引用
 * 引用方式：
 *   <link rel="stylesheet" href="css/nav-footer-component.css?v=YYYYMMDD">
 *   <script src="js/nav-footer-component.js?v=20260818-component-fix2"></script>
 *   <script>window.NAV_FOOTER_CONFIG = { ... };</script>
 * ============================================================ */

/* ============= 顶栏 nav-v2 ============= */

.nav-v2{
  position:fixed;top:0;left:0;right:0;
  display:grid;grid-template-columns:1fr auto 1fr;
  align-items:center;padding:28px 20px 28px 20px;
  z-index:200;pointer-events:none;
  mix-blend-mode:difference;  /* 整个顶栏内容(白LOGO+白字)与背景逐像素差值反色 */
  /* v122: 滚动时上下滑出/滑入动画 transition */
  /* v129: .35s → .5s 让动画更明显可见 */
  /* v130: 加 transform:translateY(0) 默认值，让 none→-100% transition 能插值 */
  transform:translateY(0);
  /* v133: transition 1s → .7s */
  transition:transform .7s var(--ease);
}

.nav-v2.is-scrolled{
  /* v54 (2026-08-19): 透明顶栏 + 保留 mix-blend-mode:difference 自适应反色，不再有实色块 */
  mix-blend-mode:difference;
  box-shadow:0 1px 0 rgba(0,0,0,.06);
  /* v131 BUG FIX: 之前只声明 transition:box-shadow, 把 .nav-v2 的 transform transition 整条覆盖了 →
     scroll >10px 加 .is-scrolled 之后, JS toggle .nav-v2--collapsed 时 transform 直接跳变(无动画)。
     现在显式同时声明 transform + box-shadow, 让 nav 上滑/下滑动画在 is-scrolled 状态仍生效 */
  transition:transform .7s var(--ease), box-shadow .3s ease;
}
/* v54: is-scrolled 不再强制改字色，由 mix-blend-mode:difference 自适应反色 */

.nav-v2 > *{pointer-events:auto}

.nav-v2__logo{
  position:relative;display:inline-block;height:28px;line-height:0;width:auto;justify-self:start;
  /* v105: grid item 默认 stretch 撑满 1fr 列宽 → 点击覆盖中部菜单。width:auto + justify-self:start 让 LOGO 收缩到图片实际大小 */
}

/* .nav-v2 绝不能 isolation:isolate，否则 blend 无背景可混→白字 invisible */
.nav-v2__logo-img{
  display:block;height:28px;width:auto;
}

.nav-v2__menu{
  display:flex;gap:56px;align-items:center;
  transition:transform .5s var(--ease),opacity .3s ease;
  color:#fff;
  font-family:var(--font-en);
}

.nav-v2__en,.nav-v2__zh{color:#fff}

.nav-v2__item{
  position:relative;height:16px;overflow:hidden;
  font-size:.8rem;font-weight:300;
  display:inline-block;text-align:center;
  white-space:nowrap;
}

.nav-v2__en{
  display:block;transition:transform .4s var(--ease),opacity .3s ease;
  text-align:center;
  font-family:var(--font-en);
  font-size:.8rem;
}

.nav-v2__zh{
  display:block;transition:transform .4s var(--ease),opacity .3s ease;
  text-align:center;
  font-family:'PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif;
  font-size:.8rem;
}

.nav-v2__zh{
  font-size:.8rem;font-weight:300;letter-spacing:.05em;
}

.nav-v2__item:hover .nav-v2__en{transform:translateY(-100%);opacity:0}

.nav-v2__item:hover .nav-v2__zh{transform:translateY(-100%);opacity:1}

/* 滚动时菜单显隐：下滑隐藏（除顶部外），上滑显示；与 V2 预览页行为一致 */
.nav-v2--collapsed .nav-v2__menu{
  transform:translateY(-200%);opacity:0;pointer-events:none;
}

.nav-v2__right{
  justify-self:end;display:flex;gap:18px;align-items:center;
  color:#fff;
}

.nav-v2__icon{color:#fff;padding:6px;display:inline-flex;align-items:center;justify-content:center}

.search-zone{position:relative;display:inline-flex;align-items:center}

.nav-v2__search{
  position:absolute;right:100%;top:50%;
  transform:translateY(-50%) scale(.75);
  transform-origin:right center;
  width:0;height:25px;
  margin-right:10px;padding:0 8px;box-sizing:border-box;
  border:none;border-bottom:1px solid #fff;
  background:transparent;color:#fff;
  font-size:16px;font-family:var(--font-zh);
  outline:none;border-radius:0;
  opacity:0;pointer-events:none;
  transition:width .35s var(--ease),opacity .25s ease;
}

.nav-v2__search::placeholder{color:rgba(255,255,255,.55)}

.nav-v2__search.is-open{width:256px;opacity:1;pointer-events:auto}

/* v106: 搜索下拉卡片面板 */
.search-dropdown{
  position:absolute;
  top:calc(100% + 8px);
  right:0;
  width:380px;
  max-height:520px;
  overflow-y:auto;
  background:rgba(20,20,20,.97);
  border:1px solid rgba(255,255,255,.12);
  border-radius:10px;
  box-shadow:0 12px 40px rgba(0,0,0,.45);
  padding:8px;
  z-index:300;
  color:#fff;                                  /* v109: 默认深色模式显式白色，避免被 nav 继承的 #fff 在浅色模式穿帮 */
  backdrop-filter:blur(12px);
  -webkit-backdrop-filter:blur(12px);
}
:root[data-theme="light"] .search-dropdown{
  background:rgba(255,255,255,.98);
  border-color:rgba(0,0,0,.1);
  box-shadow:0 12px 40px rgba(0,0,0,.18);
  color:#1a1a1a;                                /* v109: 浅色模式显式深色文字（#1a1a1a 与白底对比对得起眼），CSS var 在 body 无值所以不用 var */
}
.search-dropdown[hidden]{display:none}
.search-dropdown__item{
  display:flex;
  align-items:center;
  gap:12px;
  padding:10px 12px;
  border-radius:6px;
  text-decoration:none;
  color:inherit;
  transition:background .15s ease;
}
.search-dropdown__item:hover{background:rgba(255,255,255,.08)}
:root[data-theme="light"] .search-dropdown__item:hover{background:rgba(0,0,0,.05)}
.search-dropdown__main{flex:1 1 auto;min-width:0}
.search-dropdown__title{
  font-size:14px;font-weight:600;color:inherit;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  margin-bottom:4px;
}
.search-dropdown__sub{
  font-size:12px;color:rgba(255,255,255,.6);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  margin-bottom:3px;
}
:root[data-theme="light"] .search-dropdown__sub{color:rgba(0,0,0,.55)}
.search-dropdown__designer{
  font-size:11px;font-weight:500;
  color:#d8a96a;  /* 品牌黄 */
  letter-spacing:.04em;
}
.search-dropdown__thumb{
  width:64px;height:64px;
  object-fit:cover;
  border-radius:4px;
  flex-shrink:0;
  background:rgba(255,255,255,.05);
}
.search-dropdown__thumb--empty{
  background:rgba(255,255,255,.08);
}
:root[data-theme="light"] .search-dropdown__thumb--empty{background:rgba(0,0,0,.06)}
/* v335: 灵感库直达卡片的图标缩略块（搜索 灵感/灵感库 时置顶那张） */
.search-dropdown__thumb--insp{
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(135deg,#c9a96e,#b07a4b);color:#fff;
}
.search-dropdown__thumb--insp svg{width:28px;height:28px}
:root[data-theme="light"] .search-dropdown__thumb--insp{background:linear-gradient(135deg,#c9a96e,#b07a4b)}
.search-dropdown__empty{
  padding:30px 12px;
  text-align:center;
  font-size:13px;
  color:rgba(255,255,255,.5);
}
:root[data-theme="light"] .search-dropdown__empty{color:rgba(0,0,0,.45)}

.nav-v2__svg{width:18px;height:18px;display:block}

/* === 主题图标切换：浅色显示月亮（点击→变深色），深色显示太阳（点击→变浅色） === */
.nav-v2__svg--sun{display:none}
.nav-v2__svg--moon{display:block}
[data-theme="dark"] .nav-v2__svg--sun{display:block}
[data-theme="dark"] .nav-v2__svg--moon{display:none}


/* ============================================================
 * v120 mobile 适配 (@media max-width:768px) — 0 改动桌面
 * ============================================================ */

/* === 顶栏：3 横线在左 / LOGO 居中 / 搜索+主题在右 + solid bg === */
.nav-v2__menu-toggle{display:none}  /* 默认隐藏，desktop 看不到 */


/* === desktop: hide hamburger === */
@media (min-width:769px){
  .nav-v2__menu-toggle{display:none}
  .nav-v2__menu-overlay{display:none}
}

/* ============= 底栏 site-footer（V2 真·物理帘子） ============= */
/* footer 永远 visible（position:fixed + z-index:0 在最底）
   main z-index:1 + background:var(--bg) 滚动时盖住 footer 顶部
   spacer transparent 400px 撑出滚动行程，main 滚完后 footer 自然露出
   不要再加 visibility:hidden / transition / JS toggle — 这就是真·物理帘子 */
.site-footer{
  position:fixed;left:0;right:0;bottom:0;z-index:0;
  height:415px;                /* v140: 400 → 415 (+15 让 footer container 真正变长 15) */
  background:#9d9287;border-top:1px solid var(--line);
  padding:48px 60px 0;          /* v140: 还原 v121 默认 48 (v139 错改 63 撤回) */
  display:flex;align-items:center;
  color:#fff;
  pointer-events:auto;
}
/* main 真·物理帘子：z-index:1 + background:var(--bg)
   在滚动时盖住 footer（z:0）顶部，main 自身 z 抬高会自动分离 stacking，
   scroll 出 main 时 footer 透过 .footer-reveal-spacer（transparent 250px）自然露出 */
main{
  position:relative;
  z-index:1;
  background:var(--bg);
}
/* v159 (2026-08-22): 老板 v158 反馈 '底栏还是在帘子上面'
   根因: mask(z-index:10) 在 main(z-index:1) 里, mask 在 root 比较时代表 main(1),
   footer(z-index:2) > main(1) → footer 永远盖整个 main 包括 mask.
   修复: JS IntersectionObserver 监听 .screen-mask 在视口时给 <html> 加 .mask-active,
   main z-index 临时升到 5 (> footer 2) → main 整体盖 footer → mask 视觉盖 footer ✓
   + mask 不在视口时 main 回到 z-index:1, footer(2) 盖 main → footer 可见 + click 命中 ✓ (v156 fix 保持)
   + mask 在视口时 main(5) > footer(2) → main padding 透明区 hit-test 仍命中 footer (footer 视觉被盖但 hit-test 优先 fixed footer 位置), 屏 2 中段 main 没滚到底, footer 区可点 */
html.mask-active main{z-index:5}

/* 帘子行程：main 滚完后，spacer 占据视口底 80px 让 footer 露出；spacer 透明不挡 footer */
.footer-reveal-spacer{height:184px;background:transparent;}

.site-footer__inner{
  display:flex;
  justify-content:space-between;
  align-items:flex-end;
  width:100%;
  height:100%;
  position:relative;
  box-sizing:border-box;
  /* boss-measured 2026-08-19: footer content was 32px from edge, lift up 35px */
  padding-bottom:35px;
}
.site-footer__left{display:flex;flex-direction:column;align-items:flex-start;gap:15px;flex-shrink:0;max-width:280px}
.site-footer__logo{
  height:24px;width:auto;display:block;
  filter:brightness(0) invert(1);opacity:.92;
  flex-shrink:0;
}
.site-footer__slogan{
  display:flex;flex-direction:column;gap:4px;
  font-size:12px;color:rgba(255,255,255,.85);line-height:1.6;
}
.site-footer__slogan-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.site-footer__slogan-line--quote{font-size:11px;color:rgba(255,255,255,.75)}
.site-footer__copyright{font-size:11px;color:rgba(255,255,255,.75);margin-top:-6px;letter-spacing:.5px}
.site-footer__center{position:absolute;left:50%;bottom:35px;height:38px;transform:translateX(-50%);display:flex;justify-content:center;align-items:flex-end}
.site-footer__right{display:flex;flex-direction:column-reverse;align-items:flex-end;gap:12px;flex-shrink:0}
.site-footer__beian{font-size:11px;color:rgba(255,255,255,.7);text-align:right;display:flex;flex-direction:row;gap:18px;align-items:center}
.site-footer__beian-link{display:inline-flex;align-items:center;gap:5px;color:rgba(255,255,255,.75);text-decoration:none;transition:color .15s ease}
.site-footer__beian-link:hover{color:#fff;text-decoration:underline}
.site-footer__beian-icon{width:14px;height:14px;flex-shrink:0;display:inline-block}

.site-footer__social{display:flex;gap:14px;align-items:center;flex-wrap:wrap;justify-content:center}
.site-footer__social-btn{
  background:transparent;border:none;padding:4px;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  border-radius:6px;transition:transform .2s ease,background .2s ease;
  -webkit-tap-highlight-color:transparent;
}
.site-footer__social-btn:hover{
  transform:translateY(-2px);background:rgba(255,255,255,.08);
}
.site-footer__social-btn:focus-visible{
  outline:2px solid rgba(255,255,255,.5);outline-offset:2px;
}
.site-footer__social-btn img{
  width:20px;height:20px;display:block;
  filter:brightness(0) invert(1);
  opacity:.9;transition:opacity .2s ease,transform .2s ease;
}
.site-footer__social-btn:hover img{opacity:1}
/* B 站图标单独放大（按 data-key 区分，避免影响其他图标和间距）*/
.site-footer__social-btn[data-key="bilibili"] img{
  width:30px;height:30px;
}
.site-footer__social-btn[data-key="bilibili"]:hover img{
  transform:translateY(-2px);
}






/* 主题切换：dark 模式 */
[data-theme="dark"]{
  --bg-primary:#1a1a1a;
  --text:#e6e6e6;
  --text-secondary:#999;
  --muted:#666;
  --line:rgba(255,255,255,.12);
  --bg-2:#2a2a2a;
  --bg:#0d0d0d;
}
[data-theme="dark"] .site-footer{background:#2a2520;color:#fff}
[data-theme="dark"] .listing-head__zh,
[data-theme="dark"] .listing-head__en{color:var(--text)}


/* ============ 社交媒体二维码气泡（从图标位置向上滑出）============ */
.site-social-pop{
  position:fixed;z-index:9999;
  /* left/top 由 JS 设置 */
  transform:translate(-50%, -100%);
  opacity:0;pointer-events:none;
  /* v153: removed transition - keeps opacity 0->1 stuck on background tab + iOS Safari */
}
.site-social-pop.is-open{
  opacity:1;pointer-events:auto;
  transform:translate(-50%, calc(-100% - 12px));
  /* v153 */
  transition:none !important;
}
.site-social-pop.is-below{
  transform:translate(-50%, 0);
}
.site-social-pop.is-below.is-open{
  transform:translate(-50%, 12px);
}
.site-social-pop__panel{
  background:#fff;color:#222;
  border-radius:12px;padding:18px 20px 14px;
  width:240px;
  box-shadow:0 16px 48px rgba(0,0,0,.4),0 0 0 1px rgba(0,0,0,.04);
  text-align:center;
  position:relative;
}
.site-social-pop__arrow{
  position:absolute;left:50%;bottom:-7px;transform:translateX(-50%);
  width:14px;height:14px;background:#fff;
  box-shadow:1px 1px 0 rgba(0,0,0,.05);
  clip-path:polygon(0 0, 100% 0, 50% 100%);
}
.site-social-pop.is-below .site-social-pop__arrow{
  bottom:auto;top:-7px;
  clip-path:polygon(50% 0, 0 100%, 100% 100%);
}
.site-social-pop__title{
  font-size:14px;font-weight:500;letter-spacing:.05em;
  color:#222;margin-bottom:12px;
}
.site-social-pop__qr{
  width:200px;height:200px;margin:0 auto;
  display:flex;align-items:center;justify-content:center;
  background:#fafafa;border-radius:6px;overflow:hidden;
}
.site-social-pop__qr img{
  width:100%;height:100%;object-fit:contain;display:block;
}
.site-social-pop__empty{
  color:#999;font-size:13px;line-height:1.6;
}
.site-social-pop__empty small{
  display:block;margin-top:6px;font-size:11px;color:#bbb;
}


/* ============================================================
 * v49 (2026-08-18): footer 3-col vertical alignment tweak
 *   - .site-footer__beian  margin-top: 40px  (right col: ICP + police record DOWN 40px)
 *   - .site-footer__social margin-top: -28px (mid col: 6 social icons UP 28px)
 * RULE: ALL px here are MEASURED by boss in browser (ruler / puppeteer).
 *       DO NOT estimate / round / cross-scale. Use EXACTLY what boss says.
 * ============================================================ */

/* ============================================================
 * v50 (2026-08-18): footer 3-col bottom-edge alignment + color fix
 *   - color: removed stale .site-footer__beian{color:#000} (v44 leftover)
 *           -> rgba(255,255,255,.7) from active def now wins (ICP+police record WHITE)
 *   - .site-footer__beian  margin-top: 76px  (was 40px; +36 to bottom-align with copyright)
 *   - .site-footer__social margin-top: -58px (was -28px; -30 to bottom-align with copyright)
 * Measured bottom edges via puppeteer probe (NOT estimated):
 *     copyright (left)  bottom=688  <- target
 *     beian (right)     bottom=652  -> +36 to reach 688
 *     social (mid)      bottom=718  -> -30 to reach 688
 * RULE: 36 / 30 derived from probe, not guessed. If boss reports mismatch,
 *       re-probe and update by exact delta (NEVER round or scale).
 * ============================================================ */

/* ============================================================
 * v51 (2026-08-18): REAL bottom-edge alignment via flex column-reverse
 * WHY v50 failed: .site-footer__right is flex column + height:auto,
 *   so right auto-grew with beian margin-top, leaving beian at same viewport pos.
 * v51 fix:/n *   - .site-footer__right  flex-direction:column-reverse  (beian at bottom=688)
 *   - .site-footer__center bottom:0; height:38px; align-items:flex-end  (social at bottom=688)
 *   - removed v49/v50 margin-top:76/-58 (no longer needed)
 * Target: beian bottom = social bottom = copyright bottom = 688
 * ============================================================ */

/* ============================================================
 * v52 (2026-08-18): boss-measured finetune
 *   - .footer-reveal-spacer height: 250px -> 184px (bottom-bar reveal)
 *   - <main padding-bottom>     150px  -> 200px (card bottom -> curtain bottom)
 *   - .site-footer__center bottom: 0   -> -9px  (mid col DOWN 9px)
 *   - .site-footer__beian  color  rgba(255,255,255,.7)  KEPT (boss asked keep)
 * ALL px from boss browser measurement. DO NOT estimate.
 * ============================================================ */

/* v54 (2026-08-19): footer (C) text becomes clickable link into backend footer editor */
.site-footer__copyright-link{text-decoration:none;cursor:pointer;transition:opacity .15s ease}
.site-footer__copyright-link:hover{text-decoration:underline;opacity:.85}


/* ============================================================
 * v123 (2026-08-21): mobile @media (max-width:768px) 块从原 line 200 挪到这里
 *   原因：原位置在 desktop .site-footer 规则之前，mobile 规则被 desktop 覆盖 (source order 后写后赢)
 *   移到文件末尾后，mobile 规则在所有 desktop 规则之后，<=768px 时 mobile 真覆盖
 * 修复清单：
 *   1) .nav-v2__icon color: var(--text) !important  (浅色背景右侧图标可见)
 *   2) .nav-v2__logo-img filter: invert(1)          (去掉 brightness(.85) 让 LOGO 真黑)
 *   3) .nav-v2__menu-close display:none             (隐藏 ✕ 独立按钮)
 *   4) .nav-v2 z-index:500                          (顶栏在 overlay 之上，三横线打开后仍可点)
 *   5) @keyframes v122OverlayItemIn translateX      (5 菜单从左向右滑出)
 *   6) .card__title 9→12px / .card__location 8→11px (卡片文字 +3px)
 * ============================================================ */
@media (max-width:768px){
  /* === v125 (2026-08-21) === v123 (2026-08-21) mobile 修复 === */
  /* v125: 顶栏 mix-blend-mode + background 加 !important 防渗透 */
  /* 顶栏 grid 重排：hamburger(左) | LOGO(中) | icons(右) */

  /* === v125 main 帘子修复 === */
  /* 根因：main 是 z:1 + background:var(--bg) 不透明 + min-height:150vh 强制 main ≥1218px；
     滚到底 main 在 viewport y=0-732（恒定），footer fixed 在 y=612-812；
     main 不透明盖住 footer 上半 → 用户只看到 footer 底 80px = ICP 行 */
  /* 修复：background-clip:content-box 让 bg 只填 content-box，padding-bottom 区域透明；
     + padding-bottom:200px（覆盖 index/article.html 缺 inline padding 的页面）；
     这样滚到底时 main padding 区域透出 footer */
  /* v160: mobile main 不再单独覆盖 background-clip/padding, 用 base 段 main{z-index:1; background:var(--bg)} 默认
     background-clip 默认 border-box, padding 默认 0, main 不透明盖 footer 顶部, 滚到底自然露出 */
  .nav-v2{
    grid-template-columns:1fr auto 1fr;
    padding:11px 16px;
    /* v125: 强制 mobile 不反色 + 纯白/纯黑背景，!important 防 desktop mix-blend-mode:difference 渗透 */
    mix-blend-mode:normal !important;
    background:var(--bg,#fffdfa) !important;
    border-bottom:1px solid rgba(0,0,0,.06);
    /* v126: 默认 transform:translateY(0) 确保 none→-100% transition 能触发 */
    transform:translateY(0);
    /* v133: transition 1s → .7s (同步 desktop 节奏) */
    transition:transform .7s var(--ease), background .25s ease, border-color .25s ease;
    will-change:transform;
  }
  [data-theme="dark"] .nav-v2{
    background:#141414;
    border-bottom-color:rgba(255,255,255,.08);
  }
  /* LOGO 居中 + v130 加 transition 让搜索框展开时平滑偏移 */
  .nav-v2__logo{
    justify-self:center;
    height:22px;  /* v122b: 24→22 (-10%) */
    transition:transform .35s var(--ease), opacity .25s ease;
  }
  /* v130 原始: 搜索框展开时 LOGO 往左移避开
     v178fix15 (2026-08-22 19:30): mobile 段 LOGO 已经在 grid 中列最左，translateX(-100px) 把一半 LOGO 推出 nav-v2 左边界 → 屏幕外
     改 transform:none 让 LOGO 不动（hamburger 和 theme 已被 opacity:0 隐藏让位给 input）；垂直用 margin-top:-2px 向上微调跟 hamburger 顶对齐 */
  .nav-v2.is-search-open .nav-v2__logo{
    transform:scale(.92);
    opacity:.7;
    margin-top:-2px;
  }
  .nav-v2__logo-img{height:22px}
  /* 隐藏桌面 5 个菜单项 */
  .nav-v2__menu{display:none !important}
  /* 显示三横线按钮 */
  .nav-v2__menu-toggle{
    display:inline-flex;
    align-items:center;justify-content:center;
    width:36px;height:36px;
    background:transparent;border:0;cursor:pointer;
    color:var(--text,#1a1a1a);padding:0;
    /* v166 (2026-08-22): 老板 v165 反馈动画结束后 iOS Safari 重绘时短暂出现 ≡ + 三竖线 交叉
       iOS Safari transform transition end flicker (动画结束重绘 SVG line 时先画原始位置再画最终位置)
       修复: 改用 @keyframes animation 替代 transition (animation 无此 BUG)
       + transform-origin: center 显式声明旋转中心
       + transform: translateZ(0) 强制 GPU 层避免合成重绘 BUG */
    transition:opacity .25s ease;
    transform-origin:center center;
    transform:translateZ(0);
  }
  /* v166: 用 animation 替代 transition, JS 监听 click 切换 is-opening / is-closing 触发 animation */
  @keyframes v166MenuOpen{
    0%{transform:rotate(0deg) translateZ(0)}
    100%{transform:rotate(90deg) translateZ(0)}
  }
  @keyframes v166MenuClose{
    0%{transform:rotate(90deg) translateZ(0)}
    100%{transform:rotate(0deg) translateZ(0)}
  }
  .nav-v2__menu-toggle.is-opening{animation:v166MenuOpen .35s var(--ease) forwards}
  .nav-v2__menu-toggle.is-closing{animation:v166MenuClose .35s var(--ease) forwards}
  /* 兼容: 老 .is-open class 仍保持终态 (JS animationend 后保留 .is-open 让 transform 持续 90deg) */
  .nav-v2__menu-toggle.is-open:not(.is-opening):not(.is-closing){transform:rotate(90deg) translateZ(0)}
  /* v130: 搜索框展开时 hamburger 隐藏让位给 LOGO + input */
  .nav-v2.is-search-open .nav-v2__menu-toggle{
    opacity:0;
    pointer-events:none;
  }
  /* v130: 搜索框展开时 theme 按钮隐藏让位给 input */
  .nav-v2.is-search-open .nav-v2__icon--theme{
    opacity:0;
    pointer-events:none;
  }
  /* v166: 撤回 v165 transform:rotate(90deg), 改用 animation (避免 iOS Safari transition end flicker)
     JS 监听 click 切 is-opening/is-closing class 触发 animation, animationend 后保留 .is-open 终态 */
  .nav-v2__menu-toggle{display:inline-flex; align-items:center; justify-content:center}
  [data-theme="dark"] .nav-v2__menu-toggle{color:#f0f0f0}
  .nav-v2__menu-toggle:active{opacity:.6}
  /* 右侧图标间距收紧 */
  .nav-v2__right{gap:8px}
  .nav-v2__icon{padding:6px}

  /* === v129: mobile 搜索 input 改 inline 模式 ===
     v128 dropdown 模式：input 浮在 button 下方，width 320px 从 .search-zone right 向左展开
     但 .search-zone 不靠 nav-v2 最右 → input 左边溢出 nav-v2 左边界 → 部分内容超出 iframe 屏幕
     v129: 改为 inline 模式，input 默认 display:none 占 0 空间，点击 button 后 inline-block 占据 .nav-v2__right 剩余空间
     主题按钮被挤到 search-zone 外面但仍在 nav-v2__right 内（flex-wrap 换行） */
  .nav-v2__search{
    display:block;
    visibility:hidden;
    opacity:0;
    position:relative;   /* v178fix14 */
    left:auto;right:auto;top:auto;
    flex:1 1 0;
    width:0;
    max-width:0;
    height:27px;
    margin:0 4px;
    padding:0;
    background:transparent;
    border:none;
    border-bottom:1px solid rgba(0,0,0,.2);
    border-radius:0;
    color:var(--text,#1a1a1a);
    font-size:16px;
    transform:scale(.8125);
    transform-origin:left center;
    box-sizing:border-box;
    overflow:hidden;
    outline:none;
    transition:visibility 0s .3s linear, opacity .25s ease, max-width .3s var(--ease), padding .3s var(--ease);
  }
  [data-theme="dark"] .nav-v2__search{
    color:#f0f0f0;
    border-bottom-color:rgba(255,255,255,.3);
  }
  .nav-v2__search::placeholder{color:rgba(0,0,0,.4)}
  [data-theme="dark"] .nav-v2__search::placeholder{color:rgba(255,255,255,.4)}
  /* v129: input 展开状态——inline-block 占满 .nav-v2__right 剩余空间 */
  .nav-v2__search.is-open{
    visibility:visible;
    opacity:1;
    width:auto;
    max-width:240px;
    padding:0 8px;
    pointer-events:auto;
    transition:visibility 0s 0s linear, opacity .25s ease, max-width .3s var(--ease), padding .3s var(--ease);
  }
  /* v129: 让 search-zone 在 mobile 下 flex-wrap 让 theme button 换行不溢出 */
  .search-zone{
    flex:1;
    display:flex;
    align-items:center;
    gap:4px;
  }
  /* v178fix49 (2026-08-23): center search results popup on mobile, fix left overflow */
  .search-dropdown{
    left:50% !important;
    right:auto !important;
    transform:translateX(-50%);
    width:calc(100vw - 32px) !important;
    max-width:480px;
  }


  /* is-scrolled 加阴影 */
  /* v125: is-scrolled 状态也强制 mix-blend-mode:normal + 纯白/纯黑背景 */
  .nav-v2.is-scrolled{
    box-shadow:0 2px 12px rgba(0,0,0,.08);
    background:var(--bg,#fffdfa) !important;
    mix-blend-mode:normal !important;
  }
  [data-theme="dark"] .nav-v2.is-scrolled{background:#141414}

  /* 上滑消失 / 下滑出现（沿用 nav-v2--collapsed）—— v125: will-change 提升 GPU 合成 */
  .nav-v2--collapsed{transform:translateY(-100%);will-change:transform}

/* v154 trace overlay (iPhone click debug) */
/* v155: pointer-events:none so click pass-through to footer button */
.__siteFooterTrace{display:none}

  /* === 全屏 overlay 菜单 === */
  .nav-v2__menu-overlay{
    position:fixed;inset:0;
    background:var(--bg,#fffdfa);
    z-index:300;
    display:flex;flex-direction:column;
    padding:80px 32px 40px;
    opacity:0;pointer-events:none;
    transform:translateY(-12px);
    transition:opacity .25s ease, transform .35s var(--ease);
  }
  [data-theme="dark"] .nav-v2__menu-overlay{background:#141414}
  .nav-v2__menu-overlay.is-open{
    opacity:1;pointer-events:auto;transform:translateY(0);
  }
  /* v124: 修 v123 留下的游离 CSS 规则 BUG（删 6 行 sibling-less properties 全局污染）
       + 隐藏 ✕ 关闭按钮 + 顶栏 z-index 在 overlay 之上 */
  .nav-v2__menu-close{display:none !important}
  .nav-v2{z-index:500}
  [data-theme="dark"] .nav-v2__menu-close{color:#f0f0f0}
  .nav-v2__menu-close svg{width:22px;height:22px}
  .nav-v2__overlay-menu{
    display:flex;flex-direction:column;gap:24px;
    margin-top:32px;
  }
  /* v172 (2026-08-22): 老板 v171 验收反馈入场 BUG 修好, 出场动画还是没
     v171 出场失败根因: 出场终态 (.items-out) 与默认态目标值完全一样 (opacity:0, translateX(-120%))
     入场后元素 settled 在 .items-in 命中态 (opacity:1, translateX(0))
     出场时 .items-in 移除 + .items-out 加, iOS Safari 把渲染基线认为已经"在出场终态" (因为 .items-out 目标 = 默认态), 不触发反向 transition
     v172 修复: 彻底改用 JS inline style + void offsetWidth 强制 reflow 控制动画, 不依赖 CSS class 触发 transition
     CSS 只保留默认态 (不可见), JS 完全控制 transition 触发 + 强制 reflow
     入场: open() setTimeout(350ms) 后遍历 item 触发 inline transition + opacity:1 + translateX(0)
     出场: shut() 遍历 item 触发 inline transition + opacity:0 + translateX(-120%) (反向 stagger)
     1.4s 后清理 inline style 让下次 open() 入场能从默认态触发 */
  .nav-v2__overlay-item{
    /* v174 默认态 = 入场起点 (不可见), 元素在屏幕外左侧 */
    opacity:0;
    transform:translateX(-100%);
    transition:opacity .5s cubic-bezier(0.16,1,0.3,1), transform .5s cubic-bezier(0.16,1,0.3,1);
  }
  /* v174: 入场终态 — .items-in 命中 (translateX(0) != 默认态 translateX(-100%) -> transition 触发入场) */
  .nav-v2__menu-overlay.items-in .nav-v2__overlay-item{
    opacity:1;
    transform:translateX(0);
  }
  /* v174: 入场 stagger (正序: item 1=0s, 2=.2s, 3=.4s, 4=.6s, 5=.8s, 间隔 0.2s) */
  .nav-v2__menu-overlay.items-in .nav-v2__overlay-item:nth-child(1){transition-delay:0s}
  .nav-v2__menu-overlay.items-in .nav-v2__overlay-item:nth-child(2){transition-delay:.2s}
  .nav-v2__menu-overlay.items-in .nav-v2__overlay-item:nth-child(3){transition-delay:.4s}
  .nav-v2__menu-overlay.items-in .nav-v2__overlay-item:nth-child(4){transition-delay:.6s}
  .nav-v2__menu-overlay.items-in .nav-v2__overlay-item:nth-child(5){transition-delay:.8s}
  /* v176 (2026-08-22): 老板 v175 验收反馈"出场动画没有入场动画丝滑，出场动画一下就出去了"
     根因: 入场和出场都从默认态继承 transition easing (cubic-bezier(0.16,1,0.3,1) ease-out, 开头快结尾慢)
     入场 ease-out: 开头快结尾慢 -> 元素快速进入慢速到位置 -> 丝滑感
     出场 ease-out: 开头快结尾慢 -> 元素快速飞出 -> "一下就出去了", 不丝滑
     v176 修复: .items-out 选择器显式覆盖 transition 用 ease-in (cubic-bezier(0.7,0,0.84,0) 开头慢结尾快)
     出场 ease-in: 开头慢结尾快 -> 元素慢慢开始加速飞出 -> 丝滑感
     入场保留 v174 strong ease-out, 出场用 strong ease-in (Material Design 反向曲线) */
  .nav-v2__menu-overlay.items-out .nav-v2__overlay-item{
    opacity:0;
    transform:translateX(-200%);
    transition:opacity .5s cubic-bezier(0.7,0,0.84,0), transform .5s cubic-bezier(0.7,0,0.84,0);
  }
  /* v174: 出场 stagger (反序: item 1=.8s, 2=.6s, 3=.4s, 4=.2s, 5=0s, 从下到上) */
  .nav-v2__menu-overlay.items-out .nav-v2__overlay-item:nth-child(1){transition-delay:.8s}
  .nav-v2__menu-overlay.items-out .nav-v2__overlay-item:nth-child(2){transition-delay:.6s}
  .nav-v2__menu-overlay.items-out .nav-v2__overlay-item:nth-child(3){transition-delay:.4s}
  .nav-v2__menu-overlay.items-out .nav-v2__overlay-item:nth-child(4){transition-delay:.2s}
  .nav-v2__menu-overlay.items-out .nav-v2__overlay-item:nth-child(5){transition-delay:0s}
  .nav-v2__overlay-item{
    display:flex;flex-direction:column;align-items:flex-start;gap:4px;
    text-decoration:none;
    color:var(--text,#1a1a1a);
    font-family:'PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif;
    padding:12px 0;
    border-bottom:1px solid rgba(0,0,0,.06);
  }
  [data-theme="dark"] .nav-v2__overlay-item{
    color:#f0f0f0;border-bottom-color:rgba(255,255,255,.08);
  }
  .nav-v2__overlay-en{
    font-family:var(--font-en);
    font-size:11px;font-weight:400;
    letter-spacing:.3em;color:var(--muted,#888);
    text-transform:uppercase;
  }
  .nav-v2__overlay-zh{
    font-size:22px;font-weight:300;
    letter-spacing:.05em;
  }
  /* v121: 主题感知色 — 浅色用深字/深色用浅字（白底 + 白图标不可见）*/
  .nav-v2{color:var(--text,#1a1a1a)}
  [data-theme="dark"] .nav-v2{color:#f0f0f0}
  .nav-v2__icon{color:var(--text,#1a1a1a) !important}
  .nav-v2__logo-img{filter:invert(1)}  /* 白图 → 黑图 */
  [data-theme="dark"] .nav-v2__logo-img{filter:none}  /* 深色模式用原图 */

  /* v121: 卡片 concept 描述在 mobile 隐藏 */
.card__concept{display:none}
/* v122b: 卡片 mobile 字号缩小到 8px（仅 mobile 生效）*/
@media (max-width:768px){
  .card__title{font-size:13px !important;line-height:17px;margin:0 0 3px;letter-spacing:0}
  .card__location{font-size:12px !important;line-height:15px;letter-spacing:0}
  .card__body{margin-top:4px}
  .card__interiors{font-size:10px;letter-spacing:.1em}
}

/* === 底栏：上下排列 === */
  /* v121: 底栏 3 段重排 — Row1 社交 / Row2 版权+标语 / Row3 备案 */
  /* v160 (2026-08-22): 老板明确要求 '页面盖住底栏, 滑到最下方才出现底栏' = v53 真·物理帘子
     + 桌面已是 base 段 site-footer z-index:0 + main z-index:1 + bg:var(--bg) 不透明盖 footer
     + mobile 之前 v156 改 z-index:2 (footer 一直可见) 现在改回 z-index:0 恢复物理帘子
     + click BUG 不再是问题: 物理帘子下 footer 平时不可见, 用户不会去点, 滚到底露出后 main 已滚走, hit-test 命中 footer */
  .site-footer{
    height:auto;min-height:auto;
    padding:39px 16px 20px;
    flex-direction:column;
    align-items:stretch;
    gap:14px;
    z-index:0;
  }
  /* 隐藏 LOGO 缩略图（mobile 不需要）+ 隐藏 footer 搜索/主题按钮（mobile 已有 nav）*/
  .site-footer__logo,.site-footer__actions{display:none}
  /* Row 1: 社交图标横向、缩小 */
  .site-footer__center{order:1;position:static;transform:none;width:100%;display:flex;justify-content:flex-start;align-items:center;gap:10px;height:auto;left:auto;bottom:auto}
  .site-footer__center .site-footer__social{display:flex;flex-direction:row;gap:8px;align-items:center;flex-wrap:wrap}
  /* v152: 2026-08-21 23:30 老板 iPhone 真机测底部 6 social icon 20x20 太挤互干扰, +50% 放大 (normal 30x30, bilibili 45x45), hit-area 28->38 (bilibili 38->57) */
  .site-footer__social-btn img{width:30px;height:30px}
  .site-footer__social-btn[data-key="bilibili"] img{width:45px;height:45px}
  /* Row 2: 版权 + 标语（logo 隐藏在 left，剩下 slogan+copyright）*/
  .site-footer__left{order:2;max-width:none;width:100%;align-items:flex-start;gap:8px}
  .site-footer__slogan{gap:2px}
  .site-footer__slogan-line{font-size:11px;white-space:normal;overflow:visible;text-overflow:clip}
  .site-footer__slogan-line--quote{font-size:10px;color:rgba(255,255,255,.75)}
  [data-theme="dark"] .site-footer__slogan-line--quote{color:rgba(255,255,255,.55)}
  .site-footer__copyright{font-size:10px;margin-top:0;color:rgba(255,255,255,.75);letter-spacing:.3px}
  [data-theme="dark"] .site-footer__copyright{color:rgba(255,255,255,.5)}
  /* Row 3: ICP + 公安备案 */
  .site-footer__right{order:3;position:static;transform:none;width:100%;align-items:flex-start;flex-direction:column;gap:6px;left:auto;bottom:auto}
  .site-footer__beian{font-size:10px;text-align:left;flex-direction:row;flex-wrap:wrap;gap:6px 14px}
  [data-theme="dark"] .site-footer__beian{color:rgba(255,255,255,.7)}
  [data-theme="dark"] .site-footer__beian-link{color:rgba(255,255,255,.75)}
  .site-footer__inner{
    flex-direction:column;
    gap:24px;
    align-items:flex-start;
  }
  .site-footer__left,
  .site-footer__center,
  .site-footer__right{
    position:static;
    transform:none;
    left:auto;bottom:auto;
    align-items:flex-start;
  }
  .site-footer__right{
    flex-direction:column;
    align-items:flex-start;
  }
  .site-footer__beian{
    flex-direction:row;flex-wrap:wrap;
    gap:8px 14px;
    text-align:left;
  }
  .site-footer__actions{margin-top:6px}
  /* footer reveal spacer mobile 下不需要 250px */
/* === v144: mobile 分享二维码气泡固定 viewport 底部 24px 居中弹出 === */
/* 桌面端保留从 btn 上方弹出逻辑 */
/* mobile 端 viewport 812px, pop 264px, btn 在底部 ~712px */
/* 从 btn 上方弹出时 pop bottom 712-16+264=960 > 812, 超出 viewport 148px 被裁 */
/* 改成固定 bottom:24px center, 永远在 viewport 内可见, 箭头朝上 */
/* v147: 显式声明所有关键属性，防御 mobile @media 内 cascade 任何不确定性
   (opacity:0 / pointer-events:none 让默认态真不可见+不可点; is-open 抬起来) */
/* v158 (2026-08-22): popover 居中 (老板反馈弹窗靠下) - bottom:80px -> top:50% + translate(-50%,-50%) */
.site-social-pop{position:fixed;left:50% !important;top:50% !important;bottom:auto !important;transform:translate(-50%,-50%);width:240px;max-width:calc(100vw - 32px);max-height:80vh;overflow:auto;opacity:0;pointer-events:none;z-index:9999;border-radius:10px}
.site-social-pop.is-open{opacity:1 !important;pointer-events:auto !important;transform:translate(-50%,-50%);transition:none !important}
.site-social-pop.is-below{transform:translate(-50%,-50%);opacity:0;pointer-events:none}
.site-social-pop.is-below.is-open{opacity:1 !important;pointer-events:auto !important;transform:translate(-50%,-50%)}
.site-social-pop__arrow{top:-7px;bottom:auto;clip-path:polygon(50% 0, 0 100%, 100% 100%)}
  /* v161 (2026-08-22): 老板 v160 反馈底栏露出偏少, 184px < mobile footer 实际高度 (~220-260px)
     露出部分 footer 底部 36-80px 被 main 不透明盖住, social icons 部分被覆盖.
     spacer 184 -> 280, 让 footer 完整露出 + 留 20-60px main 透明缓冲.
     桌面 base 段 .footer-reveal-spacer{height:184px} 仍 184 (desktop footer 415px, 露出 44%) */
  .footer-reveal-spacer{height:280px}

  /* v162 (2026-08-22): 老板 v161 反馈首页底栏备案号那行和上面的文字开头没对齐
     根因: .site-footer__beian-icon (14x14) + .site-footer__beian-link gap:5px = ICP 文字起始位置 = footer 左边 16+14+5 = 35px
     而 slogan 文字起始位置 = footer 左边 16px → 备案号文字起始位置比 slogan 偏右 19px
     修复: mobile 下隐藏 beian-icon, 文字起始位置 = footer 左边 16px = slogan 文字起始位置 ✓ 对齐
     desktop 不改, 桌面 icon 仍然显示 */
  .site-footer__beian-icon{display:none}
}


/* === v147 (2026-08-21): mobile popOver cascade 显式化防御性 fix === */
/* === v127: .nav-v2--collapsed 跨 viewport 规则 ===
   v126 之前 .nav-v2--collapsed{transform:translateY(-100%)} 只在 mobile @media 内，
   桌面 viewport 下完全失效 → class 切换不影响 transform → 没动画
   v127: 在 @media 块外再加一条，确保所有 viewport 都生效 */
