/* =========================================================
   polish.css — the sitewide design system.
   Loaded LAST on every page (portal pages and the 35 legacy
   landings alike), so it is the single place where spacing,
   radii, shadows, type scale, colour and motion are decided.

   It changes presentation only. No copy, structure, route,
   schema, form or link is touched by anything in this file.

   Colour discipline: ONE green family + ONE warm accent used
   sparingly for price and rating. Nothing else.
   ========================================================= */

:root {
  /* ---- Green family (the only structural colour) ---- */
  --pl-green-900: #0d3a2a;   /* deepest — headings on tint, dark bands */
  --pl-green-800: #12503a;   /* primary — buttons, links, accents      */
  --pl-green-700: #17654a;   /* hover                                   */
  --pl-green-600: #1c7a56;   /* secondary accent, .hl                   */
  --pl-green-200: #c9e3d4;   /* borders on tint                         */
  --pl-green-100: #e4f1e9;   /* icon tiles, chips                       */
  --pl-green-050: #f2f8f4;   /* section tint                            */

  /* ---- One warm accent. Price, rating, nothing else. ---- */
  --pl-warm:      #9a7a2c;
  --pl-warm-100:  #f6efdd;

  /* ---- Ink ---- */
  --pl-ink:       #15201a;
  --pl-ink-2:     #3b4a42;
  --pl-ink-3:     #6a7a71;

  /* ---- Surfaces ---- */
  --pl-paper:     #ffffff;
  --pl-paper-2:   #f7faf8;
  --pl-rule:      #dde6e0;
  --pl-rule-soft: #eaf0ec;

  /* ---- Spacing scale (4px base) ---- */
  --pl-1: 4px;   --pl-2: 8px;   --pl-3: 12px;  --pl-4: 16px;
  --pl-5: 20px;  --pl-6: 24px;  --pl-7: 32px;  --pl-8: 40px;
  --pl-9: 56px;  --pl-10: 72px; --pl-11: 96px;

  /* ---- Radius scale ---- */
  --pl-r-sm: 8px;
  --pl-r-md: 12px;
  --pl-r-lg: 16px;
  --pl-r-xl: 22px;
  --pl-r-pill: 999px;

  /* ---- Elevation. Two levels, both neutral-green tinted. ---- */
  --pl-e-0: 0 1px 2px rgba(18,50,38,.05);
  --pl-e-1: 0 1px 2px rgba(18,50,38,.05), 0 6px 16px -8px rgba(18,50,38,.14);
  --pl-e-2: 0 2px 4px rgba(18,50,38,.06), 0 18px 34px -14px rgba(18,50,38,.22);
  --pl-e-cta: 0 8px 20px -10px rgba(18,80,58,.55);

  /* ---- Motion ---- */
  --pl-fast: 140ms;
  --pl-base: 220ms;
  --pl-slow: 420ms;
  --pl-ease: cubic-bezier(.2, .7, .3, 1);
  --pl-ease-out: cubic-bezier(.16, 1, .3, 1);
}

/* Bring the legacy palette variables onto the same green family so the
   38 pre-existing landings inherit the discipline without being rebuilt. */
:root,
body.preset-botanical,
body.page-modern-landing {
  --color-primary:        var(--pl-green-800);
  --color-primary-light:  var(--pl-green-600);
  --color-primary-dark:   var(--pl-green-900);
  --color-primary-pale:   var(--pl-green-100);
  --color-secondary:      var(--pl-green-800);
  --color-secondary-light: var(--pl-green-600);
  --color-accent:         var(--pl-green-800);
  --color-accent-dark:    var(--pl-green-900);
  --gold:                 var(--pl-warm);
  --amber:                var(--pl-warm);
  --color-border:         var(--pl-rule);
  --color-border-soft:    var(--pl-rule-soft);
  --shadow-sm:            var(--pl-e-0);
  --shadow-md:            var(--pl-e-1);
  --shadow-lg:            var(--pl-e-2);
  --shadow-cta:           var(--pl-e-cta);
}

/* =========================================================
   1. Typography — a real scale, so hierarchy is readable
      at a glance. Steps are ≥1.25 apart (WCAG-adjacent
      readability guidance, and it simply looks better).
   ========================================================= */

body { text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; }

