/* =========================================================================
   TOPFENG — White + Dark Industrial + Orange Accent  (Theme Overlay)
   Loaded AFTER each page's inline <style> via <link> in <head>.
   Strategy: remap CSS variables + selective override. Layout untouched.
   ========================================================================= */

/* ---------- 1. Token remap ------------------------------------------------ */
:root{
  /* Neutrals */
  --white:#FFFFFF;
  --warm-white:#F7F7F5;      /* Warm White  */
  --gray-light:#F1F2F1;      /* Light Gray  */
  --line:#E1E4E3;            /* Border Gray */
  --stone-50:#F1F2F1;
  --stone-100:#E1E4E3;
  --stone-200:#D8DCDD;

  /* Text system */
  --text-graphite:#202326;   /* Text Primary              */
  --text-body:#3A3F44;
  --text-muted:#687078;      /* Text Secondary            */
  --text-on-dark:#B8BEC3;    /* dark bg secondary text    */
  --text-on-dark-strong:#F5F5F5; /* dark bg primary text  */

  /* Dark industrial surfaces */
  --dark:#202326;            /* CTA — primary dark surface */
  --dark-2:#25292C;          /* Footer (Dark Industrial)   */
  --dark-3:#383E42;          /* hover surface inside dark  */

  /* Industrial background hairlines (very low contrast) */
  --tech-line:rgba(255,255,255,0.045);
  --tech-line-2:rgba(255,255,255,0.028);
  --tech-line-strong:#2C3033;
  --tech-orange:rgba(217,107,39,0.12);

  /* Brand accent */
  --orange:#D96B27;          /* Primary Orange */
  --orange-deep:#BF591F;     /* Orange Hover   */
  --orange-soft:#F4E7DE;

  /* Product gallery */
  --thumb-active:#3A3E42;
  --thumb-hover:#687078;

  /* Re-bind legacy variable names used by inline styles */
  --navy:var(--dark);
  --navy-light:var(--dark-2);
  --orange-dark:var(--orange-deep);
  --orange-light:var(--orange-soft);

  --gray-50:var(--warm-white);
  --gray-100:var(--stone-50);
  --gray-200:var(--line);
  --gray-300:var(--stone-200);
  --gray-600:var(--text-muted);
  --gray-700:var(--text-body);
  --gray-800:var(--text-graphite);

  /* Industrial corners */
  --radius:4px;
  --radius-lg:6px;
}

/* Body defaults + smooth in-page scrolling (About submenu anchors) */
html{scroll-behavior:smooth}
body{color:var(--text-body);background:var(--white)}

/* Fixed-header offset for anchored sections (both the long and short ids) */
#about-topfeng,
#topfeng-at-a-glance,
#capabilities,
#who-we-work-with,
#oem,
#manufacturing-ningbo,
#manufacturing{scroll-margin-top:92px}

/* ---------- 2. Global typography polish                                 */
h1,h2,h3,h4{color:var(--text-graphite);letter-spacing:-.01em}
.section-title{color:var(--text-graphite);font-weight:800;letter-spacing:-.02em}
.section-desc{color:var(--text-muted);font-size:16px;line-height:1.75;max-width:680px}
.section-label{color:var(--orange);letter-spacing:2.4px;font-weight:700}

/* ---------- 3. Header — adaptive page-top connection ------------------- */
/* The header is never a detached white slab: it inherits the visual of
   whatever sits directly underneath it, and only resolves to solid white
   once the page has actually scrolled. Header height / nav order / the
   left-right split all stay exactly as they were.                        */
.site-header{
  background:var(--white);
  border-bottom:1px solid transparent;
  box-shadow:none;
  transition:background-color .28s ease,border-color .28s ease,box-shadow .28s ease;
}
.header-inner{height:72px}

/* Logo — real proportions kept (2168x725 ≈ 3:1), no stretch, no shadow,
   no border, no background. 48px fills the 72px bar visually (≈12px of
   breathing room top/bottom) so the wordmark reads as the brand anchor of
   the header — the nav keeps its exact position and the bar keeps its height. */
.site-logo{display:flex;align-items:center;flex:0 0 auto}
.site-logo a{display:flex;align-items:center;line-height:0}
.site-logo img{
  height:48px;
  max-height:48px;
  width:auto;
  display:block;
  filter:none;
  border:0;
  background:transparent;
  box-shadow:none;
  image-rendering:auto;
  -webkit-backface-visibility:hidden;
  backface-visibility:hidden;
}

/* ---------- 3a. Homepage: the header IS part of the hero ---------------- */
/* Placed on <header> for index.html only. The hero is pulled up underneath
   it (see the adjacent-sibling rule below) so the two read as ONE visual
   block instead of two stacked rectangles. */
