/* =========================================================
   zho-dual-realm / skin.css — Zhongli Weiye site skin
   ---------------------------------------------------------
   Source of truth: DESIGN.md (site root). Copy is automatic:
   build_all.py copies this file to public/skin.css every build.
   §2 tokens + §3 components are GLOBAL (reusable on inner pages
   that link this sheet). §4 homepage layout blocks are scoped
   under body.zho-home — inner pages must NEVER emit them.
   Motion: transform/opacity only; prefers-reduced-motion fully
   degrades (engine primer also nukes animation/transition).
   ========================================================= */

/* ---------- §2 Design tokens (GLOBAL) ---------- */
:root {
  --zho-dark:      #0E1B2A;
  --zho-dark-2:    #16283C;
  --zho-light:     #F7F8FA;
  --zho-paper:     #FFFFFF;
  --zho-ink:       #101418;
  --zho-ink-soft:  #33404D;
  --zho-muted:     #5B6B7A;
  --zho-action:    #F0B429;
  --zho-accent:    #1E5AA8;
  --zho-accent-br: #7FB2E8;
  --zho-on-dark:   #F2F5F8;
  --zho-on-dark-s: #B9C6D2;
  --zho-line:      #E2E7EC;
  --zho-line-dark: rgba(255,255,255,.14);
  --zho-danger:    #B4232A; /* error/required marks, light grounds only (DESIGN.md §1.1-a) */

  --zho-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --zho-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

  --zho-fs-display: clamp(2.5rem, 5.4vw, 4.25rem);
  --zho-fs-h2:      clamp(1.7rem, 3vw, 2.4rem);
  --zho-fs-h3:      clamp(1.15rem, 1.6vw, 1.35rem);
  --zho-fs-body:    1rem;
  --zho-fs-sm:      .9rem;
  --zho-fs-xs:      .78rem;

  --zho-s1: .5rem; --zho-s2: 1rem; --zho-s3: 1.75rem; --zho-s4: 3rem; --zho-s5: 4.5rem; --zho-s6: 6.5rem;
  --zho-r: 10px;
  --zho-r-lg: 16px;
  --zho-shadow: 0 10px 30px rgba(14,27,42,.10);

  --zho-container: 1180px;
  --zho-split-a: 55%;
  --zho-split-b: 45%;
  --zho-skew: 4deg;

  /* Engine bridge: colour the neutral engine accents with the brand blue. */
  --brand: var(--zho-accent);
}

/* ---------- §3 Global components (GLOBAL) ---------- */
.zho-eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  margin: 0 0 var(--zho-s2);
  font-family: var(--zho-sans);
  font-size: var(--zho-fs-xs); font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--zho-ink-soft);
}
.zho-eyebrow::before {
  content: ""; width: 18px; height: 3px; background: var(--zho-action);
}
.zho-eyebrow--on-dark { color: var(--zho-on-dark-s); }

.zho-cta-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 12px 22px;
  border-radius: var(--zho-r); border: 2px solid transparent;
  font-family: var(--zho-sans); font-weight: 700; font-size: var(--zho-fs-sm);
  line-height: 1; text-decoration: none; cursor: pointer;
  transition: transform .15s ease, opacity .15s ease;
}
.zho-cta-btn:hover { text-decoration: none; transform: translateY(-1px); }
.zho-cta-btn:active { transform: translateY(0); }
.zho-cta-btn__arrow { display: inline-flex; transition: transform .15s ease; }
.zho-cta-btn:hover .zho-cta-btn__arrow { transform: translateX(3px); }
.zho-cta-btn--primary { background: var(--zho-action); color: var(--zho-ink); }
.zho-cta-btn--primary:hover { opacity: .92; }
.zho-cta-btn--quiet { background: transparent; color: var(--zho-ink); border-color: var(--zho-ink-soft); }
.zho-cta-btn--quiet:hover { border-color: var(--zho-ink); }
.zho-cta-btn--onDark { background: transparent; color: var(--zho-on-dark); border-color: var(--zho-on-dark-s); }
.zho-cta-btn--onDark:hover { border-color: var(--zho-on-dark); }
.zho-cta-btn:focus-visible,
.zho-cta-btn:focus { outline: 3px solid var(--zho-action); outline-offset: 2px; }

.zho-numlabel {
  font-family: var(--zho-mono);
  font-size: var(--zho-fs-xs);
  letter-spacing: .06em;
  color: var(--zho-accent);
}
.zho-chipset {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin: var(--zho-s2) 0 0; padding: 0; list-style: none;
}
.zho-chipset__item {
  display: inline-flex; align-items: center;
  padding: 6px 12px; border-radius: 999px;
  border: 1px solid var(--zho-line);
  background: var(--zho-paper);
  font-size: var(--zho-fs-xs); font-weight: 600; color: var(--zho-ink-soft);
}
.zho-chipset--on-dark .zho-chipset__item {
  background: transparent; border-color: var(--zho-line-dark); color: var(--zho-on-dark-s);
}
.zho-rulebar {
  width: 64px; height: 3px; margin: var(--zho-s1) 0 var(--zho-s2);
  background: var(--zho-ink);
}
.zho-rulebar--dark { background: var(--zho-action); }
.zho-askbar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--zho-s2);
  margin-top: var(--zho-s4); padding: var(--zho-s2) var(--zho-s3);
  border: 1px solid var(--zho-line-dark); border-radius: var(--zho-r-lg);
  background: var(--zho-dark-2);
}
.zho-askbar--default { color: var(--zho-on-dark); }
.zho-askbar__text { margin: 0; max-width: 56ch; color: var(--zho-on-dark-s); font-size: var(--zho-fs-sm); }
.zho-docrow {
  font-family: var(--zho-mono); font-size: var(--zho-fs-sm);
  color: var(--zho-ink-soft); letter-spacing: .02em;
}

/* Reveal (html.js gated; reduced-motion degrades below) */
.zho-reveal { opacity: 1; transform: none; }
.js .zho-reveal { opacity: 0; transform: translateY(14px); transition: opacity .5s ease, transform .5s ease; }
.js .zho-reveal.is-in { opacity: 1; transform: none; }

/* ---------- §4 Homepage-only layout (body.zho-home scope) ---------- */

