/* =====================================================================
   column-fix.css — sitewide guard against narrow / long text-column ribbons
   ---------------------------------------------------------------------
   Loaded LAST (after the per-page stylesheets) and uses !important so it
   overrides the hardcoded `repeat(N, 1fr)` grids that individual page CSS
   files declare (those force a fixed column count, so tracks shrink to
   120–276px and text-heavy cards become tall thin ribbons).

   Principle: text-card grids WRAP to fewer columns instead of shrinking
   tracks below a readable width. `min(100%, X)` keeps a single full-width
   column on mobile and inside narrow parents.

   Parent selector includes `.container` because several pages turn a plain
   `.container` block into a grid via their own CSS. `grid-template-columns`
   is inert on a non-grid (block) element, so listing `.container` here only
   takes effect where the container actually is a grid — harmless elsewhere.

   Tune the three floors here (300 / 280 / 440) to taste.
   ===================================================================== */

/* =====================================================================
   ".jack" — the user's named, reusable styled text container. Use it to
   enclose loose prose that would otherwise sit directly in a section with
   no visual frame. A clean white card with a blue accent edge, comfortable
   padding and readable line-height. (Named per request.)
   ===================================================================== */
.jack {
  position: relative;
  background: linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
  border: 1px solid #e6ecf3;
  border-radius: 14px;
  padding: 1.75rem 1.95rem 1.75rem 2.2rem;
  margin: 1.75rem auto;
  box-shadow: 0 1px 2px rgba(10, 37, 64, .05), 0 14px 34px -10px rgba(10, 37, 64, .12);
  overflow: hidden;
}
/* corporate gradient accent edge (brand navy -> blue -> gold) */
.jack::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 5px;
  background: linear-gradient(180deg, #0a2540 0%, #0a66c2 55%, #c9a227 100%);
}
/* faint brand-tint flourish in the top-right corner */
.jack::after {
  content: "";
  position: absolute;
  top: -40px; right: -40px;
  width: 130px; height: 130px;
  background: radial-gradient(circle at center, rgba(10,102,194,.06) 0%, rgba(10,102,194,0) 70%);
  pointer-events: none;
}
.jack > :first-child { margin-top: 0; }
.jack > :last-child { margin-bottom: 0; }
.jack p { margin: 0 0 0.9rem; line-height: 1.75; color: var(--text-medium, #41566b); }
.jack h2, .jack h3, .jack h4 { margin: 0 0 0.85rem; color: var(--primary-navy, #0a2540); }
.jack ul, .jack ol { margin: 0 0 0.9rem; padding-left: 1.25rem; line-height: 1.8; color: var(--text-medium, #41566b); }
.jack li { margin-bottom: 0.4rem; }
.jack strong { color: var(--primary-navy, #0a2540); }
.jack .jack-eg { background: var(--light-gray, #f5f7fa); border-radius: 8px; padding: 1rem 1.1rem; margin-top: 1rem; }
.jack .jack-eg p { margin: 0; }

/* =====================================================================
   Loose prose / list blocks in the narrow ".container-sm" wrappers get the
   same framed ".jack" treatment, so this kind of free-floating text is ALWAYS
   inside a well-formatted container (per request). Margins are left to the
   existing .container-sm* rules; only the visual frame is added here.
   ===================================================================== */
.container-sm, .container-sm-mt-2, .container-sm-mb-1, .container-sm-mb-15, .container-sm-mb-25 {
  position: relative;
  background: linear-gradient(180deg, #ffffff 0%, #fbfdff 100%) !important;
  border: 1px solid #e6ecf3;
  border-radius: 14px;
  padding: 1.6rem 1.85rem 1.6rem 2.1rem;
  overflow: hidden;
}
.container-sm::before, .container-sm-mt-2::before, .container-sm-mb-1::before,
.container-sm-mb-15::before, .container-sm-mb-25::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 5px;
  background: linear-gradient(180deg, #0a2540 0%, #0a66c2 55%, #c9a227 100%);
}
.container-sm > :first-child, .container-sm-mt-2 > :first-child,
.container-sm-mb-1 > :first-child, .container-sm-mb-15 > :first-child, .container-sm-mb-25 > :first-child { margin-top: 0; }
.container-sm > :last-child, .container-sm-mt-2 > :last-child,
.container-sm-mb-1 > :last-child, .container-sm-mb-15 > :last-child, .container-sm-mb-25 > :last-child { margin-bottom: 0; }

/* =====================================================================
   ".product-content" = loose body prose (an <h2> + paragraphs sitting bare
   in a section with no card/frame, used on ~39 product/policy pages). Give
   it the same subtle framed treatment as .container-sm so free-floating text
   is always inside a well-formatted container. Keeps main.css's centred
   max-width:800px; only the visual frame + inner spacing are added here.
   ===================================================================== */
.product-content {
  position: relative;
  background: linear-gradient(180deg, #ffffff 0%, #fbfdff 100%);
  border: 1px solid #e6ecf3;
  border-radius: 14px;
  padding: 1.85rem 2rem 1.85rem 2.35rem;
  overflow: hidden;
}
.product-content::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 5px;
  background: linear-gradient(180deg, #0a2540 0%, #0a66c2 55%, #c9a227 100%);
}
.product-content > :first-child { margin-top: 0; }
.product-content > :last-child { margin-bottom: 0; }

@media (min-width: 768px) {

  /* 1) Generic text-card grids → ~300px minimum track ------------------ */
  :is([class*="grid"], .container):has(> .card),
  :is([class*="grid"], .container):has(> .feature-card),
  :is([class*="grid"], .container):has(> .service-card),
  :is([class*="grid"], .container):has(> .standard-card),
  :is([class*="grid"], .container):has(> .equipment-compliance-card),
  :is([class*="grid"], .container):has(> .upgrade-type-card),
  :is([class*="grid"], .container):has(> .method-card),
  :is([class*="grid"], .container):has(> .resource-card),
  :is([class*="grid"], .container):has(> .topic-card),
  :is([class*="grid"], .container):has(> .application-card),
  :is([class*="grid"], .container):has(> .info-card),
  :is([class*="grid"], .container):has(> .feature-item) {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)) !important;
  }

  /* 1b) .service-mega-grid shrink-wraps to its widest card (a grid intrinsic-sizing
        quirk) leaving a single tall column. Force it to fill its container width and
        wrap to even multi-column tracks. */
  .service-mega-grid {
    width: 100% !important;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)) !important;
  }

  /* 2) Step lists laid out as grids → ~300px minimum ------------------- */
  .process-steps,
  :is([class*="grid"], .container, .bd-train):has(> .process-step),
  :is([class*="grid"], .container, .bd-train):has(> .process-step-card),
  :is([class*="grid"], .container, .bd-train):has(> .bd-step) {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)) !important;
  }

  /* 2b) ...but .process-steps is often a FLEX row (grid-template is then
         inert), so size the flex children directly to force them to wrap
         at a readable width instead of squeezing to thin ribbons. */
  .process-steps { flex-wrap: wrap !important; }
  .process-steps > .process-step {
    flex: 1 1 320px !important;
    min-width: 300px !important;
    max-width: none !important;
  }

  /* 3) Dense prose / product cards need more room → ~440px (≈2 wide) ----
     Listed AFTER rule 1 so it wins for cards that carry both .card and a
     dense modifier (source-order tiebreak at equal specificity). */
  :is([class*="grid"], .container):has(> .card-large),
  :is([class*="grid"], .container):has(> .ref-card),
  :is([class*="grid"], .container):has(> .product-card) {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr)) !important;
  }

  /* 4) "process-flow" step rows: lay the step cards out as an even, spaced
        responsive grid (wraps to equal columns) instead of a cramped flex row
        with clipped text. ------------------------------------------------- */
  .process-flow:has(> .process-step-card) {
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)) !important;
    gap: 1.5rem !important;
    align-items: stretch;
  }
  .process-flow > .process-step-card {
    min-width: 0 !important;
    max-width: none !important;
    overflow: visible !important;
  }

  /* 5) Numbered "process-flow-step" cards (step-number + step-content) are
        often dropped straight into a .container as block elements, so they
        stack in a single column. Lay any run of two or more out as a
        readable multi-column grid; section header/intro span the full row.
        (Replaces the old max-width clamp that squeezed them into a column.) */
  :is(.container, [class*="grid"], .process-flow):has(> .process-flow-step + .process-flow-step) {
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)) !important;
    gap: 1.5rem !important;
    align-items: stretch;
  }
  :is(.container, [class*="grid"], .process-flow):has(> .process-flow-step + .process-flow-step) > :not(.process-flow-step) {
    grid-column: 1 / -1;
  }
  .process-flow-step {
    max-width: none !important;
    min-width: 0 !important;
    padding: 1.5rem 1.6rem !important;   /* keep text off the card edges */
    box-sizing: border-box;
  }
  .process-flow-step > .step-content { padding: 0 !important; }
}

