  :root{
    --bg:           #080D1F;
    --bg-soft:      #111827;
    --bg-raised:    #1A2035;
    --ink:          #FFFFFF;
    --ink-soft:     #D9D9E3;
    --ink-mute:     #8A8A95;
    --ink-subtle:   #5A5A65;
    /* P0 单一色源: --accent-brand 是唯一原始色（admin SiteConfig.accent_color
       注入，默认 #0088FF；base.html 只允许注入这一个变量）。--accent 及全部派生
       token 一律由它推导 —— 任何层禁止再写死蓝色字面量，否则 admin 换色后
       按钮 hover / 渐变 / 阴影不同步。字面量是老浏览器 fallback；color-mix
       派生统一放在下方 @supports 块（自定义属性不做语法校验，直接写
       color-mix 会让老浏览器把该字面量代入消费属性 → 整条声明失效）。 */
    --accent-brand: #0088FF;
    --accent:       var(--accent-brand, #0088FF);
    --accent-hover: #269DFF;
    --accent-soft:  rgba(0, 136, 255, 0.10);
    --accent-glow:  rgba(0, 136, 255, 0.22);
    --accent-deep:  #0066BF;
    --success:      #22C55E;
    --info:         #38BDF8;
    --warning:      #F59E0B;
    --line:         rgba(255, 255, 255, 0.07);
    --line-strong:  rgba(255, 255, 255, 0.14);

    /* Font stack: Inter 是品牌字体（从 Google Fonts 加载）；
       中文 fallback 必须显式声明——浏览器自带的 system-ui 在 iOS 是 SF Pro
       (英文) + PingFang SC (中文)，两者 baseline / 字宽不同 → 中英文混排
       看起来「参差」；安卓 system-ui 是 Roboto (英文) + Noto Sans CJK (中文)，
       Noto 家族设计上保持中英文字宽统一 → 看起来「整齐」。
       解决方案：iOS 优先用 PingFang SC 接管（苹方是设计为中英文字宽统一的多
       语言字体），安卓优先用 Noto Sans CJK / 思源黑体；中间塞 -apple-system
       和 BlinkMacSystemFont 让 iOS 显式认 SF Pro。 */
    --ff-display: 'Inter', system-ui, -apple-system, BlinkMacSystemFont,
                  "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
                  "Source Han Sans CN", "Noto Sans CJK SC", Roboto, sans-serif;
    --ff-body:    'Inter', system-ui, -apple-system, BlinkMacSystemFont,
                  "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
                  "Source Han Sans CN", "Noto Sans CJK SC", Roboto, sans-serif;
    --ff-mono:    'IBM Plex Mono', ui-monospace, "SF Mono", Menlo, monospace;

    /* Font-size variables. Default values mirror the original hardcoded
       sizes so the site renders correctly even before the admin-injected
       overrides in base.html <style> block are applied (e.g. Vercel cold
       start, cached CSS without matching HTML). Admin overrides these via
       the dynamic :root block in base.html. */
    --fs-base:          clamp(15px, 0.9375rem + 0.125vw, 18px);
    --fs-nav:           17px;
    --fs-hero-title-admin:    clamp(36px, 7vw, 72px);
    --fs-hero-subtitle: clamp(15px, 1.1vw, 17px);
    --fs-section-title-admin: clamp(34px, 5vw, 64px);
    --fs-body:          clamp(15px, 0.9375rem + 0.125vw, 16px);
    --fs-card-title:    clamp(20px, 2vw, 24px);
    --fs-card-desc:     14px;

    /* Public aliases consumed by .hero-title / .section-title (F5'/D1).
       The mobile media query near the end of this file re-derives these
       responsively; the -admin vars carry the raw (admin or fallback) value. */
    --fs-hero-title:    var(--fs-hero-title-admin);
    --fs-section-title: var(--fs-section-title-admin);

    --sp-1: 8px;
    --sp-2: 16px;
    --sp-3: 24px;
    --sp-4: 48px;
    --sp-5: 96px;
    --sp-6: 160px;
    --radius-control: 8px;
  }

  /* ============ LIGHT THEME ============ */
  [data-theme="light"]{
    --bg:           #F5F7FA;
    --bg-soft:      #EBEEF3;
    --bg-raised:    #FFFFFF;
    --ink:          #111827;
    --ink-soft:     #374151;
    --ink-mute:     #6B7280;
    --ink-subtle:   #9CA3AF;
    /* P0: light 主题 accent 必须从 brand 压暗派生。修复历史 bug —— admin 注入块
       曾直接写 `:root{--accent:…}`，与本块 specificity 相同且源序更靠后，会把
       这里的 light 覆盖冲掉 → 浅色模式也用深色主题亮蓝（对比度不足）。
       admin 现只注入 --accent-brand，本覆盖永不再被冲掉。hover/deep 无需在此
       声明：@supports 块里的派生引用 var(--accent)，在 html 元素上自动解析为
       本值。 */
    --accent:       #006AC7;
    --accent-soft:  rgba(0, 106, 199, 0.08);
    --accent-glow:  rgba(0, 106, 199, 0.12);
    --success:      #16A34A;
    --info:         #0284C7;
    --warning:      #D97706;
    --line:         rgba(0, 0, 0, 0.07);
    --line-strong:  rgba(0, 0, 0, 0.12);
  }

  /* ============ P0: ACENT DERIVATION (color-mix, gated) ============ */
  /* 派生 token 的 color-mix 版本必须包在 @supports 内：自定义属性不做语法
     校验，不支持 color-mix 的浏览器会原样代入 `background: color-mix(…)`
     → 解析失败 → IACVT → 属性变 unset（比上面的字面 fallback 更糟）。
     上面 :root/[data-theme=light] 的字面量即老浏览器最终值（对默认品牌色
     精确；admin 自定义色时老浏览器派生色不跟随 —— 可接受降级）。
     普通声明里的 color-mix（渐变/阴影双声明的第二行）会在老浏览器解析期
     被整条丢弃、自然回落第一行，无需包裹。 */
  @supports (color: color-mix(in srgb, red 50%, blue)) {
    :root {
      --accent-hover: color-mix(in srgb, var(--accent), #fff 15%);
      --accent-soft:  color-mix(in srgb, var(--accent), transparent 90%);
      --accent-glow:  color-mix(in srgb, var(--accent), transparent 78%);
      --accent-deep:  color-mix(in srgb, var(--accent), #000 25%);
    }
    [data-theme="light"] {
      --accent:       color-mix(in srgb, var(--accent-brand, #0088FF), #000 22%);
      --accent-soft:  color-mix(in srgb, var(--accent), transparent 92%);
      --accent-glow:  color-mix(in srgb, var(--accent), transparent 88%);
    }
  }

  /* Light theme nav */
  [data-theme="light"] .nav {
    background: rgba(245, 247, 250, 0.82);
    box-shadow: 0 1px 3px rgba(0,0,0,0.06);
  }
  [data-theme="light"] .mobile-panel {
    background: rgba(245, 247, 250, 0.95);
  }
  [data-theme="light"] .mobile-panel-overlay {
    background: rgba(0, 0, 0, 0.3);
  }

  /* Light theme hero */
  [data-theme="light"] .hero-bg::after {
    background: transparent;
  }
  [data-theme="light"] .hero-grid {
    background-image:
      linear-gradient(to right, rgba(0, 0, 0, 0.03) 1px, transparent 1px),
      linear-gradient(to bottom, rgba(0, 0, 0, 0.03) 1px, transparent 1px);
  }
  [data-theme="light"] .hero-noise { opacity: 0.02; }
  [data-theme="light"] .hero-corner-marks::before,
  [data-theme="light"] .hero-corner-marks::after { border-color: var(--accent); opacity: 0.5; }
  [data-theme="light"] .hero-field-glow {
    background:
      radial-gradient(ellipse 80% 50% at 50% 60%, rgba(0, 98, 196, 0.04) 0%, transparent 70%),
      radial-gradient(ellipse 40% 30% at 30% 70%, rgba(0, 98, 196, 0.02) 0%, transparent 60%),
      radial-gradient(ellipse 40% 30% at 70% 70%, rgba(0, 98, 196, 0.02) 0%, transparent 60%);
  }
  [data-theme="light"] .hero-field-lines {
    border-color: rgba(0, 98, 196, 0.06);
    border-top-color: rgba(0, 98, 196, 0.1);
  }
  [data-theme="light"] .hero-field-lines::before { background: rgba(0, 98, 196, 0.06); }
  [data-theme="light"] .hero-field-lines::after { border-color: rgba(0, 98, 196, 0.05); }

  /* Light theme footer */
  [data-theme="light"] footer {
    background: #111827;
    color: #D1D5DB;
  }
  [data-theme="light"] .footer-col-label { color: #9CA3AF; }
  [data-theme="light"] .footer-list a:hover { color: #FFFFFF; }
  [data-theme="light"] .footer-brand-name { color: #FFFFFF; }
  [data-theme="light"] .footer-bottom { border-top-color: rgba(255,255,255,0.08); color: #9CA3AF; }
  [data-theme="light"] .footer-social a { color: #9CA3AF; }
  [data-theme="light"] .footer-social a:hover { color: #FFFFFF; }
  [data-theme="light"] .footer-contact-item { color: #9CA3AF; }
  [data-theme="light"] .footer-contact-item a { color: #D1D5DB; }
  [data-theme="light"] .footer-contact-item a:hover { color: #FFFFFF; }

  /* Light theme cards need subtle shadow */
  [data-theme="light"] .about-pillar,
  [data-theme="light"] .about-optic-card,
  [data-theme="light"] .about-service-card {
    box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04);
  }
  [data-theme="light"] .about-pillar:hover,
  [data-theme="light"] .about-optic-card:hover,
  [data-theme="light"] .about-service-card:hover {
    box-shadow: 0 8px 24px -8px rgba(0,0,0,0.1);
  }

  /* Theme toggle button */
  .theme-toggle {
    display: flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; border-radius: var(--radius-control);
    border: 1px solid var(--line-strong);
    background: transparent; cursor: pointer;
    transition: border-color 0.2s, background 0.2s;
    flex-shrink: 0;
  }
  .theme-toggle:hover { border-color: var(--accent); background: var(--accent-soft); }
  .theme-toggle svg { width: 18px; height: 18px; color: var(--ink-soft); transition: color 0.2s; }
  .theme-toggle:hover svg { color: var(--accent); }

  /* Body transition for smooth theme switch */
  body, .nav, .hero-bg::after { transition: background-color 0.4s ease, color 0.3s ease, border-color 0.3s ease; }

  /* Language switcher */
  .lang-switch {
    position: relative;
    flex-shrink: 0;
  }
  .lang-switch-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-control);
    background: transparent;
    cursor: pointer;
    transition: border-color 0.2s, background 0.2s;
    color: var(--ink-soft);
    font-family: var(--ff-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.06em;
  }
  .lang-switch-btn:hover { border-color: var(--accent); background: var(--accent-soft); }
  .lang-switch-menu {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    background: var(--bg-raised);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-control);
    min-width: 160px;
    z-index: 100;
    overflow: hidden;
    box-shadow: 0 8px 24px -8px rgba(0,0,0,0.3);
  }
  .lang-switch-menu.open { display: block; }
  .lang-switch-option {
    display: block;
    padding: 10px 16px;
    font-family: var(--ff-mono);
    font-size: 12px;
    color: var(--ink-soft);
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
  }
  .lang-switch-option:hover { background: var(--accent-soft); color: var(--accent); }
  .lang-switch-option.active { color: var(--accent); font-weight: 600; }

  /* RTL support for Arabic */
  /* v1.8.2 — bidi isolation. <bdi> is isolate by default per spec, but any
     inherited `unicode-bidi` or author reset can override it, and on RTL pages
     an unisolated Latin string (model code "VSP-4200W-9M-YP", "2200 lux",
     "Beijing, China") gets reorder-punctuated against the Arabic paragraph
     direction. Declaring it explicitly makes the intent non-negotiable. */
  [dir="rtl"] bdi { unicode-bidi: isolate; }
  [dir="rtl"] .nav-links { flex-direction: row-reverse; }
  [dir="rtl"] .nav-brand { order: 1; }
  [dir="rtl"] .nav-actions { flex-direction: row-reverse; }
  [dir="rtl"] .hero-content { text-align: right; }
  [dir="rtl"] .footer-grid { direction: rtl; }
  [dir="rtl"] .footer-bottom { flex-direction: row-reverse; }
  [dir="rtl"] .lang-switch-menu { right: auto; left: 0; }
  [dir="rtl"] .hero-corner-marks { transform: scaleX(-1); }
  [dir="rtl"] .home-preview-card.reversed .home-preview-img { order: 1; }
  [dir="rtl"] .home-preview-card.reversed .home-preview-text { order: 2; }

  .home-preview-section {
    padding: 48px 0 0;
  }
  .home-preview-card {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0;
    border: 1px solid var(--line);
    margin-bottom: 0;
    transition: border-color 0.3s;
  }
  .home-preview-card:hover {
    border-color: var(--line-strong);
  }
  .home-preview-img {
    overflow: hidden;
    min-height: 320px;
    background: var(--bg);
  }
  .home-preview-img img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    transition: transform 0.5s ease;
  }
  .home-preview-card:hover .home-preview-img img {
    transform: scale(1.03);
  }
  .home-preview-text {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 48px 48px;
    gap: 20px;
  }
  .home-preview-tag {
    font-family: var(--ff-mono);
    font-size: 11px;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--accent);
  }
  .home-preview-text h2 {
    font-family: var(--ff-display);
    font-size: clamp(1.4rem, 2.5vw, 1.8rem);
    font-weight: 600;
    color: var(--ink);
    line-height: 1.25;
    margin-bottom: 0;
  }
  .home-preview-text p {
    font-size: 0.95rem;
    line-height: 1.75;
    color: var(--ink-mute);
    max-width: 480px;
  }
  .home-preview-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--ff-mono);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--accent);
    transition: gap 0.2s;
    margin-top: 4px;
  }
  .home-preview-link:hover {
    gap: 12px;
  }
  .home-preview-link .link-arrow {
    transition: transform 0.2s;
    font-size: 14px;
  }
  .home-preview-link:hover .link-arrow {
    transform: translateX(4px);
  }
  .home-preview-card.reversed .home-preview-img {
    order: 2;
  }
  .home-preview-card.reversed .home-preview-text {
    order: 1;
  }
  @media (max-width: 767px) {
    .home-preview-card,
    .home-preview-card.reversed {
      grid-template-columns: 1fr;
    }
    .home-preview-card .home-preview-img,
    .home-preview-card.reversed .home-preview-img {
      order: -1;
      min-height: 220px;
    }
    .home-preview-card .home-preview-text,
    .home-preview-card.reversed .home-preview-text {
      order: 1;
      padding: 32px 24px;
    }
  }
  [dir="rtl"] .link-arrow { display: inline-block; transform: scaleX(-1); }

  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
  html {
    scroll-behavior: smooth;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* N-29: clip root-level horizontal overflow. The closed .mobile-panel is
       position:fixed at translateX(100%) (just off the right edge); its box and
       box-shadow extend past the viewport. body's overflow-x:hidden cannot clip
       a fixed element (its containing block is the viewport), so only a root
       clip stops the mobile "zoom-out / hamburger off-screen" overflow.
       clip (vs hidden) does not create a scroll container, so position:sticky
       (e.g. .sidebar-nav) still works. hidden is the fallback for old engines. */
    overflow-x: hidden;
    overflow-x: clip;
  }
  body {
    font-family: var(--ff-body);
    font-size: var(--fs-base);
    line-height: 1.6;
    color: var(--ink-soft);
    background: var(--bg);
    overflow-x: hidden;
    /* N-10: global long-word protection — emails / model names can no
       longer overflow containers and get silently clipped by
       overflow-x:hidden (same failure mode as P0-1). */
    overflow-wrap: anywhere;
    letter-spacing: -0.005em;
  }
  img { max-width: 100%; display: block; }
  a { color: inherit; text-decoration: none; }
  button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }

  .container { max-width: 1280px; margin: 0 auto; padding: 0 16px; }
  @media (min-width: 768px) { .container { padding: 0 32px; } }

  /* ============ NAV ============ */
  .nav {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 100;
    padding: 8px 0;
    background: rgba(10, 14, 26, 0.18);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  }
  .nav-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
  }
  .nav-brand {
    font-family: var(--ff-display);
    font-size: 20px;
    font-weight: 600;
    color: var(--ink);
    letter-spacing: -0.03em;
    display: flex; align-items: center; gap: 8px;
  }
  .nav-brand img { height: 40px; width: auto; }
  .nav-links {
    margin-left: auto;
    display: flex; gap: 4px; align-items: center;
    list-style: none;
    margin-top: 0; margin-bottom: 0;
    padding: 0;
  }
  /* Contact lives in the mobile panel only; desktop uses the styled .nav-cta */
  .nav-links .nav-item-contact { display: none; }
  .nav-links a {
    font-family: var(--ff-body);
    font-size: var(--fs-nav);
    font-weight: 600;
    color: var(--ink-soft);
    padding: 6px 12px;
    letter-spacing: 0.01em;
    white-space: nowrap;
    transition: color 0.2s, background 0.2s;
  }
  .nav-links a:hover { color: var(--accent); }
  .nav-cta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--ff-mono);
    font-size: 12px;
    color: var(--ink);
    padding: 8px 14px;
    border: 1px solid var(--line-strong);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    transition: all 0.2s;
    white-space: nowrap;
  }
  .nav-cta:hover { border-color: var(--accent); color: var(--accent); }
  .nav-cta .arrow { transition: transform 0.2s; }
  .nav-cta:hover .arrow { transform: translateX(3px); }

  /* Right-hand nav controls. Hidden below 768px — their functions move
     into the mobile panel (.panel-actions) so nothing is lost. */
  .nav-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-shrink: 0;
  }

  /* Hamburger */
  .hamburger {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 1px solid var(--line-strong);
    z-index: 110;
    flex-shrink: 0;
  }
  @media (min-width: 1025px) { .hamburger { display: none; } }
  .hamburger svg { width: 20px; height: 20px; color: var(--ink); }

  /* Compact nav bar (phones + tablets): keep only brand + hamburger so the
     bar can never overflow a narrow/tablet viewport. Nav links, CTA, theme and
     language all move into the mobile panel — no functionality is lost. */
  @media (max-width: 1024px) {
    .nav-inner { gap: 12px; }
    .nav-links { display: none; }
    .nav-actions { display: none; }
    .nav-brand img { height: 36px; max-width: 160px; }
    /* N-9: hit areas >=44px via transparent pseudo-elements (WCAG 2.5.8 /
       Apple HIG). Visual sizes are unchanged; only the tappable area grows. */
    .theme-toggle,
    .lang-switch-btn { position: relative; }
    .theme-toggle::after { content: ""; position: absolute; inset: -4px; }
    .lang-switch-btn::after { content: ""; position: absolute; inset: -9px -4px; }
  }

  /* Mobile side panel
     Width: 240px (down from 260px / 300px). Drawer content is just 6 short
     nav links + 2 utility buttons, so 240px is plenty (longest word
     "Products" at 18px ≈ 75px). max-width: 72vw still caps it on very
     narrow devices.
     Bottom padding uses env(safe-area-inset-bottom) — REQUIRES
     `viewport-fit=cover` in the meta viewport tag, otherwise env() returns
     0 and the bottom buttons get hidden under the iOS Home Indicator. */
  .mobile-panel {
    position: fixed;
    top: 0; right: 0;
    /* v1.1.14: 抽屉收紧到「按钮完整 + margin」最窄宽
       估算：Theme 按钮 ~112px (icon 18 + gap 8 + "Theme" 50 + padding 14×2)
             + panel padding 14×2 = 140 → 取 160px 留 6px×2 呼吸 */
    width: 160px;
    max-width: 56vw;
    height: 100vh;
    height: 100dvh;
    /* Glass. Alpha dropped 0.92 -> 0.72: at 0.92 the blur was invisible
       and the panel read as a solid slab. */
    background: rgba(10, 14, 26, 0.72);
    backdrop-filter: saturate(160%) blur(20px);
    -webkit-backdrop-filter: saturate(160%) blur(20px);
    border-left: 1px solid rgba(255, 255, 255, 0.12);
    box-shadow: -24px 0 60px rgba(0, 0, 0, 0.45);
    z-index: 105;
    transform: translateX(100%);
    /* N-29: hide the closed drawer (and its box-shadow) so it can't bleed a
       dark strip onto the viewport's far-right edge. visibility (not display)
       preserves the slide-out animation via the delayed transition below. */
    visibility: hidden;
    transition: transform 0.35s ease, visibility 0s linear 0.35s;
    display: flex;
    flex-direction: column;
    padding: 76px 22px calc(32px + env(safe-area-inset-bottom, 0px));
  }
  .mobile-panel.open { transform: translateX(0); visibility: visible; transition: transform 0.35s ease, visibility 0s; }
  .mobile-panel-close {
    position: absolute;
    top: 24px; right: 24px;
    width: 36px; height: 36px;
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--line-strong);
    color: var(--ink);
  }
  .mobile-panel-close svg { width: 16px; height: 16px; }
  .mobile-panel-links {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0;
  }
  .mobile-panel-links li {
    border-bottom: 1px solid var(--line);
  }
  .mobile-panel-links a {
    display: block;
    padding: 14px 0;
    font-family: var(--ff-display);
    font-size: 18px;
    font-weight: 500;
    color: var(--ink);
    letter-spacing: -0.01em;
    transition: color 0.2s;
  }
  .mobile-panel-links a:hover { color: var(--accent); }
  .mobile-panel-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 104;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.35s ease;
  }
  .mobile-panel-overlay.open { opacity: 1; pointer-events: auto; }

  /* N-29: the drawer is compact-nav-only (the hamburger that opens it is hidden
     at >=1025px). Keep it out of the desktop render entirely so its off-screen
     box-shadow can never bleed a dark strip onto the right edge on PC. The
     visibility rule above handles the same bleed on mobile/tablet. */
  @media (min-width: 1025px) {
    .mobile-panel,
    .mobile-panel-overlay { display: none; }
  }

  /* Utilities parked inside the mobile panel (theme + language).
     Below 768px these are the ONLY place to reach them, since the
     nav bar keeps just the brand and the hamburger. */
  .panel-actions {
    margin-top: auto;
    padding-top: 20px;
    /* N-26: 安卓 WebView（百度 App / 微信内置 / 部分 Chrome）下
       env(safe-area-inset-bottom) 经常返回 0 或不支持，
       仅用 env() 会让主题/语言按钮贴底被遮（实测安卓机被完全遮住）。
       用 max() 兜底：env 支持则取 env+48，不支持则固定 80px，
       80px ≈ 安卓底部导航条(50) + 手势条(24)，任一设备都不会被遮。
       iOS 不加 viewport-fit=cover 时，env 也会返回 0，同样走兜底分支 */
    padding-bottom: max(80px, calc(env(safe-area-inset-bottom, 0px) + 48px));
    border-top: 1px solid var(--line);
    display: flex;
    /* v1.1.14: 用户反馈"按钮太大"，竖向排列 + 抽屉宽度收紧到刚好装下 */
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    /* 防止 panel 内容过多时被挤到按钮后面 */
    flex-shrink: 0;
  }
  /* v1.1.14: panel 内的 Theme 按钮铺满 + 横向文字对齐 */
  .panel-actions .theme-toggle {
    width: 100%;
    height: 36px;
    padding: 0 14px;
    gap: 8px;
    justify-content: flex-start;
  }
  /* v1.1.14: panel 内的语言切换器 — 与 Theme 按钮完全对齐
     关键：外层 div 清 padding（避免双重 padding 让文字右偏 10px），
     内层 button 自己接管 padding:0 14px，与 Theme 按钮一致 → "EN" 起点 = 14px，
     与上方菜单 "Home" 文字起点（panel padding 14px）完全对齐。
     高度 36px + border-radius 8px + gap:8px 也与 Theme 一致 →
     两按钮视觉同构（图标到文字距离完全相同，Theme 文字 x=294 / Lang 文字 x=294）。 */
  .panel-actions .lang-switch {
    width: 100%;
    padding: 0;
  }
  .panel-actions .lang-switch-btn {
    width: 100%;
    height: 36px;
    padding: 0 14px;
    gap: 8px;
    justify-content: flex-start;
    border-radius: var(--radius-control);
  }
  .panel-action-label {
    font-family: var(--ff-mono);
    font-size: 12px;
    letter-spacing: 0.06em;
    color: var(--ink-soft);
  }
  /* The panel utilities sit at the bottom, so open the menu upward */
  .panel-actions .lang-switch-menu {
    top: auto;
    bottom: calc(100% + 8px);
    /* N-29: the popup is min-width:160px but the panel content area is ~116px;
       pin it to the button width so it never spills outside the drawer. */
    min-width: 0;
    width: 100%;
  }
  /* N-22: RTL — mirror the drawer. It must slide in from the LEFT, matching
     the reading direction, otherwise Arabic/Hebrew users get a drawer that
     opens against the text flow.
     `:not(.open)` keeps this from out-specifying `.mobile-panel.open`
     (both would be 0-2-0, so source order would decide). */
  [dir="rtl"] .mobile-panel {
    right: auto;
    left: 0;
    border-left: none;
    border-right: 1px solid rgba(255, 255, 255, 0.12);
    box-shadow: 24px 0 60px rgba(0, 0, 0, 0.45);
  }
  [dir="rtl"] .mobile-panel:not(.open) { transform: translateX(-100%); }
  [dir="rtl"] .mobile-panel-close { right: auto; left: 22px; }
  /* N-29: keep the theme/language buttons stacked vertically in the narrow
     RTL drawer (same as LTR). row-reverse forced them side-by-side, overflowing
     the 160px panel and pushing the language button outside the drawer. */
  [dir="rtl"] .panel-actions { flex-direction: column; }

  /* ============ HERO ============ */
  .hero {
    position: relative;
    min-height: 85vh;
    padding: 100px 0 70px;
    display: flex;
    align-items: center;
    overflow: hidden;
  }
  .hero-bg {
    position: absolute;
    inset: 0;
    z-index: 0;
  }
  .hero-bg::after {
    content: '';
    position: absolute;
    inset: 0;
    background: transparent;
    z-index: 2;
  }
  /* Hero carousel */
  .hero-carousel-track {
    position: absolute;
    inset: 0;
  }
  /* 用 <picture> 切换横版/竖版 hero 后，picture 自身是 inline 元素，会在
     track 内留下一个空行盒；display:contents 让它不参与布局，内部 img 的
     absolute 定位行为与改造前完全一致（N-26）。 */
  .hero-carousel-track > picture { display: contents; }
  .hero-slide {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 42%;
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    transition: opacity 1.2s ease-in-out;
  }
  .hero-slide.active {
    opacity: 1;
  }
  /* v1.10.1: base.html 的轮播会在切帧时给 <img> 赋 src（首屏预算），
     data-src 阶段元素还没有图片源，visibility:hidden 保证 alt 文本/破损
     图标不会在淡入前露头。与 opacity:0 叠加只是双保险。 */
  .hero-slide:not(.active) {
    visibility: hidden;
  }
  [data-theme="light"] .hero-slide {
    filter: brightness(0.95);
  }
  @media (min-width: 768px) {
    .hero { min-height: 100vh; min-height: 100svh; } /* N-11: svh 跟随动态视口；100vh 为不支持 svh 的旧浏览器降级（成对，§6.8.3） */
  }
  .hero-grid {
    position: absolute; inset: 0;
    background-image:
      linear-gradient(to right, rgba(255, 255, 255, 0.03) 1px, transparent 1px),
      linear-gradient(to bottom, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
    background-size: 64px 64px;
    mask-image: radial-gradient(ellipse 70% 60% at 50% 45%, rgba(0,0,0,1), transparent 85%);
    -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 45%, rgba(0,0,0,1), transparent 85%);
  }
  .hero-noise {
    position: absolute; inset: 0;
    opacity: 0.04;
    background-image:
      radial-gradient(circle at 1px 1px, #fff 1px, transparent 1px);
    background-size: 3px 3px;
  }
  .hero-corner-marks {
    position: absolute; inset: 0;
    pointer-events: none;
  }
  .hero-corner-marks::before,
  .hero-corner-marks::after {
    content: ''; position: absolute;
    width: 60px; height: 60px;
    border: 1px solid var(--accent);
    opacity: 0.6;
  }
  .hero-corner-marks::before {
    top: 100px; left: 32px;
    border-right: none; border-bottom: none;
  }
  .hero-corner-marks::after {
    bottom: 60px; right: 32px;
    border-left: none; border-top: none;
  }
  @media (max-width: 767px) {
    .hero-corner-marks::before, .hero-corner-marks::after { display: none; }
    .hero { padding: 92px 0 56px; min-height: 60svh; }
    /* N-23: the hero source is 16:9 but the mobile hero box is ~0.48 (measured
       810px tall on a 390px viewport), so object-fit:cover scales the image to
       1440px wide and shows only ~27% of it. Pin the image to a shorter band
       and fade it into the page background; that roughly doubles the visible
       fraction and stops the crop reading as "chopped off".
       A mask (not ::after) is used so the light theme's ::after override
       cannot cancel the fade. Portrait hero sources remain the real fix. */
    .hero-bg {
      height: 62%;
      bottom: auto;
      -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 58%, transparent 100%);
      mask-image: linear-gradient(to bottom, #000 0%, #000 58%, transparent 100%);
    }
  }
  .hero-field-glow {
    position: absolute; inset: 0;
    background:
      radial-gradient(ellipse 80% 50% at 50% 60%, rgba(0, 119, 237, 0.06) 0%, transparent 70%),
      radial-gradient(ellipse 40% 30% at 30% 70%, rgba(0, 119, 237, 0.04) 0%, transparent 60%),
      radial-gradient(ellipse 40% 30% at 70% 70%, rgba(0, 119, 237, 0.04) 0%, transparent 60%);
    pointer-events: none;
    z-index: 0;
  }
  .hero-field-lines {
    position: absolute;
    bottom: 0; left: 50%;
    transform: translateX(-50%);
    width: 90%;
    max-width: 1100px;
    height: 45%;
    border: 1px solid rgba(0, 119, 237, 0.06);
    border-top: 2px solid rgba(0, 119, 237, 0.12);
    border-radius: 50% 50% 0 0 / 20% 20% 0 0;
    pointer-events: none;
    z-index: 0;
  }
  .hero-field-lines::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 10%; right: 10%;
    height: 1px;
    background: rgba(0, 119, 237, 0.08);
  }
  .hero-field-lines::after {
    content: '';
    position: absolute;
    top: 30%;
    left: 50%;
    transform: translateX(-50%);
    width: 30%;
    height: 40%;
    border: 1px solid rgba(0, 119, 237, 0.06);
    border-radius: 50%;
  }

  /* Hide decorative overlays so the hero background image is fully visible */
  .hero-grid,
  .hero-noise,
  .hero-field-glow,
  .hero-field-lines,
  .hero-corner-marks,
  .hero-field-lines::before,
  .hero-field-lines::after,
  .hero-corner-marks::before,
  .hero-corner-marks::after {
    display: none !important;
  }

  .hero-content {
    position: relative;
    z-index: 2;
    text-align: center;
    max-width: 900px;
    margin: 0 auto;
  }
  .hero-meta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 24px;
    font-family: var(--ff-mono);
    font-size: 11px;
    color: var(--ink-mute);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    margin-bottom: 40px;
    flex-wrap: wrap;
  }
  .hero-meta .dot {
    display: inline-block;
    width: 6px; height: 6px;
    background: var(--accent);
    border-radius: 50%;
  }
  .hero-meta .divider {
    flex: 0 0 24px;
    height: 1px;
    background: var(--line-strong);
  }

  .hero-title {
    font-family: var(--ff-display);
    font-size: var(--fs-hero-title);
    font-weight: 500;
    line-height: 0.95;
    letter-spacing: -0.04em;
    color: var(--ink);
    margin-bottom: 40px;
  }
  .hero-title .line { display: block; }
  .hero-title .line.accent {
    background: linear-gradient(90deg, var(--accent) 0%, #4D9BFF 100%);
    /* P0: 终点改为从 accent 派生（默认 #0088FF+30%白 ≈ 原 #4D9BFF，视觉无感）；
       字面行保老浏览器，color-mix 行跟 admin 换色。 */
    background: linear-gradient(90deg, var(--accent) 0%, color-mix(in srgb, var(--accent), #fff 30%) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    font-weight: 600;
  }
  .hero-title .bracket {
    color: var(--accent);
    font-weight: 400;
  }

  /* Text shadow for readability over any hero background image */
  .hero-title,
  .hero-lede,
  .hero-meta,
  .hero-stat-label,
  .hero-stat-num-sub {
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.35), 0 1px 2px rgba(0, 0, 0, 0.5);
  }
  [data-theme="light"] .hero-title,
  [data-theme="light"] .hero-lede,
  [data-theme="light"] .hero-meta,
  [data-theme="light"] .hero-stat-label,
  [data-theme="light"] .hero-stat-num-sub {
    text-shadow: 0 1px 3px rgba(255, 255, 255, 0.7), 0 1px 1px rgba(255, 255, 255, 0.9);
  }

  .hero-lede {
    font-size: var(--fs-hero-subtitle);
    line-height: 1.7;
    color: var(--ink-soft);
    max-width: 620px;
    margin: 0 auto 40px;
    font-weight: 400;
  }

  .hero-actions {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
    justify-content: center;
    margin-bottom: 80px;
    align-items: center;
  }

  .btn-primary {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-family: var(--ff-mono);
    font-size: 12.5px;
    font-weight: 500;
    padding: 18px 28px;
    background: var(--accent);
    color: #fff;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    transition: all 0.2s;
  }
  .btn-primary:hover {
    /* P0: 旧值写死 #0088FF，恰好与 admin 默认 accent 同色 → hover 无色差。
       改为派生 token，admin 换色后 hover 永远跟随且保持可见色差。 */
    background: var(--accent-hover);
    transform: translateY(-1px);
    box-shadow: 0 16px 32px -16px rgba(0, 136, 255, 0.5);
    box-shadow: 0 16px 32px -16px color-mix(in srgb, var(--accent), transparent 50%);
  }
  .btn-primary::after {
    content: '\2192';
    transition: transform 0.2s;
  }
  .btn-primary:hover::after { transform: translateX(3px); }

  .btn-ghost {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-family: var(--ff-mono);
    font-size: 12.5px;
    font-weight: 500;
    padding: 18px 24px;
    color: var(--ink);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    border: 1px solid var(--line-strong);
    transition: all 0.2s;
  }
  .btn-ghost:hover { border-color: var(--ink); }

  .hero-stats {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0;
    max-width: 700px;
    margin: 0 auto;
    border-top: 1px solid var(--line);
    border-left: 1px solid var(--line);
  }
  @media (min-width: 768px) {
    .hero-stats { grid-template-columns: repeat(4, 1fr); }
  }
  .hero-stat {
    padding: 28px 16px 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    border-right: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
  }
  .hero-stat-num {
    font-family: var(--ff-display);
    font-size: clamp(32px, 5vw, 56px);
    font-weight: 700;
    letter-spacing: -0.07em;
    line-height: 0.92;
    /* P0: 起点 #0077ED → var(--accent)（默认 #0088FF，视觉无感），中/终点从
       accent 派生；字面行保老浏览器。 */
    background: linear-gradient(135deg, var(--accent) 0%, #4D9BFF 50%, #00D4FF 100%);
    background: linear-gradient(135deg, var(--accent) 0%, color-mix(in srgb, var(--accent), #fff 30%) 50%, color-mix(in srgb, var(--accent), #00D4FF 55%) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    filter: drop-shadow(0 0 16px rgba(0, 136, 255, 0.45));
    filter: drop-shadow(0 0 16px color-mix(in srgb, var(--accent), transparent 55%));
  }
  .hero-stat-num .unit {
    font-size: 0.4em;
    font-weight: 600;
    margin-left: 2px;
    letter-spacing: -0.03em;
    background: linear-gradient(135deg, #4D9BFF 0%, #00D4FF 100%);
    background: linear-gradient(135deg, color-mix(in srgb, var(--accent), #fff 30%) 0%, color-mix(in srgb, var(--accent), #00D4FF 55%) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    filter: none;
  }
  .hero-stat-label {
    font-family: var(--ff-mono);
    font-size: 11px;
    color: var(--ink-mute);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    font-weight: 500;
  }
  .hero-stat--warranty { gap: 2px; }
  .hero-stat-num-sub {
    font-family: var(--ff-mono);
    font-size: 12px;
    color: var(--ink-mute);
    letter-spacing: 0.1em;
    text-transform: lowercase;
    font-weight: 500;
  }

  /* ============ SECTION GENERIC ============ */
  section { position: relative; padding: 80px 0; }
  @media (min-width: 768px) { section { padding: 120px 0; } }
  @media (min-width: 1200px) { section { padding: 140px 0; } } /* F7: 1024→1200，断点收敛 3 档 */
  .section-label {
    font-family: var(--ff-mono);
    font-size: 11px;
    color: var(--ink-mute);
    letter-spacing: 0.28em;
    text-transform: uppercase;
    margin-bottom: 32px;
    display: inline-flex;
    align-items: center;
    gap: 16px;
  }
  .section-label .num {
    color: var(--accent);
    font-weight: 600;
  }
  .section-label::before {
    content: '';
    width: 40px;
    height: 1px;
    background: var(--line-strong);
  }
  .section-title {
    font-family: var(--ff-display);
    font-size: var(--fs-section-title);
    font-weight: 500;
    line-height: 1.02;
    letter-spacing: -0.04em;
    color: var(--ink);
    max-width: 1000px;
    margin-bottom: 24px;
  }
  .section-body {
    font-size: var(--fs-body);
    line-height: 1.7;
    color: var(--ink-soft);
    max-width: 560px;
  }

  /* ============ PAGE HERO (sub-pages) ============ */
  .page-hero {
    background: var(--bg);
    border-bottom: 1px solid var(--line);
  }

  /* ============ PRODUCTS ============ */
  .products-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0;
    margin-top: 32px;
    border-top: 1px solid var(--line);
    border-left: 1px solid var(--line);
  }
  @media (min-width: 768px) { .products-grid { grid-template-columns: repeat(2, 1fr); margin-top: 40px; } }
  @media (min-width: 1200px) { .products-grid { grid-template-columns: repeat(3, 1fr); margin-top: 48px; } } /* F7: 1024→1200 */
  .product-card {
    background: transparent;
    border-right: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    padding: 5px 14px 16px;
    transition: background 0.3s, transform 0.3s, box-shadow 0.3s;
    position: relative;
    min-height: auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
  }
  @media (min-width: 768px) { .product-card { padding: 5px 20px 20px; } }
  .product-card:hover {
    background: var(--bg-soft);
    transform: translateY(-8px);
    box-shadow: 0 20px 40px -20px rgba(0, 0, 0, 0.4);
  }
  .product-card:hover .product-card-img img {
    transform: scale(1.06);
  }
  .product-card-top {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 2px;
    font-family: var(--ff-mono);
    font-size: 11px;
    color: var(--ink-mute);
    letter-spacing: 0.12em;
    text-transform: uppercase;
  }
  .product-card-top .index { color: var(--accent); font-weight: 500; }
  .product-card-img {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 2px;
    aspect-ratio: 4 / 3;
    overflow: hidden;
  }
  .product-card-img img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    transition: transform 0.4s ease;
    filter: drop-shadow(0 4px 12px rgba(0,0,0,0.15));
  }
  .product-card-img img.m-series-img {
    object-fit: contain;
    object-position: center;
  }
  .product-card-title {
    font-family: var(--ff-display);
    font-size: var(--fs-card-title);
    font-weight: 500;
    color: var(--ink);
    letter-spacing: -0.02em;
    margin-bottom: 4px;
    line-height: 1.2;
  }
  .product-card-desc {
    font-size: var(--fs-card-desc);
    line-height: 1.6;
    color: var(--ink-mute);
    margin-bottom: 8px;
    flex: 0 0 auto;
  }
  /* Stadium landing page: keep the full copy in markup (SEO / a11y) but show
     roughly half of it on the card. Scoped to this page via the modifier class
     so /products/ and other grids keep their full-height descriptions. */
  .product-card-desc--compact {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    line-clamp: 4;
    overflow: hidden;
  }
  /* Stadium landing page: exactly two featured products, so the desktop grid
     must stay at two columns instead of the default three. Without this the
     third column is empty and the page looks lopsided on PC browsers. */
  @media (min-width: 768px) { .stadium-products-grid { grid-template-columns: repeat(2, 1fr); } }
  @media (min-width: 1200px) { .stadium-products-grid { grid-template-columns: repeat(2, 1fr); } }
  /* Stadium landing page: the hero intro and the section lead sit in an
     otherwise empty right-hand third on desktop. Remove the readability
     max-width so the copy fills the container and the page feels balanced. */
  .stadium-intro,
  .stadium-intro .section-body,
  .stadium-section-lead { max-width: none; }
  /* Stadium landing page: product images render too large in the two-card
     grid, pushing the table and venue projects below the fold. Cap the image
     container height and use a wider aspect ratio so visitors see more of the
     page on first load. */
  @media (min-width: 768px) {
    .stadium-products-grid .product-card-img {
      aspect-ratio: 2 / 1;
      max-height: 220px;
    }
  }
  @media (min-width: 1200px) {
    .stadium-products-grid .product-card-img {
      aspect-ratio: 2 / 1;
      max-height: 240px;
    }
  }
  /* Stadium landing page FAQ (v1.10.24). product_detail.html carries its own
     inline copy of these rules; this is the same visual language applied to a
     second page. Scoped under .stadium-faq so nothing else inherits it, and the
     values are copied verbatim from the product page rather than restyled, so
     the two FAQ blocks cannot drift apart visually. */
  .stadium-faq {
    margin-top: 0;
    padding-top: 32px;
    border-top: 1px solid var(--line);
  }
  .stadium-faq .detail-faq-label {
    display: block;
    font-family: var(--ff-mono);
    font-size: 13px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 8px;
  }
  .stadium-faq .detail-faq-title {
    font-family: var(--ff-display);
    font-size: 1.6rem;
    font-weight: 600;
    color: var(--ink);
    letter-spacing: -0.02em;
    margin: 0 0 24px;
  }
  .stadium-faq .detail-faq-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
  .stadium-faq .detail-faq-item {
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--bg-soft);
    padding: 0;
    overflow: hidden;
  }
  .stadium-faq .detail-faq-q {
    list-style: none;
    cursor: pointer;
    padding: 16px 20px;
    font-family: var(--ff-display);
    font-size: 1.02rem;
    font-weight: 600;
    color: var(--ink);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
  }
  .stadium-faq .detail-faq-q::-webkit-details-marker { display: none; }
  .stadium-faq .detail-faq-q::after {
    content: "+";
    font-size: 1.4rem;
    line-height: 1;
    color: var(--accent);
    flex-shrink: 0;
    transition: transform 0.2s;
  }
  .stadium-faq .detail-faq-item[open] > .detail-faq-q::after {
    transform: rotate(45deg);
  }
  .stadium-faq .detail-faq-a {
    padding: 0 20px 18px;
    font-size: 0.98rem;
    line-height: 1.7;
    color: var(--ink-soft);
  }
  .stadium-faq .detail-faq-a p { margin: 0 0 8px; }
  .stadium-faq .detail-faq-a p:last-child { margin-bottom: 0; }
  .product-card-specs {
    display: flex;
    gap: 0;
    border-top: 1px solid var(--line);
    padding-top: 8px;
    margin-top: auto;
  }
  .product-spec {
    flex: 1;
    padding-right: 12px;
    border-right: 1px solid var(--line);
  }
  .product-spec:last-child { border-right: none; padding-right: 0; }
  .product-spec-value {
    font-family: var(--ff-display);
    font-size: clamp(16px, 1.5vw, 20px);
    font-weight: 500;
    color: var(--ink);
    letter-spacing: -0.02em;
    line-height: 1;
  }
  .product-spec-label {
    display: block;
    font-family: var(--ff-mono);
    font-size: 10px;
    color: var(--ink-subtle);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    margin-top: 6px;
  }

  /* ============ PROJECTS ============ */
  .projects-grid {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-top: 12px;
  }
  @media (min-width: 768px) { .projects-grid { gap: 16px; margin-top: 12px; } }
  @media (min-width: 1200px) { .projects-grid { gap: 16px; margin-top: 12px; } } /* F7: 1024→1200 */
  .project-card {
    background: var(--bg-soft);
    border: 1px solid var(--line);
    border-radius: 12px;
    overflow: hidden;
    transition: transform 0.3s, box-shadow 0.3s;
    display: flex;
    flex-direction: column;
    height: auto;
  }
  @media (min-width: 768px) {
    .project-card {
      flex-direction: row;
      align-items: center;
      height: 200px;
    }
  }
  .project-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 20px 40px -20px rgba(0, 0, 0, 0.4);
  }
  .project-card-img {
    position: relative;
    width: 100%;
    height: 180px;
    overflow: hidden;
    background: var(--bg-soft);
    flex-shrink: 0;
    border-radius: 8px;
    margin: 12px 12px 0;
  }
  @media (min-width: 768px) {
    .project-card-img {
      width: 45%;
      height: 180px;
      margin: 0 0 0 12px;
      align-self: center;
    }
  }
  /* N-18: 移动端 <768px 时 .project-card 是 flex-direction:column，
     此时 `width:100%` 会与左右各 12px 的 margin 叠加 → 实际宽度 = 容器内容宽 + 24px，
     右侧超出 12px 被卡片的 overflow:hidden 静默裁掉（图片被切、左右留白不对称）。
     flex column 下改 width:auto 即可由 stretch 自动填满并扣掉 margin。
     桌面档已被上面的 45% 覆盖，此规则不影响 ≥768px 渲染。 */
  @media (max-width: 767px) {
    .project-card-img { width: auto; }
  }
  .project-card-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center center;
    border-radius: 8px;
  }
  .project-card-img-placeholder {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
  }
  .project-card-img-placeholder.stadium {
    background: linear-gradient(135deg, #0a1628 0%, #0d2040 30%, #142850 60%, #0a1830 100%);
  }
  .project-card-img-placeholder.stadium::before {
    content: '';
    position: absolute;
    inset: 0;
    background:
      radial-gradient(ellipse 60% 40% at 50% 40%, rgba(0, 119, 237, 0.15) 0%, transparent 70%),
      radial-gradient(ellipse 30% 20% at 20% 60%, rgba(77, 155, 255, 0.08) 0%, transparent 60%),
      radial-gradient(ellipse 30% 20% at 80% 60%, rgba(77, 155, 255, 0.08) 0%, transparent 60%);
  }
  .project-card-img-placeholder.stadium::after {
    content: '';
    position: absolute;
    bottom: 0; left: 10%; right: 10%;
    height: 40%;
    border-top: 1px solid rgba(0, 119, 237, 0.12);
    border-radius: 40% 40% 0 0;
  }
  .project-card-img-placeholder.arena {
    background: linear-gradient(135deg, #0d1420 0%, #101a2e 30%, #0e1830 60%, #0a1020 100%);
  }
  .project-card-img-placeholder.arena::before {
    content: '';
    position: absolute;
    inset: 0;
    background:
      radial-gradient(ellipse 50% 50% at 50% 50%, rgba(0, 119, 237, 0.12) 0%, transparent 60%),
      radial-gradient(circle at 50% 50%, rgba(77, 155, 255, 0.06) 0%, transparent 40%);
  }
  .project-card-img-placeholder.arena::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 60%; height: 50%;
    border: 1px solid rgba(0, 119, 237, 0.08);
    border-radius: 50%;
  }
  .project-card-img-placeholder .field-label {
    position: absolute;
    bottom: 16px; left: 16px;
    font-family: var(--ff-mono);
    font-size: 10px;
    color: rgba(255, 255, 255, 0.3);
    letter-spacing: 0.15em;
    text-transform: uppercase;
  }
  .project-card-body {
    padding: 16px 20px;
    min-width: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  @media (min-width: 768px) { .project-card-body { padding: 18px 22px; } }
  .project-card-location {
    font-family: var(--ff-mono);
    font-size: 11px;
    color: var(--accent);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    margin-bottom: 6px;
  }
  .project-card-title {
    font-family: var(--ff-display);
    font-size: var(--fs-card-title);
    font-weight: 500;
    color: var(--ink);
    letter-spacing: -0.02em;
    margin-bottom: 8px;
    line-height: 1.25;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* F10: 移动端允许换行（桌面卡片窄保留 ellipsis；移动端全宽本有空间） */
  @media (max-width: 767px) {
    .project-card-title { white-space: normal; overflow: visible; }
  }
  .project-card-desc {
    font-size: var(--fs-card-desc);
    line-height: 1.55;
    color: var(--ink-mute);
    margin-bottom: 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .project-card-results {
    display: none;
  }
  .project-card-quote {
    border-left: 2px solid var(--accent);
    padding-left: 16px;
    font-size: 14px;
    line-height: 1.65;
    color: var(--ink-soft);
    font-style: italic;
    margin-bottom: 8px;
  }
  .project-card-attribution {
    font-family: var(--ff-mono);
    font-size: 11px;
    color: var(--ink-subtle);
    letter-spacing: 0.05em;
  }

  /* ============ ABOUT / WHY SOLARONE ============ */
  .about-section {
    background: var(--bg-soft);
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
  }
  .about-content {
    max-width: 720px;
  }
  .about-text {
    font-size: clamp(15px, 0.9375rem + 0.125vw, 16px);
    line-height: 1.8;
    color: var(--ink-soft);
    margin-bottom: 64px;
  }
  @media (min-width: 768px) { .about-text { margin-bottom: 80px; } }
  .about-stats {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0;
    border-top: 1px solid var(--line);
    border-left: 1px solid var(--line);
  }
  @media (min-width: 768px) { .about-stats { grid-template-columns: repeat(4, 1fr); } }
  .about-stat {
    padding: 32px 20px;
    border-right: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  @media (min-width: 768px) { .about-stat { padding: 40px 24px; } }
  .about-stat-num {
    font-family: var(--ff-display);
    font-size: clamp(36px, 5vw, 56px);
    font-weight: 700;
    letter-spacing: -0.06em;
    line-height: 0.92;
    color: var(--ink);
  }
  .about-stat-num .plus { color: var(--accent); }
  .about-stat-num .unit {
    font-size: 0.45em;
    font-weight: 500;
    letter-spacing: -0.02em;
  }
  .about-stat-label {
    font-family: var(--ff-mono);
    font-size: 11px;
    color: var(--ink-mute);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    font-weight: 500;
  }

  /* ============ CONTACT ============ */
  .contact-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 48px;
    margin-top: 48px;
  }
  @media (min-width: 768px) { .contact-grid { grid-template-columns: 1fr 1fr; gap: 64px; margin-top: 64px; } }
  @media (min-width: 1200px) { .contact-grid { margin-top: 80px; } } /* F7: 1024→1200 */

  .contact-info-list {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0;
    margin-bottom: 32px;
  }
  .contact-info-item {
    display: flex;
    align-items: flex-start;
    gap: 20px;
    padding: 24px 0;
    border-bottom: 1px solid var(--line);
  }
  .contact-info-icon {
    width: 44px; height: 44px;
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--line-strong);
    flex-shrink: 0;
    color: var(--accent);
  }
  .contact-info-icon svg { width: 20px; height: 20px; }
  .contact-info-detail {
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .contact-info-label {
    font-family: var(--ff-mono);
    font-size: 10px;
    color: var(--ink-subtle);
    letter-spacing: 0.18em;
    text-transform: uppercase;
  }
  .contact-info-value {
    font-size: 15px;
    color: var(--ink);
    font-weight: 500;
    letter-spacing: -0.01em;
  }
  .contact-info-value a {
    color: inherit;
    transition: color 0.2s;
  }
  .contact-info-value a:hover { color: var(--accent); }

  .contact-whatsapp {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-family: var(--ff-mono);
    font-size: 12.5px;
    font-weight: 500;
    padding: 14px 24px;
    background: #25D366;
    color: #fff;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    transition: all 0.2s;
    margin-top: 16px;
  }
  .contact-whatsapp:hover {
    background: #20BD5A;
    transform: translateY(-1px);
    box-shadow: 0 12px 24px -12px rgba(37, 211, 102, 0.5);
  }
  .contact-whatsapp svg { width: 18px; height: 18px; }

  /* Contact form */
  .contact-form { display: flex; flex-direction: column; gap: 20px; }
  .contact-form-field { display: flex; flex-direction: column; gap: 6px; }
  .contact-form-label {
    display: block;
    font-family: var(--ff-mono);
    font-size: 10px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-subtle);
  }
  .contact-form-control {
    width: 100%;
    padding: 12px 16px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-control);
    background: var(--bg-soft);
    color: var(--ink);
    font-family: var(--ff-body);
    font-size: 16px;
    outline: none;
    transition: border-color 0.2s;
  }
  .contact-form-control[readonly] {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--accent);
  }
  .contact-form-textarea { resize: vertical; min-height: 100px; }
  .form-group { display: flex; flex-direction: column; gap: 6px; }
  .form-group label {
    font-family: var(--ff-mono);
    font-size: 10px;
    color: var(--ink-subtle);
    letter-spacing: 0.18em;
    text-transform: uppercase;
  }
  .form-group input,
  .form-group textarea {
    width: 100%;
    padding: 14px 16px;
    background: var(--bg-soft);
    border: 1px solid var(--line);
    border-radius: var(--radius-control);
    color: var(--ink);
    font-family: var(--ff-body);
    font-size: 15px;
    outline: none;
    transition: border-color 0.2s, box-shadow 0.2s;
  }
  .form-group input::placeholder,
  .form-group textarea::placeholder {
    color: var(--ink-subtle);
  }
  .form-group input:focus,
  .form-group textarea:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-glow);
  }
  .form-group textarea {
    resize: vertical;
    min-height: 120px;
  }
  /* N-1: font-size < 16px makes iOS Safari auto-zoom the page when an
     input is focused (and it never zooms back out). Placed after the base
     rule so the cascade keeps this as the effective value. */
  .form-group input,
  .form-group textarea { font-size: 16px; }
  .form-submit {
    align-self: flex-start;
  }
  .form-submit .btn-primary {
    border-radius: var(--radius-control);
  }
  .form-whatsapp-row {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-top: 8px;
  }

  /* ============ FOOTER ============ */
  footer {
    background: var(--bg);
    border-top: 1px solid var(--line);
    padding: 28px 0 16px;
  }
  @media (min-width: 768px) { footer { padding: 32px 0 16px; } }
  .footer-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 20px;
    margin-bottom: 16px;
  }
  @media (min-width: 768px) { .footer-grid { grid-template-columns: 1fr 1fr; gap: 20px; } }
  @media (min-width: 1200px) { .footer-grid { grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 24px; margin-bottom: 20px; } } /* F7: 1024→1200 */
  .footer-brand-name {
    font-family: var(--ff-display);
    font-size: clamp(22px, 2vw, 28px);
    font-weight: 500;
    color: var(--ink);
    letter-spacing: -0.03em;
    margin-bottom: 6px;
  }
  .footer-brand-text {
    font-size: 12px;
    line-height: 1.4;
    color: var(--ink-mute);
    max-width: 320px;
  }
  .footer-col-label {
    font-family: var(--ff-mono);
    font-size: 9px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-subtle);
    margin-bottom: 6px;
    font-weight: 500;
  }
  .footer-list { list-style: none; display: flex; flex-direction: column; gap: 4px; }
  .footer-list a {
    font-size: 14px;
    color: var(--ink-mute);
    transition: color 0.2s;
  }
  .footer-list a:hover { color: var(--accent); }
  .footer-social {
    display: flex;
    gap: 12px;
    align-items: center;
    flex-wrap: wrap;
  }
  .footer-social a {
    width: 40px; height: 40px;
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--line-strong);
    transition: border-color 0.2s, color 0.2s;
    color: var(--ink);
  }
  .footer-social a:hover {
    border-color: var(--accent);
    color: var(--accent);
  }
  .footer-social a svg { width: 18px; height: 18px; }

  .footer-bottom {
    padding-top: 10px;
    border-top: 1px solid var(--line);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
  }
  @media (min-width: 768px) { .footer-bottom { padding-top: 10px; } }
  .footer-copy {
    font-family: var(--ff-mono);
    font-size: 11px;
    color: var(--ink-subtle);
    letter-spacing: 0.05em;
  }
  .footer-legal {
    display: flex;
    gap: 24px;
  }
  .footer-legal a {
    font-family: var(--ff-mono);
    font-size: 11px;
    color: var(--ink-subtle);
    letter-spacing: 0.05em;
    transition: color 0.2s;
  }
  .footer-legal a:hover { color: var(--accent); }

  /* ============ SIDEBAR NAV (shared across sidebar pages) ============ */
  /* Typography hierarchy:
     - parent:    display font, uppercase, folder-like headers
     - child:     body font, readable series links
     - grandchild: body font, slightly smaller subseries links
     - mono is reserved for micro-labels (header, view-all) only. */

  .sidebar-nav {
    /* B6: hoisted from six identical inline `style="position: sticky; top:
       100px;"` attributes on <aside class="sidebar-nav">. Rendering is
       unchanged: at <=767px the `@media` block further down this file already
       forces `position: relative !important` (author !important beat the
       inline attribute too), and above that breakpoint sticky applies as
       before. Four templates carried verbatim copies of that mobile rule;
       they have been deleted now that the declaration lives here. */
    position: sticky;
    top: 100px;
    padding: 18px 14px;
    background: var(--bg-soft);
    border: 1px solid var(--line);
    border-radius: 14px;
  }
  [data-theme="light"] .sidebar-nav {
    background: var(--bg-raised);
    box-shadow: 0 1px 3px rgba(0,0,0,0.04);
  }
  .sidebar-nav-header {
    font-family: var(--ff-mono);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 18px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--line);
  }
  .sidebar-nav-list {
    display: flex;
    flex-direction: column;
    gap: 14px;
  }

  /* Level 1 — category headers */
  .sidebar-nav-parent {
    display: flex;
    align-items: center;
    padding: 5px 10px;
    font-family: var(--ff-display);
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    line-height: 1.3;
    word-break: break-word;
    color: var(--ink);
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--line);
    border-radius: 8px;
    user-select: none;
    transition: background 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s;
  }
  .sidebar-nav-parent:hover,
  .sidebar-nav-parent.active {
    color: var(--accent);
    background: var(--accent-soft);
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-glow);
  }
  [data-theme="light"] .sidebar-nav-parent {
    background: rgba(0, 0, 0, 0.02);
    border-color: rgba(0, 0, 0, 0.06);
  }
  [data-theme="light"] .sidebar-nav-parent:hover,
  [data-theme="light"] .sidebar-nav-parent.active {
    background: var(--accent-soft);
    border-color: var(--accent);
  }

  /* Level 2 — series / sport links */
  .sidebar-nav-children {
    padding: 6px 0 2px 10px;
    display: flex;
    flex-direction: column;
    gap: 1px;
  }
  .sidebar-nav-child {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 10px 4px 22px;
    font-family: var(--ff-body);
    font-size: 0.94rem;
    font-weight: 500;
    line-height: 1.4;
    color: var(--ink-mute);
    text-decoration: none;
    border-radius: 6px;
    transition: color 0.2s, background 0.2s;
    position: relative;
  }
  .sidebar-nav-child::before {
    content: '';
    position: absolute;
    left: 8px;
    top: 50%;
    transform: translateY(-50%);
    width: 0;
    height: 55%;
    background: var(--accent);
    border-radius: 2px;
    transition: width 0.2s;
  }
  .sidebar-nav-child::after {
    content: '';
    width: 0;
    height: 1.5px;
    background: var(--ink-subtle);
    flex-shrink: 0;
    border-radius: 1px;
    transition: background 0.2s, width 0.2s;
  }
  .sidebar-nav-child:hover {
    color: var(--accent);
    background: rgba(255, 255, 255, 0.04);
  }
  [data-theme="light"] .sidebar-nav-child:hover {
    background: rgba(0, 0, 0, 0.03);
  }
  .sidebar-nav-child:hover::before,
  .sidebar-nav-child.active::before {
    width: 3px;
  }
  .sidebar-nav-child:hover::after,
  .sidebar-nav-child.active::after {
    background: var(--accent);
    width: 6px;
  }
  /* Toggle rows already have an arrow; skip the trailing dash */
  .sidebar-nav-child-toggle::after { display: none; }
  .sidebar-nav-child.active {
    color: var(--accent);
    font-weight: 600;
    background: rgba(255, 255, 255, 0.06);
  }
  [data-theme="light"] .sidebar-nav-child.active {
    background: rgba(0, 136, 255, 0.06);
    background: color-mix(in srgb, var(--accent), transparent 94%);
  }

  /* Level 3 — subseries links */
  .sidebar-nav-grandchildren {
    padding: 5px 0 5px 30px;
    display: none;
    position: relative;
  }
  .sidebar-nav-grandchildren::before {
    content: '';
    position: absolute;
    left: 16px;
    top: 6px;
    bottom: 6px;
    width: 1px;
    background: var(--line-strong);
    opacity: 0.5;
  }
  .sidebar-nav-grandchildren.open {
    display: flex;
    flex-direction: column;
    gap: 2px;
  }
  .sidebar-nav-grandchild {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 10px 4px 20px;
    font-family: var(--ff-body);
    font-size: 0.87rem;
    font-weight: 400;
    line-height: 1.35;
    color: var(--ink-mute);
    text-decoration: none;
    border-radius: 5px;
    transition: color 0.15s, background 0.15s;
    position: relative;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .sidebar-nav-grandchild::before {
    content: '';
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--ink-subtle);
    flex-shrink: 0;
    transition: background 0.15s, transform 0.15s;
  }
  .sidebar-nav-grandchild:hover {
    color: var(--accent);
    background: rgba(255, 255, 255, 0.04);
  }
  [data-theme="light"] .sidebar-nav-grandchild:hover {
    background: rgba(0, 0, 0, 0.03);
  }
  .sidebar-nav-grandchild:hover::before {
    background: var(--accent);
    transform: scale(1.4);
  }
  .sidebar-nav-grandchild.active {
    color: var(--accent);
    font-weight: 600;
    background: rgba(255, 255, 255, 0.06);
  }
  [data-theme="light"] .sidebar-nav-grandchild.active {
    background: rgba(0, 136, 255, 0.06);
    background: color-mix(in srgb, var(--accent), transparent 94%);
  }
  .sidebar-nav-grandchild.active::before {
    background: var(--accent);
  }

  /* Toggle-able series row (has subseries, e.g. M Series) */
  .sidebar-nav-child-toggle {
    cursor: pointer;
    user-select: none;
  }
  .sidebar-nav-child-toggle .sidebar-nav-child-label {
    flex: 1;
    min-width: 0;
    line-height: 1.3;
    word-break: break-word;
  }
  .sidebar-nav-toggle-arrow {
    flex-shrink: 0;
    font-family: var(--ff-mono);
    font-size: 0.8rem;
    color: var(--ink-subtle);
    transition: transform 0.2s ease, color 0.15s;
    transform: rotate(0deg);
    display: inline-block;
  }
  .sidebar-nav-child-toggle.open .sidebar-nav-toggle-arrow {
    transform: rotate(90deg);
    color: var(--accent);
  }
  .sidebar-nav-child-toggle:hover .sidebar-nav-toggle-arrow {
    color: var(--accent);
  }

  /* View-all link */
  .sidebar-nav-all {
    display: block;
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px solid var(--line);
    font-family: var(--ff-mono);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-mute);
    text-decoration: none;
    transition: color 0.2s;
  }
  .sidebar-nav-all:hover,
  .sidebar-nav-all.active {
    color: var(--accent);
  }

  /* Default (desktop) sidebar layout — two-column grid. The inline
     grid-template-columns on older templates is being phased out in
     favor of this CSS-driven approach (fixes 364px overflow on mobile
     where inline styles with high specificity defeated the media
     query !important override). */
  .sidebar-layout {
    display: grid;
    grid-template-columns: 270px 1fr;
    gap: 20px;
    align-items: start;
  }
  /* N-25（grid blowout 根本解）：grid item 的 min-width 默认 auto，会把所在
     轨道顶到内容的 min-content 宽度。产品详情页因此整页撑到 921px（390 视口
     仅可见 390），用户在手机端"只能看到很小的一部分"。
     元凶是 .detail-ordering-table(min-width:900px) 与 .detail-energy-table
     (th white-space:nowrap → 899px)；它们虽被 overflow-x:auto 容器包裹，
     但 min-width:auto 让 blowout 绕过容器一路传导到 html。
     min-width:0 作用在 grid item 上，不依赖轨道写法，**不会被模板内联的
     `1fr !important` 反杀**（N-21 的 minmax(0,1fr) 就被 10 处内联覆盖了）。 */
  .sidebar-layout > *,
  .about-story-grid > *,
  .contact-grid > * {
    min-width: 0;
  }


  @media (max-width: 767px) {
    /* N-21: 必须是 minmax(0, 1fr) 而不是 1fr。
       `1fr` 等价于 minmax(auto, 1fr)，其最小值取轨道内容的 min-content；
       .project-card 的 min-content 约 347px，在 320/360 档会把轨道顶到
       346.53px（容器仅 288/328px）→ 整页横向溢出 44px，被 body
       overflow-x:hidden 静默裁切（与 P0-1 同一失效模式）。
       minmax(0, 1fr) 允许轨道收缩到 0，是 grid blowout 的标准解法。 */
    .sidebar-layout {
      grid-template-columns: minmax(0, 1fr) !important;
    }
    .sidebar-nav {
      position: relative !important;
      top: auto !important;
    }
  }
  /* F7: 768–1199 平板档保持窄侧栏；≥1200 用桌面默认 270px。3 档：≤767 / 768–1199 / ≥1200 */
  @media (min-width: 768px) and (max-width: 1199px) {
    .products-page-with-sidebar .sidebar-layout {
      grid-template-columns: 260px 1fr !important;
    }
  }

  /* ============ SIDEBAR COLLAPSE (F4' — checkbox hack, D2/D3) ============ */
  /* Desktop/tablet: toggle hidden, tree always expanded. At the ≤767px
     (F7: 原 900 收敛) sidebar-layout single-column breakpoint the label
     appears and the tree collapses unless the box is checked. "Expanded"
     is the HTML default — collapsing is the enhancement, so no-JS users
     never lose the category navigation (§8.2). */
  .sidebar-toggle-input,
  .sidebar-toggle-label { display: none; }
  @media (max-width: 767px) {
    .sidebar-toggle-input {
      position: absolute;
      width: 1px;
      height: 1px;
      opacity: 0;
      pointer-events: none;
    }
    .sidebar-toggle-input:focus-visible ~ .sidebar-toggle-label {
      outline: 2px solid var(--accent);
      outline-offset: 2px;
    }
    .sidebar-toggle-label {
      display: flex;
      align-items: center;
      min-height: 44px;
      padding: 8px 0;
      cursor: pointer;
      font-family: var(--ff-mono);
      font-size: 12px;
      letter-spacing: 0.15em;
      text-transform: uppercase;
      color: var(--accent);
    }
    .sidebar-toggle-label::after {
      content: "";
      width: 8px;
      height: 8px;
      margin-left: auto;
      border-right: 2px solid currentColor;
      border-bottom: 2px solid currentColor;
      transform: rotate(45deg);
      transition: transform 0.2s;
    }
    .sidebar-toggle-input:checked ~ .sidebar-toggle-label::after {
      transform: rotate(225deg);
    }
    .sidebar-toggle-input:not(:checked) ~ .sidebar-nav { display: none; }
  }

  /* ============ TABLE HORIZONTAL-SCROLL HINT (N-16) ============ */
  /* 全局滑动提示：任意可横滑表格容器（如 .detail-ordering-table-wrap）在其上方
     放 <p class="scroll-hint"> 即有统一样式；display 由各页在 ≤767px 显形。 */
  .scroll-hint {
    display: none;
    margin: 10px 0 0;
    font-family: var(--ff-mono);
    font-size: 11px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-mute);
  }

  /* ============ REVEAL ============ */
  /* F11: 仅在有 JS 时（html.js 前缀）初始隐藏；无 JS 时这些规则不命中 → 内容默认可见（P1-9 根治） */
  html.js .reveal {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.9s ease, transform 0.9s ease;
  }
  html.js .reveal.is-visible {
    opacity: 1;
    transform: translateY(0);
  }
  @media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; } /* N-8: CSS side; JS anchor scrolling checks the same media query */
    html.js .reveal { opacity: 1; transform: none; transition: none; }
    .hero-field-lines::before,
    .hero-field-lines::after { animation: none; }
    /* N-24: kill the cross-fade only — the rotation itself must keep running */
    .hero-slide { transition: none; }
  }

  /* ============ MOBILE TYPOGRAPHY CLAMP (F5' / D1) ============ */
  /* Mobile-only re-derivation of the two public title vars. The admin value
     always stays the upper bound (min), and the fluid term keeps a rem base
     so the browser font-size setting is respected (WCAG 1.4.4). The desktop
     rendering path is untouched (plain aliases in :root above). */
  @media (max-width: 767px) {
    :root {
      --fs-hero-title:    min(var(--fs-hero-title-admin),    max(30px, calc(1rem + 4vw)));
      --fs-section-title: min(var(--fs-section-title-admin), max(22px, calc(0.85rem + 2.4vw)));
    }
  }

  /* ============ ABOUT PAGE ============ */
  .about-story-grid {
    display: grid;
    grid-template-columns: 1.35fr 1fr;
    gap: 64px;
    align-items: center;
  }
  @media (max-width: 767px) {
    .about-story-grid { grid-template-columns: 1fr; }
  }

  .section-accent-label {
    font-family: var(--ff-mono);
    font-size: 11px;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--accent);
    display: block;
    margin-bottom: 20px;
  }

  .section-accent-label--compact {
    margin-bottom: 12px;
  }

  .about-story-stats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 32px;
    max-width: 900px;
    margin: 48px auto 0;
  }
  @media (max-width: 767px) {
    .about-story-stats { grid-template-columns: repeat(2, 1fr); }
  }

  .about-stat-circle-wrap {
    text-align: center;
  }

  .about-stat-circle {
    width: 100px;
    height: 100px;
    margin: 0 auto 16px;
    border-radius: 50%;
    border: 2px solid var(--accent);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }

  .about-stat-circle-value {
    font-family: var(--ff-display);
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--accent);
    line-height: 1;
  }

  .about-stat-circle-unit {
    font-family: var(--ff-mono);
    font-size: 9px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-mute);
    margin-top: 4px;
  }

  .about-stat-circle-label {
    font-size: 0.85rem;
    color: var(--ink-mute);
  }

  .about-tech-header {
    text-align: center;
    max-width: 800px;
    margin: 0 auto 40px;
  }

  .about-tech-pillars {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 32px;
    max-width: 1100px;
    margin: 0 auto;
  }
  @media (max-width: 767px) {
    .about-tech-pillars { grid-template-columns: 1fr; }
  }

  .about-pillar {
    background: var(--bg-soft);
    border: 1px solid var(--line);
    border-radius: 16px;
    padding: 48px 40px;
    text-align: center;
    position: relative;
    overflow: hidden;
  }

  .about-pillar-accent {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--accent), var(--accent-deep));
  }

  .about-pillar-icon {
    max-height: 180px;
    max-width: 90%;
    object-fit: contain;
  }

  .about-optics-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
    max-width: 1100px;
    margin: 0 auto;
  }
  @media (max-width: 767px) {
    .about-optics-grid { grid-template-columns: 1fr; }
  }

  /* About page — converged from about.html inline <style> (N-13/F12, v1.6) */
  .about-services-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
    max-width: 1100px;
    margin: 0 auto;
  }
  @media (max-width: 767px) {
    .about-services-grid { grid-template-columns: 1fr; }
  }
  .about-pillar, .about-service-card, .about-optic-card {
    transition: transform 0.3s, box-shadow 0.3s, border-color 0.3s;
  }
  .about-service-card:hover {
    border-color: var(--accent);
    transform: translateY(-3px);
    box-shadow: 0 12px 32px -12px rgba(0, 136, 255, 0.15);
    box-shadow: 0 12px 32px -12px color-mix(in srgb, var(--accent), transparent 85%);
  }
  .about-pillar:hover {
    transform: translateY(-4px);
    box-shadow: 0 20px 40px -20px rgba(0, 136, 255, 0.2);
    box-shadow: 0 20px 40px -20px color-mix(in srgb, var(--accent), transparent 80%);
  }
  .about-optic-card:hover {
    border-color: var(--accent-glow);
    transform: translateY(-2px);
    box-shadow: 0 16px 36px -16px rgba(0, 136, 255, 0.15);
    box-shadow: 0 16px 36px -16px color-mix(in srgb, var(--accent), transparent 85%);
  }

  .about-simple-steps {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 32px;
  }
  @media (max-width: 767px) {
    .about-simple-steps { grid-template-columns: 1fr; }
  }