/* Transparent nav overlay on the dark hero (homepage only). */
.zho-home .site-header {
  position: absolute; top: 0; left: 0; right: 0; z-index: 100;
  background: rgba(14,27,42,.55);
  border-bottom: 1px solid var(--zho-line-dark);
  backdrop-filter: blur(6px);
}
.zho-home .site-header[data-elevate="true"] {
  border-color: var(--zho-line-dark);
  box-shadow: none;
}
.zho-home .site-header .brand,
.zho-home .site-header .brand:hover { color: var(--zho-on-dark); }
.zho-home .site-header .nav__list > li > a,
.zho-home .site-header .nav__has-menu > a { color: var(--zho-on-dark-s); }
.zho-home .site-header .nav__list > li > a:hover,
.zho-home .site-header .nav__has-menu > a:hover { color: var(--zho-on-dark); background: var(--zho-dark-2); }
.zho-home .site-header .lang-badge { border-color: var(--zho-line-dark); color: var(--zho-on-dark-s); }
.zho-home .site-header .nav-toggle { border-color: var(--zho-line-dark); }
.zho-home .site-header .nav-toggle span { background: var(--zho-on-dark); }
/* Ghost button (WhatsApp) in the transparent overlay: the engine base uses
   dark --ink, which fails contrast on the dark hero. Scoped lightening —
   the global .btn--ghost stays untouched (R14 scope isolation). The SVG icon
   and .whatsapp-link__text both inherit currentColor, so one rule fixes both. */
.zho-home .site-header .btn--ghost {
  color: var(--zho-on-dark);
  border-color: var(--zho-line-dark);
}
.zho-home .site-header .btn--ghost:hover,
.zho-home .site-header .btn--ghost:focus-visible {
  background: var(--zho-dark-2);
  color: var(--zho-on-dark);
}
/* Mobile nav (<=900px) opens as the engine's WHITE fixed panel — the lightened
   link colors above would render white-on-white there. Restore engine ink
   inside the panel; the transparent-glass treatment stays desktop-only. */
@media (max-width: 900px) {
  .zho-home .site-header .nav__list > li > a,
  .zho-home .site-header .nav__has-menu > a { color: var(--ink); background: none; }
  .zho-home .site-header .nav__list > li > a:hover,
  .zho-home .site-header .nav__has-menu > a:hover { color: var(--ink); background: var(--bg-soft); }
}
.zho-home .nav-toggle:focus-visible { outline: 3px solid var(--zho-action); outline-offset: 2px; }
.zho-home main { overflow-x: clip; }

/* ---- B1 zho-frontline (full-bleed photo hero on a 55/45 stage, user-adjudicated) ---- */
.zho-frontline {
  position: relative;
  display: flex; align-items: stretch;
  min-height: max(88svh, 640px);
  overflow: hidden;
  background: var(--zho-dark);
}
.zho-frontline__bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: 72% 42%;
}
/* Left-anchored navy scrim: near-solid through the 55% realm so the white h1
   holds WCAG AA, then eases so the right 45% keeps a clearly readable photo
   presence behind the product card (user defect 1: right side must show an
   identifiable image element). */
.zho-frontline__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(92deg,
      rgba(14, 27, 42, .95) 0%,
      rgba(14, 27, 42, .90) 40%,
      rgba(14, 27, 42, .68) 55%,
      rgba(14, 27, 42, .32) 80%,
      rgba(14, 27, 42, .18) 100%),
    linear-gradient(0deg,
      rgba(14, 27, 42, .58) 0%,
      rgba(14, 27, 42, 0) 34%);
}
/* O-board signature: 4-degree action-colour divider riding the 55/45 boundary
   (skewed pseudo-element of the stage so it tracks the grid, not the viewport). */
.zho-frontline__stage::after {
  content: "";
  position: absolute; top: -4%; bottom: -4%; left: calc(55% - 5px);
  width: 10px; z-index: 1;
  background: var(--zho-action);
  transform: skewX(calc(-1 * var(--zho-skew)));
}
.zho-frontline__stage {
  position: relative; z-index: 2;
  display: grid; grid-template-columns: var(--zho-split-a) var(--zho-split-b);
  align-items: center;
  width: 100%;
}
/* Left 55% realm: copy anchored hard-left (user defect 2 — no centering). */
.zho-frontline__copy {
  max-width: 640px;
  padding: calc(68px + var(--zho-s4)) 0 var(--zho-s4);
  padding-right: var(--zho-s3);
}
/* Right 45% realm: a REAL product card (client-supplied RIELLO photo, not AI)
   floating over the photo — the asymmetric two-entity structure restored.
   W5a fix (user defect: the card read as a paper sheet stuck onto the flame
   photo): a soft dark "pocket" behind the card grounds it inside the photo,
   and the card gains a 1px light rim + dual-layer shadow so the flame light
   defines its edges. VISUAL-ONLY — no layout/grid/structure change (Gate B
   scope: this component's surface treatment, DESIGN.md §1.1-d). */
.zho-frontline__aside {
  position: relative;
  display: flex; justify-content: flex-end;
  padding: calc(68px + var(--zho-s4)) 0 var(--zho-s4);
  padding-left: var(--zho-s3);
}
.zho-frontline__aside::before {
  content: "";
  position: absolute; inset: -6% -14%;
  background: radial-gradient(ellipse 72% 62% at 60% 46%,
    rgba(6, 13, 22, .44) 0%, rgba(6, 13, 22, .22) 45%, rgba(6, 13, 22, 0) 72%);
}
.zho-frontline__card {
  position: relative; z-index: 1;
  margin: 0; width: min(420px, 100%);
  background: var(--zho-paper);
  border-radius: var(--zho-r-lg);
  overflow: hidden;
  box-shadow:
    0 36px 80px rgba(4, 10, 18, .50),
    0 10px 24px rgba(4, 10, 18, .38),
    0 0 0 1px rgba(255, 255, 255, .14);
}
/* Top-edge light catch: simulates the card's top rim picking up flame light. */
.zho-frontline__card::after {
  content: "";
  position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45);
}
.zho-frontline__card img { display: block; width: 100%; height: auto; }
/* Caption: dark mono readout strip (B2/E-gene language) instead of a second
   white sheet — the card's lower half now eases into the photo's dark register
   while the action-colour rule keeps the brand signature. Text #B9C6D2 on the
   near-#0E1B2A strip holds 8.9:1 (DESIGN.md §8). */
