/* ============================================================
   ZHONGYUAN STEEL — demo site design system
   Direction: "drafting daylight" — a bright drawing-office look:
   white paper, graphite ink, ONE engineering-blue accent.
   Signature motif: engineering dimension-line (tick + rule)
   used as eyebrow labels, stat-card frames and dividers.
   ============================================================ */

:root {
  /* -- color: drawing-office light. Paper ground, graphite ink,
        structural navy as a SPICE (topbar/footer/dark bands only),
        engineering blue as THE accent. All values WCAG-verified. -- */
  --paper: #f4f6f8;        /* page background — cool paper white */
  --surface: #ffffff;      /* card / panel background */
  --surface-2: #ebeff3;    /* inset / alt surface (table stripes, inset panels) */
  --ink: #1b2733;          /* primary text — graphite (13.1 on paper) */
  --ink-muted: #46586a;    /* secondary text (6.3) */
  /* Tertiary ink still has to be READ — a [TBD] spec cell tells a buyer the
     value isn't confirmed yet, which is content, not decoration. It therefore
     clears 4.5:1 on every surface it lands on, and the faint/muted/ink tiers
     are separated by the mono face, size and tracking rather than by tone
     alone (no 3-step ramp can be both legible and visibly fainter here). */
  --ink-faint: #57656f;    /* tertiary text — 5.2:1 worst case on light grounds */
  --steel: #16334d;        /* structural NAVY — topbar/footer/.section--dark/thead
                              (white on it 13.0; muted-on-navy: #b9c8d6 = 7.6) */
  --steel-2: #1f4260;      /* lighter navy structural panel */
  --steel-line: #ccd6de;   /* hairline border / dimension-line on light bg */
  --steel-line-dark: #3c536a; /* hairline border on navy */
  /* --safety keeps its historical name (the accent used to be safety-orange);
     it is now the ENGINEERING-BLUE accent. Links, eyebrows, rules, borders.
     6.37:1 vs white — passes both as link text on white AND as a fill under
     white text, so --safety and --safety-fill share one value in light mode. */
  --safety: #0f62a3;       /* the accent — engineering blue */
  --safety-fill: #0f62a3;  /* button/tag FILL under white text (6.37 w/ #fff) */
  --safety-dark: #0b4d80;  /* hover/active FILL */
  --safety-ink: #0d5590;   /* accent TEXT on --safety-tint (6.41 on tint) */
  --safety-tint: #ddecf9;  /* pale blue chip ground */
  --safety-line: rgba(15,98,163,.28); /* accent hairline */
  --ok: #216e46;
  --ok-tint: #e0f2e7;      /* pale mint chip ground (5.33) */
  --ok-line: rgba(33,110,70,.25);

  --radius: 2px;           /* steel doesn't get rounded corners */
  --radius-sm: 1px;

  --container: 1200px;
  --gap: 24px;

  /* -- spacing scale: 4px base. Section rhythm is chosen by content
        density, not applied uniformly: --section-y is the default,
        --section-y-tight is for sections carrying a single block. -- */
  --space-2xs: 4px;
  --space-xs: 8px;
  --space-sm: 12px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 36px;
  --space-2xl: 56px;
  --space-3xl: 72px;

  --section-y: 64px;
  --section-y-tight: 40px;

  /* -- fixed chrome heights, referenced instead of re-typed -- */
  --header-h: 76px;
  --sticky-cta-h: 68px;  /* measured: 12px padding x2 + 42px btn + 2px border */

  /* -- mono label scale: three steps, not one blur -- */
  --label-lg: .78rem;      /* section eyebrow / dim-label */
  --label-md: .72rem;      /* data labels, dt, dates, captions */
  --label-sm: .64rem;      /* chips / badges */

  --shadow-card: 0 1px 2px rgba(27,39,51,.06), 0 8px 24px rgba(27,39,51,.06);
  --shadow-lift: 0 4px 8px rgba(27,39,51,.08), 0 16px 40px rgba(27,39,51,.10);

  /* -- type: condensed/tracked display, humanist body, mono for data -- */
  --font-display: "Helvetica Neue Condensed", "Arial Narrow", -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Code", "Roboto Mono", Menlo, Consolas, monospace;
}

/* Dark scheme: blue-graphite night, not charcoal — the drawing office
   after hours, same blue accent family. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #0e161e;
    --surface: #141d26;
    --surface-2: #1b2530;
    --ink: #e7ecf1;          /* 13.0 */
    --ink-muted: #a7b3bf;    /* 7.3 */
    --ink-faint: #8b98a4;    /* 5.3 */
    --steel: #0b1826;
    --steel-2: #14283a;
    --steel-line: #2c3a48;
    --steel-line-dark: #3a4c5e;
    --safety: #4a9bd8;       /* borders / rules / link text on dark */
    /* --safety-fill stays a FILL: white text must survive on it, so it keeps
       the light-mode blue (self-contained 6.37 w/ #fff). --safety-ink is the
       TEXT counterpart and goes lighter, read against --safety-tint. */
    --safety-fill: #0f62a3;
    --safety-dark: #0b4d80;
    --safety-ink: #7ab6e8;   /* 7.15 worst */
    --safety-tint: #10263a;
    --safety-line: rgba(74,155,216,.32);
    --ok: #5fc890;
    --ok-tint: #12281c;
    --ok-line: rgba(95,200,144,.3);
    /* light-mode shadows are invisible on a #0e161e ground */
    --shadow-card: 0 1px 2px rgba(0,0,0,.5), 0 8px 24px rgba(0,0,0,.4);
    --shadow-lift: 0 4px 8px rgba(0,0,0,.5), 0 16px 40px rgba(0,0,0,.45);
  }
  html { scrollbar-color: #3a4c5e #0e161e; }
  /* The hero's INLINE wheel SVG carries light-sheet presentation attributes
     (graphite #26333f linework), which vanish on the dark hero ground
     (~1.5:1). Being inline, it CAN theme — flip its inks via exact
     attribute selectors; light mode keeps the attributes as authored. */
  .hero-figure svg [stroke="#26333f"] { stroke: #dfe7ee; }
  .hero-figure svg [stroke="#5c6b7a"] { stroke: #93a5b3; }
  .hero-figure svg [stroke="#6b7c8c"] { stroke: #7c8b99; }
  .hero-figure svg [stroke="#0d5a96"] { stroke: #7ab6e8; }
  .hero-figure svg [fill="#0d5a96"] { fill: #7ab6e8; }
  .hero-figure svg [fill="#46586a"] { fill: #a7b3bf; }
}

* { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* the header is sticky and --header-h tall: every #anchor jump would
     otherwise land underneath it. */
  scroll-padding-top: calc(var(--header-h) + 16px);
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
  .product-card:hover, .btn:active { transform: none; }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

/* selection in the accent family — fill is self-contained w/ white in both modes */
::selection { background: var(--safety-fill); color: #fff; }

img, svg { max-width: 100%; display: block; }

a { color: var(--safety); text-decoration: none; transition: color .15s ease; }
a:hover { color: var(--safety-dark); }
@media (prefers-color-scheme: dark) {
  a:hover { color: var(--safety-ink); } /* hover goes LIGHTER on dark, not deeper */
}
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid var(--safety);
  outline-offset: 2px;
}
/* Where the blue outline would land on the blue fill itself, or on the navy
   grounds, switch the ring to something that can actually be seen.
   (Verified: #fff vs --steel #16334d = 13.0; #fff vs --safety-fill = 6.37;
   --ink vs --paper = 13.1 for the ring around the blue button.) */
.btn-primary:focus-visible { outline-color: var(--ink); }
.topbar a:focus-visible, .topbar button:focus-visible,
.section--dark a:focus-visible, .section--dark button:focus-visible,
.sticky-cta a:focus-visible, .sticky-cta button:focus-visible,
.site-footer a:focus-visible, .to-top:focus-visible { outline-color: #fff; }
.dropdown a:focus-visible { outline-offset: -2px; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .01em;
  font-stretch: condensed;
  margin: 0 0 .5em;
  color: var(--ink);
  line-height: 1.1;
}
h1 { font-size: clamp(2.2rem, 4.4vw, 3.6rem); letter-spacing: .005em; }
h2 { font-size: clamp(1.65rem, 2.8vw, 2.3rem); }
/* h3 sat at 1.15rem, a hair off h4 and a long way off h2 — the middle of
   the scale was missing. Pull the steps apart so nesting is legible. */
h3 { font-size: 1.24rem; letter-spacing: .03em; }
h4 { font-size: .92rem; letter-spacing: .05em; }

p { margin: 0 0 1em; color: var(--ink-muted); }
p:last-child { margin-bottom: 0; }

.container { max-width: var(--container); margin: 0 auto; padding: 0 24px; }
.section { padding: var(--section-y) 0; }
.section--tight { padding: var(--section-y-tight) 0; }
/* Content-proportional rhythm: a section whose container carries a single
   block (the "OEM & Custom Orders" pattern — one h3 and one sentence) does
   not earn 144px of vertical padding. */
.section:has(> .container > .info-block:only-child),
.section:has(> .container > .prose:only-child),
.section:has(> .container > .check-list:only-child) { padding: var(--section-y-tight) 0; }
/* Navy is a spice: .section--dark is one of the few dark grounds left.
   It stays navy in BOTH schemes, so its text colours are literals tuned
   to --steel (#16334d light / #0b1826 dark — every value below clears
   4.5:1 on the LIGHTER of the two): #b9c8d6 = 7.6 on #16334d. */
.section--dark { background: var(--steel); color: #b9c8d6; }
.section--dark h2, .section--dark h3, .section--dark h4 { color: #fff; }
.section--dark p { color: #b9c8d6; }
.section--dark a:not(.btn) { color: #7ab6e8; }   /* 5.99 on #16334d */
.section--dark a:not(.btn):hover { color: #fff; }
.section--dark .hl { color: #7ab6e8; }

/* --alt is the white "sheet" ground. It carries a top hairline so that two
   consecutive alt sections read as two sheets rather than one dead slab
   (products.html + custom.html both stack them), and so the sheet edge is
   stated where it meets --paper. A .ruler already IS that boundary. */
.section--alt { background: var(--surface); border-top: 1px solid var(--steel-line); }
.ruler + .section--alt { border-top: none; }

/* Cards are white on --paper (raised) but would vanish on the white sheet,
   since the fill step is ~1.05:1 and only the hairline was doing any work.
   On a sheet, step the panel to --surface-2 instead. Works in both modes:
   light insets it (#ebeff3 on #fff), dark lifts it (#1b2530 on #141d26).
   Either way the panel is always one measurable step off its ground. */
.section--alt .info-block,
.section--alt .inquiry,
.section--alt .simple-card,
.section--alt .contact-card,
.section--alt .product-card,
.section--alt .news-card,
.section--alt .step,
.section--alt .trust-card { background: var(--surface-2); }

/* ---------- ruler divider — signature: a measurement scale ---------- */
.ruler {
  height: 14px;
  background-image: repeating-linear-gradient(
    to right, var(--steel-line) 0, var(--steel-line) 1px, transparent 1px, transparent 24px
  );
  background-position: bottom left;
  background-repeat: repeat-x;
  background-size: 24px 10px;
  border-bottom: 1px solid var(--steel-line);
}
.ruler--dark {
  background-image: repeating-linear-gradient(
    to right, var(--steel-line-dark) 0, var(--steel-line-dark) 1px, transparent 1px, transparent 24px
  );
  border-bottom-color: var(--steel-line-dark);
}

/* ---------- dimension-line eyebrow (signature component) ---------- */
.dim-label {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: var(--label-lg);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--safety);
  margin-bottom: 14px;
}
.dim-label::before, .dim-label::after {
  content: "";
  width: 22px;
  height: 8px;
  border-top: 1.5px solid var(--safety);
  border-left: 1.5px solid var(--safety);
  border-right: 1.5px solid var(--safety);
  border-bottom: none;
}
/* on the navy band the accent lightens (same literal-on-navy reasoning) */
.section--dark .dim-label { color: #7ab6e8; }
.section--dark .dim-label::before, .section--dark .dim-label::after { border-color: #7ab6e8; }

/* ---------- header / nav ---------- */
/* The topbar keeps a navy ground in both schemes — its text colours are
   literals rated against --steel (#b9c8d6 = 7.6, #cfdce8 = 9.3). */
.topbar {
  background: var(--steel);
  color: #b9c8d6;
  font-family: var(--font-mono);
  font-size: .78rem;
}
.topbar .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 36px;
}
.topbar-links { display: flex; gap: 20px; align-items: center; }
.topbar-links a { color: #cfdce8; }
.topbar-links a:hover { color: #fff; }
.lang-toggle { display: flex; gap: 4px; }
.lang-toggle button {
  background: transparent; border: 1px solid var(--steel-line-dark); color: #b9c8d6;
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .06em;
  padding: 3px 8px; cursor: pointer; transition: color .15s ease, border-color .15s ease;
}
.lang-toggle button.is-active { background: var(--safety-fill); border-color: var(--safety-fill); color: #fff; }

.site-header {
  position: sticky; top: 0; z-index: 40;
  background: var(--surface);
  border-bottom: 1px solid var(--steel-line);
}
.site-header .container {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  height: var(--header-h);
}
/* The supplied trademark already has a transparent background. Its dark
   Chinese wordmark is overlaid from the same alpha mask in dark mode so the
   official red mark stays unchanged without adding a white backing plate. */
.site-brand {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  height: calc(var(--header-h) - 18px);
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  line-height: 0;
}
.site-brand img {
  display: block;
  width: auto;
  height: 100%;
  max-width: none;
  object-fit: contain;
}
@media (prefers-color-scheme: dark) {
  @supports ((-webkit-mask-image: url("")) or (mask-image: url(""))) {
    .site-brand::after {
      content: "";
      position: absolute;
      inset: 0;
      background: var(--ink);
      -webkit-mask: url("../img/brand/zhongyuan-logo.png") center / contain no-repeat;
      mask: url("../img/brand/zhongyuan-logo.png") center / contain no-repeat;
      clip-path: inset(80% 0 0 0);
      pointer-events: none;
    }
  }
}
@media (max-width: 767px) {
  .site-brand {
    height: calc(var(--header-h) - 22px);
  }
}

/* Text wordmark retained in the footer. */
.logo {
  font-family: var(--font-display);
  font-weight: 800; text-transform: uppercase; letter-spacing: .02em;
  font-size: 1.35rem; color: var(--ink); display: flex; flex-direction: column; line-height: 1;
  flex-shrink: 0; /* was being crushed by the nowrap nav and wrapping its <small> */
}
.logo span { color: var(--safety); }
.logo small {
  font-family: var(--font-mono); font-weight: 400; letter-spacing: .12em;
  font-size: .6rem; color: var(--ink-muted); text-transform: uppercase; margin-top: 4px;
  white-space: nowrap;
}

.nav { display: flex; align-items: center; gap: 4px; }
.nav > ul { display: flex; list-style: none; margin: 0; padding: 0; gap: 2px; }
.nav a.nav-link {
  /* 14px side padding put the nav's min-content at 741px; with the logo
     (194) and header CTA (196) that needs ~1131px of a 1152px inner
     container — no slack at any viewport. 10px buys back 56px. */
  display: flex; align-items: center; height: var(--header-h); padding: 0 10px;
  color: var(--ink); font-size: .92rem; font-weight: 600; white-space: nowrap;
  border-bottom: 2px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
.nav a.nav-link:hover, .nav li.is-active > a.nav-link { color: var(--safety); border-bottom-color: var(--safety); }
.nav li { position: relative; }
.nav .has-dropdown > a.nav-link::after { content: "▾"; margin-left: 6px; font-size: .7em; }
.dropdown {
  position: absolute; top: 100%; left: 0; background: var(--surface);
  border: 1px solid var(--steel-line); box-shadow: var(--shadow-lift);
  min-width: 300px; list-style: none; margin: 0; padding: 8px; opacity: 0; visibility: hidden;
  transform: translateY(4px); transition: opacity .15s ease, transform .15s ease, visibility .15s;
}
.nav .has-dropdown:hover .dropdown,
.nav .has-dropdown:focus-within .dropdown { opacity: 1; visibility: visible; transform: translateY(0); }
.dropdown a { display: block; padding: 10px 12px; color: var(--ink); font-size: .88rem; border-radius: var(--radius-sm); }
.dropdown a:hover { background: var(--surface-2); color: var(--safety); }
.dropdown .dropdown-note { display: block; font-family: var(--font-mono); font-size: .68rem; color: var(--ink-faint); margin-top: 1px; }
.dropdown .dropdown-group { padding: 9px 12px 4px; font-family: var(--font-mono); font-size: var(--label-sm); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); border-top: 1px solid var(--steel-line); margin-top: 4px; pointer-events: none; }
.dropdown .dropdown-group:first-child { border-top: none; margin-top: 0; }
.badge-trade { background: var(--surface-2); color: var(--ink-muted); border: 1px solid var(--steel-line); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-body); font-weight: 700; font-size: .88rem;
  letter-spacing: .02em; padding: 13px 24px; border-radius: var(--radius);
  border: 1.5px solid transparent; cursor: pointer; transition: background .15s, color .15s, border-color .15s, transform .1s;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--safety-fill); color: #fff; border-color: var(--safety-fill); }
.btn-primary:hover { background: var(--safety-dark); border-color: var(--safety-dark); color: #fff; }
.btn-outline { background: transparent; color: var(--ink); border-color: var(--steel-line); }
.btn-outline:hover { border-color: var(--ink); color: var(--ink); }
/* lives on the navy grounds only — border rated vs --steel #16334d (3.6:1) */
.btn-outline-light { background: transparent; color: #fff; border-color: #6a8aa6; }
.btn-outline-light:hover { border-color: #fff; }
.btn-block { width: 100%; }
.btn-sm { padding: 9px 16px; font-size: .8rem; }

.header-cta { display: flex; align-items: center; gap: 10px; }
/* "Get a Quote" was breaking to two lines and pushing the header to 63px of
   content in a 76px bar. Only the header is width-critical — long labels
   elsewhere (e.g. the hero's "Learn More About OEM & Custom Orders") must
   still be free to wrap on a phone. */
.header-cta .btn { white-space: nowrap; flex-shrink: 0; }
.burger { display: none; background: none; border: none; cursor: pointer; padding: 8px; }
.burger span { display: block; width: 22px; height: 2px; background: var(--ink); margin: 5px 0; }

/* ---------- hero ----------
   A light drafting sheet, not a dark slab: paper ground with a very faint
   24px blueprint grid in the hairline tone, graphite headline, the em
   accent in engineering blue. The inline hero SVG is drawn as its own
   opaque sheet, so it sits on this grid like a pinned drawing. */
.hero {
  background-color: var(--paper);
  background-image:
    repeating-linear-gradient(to right, var(--steel-line) 0, var(--steel-line) 1px, transparent 1px, transparent 24px),
    repeating-linear-gradient(to bottom, var(--steel-line) 0, var(--steel-line) 1px, transparent 1px, transparent 24px);
  color: var(--ink);
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--steel-line);
}
.hero .container {
  display: grid; grid-template-columns: 1.1fr .9fr; gap: 48px; align-items: center;
  padding-top: 72px; padding-bottom: 56px;
}
.hero h1 { color: var(--ink); }
.hero h1 em { font-style: normal; color: var(--safety); }
.hero-sub { color: var(--ink-muted); font-size: 1.08rem; max-width: 46ch; margin-bottom: 28px; }
.hero-actions { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 8px; }
.hero-figure { position: relative; }

/* ---------- photo slot ----------
   Slots a technical drawing CANNOT honestly fill — the Tangyin workshop, the
   team, a certificate — still need a real camera. They stay marked as pending
   on purpose, but they are dressed as the same object as the drawings: an
   opaque LIGHT SHEET (#f3f6f9) with the drawings' own grid and crop marks,
   awaiting its photograph. The colours are LITERALS, not tokens, because the
   drawings ship as standalone <img> and cannot follow the theme — matching
   them means not theming either, or the two drift apart in dark mode. The
   sheet reads as paper on both card colours via its #8494a3 edge (3.11 vs
   #fff, 5.47 vs the dark card).
   Swapping in a real photo is <img src> into the same slot: no layout change. */
.placeholder {
  position: relative;
  min-width: 0;
  display: flex; align-items: center; justify-content: center; text-align: center;
  background-color: #f3f6f9;
  background-image:
    linear-gradient(to right, #e4ebf1 1px, transparent 1px),
    linear-gradient(to bottom, #e4ebf1 1px, transparent 1px);
  background-size: 24px 24px;
  border: 1.5px solid #8494a3;   /* load-bearing sheet edge — see note above */
  color: #46586a;                /* the drawings' caption ink (6.1 on sheet) */
  font-family: var(--font-mono);
  font-size: .74rem;
  letter-spacing: .03em;
  padding: 26px 20px 20px;
  min-height: 180px;
  border-radius: var(--radius);
  overflow: hidden;
}
/* crop marks — from the same drafting vocabulary as .ruler and .dim-label,
   in the drawings' dimension-blue */
.placeholder::before, .placeholder::after {
  content: ""; position: absolute; width: 14px; height: 14px; pointer-events: none;
  border-color: #0d5a96; border-style: solid; opacity: .9;
}
.placeholder::before { top: 7px; right: 7px; border-width: 1.5px 1.5px 0 0; }
.placeholder::after { bottom: 7px; left: 7px; border-width: 0 0 1.5px 1.5px; }
.placeholder .ph-tag {
  position: absolute; top: 0; left: 0;
  background: var(--safety-fill); color: #fff; font-size: var(--label-sm); letter-spacing: .08em;
  padding: 3px 8px; text-transform: uppercase;
}
.placeholder > div {
  background: rgba(255,255,255,.75);
  border: 1px solid #c6d2dc;
  padding: 14px 18px;
  border-radius: var(--radius);
  /* plain `34ch` is a floor as well as a ceiling once the tile is narrower
     than the label, which pushed the tile's min-content past its grid track
     and scrolled the page sideways on a 320px phone */
  max-width: min(34ch, 100%);
}
/* label ink is literal too (#1b2733/#46586a): the sheet stays light in dark
   mode, so the themed --ink tokens would flip light-on-light there */
.placeholder strong { display: block; color: #1b2733; font-size: .82rem; margin-bottom: 4px; text-transform: none; letter-spacing: 0; font-family: var(--font-body); font-weight: 700; }
.placeholder .profile-icon { margin: 0 auto 10px; color: #0d5a96; }

/* ---------- section header ---------- */
.section-head { max-width: 640px; margin: 0 0 40px; }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.section-head.center .profile-icon { margin: 0 auto 16px; }

/* ---------- trust / why choose us ----------
   6-up put each card at 172px, minus 36px of padding = 136px of content box
   for strings like "ISO9001" at 1.35rem mono — one font fallback away from
   overflowing. 3x2 gives the same six figures a 368px card to sit in. */
.trust-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap); }
.trust-card {
  background: var(--surface); border: 1px solid var(--steel-line); padding: 24px 18px;
  position: relative; transition: border-color .15s ease;
}
.trust-card::before, .trust-card::after {
  content: ""; position: absolute; width: 10px; height: 10px; border-color: var(--safety); border-style: solid; opacity: .8;
}
.trust-card::before { top: -1px; left: -1px; border-width: 2px 0 0 2px; }
.trust-card::after { bottom: -1px; right: -1px; border-width: 0 2px 2px 0; }
.trust-icon { width: 34px; height: 34px; margin-bottom: 14px; color: var(--safety); }
.trust-num { font-family: var(--font-mono); font-weight: 700; font-size: 1.35rem; color: var(--ink); overflow-wrap: anywhere; }
/* The markup has no whitespace before <span class="unit">, so this rendered
   as "Since1990s" / "3BASES" / "2MSETS/YR" in all six cards. */
.trust-num .unit { font-size: .6em; color: var(--safety-ink); margin-left: .35em; }
.trust-label { font-size: .78rem; color: var(--ink-muted); margin-top: 4px; line-height: 1.4; }
.trust-tbd { display: inline-block; margin-top: 8px; }

/* ---------- badges ---------- */
.badge {
  display: inline-block; font-family: var(--font-mono); font-size: var(--label-sm); letter-spacing: .06em;
  text-transform: uppercase; padding: 3px 8px; border-radius: var(--radius-sm);
  background: var(--safety-tint); color: var(--safety-ink); border: 1px solid var(--safety-line);
}
.badge-outline { background: transparent; border: 1px solid var(--steel-line); color: var(--ink-muted); }
/* was a hard-coded #e4f2e9 mint that never flipped for dark mode */
.badge-live { background: var(--ok-tint); color: var(--ok); border-color: var(--ok-line); }

/* ---------- product grid ----------
   Was repeat(3, 1fr) while every product grid on the site holds exactly TWO
   cards, so a ~380px dead column sat beside every row. auto-fit collapses
   the empty track, so two cards honestly fill the row (2 x 564px at the
   1200px container) and a future third or fourth card still lands correctly
   without anyone remembering to change a modifier. */
.product-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--gap); }
.product-card {
  background: var(--surface); border: 1px solid var(--steel-line);
  display: flex; flex-direction: column; transition: box-shadow .15s, transform .15s;
}
.product-card:hover, .product-card:focus-within { box-shadow: var(--shadow-lift); transform: translateY(-2px); }
/* The figure slot is briefed to the illustration track as a 5:2 letterbox.
   At 368px wide a 150px min-height happened to land there; at 564px it no
   longer does, so state the ratio instead of implying it with a height.
   min-height MUST be cleared: against an aspect-ratio it back-computes into
   a min-width (150 x 5/2 = 375px) and overflows the card on phones. */
.product-card .ph-figure { min-height: 0; aspect-ratio: 5 / 2; }

/* ---------- drawing / photo slot (img) ----------
   A finished technical drawing (or, later, a real photo) drops straight into a
   placeholder's slot as <img class="dwg-slot ...">. The drawings are already
   self-framed opaque panels, so the slot adds no border of its own — object-fit
   COVER means swapping in a real photograph of a different pixel size needs no
   layout change, which is the whole point of the drawing-as-bridge approach. */
.dwg-slot { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: var(--radius); }
.product-card .dwg-slot { aspect-ratio: 5 / 2; }          /* card tier drawings are 5:2 */
.news-card .dwg-slot { aspect-ratio: 5 / 2; }
.pd-hero .dwg-slot { aspect-ratio: 16 / 9; min-height: 300px; align-self: stretch; }  /* hero tier drawings are 16:9 */
.pd-figure .dwg-slot, .figure-block .dwg-slot { aspect-ratio: 16 / 9; }
.product-card-body { padding: 20px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.product-card-body h3 { margin-bottom: 2px; }
.product-card-body p { font-size: .88rem; flex: 1; }
.product-card-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 8px; }
.product-card-link { font-family: var(--font-mono); font-size: var(--label-lg); font-weight: 600; letter-spacing: .02em; }
.product-card-link:hover { text-decoration: underline; text-underline-offset: 3px; }
.product-card-link::after { content: " →"; }

/* ---------- profile icon svgs ---------- */
.profile-icon { width: 44px; height: 44px; color: var(--safety); }

/* ---------- step flow (custom profile — a real sequence, numbering justified) ---------- */
.step-flow { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap); counter-reset: step; }
.step {
  background: var(--surface); border: 1px solid var(--steel-line); padding: 26px 20px; position: relative;
}
.step-num {
  font-family: var(--font-mono); font-size: var(--label-lg); color: var(--safety); font-weight: 700;
  letter-spacing: .04em; margin-bottom: 14px; display: block;
}
.step h3 { margin-bottom: 8px; }
.step p { font-size: .86rem; }
/* .step panels keep a --surface fill even inside the navy band (index,
   custom, two product pages), so the navy-ground text overrides above must
   not leak onto them — reset to the panel's own ink tokens, which are rated
   for --surface in both schemes. */
.section--dark .step h2, .section--dark .step h3, .section--dark .step h4 { color: var(--ink); }
.section--dark .step p { color: var(--ink-muted); }
.step-arrow {
  display: none;
  /* spans exactly the --gap gutter, card edge to card edge, instead of
     overhanging 5px into the next card on each side */
  position: absolute; top: 50%; right: calc(-1 * var(--gap)); transform: translateY(-50%);
  width: var(--gap); height: 1px; background: var(--steel-line);
}
.step-arrow::after {
  content: ""; position: absolute; right: 0; top: -4px; border: 4px solid transparent; border-left-color: var(--steel-line);
}
/* .step-flow only becomes a single 4-up row at >=1024px. Showing arrows from
   900px left the row-1 trailing arrow pointing out of the grid into nothing. */
@media (min-width: 1024px) { .step-arrow { display: block; } }

/* ---------- news ---------- */
.news-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap); }
.news-card { background: var(--surface); border: 1px solid var(--steel-line); }
.news-card .ph-figure { min-height: 130px; }
.news-card-body { padding: 18px 20px 22px; }
.news-date { font-family: var(--font-mono); font-size: var(--label-md); color: var(--ink-faint); }
.news-card h3 { font-size: 1rem; margin: 8px 0; text-transform: none; letter-spacing: 0; font-family: var(--font-body); font-weight: 700; }
.news-card p { font-size: .86rem; }

/* ---------- breadcrumb ---------- */
.breadcrumb {
  font-family: var(--font-mono); font-size: var(--label-md); color: var(--ink-faint);
  padding: 16px 0; border-bottom: 1px solid var(--steel-line); background: var(--surface-2);
}
.breadcrumb a { color: var(--ink-muted); }
.breadcrumb a:hover { color: var(--safety); }
/* --steel-line is a hairline token — tuned to be barely visible, which is right
   for a 1px rule and wrong for a glyph (it rendered the "/" at 1.36:1). */
.breadcrumb .sep { margin: 0 6px; color: var(--ink-faint); }
.breadcrumb .current { color: var(--ink); }

/* ---------- product detail layout ---------- */
/* --surface-2 gives the hero its own ground: it was #fff directly under a
   #fff sticky header, with only the breadcrumb hairline between them. */
.pd-hero { background: var(--surface-2); border-bottom: 1px solid var(--steel-line); padding: 44px 0 40px; }
.pd-hero .container { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
/* stretch, not centre: a 300px figure floating in a ~420px column left a
   band of dead space above and below it */
.pd-hero .placeholder { min-height: 300px; align-self: stretch; }
.pd-meta { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.pd-title { margin-bottom: 10px; }
.pd-lead { font-size: 1.02rem; max-width: 58ch; } /* .hero-sub is capped at 46ch; this was missed */

.spec-table-wrap { overflow-x: auto; border: 1px solid var(--steel-line); }
table.spec-table { width: 100%; border-collapse: collapse; background: var(--surface); font-size: .88rem; min-width: 640px; }
table.spec-table caption { caption-side: top; text-align: left; padding: 12px 16px; font-family: var(--font-mono); font-size: var(--label-md); color: var(--ink-muted); background: var(--surface-2); border-bottom: 1px solid var(--steel-line); }
table.spec-table th, table.spec-table td { padding: 12px 16px; text-align: left; border-bottom: 1px solid var(--steel-line); font-family: var(--font-mono); }
/* the navy spice again: a spec-sheet title bar */
table.spec-table thead th {
  background: var(--steel); color: #fff; font-family: var(--font-body); text-transform: uppercase;
  font-size: .72rem; letter-spacing: .06em; font-weight: 700; border-bottom: none;
}
table.spec-table tbody tr { transition: background .15s ease; }
table.spec-table tbody tr:nth-child(even) { background: var(--surface-2); }
table.spec-table tbody tr:hover { background: var(--safety-tint); }
table.spec-table td.model { font-weight: 700; color: var(--ink); }
table.spec-table td.tbd, table.spec-table span.tbd { color: var(--ink-faint); font-style: normal; }
table.spec-table td.tbd::after { content: ""; }

.spec-note {
  display: flex; gap: 10px; align-items: flex-start; padding: 14px 16px; background: var(--safety-tint);
  border: 1px solid var(--safety-line); font-size: .84rem; color: var(--safety-ink); margin-top: 12px;
  max-width: 90ch;
}

.muted-note { margin-top: 14px; font-size: .82rem; color: var(--ink-faint); font-style: italic; max-width: 760px; }
.park-banner { background: var(--safety-tint); border-bottom: 1px solid var(--safety-line); }
/* `padding: 10px 0` (0,2,0) was overriding `.container { padding: 0 24px }`
   (0,1,0), so the banner text ran flush to the viewport edge, out of
   alignment with every other element on the page. padding-block leaves the
   inherited horizontal gutter alone. */
.park-banner .container { padding-block: 10px; font-size: .84rem; color: var(--safety-ink); }

.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); }
.info-block { background: var(--surface); border: 1px solid var(--steel-line); padding: 22px 24px; }
.info-block h3 { margin-bottom: 12px; }
.info-block p { max-width: 74ch; } /* a lone block spans the full 1152px container */
.info-block ul { margin: 0; padding-left: 18px; color: var(--ink-muted); font-size: .92rem; }
.info-block li { margin-bottom: 6px; }
/* The only browser-default styling left on the site was the disc bullet on
   these two lists. Give them the house marker instead. */
.info-block ul:not(.check-list) { list-style: none; padding-left: 0; }
.info-block ul:not(.check-list) > li { position: relative; padding-left: 18px; }
.info-block ul:not(.check-list) > li::before {
  content: "—"; position: absolute; left: 0; top: 0;
  color: var(--safety); font-family: var(--font-mono);
}
.info-block dl { margin: 0; }
.info-block dt { font-family: var(--font-mono); font-size: var(--label-md); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-faint); margin-top: 12px; }
.info-block dt:first-child { margin-top: 0; }
.info-block dd { margin: 2px 0 0; color: var(--ink); font-weight: 600; }

.media-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
/* A 110px min-height left a 70px content box after the 20px padding, so the
   centred label card ran back under the absolutely-positioned .ph-tag in all
   12 gallery tiles. Give the tag its own headroom rather than restyling the
   placeholder component (the tag chip itself is another track's to own). */
.media-grid .placeholder { min-height: 132px; padding-top: 36px; min-width: 0; }

/* ---------- sticky product CTA ---------- */
.sticky-cta {
  position: sticky; bottom: 0; z-index: 30;
  background: var(--steel); color: #fff;
  border-top: 2px solid var(--safety);
}
.sticky-cta .container { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 24px; }
.sticky-cta-text { font-size: .86rem; color: #b9c8d6; }
.sticky-cta-text strong { color: #fff; }
.sticky-cta-actions { display: flex; gap: 10px; align-items: center; flex-shrink: 0; }

/* ---------- inquiry form ---------- */
.inquiry {
  background: var(--surface); border: 1px solid var(--steel-line); padding: 32px;
}
.inquiry-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
/* the grid gap and this margin were stacking: 32px row gutters against 16px
   column gutters. Let the gap own the spacing inside the grid. */
.inquiry-grid > .field { margin-bottom: 0; }
.field.full { grid-column: 1 / -1; }
.field label { font-family: var(--font-mono); font-size: var(--label-md); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-muted); }
.field input, .field select, .field textarea {
  border: 1.5px solid var(--steel-line); background: var(--surface); color: var(--ink);
  padding: 11px 12px; font-family: var(--font-body); font-size: .92rem; border-radius: var(--radius);
  transition: border-color .15s ease;
}
.field textarea { resize: vertical; min-height: 96px; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--safety); outline: none; }
/* UA-default placeholder (#757575) is 3.70:1 on the dark input fill — pin it
   to the rated tertiary ink instead (6.01 light / 5.4 dark) */
.field input::placeholder, .field textarea::placeholder { color: var(--ink-faint); opacity: 1; }
.form-promise { display: flex; align-items: center; gap: 10px; font-size: .82rem; color: var(--ink-muted); margin-top: 4px; }
.form-promise .dot { width: 8px; height: 8px; background: var(--ok); border-radius: 50%; flex-shrink: 0; }
.form-status { font-family: var(--font-mono); font-size: .8rem; margin-top: 12px; display: none; padding: 10px 12px; border: 1px solid var(--ok-line); background: var(--ok-tint); color: var(--ok); }
.form-status.is-visible { display: block; }

/* ---------- footer ----------
   The footer keeps the navy ground in both schemes — text colours are
   literals rated against --steel: #b9c8d6 = 7.6, #9fb2c3 = 6.0 (meta),
   #7ab6e8 = 6.0 (accent). */
.site-footer { background: var(--steel); color: #b9c8d6; }
.site-footer p { color: #b9c8d6; } /* the base `p` rule is light-ground ink */
.footer-top { padding: 64px 0 40px; }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 40px; }
.footer-brand .logo { color: #fff; }
/* the accent span inherits light-mode --safety #0f62a3, which is only 2.04:1
   on the always-navy footer — lift to the navy-ground accent (5.99:1) */
.footer-brand .logo span { color: #7ab6e8; }
.footer-brand .logo small { color: #9fb2c3; }
.footer-brand p { margin-top: 14px; font-size: .88rem; max-width: 34ch; }
.footer-col h4 { color: #fff; font-size: .78rem; margin-bottom: 16px; }
.footer-col ul { list-style: none; margin: 0; padding: 0; }
.footer-col li { margin-bottom: 10px; }
.footer-col a { color: #b9c8d6; font-size: .88rem; }
.footer-col a:hover { color: #fff; }
.footer-contact-item { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 12px; font-size: .88rem; }
.footer-contact-item svg { width: 16px; height: 16px; color: #7ab6e8; flex-shrink: 0; margin-top: 3px; }
.footer-bottom {
  border-top: 1px solid var(--steel-line-dark);
  padding: 20px 0; font-size: .78rem; color: #9fb2c3;
  display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px;
}
.footer-bottom a { color: #b9c8d6; }
/* lives on the navy footer in both schemes → dark-tint literals:
   #7ab6e8 on #10263a = 7.1 */
.demo-flag {
  font-family: var(--font-mono); font-size: var(--label-sm); letter-spacing: .04em; color: #7ab6e8;
  border: 1px solid #2c4a66; background: #10263a; padding: 3px 9px;
}

/* ---------- misc content pages (about/quality/news/custom) ---------- */
.page-hero { background: var(--surface-2); border-bottom: 1px solid var(--steel-line); padding: 48px 0; }
.page-hero .container { max-width: 900px; }
.page-hero p { max-width: 62ch; }
.prose { max-width: 72ch; }
.prose h2 { margin-top: 2em; }
.prose h2:first-child { margin-top: 0; }
.card-list { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--gap); }
/* A 3-item set in a 2-col grid orphans the third card beside a 564px hole
   (about.html "Three Production Bases"). Let a 3-up set be 3-up. */
@media (min-width: 1024px) {
  .card-list:has(> :last-child:nth-child(3)) { grid-template-columns: repeat(3, 1fr); }
}
.simple-card { background: var(--surface); border: 1px solid var(--steel-line); padding: 24px; }
.simple-card h3 { display: flex; align-items: center; gap: 10px; }
/* These inline SVGs carry no width/height attribute, so without a rule they
   resolve to the SVG default replaced size and rendered as 307–445px
   checkmarks on about.html and quality.html. One card hard-codes width="18"
   and was the only correct one; size them here so it cannot regress. */
.simple-card h3 svg { width: 18px; height: 18px; flex-shrink: 0; }

.check-list { list-style: none; margin: 0; padding: 0; max-width: 74ch; }
.check-list li { display: flex; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--steel-line); font-size: .92rem; color: var(--ink-muted); }
.check-list li:last-child { border-bottom: none; }
.check-list svg { width: 16px; height: 16px; color: var(--ok); flex-shrink: 0; margin-top: 3px; }
/* A long list (products.html has 8 two-word items) reads as a thin ribbon of
   full-width rules with a 16px tick. Two columns give it a real measure. */
@media (min-width: 768px) {
  .check-list:has(> li:nth-child(6)) {
    display: grid; grid-template-columns: 1fr 1fr; column-gap: 40px; max-width: 900px;
  }
  .check-list:has(> li:nth-child(6)) li:nth-last-child(-n+2) { border-bottom: none; }
}

.mt-md { margin-top: 24px; }
.mt-lg { margin-top: 32px; }

/* was .9fr 1.1fr — the wider column held the least content (one info-block
   against a 522px stack of contact cards) and bottomed out 145px early. */
.contact-grid { display: grid; grid-template-columns: 1.1fr .9fr; gap: 48px; }
.contact-card { background: var(--surface); border: 1px solid var(--steel-line); padding: 22px 24px; margin-bottom: 16px; }
.contact-card h4 { margin-bottom: 10px; }

.tbd { color: var(--ink-faint); font-style: normal; }
/* The steel surfaces are navy in BOTH schemes, so --ink-faint (tuned for light
   grounds) fails on them — the footer's "+86 [TBD]" lines. Lift to a tone that
   clears 4.5:1 on --steel (#9fb2c3 = 6.0 on #16334d) while staying visibly
   fainter than the surrounding #b9c8d6, matching how .section--dark already
   overrides .dim-label. (The hero is light now and needs no override.) */
.section--dark .tbd, .site-footer .tbd { color: #9fb2c3; }
.hl { color: var(--safety); }

/* ---------- back to top ---------- */
.to-top {
  position: fixed; right: 20px; bottom: 20px; z-index: 50;
  width: 42px; height: 42px; background: var(--steel); color: #fff;
  border: 1px solid var(--steel-line-dark);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  opacity: 0; visibility: hidden; transition: opacity .2s, visibility .2s;
  box-shadow: var(--shadow-lift);
}
.to-top.is-visible { opacity: 1; visibility: visible; }
/* On every product page .to-top was landing on top of the sticky CTA bar —
   same --steel fill, 20px higher z-index — and physically blocking the
   "Request a Quote" button, i.e. the site's primary conversion action.
   Sit it above the bar wherever the bar exists. */
body:has(.sticky-cta) .to-top { bottom: calc(var(--sticky-cta-h) + 16px); }
/* Under 768px the bar stacks to two rows and already carries both actions,
   so the floating button is pure obstruction. */
@media (max-width: 767px) {
  body:has(.sticky-cta) .to-top { display: none; }
}

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 1023px) {
  .trust-grid { grid-template-columns: repeat(3, 1fr); }
  .product-grid { grid-template-columns: repeat(2, 1fr); }
  .step-flow { grid-template-columns: repeat(2, 1fr); }
  .news-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .hero .container { grid-template-columns: 1fr; }
  .hero-figure { order: -1; max-width: 420px; }
  .pd-hero .container { grid-template-columns: 1fr; }
  .contact-grid { grid-template-columns: 1fr; }
  .two-col { grid-template-columns: 1fr; }
  .card-list { grid-template-columns: 1fr; }
}

/* ---- mobile nav ------------------------------------------------------
   The burger used to appear only at <=767px, but the desktop nav's
   min-content is unshrinkable (7 nowrap links) and needs ~1131px beside
   the logo and CTA. Every viewport from 768px to ~1103px therefore pushed
   the WHOLE DOCUMENT into horizontal scroll (measured: 1079px of content
   in a 900px viewport). The drawer now owns everything below 1120px,
   which covers the broken band with ~147px of slack at the seam. */
@media (max-width: 1119px) {
  .nav { position: fixed; inset: var(--header-h) 0 0 0; background: var(--surface); flex-direction: column;
    align-items: stretch; padding: 12px 20px; overflow-y: auto; transform: translateX(100%);
    transition: transform .2s ease; border-top: 1px solid var(--steel-line); }
  .nav.is-open { transform: translateX(0); }
  .nav > ul { flex-direction: column; width: 100%; }
  .nav a.nav-link { height: auto; padding: 14px 4px; border-bottom: 1px solid var(--steel-line); }
  .nav .dropdown { position: static; opacity: 1; visibility: visible; transform: none; box-shadow: none; border: none; min-width: 0; padding: 0 0 0 12px; display: none; }
  .nav .has-dropdown.is-open .dropdown { display: block; }
  .burger { display: block; }
}
/* main.js only wires the tap-to-expand dropdown handler under 767px, so in
   the 768–1119px band the drawer's submenu items would be unreachable.
   Keep them expanded there until that breakpoint is reconciled in JS. */
@media (min-width: 768px) and (max-width: 1119px) {
  .nav .dropdown { display: block; }
}
/* The outline CTA is the first non-essential item in the header budget. */
@media (max-width: 1199px) {
  .header-cta .btn-outline { display: none; }
}

@media (max-width: 767px) {
  .section { padding: 44px 0; }
  .section:has(> .container > .info-block:only-child),
  .section:has(> .container > .prose:only-child),
  .section:has(> .container > .check-list:only-child) { padding: 32px 0; }
  .topbar .topbar-links span.hide-mobile { display: none; }
  .trust-grid { grid-template-columns: 1fr 1fr; }
  .product-grid { grid-template-columns: 1fr; }
  .step-flow { grid-template-columns: 1fr; }
  .news-grid { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr; gap: 32px; }
  .inquiry-grid { grid-template-columns: 1fr; }
  .media-grid { grid-template-columns: repeat(2, 1fr); }
  .sticky-cta .container { flex-direction: column; align-items: stretch; text-align: center; }
  h1 { font-size: 2rem; }
}

/* ============================================================
   PHOTO-FIRST LAYER (2026-07-17) — layout rebuilt around real
   brochure photography (product shots, plant & workshop views),
   after the anyanghammer/hongyuan pattern. Theme stays Drafting
   Daylight blue; photos ride on the same tokens.
   ============================================================ */

/* --- full-bleed photo hero with crossfade slides --- */
.hero-photo {
  position: relative; overflow: hidden;
  min-height: clamp(380px, 52vw, 540px);
  display: flex; align-items: center;
  border-bottom: 1px solid var(--steel-line);
  background: var(--steel);
}
.hero-photo .hero-slides { position: absolute; inset: 0; }
.hero-photo .hero-slide {
  position: absolute; inset: 0; opacity: 0; transition: opacity .9s ease;
  background-size: cover; background-position: center;
}
.hero-photo .hero-slide.is-active { opacity: 1; }
/* scrim: steel-blue left-to-right so white copy always clears 4.5:1 */
.hero-photo::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(13,28,42,.82) 0%, rgba(13,28,42,.55) 46%, rgba(13,28,42,.18) 100%);
}
.hero-photo .container { position: relative; z-index: 2; padding-top: 64px; padding-bottom: 64px; }
.hero-photo .hero-copy { max-width: 60ch; }
.hero-photo h1 { color: #fff; }
.hero-photo h1 em { font-style: normal; color: #7ab6e8; }
.hero-photo .hero-sub { color: #d6e2ec; }
.hero-photo .dim-label { color: #7ab6e8; }
.hero-photo .dim-label::before, .hero-photo .dim-label::after { border-color: #7ab6e8; }
.hero-dots { position: absolute; z-index: 3; left: 0; right: 0; bottom: 14px; display: flex; gap: 8px; justify-content: center; }
.hero-dots button {
  width: 26px; height: 4px; border: 0; border-radius: 2px; cursor: pointer;
  background: rgba(255,255,255,.38); padding: 0;
}
.hero-dots button.is-active { background: #fff; }
@media (prefers-reduced-motion: reduce) { .hero-photo .hero-slide { transition: none; } }

/* --- photo slots in cards (product/news) --- */
.photo-figure {
  display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: var(--radius); border: 1px solid var(--steel-line);
  background: #f3f6f9;
}
.photo-figure--wide { aspect-ratio: 16 / 9; }
.product-card .photo-figure { border: 0; border-bottom: 1px solid var(--steel-line); border-radius: var(--radius) var(--radius) 0 0; }
/* photo placeholder = the existing drafting sheet, sized like a photo */
.placeholder.ph-photo { aspect-ratio: 4 / 3; min-height: 0; }

/* --- product page: split photo hero --- */
.photo-split { display: grid; grid-template-columns: 1.05fr .95fr; gap: 40px; align-items: center; }
.photo-split .photo-figure, .photo-split .placeholder.ph-photo { aspect-ratio: 4 / 3; }
@media (max-width: 1023px) { .photo-split { grid-template-columns: 1fr; } }

/* --- gallery strip (product pages) --- */
.gallery-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.gallery-strip .photo-figure, .gallery-strip .placeholder.ph-photo { aspect-ratio: 1 / 1; }
@media (max-width: 767px) { .gallery-strip { grid-template-columns: repeat(2, 1fr); } }

/* --- captioned product photo cards (steel-wheels page: model under each photo) --- */
.photo-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 14px; }
.photo-card { margin: 0; border: 1px solid var(--steel-line); border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.photo-card .photo-figure { border: 0; border-radius: 0; aspect-ratio: 1 / 1; }
.photo-card figcaption { padding: 10px 12px 11px; border-top: 1px solid var(--steel-line); }
.photo-card .cap-model { display: block; font-family: var(--font-mono); font-size: .84rem; letter-spacing: .04em; color: var(--ink); }
.photo-card .cap-desc { display: block; font-size: .76rem; color: var(--ink-muted); margin-top: 3px; line-height: 1.45; }
@media (max-width: 767px) { .photo-card-grid { grid-template-columns: repeat(2, 1fr); } }

/* --- spec bullet list (product sub-sections) --- */
.spec-bullets { list-style: none; padding: 0; margin: 18px 0 0; display: grid; gap: 8px;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.spec-bullets li { position: relative; padding-left: 18px; font-size: .92rem; color: var(--ink-muted); line-height: 1.6; }
.spec-bullets li::before { content: ""; position: absolute; left: 0; top: .62em;
  width: 7px; height: 1px; background: var(--safety); }

/* --- factory / workshop band --- */
.factory-strip { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.factory-item { position: relative; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--steel-line); }
.factory-item .photo-figure { border: 0; border-radius: 0; aspect-ratio: 3 / 2; }
.factory-item figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: linear-gradient(transparent, rgba(13,28,42,.86));
  color: #fff; font-family: var(--font-mono); font-size: .78rem; letter-spacing: .05em;
  padding: 26px 12px 10px;
}
@media (max-width: 767px) { .factory-strip { grid-template-columns: 1fr; } }

/* --- wide plant banner (about / section divider) --- */
.plant-banner { position: relative; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--steel-line); }
.plant-banner img { display: block; width: 100%; aspect-ratio: 21 / 9; object-fit: cover; }
.plant-banner .plant-caption {
  position: absolute; left: 0; bottom: 0; right: 0;
  background: linear-gradient(transparent, rgba(13,28,42,.85));
  color: #fff; padding: 34px 18px 12px; font-family: var(--font-mono); font-size: .8rem; letter-spacing: .05em;
}

/* ============================================================
   DATA-DRIVEN WHEEL CATALOGUE + PRODUCT DETAIL
   Compact catalogue cards disclose the full gallery/specification
   only after the visitor opens a product detail URL.
   ============================================================ */
.wheel-catalog-toolbar {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  margin-bottom: 26px; padding-bottom: 16px; border-bottom: 1px solid var(--steel-line);
}
.wheel-catalog-filters { display: flex; flex-wrap: wrap; gap: 8px; }
.wheel-filter {
  appearance: none; border: 1px solid var(--steel-line); background: var(--surface);
  color: var(--ink-muted); padding: 8px 13px; font-family: var(--font-mono);
  font-size: var(--label-md); letter-spacing: .03em; cursor: pointer;
}
.wheel-filter:hover { border-color: var(--safety); color: var(--safety); }
.wheel-filter.is-active {
  background: var(--safety-fill); border-color: var(--safety-fill); color: #fff;
}
.wheel-catalog-count {
  flex: 0 0 auto; font-family: var(--font-mono); font-size: var(--label-md);
  color: var(--ink-faint); text-transform: uppercase; letter-spacing: .05em;
}
.wheel-catalog-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px;
}
.wheel-card {
  min-width: 0; display: flex; flex-direction: column; background: var(--surface);
  border: 1px solid var(--steel-line); color: var(--ink); overflow: hidden;
  box-shadow: var(--shadow-card); transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.wheel-card:hover, .wheel-card:focus-visible {
  color: var(--ink); border-color: var(--safety); box-shadow: var(--shadow-lift); transform: translateY(-3px);
}
.wheel-card-media { position: relative; overflow: hidden; background: var(--surface-2); }
.wheel-card-image {
  display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  transition: transform .28s ease;
}
.wheel-card:hover .wheel-card-image { transform: scale(1.025); }
.wheel-card-category {
  position: absolute; left: 10px; bottom: 10px; max-width: calc(100% - 20px);
  padding: 5px 8px; background: rgba(11,24,38,.88); color: #fff;
  font-family: var(--font-mono); font-size: var(--label-sm); text-transform: uppercase;
  letter-spacing: .06em; line-height: 1.2;
}
.wheel-card-body { display: flex; flex-direction: column; flex: 1; padding: 18px; }
.wheel-card-model {
  margin-bottom: 7px; color: var(--safety); font-family: var(--font-mono);
  font-size: var(--label-md); line-height: 1.45; letter-spacing: .025em;
}
.wheel-card-title { margin-bottom: 8px; font-size: 1.12rem; line-height: 1.2; }
.wheel-card-summary {
  display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  min-height: 4.2em; margin-bottom: 15px; font-size: .84rem; line-height: 1.55;
}
.wheel-card-meta {
  display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin: auto 0 14px; padding: 0;
}
.wheel-card-meta li {
  border: 1px solid var(--steel-line); background: var(--surface-2); color: var(--ink-muted);
  padding: 3px 6px; font-family: var(--font-mono); font-size: var(--label-sm); line-height: 1.35;
}
.wheel-card-action {
  display: block; padding-top: 12px; border-top: 1px solid var(--steel-line);
  color: var(--safety); font-family: var(--font-mono); font-size: var(--label-lg); font-weight: 700;
}
.wheel-card-action::after { content: "  →"; }
.wheel-card--related .wheel-card-title { font-size: 1rem; }
.wheel-card--related .wheel-card-image { aspect-ratio: 16 / 10; }

.wheel-catalog-loading, .wheel-catalog-error {
  min-height: 150px; display: grid; place-items: center; border: 1px dashed var(--steel-line);
  background: var(--surface-2); color: var(--ink-muted); font-family: var(--font-mono);
  font-size: .84rem; text-align: center; padding: 24px;
}
.wheel-catalog-error { border-color: var(--safety-line); background: var(--safety-tint); color: var(--safety-ink); }
.wheel-catalog-note {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 28px;
  padding: 28px; background: var(--steel); border-left: 3px solid var(--safety); color: #b9c8d6;
}
.wheel-catalog-note h2 { color: #fff; margin-bottom: 8px; }
.wheel-catalog-note p { color: #b9c8d6; max-width: 78ch; }
.technical-backbar { background: var(--safety-tint); border-bottom: 1px solid var(--safety-line); }
.technical-backbar .container { padding-block: 10px; font-family: var(--font-mono); font-size: .78rem; }

.wheel-detail-hero { padding-top: 48px; }
.wheel-detail-layout {
  display: grid; grid-template-columns: minmax(0, 1.08fr) minmax(340px, .92fr);
  gap: clamp(32px, 5vw, 64px); align-items: start;
}
.wheel-detail-main { margin: 0; border: 1px solid var(--steel-line); background: var(--surface); }
.wheel-detail-main img {
  display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover; background: var(--surface-2);
}
.wheel-detail-main figcaption {
  padding: 10px 13px; border-top: 1px solid var(--steel-line); color: var(--ink-muted);
  font-family: var(--font-mono); font-size: var(--label-md);
}
.wheel-detail-thumbs { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; margin-top: 10px; }
.wheel-detail-thumb {
  appearance: none; border: 2px solid transparent; background: var(--surface-2); padding: 0;
  cursor: pointer; opacity: .68;
}
.wheel-detail-thumb:hover { opacity: 1; }
.wheel-detail-thumb.is-active { border-color: var(--safety); opacity: 1; }
.wheel-detail-thumb img { display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
.wheel-detail-model {
  margin: 15px 0 8px; color: var(--safety); font-family: var(--font-mono);
  font-size: .84rem; font-weight: 700; letter-spacing: .04em;
}
.wheel-detail-summary h1 { margin-bottom: 14px; }
.wheel-detail-lead { font-size: 1rem; max-width: 58ch; }
.wheel-detail-facts-title {
  margin: 28px 0 12px; font-size: .82rem; font-family: var(--font-mono);
  letter-spacing: .08em; color: var(--ink-muted);
}
.wheel-detail-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--steel-line); margin: 0; border: 1px solid var(--steel-line); }
.wheel-detail-fact { min-width: 0; background: var(--surface); padding: 12px 13px; }
.wheel-detail-fact dt {
  color: var(--ink-faint); font-family: var(--font-mono); font-size: var(--label-sm);
  text-transform: uppercase; letter-spacing: .05em;
}
.wheel-detail-fact dd { margin: 3px 0 0; color: var(--ink); font-weight: 700; line-height: 1.4; }
.wheel-detail-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 24px; }
.wheel-detail-content { display: grid; grid-template-columns: 1.2fr .8fr; gap: 24px; }
.wheel-detail-panel { border: 1px solid var(--steel-line); background: var(--surface); padding: 24px; }
.wheel-detail-panel h2 { font-size: 1.25rem; }
.wheel-detail-list { list-style: none; margin: 0; padding: 0; }
.wheel-detail-list li {
  position: relative; padding: 10px 0 10px 20px; border-top: 1px solid var(--steel-line);
  color: var(--ink-muted); font-size: .92rem;
}
.wheel-detail-list li::before { content: "—"; position: absolute; left: 0; color: var(--safety); }
.wheel-variant-section { border-bottom: 1px solid var(--steel-line); }
.wheel-variant-table table { min-width: 1120px; }
.wheel-config-select {
  appearance: none; border: 1px solid var(--safety); background: transparent; color: var(--safety);
  padding: 7px 10px; white-space: nowrap; cursor: pointer; font: 700 .72rem/1 var(--font-body);
}
.wheel-config-select:hover, .wheel-config-select:focus-visible { background: var(--safety); color: #fff; outline: none; }
.wheel-quote-column { white-space: nowrap; }
.wheel-procurement-section { border-bottom: 1px solid var(--steel-line); }
.wheel-procurement-grid { display: grid; grid-template-columns: minmax(0, 1.18fr) minmax(300px, .82fr); gap: 24px; }
.wheel-procurement-panel { border: 1px solid var(--steel-line); background: var(--surface); padding: 24px; }
.wheel-procurement-panel h3 { margin-bottom: 16px; font-size: 1.18rem; }
.wheel-procurement-panel--action { border-top: 3px solid var(--safety); }
.wheel-procurement-specs { margin: 0; }
.wheel-procurement-spec {
  display: grid; grid-template-columns: minmax(130px, .38fr) minmax(0, .62fr); gap: 18px;
  padding: 12px 0; border-top: 1px solid var(--steel-line);
}
.wheel-procurement-spec:first-child { border-top: none; padding-top: 0; }
.wheel-procurement-spec dt {
  color: var(--ink-faint); font-family: var(--font-mono); font-size: var(--label-sm);
  text-transform: uppercase; letter-spacing: .05em;
}
.wheel-procurement-spec dd { margin: 0; color: var(--ink); font-weight: 700; line-height: 1.45; }
.wheel-procurement-link { display: inline-block; margin-top: 16px; font-weight: 700; }
.wheel-procurement-intro { margin-bottom: 12px; color: var(--ink-muted); font-size: .9rem; }
.wheel-order-checks { list-style: none; margin: 0 0 22px; padding: 0; }
.wheel-order-checks li { position: relative; padding: 9px 0 9px 20px; border-top: 1px solid var(--steel-line); color: var(--ink-muted); }
.wheel-order-checks li::before { content: "✓"; position: absolute; left: 0; color: var(--safety); font-weight: 800; }
.field input[readonly] { background: var(--surface-2); color: var(--ink-muted); cursor: default; }
.wheel-related-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.wheel-not-found .container { max-width: 760px; }
.wheel-not-found p { max-width: 60ch; margin-bottom: 24px; }

@media (max-width: 1199px) {
  .wheel-catalog-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 899px) {
  .wheel-catalog-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .wheel-detail-layout { grid-template-columns: 1fr; }
  .wheel-detail-gallery { max-width: 700px; }
  .wheel-detail-content { grid-template-columns: 1fr; }
  .wheel-procurement-grid { grid-template-columns: 1fr; }
}
@media (max-width: 767px) {
  .wheel-catalog-toolbar { align-items: flex-start; flex-direction: column; }
  .wheel-catalog-note { grid-template-columns: 1fr; }
  .wheel-detail-hero { padding-top: 32px; }
  .wheel-detail-actions .btn { width: 100%; }
  .wheel-related-grid { grid-template-columns: 1fr; }
}
@media (max-width: 579px) {
  .wheel-catalog-grid { grid-template-columns: 1fr; }
  .wheel-card-summary { min-height: 0; }
  .wheel-detail-facts { grid-template-columns: 1fr; }
  .wheel-detail-thumbs { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .wheel-procurement-spec { grid-template-columns: 1fr; gap: 4px; }
}
@media (prefers-reduced-motion: reduce) {
  .wheel-card, .wheel-card-image { transition: none; }
  .wheel-card:hover, .wheel-card:focus-visible { transform: none; }
  .wheel-card:hover .wheel-card-image { transform: none; }
}

/* ============================================================
   P2 PROPORTION & RHYTHM PASS — 2026-07-25
   One readable measure across page families; media, cards and
   tables stay subordinate to the product and section titles.
   ============================================================ */
.section-head {
  max-width: 760px;
  margin-bottom: clamp(28px, 3vw, 38px);
}
.section-head > p { max-width: 68ch; }

.pd-hero { padding-block: clamp(36px, 5vw, 56px); }
.pd-hero .container {
  grid-template-columns: minmax(0, 1.04fr) minmax(360px, .96fr);
  gap: clamp(32px, 5vw, 64px);
}
.pd-hero .photo-figure,
.photo-split .photo-figure,
.photo-split .placeholder.ph-photo { aspect-ratio: 16 / 10; }
.pd-title { font-size: clamp(2rem, 3.8vw, 3.25rem); }
.pd-lead { font-size: clamp(.98rem, 1.2vw, 1.08rem); line-height: 1.7; }

.product-grid,
.card-list,
.news-grid { align-items: stretch; }
.product-card,
.simple-card,
.news-card { height: 100%; }
.card-list {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}
.simple-card { padding: clamp(20px, 2.5vw, 28px); }
.simple-card h3 { flex-wrap: wrap; }

.gallery-strip { gap: clamp(10px, 1.5vw, 16px); }
.gallery-strip .photo-figure,
.gallery-strip .placeholder.ph-photo { aspect-ratio: 4 / 3; }
.factory-strip { gap: clamp(12px, 2vw, 20px); }

.info-block { padding: clamp(20px, 2.5vw, 28px); }
.two-col { gap: clamp(18px, 2.5vw, 28px); align-items: stretch; }
.two-col > * { min-width: 0; }

table.spec-table th,
table.spec-table td { padding: 11px 14px; line-height: 1.45; }
.spec-table-wrap { scrollbar-gutter: stable; }

.certificate-scan-label { margin: 36px 0 16px; }
.certificate-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}
.certificate-placeholder {
  aspect-ratio: 4 / 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 20px;
  text-align: center;
  border: 1px dashed var(--steel-line);
  background:
    linear-gradient(135deg, transparent 49.7%, var(--steel-line) 50%, transparent 50.3%),
    var(--surface-2);
}
.certificate-placeholder strong {
  color: var(--ink);
  font-size: .88rem;
  line-height: 1.4;
}
.certificate-placeholder span {
  color: var(--ink-faint);
  font-family: var(--font-mono);
  font-size: var(--label-sm);
  letter-spacing: .06em;
  text-transform: uppercase;
}
.certificate-scan {
  margin: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--steel-line);
  background: var(--surface-2);
}
.certificate-scan a { display: block; line-height: 0; }
.certificate-scan img { width: 100%; height: auto; display: block; }
.certificate-scan figcaption {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px 12px;
}
.certificate-scan figcaption strong {
  color: var(--ink);
  font-size: .85rem;
  line-height: 1.4;
}
.certificate-scan figcaption span {
  color: var(--ink-faint);
  font-size: .78rem;
  line-height: 1.45;
}

@media (max-width: 1023px) {
  .pd-hero .container { grid-template-columns: 1fr; }
  .pd-hero .pd-copy { max-width: 760px; }
  .certificate-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 767px) {
  .container { padding-inline: 18px; }
  .page-hero { padding-block: 36px; }
  .pd-hero { padding-block: 32px; }
  .pd-hero .container { gap: 26px; }
  .pd-title { font-size: clamp(1.85rem, 9vw, 2.4rem); }
  .section-head { margin-bottom: 26px; }
  .photo-card-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
  .photo-card figcaption { padding: 9px 10px 10px; }
}
@media (max-width: 479px) {
  .certificate-grid { grid-template-columns: 1fr; }
  .certificate-placeholder { aspect-ratio: 16 / 9; }
  .photo-card-grid { grid-template-columns: 1fr; }
}