.site-header--over-hero{
  background:transparent;
  border-bottom:1px solid rgba(255,255,255,.09);
  box-shadow:none;
}
/* very light top scrim — keeps the logo + menu legible over the photo */
.site-header--over-hero::before{
  content:"";
  position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(20,24,27,.58) 0%,rgba(20,24,27,.30) 58%,rgba(20,24,27,0) 100%);
  pointer-events:none;
  z-index:-1;
  transition:opacity .28s ease;
}
.site-header--over-hero .main-nav > a,
.site-header--over-hero .main-nav > .nav-item--dropdown > .nav-item--dropdown-toggle{
  color:rgba(255,255,255,.9);
}
.site-header--over-hero .main-nav > a:hover,
.site-header--over-hero .main-nav > .nav-item--dropdown:hover > .nav-item--dropdown-toggle{
  color:#fff;
}
.site-header--over-hero .main-nav > a.active,
.site-header--over-hero .main-nav > .nav-item--dropdown > .nav-item--dropdown-toggle.active{
  color:#fff;
}
.site-header--over-hero .hamburger span{background:#fff}

/* once scrolled the page content runs underneath -> go solid */
.site-header--over-hero.is-scrolled{
  background:var(--white);
  border-bottom-color:var(--line);
  box-shadow:0 1px 10px rgba(20,24,28,.05);
}
.site-header--over-hero.is-scrolled::before{opacity:0}
.site-header--over-hero.is-scrolled .main-nav > a,
.site-header--over-hero.is-scrolled .main-nav > .nav-item--dropdown > .nav-item--dropdown-toggle{
  color:var(--text-body);
}
.site-header--over-hero.is-scrolled .main-nav > a.active,
.site-header--over-hero.is-scrolled .main-nav > .nav-item--dropdown > .nav-item--dropdown-toggle.active{
  color:var(--orange);
}
.site-header--over-hero.is-scrolled .hamburger span{background:var(--text-graphite)}

/* Inner pages: seamless at the top, hairline appears only after scrolling */
.site-header.is-scrolled{
  border-bottom-color:var(--line);
  box-shadow:0 1px 10px rgba(20,24,28,.05);
}

/* Sticky header reserved space */

.main-nav{display:flex;gap:2px;align-items:center}
.main-nav > a,
.main-nav > .nav-item--dropdown > .nav-item--dropdown-toggle{
  position:relative;
  display:inline-flex;
  align-items:center;
  padding:24px 16px;
  font-size:14px;
  font-weight:600;
  color:var(--text-body);
  border-radius:0;
  background:transparent;
  transition:color .18s ease;
  cursor:pointer;
}
.main-nav > a:hover,
.main-nav > .nav-item--dropdown:hover > .nav-item--dropdown-toggle{
  color:var(--text-graphite);
  background:transparent;
}
/* Thin orange underline sliding left → right */
.main-nav > a::after,
.main-nav > .nav-item--dropdown > .nav-item--dropdown-toggle::after{
  content:"";
  position:absolute;
  left:16px;right:16px;
  bottom:18px;
  height:2px;
  background:var(--orange);
  transform:scaleX(0);
  transform-origin:left center;
  transition:transform .28s cubic-bezier(.22,.61,.36,1);
  border-radius:1px;
}
.main-nav > a:hover::after,
.main-nav > .nav-item--dropdown:hover > .nav-item--dropdown-toggle::after{
  transform:scaleX(1);
}
/* Active item = permanent underline (no caret, no box) */
.main-nav > a.active,
.main-nav > .nav-item--dropdown > .nav-item--dropdown-toggle.active{
  color:var(--orange);
  background:transparent;
}
.main-nav > a.active::after,
.main-nav > .nav-item--dropdown > .nav-item--dropdown-toggle.active::after{transform:scaleX(1)}

/* Dropdown — NO caret / triangle / arrow, hover to open on desktop */
.nav-item--dropdown{position:relative;display:inline-flex;align-items:center}
.nav-dropdown{
  position:absolute;
  top:100%;left:8px;
  min-width:220px;
  background:var(--white);
  border:1px solid var(--line);
  border-top:2px solid var(--orange);
  box-shadow:0 14px 36px rgba(20,24,28,.10);
  padding:8px 0;
  display:none;
  z-index:1100;
}
/* invisible hover bridge — keeps the panel open while the pointer travels down */
.nav-dropdown::before{
  content:"";
  position:absolute;
  left:0;right:0;top:-14px;height:14px;
}
/* Desktop: hover (or keyboard focus) reveals the panel — no click needed */
@media (min-width:769px){
  .nav-item--dropdown:hover .nav-dropdown,
  .nav-item--dropdown:focus-within .nav-dropdown{display:block}
}
/* Force-closed right after a submenu click (same-page smooth scroll case) */
.nav-item--dropdown.suppress .nav-dropdown{display:none!important}

.nav-dropdown a{
  display:block;
  padding:10px 18px;
  font-size:14px;
  font-weight:600;
  color:var(--text-body);
  background:transparent;
  border-radius:0;
  transition:background .15s,color .15s;
}
.nav-dropdown a:hover,
.nav-dropdown a:focus{
  color:var(--orange);
  background:var(--warm-white);
}
.nav-dropdown a::after{display:none!important}

/* ---------- 4. Buttons                                                    */
.btn{border-radius:4px;padding:11px 22px;font-weight:700;letter-spacing:.01em}
.btn-lg{padding:14px 30px;font-size:15px}
.btn-primary{background:var(--orange);color:#fff;border:1px solid var(--orange)}
.btn-primary:hover{background:var(--orange-deep);border-color:var(--orange-deep)}
.btn-outline{background:transparent;color:var(--text-graphite);border:1.5px solid var(--text-graphite)}
.btn-outline:hover{background:var(--text-graphite);color:#fff}
.btn-outline-light{background:transparent;color:#fff;border:1.5px solid rgba(255,255,255,.55)}
.btn-outline-light:hover{background:rgba(255,255,255,.12);color:#fff}
.btn-white{background:#fff;color:var(--text-graphite);border:1px solid #fff}
.btn-white:hover{background:var(--orange);color:#fff;border-color:var(--orange)}
.header-actions .btn-primary{box-shadow:0 2px 0 rgba(191,89,31,.25)}
/* ---------- 5. Hero — image kept, professional dark gradient overlay      */
/* Transparent → dark → local boost. The left (headline) side is deeper,   */
/* the right keeps the outdoor scene bright and photographic.              */
.hero{
  background-color:var(--dark);
  background-image:
    linear-gradient(90deg,
      rgba(20,24,27,0.72) 0%,
      rgba(20,24,27,0.48) 42%,
      rgba(20,24,27,0.18) 72%,
      rgba(20,24,27,0.05) 100%),
    url('../images/home-hero-bg.webp');
  background-size:cover,cover;
  background-position:center,center;
  background-repeat:no-repeat,no-repeat;
  color:#fff;
}
/* keep the decorative glows extremely subtle so the photo stays readable */
.hero::before{
  background:radial-gradient(circle,rgba(217,107,39,.10) 0%,transparent 70%);
}
.hero::after{
  background:radial-gradient(circle,rgba(255,255,255,.025) 0%,transparent 70%);
}
.hero h1{color:#fff}
.hero h1 span{color:var(--orange)}
.hero p{color:rgba(255,255,255,.88)}

/* ---- 5a. Homepage only: hero slides up behind the header --------------- */
/* -72px lifts the hero to y=0 so the (transparent) header sits ON it, and  */
/* +72px of top padding keeps every piece of hero content at exactly the    */
/* same position it had before. Total page height is unchanged.             */
.site-header--over-hero + .hero{
  margin-top:-72px;
  padding-top:172px;
}

/* ---- 5b. Hero vertical rhythm ----------------------------------------- */
/* Only spacing, no font / position / size changes.                         */
.hero h1{margin-bottom:22px}   /* headline  -> body    ≈ 22px */
.hero p{margin-bottom:30px}    /* body      -> buttons ≈ 30px */
.hero{padding-bottom:96px}

/* Explore Products — full label, no clipping / overflow / overlap */
.hero-btns{display:flex;gap:14px;flex-wrap:wrap;align-items:center}
.hero-btns .btn{
  position:relative;z-index:3;
  display:inline-flex;align-items:center;justify-content:center;
  min-width:180px;height:54px;padding:0 28px;
  font-size:15px;font-weight:700;
  white-space:nowrap;
  max-width:100%;
  overflow:visible;
  text-overflow:clip;
}
/* Explore Products — clean cut at rest, industrial orange on hover.
   Only background / text / border colour move: no scale, no jump, no glow. */
.hero-btns .btn-white{
  background:#FFFFFF;
  color:#202326;
  border:1px solid #FFFFFF;
  box-shadow:none;
  transform:none;
  transition:background-color .2s ease,color .2s ease,border-color .2s ease;
}
.hero-btns .btn-white:hover,
.hero-btns .btn-white:focus-visible{
  background:var(--orange);
  color:#FFFFFF;
  border-color:var(--orange);
  box-shadow:none;
  transform:none;
}
.hero-btns .btn-outline-light{
  background:transparent;color:#fff;border:1.5px solid rgba(255,255,255,.62);
}
.hero-btns .btn-outline-light:hover{background:rgba(255,255,255,.14);color:#fff}

/* ---- 5c. Key-figures band (sits just BELOW the hero) ------------------- */
/* Owns its own white surface, 5 evenly balanced columns, orange figures,   */
/* hairline dividers — clean B2B, no cards, no shadows.                     */
.stats-band{
  background:var(--white);
  border-bottom:1px solid var(--line);
}
.stats-band .hero-stats{
  display:grid;
  grid-template-columns:repeat(5,1fr);
  align-items:stretch;
  gap:0;
  margin:0;
  padding:34px 0 36px;
  flex-wrap:nowrap;
}
.stats-band .hero-stat{
  position:relative;
  text-align:center;
  padding:4px 20px;
  min-width:0;
}
.stats-band .hero-stat + .hero-stat::before{
  content:"";
  position:absolute;
  left:0;top:6px;bottom:6px;
  width:1px;
  background:var(--line);
}
.stats-band .hero-stat-num{
  color:var(--orange);
  font-size:38px;
  font-weight:800;
  line-height:1.05;
  letter-spacing:-.01em;
}
.stats-band .hero-stat-label{
  color:var(--text-muted);
  font-size:11.5px;
  font-weight:700;
  letter-spacing:1.5px;
  text-transform:uppercase;
  margin-top:9px;
}

/* ---------- 6. About / sections                                          */
.about-section,
.products-section,
.why-section,
.section[style*="--gray-50"]{
  background:var(--warm-white);
}
.feature-icon,
.why-icon,
.ci-icon{
  background:var(--orange-soft);
  border-radius:8px;
}
.feature-icon svg,
.why-icon svg,
.ci-icon svg{color:var(--orange)}
.feature-content strong,
.why-card h3,
.contact-info h3,
.inquiry-box h3,
.contact-form-card h3,
.pd-name,
.blog-card-body h3,
.product-info h3 a,
.product-info h3,
.breadcrumb strong{color:var(--text-graphite)}
.feature-content span,
.why-card p,
.contact-info .ci-label,
.contact-form-card .ib-sub,
.inquiry-box .ib-sub{color:var(--text-muted)}

/* ---------- 6b. Our Story — reading rhythm + stacked media -------------- */
/* Copy column: natural left alignment with a sane measure. Deliberately NOT
   justified — an English paragraph that is stretched to a flush right edge
   looks wrong on the web and starves the closing line.                     */
.story-copy .section-title{max-width:640px}
.story-copy .section-desc{
  max-width:600px;
  line-height:1.78;
  text-align:left;
  letter-spacing:.002em;
  text-wrap:pretty;
}
.story-copy p strong{color:var(--text-graphite)}

/* An editorial two-plate composition. Both plates are the SAME size, laid on
   a slight diagonal: the auxiliary plate (story-2) sits HIGH and to the
   RIGHT, the hero plate (story-1) sits LOW and to the LEFT and overlaps it by
   one centimetre, so the pair reads as premium overlapping photography rather
   than two panels laid out side by side.
     Both source files are square (1254x1254), so a plate's height always
   equals its width - which is why every dimension below can be written as a
   ratio of the media-box width (W) and stays identical at any viewport:
       plate width = calc(50% + 19px)  ->  the pair spans 2*plate - 38px
       back  (story-2) top:0     right:0 -> x (.5W-19)-W,  y 0-(.5W+19)
       front (story-1) top:38px  left:0  -> x 0-(.5W+19),  y 38-(.5W+57)
   so the side overlap is a constant 38px (~1cm at 96dpi) and the top of the
   hero plate sits exactly 38px below the top of the auxiliary one - the "one
   centimetre" tuck asked for.
     V11 - the pair no longer has to sit small inside its grid column. It
   bleeds 32px out into the 64px gutter on the left (32px still clear of the
   copy) and, once the page is wide enough to have a margin of its own, runs
   all the way out to 24px short of the viewport edge; at 1440 that widens the
   box to 696px and the plates to 367x367 instead of 301x301. Both bleeds are
   WIDTH only, so every ratio above still holds and the two plates stay exactly
   equal in size. The box is therefore a 2:1 aspect ratio (half its own width =
   one plate) plus a 57px tail for the tuck, so its height follows the width
   automatically at every viewport.
     Person safety: the walker in story-2 lives at x 25-41% / y 51-79% of that
   frame. Placed on the diagonal above he lands at x (W-.75*plate)-(W-.59*
   plate) - at least .25*plate right of story-2's left edge - while the front
   plate covers only the first 38px of that image, leaving a clear margin of
   .25*plate - 38px (37px at the old 564px column, 54px at 696px), so the front
   plate can never crop him. story-1's own walker is mid-frame on the plate
   that sits on top, so nothing can ever cover it either.                   */
.story-media{
  position:relative;
  width:100%;
  /* half the box width = one square plate; the 57px tail below carries the
     38px tuck plus the 19px the front plate overhangs past the pair */
  aspect-ratio:2 / 1;
  margin:0 0 57px;
  /* the copy column runs ~630px tall while a pair of squares can only ever
     reach ~.5W+57, so centre the pair on the copy rather than pinning it to
     the top and leaving all the leftover air underneath */
  align-self:center;
}
.story-media img{
  position:absolute;
  display:block;
  width:auto;
  border-radius:24px;
}
.story-media .story-media-back{
  top:0;
  right:0;
  width:calc(50% + 19px);
  z-index:1;
  box-shadow:0 8px 22px rgba(0,0,0,.06);
}
.story-media .story-media-front{
  top:38px;
  left:0;
  width:calc(50% + 19px);
  z-index:2;
  box-shadow:0 12px 35px rgba(0,0,0,.10);
}
/* Let the pair use the space around its column instead of sitting small in the
   middle of it. Two columns only (below 768 the grid stacks, so there is no
   gutter to bleed into and the box must stay inside the page padding):
   32px into the 64px gutter on the left, leaving 32px of clear air next to the
   copy. Nothing here changes the plates - they are still one half of the box
   each, so they simply scale up with it.                                    */
@media (min-width:769px){
  .story-media{
    margin-left:-32px;
    width:calc(100% + 32px);
  }
}
/* Past the 1240px container there is a real page margin to spend: run the pair
   out to 24px short of the viewport edge. min() caps the extra at 120px so the
   composition never grows without bound on very wide screens, and the /2 keeps
   it tracking the actual margin, so it can never cause a horizontal scrollbar.
   At 1440: box 696px -> plates 367x367, pair 405px tall (was 301 / 339).     */
@media (min-width:1280px){
  .story-media{
    width:calc(100% + 32px + min(120px, (100vw - 1240px) / 2));
  }
}

/* ---------- 7. Category / product cards                                  */
.cat-card{border-radius:6px}
/* Scrim is weighted to the BOTTOM (where the copy sits) so the product
   itself keeps its original brightness in the upper part of the image. */
.cat-overlay{
  background:linear-gradient(to top,
    rgba(20,24,27,.72) 0%,
    rgba(20,24,27,.58) 20%,
    rgba(20,24,27,.24) 48%,
    rgba(20,24,27,0) 76%);
}
.cat-overlay h3{color:#FFFFFF}
.cat-overlay p{color:#F3F4F4}
.cat-overlay .arrow{color:var(--orange)}

.product-card{
  background:#fff;
  border:1px solid var(--line);
  border-radius:6px;
  transition:transform .25s ease,box-shadow .25s ease,border-color .25s ease;
}
.product-card:hover{
  border-color:var(--stone-100);
  box-shadow:0 10px 30px rgba(20,24,28,.08);
  transform:translateY(-3px);
}
.product-img{background:var(--warm-white)}
.product-info .cat-tag{color:var(--orange);letter-spacing:1.4px}
.product-info .inq{color:var(--text-graphite)}
.product-info .inq:hover{color:var(--orange)}
.product-info .p-id,
.product-info .p-specs{color:var(--text-muted)}

/* Toolbar chips */
.filter-btn{background:#fff;border:1px solid var(--line);color:var(--text-body);border-radius:999px}
.filter-btn:hover{border-color:var(--text-graphite);color:var(--text-graphite)}
.filter-btn.active{background:var(--text-graphite);color:#fff;border-color:var(--text-graphite)}
.search-box input{border:1px solid var(--line);color:var(--text-graphite)}
.search-box input:focus{border-color:var(--orange)}

/* ---------- 8. Factory gallery                                           */
.gallery-item{border-radius:6px;box-shadow:0 1px 3px rgba(20,24,28,.08)}
.gallery-item:hover{transform:translateY(-2px);box-shadow:0 8px 22px rgba(20,24,28,.12)}
.gallery-label{background:rgba(20,24,28,.78);color:#fff;border-radius:3px;letter-spacing:1.2px}

/* ---------- 9. Why / Facts / OEM cards                                  */
.why-card{background:transparent;padding:30px 18px}
.why-card:hover{background:#fff;border-radius:6px}
.fact-card,
.oem-card{
  background:#fff;
  border:1px solid var(--line);
  border-radius:6px;
}
.fact-num,
.oem-value{color:var(--orange);font-weight:800}

/* ---------- 10. Certification block                                      */
.cert-box{
  background:#fff;
  border:1px solid var(--line);
  border-radius:6px;
}
.cert-badge{
  background:var(--warm-white);
  border:1px solid var(--line);
  color:var(--text-graphite);
  border-radius:4px;
}
.cert-badge svg{color:var(--orange)}
.cert-model{color:var(--text-muted)}
.cert-model strong{color:var(--text-graphite)}
.cert-numbers{color:var(--text-muted)}

/* ---------- 11. CTA + Footer — UNIFIED DARK INDUSTRIAL AREA             */
/* The dark blocks carry NO line work at all — no hatching, no guide rules,
   no grid, no markers. Everything that used to read as a technical ruled
   surface has been removed; the only texture left is the drifting white
   particle field painted by ::after, plus one barely-there wash so the
   graphite surface is flat but not dead.                                   */
.cta-section{
  background-color:var(--dark);
  background-image:
    /* soft light from the top so the dark surface is not flat */
    radial-gradient(130% 90% at 50% -12%,rgba(255,255,255,.05) 0%,transparent 62%);
  color:#fff;
  text-align:center;
  position:relative;
  padding:88px 0 96px;
  border-bottom:0;
  margin-bottom:0;
  /* the drifting particle layer is decorative — never let it add scroll */
  overflow:clip;
}
.cta-section .section-label{color:var(--orange)}
.cta-section .section-title{color:var(--text-on-dark-strong);max-width:680px;margin:0 auto 12px}
.cta-section .section-desc{color:var(--text-on-dark);max-width:560px;margin:0 auto 28px}
.cta-section .btn-outline{
  color:#fff;border-color:rgba(255,255,255,.6);
  background:transparent;
}
.cta-section .btn-outline:hover{
  background:#fff;color:var(--text-graphite);
}
.cta-section .btn-primary{
  background:var(--orange);border-color:var(--orange);
}
.cta-section .btn-primary:hover{
  background:var(--orange-deep);border-color:var(--orange-deep);
}

.site-footer{
  background-color:#171A18;
  /* Deep neutral lake-dark surface, a plane below the CTA's --dark. There is
     no ruled surface, no grid, no hatching and no line work of any kind down
     here - the only texture is the interactive particle water painted onto
     the canvas in section 11b. The orange hairline above is a structural
     divider between the two dark blocks, not a background line. */
  background-image:
    radial-gradient(130% 80% at 50% 0%,rgba(255,255,255,.035) 0%,transparent 64%);
  color:var(--text-on-dark);
  padding:60px 0 28px;
  /* thin translucent orange brand divider between CTA and Footer */
  border-top:1px solid rgba(217,107,39,.55);
  position:relative;
  /* keeps the slow particle drift from ever producing page overflow */
  overflow:clip;
}
.site-footer h4{color:var(--text-on-dark-strong);font-size:14px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;margin-bottom:18px;white-space:nowrap}
/* Company blurb — capped so its right edge lines up with the column grid
   instead of running wider than the link columns. Natural left alignment,
   never justified (the last line is allowed to be short). */
.footer-about p{
  color:var(--text-on-dark);
  font-size:13px;
  line-height:1.78;
  margin-bottom:16px;
  max-width:400px;
  text-align:left;
}
.footer-social a{
  background:rgba(255,255,255,.06);
  color:var(--text-on-dark);
  border-radius:6px;
  transition:background .2s ease,color .2s ease;
}
.footer-social a:hover{background:var(--orange);color:#fff}
.footer-links a{color:var(--text-on-dark);font-size:13px;transition:color .2s ease}
.footer-links a:hover{color:var(--orange)}
.footer-contact p{color:var(--text-on-dark);font-size:13px;line-height:1.85}
.footer-contact a{color:var(--text-on-dark-strong);transition:color .2s ease}
.footer-contact a:hover{color:var(--orange)}
.footer-bottom{
  border-top:1px solid rgba(255,255,255,.08);
  color:rgba(255,255,255,.44);
  font-size:12px;
}

/* ---- 11b. Dark-area particle fields ------------------------------------ */
/* CTA - a few hundred sub-2px white specks arranged as two soft, undulating
   wave ribbons. There is not a single stroke in the SVG: the density itself
   carries the shape, so the block reads as a calm water surface with a
   slight disturbance rather than as a starfield or a ruled background.
     Each ribbon is roughly 64px thick (2 sigma) and its centre rises and
     falls by 24-30px across the width. The particle density is phase-locked
     to that same undulation - crest ~1.00, trough ~0.30 - which is what
     makes a crest read as "denser" and a valley as "thinner". The first and
     last ~16% of the width fades to zero, so the ripple enters from one side
     and dissipates on the other instead of abutting the section wall.
       strip  1600 x 420, two ribbons at y ~ 140 and y ~ 300
       specks 0.6-1.8px core, 62% of them carry a soft white halo
       alpha  0.03-0.33, pure #FFFFFF - no hue, no gradient, no glow colour
   `background-size:100% auto` (not `cover`) is deliberate: cover crops the
   strip's faded ends away on narrow or tall blocks and leaves the ribbons
   running off the sides. Full width always keeps the enter/dissipate ends
   in frame.
    Footer - a real drifting water mist on a <canvas>, injected and driven by
  assets/js/footer-particles.js. It is not a wave line, not an even scatter
  and not starfield: a BODY OF MIST settles in the lower part of the block and
  thickens towards the bottom edge, so the footer reads as a dark water surface
  with fine spray hanging over it. Every droplet is placed against an irregular
  mist boundary (four incommensurate sines plus a noise rag, so it never
  repeats and never reads as a sine); above it sits a soft shoulder of haze
  that thins as you climb, leaving only a few lone specks near the top; below
  it a power-skewed depth packs the count towards the bottom, then eases off
  over the last few percent so the spray crest lands just above the bottom edge
  instead of ending in a hard band. A two-octave value-noise gate breaks the
  body into soft clumps and gaps -蓬松, never a lattice. Four restrained greys
  and nothing else (#BFC4BE main, #858C85 further back, #D9DDD7 a few brighter
  droplets at the front, #525953 the deepest shadows); ink and alpha both grow
  with depth, so the field gains atmosphere with no glow, bloom or hue. About
  62% of droplets are 1-2px across and the rare largest few are blitted from a
  soft sprite rather than drawn as discs, so they read as out-of-focus droplets
  and give the layer its depth of field. The surface answers the pointer with
  a soft, decaying, spring-damped ripple - a resting cursor disturbs nothing.
  The canvas sits under the copy on z-index 0, so nothing in the footer's text
  is ever covered.                                                          */
.cta-section::after{
  content:"";
  position:absolute;
  inset:0;
  pointer-events:none;
  z-index:0;
  background-repeat:no-repeat;
  background-position:center bottom;
  background-size:100% auto;
  will-change:transform,opacity;
}
.cta-section::after{
  background-image:url('../images/particle-wave.svg');
  animation:tfParticleDriftA 11s ease-in-out infinite alternate,
            tfParticleGlowA 7.5s ease-in-out infinite alternate;
}
/* Drift is a long, slow lateral float with a hair of scale — 20-26px over
   11-12.5s, so roughly 2px a second. Faster than before, still far too slow
   to read as "playing an animation", and never enough to feel like motion
   sickness. */
@keyframes tfParticleDriftA{
  from{transform:translate3d(-11px,6px,0) scale(1.006)}
  to{transform:translate3d(13px,-9px,0) scale(1.018)}
}
/* A gentle breathing on the layer opacity so the field feels alive even
   where the drift is imperceptible. */
@keyframes tfParticleGlowA{
  from{opacity:.78}
  to{opacity:1}
}
/* keep the copy above the texture */
.cta-section > .container,
.site-footer > .container{position:relative;z-index:1}

/* the footer's drifting water mist: a plain canvas pinned inside the footer,
   always under the copy, never stealing pointer events (the JS reads the
   cursor from the footer element itself) */
.site-footer > .footer-particles{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  display:block;
  z-index:0;
  pointer-events:none;
}

/* ---------- 12. Breadcrumb / product detail                              */
.breadcrumb{padding:20px 0;font-size:13px}
.breadcrumb a{color:var(--text-muted)}
.breadcrumb a:hover{color:var(--orange)}
.breadcrumb strong{color:var(--text-graphite)}
.pd-cat{color:var(--orange)}
.pd-name,
.pd-id strong,
.pd-features-title,
.detail-title{color:var(--text-graphite)}
.pd-shortdesc,
.pd-id{color:var(--text-muted)}
.pd-feature{
  background:var(--orange-soft);
  color:var(--orange-deep);
  border-radius:4px;
}
.detail-section{border-top:1px solid var(--stone-50)}
.spec-table{border:1px solid var(--line);border-radius:6px;overflow:hidden}
.spec-table th,
.spec-table td{border-bottom:1px solid var(--line)}
.spec-table th{background:var(--warm-white);color:var(--text-muted);font-weight:600}
.spec-table td{color:var(--text-graphite);font-weight:500}
.acc-list li::before,
.app-list li::before{background:var(--orange)}
.source-note{
  background:var(--warm-white);
  border-left:3px solid var(--stone-200);
  color:var(--text-muted);
  border-radius:0 4px 4px 0;
}

/* ---------- 12b. Product image gallery                                   */
/* Products keep their original proportions (object-fit: contain) — no crop */
.pd-gallery{position:sticky;top:96px;min-width:0;max-width:100%}

/* Mobile / tablet: the product gallery must NOT stick to the top of the
   viewport. On a 1-column stacked layout, a sticky gallery overlaps the
   product description that scrolls beneath it. Drop sticky everywhere
   below 1024px (iPad portrait and all phones incl. iPhone 14 Pro / 393px). */
@media (max-width:1024px){
  .pd-gallery{position:static;top:auto;align-self:start}
}

.pd-main-img{
  position:relative;
  aspect-ratio:1;
  border:1px solid var(--line);
  border-radius:6px;
  overflow:hidden;
  background:#fff;
}
.pd-main-img img{
  width:100%;height:100%;
  object-fit:contain;
  padding:20px;
  transition:opacity .3s ease,transform .3s ease;
  will-change:opacity,transform;
}
/* subtle premium cross-fade + micro scale while swapping */
.pd-main-img img.is-fading{opacity:0;transform:scale(.985)}

/* prev / next arrows over the main image — never cover the product */
.pd-nav{
  position:absolute;top:50%;transform:translateY(-50%);
  width:36px;height:36px;
  display:flex;align-items:center;justify-content:center;
  padding:0;margin:0;
  border-radius:50%;
  background:rgba(255,255,255,.92);
  border:1px solid var(--line);
  color:var(--thumb-active);
  cursor:pointer;
  z-index:3;
  box-shadow:0 2px 10px rgba(20,24,28,.12);
  transition:color .2s ease,border-color .2s ease,background .2s ease,opacity .2s ease;
  -webkit-appearance:none;appearance:none;
}
.pd-nav:hover{color:var(--orange);border-color:var(--orange);background:#fff}
.pd-nav:focus-visible{outline:2px solid var(--orange);outline-offset:2px}
.pd-nav svg{width:16px;height:16px;display:block;pointer-events:none}
.pd-nav--prev{left:12px}
.pd-nav--next{right:12px}
.pd-nav[disabled]{opacity:.3;cursor:default}
.pd-nav[disabled]:hover{color:var(--thumb-active);border-color:var(--line);background:rgba(255,255,255,.92)}

/* thumbnail rail — always ONE row; extra images live in the scroll area */
.pd-thumbs{
  display:flex;
  flex-wrap:nowrap;
  gap:10px;
  margin-top:12px;
  min-width:0;
  max-width:100%;
  overflow-x:auto;
  overflow-y:hidden;
  scroll-behavior:smooth;
  scrollbar-width:none;
  -ms-overflow-style:none;
  padding:2px 2px 4px;
}
.pd-thumbs::-webkit-scrollbar{display:none}
.pd-thumb{
  flex:0 0 auto;
  width:64px;height:64px;
  border:1px solid var(--line);
  border-radius:4px;
  overflow:hidden;
  cursor:pointer;
  background:var(--warm-white);
  padding:0;
  box-sizing:border-box;
  transition:border-color .2s ease;
  -webkit-appearance:none;appearance:none;
}
.pd-thumb img{width:100%;height:100%;object-fit:contain;padding:4px;pointer-events:none}
.pd-thumb:hover{border-color:var(--thumb-hover)}
.pd-thumb.active{border-color:var(--thumb-active)}

/* ---------- 13. Forms                                                    */
.inquiry-box,
.contact-form-card{
  background:#fff;
  border:1px solid var(--line);
  border-radius:6px;
}
.form-group label{color:var(--text-graphite);letter-spacing:.6px}
.form-group input,
.form-group select,
.form-group textarea{
  border:1px solid var(--line);
  color:var(--text-graphite);
  background:#fff;
  border-radius:4px;
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus{border-color:var(--orange);box-shadow:0 0 0 3px rgba(217,107,39,.12)}
.form-group input[readonly]{background:var(--warm-white);color:var(--text-muted)}
.form-note{color:var(--text-muted)}
.form-status-success{background:#E8F3ED;color:#1F6A3F;border-radius:4px}
.form-status-error{background:#FDECEA;color:#9F2A20;border-radius:4px}

/* ---------- 14. Contact — QR block                                       */
.contact-info{padding:32px}
.ci-value{color:var(--text-graphite)}
.ci-value a:hover{color:var(--orange)}
.qr-block{
  margin-top:28px;
  padding-top:24px;
  border-top:1px solid var(--line);
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:18px;
}
.qr-cell{
  background:var(--warm-white);
  border:1px solid var(--line);
  border-radius:6px;
  padding:14px 14px 12px;
  text-align:center;
}
.qr-cell img{
  width:100%;
  max-width:148px;
  height:auto;
  margin:0 auto 10px;
  display:block;
  background:#fff;
  padding:6px;
  border-radius:4px;
}
.qr-cell .qr-label{
  display:block;
  font-size:11px;
  font-weight:700;
  letter-spacing:1.2px;
  text-transform:uppercase;
  color:var(--text-graphite);
}
.qr-cell .qr-meta{
  display:block;
  font-size:11px;
  color:var(--text-muted);
  margin-top:2px;
  line-height:1.4;
}

/* ---------- 15. Blog                                                     */
.blog-card{
  background:#fff;
  border:1px solid var(--line);
  border-radius:6px;
}
.blog-card:hover{
  box-shadow:0 10px 30px rgba(20,24,28,.08);
  transform:translateY(-2px);
}
.blog-card-body .cat-tag{color:var(--orange);letter-spacing:1.2px}
.blog-card-body h3{color:var(--text-graphite)}
.blog-card-body p{color:var(--text-muted)}

/* ---------- 16. Not found                                                */
.not-found h2{color:var(--text-graphite)}
.not-found p{color:var(--text-muted)}

/* ---------- 17. Responsive                                                */
@media (max-width:1024px){
  .qr-block{grid-template-columns:1fr 1fr}
  .stats-band .hero-stat{padding:4px 12px}
  .stats-band .hero-stat-num{font-size:32px}
  .stats-band .hero-stat-label{letter-spacing:1px;font-size:11px}
}
@media (max-width:768px){
  .main-nav{
    display:none;
    position:absolute;
    top:72px;left:0;right:0;
    background:#fff;
    flex-direction:column;
    padding:8px 0;
    border-bottom:1px solid var(--line);
    box-shadow:0 10px 24px rgba(20,24,28,.08);
  }
  .main-nav.open{display:flex}
  .main-nav > a,
  .main-nav > .nav-item--dropdown > .nav-item--dropdown-toggle{
    padding:14px 24px;width:100%;
  }
  .main-nav > a::after,
  .main-nav > .nav-item--dropdown > .nav-item--dropdown-toggle::after{
    left:24px;right:24px;bottom:8px;
  }
  /* On mobile the submenu is a plain in-flow list — no hover, no overlap */
  .nav-item--dropdown{width:100%;flex-direction:column;align-items:stretch}
  .nav-dropdown{
    display:block;
    position:static;
    min-width:0;
    box-shadow:none;
    border:none;
    border-top:0;
    background:var(--warm-white);
    padding:0;
    margin:0 0 6px 0;
  }
  .nav-dropdown::before{display:none}
  .nav-dropdown a{padding:10px 36px;font-size:14px}

  /* mobile: one step down from desktop, still crisp and still the anchor */
  .site-logo img{height:40px;max-height:40px}

  /* particle field: same full-width mapping as desktop, so both wave
     ribbons (and their faded entry / exit ends) stay in frame on a narrow
     block instead of being cropped (see section 11b) */
  .cta-section::after{background-position:center bottom}

  /* hero rhythm on small screens */
  .hero{padding-top:60px;padding-bottom:56px}
  .site-header--over-hero + .hero{margin-top:-72px;padding-top:132px;padding-bottom:56px}
  .hero h1{margin-bottom:18px}
  .hero p{margin-bottom:26px}
  .hero-btns{flex-direction:column;align-items:stretch;gap:12px}
  .hero-btns .btn{min-width:0;width:100%;height:52px;justify-content:center}

  /* key figures: 2 balanced columns with clean dividers */
  .stats-band .hero-stats{
    grid-template-columns:repeat(2,1fr);
    padding:20px 0;
  }
  .stats-band .hero-stat{padding:14px 10px}
  .stats-band .hero-stat + .hero-stat::before{display:none}
  .stats-band .hero-stat:nth-child(even){border-left:1px solid var(--line)}
  .stats-band .hero-stat:nth-child(n+3){border-top:1px solid var(--line)}
  .stats-band .hero-stat-num{font-size:28px}
  .stats-band .hero-stat-label{font-size:10.5px;letter-spacing:.9px;margin-top:7px}

  .section{padding:56px 0}
  .section-title{font-size:26px}
  .qr-block{grid-template-columns:1fr}
  .footer-grid{grid-template-columns:1fr;gap:32px}
  .cta-section{padding:64px 0 72px}
  .site-footer{padding:48px 0 24px}

  .pd-thumb{width:56px;height:56px}
  .pd-nav{width:32px;height:32px}
  .pd-nav--prev{left:8px}
  .pd-nav--next{right:8px}
  .pd-nav svg{width:14px;height:14px}
}

/* ---------- 18. Motion preferences                                       */
/* The particle drift + breathing are the only decorative animations on the
   page, so switching them off for reduced-motion users costs nothing.      */
@media (prefers-reduced-motion:reduce){
  .cta-section::after{animation:none}
}