.zho-frontline__cardcap {
  padding: 10px 14px;
  border-top: 3px solid var(--zho-action);
  background: rgba(14, 27, 42, .92);
  font-family: var(--zho-mono); font-size: var(--zho-fs-xs);
  letter-spacing: .04em; color: var(--zho-on-dark-s);
}
.zho-frontline__title {
  margin: 0 0 var(--zho-s2);
  font-family: var(--zho-sans);
  font-size: var(--zho-fs-display); line-height: 1.06; letter-spacing: -.02em;
  font-weight: 800; color: var(--zho-on-dark);
  text-wrap: balance;
}
.zho-frontline__sub {
  margin: 0 0 var(--zho-s3); max-width: 52ch;
  font-size: clamp(1.05rem, 1.4vw, 1.2rem); line-height: 1.55;
  color: var(--zho-on-dark-s);
}
.zho-frontline__ctas { display: flex; flex-wrap: wrap; gap: 12px; }
.zho-frontline__finder { margin-top: var(--zho-s3); max-width: 460px; }
.zho-frontline__finder-label {
  display: block; margin-bottom: 6px;
  font-size: var(--zho-fs-xs); font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--zho-on-dark-s);
}
.zho-frontline__finder-row { display: flex; gap: 8px; }
.zho-frontline__finder-row select {
  flex: 1; min-height: 48px; padding: 0 12px;
  border: 1px solid var(--zho-line-dark); border-radius: var(--zho-r);
  background: var(--zho-dark-2); color: var(--zho-on-dark);
  font: inherit; font-size: var(--zho-fs-sm);
}
.zho-frontline__credit {
  margin: var(--zho-s2) 0 0;
  font-family: var(--zho-mono); font-size: var(--zho-fs-xs);
  letter-spacing: .04em; color: var(--zho-on-dark-s); opacity: .66;
}

/* ---- B2 zho-dualline ---- */
.zho-dualline {
  position: relative;
  display: grid; grid-template-columns: var(--zho-split-a) var(--zho-split-b);
  background: var(--zho-light);
}
.zho-dualline__dark {
  background: linear-gradient(180deg, var(--zho-dark) 0%, var(--zho-dark-2) 100%);
  padding: var(--zho-s5) 0;
  clip-path: polygon(0 0, 100% 0, calc(100% - 3.5%) 100%, 0 100%);
  padding-right: 4%;
}
.zho-dualline__darktitle, .zho-dualline__lighttitle {
  margin: 0 0 var(--zho-s2);
  font-size: var(--zho-fs-h2); line-height: 1.15; letter-spacing: -.01em;
  color: var(--zho-on-dark); font-weight: 800;
}
.zho-dualline__fuelgrid {
  display: grid; grid-template-columns: 1fr; gap: 12px;
  margin: 0 0 var(--zho-s3);
}
.zho-dualline__fuelcard {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 18px; border-radius: var(--zho-r-lg);
  border: 1px solid var(--zho-line-dark); background: var(--zho-dark-2);
  text-decoration: none;
  transition: transform .15s ease, opacity .15s ease;
}
.zho-dualline__fuelcard:hover { transform: translateY(-4px); text-decoration: none; }
.zho-dualline__fuelcard:focus-visible { outline: 3px solid var(--zho-action); outline-offset: 2px; }
.zho-dualline__fuelchip {
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  padding: 6px 10px; border-radius: 6px;
  background: rgba(240,180,41,.14); color: var(--zho-action);
  font-family: var(--zho-mono); font-size: var(--zho-fs-xs); font-weight: 700; letter-spacing: .08em;
}
.zho-dualline__fuelbody { display: grid; gap: 4px; }
.zho-dualline__fueltitle { font-weight: 700; color: var(--zho-on-dark); font-size: var(--zho-fs-h3); }
.zho-dualline__fueldesc { color: var(--zho-on-dark-s); font-size: var(--zho-fs-sm); line-height: 1.5; }
.zho-dualline__fuelbody .zho-numlabel { color: var(--zho-accent-br); }
.zho-dualline__fuelarrow { margin-left: auto; color: var(--zho-action); display: inline-flex; }
.zho-dualline__light { padding: var(--zho-s5) 0; }
.zho-dualline__lighttitle { color: var(--zho-ink); }
.zho-dualline__lighttitle .zho-numlabel, .zho-dualline__lightintro .zho-numlabel { color: var(--zho-accent); }
.zho-dualline__lightintro { margin: 0 0 var(--zho-s3); color: var(--zho-ink-soft); max-width: 44ch; }
.zho-dualline__rows { list-style: none; margin: 0 0 var(--zho-s3); padding: 0; }
.zho-dualline__row {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 10px; border-radius: 8px;
  border-bottom: 1px solid var(--zho-line);
  text-decoration: none;
  transition: transform .15s ease, opacity .15s ease;
}
.zho-dualline__row:hover { text-decoration: none; transform: translateX(3px); }
.zho-dualline__row:focus-visible { outline: 3px solid var(--zho-accent); outline-offset: 2px; }
.zho-dualline__row .zho-numlabel { color: var(--zho-accent); min-width: 3.2em; }
.zho-dualline__rowlabel { color: var(--zho-ink); font-weight: 600; font-size: var(--zho-fs-sm); }
.zho-dualline__rowarrow { margin-left: auto; color: var(--zho-muted); display: inline-flex; }