/* main.js gives every section `.reveal-up`, which is `opacity: 0` until an
   IntersectionObserver marks it in-view. On this site that meant 14 of 16
   sections on a landing page started invisible: the hero fades in (delaying
   LCP), and if the script is slow or blocked the page is blank. Content is
   shown immediately instead — the polish layer animates with transform and
   hover states, which never hide anything. */
.reveal-up { opacity: 1 !important; transform: none !important; }

h1, .modern-hero-h1, .hub-h1 {
  font-size: clamp(2.05rem, 1.35rem + 2.6vw, 3.4rem);
  line-height: 1.08;
  letter-spacing: -0.025em;
  font-weight: 800;
}
h2, .section-title {
  font-size: clamp(1.5rem, 1.15rem + 1.35vw, 2.15rem);
  line-height: 1.16;
  letter-spacing: -0.02em;
  font-weight: 750;
}
h3 {
  font-size: clamp(1.08rem, 1rem + .38vw, 1.27rem);
  line-height: 1.28;
  letter-spacing: -0.012em;
  font-weight: 700;
}

/* Prose measure: 65–75 characters is the readable band. */
.pbody .prose p,
.pbody .prose li,
.pbody .prose-lede { max-width: 68ch; }

/* ---------------------------------------------------------
   Highlight system — ONE meaning per style, or it stops
   working as a scanning aid and becomes decoration.

     <strong>  → dark bold  = the point of the sentence
     .hl       → green 600  = named entity / section keyword
     <a>       → green + underline = navigation

   Links keep their underline precisely so .hl is never
   mistaken for something clickable.
   --------------------------------------------------------- */
.pbody .prose strong,
.prose-page strong,
.legacy-landing strong { color: var(--pl-ink); font-weight: 700; }

.hl {
  color: var(--pl-green-600);
  font-weight: 600;
  text-decoration: none;
}
h1 .hl, h2 .hl, h3 .hl { font-weight: inherit; color: var(--pl-green-600); }
/* Never inside a table or a warning box — those have their own emphasis. */
.table-scroll .hl, .compare-table .hl { color: inherit; font-weight: inherit; }

/* =========================================================
   2. Buttons — one primary, one quiet. Both with a real
      focus ring (never outline:none without a replacement).
   ========================================================= */

.pbody .btn, .btn, .cw1-btn-primary {
  border-radius: var(--pl-r-md);
  font-weight: 700;
  letter-spacing: -0.005em;
  transition: transform var(--pl-fast) var(--pl-ease),
              box-shadow var(--pl-base) var(--pl-ease),
              background-color var(--pl-fast) var(--pl-ease),
              border-color var(--pl-fast) var(--pl-ease);
  will-change: transform;
}
.pbody .btn-primary, .btn-primary, body.preset-botanical .btn-primary {
  background: var(--pl-green-800);
  color: #fff !important;
  box-shadow: var(--pl-e-cta);
  border: 1px solid transparent;
}
.pbody .btn-primary:hover, .btn-primary:hover, body.preset-botanical .btn-primary:hover {
  background: var(--pl-green-700);
  box-shadow: 0 12px 26px -10px rgba(18,80,58,.62);
}
.pbody .btn-ghost, .btn-secondary {
  background: var(--pl-paper);
  color: var(--pl-green-800);
  border: 1px solid var(--pl-rule);
  box-shadow: var(--pl-e-0);
}
.pbody .btn-ghost:hover, .btn-secondary:hover {
  border-color: var(--pl-green-600);
  background: var(--pl-green-050);
}
.btn-accent { background: var(--pl-green-800) !important; color: #fff !important; }
.btn-accent:hover { background: var(--pl-green-700) !important; }

/* Tap targets: 44px minimum on touch (WCAG 2.5.8 / Apple HIG). */
.btn, .pbody .btn, .nav-link, .faq-item summary { min-height: 44px; }
.pbody .btn, .btn { display: inline-flex; align-items: center; justify-content: center; }

:where(a, button, summary, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--pl-green-600);
  outline-offset: 2px;
  border-radius: 6px;
}

/* =========================================================
   3. Cards — one radius, one border, two elevations.
      Applied to the portal components AND to every legacy
      card class so the whole site reads as one system.
   ========================================================= */

