
  :root{
    --bg:#F7F7F7; --white:#FFFFFF; --black:#000000; --gray:#6F6F6F;
    --line:#E4E4E4; --accent:#C9A227; /* brand accent: champagne gold (可替换为橙色 #FF7D00 或玫瑰金) */
    --dark:#1C1C1C;
  }
  *{margin:0;padding:0;box-sizing:border-box}
  html{scroll-behavior:smooth}
  body{background:var(--bg);color:var(--black);font-family:'Josefin Sans',Arial,sans-serif;overflow-x:hidden}
  a{color:inherit;text-decoration:none}
  /* height:auto keeps the aspect ratio when max-width shrinks an image. Without
     it the intrinsic height="..." attribute stays at its pixel value and a
     1600x900 photo constrained to 1190px renders 1190x900 -- squashed. Every
     other image rule here sets both axes, so this only affects images relying
     on this base rule. */
  img{max-width:100%;height:auto;display:block}
  .wrap{max-width:1240px;margin:0 auto;padding:0 24px}
  /* ---------- top promo marquee ---------- */
  .promo{background:var(--black);color:#fff;font-size:12.5px;letter-spacing:.14em;text-transform:uppercase;padding:8px 16px;text-align:center;overflow:hidden;white-space:nowrap}
   .promo span{display:inline-block;animation:slide 26s linear infinite}
   @keyframes slide{0%{transform:translateX(100%)}100%{transform:translateX(-100%)}}
   /* Wide screens: the line is short enough to slide in and out. Phones: the same line wraps
      to two or three lines, and the marquee leaves the bar empty for seconds at a time --
      while the bar carries the MOQ, the first thing a wholesale buyer needs. Wrap it, align
      it left, and leave it still. */
   @media (max-width: 860px){
     .promo{white-space:normal;overflow:visible;text-transform:none;letter-spacing:.02em;font-size:10.5px;line-height:1.5;padding:8px 14px;text-align:left}
     .promo span{animation:none;transform:none;display:block;white-space:normal}
   }
  /* ---------- nav ---------- */
  nav.main{position:sticky;top:0;z-index:50;background:var(--bg);border-bottom:1px solid var(--line)}
  .navrow{display:flex;align-items:center;gap:18px;height:56px}
  .logo-s{height:42px;width:auto;display:block;background:#fff;padding:4px 8px;box-sizing:content-box}
  .menu{display:flex;gap:22px;margin-left:auto;align-items:center;list-style:none;font-size:16px;letter-spacing:.05em;text-transform:uppercase;font-weight:600}
   /* Same treatment as pdp-shared.css so the nav behaves the same on every page.
      This replaces an instant black underline; the transparent border stays to
      reserve the 2px so the row does not move. */
   .menu a{position:relative;padding:4px 0;border-bottom:2px solid transparent;white-space:nowrap}
   .navrow .btn{white-space:nowrap}
   /* nav-cta:start */
/* The quote button, 40px like the icon beside it. height works from CSS because the
   inline style does not declare it; padding/font-size/border do NOT, which is why the
   edge is an inset ring rather than a border. Scoped to .nav-actions so the card
   buttons that share .btn on the homepage are untouched. */
.navrow .nav-actions .btn{display:flex;align-items:center;justify-content:center;
  height:40px;background:#6B3FA0;color:#fff;box-shadow:inset 0 0 0 1px #6B3FA0;
  transition:background-color .2s,color .2s,box-shadow .2s}
.navrow .nav-actions .btn:hover,.navrow .nav-actions .btn:focus-visible{
  background:#fff;color:#6B3FA0}

/* One width for both controls, so the pair reads as a unit. 161px is the QUOTE label's
   own natural size at 11px / .14em with its inline 16px padding - i.e. nothing about
   the button that was just approved changes; the WhatsApp button is given that width
   rather than the quote button being squeezed down to a WhatsApp-sized box.
   min-width is deliberately left at `auto`: if a fallback font ever makes the quote
   label wider than 161px, its button grows to fit and the two stop matching - visibly
   wrong, and the suite fails on it, instead of the label painting outside its box. */
.navrow .nav-actions>*{flex:0 0 161px}

/* WhatsApp, as the same button in WhatsApp's own colours. The mark keeps its 24px and
   the word takes the quote label's type treatment, so the two line up letter for letter.
   The anchor is display:flex because .icon-btn is a grid, which would stack the mark
   above the word in two rows. */
.navrow .nav-actions .icon-btn.wa{display:flex;align-items:center;justify-content:center;gap:7px}
.navrow .nav-actions .icon-btn.wa svg{flex:0 0 auto}
.navrow .nav-actions .wa-label{color:#fff;font-size:11px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;white-space:nowrap;transition:color .2s}
.navrow .nav-actions .icon-btn.wa:hover .wa-label,
.navrow .nav-actions .icon-btn.wa:focus-visible .wa-label{color:#25D366}

/* 6px off each of the row's two gaps pays for most of the wider cluster, and is the
   smallest change that does: measured, the row has 116px of free space at >=1241px and
   the pair needs 121px more than the icon+button it replaces. */
.navrow{gap:12px}

/* Below 1121px the menu is already at its smallest step and there is no longer room for
   two full-width buttons beside the logo, so WhatsApp falls back to the 40px square it
   was, and the pair keeps its old footprint. Measured: at 1120px the labelled cluster
   needs 121px more than the row has; at 1121px it fits. */
@media(max-width:1120px){
  .navrow .nav-actions>*{flex:0 0 auto}
  .navrow .nav-actions .wa-label{display:none}
}
/* nav-cta:end */
   .menu a::after{content:"";position:absolute;left:0;right:0;bottom:-2px;height:2px;background:var(--accent);transform:scaleX(0);transform-origin:left}
   .menu a:hover::after{transform:scaleX(1)}
   @media(min-width:1000px) and (prefers-reduced-motion: no-preference){
   .menu a::after{transition:transform .28s cubic-bezier(.2,.7,.2,1)}
   }
   @media(max-width:999px){.menu a::after{display:none}}
  .menu .hot a{color:var(--accent);border-color:transparent}
  .nav-actions{display:flex;align-items:center;gap:12px;margin-left:auto}
  .icon-btn{width:34px;height:34px;display:grid;place-items:center;border:1px solid var(--line);background:#fff;cursor:pointer}
  .burger{display:none;flex-direction:column;gap:4px;background:none;border:0;cursor:pointer;padding:6px}
  .burger i{width:22px;height:2px;background:var(--black)}
  /* ---------- utility bar ---------- */
  .util{background:var(--white);border-bottom:1px solid var(--line)}
  .utilrow{display:flex;align-items:center;gap:20px;min-height:84px}
  .slogan{font-size:12px;color:var(--gray);letter-spacing:.06em;line-height:1.5;max-width:210px;text-transform:uppercase}
  .logo-big{height:84px;width:auto;display:block;margin:0 auto;flex-shrink:0;background:#fff;padding:8px 16px;box-sizing:content-box}
  .util-right{display:flex;align-items:center;gap:14px;margin-left:auto}
  .quick{font-size:12.5px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;display:flex;align-items:center;gap:6px;color:var(--gray)}
  .quick b{color:var(--black)}
  /* Social profiles, in the space the three non-clickable .quick labels used to
     occupy. Four 26px buttons are far narrower than those labels were, so this
     buys room instead of spending it -- the nav row above is full to the pixel
     (its content box measures 1192.00 against 1192 available) and could not
     have taken them. The brand glyphs are Simple Icons paths (CC0), inlined so
     the page keeps no third-party request. */
  /* Brand colours rather than the site's monochrome: at this size they are meant
     to be spotted at a glance. Each hex is the brand's own, read from Simple
     Icons' data file rather than recalled (#0866FF, #0A66C2, #FF0069, #FF0000).
     The colour lives on the path, so the CSS must not set fill on the svg.
     The glyph sits in the same bordered square as the WhatsApp button so the
     two read as one set. */
  .soc{display:flex;align-items:center;gap:8px}
  .soc a{width:36px;height:36px;display:grid;place-items:center;border:1px solid var(--line);background:#fff;
    transition:border-color .2s,box-shadow .2s}
  .soc a:hover,.soc a:focus-visible{border-color:#b4b4b4;box-shadow:0 2px 10px rgba(0,0,0,.10)}
  .soc svg{width:19px;height:19px;display:block}
  .btn{display:inline-block;background:var(--black);color:#fff;font-size:13px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;padding:14px 28px;border:1px solid var(--black);border-radius:0;cursor:pointer;transition:.2s}
  .btn:hover{background:#fff;color:#000}
  .btn.gold{background:var(--accent);border-color:var(--accent)}
  /* ---------- hero carousel ----------
     Three stacked banners A/B/C, scrolled by the browser itself: a scroll-snap
     track needs no library, works before JS loads, and keeps the dots as real
     links so a keyboard or a crawler can reach every slide. */
  .hero-carousel{position:relative;background:var(--bg);border-bottom:1px solid var(--line)}
  .hc-track{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;
    -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;scrollbar-width:none}
  .hc-track::-webkit-scrollbar{display:none}
  .hc-slide{flex:0 0 100%;scroll-snap-align:center;scroll-snap-stop:always;line-height:0}
  .hc-slide img{width:100%;height:auto;aspect-ratio:1920/650;object-fit:cover;display:block}
  .hc-dots{position:absolute;left:0;right:0;bottom:14px;display:flex;gap:10px;
    justify-content:center;pointer-events:none}
   /* A short, tall bar (25x10) reads as a marker rather than a full-width rule,
      and the active one is easier to spot on the dark artwork. */
   .hc-dots a{pointer-events:auto;width:25px;height:10px;background:rgba(0,0,0,.22);
     transition:background .25s;display:block}
  .hc-dots a:hover,.hc-dots a.on{background:var(--accent)}
  .hc-arrow{position:absolute;top:50%;transform:translateY(-50%);width:44px;height:44px;
    display:grid;place-items:center;background:rgba(255,255,255,.78);border:1px solid var(--line);
    color:var(--black);font-size:20px;line-height:1;cursor:pointer;z-index:3;transition:.2s}
  .hc-arrow:hover{background:#fff}
  .hc-arrow[hidden]{display:none}
  .hc-prev{left:16px}
  .hc-next{right:16px}
  /* ---------- hero copy ----------
     The banners carry their message as pixels, which a crawler cannot read. The
     H1, the opening paragraph and the certificate numbers therefore stay here as
     real text directly under the carousel, never as an image. */
  .hero-intro{background:var(--bg)}
  .hi-row{display:grid;grid-template-columns:1.05fr .95fr;align-items:start;gap:36px;
    padding:46px 24px 54px}
  .hi-row .kicker{margin-bottom:10px}
  .hero-intro h1{font-size:clamp(32px,4.6vw,60px);font-weight:700;text-transform:uppercase;
    line-height:1;letter-spacing:.02em}
  .hero-intro h1 .thin{font-weight:300}
  .hero-intro p.sub{margin:18px 0 0;font-size:15.5px;line-height:1.75;color:#3c3c3c;max-width:560px}
  .hi-side{display:flex;flex-direction:column;align-items:flex-start;gap:22px;padding-top:4px}
  .hero-intro .ctas{display:flex;gap:14px;flex-wrap:wrap}
  .hero-note{font-size:12px;color:var(--gray);letter-spacing:.05em;text-transform:uppercase;line-height:1.9}
  /* ---------- generic section ---------- */
  section{padding:64px 0}
  .kicker{font-size:12px;letter-spacing:.3em;text-transform:uppercase;color:var(--accent);font-weight:600}
  h2.sec{font-size:clamp(28px,3.6vw,46px);text-transform:uppercase;font-weight:700;letter-spacing:.04em;margin:10px 0 6px}
  .slash{display:inline-block;width:34px;height:2px;background:var(--black);transform:rotate(-45deg);margin:4px 0 24px}
  .lead{font-size:15px;color:var(--gray);line-height:1.8;max-width:760px;margin-bottom:28px}
  /* ---------- factory ---------- */
  .factory{background:#fff;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
  .frow{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:center}
  .fstats{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-top:30px;align-items:stretch}
  .fstat{display:flex;flex-direction:column;justify-content:center;border-left:2px solid var(--black);padding:10px 0 10px 18px;min-height:74px}
  .fstat b{font-size:26px;line-height:1;letter-spacing:.02em;display:block;font-weight:700;white-space:nowrap}
  .fstat span{font-size:11.5px;color:var(--gray);text-transform:uppercase;letter-spacing:.14em;margin-top:12px;line-height:1.4}
  .photos{display:grid;grid-template-columns:1.4fr 1fr;gap:12px}
  .photos .p2{display:grid;gap:12px}
  .ph{background:linear-gradient(135deg,#ECECEC,#DADADA);border:1px solid var(--line);display:grid;place-items:center;color:#9a9a9a;font-size:12px;letter-spacing:.2em;text-transform:uppercase;min-height:130px}
  .ph.big{min-height:280px}
  /* ---------- certs strip ---------- */
  .certs{border-bottom:1px solid var(--line)}
  .certbar{display:flex;gap:10px;flex-wrap:wrap;align-items:center;justify-content:center}
  .chip{border:1px solid var(--line);background:#fff;padding:10px 18px;font-size:12px;font-weight:600;letter-spacing:.14em;text-transform:uppercase}
  .chip.hl{border-color:var(--accent);color:var(--accent)}
  /* ---------- why us ---------- */
  .why-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
  .why{border:1px solid var(--line);background:#fff;padding:26px 22px}
  .why .n{font-size:11px;letter-spacing:.3em;color:var(--accent);font-weight:700}
  .why h3{margin:12px 0 8px;font-size:16.5px;text-transform:uppercase;letter-spacing:.05em}
  .why p{font-size:13.5px;color:var(--gray);line-height:1.7}
  /* ---------- product grids ---------- */
  .prod-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
  .card{border:1px solid var(--line);background:#fff;display:flex;flex-direction:column}
  .card .img{aspect-ratio:1/1;background:#fff;display:grid;place-items:center;border-bottom:1px solid var(--line);position:relative;overflow:hidden}
  .card .img img{width:100%;height:100%;object-fit:cover;display:block}
  .tag{position:absolute;top:10px;left:10px;background:var(--black);color:#fff;font-size:10px;letter-spacing:.14em;padding:4px 8px;text-transform:uppercase}
  .tag.goldtag{background:var(--accent)}
  .card .body{padding:14px 14px 18px;display:flex;flex-direction:column;gap:6px;flex:1}
  .card h4{font-size:13.5px;text-transform:uppercase;letter-spacing:.04em;font-weight:600;line-height:1.4;min-height:56px}
  .meta{font-size:11px;color:var(--gray);letter-spacing:.06em;display:flex;justify-content:space-between;text-transform:uppercase}
  .price{font-size:15px;font-weight:700}
   .card .btn{padding:11px 14px;font-size:11.5px;width:100%;text-align:center;margin-top:auto}
   /* ---------- hover dynamics (homepage product / category cards) ----------
      Hovering the card -- the product photo included -- wakes the card and its
      CTA: the frame lifts on a soft shadow, the photo zooms inside its frame,
      and a champagne rule sweeps across the base of the button while the button
      picks up its own shadow. Geometry and colour change for everyone; only the
      movement is gated behind prefers-reduced-motion, so a reader who has asked
      for less motion still gets the underline and the shadow, just instantly.
      The button is not translated: the card's own lift already carries it, and
      not moving it keeps the pointer from slipping off its edge. */
   .card{transition:border-color .25s ease,box-shadow .3s ease}
   .card .btn{position:relative;overflow:hidden}
   .card .btn::after{content:"";position:absolute;left:0;right:0;bottom:0;height:3px;
     background:var(--accent);transform:scaleX(0);transform-origin:left center}
   .card:hover{border-color:#b4b4b4;box-shadow:0 12px 34px rgba(0,0,0,.09)}
   .card:hover .btn{box-shadow:0 8px 20px rgba(0,0,0,.16)}
   .card:hover .btn::after{transform:scaleX(1)}
   @media (prefers-reduced-motion: no-preference){
     .card{transition:border-color .25s ease,box-shadow .3s ease,
       transform .3s cubic-bezier(.2,.7,.2,1)}
     .card .img img{transition:transform .55s cubic-bezier(.2,.7,.2,1)}
     .card .btn{transition:transform .28s cubic-bezier(.2,.7,.2,1),box-shadow .28s ease,
       background .2s,color .2s,border-color .2s}
     .card .btn::after{transition:transform .4s cubic-bezier(.2,.7,.2,1)}
     .card:hover{transform:translateY(-4px)}
     .card:hover .img img{transform:scale(1.06)}
   }
   /* ---------- end hover dynamics ---------- */
   .small-c{font-size:12px;color:var(--gray);margin-top:20px;text-align:center;letter-spacing:.08em;text-transform:uppercase}
  /* ---------- custom band ---------- */
  .customband{background:var(--black);color:#fff}
  .customrow{display:grid;grid-template-columns:1.2fr 1fr;gap:48px;align-items:center}
  .customrow h2.sec{color:#fff}
  .customrow .slash{background:var(--accent)}
  .steps{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-top:30px;counter-reset:s}
  .step{counter-increment:s;border:1px solid #3a3a3a;padding:16px 12px;text-align:center}
  .step:before{content:"0" counter(s);display:block;font-size:20px;font-weight:700;color:var(--accent);margin-bottom:6px}
  .step span{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:#cfcfcf;line-height:1.6;display:block}
  /* ---------- clients / blog ---------- */
  .clients{display:flex;flex-wrap:wrap;gap:18px;align-items:center;justify-content:center}
  .clients .cname{font-size:18px;letter-spacing:.24em;font-weight:700;text-transform:uppercase;color:#b9b9b9}
  .clients .cname.solid{color:var(--black)}
  .blog-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
  .post{display:block;border:1px solid var(--line);background:#fff;overflow:hidden;transition:border-color .2s}
  .post:hover{border-color:#b4b4b4}
  /* Same trap as .exhi .ph: a min-height would also floor the width (150 x 16/9
   = 267px). This card is narrower than that only on very small phones, but the
   rule is the same, so the minimum comes off here too. */
.post{min-width:0}
.post .ph{aspect-ratio:16/9;min-height:0;border:0;border-bottom:1px solid var(--line)}
  .post .b{padding:16px}
  .post h3{font-size:15px;text-transform:uppercase;letter-spacing:.04em;line-height:1.45;font-weight:600}
  .post .d{font-size:11.5px;color:var(--gray);margin-top:8px;letter-spacing:.08em;text-transform:uppercase}
  /* ---------- final cta + footer ---------- */
  .ctaband{background:linear-gradient(120deg,#141414,#000);color:#fff;text-align:center}
  .ctaband h2{font-size:clamp(24px,3vw,38px);text-transform:uppercase;letter-spacing:.04em;max-width:820px;margin:0 auto 26px;line-height:1.3}
  footer{border-top:1px solid var(--line);padding:48px 0 56px;background:#fff}
  .fcols{display:grid;grid-template-columns:1.3fr 1fr 1fr 1.4fr;gap:32px}
  footer h5{font-size:12px;letter-spacing:.22em;text-transform:uppercase;margin-bottom:14px}
  footer li{list-style:none;font-size:13px;color:var(--gray);line-height:2.1}
  footer li a:hover{color:var(--black)}
  .brand-lg{height:64px;width:auto;display:inline-block;background:#fff;padding:4px 8px;box-sizing:content-box}
  .foot-note{font-size:11px;color:#a8a8a8;margin-top:20px;letter-spacing:.06em;text-transform:uppercase}
  /* ---------- responsive ---------- */
  @media(max-width:1024px){
    .why-grid{grid-template-columns:repeat(2,1fr)}
    .prod-grid{grid-template-columns:repeat(3,1fr)}
    .blog-grid{grid-template-columns:repeat(2,1fr)}
  }
  /* 8 top-level items: tighten the row on mid-size screens and hand over to the
     burger at 999px. .menu.open has to be defined here too -- it previously
     lived only inside the 560px block, so the burger did nothing between 561px
     and 860px. */
  @media(max-width:1240px){.menu{gap:18px;font-size:14px;letter-spacing:.04em}}
  @media(max-width:1120px){.menu{gap:13px;font-size:12.5px;letter-spacing:0}}
  @media(max-width:999px){
    .menu{display:none;position:absolute;top:56px;left:0;right:0;background:#fff;flex-direction:column;gap:0;border-bottom:1px solid var(--line)}
    .menu.open{display:flex}
    .menu li{width:100%;border-bottom:1px solid var(--line)}
    .menu a{display:block;padding:14px 24px;white-space:nowrap}
    .burger{display:flex;margin-left:auto}
  }
  @media(max-width:860px){
    .menu{display:none}
    .burger{display:flex;margin-left:auto}
    .logo-big{height:56px}
    .utilrow{flex-wrap:wrap;padding:12px 24px}
    .slogan{display:none}
    /* Once the utility row wraps, this holds a single child (the icon cluster),
       so space-between would leave it pinned to the left under a centred logo.
       Centre it instead. */
    .util-right{margin-left:0;width:100%;justify-content:center}
    .hi-row{grid-template-columns:1fr;gap:26px;padding:34px 24px 44px}
    /* At 2.95:1 a full-width banner is ~127px tall on a phone and its copy is
       unreadable. Narrow screens take a left-anchored crop of the artwork
       instead, which frames the copy block and drops the illustration. */
    .hc-slide img{aspect-ratio:3/2;object-position:left center}
    .hc-arrow{display:none}
    .frow{grid-template-columns:1fr;gap:28px}
    .fstats{grid-template-columns:repeat(2,1fr)}
    .customrow{grid-template-columns:1fr;gap:28px}
    .steps{grid-template-columns:repeat(2,1fr)}
    .fcols{grid-template-columns:1fr 1fr;gap:24px}
  }
  @media(max-width:560px){
    .prod-grid,.why-grid,.blog-grid{grid-template-columns:1fr}
    .steps{grid-template-columns:1fr}
    .fcols{grid-template-columns:1fr}
    .navrow{gap:10px}
    .menu{position:absolute;top:56px;left:0;right:0;background:#fff;flex-direction:column;gap:0;display:none;border-bottom:1px solid var(--line)}
    .menu.open{display:flex}
    .menu li{width:100%;border-bottom:1px solid var(--line)}
    .menu a{display:block;padding:14px 24px;white-space:nowrap}
    .card .btn{min-height:46px;display:grid;place-items:center}
    .btn{padding:16px 24px}
    section{padding:44px 0}
  }

  /* ---------- added: certification grid / flow / exhibition / brand logos ---------- */
  .cert-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
  .certi{border:1px solid var(--line);background:#fff;padding:18px 16px}
  .certi b{display:block;font-size:16px;letter-spacing:.12em;text-transform:uppercase;margin-bottom:5px}
  .certi span{font-size:11px;color:var(--gray);letter-spacing:.1em;text-transform:uppercase}
  .certi b.gold{color:var(--accent)}
  .flow-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;counter-reset:fl}
  .flow{border:1px solid var(--line);background:#fff;padding:16px 10px;text-align:center;counter-increment:fl}
  .flow:before{content:"0" counter(fl);display:block;font-size:18px;font-weight:700;color:var(--accent);margin-bottom:8px}
   .flow span{font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;line-height:1.6;display:block;font-weight:600}
   /* ---------- hover dynamics: process / feature tiles ----------
      Same family as the product cards: the tile lifts, its border takes the
      champagne accent, and the step number steps up a size. The 5-step band at
      the foot of the custom section is the one dark surface here, so it lifts
      onto a lighter fill instead of a shadow (a shadow on black is invisible).
      Only the movement is gated behind prefers-reduced-motion; the border, the
      shadow and the fill change for everyone. */
   /* Scoped through the grid containers so the rule can only ever reach a tile:
      "step" and "flow" are generic enough that a future block could reuse them
      as a plain wrapper class. */
   .flow-grid .flow,.why-grid .why,.steps .step{transition:border-color .25s ease,box-shadow .3s ease,background .25s ease}
   .flow-grid .flow:hover,.why-grid .why:hover{border-color:var(--accent);box-shadow:0 10px 26px rgba(0,0,0,.08)}
   .steps .step:hover{border-color:var(--accent);background:rgba(255,255,255,.05)}
   .why-grid .why .n{display:inline-block}
   @media (prefers-reduced-motion: no-preference){
     .flow-grid .flow,.why-grid .why,.steps .step{transition:border-color .25s ease,box-shadow .3s ease,
       background .25s ease,transform .3s cubic-bezier(.2,.7,.2,1)}
     .flow-grid .flow:before,.steps .step:before,.why-grid .why .n{transition:transform .3s cubic-bezier(.2,.7,.2,1)}
     .flow-grid .flow:hover,.why-grid .why:hover,.steps .step:hover{transform:translateY(-3px)}
     .flow-grid .flow:hover:before,.steps .step:hover:before,.why-grid .why:hover .n{transform:scale(1.15)}
   }
    /* ---------- end hover dynamics: tiles ---------- */
   /* The workshop's own 15-step graphic. It is a dense, text-heavy image: legible
      at desktop width, mush at 375px. Rather than shrink it into illegibility,
      narrow screens keep it at a readable size inside a horizontal scroller, so
      the labels can be read by panning instead of being given up on. */
   .procshot{margin:24px 0 0;border:1px solid var(--line);background:#fff}
   .procshot img{display:block;width:100%;height:auto}
   @media (max-width:860px){
     .procshot{overflow-x:auto;-webkit-overflow-scrolling:touch}
      /* width:auto meant "use the natural width", so a 1920px poster sat inside a
         327px scroller: readable, but only after panning five screens across.
         A fixed legible width bounds that. */
      .procshot img{width:1000px;max-width:none}
   }
   /* The cooperative-services graphic is its own band, so the card must not carry
      the 24px top margin that offsets it from the step tiles in the section above. */
   .coopband{background:#fff;border-bottom:1px solid var(--line)}
   .coopband .procshot{margin:0}
   .exh-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
  .exhi{border:1px solid var(--line);background:#fff}
  /* min-height:0 is deliberate. A min-height combined with an aspect-ratio also
   sets a minimum WIDTH (180px x 16/9 = 320px), which was wider than the 297px
   track a phone gives the card, so the card bled past the page margin and
   pushed the whole document 1px wide at a 360px viewport. With the minimum
   dropped the height follows the width and the card can shrink. */
.exhi{min-width:0}
.exhi .ph{aspect-ratio:16/9;min-height:0}
  .exhi .b{padding:16px}
  .exhi h3{font-size:13.5px;letter-spacing:.12em;text-transform:uppercase;font-weight:700;margin-bottom:4px}
  .exhi p{font-size:12.5px;color:var(--gray);line-height:1.6}
  @media(max-width:1024px){.flow-grid{grid-template-columns:repeat(4,1fr)}.cert-grid{grid-template-columns:repeat(3,1fr)}.exh-grid{grid-template-columns:repeat(2,1fr)}}
  @media(max-width:860px){.flow-grid{grid-template-columns:repeat(3,1fr)}.cert-grid{grid-template-columns:repeat(2,1fr)}}
  @media(max-width:560px){.flow-grid{grid-template-columns:repeat(2,1fr)}.cert-grid{grid-template-columns:1fr}.exh-grid{grid-template-columns:1fr}}

  .ph{overflow:hidden}
  .ph img{width:100%;height:100%;object-fit:cover;display:block}
  .certimgs{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:16px}
   /* min-height:150 also floors the WIDTH at 150 x 16/9 = 267px, which is wider
      than the ~255px column at a 570px viewport, so the second bench photo was
      being clipped by body{overflow-x:hidden} rather than scrolling. Same trap as
      .post .ph and .exhi .ph above; same fix. */
   .certimgs .ph{aspect-ratio:16/9;min-height:0;border:1px solid var(--line)}
   /* ---------- hover dynamics: certification grid + bench photos ----------
      Same answer as the process tiles: a champagne edge and a small lift, with the
      photo zooming inside its frame. These are static labels rather than links, so
      the response is an acknowledgement, not a button. Movement is gated behind
      prefers-reduced-motion; the edge and the shadow always change. */
   .cert-grid .certi{transition:border-color .25s ease,box-shadow .3s ease}
   .cert-grid .certi:hover{border-color:var(--accent);box-shadow:0 10px 26px rgba(0,0,0,.08)}
   .certimgs .ph{transition:border-color .25s ease,box-shadow .3s ease}
   .certimgs .ph:hover{border-color:var(--accent);box-shadow:0 10px 26px rgba(0,0,0,.08)}
   @media (prefers-reduced-motion: no-preference){
     .cert-grid .certi{transition:border-color .25s ease,box-shadow .3s ease,
       transform .3s cubic-bezier(.2,.7,.2,1)}
     .cert-grid .certi:hover{transform:translateY(-3px)}
     .certimgs .ph{transition:border-color .25s ease,box-shadow .3s ease,
       transform .3s cubic-bezier(.2,.7,.2,1)}
     .certimgs .ph:hover{transform:translateY(-3px)}
     /* the zoom is motion too, so it belongs in here with the lift */
     .certimgs .ph img{transition:transform .55s cubic-bezier(.2,.7,.2,1)}
     .certimgs .ph:hover img{transform:scale(1.06)}
   }
   /* ---------- end hover dynamics: certification ---------- */
  .exhban{width:100%;min-height:230px;border:1px solid var(--line);margin-bottom:18px}
  @media(max-width:560px){.certimgs{grid-template-columns:1fr}}
/* image-slots:start */
.poster{background:var(--white);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.poster[hidden]{display:none}
.poster a{display:block;line-height:0}
.poster img{display:block;width:100%;height:auto;max-height:440px;object-fit:cover}
@media(max-width:900px){
  .poster img{max-height:240px}
}
/* image-slots:end */
/* nav-sub:start */
/* The labels are anchors carrying 4px of vertical padding inside a stretched list
   item, so they rode 4px above the row's centre while the logo and both buttons
   were centred. pdp-shared.css's .menu had no align-items at all; index.html's
   inline copy has always had it, which is why only sub-pages looked wrong. */
.menu{align-items:center}
.menu .has-sub{position:relative;display:flex;align-items:center}
/* Bridge the strip between the trigger and its panel. Measured at 4px, and it
   belongs to the row rather than to .has-sub, so :hover was dropped the instant
   the cursor left the trigger and the panel shut before the cursor could reach a
   category - which reads as "you have to click Products first". The panel paints
   above this (z-index 60), so nothing becomes unclickable. */
.menu .has-sub::after{content:"";position:absolute;left:0;right:0;top:100%;height:16px}
.menu .subtrg{position:relative;display:inline-flex;align-items:center;gap:7px;font:inherit;
  letter-spacing:inherit;text-transform:inherit;font-weight:inherit;color:inherit;background:none;
  border:0;border-bottom:2px solid transparent;padding:4px 0;cursor:pointer;white-space:nowrap}
/* The top-level links sweep a gold rule in on hover; the trigger is a button, so
   it has to be told the same thing or Products would be the one item that does not. */
.menu .subtrg::after{content:"";position:absolute;left:0;right:0;bottom:-2px;height:2px;
  background:var(--accent);transform:scaleX(0);transform-origin:left}
.menu .has-sub:hover .subtrg::after,.menu .has-sub:focus-within .subtrg::after{transform:scaleX(1)}
.menu .caret{width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;
  border-top:5px solid currentColor}
.menu .has-sub:hover .caret,.menu .has-sub:focus-within .caret{transform:rotate(180deg)}
.menu .sub{position:absolute;top:100%;left:-18px;min-width:224px;margin-top:10px;padding:8px 0;
  list-style:none;background:#fff;border:1px solid var(--line);
  box-shadow:0 12px 30px rgba(0,0,0,.10);z-index:60;display:flex;flex-direction:column;gap:0;
  font-size:inherit;letter-spacing:inherit;opacity:0;pointer-events:none;transform:translateY(-6px);
  transition:opacity .18s,transform .18s}
.menu .has-sub:hover .sub,.menu .has-sub:focus-within .sub{opacity:1;pointer-events:auto;transform:none}
.menu .sub a{display:block;padding:11px 22px;border-bottom:0;white-space:nowrap}
.menu .sub a::after{display:none}
 .menu .sub a:hover{background:#F7F7F7}
 /* Trade sits near the right end of the row, so its panel has to open leftwards:
    left:-18px would push a 224px panel past the viewport, where
    body{overflow-x:hidden} clips it without a trace. */
 .menu .has-sub.trade .sub{left:auto;right:-18px}
@media(min-width:1000px) and (prefers-reduced-motion: no-preference){
  .menu .subtrg::after{transition:transform .28s cubic-bezier(.2,.7,.2,1)}
  .menu .caret{transition:transform .25s}
}
/* The home page's drawer IS this list, so below 999px the submenu flattens into
   indented rows instead of a floating panel. Sub-pages hide .menu at 860px and
   use .mnav instead, which this does not touch. */
@media(max-width:999px){
  /* Undo the centring: in the drawer the list is a column, and centring would
     shrink every row to its text width. */
  .menu{align-items:stretch}
  .menu .has-sub{display:block;width:100%}
  .menu .has-sub::after{display:none}
  .menu .subtrg{display:block;width:100%;text-align:left;padding:14px 24px;border-bottom:0}
  .menu .subtrg::after{display:none}
  .menu .caret{display:none}
  .menu .sub{position:static;opacity:1;pointer-events:auto;transform:none;border:0;box-shadow:none;
    margin:0;padding:0;min-width:0;background:transparent}
  .menu .sub a{padding:12px 24px 12px 44px}
}
/* nav-sub:end */