/* ---- B3 zho-brandgrid ---- */
.zho-brandgrid { background: var(--zho-light); padding: var(--zho-s5) 0; }
.zho-brandgrid__title {
  margin: 0; font-size: var(--zho-fs-h2); font-weight: 800;
  letter-spacing: -.01em; color: var(--zho-ink);
}
.zho-brandgrid__intro { max-width: 62ch; margin: 0 0 var(--zho-s3); color: var(--zho-ink-soft); }
.zho-brandgrid__grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px;
}
.zho-brandgrid__card {
  display: flex; flex-direction: column;
  background: var(--zho-paper); border: 1px solid var(--zho-line);
  border-radius: var(--zho-r-lg); overflow: hidden; text-decoration: none;
  transition: transform .15s ease, opacity .15s ease;
}
.zho-brandgrid__card:hover { transform: translateY(-4px); box-shadow: var(--zho-shadow); text-decoration: none; }
.zho-brandgrid__card:focus-visible { outline: 3px solid var(--zho-accent); outline-offset: 2px; }
.zho-brandgrid__media { background: var(--zho-paper); }
.zho-brandgrid__media img { width: 100%; height: auto; display: block; }
.zho-brandgrid__body {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 14px 16px; border-top: 1px solid var(--zho-line);
}
.zho-brandgrid__brand { font-weight: 800; letter-spacing: .02em; color: var(--zho-ink); }
.zho-brandgrid__label {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--zho-fs-xs); text-transform: uppercase; letter-spacing: .08em;
  color: var(--zho-muted);
}
.zho-brandgrid__arrow { display: inline-flex; color: var(--zho-accent); }
.zho-brandgrid__footnote {
  margin: var(--zho-s3) 0 0; padding-top: var(--zho-s2);
  border-top: 2px solid var(--zho-ink);
  font-size: var(--zho-fs-sm); color: var(--zho-ink-soft); max-width: 78ch;
}

/* ---- B4 zho-aboutvault ---- */
.zho-aboutvault { background: var(--zho-paper); padding: var(--zho-s5) 0; }
.zho-aboutvault__grid {
  display: grid; grid-template-columns: 7fr 5fr; gap: var(--zho-s4);
  align-items: start;
}
.zho-aboutvault__title {
  margin: 0 0 var(--zho-s2); font-size: var(--zho-fs-h2);
  font-weight: 800; letter-spacing: -.01em; color: var(--zho-ink);
}
.zho-aboutvault__body { margin: 0; color: var(--zho-ink-soft); line-height: 1.65; max-width: 60ch; }
.zho-aboutvault__numbers {
  display: grid; grid-template-columns: repeat(4, auto); gap: var(--zho-s3);
  margin-top: var(--zho-s3); padding-top: var(--zho-s2);
  border-top: 2px solid var(--zho-ink);
}
.zho-aboutvault__num { display: grid; gap: 2px; }
.zho-aboutvault__numval {
  font-family: var(--zho-mono); font-weight: 700;
  font-size: clamp(1.6rem, 2.6vw, 2.2rem); color: var(--zho-ink); line-height: 1;
}
.zho-aboutvault__numval::after { content: ""; display: block; width: 22px; height: 3px; margin-top: 6px; background: var(--zho-action); }
.zho-aboutvault__numlabel { font-size: var(--zho-fs-xs); color: var(--zho-muted); text-transform: uppercase; letter-spacing: .06em; }
.zho-aboutvault__vault { position: relative; }
.zho-aboutvault__stampcard {
  position: relative;
  background: var(--zho-light); border: 1px solid var(--zho-line);
  border-top: 4px solid var(--zho-ink);
  border-radius: var(--zho-r); padding: var(--zho-s3);
}
.zho-aboutvault__stamp {
  position: absolute; top: 18px; right: 18px;
  padding: 8px 14px; border: 2px solid var(--zho-accent); border-radius: 6px;
  transform: rotate(4deg);
  color: var(--zho-accent); font-family: var(--zho-mono);
  font-size: var(--zho-fs-xs); font-weight: 700; letter-spacing: .18em;
}
.zho-aboutvault__stamptitle { margin: 0 0 var(--zho-s2); font-size: var(--zho-fs-h3); color: var(--zho-ink); }
.zho-aboutvault__stamplines { list-style: none; margin: 0 0 var(--zho-s2); padding: 0; display: grid; gap: 6px; }
.zho-aboutvault__serial { color: var(--zho-ink); font-weight: 700; }
.zho-aboutvault__stamplink {
  display: inline-flex; align-items: center; gap: 6px; margin-top: var(--zho-s2);
  color: var(--zho-accent); font-weight: 700; font-size: var(--zho-fs-sm); text-decoration: none;
}
.zho-aboutvault__stamplink:hover { text-decoration: underline; }
.zho-aboutvault__stamplink:focus-visible { outline: 3px solid var(--zho-accent); outline-offset: 2px; }

/* ---- B5 zho-industrystack ---- */
.zho-industrystack { background: var(--zho-light); padding: var(--zho-s5) 0; }
.zho-industrystack__title {
  margin: 0; font-size: var(--zho-fs-h2); font-weight: 800; color: var(--zho-ink);
}
.zho-industrystack__intro { max-width: 62ch; margin: 0 0 var(--zho-s3); color: var(--zho-ink-soft); }
.zho-industrystack__grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px;
}
.zho-industrystack__card {
  position: relative;
  display: flex; flex-direction: column; gap: 6px;
  padding: var(--zho-s2) var(--zho-s2) calc(var(--zho-s2) + 14px);
  background: var(--zho-paper); border: 1px solid var(--zho-line);
  border-radius: var(--zho-r-lg); text-decoration: none;
  /* 视差深度：GSAP 只写 --zho-py 变量，transform 由 CSS 合成（§13.3）；
     transition 摘掉 transform——scrub 逐帧写变量时 transform 过渡会拖影 */
  transform: translateY(var(--zho-py, 0px));
  transition: opacity .15s ease, box-shadow .2s ease;
}
.zho-industrystack__card:hover { transform: translateY(calc(var(--zho-py, 0px) - 4px)); box-shadow: var(--zho-shadow); text-decoration: none; }
.zho-industrystack__card:focus-visible { outline: 3px solid var(--zho-accent); outline-offset: 2px; }
.zho-industrystack__card--featured { grid-column: span 2; background: var(--zho-paper); border-top: 4px solid var(--zho-ink); }
.zho-industrystack__num { color: var(--zho-accent); }
.zho-industrystack__cardtitle { font-weight: 800; color: var(--zho-ink); font-size: var(--zho-fs-h3); }
.zho-industrystack__carddesc { color: var(--zho-ink-soft); font-size: var(--zho-fs-sm); line-height: 1.5; }
.zho-industrystack__cardarrow { position: absolute; bottom: 14px; right: 16px; color: var(--zho-accent); display: inline-flex; }