.pbody .cat-card, .pbody .art-card, .pbody .ing-card, .pbody .prod-card,
.pbody .toc, .pbody .faq-item, .pbody .table-scroll,
.card, .benefit-card, .mechanism-card, .testi-card, .timeline-step,
.howtake-step, .contact-card, .who-card, .ing-card-modern,
details.faq-item, .trust-bar-item {
  border-radius: var(--pl-r-lg);
  border: 1px solid var(--pl-rule);
  background: var(--pl-paper);
  box-shadow: var(--pl-e-0);
  transition: transform var(--pl-base) var(--pl-ease),
              box-shadow var(--pl-base) var(--pl-ease),
              border-color var(--pl-base) var(--pl-ease);
}

/* Interior air — the single most effective "premium" lever. */
.pbody .cat-card { padding: var(--pl-5) var(--pl-5); gap: var(--pl-4); align-items: center; }
.pbody .art-card-body { padding: var(--pl-5) var(--pl-5) var(--pl-6); gap: var(--pl-3); }
.pbody .ing-card-body { padding: var(--pl-4) var(--pl-4) var(--pl-5); }
.pbody .prod-card-body { padding: var(--pl-5) var(--pl-5) var(--pl-6); gap: var(--pl-3); }
/* The fact box is the one deliberately tinted panel on a page — it is the
   "read this if you read nothing else" block, so it should not look like
   every other white card. */
.pbody .factbox {
  padding: var(--pl-6) var(--pl-7);
  border-radius: var(--pl-r-lg);
  border: 1px solid var(--pl-green-200);
  background: linear-gradient(180deg, var(--pl-green-100), var(--pl-green-050));
  box-shadow: none;
}
.pbody .factbox-list > div { padding-block: var(--pl-2); border-bottom: 1px solid rgba(18,80,58,.10); }
.pbody .factbox-list > div:last-child { border-bottom: 0; }
.pbody .toc { padding: var(--pl-5) var(--pl-6); margin-block: var(--pl-8) var(--pl-9); }
.pbody .prose .factbox { margin-bottom: var(--pl-2); }
.benefit-card, .mechanism-card, .who-card, .testi-card,
.timeline-step, .howtake-step, .contact-card { padding: var(--pl-6); }

/* Grid rhythm — one gap value per breadth of card. */
.pbody .cat-grid { gap: var(--pl-4); }
.pbody .ing-grid { gap: var(--pl-4); }
.pbody .prod-grid { gap: var(--pl-5); }
.pbody .art-grid  { gap: var(--pl-6); }

/* =========================================================
   4. Section rhythm and tint — one tint, used alternately.
      The old four-colour gradient set (blue/cyan/purple/
      green) is collapsed into a single paper tint.
   ========================================================= */

.sec-gradient-blue, .sec-gradient-cyan, .sec-gradient-purple, .sec-gradient-green,
body.preset-botanical .sec-gradient-blue, body.preset-botanical .sec-gradient-cyan,
body.preset-botanical .sec-gradient-purple, body.preset-botanical .sec-gradient-green {
  background: linear-gradient(180deg, var(--pl-green-050) 0%, var(--pl-paper) 100%);
}
.pbody .section-alt { background: var(--pl-green-050); }

.pbody .section { padding-block: clamp(var(--pl-9), 6vw, var(--pl-11)); }
.section { padding-block: clamp(var(--pl-9), 6vw, var(--pl-11)); }
.pbody .section-head { margin-bottom: clamp(var(--pl-6), 3vw, var(--pl-8)); }

/* H2 accent rule — a hairline, not a slab. */
.pbody .prose-section h2::after {
  width: 44px; height: 3px; border-radius: 2px;
  background: linear-gradient(90deg, var(--pl-green-800), var(--pl-green-600));
  margin-top: var(--pl-3);
}
.heading-accent::after,
body.preset-botanical .heading-accent::after {
  height: 3px; border-radius: 2px;
  background: linear-gradient(90deg, var(--pl-green-800), var(--pl-green-600));
}

/* =========================================================
   5. Media — nothing cropped, air preserved, no CLS.
   ========================================================= */

img, picture img { max-width: 100%; height: auto; }

/* Card media boxes. The thumbnail file is already cropped to 3:2 at build
   time, so the box matches the file exactly and the browser crops nothing;
   `overflow:hidden` exists only to contain the hover zoom. */