/* Hero stat labels: on dark hero backgrounds the global "hero-content p ->
   dark" theme rule turns the <p> inside .hero-stat .label nearly invisible.
   Force light text for the value and label so hero stats stay readable.
   (Outside the media query so it applies at every breakpoint.) */
.hero-stat .value { color: #fff !important; }
.hero-stat .label,
.hero-stat .label p { color: rgba(255, 255, 255, 0.85) !important; }
.hero-stat .icon i { color: #fff !important; }

/* The global ".py-2 { padding: 2rem !important }" utility is far too large for
   list items — it gives every bullet 64px of vertical padding, leaving big
   gaps between lines inside cards. Tighten it for list items specifically. */
li.py-2 { padding-top: 0.3rem !important; padding-bottom: 0.3rem !important; }

/* ---------------------------------------------------------------------------
   AGGRESSIVE vertical-space reduction for process / step / checklist cards
   (pilot-plant-design, services workflow, etc.). The cards stay EQUAL height,
   but the internal spacing is compressed so they no longer read as airy:
   smaller badge/icon margins, tight prose→list gap, and dense bullet lists. */
.cards-grid .card .step-badge,
.card-grid .card .step-badge { margin-bottom: 0.5rem !important; }
.cards-grid .card > .card-icon,
.card-grid .card > .card-icon { margin-bottom: 0.4rem !important; }
.cards-grid .card > h3,
.card-grid .card > h3 { margin-bottom: 0.3rem !important; }
.cards-grid .card > p,
.card-grid .card > p { margin-bottom: 0.45rem !important; }
.card ul.list-none,
.process-step ul.list-none,
.process-flow-step ul.list-none { margin-top: 0.25rem !important; margin-bottom: 0 !important; }

/* THE key fix for the "mess"/mid-card gap: the card paragraph has flex-grow:1,
   so it expands and pushes the bullet list down, opening a large gap between the
   prose and the bullets. Stop the paragraph growing so bullets sit directly under
   the text. */
.card:has(> ul) > p,
.card:has(ul.list-none) > p,
.cards-grid .card > p { flex-grow: 0 !important; }

/* Bottom-align the action button so buttons line up horizontally across an
   equal-height row. The mt-1 utility pins the button with a fixed 8px top margin,
   so it follows the content and ends up at different heights per card; margin-top:auto
   pushes it to the card bottom where all the buttons align. */
@media (min-width: 768px) {
  .cards-grid .card > a.btn:last-child,
  .card-grid .card > a.btn:last-child,
  .cards-grid .card > .btn:last-child,
  .cards-grid .card > a.btn-secondary:last-child { margin-top: auto !important; }
}
/* (Cards stay EQUAL height — the site default. With flex-grow:0 above, the bullets
   sit directly under the paragraph and any spare space is a small pad at the card
   bottom, so equal-height no longer produces a mid-card gap.) */
/* dense bullets: minimal padding/margin, tighter line-height */
.card ul.list-none > li,
.card ul li.py-2, .card ul li.py-3,
li.py-2, li.py-3 {
  padding-top: 0.12rem !important;
  padding-bottom: 0.12rem !important;
  margin-top: 0 !important;
  margin-bottom: 0 !important;
  line-height: 1.4 !important;
}

/* Cards are kept EQUAL height within a row (site default: .card{height:100%} +
   grid align-items:stretch) — the user's requirement, text unchanged. To stop the
   equal-height look from reading as "too much vertical space", a flex-grow paragraph
   is prevented from ballooning so the spare space collects tidily at the BOTTOM of
   the card (a clean equal-height card) rather than opening a gap in the middle.
   Buttons still bottom-align via their own margin-top:auto. */
@media (min-width: 768px) {
  :is(.cards-grid, .card-grid, .features-grid, .feature-card-grid, .content-grid, [class*="grid"]):has(> .card) > .card > p.flex-grow {
    flex-grow: 0 !important;
  }
}

/* Numbered process-step badges read as oversized (56px rounded square). Make them
   a compact, consistent circle sitewide. */
.process-step .step-number,
.process-flow .step-number {
  width: 44px !important;
  height: 44px !important;
  min-width: 44px !important;
  border-radius: 50% !important;
  font-size: 1.05rem !important;
  margin-left: auto !important;
  margin-right: auto !important;
  margin-bottom: 0.9rem !important;
}

/* Timeline / workflow steps (services-overview Consultation→Support): the steps had
   max-width:200px, so they sat narrow inside their ~376px grid columns leaving big
   horizontal gaps and not matching the full-width cards elsewhere. Let them fill the
   column (full width), and compact the internals so they read like the other cards. */
.process-timeline { gap: 1rem !important; }
.process-timeline .timeline-step,
.timeline-step { max-width: none !important; width: auto !important; padding: 1.25rem 1.25rem !important; }
.timeline-step .tl-icon { width: 48px !important; height: 48px !important; margin-bottom: 0.6rem !important; }
.timeline-step .tl-title { margin-bottom: 0.3rem !important; }
.timeline-step .tl-desc { line-height: 1.5 !important; }

/* Tighten the prose -> checklist gap inside step/feature cards so the bullet lists
   no longer read as airy. */
.card ul.list-none,
.process-step ul.list-none,
.process-flow-step ul.list-none { margin-top: 0.4rem !important; }

/* Dark-background stat & CTA panels: their page CSS sets a dark gradient with
   white text, but the light theme overrides the background to white, leaving
   white-on-white (invisible). Force BOTH the dark gradient and light text. */
.metrics-section, .cta-section-dark {
  background: linear-gradient(135deg, #0a2540 0%, #1a3a5c 100%) !important;
}
.metrics-section, .metrics-section h2, .metrics-section h3,
.metrics-section .metric-item, .metric-item .number,
.cta-section-dark, .cta-section-dark h2, .cta-section-dark h3 { color: #fff !important; }
.metric-item .label, .cta-section-dark p,
.cta-section-dark a:not(.btn) { color: rgba(255, 255, 255, 0.85) !important; }

/* Calculator result cards: the "highlight" card has a NAVY background, but the
   .result-value uses a navy→blue gradient text-clip (transparent fill) which is
   invisible on dark. Force highlight-card values/labels to white. Fixes e.g.
   chemical-dosing "Total Daily Chemical Cost £29.7" being unreadable. */
body.is-calc .result-card.highlight .result-value,
body.is-calc .result-highlight .result-value,
body.is-calc .result-card.highlight .result-value.text-primary-blue {
  background: none !important;
  -webkit-text-fill-color: #fff !important;
  color: #fff !important;
}
body.is-calc .result-card.highlight .result-label,
body.is-calc .result-highlight .result-label { color: rgba(255,255,255,0.88) !important; }

/* New advanced dosing calculator (.jdc): the source is dark-themed, so its metric
   value text is white — invisible on the light panels we recoloured it to. Force
   dark text for the metric values/labels. */
.jdc .metric .v { color: #fff !important; }
.jdc .metric .v .u { color: #9fb3c8 !important; }

/* Standards / compliance pages: the equipment-card headers are a navy gradient with
   white text BY DESIGN, but theme-light forces the heading text to navy too —
   navy-on-navy = invisible (the "mess" on standards-uk / -canada / -usa etc.).
   Restore white header text/icons so the navy headers read correctly sitewide. */
.equipment-compliance-card .card-header h3,
.equipment-compliance-card .card-header h4,
.equipment-compliance-card .card-header p,
.equipment-compliance-card .card-header > span,
.carbon-type-header h3,
.carbon-type-header i {
  color: #fff !important;
  -webkit-text-fill-color: #fff !important;
}

/* =====================================================================
   No hover movement — containers/cards must not shift or lift on hover
   (per request). Keep any shadow change, but cancel the transform so the
   box stays put. Sitewide.
   ===================================================================== */
:is(.card, .feature-card, .service-card, .service-mega-card, .topic-card,
    .region-card, .application-card, .standard-card, .equipment-compliance-card,
    .method-card, .resource-card, .info-card, .product-card, .calc-card,
    .scen-card, .carbon-type-card, .cert-card, .ref-card, .case-card,
    .upgrade-type-card, .industry-card, .solution-card, .tech-card,
    [class*="card"]):hover {
  transform: none !important;
}
.jdc .metric:hover, .jdc .line:hover, .timeline-step:hover { transform: none !important; }

/* =====================================================================
   Mobile responsiveness guards (loaded last; site-wide).
   Targets the audit findings: wide tables forcing the whole page to
   scroll sideways, oversized SVG diagrams/maps, and long unbroken
   strings (formulas, hex, URLs) overflowing their container.
   ===================================================================== */
/* SVGs never exceed their container (diagrams, schematics, maps). */
svg { max-width: 100%; }
/* Long chemical formulas, hex values and URLs wrap instead of overflowing. */
p, li, dd, td, th, h1, h2, h3, h4, h5, figcaption,
.lead, .hero-description, .section-subtitle, .note, .card p, .feature-content p {
  overflow-wrap: break-word;
}
@media (max-width: 768px) {
  /* Every data table becomes horizontally scrollable WITHIN itself instead
     of forcing the entire page to scroll sideways. Covers the 401 pages
     whose tables are not wrapped in .table-responsive (incl. dosing-
     calculator .reftab, .wtab and any unclassed <table>). */
  table {
    display: block;
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* Wrapped tables: let the .table-responsive WRAPPER do the scrolling and
     keep the table a real table (aligned columns) with a readable min-width,
     so multi-column data tables scroll sideways instead of crushing headers
     into mid-word breaks ("PARA METER"). .table-responsive is styled only in
     the unloaded legacy-styles.css, so its mobile behaviour lives here. */
  .table-responsive, .table-wrap, .table-wrapper {
    display: block;
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* :not(#_) lifts specificity above main.css's
     `.table-responsive .refinery-table{min-width:280px!important}` (0,2,0),
     which otherwise keeps the table narrow enough to crush its columns. */
  .table-responsive > table:not(#_), .table-wrap > table:not(#_),
  .table-wrapper > table:not(#_) {
    display: table !important;
    width: 100%;
    min-width: 34rem !important;
  }
  /* SVGs scale proportionally on phones (keep aspect ratio when width caps). */
  svg { height: auto; }
  /* Safety net: oversized fixed-width boxes never break the viewport lock. */
  .container, section, main, .hero-content, .wrap, .calc-box, .jdc,
  .daf-calc-container, .login-shell { max-width: 100%; }
  /* Inline hard-coded widths on diagrams / process flowcharts must never
     exceed the viewport. max-width:100% only ever caps — it cannot widen
     anything — so this is safe across the site. */
  [style*="width:"] { max-width: 100% !important; }
}

/* =====================================================================
   Customer Hub login — keep the brand-panel heading and intro legible.
   theme-light.css otherwise forces them to dark navy, which is invisible
   on the dark-navy gradient panel. Scoped to the login brand panel only.
   ===================================================================== */
.login-brand .brand-content h1 { color: #ffffff !important; -webkit-text-fill-color: #ffffff !important; }
.login-brand .brand-content h1 span { color: #f0c04a !important; -webkit-text-fill-color: #f0c04a !important; }
.login-brand .brand-content > p { color: rgba(255,255,255,0.88) !important; -webkit-text-fill-color: rgba(255,255,255,0.88) !important; }
/* Feature-tile titles sit on a dark translucent tile — keep them white. */
.login-brand .brand-feature-text strong { color: #ffffff !important; -webkit-text-fill-color: #ffffff !important; }
.login-brand .brand-feature-text span { color: rgba(255,255,255,0.78) !important; -webkit-text-fill-color: rgba(255,255,255,0.78) !important; }

/* =====================================================================
   Utility classes replacing the two most-repeated inline styles sitewide.
   Identical CSS to the inline values — this only removes inline-style
   weight (HTML size), with no visual change.
   ===================================================================== */
.rb-flex-start { display: flex; align-items: flex-start; gap: 0.5rem; }
.rb-ic-blue { color: #00529b; margin-top: 3px; }

/* LAMELLA "How it works" steps in two columns (never one over-wide column). */
.principle-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem 2rem; margin-top: 1.5rem; }
@media (max-width: 768px) { .principle-grid { grid-template-columns: 1fr; } }

/* =====================================================================
   Readable line length for flowing body prose. Classless <p> in section
   containers are capped to a comfortable measure so desktop lines aren't
   130-160 characters wide. Because the cap is in `ch`, it ONLY shrinks
   paragraphs wider than the measure — text already inside cards, grids and
   flex components is narrower, so this is a no-op there (no layout change).
   Classed paragraphs (lead, section-subtitle, flex-grow, hero-description,
   eq-where, etc.) keep their own styling.
   ===================================================================== */
@media (min-width: 920px) {
  .section .container p:not([class]) { max-width: 72ch; }
  /* centre the measure only where the section is already centre-aligned */
  .section .container.text-center p:not([class]),
  .section .container p.text-center:not([class]) { margin-left: auto; margin-right: auto; }
}

/* =====================================================================
   A lone, full-width card in a cards-grid (e.g. a single "Main Control
   Panel" spec card) flows its list into TWO columns instead of one tall
   narrow column. :only-child means normal multi-card grids are untouched.
   ===================================================================== */
@media (min-width: 760px) {
  .cards-grid > .card:only-child ul { column-count: 2; column-gap: 2.5rem; }
  .cards-grid > .card:only-child ul > li { break-inside: avoid; -webkit-column-break-inside: avoid; }
}

/* =====================================================================
   .feature-grid was computing to display:block (its rules only ever set
   grid-template-columns, never display:grid), so feature cards stacked in
   one wide column. Make it a real grid: two equal-width columns on desktop,
   equal-height cards (align-items:stretch), single column on mobile.
   ===================================================================== */
.feature-grid { display: grid !important; gap: 1.5rem; align-items: stretch; }
@media (min-width: 769px) {
  /* match the specificity of main.css's :has(:nth-child) rules so 2-col wins */
  .feature-grid,
  .feature-grid:has(> :nth-child(2)),
  .feature-grid:has(> :nth-child(3)),
  .feature-grid:has(> :nth-child(4)),
  .feature-grid:has(> :nth-child(5)) {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
}
@media (max-width: 768px) {
  .feature-grid { grid-template-columns: 1fr !important; }
}
.feature-grid > .feature-card { height: 100%; }

/* =====================================================================
   Clickable benefit-cards: when a .benefit-card is an <a> (e.g. the
   desalination pre-treatment train cards linking to their detail pages),
   reset link styling and add a subtle hover lift + a "Learn more" cue.
   ===================================================================== */
a.benefit-card { text-decoration: none; color: inherit; cursor: pointer; transition: transform .15s ease, box-shadow .15s ease; }
a.benefit-card:hover { transform: translateY(-3px); }
/* Clickable feature-items (e.g. the resources cards linked to their pages) */
a.feature-item { text-decoration: none; color: inherit; cursor: pointer; transition: transform .15s ease, box-shadow .15s ease; }
a.feature-item:hover { transform: translateY(-3px); }
.feature-card-grid .benefit-card .card-link {
  display: inline-flex; align-items: center; gap: .4rem; margin-top: .9rem;
  color: var(--primary-blue, #0a66c2); font-weight: 600; font-size: .85rem;
}
.feature-card-grid .benefit-card .card-link i { font-size: .78em; transition: transform .15s ease; }
a.benefit-card:hover .card-link i { transform: translateX(3px); }

/* =====================================================================
   Remove ALL drop shadows from tables and container / card elements
   (per request). The ":not(#_)" raises specificity above theme-light.css's
   high-specificity card-shadow rules (e.g. .card:not(.benefit-card):not(...))
   so this reliably wins. (#_ never matches, so the selector still applies.)
   ===================================================================== */
table:not(#_), thead:not(#_), tbody:not(#_), tr:not(#_), th:not(#_), td:not(#_),
.table-responsive:not(#_), .table-wrap:not(#_), .table-wrapper:not(#_),
[class*="card"]:not(#_), [class*="container"]:not(#_), [class*="box"]:not(#_),
[class*="panel"]:not(#_), [class*="tile"]:not(#_),
.jack:not(#_), .stat-card:not(#_), .process-step:not(#_), .process-step-box:not(#_),
.timeline-step:not(#_), .train-step:not(#_), .principle-step:not(#_),
.feature-item:not(#_), .list-grid-item:not(#_), .metric:not(#_),
.callout:not(#_), .note-box:not(#_), .info-box:not(#_), .highlight-box:not(#_),
.key-insight:not(#_), .benefit-highlight:not(#_), .feature-highlight:not(#_),
.compliance-note:not(#_), .challenge-list:not(#_), .diagram-placeholder:not(#_),
.dosing-type-card:not(#_), .scen-card:not(#_), .subscribe-banner:not(#_),
.doc-item:not(#_), .calc-box:not(#_) {
  box-shadow: none !important;
}
/* Card CTA / link labels were rendering oversized (inheriting card font-size or
   the global h4 size). Size them like normal link labels (sitewide). */
.view-details-link { font-size: 0.9rem !important; line-height: 1.3 !important; }
.subpage-link .content h4 { font-size: 0.9rem !important; line-height: 1.3 !important; font-weight: 600 !important; }
.subpage-link .content p { font-size: 0.8rem !important; line-height: 1.35 !important; }

/* Service-list ticks were inheriting the card's 2.5rem block header-icon style,
   so each check rendered huge, on its own line, with a 1rem gap — spreading the
   list out and leaving big empty space. Make them small inline bullets. */
.service-list li i {
  font-size: 0.8em !important;
  display: inline !important;
  margin: 0 0.45rem 0 0 !important;
  color: var(--primary-blue, #0066cc) !important;
  vertical-align: baseline !important;
}
.service-list li { padding: 0.35rem 0 !important; }

/* "What's in the Package" blocks: two-column grid of framed containers
   (were unstyled full-width divs stacked in one column with lots of empty space). */
.package-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; align-items: stretch; margin-top: 1.25rem; }
@media (max-width: 600px) { .package-grid { grid-template-columns: 1fr; } }
.package-block { background: #fff; border: 1px solid #e6ecf3; border-radius: 12px; padding: 1.2rem 1.4rem; }
.package-block h3 { margin: 0 0 0.6rem; color: var(--primary-navy, #0a2540); font-size: 1.05rem; display: flex; align-items: center; gap: 0.5rem; }
.package-block h3 i { color: var(--primary-blue, #0066cc); }
.package-block ul { margin: 0; padding-left: 1.15rem; }
.package-block li { margin-bottom: 0.4rem; line-height: 1.55; color: var(--text-medium, #41566b); }

/* Equipment-category cards: equal height within each row (default grid stretch),
   with the list tightened so the row isn't excessively tall. */
.equipment-categories-grid { align-items: stretch !important; }
.equipment-category-card { display: flex; flex-direction: column; }
.equipment-category-card ul { margin: 0.7rem 0 0.9rem; }
.equipment-category-card ul li { margin-bottom: 0.35rem; line-height: 1.4; }
.equipment-category-card .explore-link { margin-top: auto; }

/* =====================================================================
   Content-card grids: equal-height cards in every row AND a centred last
   (partial) row. Uses CSS GRID (not flex) because flex align-items:stretch
   silently fails to equalise cards with no trailing button, whereas grid
   reliably stretches every card in a row to the row height. minmax(0,360px)
   + justify-content:center centres an orphan card; auto row sizing means
   rows fit their content (no cross-row empty space). Scoped to the
   consistently 3-column .cards-grid / .features-grid; desktop only
   (mobile already collapses to a single column).
   ===================================================================== */
@media (min-width: 769px) {
  .cards-grid:not(.grid-2), .features-grid, .process-steps, .feature-card-grid {
    display: grid !important;
    grid-template-columns: repeat(3, minmax(0, 360px));
    justify-content: center;
    align-items: stretch;
    gap: 1.5rem;
  }
  .cards-grid:not(.grid-2) > *, .features-grid > *, .process-steps > *, .feature-card-grid > * {
    width: auto !important;
    max-width: none !important;
    min-width: 0 !important;
    min-height: 0 !important;
    flex: none !important;
    height: auto;
  }
}

/* =====================================================================
   STANDING RULE: every container in a row is ALWAYS the same height as the
   container next to it. Card grids stretch their items to fill the row
   height (align-items:stretch); cards must never carry a fixed height.
   ===================================================================== */
:is(.cards-grid, .cards-grid-wide, .cards-grid-physics, .feature-card-grid,
    .service-grid, .features-grid, .dosing-types-grid, .grid-2, .grid-3, .grid-4,
    [class*="grid-auto"], .related-grid, .solutions-grid, .challenge-grid,
    .applications-grid, .application-grid, .card-grid, .card-grid-4, .topics-grid,
    .content-grid, .butter-grid, .treatment-grid, .problem-grid, .region-grid,
    .scenario-grid, .capabilities-grid, .components-grid, .industries-glance-grid,
    .process-overview-grid, .treatment-nav-grid, .coagulant-grid, .benefit-grid,
    .rg-grid, .product-grid, .service-mega-grid, .industry-grid,
    .industry-cards-grid, .component-grid, .scen-grid, .resources-grid,
    .case-study-grid, .equipment-grid, .projects-grid, .comparison-grid,
    .list-grid) {
  align-items: stretch;
}

/* =====================================================================
   Equal-height cards with BOTTOM-ALIGNED buttons across a row.
   Cards in a grid with a trailing button were aligned to the end of their
   text, so when copy length varied the buttons sat at different heights
   within a row. Make grid cards flex columns and push the trailing
   button/link to the bottom so every button in a row lines up. Cards are
   already equal-height via the grid's default align-items:stretch.
   ===================================================================== */
:is(.cards-grid, .cards-grid-wide, .cards-grid-physics, .feature-card-grid,
    .service-grid, .features-grid, .dosing-types-grid, .grid-2, .grid-3, .grid-4,
    [class*="grid-auto"], .related-grid, .solutions-grid, .challenge-grid,
    .applications-grid, .application-grid, .card-grid, .card-grid-4, .topics-grid,
    .content-grid, .butter-grid, .treatment-grid, .problem-grid, .region-grid,
    .scenario-grid, .capabilities-grid, .components-grid, .industries-glance-grid,
    .process-overview-grid, .treatment-nav-grid, .coagulant-grid, .benefit-grid,
    .rg-grid, .product-grid, .service-mega-grid, .applications-grid,
    .industry-grid, .industry-cards-grid, .component-grid, .scen-grid,
    .resources-grid, .case-study-grid, .equipment-grid, .projects-grid,
    .comparison-grid, .list-grid)
  > :is(.card, [class*="-card"]) {
  display: flex;
  flex-direction: column;
}
:is(.cards-grid, .cards-grid-wide, .cards-grid-physics, .feature-card-grid,
    .service-grid, .features-grid, .dosing-types-grid, .grid-2, .grid-3, .grid-4,
    [class*="grid-auto"], .related-grid, .solutions-grid, .challenge-grid,
    .applications-grid, .application-grid, .card-grid, .card-grid-4, .topics-grid,
    .content-grid, .butter-grid, .treatment-grid, .problem-grid, .region-grid,
    .scenario-grid, .capabilities-grid, .components-grid, .industries-glance-grid,
    .process-overview-grid, .treatment-nav-grid, .coagulant-grid, .benefit-grid,
    .rg-grid, .product-grid, .service-mega-grid, .applications-grid,
    .industry-grid, .industry-cards-grid, .component-grid, .scen-grid,
    .resources-grid, .case-study-grid, .equipment-grid, .projects-grid,
    .comparison-grid, .list-grid)
  > :is(.card, [class*="-card"]) > :is(a.btn, .btn, .btn-text, .explore-link, .card-link):last-child {
  margin-top: auto !important;
}

/* Standalone intro / "lead" paragraphs sit directly in a section with no frame —
   give them a subtle callout frame so loose text reads as formatted (per request). */
.section .container > p.lead,
.section .container > p.lead-auto,
.section .container > p.lead-narrow {
  background: #f8fbff;
  border: 1px solid #e6ecf3;
  border-radius: 10px;
  padding: 1.05rem 1.5rem;
}

/* =====================================================================
   PHONE: stack content/card grids to ONE column (<=600px) so long, text-heavy
   containers are never squeezed two-up. main.css forces these to 2 columns
   even at <=480px (repeat(2,minmax(140px,1fr))); this overrides it on phones,
   matching the old site's single-column mobile layout. Small hero/stat grids
   are deliberately left two-up.
   ===================================================================== */
@media (max-width: 600px) {
  .cards-grid, .cards-grid-wide, .cards-grid-physics, .feature-grid,
  .feature-card-grid, .related-grid, .component-grid, .benefit-grid,
  .content-grid, .challenge-grid, .solutions-grid, .industry-grid,
  .equipment-grid, .comparison-grid, .case-study-grid, .resources-grid,
  .projects-grid, .features-grid, .process-steps, .principle-grid,
  .list-grid, .dosing-types-grid, .industry-cards-grid, .scen-grid,
  .equipment-categories-grid, .services-grid-top, .services-grid-bottom,
  .treatment-row, .butter-grid, .fluid-grid, .streams-grid,
  .process-steps-grid, .spec-grid, .media-grid, .product-variants-grid,
  .grid-2, .grid-3, .grid-4 {
    grid-template-columns: 1fr !important;
  }
}

/* kill shadows that appear only on hover too */
[class*="card"]:hover:not(#_), [class*="box"]:hover:not(#_),
[class*="panel"]:hover:not(#_), [class*="tile"]:hover:not(#_),
.jack:hover:not(#_), table:hover:not(#_), .stat-card:hover:not(#_),
.process-step:hover:not(#_), .timeline-step:hover:not(#_),
.doc-item:hover:not(#_), .standard-region-card:hover:not(#_),
.feature-item:hover:not(#_), .list-grid-item:hover:not(#_) {
  box-shadow: none !important;
}

/* =====================================================================
   SCROLL-REVEAL SAFETY NET
   main.css sets [data-animate]{opacity:0; animation:none} and relies on
   JS (.visible) to show content. If that JS is stale/blocked/misses an
   element, the content stays invisible and the page reads as "broken /
   no CSS". Here we guarantee a self-completing on-load fade so content
   is ALWAYS visible even when the JS never runs.
   ===================================================================== */
[data-animate]:not(#_) {
  opacity: 1 !important;
  transform: none !important;
  animation: rbRevealUp 0.55s ease-out both !important;
}
@keyframes rbRevealUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  [data-animate]:not(#_) { animation: none !important; opacity: 1 !important; transform: none !important; }
}

/* Process-flow steppers (cards + arrow separators): equal-height step cards.
   The container was centring items, leaving the step cards different heights;
   force stretch so every step card matches its neighbour. Arrows keep their
   own align-self:center. */
.process-flow { align-items: stretch !important; }
.process-flow > .process-step { align-self: stretch !important; height: auto; }

/* =====================================================================
   Equipment product pages: keep the Product Overview as a clean 2-column
   layout (image | info). Grid items default to min-width:auto, so a large
   image forced .product-image to its content width (overflowing the track
   and breaking the 2-col layout). min-width:0 lets it respect the column;
   images are capped and never exceed their cell.
   ===================================================================== */
.product-main .product-image img { max-width: 100%; height: auto; }
@media (min-width: 769px) {
  .product-main .product-grid {
    display: grid !important;
    grid-template-columns: minmax(0, 460px) 1fr !important;
    gap: 2.5rem !important;
    align-items: start !important;
  }
  .product-main .product-grid > * { min-width: 0 !important; width: auto !important; }
  .product-main .product-image { display: block !important; }
}
@media (max-width: 768px) {
  .product-main .product-grid { display: grid !important; grid-template-columns: 1fr !important; }
}


/* ===== Top utility bar with live clocks (owner UK HQ + visitor local time) ===== */
.topbar{position:fixed;top:0;left:0;right:0;height:20px;z-index:101;background:#eef4fb;border-bottom:1px solid #dbe4ee;color:#0a2540;font-size:11px;line-height:20px;}
.topbar .container{height:20px;}
.topbar-inner{display:flex;align-items:center;justify-content:flex-end;gap:.55rem;height:20px;}
.topbar .tb-clock{display:inline-flex;align-items:center;gap:.3rem;white-space:nowrap;}
.topbar .tb-clock i{color:#0a66c2;font-size:11px;}
.topbar .tb-label{color:#5b6b7b;}
.topbar time{font-variant-numeric:tabular-nums;font-weight:700;color:#0a2540;letter-spacing:.3px;}
.topbar .tb-sep{color:#9fb0c0;}
.header{top:20px;}
@media(max-width:560px){.topbar .tb-label{display:none;}.topbar-inner{justify-content:center;gap:.9rem;}}