/* ---- B6 zho-proofcase ---- */
.zho-proofcase {
  position: relative;
  background: linear-gradient(160deg, var(--zho-dark) 0%, #0A1420 100%);
  padding: var(--zho-s5) 0;
  clip-path: polygon(0 3.5%, 100% 0, 100% 100%, 0 100%);
  margin-top: -2.5%;
  padding-top: calc(var(--zho-s5) + 3%);
}
.zho-proofcase__title {
  margin: 0 0 var(--zho-s3); font-size: var(--zho-fs-h2); font-weight: 800; color: var(--zho-on-dark);
}
.zho-proofcase__cards { display: grid; gap: 18px; max-width: 880px; }
.zho-proofcase__card {
  background: var(--zho-dark-2); border: 1px solid var(--zho-line-dark);
  border-left: 4px solid var(--zho-action);
  border-radius: var(--zho-r-lg); padding: var(--zho-s3);
  transform: translateY(var(--zho-py, 0px)); /* 视差深度，GSAP 写变量（§13.3） */
}
.zho-proofcase__client {
  margin: 0 0 6px; font-family: var(--zho-mono); font-size: var(--zho-fs-xs);
  letter-spacing: .06em; color: var(--zho-on-dark-s);
}
.zho-proofcase__casetitle { margin: 0 0 8px; font-size: var(--zho-fs-h3); color: var(--zho-on-dark); }
.zho-proofcase__casedesc { margin: 0; color: var(--zho-on-dark-s); font-size: var(--zho-fs-sm); line-height: 1.6; }
.zho-proofcase__num { display: flex; align-items: baseline; gap: 10px; margin: var(--zho-s2) 0 0; }
.zho-proofcase__numval {
  font-family: var(--zho-mono); font-weight: 700;
  font-size: clamp(1.8rem, 3vw, 2.6rem); color: var(--zho-action); line-height: 1;
}
.zho-proofcase__numlabel { font-size: var(--zho-fs-xs); text-transform: uppercase; letter-spacing: .08em; color: var(--zho-on-dark-s); }
/* Clickable case cards (link to /cases/<slug>.html) + view-all link */
.zho-proofcase__card--link {
  cursor: pointer; text-decoration: none; color: inherit;
  transition: transform .2s ease, border-color .2s ease;
}
.zho-proofcase__card--link:hover { transform: translateY(-3px); border-color: var(--zho-action); }
.zho-proofcase__viewall {
  display: inline-flex; align-items: center; gap: 8px;
  margin-top: 28px; font-weight: 700; color: var(--zho-on-dark); text-decoration: none;
}
.zho-proofcase__viewall:hover { color: var(--zho-action); }
.zho-proofcase__viewall svg { width: 14px; height: 14px; }

/* ---- B7 zho-whypanel ---- */
.zho-whypanel { background: var(--zho-dark-2); padding: var(--zho-s5) 0; }
.zho-whypanel__title {
  margin: 0; font-size: var(--zho-fs-h2); font-weight: 800; color: var(--zho-on-dark);
}
.zho-whypanel__grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--zho-s4);
}
.zho-whypanel__pillar {
  display: flex; gap: 14px; align-items: flex-start;
  padding: var(--zho-s2) 0;
  border-bottom: 2px solid var(--zho-line-dark);
}
.zho-whypanel__code { color: var(--zho-action); min-width: 3.4em; }
.zho-whypanel__pillartitle { margin: 0 0 4px; font-size: var(--zho-fs-h3); color: var(--zho-on-dark); }
.zho-whypanel__pillardesc { margin: 0; color: var(--zho-on-dark-s); font-size: var(--zho-fs-sm); line-height: 1.6; }