.pbody .art-card-media {
  overflow: hidden;
  aspect-ratio: 3 / 2;
  border-bottom: 1px solid var(--pl-rule-soft);
  background: var(--pl-green-050);
}
.pbody .art-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Composed banners — the ones with ingredient names or a product baked into
   the artwork — are shown whole. Cutting an edge off those removes the point
   of the image, so the box letterboxes them on the section tint instead. */
.pbody .art-card-media--whole { background: var(--pl-green-050); }
.pbody .art-card-media--whole img { object-fit: contain; padding: var(--pl-3); }

/* Ingredient photos are square files in a square box — nothing is cut. */
.pbody .ing-card-media {
  overflow: hidden;
  aspect-ratio: 1 / 1;
  border-bottom: 1px solid var(--pl-rule-soft);
  background: var(--pl-green-050);
}
.pbody .ing-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---------------------------------------------------------
   Banners: shown WHOLE, never cropped, with real air at the
   sides. The image sits ~180px narrower than its container,
   which is what stops a banner reading as a pasted-in strip.
   --------------------------------------------------------- */
.pbody .art-hero-media {
  max-width: 860px;                 /* container is 1220 → ~180px air each side */
  margin-inline: auto;
}
.pbody .art-hero-img {
  width: 100%;
  height: auto;                     /* native ratio — no max-height, no crop */
  object-fit: contain;
  display: block;
}
.pbody .hub-hero-img { width: 100%; height: auto; object-fit: contain; display: block; }
.pbody .art-card-img, .pbody .ing-card-img {
  transition: transform var(--pl-slow) var(--pl-ease-out);
  will-change: transform;
}

/* Product packshots are never cropped and never edge-to-edge — they sit
   in a tinted box with breathing room, which is what reads as "premium". */
.pbody .prod-card-media {
  background: linear-gradient(180deg, var(--pl-green-050), var(--pl-paper));
  border-bottom: 1px solid var(--pl-rule-soft);
  padding: var(--pl-5);
}
.pbody .prod-hero-img, .pbody .ing-hero-img, .pbody .hub-hero-img, .pbody .art-hero-img {
  border-radius: var(--pl-r-xl);
  border: 1px solid var(--pl-rule);
  box-shadow: var(--pl-e-1);
}
.pbody .prod-hero-img { background: linear-gradient(180deg, var(--pl-green-050), var(--pl-paper)); padding: var(--pl-6); }

/* =========================================================
   6. Hero — stronger hierarchy, quieter surroundings.
   ========================================================= */

.pbody .hub-hero {
  background:
    radial-gradient(1200px 420px at 78% -10%, var(--pl-green-050) 0%, transparent 70%),
    var(--pl-paper);
  padding-block: clamp(var(--pl-9), 6vw, var(--pl-11)) clamp(var(--pl-8), 5vw, var(--pl-10));
}
.pbody .hub-lede, .pbody .cat-lede, .pbody .art-lede, .pbody .prod-hero-lede {
  font-size: clamp(1.06rem, 1rem + .35vw, 1.2rem);
  line-height: 1.62;
  color: var(--pl-ink-2);
}
.pbody .hub-stats { border-top: 1px solid var(--pl-rule); padding-top: var(--pl-6); gap: var(--pl-7); }
.pbody .hub-stats strong { font-size: 1.7rem; color: var(--pl-green-800); letter-spacing: -0.03em; }

/* No kicker stacked above an H1. The portal pages were built without one;
   hiding it on the legacy heroes is what makes the site read as one design
   rather than two. The H1 already states the topic. */
.modern-hero-content > .eyebrow,
.modern-hero > .container > .eyebrow { display: none; }

.pbody .cat-hero, .pbody .art-hero, .pbody .ing-hero, .pbody .prod-hero {
  background: linear-gradient(180deg, var(--pl-green-050) 0%, var(--pl-paper) 100%);
  border-bottom: 1px solid var(--pl-rule-soft);
}

/* Hero composition.
   DOM order is head → media → detail, which gives the right reading order on
   a phone: title, then the product, then the facts and the action. Desktop
   reassembles it into the two-column composition with grid areas, so the
   image is back on the left and nothing moves. */
