/* ===== 风格大页（styles.html，2026-09-29；收编时进 page-*.css）===== */
    @font-face {
      font-family: 'Noto Serif SC STY';
      font-style: normal;
      font-weight: 700;
      font-display: swap;
      src: url('../fonts/noto-serif-sc-sty.woff2?v=517ad43e') format('woff2');
    }
    .sty { --sty-ink: var(--navy-800); --sty-mut: #5A6572; --sty-accent: #8A9A7B; }
    .sty-display { font-family: 'Noto Serif SC STY', 'Noto Serif SC', 'Songti SC', serif; }
    /* 2026-10-26：共享组件的标题把族写死成 `Outfit, "Noto Serif SC", …`，
       绕过了本页子集 ⇒ 为 16 个字白下 155KB 全局字体。把本页子集插在
       Outfit 之后、Noto Serif SC 之前：Latin 仍走 Outfit，CJK 落到本页子集。 */
    .services-title, .quote-form-title, .quote-faq-title {
      font-family: Outfit, 'Noto Serif SC STY', 'Noto Serif SC', 'Source Han Serif SC', serif;
    }

    /* ---- 头段 ---- */
    /* 2026-10-22：首屏要「一屏看全 6 个风格」——标题与导语改成左右两栏（原来上下堆叠，
       光这两块就吃掉 428px），上边距也从 148 收到 116（固定页头 72 + 44 呼吸）。
       竖屏 / 窄屏在 860 断点回到单栏。 */
    .sty-hero { max-width: 1200px; margin: 0 auto;
      padding: calc(var(--space-20) + var(--space-9)) var(--space-6) 0;   /* 80+36=116 = 固定页头 72 + 44 呼吸 */
      display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 660px);
      align-items: end; gap: var(--space-4) var(--space-10); }
    .sty-h1 { font-size: clamp(2.5rem, 5.4vw, 4.5rem); line-height: 1.12; letter-spacing: .02em; margin: 0; font-weight: 700; color: var(--sty-ink); }
    .sty-hero-sub { font-size: clamp(1rem, 1.35vw, 1.125rem); line-height: 1.85; color: var(--sty-mut); max-width: none; margin: 0; }
    .sty-hero-sub strong { color: var(--sty-ink); }



    /* ---- 收口 CTA ---- */
    .sty-cta { margin: 100px auto 0; max-width: 1200px; padding: 0 var(--space-6); }
    .sty-cta-in { background: var(--navy-800); border-radius: var(--radius-xl); color: #fff; padding: 60px var(--space-10); text-align: center; }
    .sty-cta-in h2 { font-size: clamp(1.625rem, 3.4vw, 2.375rem); margin: 0 0 var(--space-3-5); font-weight: 700; }
    .sty-cta-in p { opacity: .82; margin: 0 0 var(--space-7); font-size: var(--fs-body-sm); }
    .sty-cta-btns { display: flex; gap: var(--space-3-5); justify-content: center; flex-wrap: wrap; }
    .sty-btn { display: inline-block; padding: var(--space-3-5) 34px; border-radius: var(--radius-full); font-size: var(--fs-body-sm); text-decoration: none; transition: all var(--duration-fast) var(--ease-out-quart); }
    .sty-btn-pri { background: #fff; color: var(--navy-800); font-weight: 600; }
    .sty-btn-pri:hover { transform: translateY(-2px); }
    .sty-btn-sec { border: 1px solid rgba(255,255,255,.5); color: #fff; }
    .sty-btn-sec:hover { border-color: #fff; }
    .sty-note { max-width: 1200px; margin: 26px auto 0; padding: 0 var(--space-6); font-size: var(--fs-nano); color: var(--sty-mut); line-height: 1.8; }

    /* 本页无深色 hero：header 恒为白底深字（复刻 .scrolled 态，否则白字导航压在白底上不可见，2026-09-29） */
    /* 2026-10-08：同 about.py —— 永久半透明会导致滚动时内容透出。 */
    .site-header { background: var(--white); box-shadow: var(--shadow-xs); }
    .site-header .nav-link { color: var(--navy-900); }
    .site-header .brand-logo-white { opacity: 0; }
    .site-header .brand-logo-color { opacity: 1; }
    .site-header .mobile-menu-btn { color: var(--navy-900); }

    @media (max-width: 860px) {
      .sty-hero { padding-top: 100px; grid-template-columns: 1fr; gap: var(--space-3); }
    }

    /* ==================================================================
       方案 A「风格志」结构（2026-10-30）
       —— 取代原「预览台 + 卡片墙」。旧 stage / card 规则**已随结构删除**
          （2026-10-30 清理：75 个死规则块，check_css_contract 的 A 段从 92 回到基线内）。
       三条判据：
         ① 一个风格在页面上只出现一次（印样条是锚点，不是第二份内容）；
         ② 谱系（章）是分类单点，加风格 = 加一条 JSON + 落到某一章；
         ③ 图片沿用原 <picture>（avif + 4 档 srcset + ?v=），只换 sizes。
       ================================================================== */

    /* ---- 印样条：一屏看全；N 变大就横滑（rail-x 四态由 shared.js 挂）---- */
    .sty-sheet { max-width: 1200px; margin: 0 auto; padding: clamp(1.875rem,3.6vw,2.75rem) var(--space-6) 0; }
    .sty-sheet-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-5);
      font-size: var(--fs-nano); letter-spacing: .2em; text-transform: uppercase; color: var(--sty-mut); margin-bottom: var(--space-3-5); }
    .sty-sheet-head span:last-child { letter-spacing: .02em; text-transform: none; font-size: var(--fs-nano); }
    .sty-rail { display: flex; gap: var(--space-2-5); overflow-x: auto; overflow-y: hidden;
      scrollbar-width: none; padding-bottom: 2px; }
    .sty-rail::-webkit-scrollbar { display: none; }
    .sty-thumb { position: relative; display: block; flex: 1 1 0; min-width: 106px; max-width: 186px;
      text-decoration: none; }
    .sty-thumb-bar { position: absolute; left: 0; right: 0; top: 0; height: 2px; z-index: 2;
      background: var(--sty-accent, #8A9A7B); transform: scaleX(0); transform-origin: left;
      transition: transform var(--duration-slow) var(--ease-out-quart, ease); }
    /* ⚠️ picture 是 inline：不给它 block + 100% 高，里面的 img 高度会成环 */
    .sty-thumb-img { position: relative; display: block; aspect-ratio: 3 / 2; overflow: hidden;
      border-radius: 2px; background: #EAE7E1; }
    .sty-thumb-img picture { display: block; width: 100%; height: 100%; }
    .sty-thumb-img img { width: 100%; height: 100%; object-fit: cover;
      filter: saturate(.82) brightness(1.02);
      transition: filter .75s ease, transform .9s var(--ease-out-quart, ease); }
    .sty-thumb-n { display: block; margin-top: var(--space-2); font-size: var(--fs-small); color: var(--sty-mut);
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: color var(--duration-normal); }
    @media (hover: hover) and (prefers-reduced-motion: no-preference) {
      .sty-thumb:hover .sty-thumb-img img { filter: none; transform: scale(1.05); }
      .sty-thumb:hover .sty-thumb-bar { transform: scaleX(1); }
      .sty-thumb:hover .sty-thumb-n { color: var(--sty-ink); }
    }
    .sty-thumb:focus-visible { outline: 2px solid var(--sty-ink); outline-offset: 4px; }

    /* ---- 谱系导航（吸顶；top = 固定页头 72）---- */
    .sty-toc { position: sticky; top: 72px; z-index: 40; background: var(--white);
      border-bottom: 1px solid var(--line, #E2DED5); margin-top: clamp(var(--space-3-5),1.8vw,var(--space-5-5)); }
    .sty-toc-in { display: flex; align-items: center; gap: clamp(var(--space-4),2.6vw,var(--space-9)); height: 54px;
      max-width: 1200px; margin: 0 auto; padding: 0 var(--space-6);
      font-size: var(--fs-small); color: var(--sty-mut); overflow-x: auto; scrollbar-width: none; }
    .sty-toc-in::-webkit-scrollbar { display: none; }
    .sty-toc-in a { position: relative; text-decoration: none; white-space: nowrap; padding: 2px 0;
      color: inherit; transition: color var(--duration-normal); }
    .sty-toc-in a b { font-family: 'Outfit', sans-serif; font-weight: 400; font-size: var(--fs-nano);
      letter-spacing: .12em; margin-right: var(--space-2); opacity: .5; }
    .sty-toc-in a.on { color: var(--sty-ink); font-weight: 600; }
    .sty-toc-in a.on b { opacity: .85; }
    .sty-toc-in a.on::after { content: ''; position: absolute; left: 0; right: 0; bottom: -6px;
      height: 2px; background: var(--sty-accent, #8A9A7B); }
    .sty-toc-cnt { margin-left: auto; font-family: 'Outfit', sans-serif; font-size: var(--fs-nano);
      letter-spacing: .16em; color: #9AA1AC; white-space: nowrap; }

    /* ---- 章 ---- */
    .sty-chap { max-width: 1200px; margin: 0 auto; padding: clamp(var(--space-12),6vw,5.75rem) var(--space-6) 0;
      scroll-margin-top: 132px; }
    .sty-chap-head { display: grid; grid-template-columns: auto minmax(0,1fr);
      align-items: baseline; gap: clamp(0.6875rem,1.4vw,1.1875rem); padding-bottom: var(--space-4); border-bottom: 1px solid #E2DED5; }
    .sty-chap-no { font-family: 'Outfit', sans-serif; font-weight: 300; line-height: .9;
      font-size: clamp(2rem,3.6vw,3.1rem); letter-spacing: .02em; color: var(--sty-ink); opacity: .9; }
    .sty-chap-t h2 { margin: 0; font-weight: 700; line-height: 1.28;
      font-size: clamp(1.45rem,2.5vw,2rem); letter-spacing: .01em; color: var(--sty-ink); }
    .sty-chap-t p { margin: var(--space-1-5) 0 0; font-size: var(--fs-caption); color: var(--sty-mut); }
    .sty-chap-dot { display: inline-block; width: 9px; height: 9px; border-radius: 1px;
      background: var(--sty-accent, #8A9A7B); margin-right: var(--space-2-5); vertical-align: 2px; }

    /* ---- 条目 ---- */
    .sty-entry { display: grid; grid-template-columns: minmax(0,1.55fr) minmax(0,1fr);
      gap: clamp(var(--space-5-5),3.8vw,3.75rem); align-items: center; margin-top: clamp(2.625rem,5vw,var(--space-20)); }
    .sty-entry:nth-of-type(even) { grid-template-columns: minmax(0,1fr) minmax(0,1.55fr); }
    .sty-entry:nth-of-type(even) .sty-entry-media { order: 2; }
    .sty-entry-media { position: relative; display: block; overflow: hidden; border-radius: 3px;
      background: #EAE7E1; }
    .sty-entry-media picture { display: block; }
    /* ⚠️ img 带 width/height 属性时 aspect-ratio 不生效（属性 height 赢）⇒ 必须 height:auto */
    .sty-entry-media img { width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; display: block;
      transition: transform 1.15s var(--ease-out-quart, ease); }
    @media (hover: hover) and (prefers-reduced-motion: no-preference) {
      .sty-entry:hover .sty-entry-media img { transform: scale(1.026); }
    }
    .sty-entry-body { padding-block: 2px; }
    .sty-entry-line { display: flex; align-items: center; gap: var(--space-2-5); margin-bottom: var(--space-3);
      font-family: 'Outfit', sans-serif; font-size: var(--fs-nano); letter-spacing: .2em;
      text-transform: uppercase; color: var(--sty-mut); }
    .sty-entry-line b { font-weight: 400; color: color-mix(in srgb, var(--sty-accent, #8A9A7B) 66%, var(--sty-ink)); }
    .sty-entry-line::after { content: ''; width: 56px; height: 1px; background: #E2DED5; }
    .sty-entry-name { margin: 0; font-weight: 700; line-height: 1.18; letter-spacing: .01em;
      font-size: clamp(1.55rem,2.5vw,2.05rem); color: var(--sty-ink); }
    .sty-entry-name a { color: inherit; text-decoration: none; }
    .sty-entry-sub { margin: var(--space-2-5) 0 0; font-size: var(--fs-body-sm); line-height: 1.85; color: #2E3D56;
      letter-spacing: .01em; max-width: 30em; }
    .sty-sw { display: flex; flex-wrap: wrap; gap: var(--space-3-5); margin: var(--space-5) 0 0; padding: 0; list-style: none; }
    .sty-sw li { display: flex; align-items: center; gap: var(--space-2); font-size: var(--fs-nano); color: var(--sty-mut); white-space: nowrap; }
    .sty-sw i { width: 14px; height: 14px; border-radius: 50%; flex: 0 0 auto;
      box-shadow: inset 0 0 0 1px rgba(11,31,58,.12); }
    .sty-entry-go { display: inline-flex; align-items: center; gap: var(--space-2); margin-top: var(--space-4);
      font-size: var(--fs-caption); font-weight: 600; text-decoration: none;
      color: color-mix(in srgb, var(--sty-accent, #8A9A7B) 70%, var(--sty-ink)); }
    .sty-entry-go .arw { transition: transform var(--duration-normal) var(--ease-out-quart, ease); }
    @media (hover: hover) {
      .sty-entry:hover .sty-entry-go { text-decoration: underline; text-underline-offset: 4px; }
      .sty-entry:hover .sty-entry-go .arw { transform: translateX(4px); }
    }

    /* 章首条：通栏大图 + 双栏说明（右列贴底，与左列形成一条基线） */
    .sty-entry--lead { grid-template-columns: 1fr; gap: 0; }
    .sty-entry--lead .sty-entry-media img { aspect-ratio: 2.28 / 1; }
    .sty-entry--lead .sty-entry-body { display: grid; grid-template-columns: minmax(0,1fr) auto;
      gap: clamp(var(--space-6),4vw,var(--space-16)); align-items: end; margin-top: var(--space-6); }
    .sty-entry--lead .sty-entry-side { justify-self: end; text-align: right; max-width: 330px; }
    .sty-entry--lead .sty-sw { justify-content: flex-end; margin-top: 0; }
    .sty-entry--lead .sty-entry-name { font-size: clamp(1.9rem,3vw,2.5rem); }
    .sty-entry--lead .sty-entry-sub { font-size: var(--fs-body); margin-top: var(--space-3-5); }
    .sty-entry--lead .sty-entry-go { margin-top: var(--space-4); }

    /* 普通条目：文字在上、色卡与链接一行在下（侧栏就是 block，别再套一层） */
    .sty-entry-side { margin-top: var(--space-5-5); }
    .sty-entry-side .sty-entry-go { margin-top: var(--space-4); }

    @media (max-width: 860px) {
      .sty-sheet { padding-top: var(--space-10); }
      .sty-chap-head { grid-template-columns: auto minmax(0,1fr); }
      .sty-entry, .sty-entry:nth-of-type(even) { grid-template-columns: 1fr; gap: var(--space-5); margin-top: var(--space-9); }
      .sty-entry:nth-of-type(even) .sty-entry-media { order: 0; }
      .sty-entry--lead .sty-entry-media img { aspect-ratio: 3 / 2; }
      .sty-entry--lead .sty-entry-body { grid-template-columns: 1fr; gap: 0; align-items: start; }
      .sty-entry--lead .sty-entry-side { justify-self: start; text-align: left; max-width: none; }
      .sty-entry--lead .sty-sw { justify-content: flex-start; margin-top: var(--space-5); }
      .sty-entry-sub { font-size: var(--fs-body-sm); }
      .sty-toc { top: var(--space-16); }
      /* 窄屏 4 个谱系要占满一行：计数让位，否则「04 色块表达」被挤出可视区 */
      .sty-toc-cnt { display: none; }
    }
    @media (prefers-reduced-motion: reduce) {
      .sty-thumb-img img, .sty-thumb-bar, .sty-entry-media img, .sty-entry-go .arw { transition: none !important; }
      .sty-thumb-img img { filter: none !important; }
    }

/* DG:GALLERY:START */
    /* ==================================================================
       序 · 深度画廊（2026-10-30）
       —— 客户参照 codrops「Atmospheric Depth Gallery」，但**不引 WebGL**：
          那会把首屏 LCP 从一张图变成 canvas（风格页是核心 SEO 页），
          还要背 +150KB 依赖与 iOS 纹理内存。这里用 transform/opacity 复刻空间逻辑。
       三条判据：
         ① 一次只有「当前 + 下一张」可见，两者 opacity 之和恒为 1（多层半透明必然发浑）；
         ② 尺寸走透视除法 1/(1+rel)：退场是「放大到被屏幕边缘裁掉」，不是淡出；
         ③ 背景 = 环境色 + 两块色斑，颜色按风格硬编码在注入脚本的 MOOD 表里。
       ================================================================== */
    /* 画廊是开屏第一屏：铺满整屏、页头透明压在它上面（不再让出 72px） */
    .dg { --dg-h: 100svh; position: relative; }
    .dg-track { position: relative; height: calc(var(--dg-h) + 280svh); }
    .dg-stage { position: sticky; top: 0; height: var(--dg-h); overflow: hidden;
      /* 🔴 不要给 background-color 加 transition：JS 的 draw() 每帧都在写这个值，
         两者会互相打架（transition 每帧被重置、永远跑不完），白烧一份样式重算。
         平滑由 JS 侧的逐帧插值负责。 */
      background-color: #4A3428; }

    /* ---- 背景色块：一层一个风格，切换只改 opacity（合成层，不重绘渐变）---- */
    .dg-bg { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
    .dg-bgset { position: absolute; inset: 0; opacity: 0; will-change: opacity; }
    /* ⚠️ 这里不能给 i 加 border-radius：元素已不是正方形（视口 + 16vmax），
       50% 圆角会变成椭圆，在屏幕边缘把渐变裁掉一截（实测底部 x≈353–390 出现差异带）。 */
    .dg-bgset i { position: absolute; display: block; opacity: .9; }
    /* 🔴 色斑只覆盖「视口 + 漂移余量」，不再画成 130vmax 的整块方框。
       原写法 radial-gradient(circle … 50%) 的尺寸是 farthest-corner：130vmax 方框里
       渐变线 = 半边长 × √2 = 91.9vmax，50% 落在 45.96vmax —— 方框外圈约一半面积是纯透明，
       却照样被提升成合成层栅格化（实测桌面 5×3.50 + 5×2.12 Mpx ≈ 132MB 纹理，移动 43MB，
       且滚到页底也不释放，占住整个页面生命周期）。
       改法：元素只做视口四边外扩 8vmax（容纳 dg-drift 最大 6vmax 位移），渐变半径写成显式
       长度。半径 = 原半边长 × √2 × 50%，圆心与插值曲线不变 ⇒ 可见区逐像素一致。
       ⚠️ 别把 50% 当成「半边长」：circle 默认 farthest-corner，两者差一个 √2（踩过一次）。 */
    .dg-bgset .b1 { width: calc(100vw + 16vmax); height: calc(100svh + 16vmax);
      left: calc(50% - 50vw - 8vmax); top: calc(48% - 50svh - 8vmax);
      background: radial-gradient(circle 45.96vmax at 50% 50%, var(--b1, transparent) 0%, rgba(255,255,255,0) 100%);
      animation: dg-drift-1 38s ease-in-out infinite alternate; }
    .dg-bgset .b2 { width: calc(100vw + 16vmax); height: calc(100svh + 16vmax);
      left: calc(35% - 50vw - 8vmax); top: calc(55% - 50svh - 8vmax);
      background: radial-gradient(circle 35.71vmax at 50% 50%, var(--b2, transparent) 0%, rgba(255,255,255,0) 100%);
      animation: dg-drift-2 46s ease-in-out infinite alternate; }
    @keyframes dg-drift-1 {
      from { transform: translate3d(-6vmax,-4vmax,0); }
      to { transform: translate3d(6vmax,4vmax,0); }
    }
    @keyframes dg-drift-2 {
      from { transform: translate3d(5vmax,3vmax,0); }
      to { transform: translate3d(-5vmax,-4vmax,0); }
    }

    /* ---- 图片：不是「相框」，是「照片」——无圆角、无阴影、无描边 ---- */
    .dg-planes { position: absolute; inset: 0; z-index: 2; }
    .dg-plane { position: absolute; left: 50%; top: 50%; margin: 0; width: min(40vw, 620px);
      transform: translate3d(-50%,-50%,0); will-change: transform, opacity; opacity: 0; }
    /* 无 JS 时只露出第一张，页面不至于空白 */
    .dg-plane[data-i="0"] { opacity: 1; }
    /* ⚠️ img 带 width/height 属性时 aspect-ratio 不生效，必须同时 height:auto */
    .dg-plane img { width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover; display: block; }
    /* 预告层描一道极淡的边：室内照底色和背景接近，半透明后整块消失会读成「脏印」 */
    .dg-plane:not([data-i="0"]) img { box-shadow: inset 0 0 0 1px rgba(40,34,26,.05); }
    /* 退场层叠一层「当前底色」的雾：两个暖木色风格叠在一起时，单靠 opacity 会读成一坨深色 */
    .dg-veil { position: absolute; inset: 0; background: var(--dg-now, #4A3428);
      opacity: var(--dg-veil, 0); pointer-events: none; }

    /* ---- 固定文字层（左侧中部，与页面 1200 栅格对齐）---- */
    .dg-cap { position: absolute; z-index: 8; top: 50%; transform: translateY(-50%);
      left: max(var(--space-6), calc((100vw - 1200px) / 2 + var(--space-6)));
      max-width: min(26ch, 26vw); pointer-events: none; }
    .dg-name { margin: 0; font-weight: 700; line-height: 1.16; letter-spacing: .02em;
      font-size: clamp(1.75rem, 3.4vw, 2.9rem); color: var(--dg-ink); }
    .dg-sub { margin: var(--space-2-5) 0 0; font-size: var(--fs-caption); line-height: 1.9;
      color: var(--dg-mut); }
    .dg-sw { display: flex; flex-wrap: wrap; gap: var(--space-3-5); list-style: none;
      margin: var(--space-4) 0 0; padding: 0; font-size: var(--fs-nano); color: var(--dg-mut); }
    .dg-sw li { display: flex; align-items: center; gap: var(--space-2); white-space: nowrap; }
    /* 色块常常和背景同色（意式的橙红压在橙红底上）⇒ 必须描边才看得见 */
    .dg-sw i { width: 12px; height: 12px; border-radius: 1px; flex: 0 0 auto;
      box-shadow: 0 0 0 1px rgba(17,17,17,.45); }

    /* ---- 文字明暗：只给纯黑 / 纯白两套，深底上灰字就是看不清 ---- */
    .dg-stage { --dg-ink: #111111; --dg-mut: rgba(17,17,17,.78); }
    .dg-stage.is-dark { --dg-ink: #fff; --dg-mut: rgba(255,255,255,.86); }
    .dg-stage.is-dark .dg-sw i { box-shadow: 0 0 0 1px rgba(255,255,255,.55); }
    .dg-name, .dg-sub, .dg-sw { transition: color .5s var(--ease-out-quart, ease); }

    /* 只做淡入：淡出要靠定时器，后台标签/无 rAF 环境会卡在半透明 */
    .dg-cap-in.is-in { animation: dg-cap-in .42s var(--ease-out-quart, ease) both; }
    @keyframes dg-cap-in {
      from { opacity: 0; transform: translateY(5px); }
      to { opacity: 1; transform: none; }
    }

    /* ---- 收尾提示：滚到最后一格才出现，指着下面的正式清单 ---- */
    .dg-more { position: absolute; left: 50%; transform: translateX(-50%);
      bottom: clamp(var(--space-6), 5vh, var(--space-12)); z-index: 8;
      display: flex; flex-direction: column; align-items: center; gap: var(--space-2-5);
      font-size: var(--fs-nano); letter-spacing: .14em; color: var(--dg-mut);
      /* 首帧就在（它本身就是下拉引导），不做「滚到底才出现」那套 */
      opacity: 1; pointer-events: none; }
    .dg-more i { display: block; width: 1px; height: var(--space-8);
      background: linear-gradient(to bottom, currentColor, transparent);
      animation: dg-drop 2s var(--ease-out-quart, ease) infinite; }
    @keyframes dg-drop {
      0% { transform: scaleY(.15); transform-origin: top; opacity: 0; }
      45% { transform: scaleY(1); opacity: 1; }
      100% { transform: scaleY(1); opacity: 0; }
    }

    @media (max-width: 767px) {
      .dg-track { height: calc(var(--dg-h) + 250svh); }
      .dg-plane { width: 88vw; }
      /* 手机上底部被站点的浮动 CTA 条占着（fixed / 左右 16 / 下 14 / 高约 52）
         ⇒ 文字挪到上方，不去和按钮抢位置；副标让给图片 */
      .dg-cap { top: calc(var(--header-height) + var(--space-6)); bottom: auto; transform: none;
        left: var(--space-6); right: var(--space-6); max-width: none; }
      .dg-sub { display: none; }
      /* 提示要让开浮动条：80 + 8 = 88px，再加安全区 */
      .dg-more { left: auto; right: var(--space-6); transform: none; align-items: flex-end;
        bottom: calc(var(--space-20) + var(--space-2) + env(safe-area-inset-bottom, 0px)); }
    }

    /* ---- 开屏期间的透明页头 ------------------------------------------
       本页常态是「白底深字」（page-styles.css 上方那段强制）。画廊当开屏时，
       页头必须让位：透明底 + 白字 + 白色 logo，直到最后那格（法式 / 暖白）
       亮起来才切回白底深字。由 JS 按**当前插值底色亮度**挂 body.dg-hd-dark，
       不写死进度 —— 深蓝→暖白的中段是浅灰，按进度切会有一段白字压浅灰。 */
    body.dg-hd-dark .site-header,
    body.dg-hd-dark .site-header.scrolled { background: transparent; box-shadow: none; }
    body.dg-hd-dark .site-header:not(.scrolled)::before { content: none; }
    body.dg-hd-dark .site-header .nav-link { color: #fff; }
    body.dg-hd-dark .site-header .brand-logo-white { opacity: 1; }
    body.dg-hd-dark .site-header .brand-logo-color { opacity: 0; }
    body.dg-hd-dark .site-header .mobile-menu-btn { color: #fff; }
    /* 🔴 2026-10-31：这里**不再覆盖 `.nav-cta`**。原来那条是
       `body.dg-hd-dark .site-header .nav-cta`，只设了 color 与 border-color（加一圈半透明白描边）
       —— 而主 CTA 本身是「蓝底白字」，压在任何色斑上都清楚
       （实测画廊五个底色里最亮的法式 #F4EDE3 上，蓝色按钮对比度反而更好）。
       删掉之后：全站 `.nav-cta` 只剩 shared.css 一处定义，跨页视觉统一 ——
       这正是「同类名只许一处定义」那条单点判据要的结果（原先它报红：命中 4 处，2 处在本文件）。
       ⚠️ 想再加深色页头专属样式，**改 shared.css 的变量** `--nav-cta-ink / --nav-cta-line`，
          不要在这里写选择器；改 shared.css 后必须跑
          `build_css_split.py` + `build_css_bundles.py` 重建分包（后者依赖 Python 版 playwright）。 */
    .site-header, .site-header .nav-link, .site-header .brand-logo,
    .site-header .mobile-menu-btn {
      transition: background-color var(--duration-normal) var(--ease-out-quart), box-shadow var(--duration-normal) var(--ease-out-quart), color var(--duration-normal) var(--ease-out-quart), opacity var(--duration-normal) var(--ease-out-quart), border-color var(--duration-normal) var(--ease-out-quart);
    }

    @media (prefers-reduced-motion: reduce) {
      .dg-bgset i, .dg-more i { animation: none; }
    }
/* DG:GALLERY:END */

/* ===== 风格索引层（2026-11-02）=====
   八张卡 + 温度/浓度两条筛选轴，插在 hero 与 contact sheet 之间。
   🔴 不删除、不重排不匹配的卡：删了会跳版，且用户失去「全集」感；
      手机单列时例外（变灰会白占三屏）⇒ ≤767 直接收起。
   🔴 圆角/字号/间距全部走令牌；颜色只取本文件既有值（--sty-ink/-mut、#E2DED5、#EAE7E1）。 */
.sty-index { max-width: 1200px; margin: 0 auto; padding: clamp(var(--space-9), 4.5vw, var(--space-12)) var(--space-6) 0; }
.sty-index-head h2 { margin: 0; font-size: clamp(1.5rem, 2.8vw, 2.125rem); line-height: 1.3; font-weight: 700; letter-spacing: .01em; color: var(--sty-ink); }
.sty-index-head p { margin: var(--space-3) 0 0; font-size: var(--fs-body); line-height: 1.85; color: var(--sty-mut); max-width: 62ch; }
.sty-axis { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; margin-top: var(--space-5); }
.sty-axis-lb { font-size: var(--fs-small); letter-spacing: .1em; color: var(--sty-mut); }
.sty-chips { display: flex; gap: var(--space-1-5); flex-wrap: wrap; }
.sty-chip {
  appearance: none; cursor: pointer; font: inherit; font-size: var(--fs-small);
  color: var(--sty-ink); background: transparent; border: 1px solid #E2DED5;
  border-radius: var(--radius-full); padding: var(--space-1-5) var(--space-3-5);
  transition: background-color var(--duration-normal) var(--ease-out-quart),
              border-color var(--duration-normal) var(--ease-out-quart),
              color var(--duration-normal) var(--ease-out-quart);
}
.sty-chip[aria-pressed="true"] { background: var(--sty-ink); border-color: var(--sty-ink); color: var(--color-surface, #fff); }
.sty-chip:focus-visible { outline: 2px solid var(--sty-accent, #8A9A7B); outline-offset: 2px; }
.sty-count { margin-left: auto; font-size: var(--fs-caption); color: var(--sty-mut); font-variant-numeric: tabular-nums; }

.sty-cards { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4); margin-top: var(--space-6); }
.sty-card { display: flex; flex-direction: column; text-decoration: none; color: inherit; border: 1px solid #E2DED5; border-radius: var(--radius-md); overflow: hidden;
  transition: border-color var(--duration-normal) var(--ease-out-quart),
              opacity var(--duration-normal) var(--ease-out-quart),
              filter var(--duration-normal) var(--ease-out-quart); }
.sty-card-ph { display: block; aspect-ratio: 3 / 2; overflow: hidden; background: #EAE7E1; }
.sty-card-ph picture { display: block; width: 100%; height: 100%; }
.sty-card-ph img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform var(--duration-slow) var(--ease-out-quart); }
.sty-card-body { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3-5); }
.sty-card-top { display: flex; align-items: baseline; gap: var(--space-2); }
.sty-card-no { font-size: var(--fs-nano); color: var(--sty-mut); letter-spacing: .08em; font-variant-numeric: tabular-nums; }
.sty-card-nm { font-size: var(--fs-body); font-weight: 700; color: var(--sty-ink); }
.sty-card-dots { margin-left: auto; display: flex; gap: var(--space-1); }
/* 色点描边用 border 不用 box-shadow：10px 的圆点上 inset 阴影与 inset 边框肉眼等价，
   但 box-shadow 走 shadow 族会被令牌棘轮记一笔（同值第 2 处 ⇒ B1 +1）。 */
.sty-card-dots i { width: 10px; height: 10px; box-sizing: border-box; border: 1px solid rgba(11, 31, 58, .12); border-radius: var(--radius-full); }
.sty-card-ln { font-size: var(--fs-small); line-height: 1.7; color: var(--sty-mut); }
.sty-card-ft { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-1); font-size: var(--fs-caption); color: var(--sty-mut); }
/* 「进入 →」原用 --sty-accent 上色，实测对比度 2.96–3.89 < 4.5 判红（浅色系尤甚）。
   主色留给描边与色点，文字回到 --sty-ink —— 克制优先，可读性优先。 */
.sty-card-go { margin-left: auto; color: var(--sty-ink); }
.sty-card.is-dim { opacity: .38; filter: saturate(.3); }
.sty-card:focus-visible { outline: 2px solid var(--sty-accent, #8A9A7B); outline-offset: 3px; }
@media (hover: hover) {
  .sty-card:hover { border-color: var(--sty-accent, #8A9A7B); }
  .sty-card:hover .sty-card-ph img { transform: scale(1.045); }
}
@media (max-width: 1023px) { .sty-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px) {
  .sty-cards { grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
  .sty-card.is-dim { display: none; }
  .sty-count { margin-left: 0; flex-basis: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .sty-card, .sty-card-ph img, .sty-chip { transition: none; }
}