/* ---- B8 zho-closecta ---- */
.zho-closecta {
  background: linear-gradient(180deg, var(--zho-dark-2) 0%, var(--zho-dark) 60%, #0A1420 100%);
  padding: var(--zho-s6) 0;
  text-align: center;
}
.zho-closecta__inner { max-width: 720px; }
.zho-closecta__title {
  margin: 0 0 var(--zho-s2); font-size: var(--zho-fs-h2); font-weight: 800; color: var(--zho-on-dark);
}
.zho-closecta__text { margin: 0 auto var(--zho-s3); max-width: 52ch; color: var(--zho-on-dark-s); }
.zho-closecta__btn { min-width: 220px; }
.zho-closecta__contact {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 14px;
  margin: var(--zho-s3) 0 0; font-size: var(--zho-fs-sm); color: var(--zho-on-dark-s);
}
.zho-closecta__dot { color: var(--zho-action); }

/* ---- §4 sub-elements completed (audit_css_coverage layer-1 closure) ---- */
.zho-rulebar--light { background: var(--zho-ink); opacity: .18; }
.zho-aboutvault__about { max-width: 60ch; }
.zho-aboutvault__about p { color: var(--zho-ink-soft); }
.zho-whypanel__pillarbody { min-width: 0; }
.zho-closecta__item { white-space: nowrap; }

/* ---------- §7 Responsive (mobile-first overrides) ---------- */
@media (max-width: 960px) {
  .zho-dualline { grid-template-columns: 1fr; }
  /* Hero collapses to a single column: copy on top, product card centered
     below; the 180-deg scrim keeps text contrast over the full photo. */
  .zho-frontline__stage { grid-template-columns: 1fr; }
  .zho-frontline__stage::after { display: none; }
  .zho-frontline__copy { max-width: 100%; padding: calc(68px + var(--zho-s3)) 0 var(--zho-s4); }
  .zho-frontline__aside { justify-content: center; padding: 0 0 var(--zho-s4); }
  .zho-frontline__card { width: min(360px, 100%); }
  .zho-frontline__scrim {
    background:
      linear-gradient(180deg,
        rgba(14, 27, 42, .82) 0%,
        rgba(14, 27, 42, .9) 100%);
  }
  .zho-dualline__dark {
    clip-path: polygon(0 0, 100% 0, 100% calc(100% - 2.5%), 0 100%);
    padding-right: 0; padding-bottom: calc(var(--zho-s5) + 3%);
  }
  .zho-dualline__light { padding-top: calc(var(--zho-s4) + 3%); margin-top: -2%; }
  .zho-aboutvault__grid { grid-template-columns: 1fr; }
  .zho-industrystack__grid { grid-template-columns: repeat(2, 1fr); }
  .zho-brandgrid__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
  .zho-brandgrid__grid, .zho-industrystack__grid, .zho-whypanel__grid { grid-template-columns: 1fr; }
  .zho-aboutvault__numbers { grid-template-columns: repeat(2, 1fr); gap: var(--zho-s2) var(--zho-s3); }
  .zho-frontline__ctas .zho-cta-btn { flex: 1 1 100%; }
  .zho-industrystack__card--featured { grid-column: span 1; }
}

/* ---------- §4.9 flame band — P0 shader pilot (data/motion-3d.json driven) --
   Motif: burner port row (industry physics, never abstract particles).
   JS stays dormant under reduced-motion / no-WebGL2 / low-end device; the
   gradient below is the static fallback in all three cases, so the block
   never looks broken when the shader is skipped. */
body.zho-home .zho-whypanel { position: relative; overflow: hidden; }
body.zho-home .zho-whypanel > .container { position: relative; z-index: 1; }
body.zho-home .zho-flameband {
  position: absolute; left: 0; right: 0; bottom: 0; height: 62%;
  z-index: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(240,180,41,.18) 0%, rgba(240,180,41,.07) 38%, rgba(240,180,41,0) 100%);
  -webkit-mask-image: linear-gradient(to top, #000 0%, #000 28%, transparent 100%);
  mask-image: linear-gradient(to top, #000 0%, #000 28%, transparent 100%);
}
body.zho-home .zho-flameband__canvas {
  display: block; width: 100%; height: 100%;
  opacity: 0; transition: opacity .6s ease;
}
body.zho-home .zho-flameband[data-flame-state="live"] .zho-flameband__canvas { opacity: 1; }

/* ---------- §4.10 Whole-page atmospheric scroll system (motion-only, VISUAL scope) ----------
   A cohesive "Dual Realm" scroll atmosphere WITHOUT touching layout/grid/tokens:
   (1) fixed amber scroll-progress rail; (2) hero cinematic parallax + Ken Burns
   driven by --zho-hero; (3) a drifting ember glow shared across the dark realms
   driven by --zho-scroll; (4) an upgraded .zho-reveal entrance. transform/opacity
   only; all layers freeze under prefers-reduced-motion (§7 guard). home.py sets
   the two CSS vars from a single rAF scroll handler — no extra network, no layout
   thrash (will-change scopes the composited layers). */
body.zho-home .zho-scrollrail {
  position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 200;
  pointer-events: none; background: transparent;
}
body.zho-home .zho-scrollrail__fill {
  display: block; height: 100%; width: 100%;
  transform: scaleX(var(--zho-scroll, 0)); transform-origin: left center;
  background: linear-gradient(90deg, var(--zho-accent), var(--zho-action));
  box-shadow: 0 0 14px rgba(240, 180, 41, .55);
}

/* (2) Hero cinematic depth — TWO stacked layers:
     · __bgwrap : scroll parallax (zoom 1→1.22 + drift driven by --zho-hero,
       completing over the first 65% of the hero's scroll range — home.py JS)
     · __bg img : continuous slow Ken Burns zoom (26s alternate) so the hero
       is visibly alive even before any scrolling.
     translate magnitude == scale-extra/2 (center origin) so the bottom edge
     stays flush (no gap reveal) at every progress value; overflow:hidden on
     .zho-frontline clips the top. */
body.zho-home .zho-frontline__bgwrap {
  position: absolute; inset: 0;
  transform: translate3d(0, calc(var(--zho-hero, 0) * -11%), 0)
             scale(calc(1 + var(--zho-hero, 0) * .22));
  transform-origin: 50% 50%;
  will-change: transform;
}
body.zho-home .zho-frontline__bg {
  animation: zho-kenburns 26s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes zho-kenburns {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.09) translate3d(0, -1.4%, 0); }
}
/* scrim breathes out slightly as the hero exits — cinematic dim (opacity only) */
body.zho-home .zho-frontline__scrim { opacity: calc(1 - var(--zho-hero, 0) * .18); }
/* amber ember bloom rising from the hero base — depth cue as you scroll */
body.zho-home .zho-frontline::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 46%;
  z-index: 1; pointer-events: none;
  background: radial-gradient(120% 80% at 50% 120%,
    rgba(240, 180, 41, .16) 0%, rgba(240, 180, 41, .05) 40%, rgba(240, 180, 41, 0) 72%);
  -webkit-mask-image: linear-gradient(to top, #000, transparent);
  mask-image: linear-gradient(to top, #000, transparent);
}

/* (3) Drifting ember glow shared across the dark realms — ties the page together */
body.zho-home .zho-dualline__dark,
body.zho-home .zho-proofcase,
body.zho-home .zho-whypanel,
body.zho-home .zho-closecta { position: relative; overflow: hidden; }
body.zho-home .zho-dualline__dark::before,
body.zho-home .zho-proofcase::before,
body.zho-home .zho-whypanel::before,
body.zho-home .zho-closecta::before {
  content: ""; position: absolute; inset: -25% -15%; z-index: 0; pointer-events: none;
  background:
    radial-gradient(38% 30% at 18% 28%,
      rgba(240, 180, 41, .10), rgba(240, 180, 41, 0) 70%),
    radial-gradient(46% 40% at 84% 82%,
      rgba(30, 90, 168, .14), rgba(30, 90, 168, 0) 72%);
  transform: translate3d(0, calc((var(--zho-scroll, 0) - .5) * 90px), 0);
  will-change: transform;
}
/* lift real content above the ambient layer (whypanel container already lifted for §4.9) */
body.zho-home .zho-dualline__dark > .container,
body.zho-home .zho-proofcase > .container,
body.zho-home .zho-closecta > .container { position: relative; z-index: 1; }

/* (5) Scroll-driven assembly — B2 "Dual Realm" panels slide TOGETHER as the
   section enters the viewport (hero -> dualline transition): dark panel in
   from the left, light panel in from the right, an amber "weld seam" draws
   across the top, and copy rises into place on top of the assembled panels.
   Driven by --zho-assemble (0..1, set by home.py JS on [data-assemble]);
   default 1 so no-JS / pre-JS / reduced-motion all render the final state. */
body.zho-home [data-assemble] { --zho-assemble: 1; }
body.zho-home .zho-dualline__dark {
  transform: translate3d(calc((1 - var(--zho-assemble, 1)) * -7%), calc((1 - var(--zho-assemble, 1)) * 44px), 0);
  opacity: calc(.25 + .75 * var(--zho-assemble, 1));
  will-change: transform, opacity;
}
body.zho-home .zho-dualline__light {
  transform: translate3d(calc((1 - var(--zho-assemble, 1)) * 7%), calc((1 - var(--zho-assemble, 1)) * 44px), 0);
  opacity: calc(.25 + .75 * var(--zho-assemble, 1));
  will-change: transform, opacity;
}
/* weld seam: draws left-to-right as the two panels meet */
body.zho-home .zho-dualline::after {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  z-index: 2; pointer-events: none;
  background: linear-gradient(90deg, var(--zho-accent), var(--zho-action));
  transform: scaleX(var(--zho-assemble, 1)); transform-origin: left center;
}
/* copy arrives after the panels: rises the remaining distance */
body.zho-home .zho-dualline__dark > .container,
body.zho-home .zho-dualline__light > .container {
  transform: translate3d(0, calc((1 - var(--zho-assemble, 1)) * 30px), 0);
  opacity: var(--zho-assemble, 1);
}

/* (4) Upgraded reveal entrance — longer, eased, slightly deeper (stagger kept by JS) */
.js .zho-reveal {
  opacity: 0; transform: translateY(26px);
  transition: opacity .7s cubic-bezier(.2, .7, .2, 1),
              transform .7s cubic-bezier(.2, .7, .2, 1);
}
.js .zho-reveal.is-in { opacity: 1; transform: none; }

/* ---------- §7 Reduced motion safety (freeze-out guard) ---------- */
@media (prefers-reduced-motion: reduce) {
  .js .zho-reveal { opacity: 1; transform: none; transition: none; }
  body.zho-home .zho-flameband__canvas { opacity: 0; transition: none; }
  body.zho-home .zho-scrollrail { display: none; }
  body.zho-home .zho-frontline__bgwrap { transform: none; }
  body.zho-home .zho-frontline__bg { animation: none; }
  body.zho-home .zho-frontline__scrim { opacity: 1; }
  body.zho-home .zho-frontline::after { display: none; }
  body.zho-home .zho-dualline__dark::before,
  body.zho-home .zho-proofcase::before,
  body.zho-home .zho-whypanel::before,
  body.zho-home .zho-closecta::before { transform: none; opacity: .5; }
  body.zho-home .zho-dualline__dark,
  body.zho-home .zho-dualline__light,
  body.zho-home .zho-dualline__dark > .container,
  body.zho-home .zho-dualline__light > .container { transform: none; opacity: 1; }
  body.zho-home .zho-dualline::after { transform: none; }
}

/* =========================================================
   §12 GSAP motion pass (2026-09-09, data/motion.json + /js/motion.js)
   GSAP 接管 reveal 编排时由 motion.js 给 <html> 加 .zho-gsap：
   - 杀掉 CSS transition（避免与 GSAP 逐帧写入打架）
   - 初始隐藏态仍由 .js .zho-reveal 提供（无 JS / GSAP 缺载时原样可见）
   v5.1（2026-09-09 逐屏验收）：
   - reveal 类默认直出终态（opacity/transform 不再由类预藏）——GSAP 用
     内联样式接管全部隐藏；异常兜底时即使 clearProps 失败内容也可见（N-4）；
   - A1 CTA 的组件级 transition 必须在 zho-gsap 下关闭：.from() 初始化
     需读计算样式作终值，与 transition: transform/opacity 并发会随机抛
     GSAP 内部异常或把 tween 冻在 from 态（浏览器实测：CTA 随机隐身）。
   ========================================================= */
html.zho-gsap .zho-reveal { transition: none; opacity: 1; transform: none; }
html.zho-gsap .zho-frontline__ctas .zho-cta-btn { transition: none; }
@media (prefers-reduced-motion: reduce) {
  html.zho-gsap .zho-reveal { opacity: 1; transform: none; }
}

/* =========================================================
   §13 点火母题装饰元素（2026-09-09，motion.js A1/D1 专用）
   纯装饰 aria-hidden，不参与布局（absolute + pointer-events none）
   ========================================================= */
.zho-frontline__copy { position: relative; } /* 点火线定位上下文（原为 static） */
.zho-ignite-line {
  position: absolute; top: 0; left: 0;
  width: 140px; height: 2px; border-radius: 1px; /* 宽度由 JS 锚定眉题，140px 读作电极而非分隔线 */
  background: linear-gradient(90deg,
    rgba(240,180,41,0) 0%, var(--zho-action, #F0B429) 6%,
    var(--zho-action, #F0B429) 94%, rgba(240,180,41,0) 100%);
  box-shadow: 0 0 18px rgba(240, 180, 41, .75), 0 0 4px rgba(255, 217, 138, .9);
  pointer-events: none;
}
.zho-ignite-rail {
  position: absolute; left: 50%; top: 3%; bottom: 3%;
  width: 2px; margin-left: -1px;
  transform-origin: top center;
  background: linear-gradient(180deg,
    rgba(240,180,41,0) 0%, #F0B429 10%, #F0B429 46%,
    #B45309 54%, #B45309 90%, rgba(180,83,9,0) 100%);
  opacity: .9; z-index: 2; pointer-events: none;
}
@media (max-width: 960px) {
  /* 分屏改纵向堆叠后中缝轨失去意义，隐藏防压内容 */
  .zho-ignite-rail { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .zho-ignite-line, .zho-ignite-rail { display: none; }
}

/* §13.1 A1 v2 词级揭示遮罩（motion.js 拆词注入 .zho-ww>.zho-wi） */
.zho-ww { display: inline-block; overflow: hidden; vertical-align: bottom; }
.zho-wi { display: inline-block; will-change: transform; }

/* §13.2 滚动视差组装饰（2026-09-09，motion.js §5 专用）
   P1 水印大字：居中用 margin（非 transform——GSAP 独占该元素 transform） */
body.zho-home .zho-watermark {
  position: absolute; left: 0; top: 50%; margin-top: -0.5em;
  font-size: clamp(140px, 20vw, 300px); line-height: 1; font-weight: 800;
  letter-spacing: .04em; white-space: nowrap; z-index: 0;
  color: transparent;
  -webkit-text-stroke: 1.5px rgba(240, 180, 41, .13);
  pointer-events: none; user-select: none;
}
@supports not (-webkit-text-stroke: 1px black) {
  body.zho-home .zho-watermark { color: rgba(240, 180, 41, .05); }
}
body.zho-home .zho-whypanel .container { position: relative; z-index: 1; }
@media (max-width: 960px) {
  body.zho-home .zho-watermark { display: none; } /* 视差组仅桌面启用 */
}

/* §13.6 背景字变体（2026-09-09 v3，motion.js §6 注入；F2 火路已下线）
   B2 brandgrid「墨水填充」：描边底常显，实心层随 --zho-wmfill 自下而上
   clip-path 填充（GSAP 只写变量，CSS 合成，零 transform 冲突） */
body.zho-home .zho-brandgrid { position: relative; overflow: hidden; }
body.zho-home .zho-brandgrid .container,
body.zho-home .zho-closecta__inner { position: relative; z-index: 1; }
body.zho-home .zho-watermark--ink::after {
  content: attr(data-text);
  position: absolute; left: 0; top: 0;
  color: rgba(240, 180, 41, .10);
  -webkit-text-stroke: 0;
  clip-path: inset(var(--zho-wmfill, 100%) 0 0 0);
}
@supports not (-webkit-text-stroke: 1px black) {
  body.zho-home .zho-watermark--ink { color: rgba(240, 180, 41, .05); }
  body.zho-home .zho-watermark--ink::after { color: rgba(240, 180, 41, .09); }
}
/* v5.2：B2 铺满整屏（仅 brandgrid 作用域）——字号按视口宽约 22.5vw，
   水平居中两侧出血（GSAP 不写该元素 transform，CSS translateX 安全），
   超宽部分由 brandgrid overflow:hidden 裁切，签名感拉满 */
body.zho-home .zho-brandgrid .zho-watermark--ink {
  font-size: 22.5vw; letter-spacing: .02em;
  left: 50%; transform: translateX(-50%);
}
/* v5.2：B3 镜像填充——clip-path 改自下 inset，LET'S TALK 自上而下显影，
   与 B2 自下而上构成对位反差（浅底升 / 深底降） */
body.zho-home .zho-watermark--ink-rev::after {
  clip-path: inset(0 0 var(--zho-wmfill, 100%) 0);
}

/* §13.5 收尾 CTA 余温脉冲（closecta L1 氛围层，纯 CSS 零 JS）
   v5.1：扩散环由 ::after 伪元素 transform/opacity 驱动——box-shadow 动画
   违反动效白名单（只动 transform/opacity/CSS 变量），伪元素方案观感等价。 */
body.zho-home .zho-closecta .zho-cta-btn--primary { position: relative; }
body.zho-home .zho-closecta .zho-cta-btn--primary::after {
  content: ""; position: absolute; inset: 0;
  border-radius: inherit;
  box-shadow: 0 0 0 12px rgba(240, 180, 41, .32);
  opacity: 0; pointer-events: none;
  animation: zho-cta-pulse 2.8s ease-out infinite;
}
@keyframes zho-cta-pulse {
  0%       { transform: scale(1);    opacity: .32; }
  55%,100% { transform: scale(1.16); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  body.zho-home .zho-closecta .zho-cta-btn--primary::after { animation: none; opacity: 0; }
}

/* §13.7 差速视差合成权保障（v5.1，2026-09-09 逐屏验收）
   industrystack 卡片兼有 .zho-reveal 与 --zho-py var 合成：
   .js .zho-reveal 的 translateY(26px) 与 .is-in 的 transform:none
   （特异性 0-3-0）会把 §5 的 var 合成 transform 全程压死——实测差速
   不可见。此处以更高特异性恢复合成权（仅 GSAP 编排在场时生效）。 */
html.zho-gsap body.zho-home .zho-industrystack__card,
html.zho-gsap body.zho-home .zho-industrystack__card.is-in {
  transform: translateY(var(--zho-py, 0px));
}
html.zho-gsap body.zho-home .zho-industrystack__card:hover,
html.zho-gsap body.zho-home .zho-industrystack__card.is-in:hover {
  transform: translateY(calc(var(--zho-py, 0px) - 4px));
}

/* TEMP EXPERIMENT: kill transition on frontline CTAs under GSAP */
html.zho-gsap .zho-frontline__ctas .zho-cta-btn { transition: none; }

/* ---- B6-bis zho-proofcase__articles (Latest Articles module) ---- */
.zho-proofcase__articles {
  margin-top: var(--zho-s5);
  padding-top: var(--zho-s4);
  border-top: 1px solid var(--zho-line-dark);
}
.zho-proofcase__articlestitle {
  margin: 0 0 6px;
  font-size: var(--zho-fs-h3);
  color: var(--zho-on-dark);
}
.zho-proofcase__articlesintro {
  margin: 0 0 var(--zho-s3);
  max-width: 62ch;
  color: var(--zho-on-dark-s);
  font-size: var(--zho-fs-sm);
  line-height: 1.6;
}
.zho-proofcase__articlegrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 18px;
}
.zho-proofcase__article {
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--zho-dark-2);
  border: 1px solid var(--zho-line-dark);
  border-top: 3px solid var(--zho-action);
  border-radius: var(--zho-r-lg);
  padding: var(--zho-s3);
  text-decoration: none;
  color: inherit;
  transition: transform .25s ease, border-color .25s ease;
}
.zho-proofcase__article:hover {
  transform: translateY(-4px);
  border-color: var(--zho-action);
}
.zho-proofcase__articledate {
  font-family: var(--zho-mono);
  font-size: var(--zho-fs-xs);
  letter-spacing: .06em;
  color: var(--zho-on-dark-s);
}
.zho-proofcase__articletitle {
  margin: 0;
  font-size: 1.15rem;
  line-height: 1.35;
  font-weight: 700;
  color: var(--zho-on-dark);
}
.zho-proofcase__articleexcerpt {
  margin: 0;
  flex: 1;
  color: var(--zho-on-dark-s);
  font-size: var(--zho-fs-sm);
  line-height: 1.6;
}
.zho-proofcase__articlemore {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--zho-fs-sm);
  font-weight: 600;
  color: var(--zho-action);
}
.zho-proofcase__articlemore svg { width: 14px; height: 14px; }