.pbody .prod-hero-inner, .pbody .ing-hero-inner { display: grid; gap: clamp(var(--pl-5), 3vw, var(--pl-8)); }

@media (min-width: 901px) {
  .pbody .prod-hero-inner {
    grid-template-columns: 340px minmax(0, 1fr);
    grid-template-areas: "media head" "media detail";
    align-content: center;
  }
  .pbody .ing-hero-inner {
    grid-template-columns: 320px minmax(0, 1fr);
    grid-template-areas: "media head" "media detail";
    align-content: center;
  }
  .pbody .prod-hero-media, .pbody .ing-hero-media { grid-area: media; align-self: center; }
  .pbody .prod-hero-head,  .pbody .ing-hero-head  { grid-area: head; align-self: end; }
  .pbody .prod-hero-detail,.pbody .ing-hero-detail{ grid-area: detail; align-self: start; }
}

@media (max-width: 900px) {
  .pbody .prod-hero-media, .pbody .ing-hero-media { max-width: 260px; margin-inline: auto; }
}

/* Review titles are descriptive and long; at full display size they run to
   three lines and push the facts below the fold. One step down keeps the
   hierarchy and the composition. */
.pbody .prod-hero-head h1 { font-size: clamp(1.85rem, 1.25rem + 1.75vw, 2.6rem); }
.pbody .prod-hero-head { margin-bottom: 0; }
.pbody .prod-hero-lede { margin-top: var(--pl-4); }

/* Fact rows in product/ingredient heroes — aligned, ruled, calm. */
.pbody .prod-hero-facts li { padding-block: var(--pl-2); border-bottom: 1px solid var(--pl-rule-soft); }
.pbody .prod-hero-facts li:last-child { border-bottom: 0; }
.pbody .prod-hero-cta { margin-top: var(--pl-6); }

/* =========================================================
   7. Chips, badges, prices — where the warm accent lives.
   ========================================================= */

.pbody .evidence-badge { border-radius: var(--pl-r-sm); letter-spacing: .045em; }
.pbody .prod-price { color: var(--pl-warm); font-weight: 800; font-variant-numeric: tabular-nums; }
.pbody .prod-ings li a { border-radius: var(--pl-r-sm); border: 1px solid transparent; }
.pbody .prod-ings li a:hover { border-color: var(--pl-green-200); }
.pbody .cat-icon { border-radius: var(--pl-r-md); }

/* =========================================================
   8. Motion. Transform + opacity only — both composited on
      the GPU, neither triggers layout or paint. No parallax,
      no looping ambient movement, nothing that runs forever.
   ========================================================= */

@media (prefers-reduced-motion: no-preference) {

  /* Hero entrance: one pass on load, CSS only, zero JS, and it
     cannot cause CLS because only opacity and transform move. */
  .pbody .hub-hero-text > *,
  .pbody .cat-hero > .container > *,
  .pbody .art-hero > .container > *,
  .pbody .ing-hero-text > *,
  .pbody .prod-hero-text > * {
    animation: pl-rise var(--pl-slow) var(--pl-ease-out) both;
  }
  .pbody .hub-hero-text > *:nth-child(2),
  .pbody .ing-hero-text > *:nth-child(2),
  .pbody .prod-hero-text > *:nth-child(2) { animation-delay: 60ms; }
  .pbody .hub-hero-text > *:nth-child(3),
  .pbody .ing-hero-text > *:nth-child(3),
  .pbody .prod-hero-text > *:nth-child(3) { animation-delay: 120ms; }
  .pbody .hub-hero-text > *:nth-child(4),
  .pbody .ing-hero-text > *:nth-child(4),
  .pbody .prod-hero-text > *:nth-child(4) { animation-delay: 180ms; }
  .pbody .hub-hero-text > *:nth-child(n+5) { animation-delay: 240ms; }

  .pbody .hub-hero-media, .pbody .ing-hero-media, .pbody .prod-hero-media {
    animation: pl-fade-scale 640ms var(--pl-ease-out) both;
  }

  /* Card hover: lift + shadow. 3px is enough to feel responsive
     and small enough never to feel like a toy. */
  .pbody .cat-card:hover, .pbody .art-card:hover,
  .pbody .ing-card:hover, .pbody .prod-card:hover,
  .card:hover, .benefit-card:hover, .mechanism-card:hover, .testi-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--pl-e-2);
    border-color: var(--pl-green-200);
  }
  .pbody .art-card:hover .art-card-img,
  .pbody .ing-card:hover .ing-card-img { transform: scale(1.04); }

  .pbody .btn:hover, .btn:hover { transform: translateY(-1px); }
  .pbody .btn:active, .btn:active { transform: translateY(0); }

  /* FAQ body fades in rather than snapping. */
  details.faq-item[open] .faq-answer,
  details.faq-item[open] .faq-body { animation: pl-fade var(--pl-base) var(--pl-ease) both; }
}

@keyframes pl-rise {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes pl-fade-scale {
  from { opacity: 0; transform: scale(.97); }
  to   { opacity: 1; transform: scale(1); }
}
@keyframes pl-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* The whole motion layer is opt-out by default for anyone who asked
   their OS to reduce motion — nothing here is load-bearing. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* =========================================================
   9. Header, breadcrumbs, footer — finishing pass.
   ========================================================= */

.portal-header { border-bottom: 1px solid var(--pl-rule); }
.portal-header.is-sticky { box-shadow: var(--pl-e-1); }
.portal-nav .nav-link { border-radius: var(--pl-r-sm); }
.portal-nav .mega-panel { border-radius: var(--pl-r-lg); box-shadow: var(--pl-e-2); }
.breadcrumbs { background: var(--pl-paper-2); }
.portal-footer { background: var(--pl-green-900); }
/* The site mark is a white badge, so it reads on the dark footer as well as
   on the white header — one asset, both contexts. */
.portal-header .brand-logo, .portal-footer .footer-logo {
  border-radius: 10px;
  box-shadow: 0 1px 3px rgba(0,0,0,.10);
}
.portal-footer .footer-disclaimer-bar { background: #0a2d20; }

.pbody .related-section { border-top: 1px solid var(--pl-rule); background: var(--pl-paper-2); }
.pbody .editorial-note {
  border-left: 3px solid var(--pl-green-800);
  border-radius: 0 var(--pl-r-lg) var(--pl-r-lg) 0;
  background: var(--pl-green-050);
  padding: var(--pl-6) var(--pl-7);
}

/* =========================================================
   10. Mobile. Air preserved, nothing cropped, nothing wider
       than the viewport.
   ========================================================= */

html, body { overflow-x: clip; }

@media (max-width: 768px) {
  :root { --pl-9: 44px; --pl-10: 52px; --pl-11: 60px; }

  .pbody .container, .container { padding-inline: var(--pl-4); }

  /* Cards keep their air, just a little less of it. */
  .pbody .cat-card { padding: var(--pl-4); }
  .pbody .art-card-body, .pbody .prod-card-body { padding: var(--pl-4) var(--pl-4) var(--pl-5); }
  .pbody .factbox, .pbody .editorial-note { padding: var(--pl-5); }
  .benefit-card, .mechanism-card, .who-card, .testi-card,
  .timeline-step, .howtake-step, .contact-card { padding: var(--pl-5); }

  /* Packshots: contained, never cropped, with margin around them. */
  .pbody .prod-card-media { height: 180px; padding: var(--pl-4); }
  .pbody .prod-hero-img { padding: var(--pl-4); }
  .pbody .prod-hero-media, .pbody .ing-hero-media { margin-inline: auto; }

  /* Full-width primary action — the standard mobile pattern. */
  .pbody .hub-hero-actions { flex-direction: column; align-items: stretch; }
  .pbody .hub-hero-actions .btn, .pbody .prod-hero-cta .btn { width: 100%; }

  /* Wide content scrolls inside its own box, never the page. */
  .table-scroll, .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

  /* Mobile heroes: keep the entrance animation cheap on low-end devices. */
  .pbody .hub-hero-media, .pbody .ing-hero-media, .pbody .prod-hero-media { animation: none; }
}

@media (max-width: 420px) {
  .pbody .hub-stats { gap: var(--pl-4) var(--pl-5); }
  .pbody .hub-stats strong { font-size: 1.45rem; }
}

/* Users on a metered or low-memory device get the static site. */
@media (prefers-reduced-data: reduce) {
  *, *::before, *::after { animation: none !important; }
}
