/* ===========================================================================
   Nunito and Inter, self-hosted.

   These used to come from a stylesheet on fonts.googleapis.com, which the
   browser had to fetch and parse before it could paint any text, and which
   then pointed at a second host, fonts.gstatic.com, for the files. That is
   two name lookups and two TLS handshakes on the critical path, and on a
   phone it was a large part of a 3.9s First Contentful Paint.

   The declarations below are Google's own, weights and unicode-ranges
   unchanged, with the addresses pointing at our copies instead, so the
   rendering is identical. Only the latin and latin-ext subsets are kept;
   the browser still fetches latin-ext only when a page actually uses a
   character from that range, which is the country list and little else.
   =========================================================================== */
/* latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/nunito-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/nunito-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/nunito-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/nunito-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/nunito-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Nunito';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/nunito-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ============================================================
   Tara Polymers, site styles
   Navy and gold accents
   ============================================================ */

/* Fonts are loaded via <link> tags in each page's <head>, not @import.
   An @import inside CSS forces the browser to fetch styles.css, parse it,
   THEN fetch the font CSS, THEN the font files, three chained round trips
   before any text can render. The <link> version starts the font request in
   parallel with the stylesheet. Weights were also trimmed from 11 static
   files to 2 variable fonts covering the 400-800 range the site uses. */

/* --- Design Tokens --- */
:root {
  /* Brand, from logo */
  --navy:      #0F3E66;
  --navy-dark: #0A2C49;
  --navy-tint: #EDF2F7;
  --gold:        #C99905;
  --gold-dark:   #A37C04;
  /* Text-safe gold. --gold (#C9963A) measures 2.66:1 on white and 2.56:1 on
     --snow, failing AA everywhere it was used as type. This is the lightest
     gold that clears 4.5:1 on both grounds (4.75 / 4.59). Decorative gold
     rules, bars and brackets keep the original: they are graphics, not text. */
  --gold-text:   #966B20;
  --gold-light:  #D4AC5E;
  --gold-tint:   #FDF8EE;
  /* The third colour. It means one thing, "yes / confirmed / done": the
     checklist tick, the approved badge on the credentials, the thank-you
     page. Never headings, buttons or backgrounds, or it stops being a signal.
     6.3:1 on white, 5.5:1 on its own tint. */
  --green:       #2F6B4F;
  --green-tint:  #E8F2EC;

  /* Neutrals */
  --white:       #FFFFFF;
  --snow:        #FAFBFC;
  --pearl:       #F5F6F8;
  --mist:        #DDE1E8;
  /* Body copy. Originally #6E7A8A (4.37:1 on white, failed WCAG AA), then
     #667384 (4.83:1). Now #2B3341 at the client's request: body text should
     read as black rather than grey. Measures 12.7:1 on white. */
  --slate:       #2B3341;
  --charcoal:    #3D4654;
  --ink:         #1A1F2B;

  /* Functional */
  --text:        var(--ink);
  --text-sub:    var(--slate);
  --border:      #E8ECF2;
  --border-soft: #F0F2F6;

  /* Typography */
  /* One typeface for the whole site. Headings previously used Playfair
     Display, a high-contrast editorial serif that read as fashion/luxury
     rather than heavy industry, and cost a second font download. */
  --font-display: 'Nunito', 'Inter', -apple-system, system-ui, sans-serif;
  --font-body:    'Inter', -apple-system, system-ui, sans-serif;

  /* Sizing */
  --max:    1320px;   /* was 1200: the content sat ~230px off each edge on wide screens */
  --gutter: clamp(16px, 3.5vw, 56px);

  /* Radii */
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 24px;
  --r-xl: 32px;
  --r-full: 999px;

  /* Shadows, very soft */
  --sh-xs:  0 1px 3px rgba(0,0,0,.04);
  --sh-sm:  0 2px 8px rgba(0,0,0,.05);
  --sh-md:  0 4px 20px rgba(0,0,0,.06);
  --sh-lg:  0 12px 40px rgba(0,0,0,.08);

  /* Motion */
  --ease:   cubic-bezier(.4, 0, .2, 1);
  --t-fast: .18s var(--ease);
  --t-med:  .3s var(--ease);
}

/* --- Hard Reset --- */
*,*::before,*::after { box-sizing:border-box; margin:0; padding:0 }
html { scroll-behavior:smooth; font-size:16px; -webkit-text-size-adjust:100% }
/* The nav is fixed and 101px tall (81px below 1000px), so a jump to #quality
   or #manufacturing would land the heading underneath it. scroll-padding on
   the scroll container offsets every anchor jump in one place, including the
   skip link and any future ones, rather than needing scroll-margin repeated
   on each target. The extra 32px is breathing room so the heading sits clear
   of the nav rather than flush against it. */
html { scroll-padding-top: 133px }              /* 101px nav + 32 */
@media (max-width: 1240px) { html { scroll-padding-top: 105px } }  /* 73px nav */
@media (max-width: 900px)  { html { scroll-padding-top: 113px } }  /* 81px nav */
/* 4. Page load fade-in */
@keyframes pageFadeIn { from { opacity: 0 } to { opacity: 1 } }

body {
  font-family: var(--font-body);
  color: var(--text);
  background: var(--white);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  animation: pageFadeIn .45s ease forwards;
}

/* 2. Scroll reveal */
.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .65s cubic-bezier(.4,0,.2,1), transform .65s cubic-bezier(.4,0,.2,1);
}
.reveal.visible { opacity: 1; transform: translateY(0); }

/* 3. Staggered items */
.reveal-item {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .5s cubic-bezier(.4,0,.2,1), transform .5s cubic-bezier(.4,0,.2,1);
}
.reveal-item.visible { opacity: 1; transform: translateY(0); }
img { max-width:100%; height:auto; display:block }
a { color:inherit; text-decoration:none }
ul,ol { list-style:none }
button { cursor:pointer; font-family:inherit; border:none; background:none }

/* --- Container --- */
.container { max-width:var(--max); margin:0 auto; padding:0 var(--gutter) }

/* ============================================================
   TYPOGRAPHY, Premium Hierarchy
   ============================================================ */
.eyebrow {
  position: relative; display: inline-block;
  font-family: var(--font-body);
  font-size: 1rem; font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--gold-text);
  margin-bottom: 18px;
  padding: 13px 30px; line-height: 1;
}
.eyebrow::before, .eyebrow::after {
  content: ''; position: absolute;
  width: 16px; height: 16px;
  border: 2.5px solid var(--gold);
}
.eyebrow::before { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.eyebrow::after  { bottom: 0; right: 0; border-left: 0; border-top: 0; }

/* Tracking is tighter than it was under Playfair: a sans-serif at display
   sizes needs negative letter-spacing to avoid looking loose, where a
   high-contrast serif did not. */
h1 {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 5.5vw, 4rem);
  font-weight: 700; line-height: 1.1;
  letter-spacing: -.03em; color: var(--ink);
}
h2 {
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 3.5vw, 2.8rem);
  font-weight: 700; line-height: 1.18;
  letter-spacing: -.022em; color: var(--ink);
}
h3 {
  font-family: var(--font-body);
  font-size: 1.15rem; font-weight: 700;
  line-height: 1.35; color: var(--ink);
}
h4 {
  font-family: var(--font-body);
  font-size: .95rem; font-weight: 700;
  color: var(--ink);
}
.lead {
  font-size: 1rem; color: var(--text-sub);
  line-height: 1.75; max-width: 580px;
}
.text-sub   { color: var(--text-sub) }

.text-xs    { font-size: .75rem }
.text-center{ text-align: center }

/* Section Header */
.sh { margin-bottom: 44px }
.sh.center { text-align: center }
.sh.center .eyebrow { justify-content: center }
.sh.center .lead { margin: 0 auto }
.sh h2 { margin-bottom: 12px }

/* ============================================================
   BUTTONS, Refined
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 14px 30px; border-radius: var(--r-full);
  font-family: var(--font-body);
  font-size: .85rem; font-weight: 600;
  letter-spacing: .3px;
  transition: all var(--t-med);
  white-space: nowrap; cursor: pointer;
  border: 1.5px solid transparent;
}

.btn-primary {
  background: var(--navy); color: #fff;
  border-color: var(--navy);
  box-shadow: 0 4px 16px rgba(107,31,58,.2);
}
.btn-primary:hover {
  background: var(--navy-dark);
  border-color: var(--navy-dark);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(107,31,58,.28);
}

.btn-outline {
  background: transparent; color: var(--navy);
  border-color: var(--mist);
}
.btn-outline:hover {
  background: var(--navy-tint);
  border-color: var(--navy);
  transform: translateY(-2px);
}

.btn-sm { padding: 10px 22px; font-size: .8rem }
.btn-lg { padding: 17px 38px; font-size: .9rem }

/* ============================================================
   NAVBAR, Premium Glass
   ============================================================ */
.nav {
  position: fixed; top: 0; left: 0; width: 100%;
  background: #ffffff;
  /* No backdrop-filter here. The bar is opaque, so a blur behind it is
     invisible, but on a fixed element it made the compositor re-blur this
     strip on every frame of every animation on the page. */
  z-index: 1000;
  border-bottom: 1px solid rgba(0,0,0,.06);
  transition: box-shadow .3s ease, background .3s ease;
}
.nav.scrolled {
  background: #ffffff;
  box-shadow: 0 4px 24px rgba(0,0,0,.07);
  border-bottom-color: transparent;
}
.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 100px;
  padding: 0 var(--gutter);
}
/* Logo, left aligned in left column */
.nav-logo {
  display: flex; align-items: center; justify-content: flex-start;
}
.nav-logo img {
  height: 76px; width: auto;
  transition: opacity .2s ease;
}
.nav-logo:hover img { opacity: 1; }
.nav-menu-label { display: none; }
/* Links, fill all center space, truly centered */
.nav-links {
  display: flex; align-items: center; justify-content: center; gap: 36px;
  list-style: none; margin: 0; padding: 0;
}
.nav-link {
  font-size: .78rem; font-weight: 600;
  letter-spacing: .6px; text-transform: uppercase;
  color: var(--charcoal);
  transition: color var(--t-fast);
  position: relative; white-space: nowrap;
}
.nav-link::after {
  content: ''; position: absolute;
  bottom: -6px; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--navy), var(--gold));
  border-radius: 2px;
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--t-med);
}
.nav-link:hover, .nav-link.active { color: var(--navy) }
.nav-link:hover::after, .nav-link.active::after { transform: scaleX(1) }
/* CTA, right aligned in right column */
.nav-right {
  display: flex; align-items: center; justify-content: flex-end;
}
.nav-right .btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 13px 28px;
  font-size: .76rem; font-weight: 700;
  letter-spacing: 1px; text-transform: uppercase;
  border-radius: 999px;
  background: var(--navy);
  color: #fff;
  border: 2px solid var(--navy);
  box-shadow: 0 4px 20px rgba(107,31,58,.25);
  transition: all var(--t-med);
}
.nav-right .btn::after {
  content: none; font-size: .85rem;
  transition: transform var(--t-fast);
}
.nav-right .btn:hover {
  background: transparent; color: var(--navy);
  transform: translateY(-2px);
  box-shadow: 0 8px 28px rgba(107,31,58,.15);
}
.nav-right .btn:hover::after { transform: translateX(4px); }
/* Burger */
.nav-burger {
  display: none; flex-direction: column; justify-content: center; gap: 5px;
  width: 38px; height: 38px; padding: 7px;
  border-radius: 6px; transition: background var(--t-fast);
}
.nav-burger:hover { background: rgba(0,0,0,.05); }
.nav-burger span {
  display: block; width: 20px; height: 1.5px;
  background: var(--charcoal); border-radius: 2px; transition: var(--t-fast);
}

/* Mobile */
/* 1240, not 900: measured, the six links plus the Request Quote button need
   ~1250px before they touch. Below that the nav collapses to the burger. */
@media(max-width:1240px) {
  .nav-inner { height: 72px; }
  .nav-logo img { height: 54px; }
  .nav-burger { display: flex; margin-left: auto; }
  /* The menu is a floating card, not a full-bleed sheet: inset from both
     edges with rounded corners, a border and a real shadow, so it reads as
     its own surface rather than more white under the white bar. Items are
     sentence case at body size (the desktop bar's tiny uppercase read as
     cramped in a vertical list), each a rounded row; the current page is a
     tinted pill. A small gold PRODUCTS label groups the three product
     links, same voice as the footer's column titles. Short drop-in on
     open; skipped for reduced motion. */
  .nav-links {
    display: none; flex-direction: column; gap: 2px;
    position: absolute; top: calc(100% + 8px); left: 12px; right: 12px;
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 10px;
    box-shadow: 0 18px 40px rgba(26, 31, 43, .16);
  }
  .nav-links.open { display: flex; }
  @media (prefers-reduced-motion: no-preference) {
    .nav-links.open { animation: menu-drop .24s var(--ease); }
  }
  .nav-links li { width: 100%; }
  /* A small gold PRODUCTS label opens the group, same voice as the footer's
     column titles, and the three links sit a step deeper beneath it. */
  .nav-menu-label {
    display: block;
    font-size: .62rem; font-weight: 700; letter-spacing: 1.6px;
    text-transform: uppercase; color: var(--gold-text);
    padding: 14px 14px 2px;
  }
  .nav-link {
    display: block; padding: 12px 14px;
    font-size: .95rem; font-weight: 600;
    letter-spacing: 0; text-transform: none;
    color: var(--charcoal);
    border-radius: 10px;
  }
  .nav-link.active { background: var(--navy-tint); color: var(--navy); }
  .nav-link::after { display: none; }
  .nav-right { display: none; }
}
.nav-burger.open span:nth-child(1) { transform: translateY(6.5px) rotate(45deg) }
.nav-burger.open span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.nav-burger.open span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg) }

/* ============================================================
   HERO, Cinematic Light
   ============================================================ */
/* The illustration is anchored to its right edge, so whatever crop the
   cover scale needs comes off the empty cream on the left and the icon
   cluster stays inside the panel. Measured at 1440x900: crop is 42px in
   total, the rightmost icon ends exactly at the panel edge, and the leftmost
   icon clears the cards by 31px. */
.why-stage .stage-bg img { object-position: 100% 50%; }
/* No overlay of any kind. The photograph is shown at its own colour and
   brightness; the white panel is separated from it by its shadow alone. */
.stage .container { position: relative; z-index: 1; }

/* Homepage intro between the hero and the products: who we are, text only.
   The statement sits on the left and the two paragraphs on the right, so
   the block has a shape without a photograph; the plant's aerial already
   carries the About page and is not repeated here. The Why Us section
   further down says why; this does not repeat that either. */
.intro-head .eyebrow { margin-bottom: 14px; }
.intro-body.reveal { transition-delay: .1s; }

/* Why Us, same treatment as the hero. The copy is set to the left because
   the illustration was drawn that way: its left half is empty cream and its
   icons sit on the right, so a centred heading would run into them. */
.why-stage { padding: 56px 0 52px; }
/* Between 901 and 1366 the panel tightens so the pinned sequence fits under
   the bar on ordinary laptop heights; at 1440+ the roomier spacing above
   applies. Below 900 the scroll-entrance fallback runs instead. */
@media (max-width: 1366px) and (min-width: 901px) {
  .why-stage { padding: 40px 0 36px; }
  .why-stage .sh { margin-bottom: 22px !important; }
  .why-stage .feat-grid { gap: 14px; }
}

/* Why Us choreography. The panel scrolls in with its heading, pins under the
   bar while the four cards arrive one by one, then releases and scrolls away
   over the fixed illustration. .why-pin is the tall track the panel travels
   through; main.js sets its height and adds .is-active only when the whole
   panel fits below the bar. On short or narrow screens, with JS off, or under
   reduced motion, nothing here applies and it is an ordinary section with
   every card showing. */
.why-pin { position: relative; }
.why-pin.is-active .why-stage { position: sticky; top: var(--nav-h, 101px); }
/* Each card rises from well below its slot, so the arrival reads as a card
   coming up from the bottom of the panel rather than a fade in place. */
.why-pin.is-active .feat {
  opacity: 0; transform: translateY(90px);
  transition: opacity .6s var(--ease), transform .6s var(--ease), box-shadow var(--t-med);
}
.why-pin.is-active .feat.is-in { opacity: 1; transform: none; }
.why-pin.is-active .feat.is-in:hover { transform: translateY(-4px); }
/* Where the pin cannot run (the panel is taller than the viewport under the
   bar), the cards still get an entrance: main.js marks the track .why-anim
   and each card carries its own observer, so laptops and phones see a card
   rise as it reaches the screen and settle back out as it slides under the
   bar. Same hidden state, same transition as the pinned version, only the
   trigger differs. 34px of travel because a phone card is close to full
   width, where a shorter rise is hard to notice. */
.why-pin.why-anim .feat {
  opacity: 0; transform: translateY(34px);
  transition: opacity .55s var(--ease), transform .55s var(--ease), box-shadow var(--t-med);
}
.why-pin.why-anim .feat.is-in { opacity: 1; transform: none; }
.why-pin.why-anim .feat.is-in:hover { transform: translateY(-4px); }

/* Copy and cards keep to the left 54 percent of the panel, the empty cream
   of the illustration. Its icons occupy the right and stay uncovered. 54 is
   the widest share that clears the leftmost icon now that the picture is
   scaled from the bar down (less side crop, so the icons sit further left),
   and still wide enough for a card's text to hold in four or five lines. */
.why-stage .sh, .why-stage .feat-grid { max-width: 54%; }
.why-stage .sh { margin-bottom: 30px; }
.why-stage .feat-grid { grid-template-columns: repeat(2, 1fr); gap: 18px; }
/* Compact card: icon and title share the first row, the text runs the full
   width beneath both. Two rows of the site's stacked card did not fit under
   the bar on a 900px screen, and an icon column beside the text left the
   text in a 228px strip that ran to seven lines. */
.why-stage .feat {
  display: grid; grid-template-columns: 44px 1fr; column-gap: 12px; align-items: center;
  padding: 22px 24px 24px;
}
.why-stage .feat-icon { width: 44px; height: 44px; font-size: 1.35rem; margin: 0; }
.why-stage .feat-title { text-align: left; margin: 0; }
.why-stage .feat-text { grid-column: 1 / -1; margin-top: 12px; }
.why-stage .sh.center { text-align: left; }
.why-stage .sh.center .eyebrow { justify-content: flex-start; }
.why-stage .sh.center .lead { margin: 0; }
/* --gold-text measures 4.04:1 on the illustration's cream (250,236,199).
   This darker gold measures 5.6:1 there and 5.1:1 on the zone's darkest
   pixel. Only the text changes; the gold rules beside it are decorative. */
.why-stage .eyebrow { color: #7A5713; }
.why-stage .feat { border-color: transparent; box-shadow: 0 4px 20px rgba(26,31,43,.08); }


/* Bar goes back up to 80px+1 under 900. */
@media (max-width: 900px) {
  .why-stage { padding: 60px 0 56px; }
  /* The section lead repeats what the four cards below already say, and on
     a phone it pushes the first card most of a screen further down. */
  .why-stage .sh .lead { display: none }
  .why-stage .sh, .why-stage .feat-grid { max-width: 100%; }
  /* Below 900 the cards drop under the heading and claim the panel's whole
     width, so no empty side is left for the drawing to occupy. cover then
     scales off the box's height and only a narrow vertical slice of the
     1380px source survives: right-anchored it put the icon cluster behind
     the heading, left-anchored it showed nothing but the illustration's
     empty cream (measured, source 0 to 386 on a 390px screen). Neither is
     worth the download, so here the picture stops being the background and
     takes its own band under the cards, cropped where the icons read. The
     cream it used to contribute is painted directly, keeping the drawing's
     light direction, lit at the top left and warm toward the bottom. */
  .why-stage .stage-bg { display: none; }
  .why-stage {
    background: linear-gradient(168deg, #FCEFCC 0%, #FAECC7 42%, #F8E6B8 100%);
  }
}
@media (max-width: 560px) {
  .why-stage { padding: 44px 0 40px; }
  .hero-actions .btn { width: 100%; justify-content: center; }

  /* Section headers. The same scale as the hero: the desktop h2 floor
     (1.8rem) and 1rem lead were set for a wide column, and centred over
     three or four lines on a phone they read as a wall rather than a
     heading. */
  .sh { margin-bottom: 24px; }
  .section h2, .section-alt h2, .sh h2 { font-size: 1.5rem; margin-bottom: 10px; }
  .sh .lead { font-size: .92rem; line-height: 1.65; }
  .eyebrow { font-size: .84rem; letter-spacing: .16em; margin-bottom: 14px; padding: 11px 24px; }
  .eyebrow::before, .eyebrow::after { width: 13px; height: 13px; }
}

/* ============================================================
   SECTIONS
   ============================================================ */
.section     { padding: 80px 0 }
.section-alt { padding: 80px 0; background: var(--snow) }

/* Product page overview, tighter connection to hero */
/* .prod-page-hero + .section pull-up removed: the hero pads properly now. */
/* Heading → body paragraph spacing standard */
.section h2, .section-alt h2 { margin-bottom: 14px; }
.sh h2 { margin-bottom: 12px; }


/* ============================================================
   INDUSTRY CARDS
   ============================================================ */

/* ============================================================
   FEATURE CARDS, Minimal
   ============================================================ */
.feat {
  padding: 32px 24px; border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--white);
  transition: all var(--t-med); position: relative;
}
.feat:hover { transform: translateY(-4px); box-shadow: var(--sh-md); border-color: transparent }

/* ============================================================
   PROCESS STRIP, About page, "How It Is Made"
   ============================================================
   The homepage Infrastructure section lists WHAT we make. This one explains
   HOW, as a numbered sequence. Without that split the two were near-identical:
   same eyebrow, same photo, and all six homepage list items repeated here.
   Numbered circles rather than ticks or dots, so it also reads differently
   from the checklist above and the Our Journey timeline below. */
.process {
  position: relative;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
}

/* ── PROGRESS LINE ────────────────────────────────────────────────────
   A single horizontal rule from x=100 to x=900 in a 0 0 1000 40 viewBox,
   i.e. 10% to 90% of the container, exactly the centres of the first and
   last of five equal grid columns, so the circles sit on it.

   The line draws left to right, halting at each circle as that step appears.

   preserveAspectRatio="none" lets the line stretch horizontally while its
   vertical geometry stays in fixed px; non-scaling-stroke keeps it 2px. */
/* The strip breaks fully out of the container, centring itself on the viewport
   rather than the 1200px column. Capped at 1500px and always keeping 24px of
   viewport margin, so it can never touch the screen edge.
   Honest limit: on a 1280px browser this yields ~1232px against the container's
   1072px (columns 246px vs 214px). The real gain is on larger displays, where
   each of the five columns reaches 300px. */
@media (min-width: 1024px) {
  .process-path {
    width: min(1340px, calc(100vw - 48px));
    margin-left: 50%;
    transform: translateX(-50%);
  }
}

/* Each leg is 15% of the run and each stop 10%, so the line reaches a circle
   at 0 / 25 / 50 / 75 / 100%, an even 0.6s apart at 2.4s total. Each leg is
   11% (264ms) and each hold 14% (336ms), the hold being the longer of the two
   so the circle's 300ms pop completes before the line sets off again. 600ms
   is also the data-stagger on the markup, which is how each step appears
   exactly as the line arrives at it. Change one and the other must follow. */
/* The timing function declared in a keyframe governs the interval that
   STARTS at it, so the curve sits on 14/39/64/89%: the moment each travel leg
   begins. The animation itself is linear so these do not compound. */
/* One continuous, even draw. It used to stop at every circle and set off
   again, which read as a mechanical stutter. Linear so it reaches each
   circle at exactly i * 500ms, the stagger on the markup; the steps then
   fade in over the line rather than snapping to it. 2s = 4 legs * 500ms. */
@keyframes line-draw {
  from { transform: scaleX(0) }
  to   { transform: scaleX(1) }
}
/* The rail spans 10% to 90%, which is the centre of the first column to the
   centre of the last across five equal tracks. Its 2px sits at y=23 so its
   centre lands on 24, the centre of the 48px circle. */
.process-rail {
  position: absolute; top: 23px; left: 10%; right: 10%;
  height: 2px; background: var(--mist);
  pointer-events: none;
}
/* A pixel thicker than the rail, so the drawn part reads as laid over the
   undrawn part rather than merely recoloured. */
.process-rail-fill {
  position: absolute; top: 0; left: 0;
  width: 100%; height: 2px;
  background: linear-gradient(90deg, var(--navy), var(--gold));
  border-radius: 2px;
  transform: scaleX(0); transform-origin: left center;
}
.process.flowing .process-rail-fill {
  animation: line-draw 2s linear 1 forwards;
}

/* Steps centre under their point on the line. */
.process-path .process-step {
  text-align: center;
  padding-right: 0;
}
.process-path .process-num  { margin-left: auto; margin-right: auto }
.process-path .process-text { padding-inline: 8px }

.process-step { position: relative; padding-right: 24px }

/* Each process step carries its own line-art icon in a tinted disc rather than a bare numeral; the drawing line and reading order carry the sequence. */
/* Line-art icon in a tinted disc. The emoji they replaced were heavy, full
   colour and different on every OS. The disc no longer pops: it used an
   overshoot curve (scale .6 to past 1 and back in 300ms), which read as a
   snap. Now it eases from .85 over 600ms with a soft halo fading in. */
.process-num {
  position: relative; z-index: 1;
  width: 48px; height: 48px; border-radius: 50%;
  background: var(--navy-tint);
  border: 1.5px solid var(--navy);
  color: var(--navy);
  display: flex; align-items: center; justify-content: center;
  font-size: 0; line-height: 1;
  margin: 0 auto 22px;
  transform: scale(.85); opacity: 0;
  box-shadow: 0 0 0 0 rgba(107, 31, 58, 0);
  transition: transform .6s var(--ease), opacity .6s var(--ease), box-shadow .9s var(--ease);
}
.process-num svg { display: block }
.process-step.visible .process-num {
  transform: scale(1); opacity: 1;
  box-shadow: 0 0 0 8px rgba(107, 31, 58, .06);
}

/* The step itself no longer moves as a block. Its title and text follow the
   disc in a short cascade, 150ms and 270ms behind it, each rising 10px over
   700ms, so a step arrives as a small wave rather than all at once. */
.process-path .process-step.reveal-item { opacity: 1; transform: none; transition: none }
.process-path .process-title, .process-path .process-text {
  opacity: 0; transform: translateY(10px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.process-path .process-step.visible .process-title { opacity: 1; transform: none; transition-delay: .15s }
.process-path .process-step.visible .process-text  { opacity: 1; transform: none; transition-delay: .27s }
.process-title {
  font-family: var(--font-body);
  font-size: .95rem; font-weight: 700;
  color: var(--ink); margin-bottom: 6px;
}
/* Copy is written to fall on three lines. The measure is capped so that a
   wider column cannot re-wrap it to two, without this cap, screens above
   ~1500px gave 300px columns, four of the five paragraphs collapsed to two
   lines, and min-height held the boxes open with a blank line inside.
   The cap keeps the wrap identical at every width; min-height is then only a
   safety floor for a late-loading font. */
.process-text {
  font-size: .85rem; line-height: 1.65;
  color: var(--text-sub);
  max-width: 250px;
  margin-inline: auto;
  min-height: calc(1.65em * 3);
}

/* Once the steps wrap onto more than one row the curve no longer passes
   through them, so it is dropped and the arc offsets are flattened rather
   than left applied to a layout they no longer describe. */
@media (max-width: 1000px) {
  .process { grid-template-columns: repeat(3, 1fr); row-gap: 32px }
  .process-path { padding-bottom: 0 }
  .process-rail { display: none }
  .process-path .process-step { text-align: left }
  .process-path .process-num { margin-left: 0 }
  /* The step is left-aligned from here down, but .process-text still carried
     the desktop centring pair, max-width: 250px with margin-inline: auto.
     In a full-width step that centred the paragraph inside its own column
     while the icon and title stayed hard left, so the three never lined up.
     min-height also held every paragraph open to three lines, leaving a gap
     under the short ones. Both are desktop-only concerns: they exist to keep
     five side-by-side columns even, and there are no columns here. */
  .process-path .process-text {
    max-width: none; margin-inline: 0; min-height: 0; padding-inline: 0;
  }
  /* The reveal stagger runs here too, but capped: main.js shortens the
     per-step gap below 1000px so the stacked steps arrive in under a
     second instead of holding blank space for the 500ms-per-step rhythm
     that was timed for a single wide row. */
}
/* On a phone the strip becomes a vertical list: disc on the left, title and
   text beside it, and a rule running down through the discs.

   Stacked the old way, disc above title above text, five steps ran 827px,
   a full screen of scroll for five one-line stages. Worse, the horizontal
   rail is hidden below 1000px, so nothing was left to say these were five
   stages of one process rather than five unrelated blocks. The vertical
   connector restores that reading and the side-by-side layout roughly halves
   the height. */
@media (max-width: 700px) {
  .process { grid-template-columns: 1fr; row-gap: 0 }
  .process-path .process-step {
    display: grid; grid-template-columns: 44px 1fr;
    column-gap: 16px; row-gap: 4px;
    padding: 0 0 24px; position: relative;
  }
  .process-path .process-step:last-child { padding-bottom: 0 }
  /* The connector starts below the disc and runs to the next one. Drawn per
     step rather than as one element so it cannot outlive the last disc. */
  .process-path .process-step:not(:last-child)::before {
    content: ''; position: absolute;
    left: 21px; top: 48px; bottom: 4px; width: 2px;
    background: var(--mist); border-radius: 2px;
  }
  .process-path .process-num {
    width: 44px; height: 44px; margin: 0;
    grid-row: 1 / 3; align-self: start;
  }
  .process-path .process-num svg { width: 20px; height: 20px }
  .process-path .process-title { grid-column: 2; margin: 0; align-self: center }
  /* Two lines reserved for every step, so a one-line stage does not sit at a
     shorter pitch than its neighbours and break the rhythm down the
     connector. The copy is trimmed to hold two lines at 360px and up; at
     320px every step wraps to three and the pitch is even again. */
  .process-path .process-text { grid-column: 2; min-height: calc(1.65em * 2) }
}

/* ============================================================
   CTA, Warm Cream
   ============================================================ */
/* A contained light box on a light section, rather than a full-bleed dark
   band. The old treatment was a solid slab in a dark that was not in the
   palette, sitting directly above a second dark footer. This suits the light
   design system the rest of the site is built on. */
.cta-section {
  padding: 56px 0 80px;
  background: var(--white);
  text-align: left;
}
/* Left-aligned card with a soft warm wash. One sentence carries it; the
   button sits inline with the email rather than pairing with a second
   button, so there is a single obvious action. */
.cta-box {
  max-width: 1040px;
  margin: 0 auto;
  padding: clamp(34px, 4.5vw, 52px) clamp(28px, 5vw, 60px);
  border-radius: 24px;
  display: flex; flex-wrap: wrap;
  align-items: center; justify-content: space-between;
  gap: 28px 48px;
  background: linear-gradient(120deg, #FDF7EC 0%, #F1F5F9 55%, #EAF1F8 100%);
}
.cta-section .container { position: relative; z-index: 1; }
/* The box is a two-column row: the question on the left, the actions on the
   right, both centred on the same axis. At 1040px the single-column version
   left the right half of the box empty. Sized so the pair fits one row from
   ~1000px up and stacks cleanly below. */
.cta-section h2 {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.4vw, 2.1rem);
  font-weight: 700; color: var(--ink);
  line-height: 1.2; letter-spacing: -.025em;
  max-width: 24ch;
  text-wrap: balance;
  margin: 0;
  flex: 1 1 380px;
}
/* Button over email on the right, so the question keeps ~640px and holds
   two lines. Side by side they took 444px and pushed the question to three. */
.cta-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 16px; flex: 0 0 auto }
@media (max-width: 1000px) {
  /* width:100% pins .cta-actions to the card's own content width. Without it,
     .cta-actions sizes to its content (flex: 0 0 auto on .cta-box), and the
     sitewide "@media ≤768px .btn{width:100%}" rule then resolves that 100%
     against the nearest sized ancestor instead, which on a narrow phone is
     effectively the viewport: the button rendered 437px wide inside a 232px
     card and ran off the right edge. */
  .cta-actions { flex-direction: row; align-items: center; flex-wrap: wrap; gap: 20px 24px; width: 100% }
}

/* Phone and email sit above the buttons so a reader who has got this far can
   act without another click. Matches the homepage CTA, which already had them. */
/* The button is the site's own primary navy, same as every other CTA.
   Only the padding is kept from the plum version that sat here before. */
.cta-box .btn-primary { padding: 15px 32px; }
.cta-box h2 { color: #0A2C49 }

/* ============================================================
   FOOTER, Clean Dark
   ============================================================ */
/* Dark footer, in the same plum as the CTA button. It was near-white
   (#FAFBFC) against a white CTA section, the page did not end, it faded out.
   The earlier objection to a dark footer was that it sat under a dark CTA in
   a different dark; the CTA is a light card now, so that no longer applies. */
.footer {
  background: #0A2C49;
  color: rgba(255,255,255,.72);
  padding: 64px 0 0;
}
/* Three columns: brand, Quick Links, Contact. Products and Company used to
   be two separate labelled columns; with three product links and four
   company links, eight in total, splitting them needed more structure than
   the list actually has. One "Quick Links" column holds all seven, products
   first, in the order a reader would look for them. */
/* Four columns on desktop, as the site always had: brand, Products,
   Company, Contact. The one-column "Quick Links" merge was a mobile-round
   change that leaked to desktop; reverted at the client's request. */
.footer-grid {
  display: grid; grid-template-columns: 1fr .85fr .85fr 1.9fr;
  gap: 40px; padding-bottom: 44px;
  border-bottom: 1px solid rgba(255,255,255,.10);
}
/* Below 900px Contact needs more than a quarter of the row for a two-line
   address, so it drops to its own full-width row. */
@media (max-width: 900px) {
  .footer-grid { grid-template-columns: 1fr 1fr 1fr; gap: 32px }
  .footer-grid > div:nth-child(4) { grid-column: 1 / -1; margin-top: 4px }
}
/* The logo is navy and gold, on a dark ground it needs a light plate
   behind it or it disappears. */
.footer-logo {
  display: inline-block;
  background: #fff; border-radius: 12px; padding: 7px 12px;
}
.footer-logo img { height: 34px; width: auto; display: block }
.footer-tagline {
  margin-top: 18px; max-width: 24ch;
  font-size: .84rem; line-height: 1.6;
  color: rgba(255,255,255,.62);
}
.footer-contact-row {
  display: flex; align-items: baseline; gap: 10px;
  margin-top: 12px; font-size: .84rem;
}
/* Fixed-width label column so the four values line up on a common left edge.
   .50 alpha measures 5.05:1 on #241D30, the labels are secondary to the
   values beside them but still clear AA. */
.footer-contact-label {
  flex: 0 0 58px;
  font-size: .66rem; font-weight: 600;
  letter-spacing: 1.1px; text-transform: uppercase;
  color: rgba(255,255,255,.50);
}
/* On phones the 58px label column costs the address exactly the width it needs
, at 414px the value box lands on 290px against the 298px the longest line
   measures. Stacking the label hands the whole column back to the value.
   This has to sit AFTER the two rules above, not up with the other footer
   breakpoints: same specificity, so source order decides. */
@media (max-width: 480px) {
  .footer-contact-row { display: block }
  .footer-contact-label { display: block; margin-bottom: 2px }
}
/* Footer opacities raised across the board, the previous values measured
   between 2.3:1 and 3.4:1 against the dark background and failed WCAG AA.
   Hierarchy is preserved by keeping links brighter than column headings. */
.footer-col-title {
  font-size: .7rem; font-weight: 700;
  letter-spacing: 2px; text-transform: uppercase;
  color: rgba(255,255,255,.55); margin-bottom: 16px;
}
.footer-link {
  display: block; font-size: .86rem;
  color: rgba(255,255,255,.75);
  /* 12px matches the contact rows, one vertical rhythm down the whole
     footer. Tablet and phone blocks override this margin, so the change
     lands on desktop only. */
  transition: color var(--t-fast); margin-bottom: 12px;
}
.footer-link:hover { color: #fff }
.footer-link-inline { margin: 0 }
.footer-bottom {
  display: flex; justify-content: space-between; align-items: center;
  padding: 18px 0; font-size: .78rem;
  color: rgba(255,255,255,.55); flex-wrap: wrap; gap: 8px;
}

/* Mobile footer. These must sit AFTER the base rules above: same specificity,
   so source order decides. Placed earlier, .footer-link{margin-bottom:9px}
   kept winning and the tap padding stacked on top of it.
   Sizes here are the mobile floor: 15px body, 12px labels. The desktop scale
   (13.8 / 11.2 / 10.6px) is too small to read comfortably on a phone. */
@media (max-width: 900px) {
  .footer { padding-top: 48px }
  .footer-grid { gap: 28px; padding-bottom: 32px }
  .footer-col-title { font-size: .75rem; margin-bottom: 8px }
  /* 9px top/bottom brings the tap target to ~44px, the size a thumb needs;
     the desktop 7px was sized for a mouse pointer. */
  .footer-link { font-size: .94rem; padding: 9px 0; margin-bottom: 0 }
  .footer-tagline { font-size: .94rem }
  .footer-contact-label { font-size: .75rem }
  .footer-contact-row { font-size: .94rem }
  .footer-bottom { font-size: .82rem }
}
/* Phone. Tighter than the 900px tablet block: smaller logo, smaller type,
   less padding throughout, so the footer reads as a compact close to the
   page rather than a second scroll of its own. Links keep a 40px tap
   target (9px vertical padding over .88rem/1.5 line-height), just under the
   44px ideal but still comfortably tappable at this reduced scale. */
@media (max-width: 560px) {
  .footer { padding-top: 32px }
  .footer-logo img { height: 30px }
  /* One size, one weight, one case for every line of footer text. QUICK
     LINKS / CONTACT / ADDRESS were bold, uppercase and letter-spaced at the
     same font-size as the plain text around them, which still read as a
     different, larger type on the page even though the number was equal.
     Flattened here to the same plain style as a link or a tagline; the
     labels are still distinguished by sitting alone on their own line. */
  .footer-tagline, .footer-col-title, .footer-link, .footer-contact-label,
  .footer-contact-row, .footer-bottom { font-size: .76rem; }
  .footer-col-title, .footer-contact-label {
    font-weight: 400; text-transform: none; letter-spacing: normal;
  }
  /* One gap value for every vertical space in the footer: between the three
     blocks, between a heading and its first line, between one line and the
     next. Margins and padding used to set this piece by piece (10px here,
     6px there, 7px of padding somewhere else) and never quite matched;
     flex + gap makes it exact by construction instead of by arithmetic. */
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 20px 24px; padding-bottom: 14px }
  /* The brand block stays on phones: the logo plate and tagline give the
     footer a proper head instead of opening cold on a list of links.
     Products and Company are two short lists, so they sit side by side;
     the brand block and Contact span the full width. nth-child counts DOM
     children: 1 brand, 2 Products, 3 Company, 4 Contact. */
  .footer-grid > div:nth-child(1) { grid-column: 1 / -1; align-items: flex-start; gap: 12px }
  .footer-tagline { max-width: 40ch }
  .footer-grid > div { display: flex; flex-direction: column; gap: 14px }
  /* 7px vertical padding lifts each link's hit area to ~31px; the Quick
     Links column drops its flex gap to 2px so the visible rhythm stays
     close to the 14px used elsewhere. */
  .footer-link { padding: 7px 0 }
  .footer-grid > div:nth-child(2), .footer-grid > div:nth-child(3) { gap: 2px }
  .footer-contact-row { margin-top: 0 }
  /* A hairline separates Contact from Quick Links above it; without it
     Contact ran straight on with only the grid's row gap and read as part
     of the same list rather than its own block. Its own top padding matches
     the shared gap so the rhythm does not break across the divider. */
  .footer-grid > div:nth-child(4) {
    margin-top: 0; padding-top: 14px;
    border-top: 1px solid rgba(255,255,255,.10);
  }
  .footer-bottom { flex-direction: column; align-items: flex-start; gap: 14px; padding: 14px 0 }
  /* Underline tried here and dropped: on the dark background at this size
     it read as a stray line rather than a heading treatment. */
  .footer-tagline, .footer-col-title, .footer-link, .footer-contact-row { margin: 0 }
  .footer-col-title { margin-bottom: 0 }
}

/* ============================================================
   PAGE HERO, Light Inner Pages
   ============================================================ */
/* The nav is fixed and 101px tall, so padding-top has to clear it before any
   of it reads as breathing room.
   Background was --navy-tint, a fairly saturated pink that sat oddly on an
   industrial site and clashed with the new light CTA box. Now a near-white
   neutral that lets the heading carry the page. */
.page-hero {
  position: relative; overflow: hidden;
  padding: 168px 0 66px;
  background: var(--snow);
  text-align: center;
}
/* On a phone the breadcrumb tells a reader nothing they do not already know
   (they are one tap into the site from the nav) and the banner it sits in
   costs a full screen's worth of scroll before any real content. Dropped
   below 768px on any plain banner; About's geo banner is excluded and stays. The full-height
   .page-hero-tall banner on the 404 and thank-you pages is the page's only
   content and stays. Since the banner also carried the nav clearance, the
   section right after it picks that up instead so it does not render under
   the fixed bar. */
@media (max-width: 768px) {
  .page-hero:not(.page-hero-tall):not(.page-hero--geo) { display: none; }
  .page-hero:not(.page-hero-tall):not(.page-hero--geo) + section { padding-top: 121px; }
}
/* Offsets are tuned against the real box, not the preview's: the nav is fixed
   and 101px tall, so anything centred above ~110px is hidden behind it. The
   first disc centres at 160px and the second at ~295px, framing the heading
   from upper-left and lower-right. */
.page-hero::before,
.page-hero::after {
  content: ''; position: absolute; border-radius: 50%;
  filter: blur(70px); opacity: .55; pointer-events: none;
}
.page-hero::before { width: 380px; height: 380px; background: #F6DCC6; top: -30px; left: -70px }
.page-hero::after  { width: 320px; height: 320px; background: #DCE7F1; bottom: -140px; right: -50px }
.page-hero > .container { position: relative; z-index: 1 }
/* .page-hero-tall (404, thank-you) centres its content with flex, so its child
   needs the same lift to clear the discs. */
.page-hero-tall > * { position: relative; z-index: 1 }
/* Smaller than the homepage hero (72px) so the front page still leads. */
.page-hero h1 {
  font-size: clamp(1.9rem, 4vw, 3rem);
  line-height: 1.14;
  color: var(--ink);
  margin-bottom: 14px;
}
.page-hero .lead { color: var(--text-sub); margin: 0 auto; max-width: 620px }

/* Contact hero: the photo alone, cropped edge to edge and kept shallow so it
   does not push the form down the page. The band is a fixed height and the
   image covers it. The source is already a 5:2 band so 52% framing centres
   the discs; the earlier 76% was compensating for a tall 3:2 original. */
.contact-hero-img {
  padding-top: 101px;            /* the fixed nav; 1240/900 steps below */
  line-height: 0;
}
@media (max-width: 1240px) { .contact-hero-img { padding-top: 73px } }
.contact-hero-img img {
  display: block; width: 100%;
  height: clamp(150px, 17vw, 250px);
  object-fit: cover; object-position: center 52%;
}
@media (max-width: 900px) {
  .contact-hero-img { padding-top: 81px }
  .contact-hero-img img { height: clamp(130px, 22vw, 170px) }
}

@media (max-width: 900px) {
  .page-hero { padding: 132px 0 62px }   /* nav is 72px at this breakpoint */
}

/* Industries We Serve, phones: the first five cards stand, the other five sit
   behind a Read more toggle so ten stacked cards do not become three screens
   of scroll. Desktop shows all ten and never sees the button. */
/* Compound selector on purpose: the plain class lost to .story-toggle's own
   display: inline-flex, which sits later in the file at equal specificity. */
.story-toggle.ind-more-toggle { display: none; }
@media (max-width: 900px) {
  .ind-grid-h[data-collapsed="true"] .ind-card-h:nth-child(n+6) { display: none; }
  .story-toggle.ind-more-toggle { display: inline-flex; margin-top: 18px; }
}
/* The breadcrumb inside is hidden on phones, so the bar must not keep
   reserving its padding, and the following section returns to a normal gap. */
@media (max-width: 768px) {
  .breadcrumb-bar + .section { padding-top: 56px }
}
.breadcrumb-bar + .section { padding-top: 44px }

/* ============================================================
   SPEC TABLE
   ============================================================ */
.spec-table {
  width: 100%; max-width: 760px; margin-inline: auto; border-collapse: collapse; font-size: .9rem;
  background: var(--white);
}
/* Column headings only, scoped to thead so row headings (<th scope="row">)
   are not also rendered as dark bars. */
.spec-table thead th {
  background: var(--ink); color: #fff;
  padding: 13px 18px; text-align: left;
  font-weight: 600; font-size: .8rem;
  letter-spacing: .5px;
  white-space: nowrap;
}
.spec-table thead th:first-child { border-radius: var(--r-sm) 0 0 0 }
.spec-table thead th:last-child  { border-radius: 0 var(--r-sm) 0 0 }

/* Row headings, the leftmost label cell in each body row */
.spec-table tbody th {
  padding: 12px 18px; text-align: left;
  font-weight: 700; color: var(--ink);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.spec-table td {
  padding: 12px 18px;
  border-bottom: 1px solid var(--border);
  color: var(--charcoal);
}
.spec-table tbody tr:nth-child(even) th,
.spec-table tbody tr:nth-child(even) td { background: var(--snow) }
.spec-table tbody tr:last-child th,
.spec-table tbody tr:last-child td { border-bottom: none }
.spec-table td:last-child { font-weight: 700; color: var(--navy) }

/* Modifier: no navy emphasis on the final column. Used where the last
   column is an ordinary value (mesh range, dispatch note) rather than the
   headline figure. */
.spec-table--flat td:last-child { font-weight: 500; color: var(--charcoal) }
.spec-table caption { text-align: left }

/* ============================================================
   APP TAGS
   ============================================================ */

/* ============================================================
   FORMS & INQUIRY
   ============================================================ */
/* White, not cream. The page already carries warmth above and below it (the
   hero's tinted discs, the closing CTA box), so a warm form card made three
   warm blocks in a row with no hierarchy between them, and left the fields
   with nothing to sit against. */
.form-wrap {
  padding: 34px 34px 30px; background: var(--white);
  border-radius: var(--r-xl); border: 1px solid var(--mist);
  box-shadow: var(--sh-xs);
  max-width: 800px; /* Capped for premium look on laptop */
}

/* The card's only header is the small label; the left column carries the
   section's heading and pitch, so the card does not repeat them. */
/* Centred within their own column. .eyebrow is inline-flex, so justify-content
   alone only centres the flanking rules inside it; display:flex makes the
   element itself span the column so the whole label centres. */
.form-wrap .eyebrow { display: block; width: fit-content; margin: 0 auto 22px; }

.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 18px; }
.form-group { margin-bottom: 18px; display: flex; flex-direction: column; }
.form-row .form-group { margin-bottom: 0; }
.form-label { font-size: .76rem; font-weight: 600; color: var(--charcoal); margin-bottom: 7px; text-transform: uppercase; letter-spacing: .6px; }
/* #8792A3 measures 3.15:1 on white, clearing the 3:1 WCAG 1.4.11 asks for
   the visual boundary of a UI component. The fill stays near-white on
   purpose: on a form the border should carry the boundary and the fill should
   stay out of the text's way. */
.form-control {
  width: 100%; padding: 14px 18px;
  border: 1px solid #8792A3; border-radius: var(--r-md);
  background: var(--white); font-family: inherit;
  font-size: .95rem; transition: all var(--t-fast); color: var(--ink);
}
.form-control:hover { border-color: #6F7A8A }
.form-control:focus { outline: none; border-color: var(--navy); background-color: #fff; box-shadow: 0 0 0 3px rgba(15, 62, 102, .12); }
textarea.form-control { min-height: 96px; resize: vertical; }

/* A select carried the same border, radius and padding as the text inputs,
   but the browser drew its own arrow and gave the box two extra pixels of
   height. Turning the native appearance off settles both: the box now
   matches the inputs exactly and the caret is the same triangle the country
   picker uses. The open list is deliberately left native, because on a phone
   that is the operating system picker, which beats anything drawn in a page.
   The country code select is excluded: it keeps its own compact padding for
   the no-JS path. */
select.form-control:not(.phone-cc) {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  padding-right: 44px;
  /* Chrome keeps a minimum line box inside a select that appearance:none does
     not clear, which left it 2.4px deeper than the inputs beside it. Any
     explicit line-height drops it; this ratio is the one the inputs resolve
     to at the same font-size, so the two sit exactly level. */
  line-height: 1.21;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5'%3E%3Cpath d='M0 0h8L4 5z' fill='%237E8999'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 18px center;
}
/* Placeholder darkened from the faint browser default to a readable grey that
   still stays clearly lighter than typed input (var(--ink)). opacity:1 stops
   Firefox from fading it further. */
.form-control::placeholder { color: #6A7383; opacity: 1; }

/* Equal-height columns. Rather than stretching the card and leaving dead white
   space under the button, the message box absorbs the difference: the card
   fills the row, the form fills the card, and the one flexible group takes
   whatever is left. The slack becomes a bigger textarea, which is useful
   rather than empty. min-height still floors it if the left column is short. */
.form-wrap { display: flex; flex-direction: column }
.form-wrap form { display: flex; flex-direction: column; flex: 1 1 auto }
.form-group-grow { flex: 1 1 auto; min-height: 0 }
.form-group-grow textarea.form-control { flex: 1 1 auto; height: 100% }
@media (max-width: 900px) {
  /* Stacked, there is no neighbour to match, so the textarea returns to its
     natural size instead of stretching to fill a full-width card. */
  .form-group-grow { flex: 0 0 auto }
  .form-group-grow textarea.form-control { height: auto }
}

/* Country code and number read as one control: the select is fixed-width and
   the number takes the rest, with the seam between them a single shared
   border rather than two adjacent ones. */
.phone-field { display: grid; grid-template-columns: 92px 1fr; gap: 0 }
.phone-field .phone-cc {
  border-top-right-radius: 0; border-bottom-right-radius: 0;
  border-right-color: transparent;
  padding-left: 12px; padding-right: 4px;
  font-size: .88rem;
}
.phone-field input[type="tel"] {
  border-top-left-radius: 0; border-bottom-left-radius: 0;
}
/* Focus has to lift the focused half above its neighbour or the ring is
   clipped by the adjacent border. */
.phone-field .form-control:focus { position: relative; z-index: 1; border-right-color: var(--navy) }

/* Country picker. The native select stays in the DOM for form submission and
   for the no-JS path; it is only hidden once the picker has replaced it. */
.ccp { position: relative }
.ccp-btn {
  display: flex; align-items: center; gap: 7px;
  height: 100%; width: 100%; cursor: pointer; text-align: left;
  border-top-right-radius: 0; border-bottom-right-radius: 0;
  border-right-color: transparent; padding-left: 12px; padding-right: 8px;
}
.ccp-btn:hover { border-color: #6F7A8A }
.ccp-btn[aria-expanded="true"] { border-color: var(--navy); position: relative; z-index: 2 }
.ccp-flag { width: 20px; height: 15px; object-fit: cover; border-radius: 2px; flex: 0 0 20px;
  box-shadow: 0 0 0 1px rgba(0,0,0,.10) }
.ccp-dial { font-size: .86rem; color: var(--ink); white-space: nowrap }
.ccp-caret { margin-left: auto; width: 0; height: 0;
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid #7E8999 }
/* Popup is wider than the 92px button so country names fit. */
.ccp-pop {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 30;
  width: 290px; max-width: 78vw;
  background: var(--white); border: 1px solid #C2CCDA;
  border-radius: var(--r-md); box-shadow: var(--sh-lg); overflow: hidden;
}
.ccp-search {
  width: 100%; border: 0; border-bottom: 1px solid var(--border);
  padding: 12px 14px; font: inherit; font-size: .9rem; color: var(--ink);
  background: var(--white); outline: none;
}
.ccp-search:focus { border-bottom-color: var(--navy) }
.ccp-list { max-height: 240px; overflow-y: auto; margin: 0; padding: 4px 0; list-style: none }
.ccp-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 14px; cursor: pointer; font-size: .9rem;
}
.ccp-row:hover, .ccp-row.is-active { background: var(--navy-tint) }
.ccp-row[aria-selected="true"] { font-weight: 600 }
.ccp-row .ccp-name { color: var(--ink); flex: 1 1 auto }
.ccp-row .ccp-dial { color: var(--text-sub) }

/* Quick enquiry: two fields, sitting directly under the spec table where a
   buyer has just decided the grade fits. Copy on the left, form on the right,
   so it reads as one short ask rather than a page-width form. */
.quick-enq {
  display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center;
  max-width: 1000px; margin: 0 auto;
  background: var(--white); border: 1px solid #C2CCDA;
  border-radius: var(--r-xl); box-shadow: var(--sh-md); padding: 40px;
}
.quick-enq-copy .eyebrow { justify-content: flex-start; margin-bottom: 10px }
.quick-enq-copy h2 { font-size: 1.5rem; line-height: 1.3; margin-bottom: 10px }
.quick-enq-copy p { font-size: .95rem; line-height: 1.7; color: var(--text-sub); margin: 0 }
.quick-enq-form .form-group { margin-bottom: 18px }
.quick-enq-form .btn { margin-top: 4px }
.quick-enq-alt { margin: 14px 0 0; font-size: .84rem; color: var(--text-sub); text-align: center }
.quick-enq-alt a { color: var(--navy); font-weight: 600; text-decoration: underline; text-underline-offset: 3px }
@media (max-width: 860px) {
  .quick-enq { grid-template-columns: 1fr; gap: 28px; padding: 30px 24px }
  .quick-enq-copy h2 { font-size: 1.3rem }
  /* Stacked above the form, the copy centres and reads as the card's header
     rather than a left-hung column. */
  .quick-enq-copy { text-align: center }
}

/* The old two-column contact layout (.contact-grid / .contact-info-wrap /
   .contact-method(s) / .contact-icon / .contact-lbl / .contact-val /
   .contact-link) was removed on 2026-09-10 when the contact page was rebuilt
   as .contact-v2. The contact hero image (.contact-hero-img) lives further
   down and is still in use. */

/* .contact-products-box and its children removed with the markup. The three
   product links it carried are still reachable from the nav and the footer,
   which is where a visitor on the contact page looks for them anyway. */

/* ============================================================
   SEO PRODUCT PAGE, Light Hero
   ============================================================ */

/* Bottom padding was 44px, so the gap into the next section came to 96px
   against the 160px every other boundary on the page uses. 80px matches the
   .section rhythm exactly. */
/* The nav is fixed and 101px tall, so a flat 120px left only 19px of air above
   the breadcrumb on desktop while narrow screens, where the nav drops to 81px,
   got 39px. The gap was inverted. Padding now clears the nav explicitly and
   leaves the same ~52px at both, matching what .page-hero and .contact-hero-img
   already do. The 1240px breakpoint is where .nav-inner drops to 72px. */
.prod-page-hero {
  padding: 152px 0 80px;
  background: var(--white);
}
@media (max-width: 1240px) {
  .prod-page-hero { padding-top: 132px }
}
.prod-page-hero-inner {
  max-width: var(--max); margin: 0 auto;
  padding: 0 var(--gutter);
  display: grid; grid-template-columns: 1.26fr .74fr;
  gap: 60px; align-items: center;
}
.prod-page-hero h1 { color: var(--ink); margin-bottom: 9px }
/* The all-caps pill above the heading became this quiet line below it: same
   content, no longer shouting before the h1 gets a word in. */
/* The button row used a generic .mt-28 utility; in this hero it needs to
   clear the spec strip by a little more than the utility gives. */
.prod-page-hero .mt-28 { margin-top: 34px }
/* The identity line carries the product's other names, so it is metadata, not
   prose. It was set in --text-sub, the same colour as the lead directly beneath
   it, which made it read as the first line of the paragraph. Maroon separates
   the two registers and holds 11.16:1, so it stays legible on a phone outdoors
   where --gold-text at 4.75:1 was the weakest link. Never uppercase this:
   Ca(OH) with a subscript two would become CA(OH), which is not the formula. */
.prod-ident {
  font-size: .92rem; font-weight: 500;
  color: var(--navy);
  letter-spacing: .03em;
  margin: 0 0 26px;
}

.prod-page-hero .lead { color: var(--text-sub); max-width: 100%; margin-bottom: 32px }
.prod-page-hero .breadcrumb { justify-content: flex-start; margin-bottom: 26px }

/* Gold corner brackets on two opposite corners, drawn with pseudo-elements so
   no extra markup is needed. The frame is the padding; the image sits inside
   it and lifts slightly on hover (transform only, so it stays on the
   compositor and never repaints). */
.prod-page-hero-img {
  position: relative; padding: 12px;
  border-radius: 0; overflow: visible; box-shadow: none; border: 0;
  aspect-ratio: auto;
}
.prod-page-hero-img::before,
.prod-page-hero-img::after {
  content: ""; position: absolute; width: 38px; height: 38px;
  border: 2px solid var(--ink); pointer-events: none;
}
.prod-page-hero-img::before { top: 0; left: 0; border-right: 0; border-bottom: 0; border-radius: 6px 0 0 0 }
.prod-page-hero-img::after  { bottom: 0; right: 0; border-left: 0; border-top: 0; border-radius: 0 0 6px 0 }
.prod-img-inner {
  /* 3:2 at every width, same ratio as the homepage product cards. The old
     square crop threw away most of the 1200x438 source and stood taller
     than the text column beside it. */
  aspect-ratio: 3 / 2; overflow: hidden;
  border-radius: var(--r-xl); border: 1px solid var(--border);
}
.prod-page-hero-img img {
  width: 100%; height: 100%; object-fit: cover; object-position: center; display: block;
  transition: transform .55s cubic-bezier(.2,.6,.2,1);
}
.prod-page-hero-img:hover img { transform: scale(1.05) }
@media (prefers-reduced-motion: reduce) {
  .prod-page-hero-img img { transition: none }
  .prod-page-hero-img:hover img { transform: none }
}

.hero-spec-strip {
  display: flex; gap: 24px; flex-wrap: wrap;
  margin-top: 36px; padding-top: 34px;
  border-top: 1px solid var(--border);
}
.hero-spec-item { padding-left: 18px; border-left: 3px solid var(--gold) }
.hero-spec-val {
  font-family: var(--font-display);
  font-size: 1.6rem; font-weight: 700;
  color: var(--navy); line-height: 1;
}
.hero-spec-lbl { font-size: .72rem; color: var(--text-sub); margin-top: 4px }

/* ============================================================
   PRODUCTS DETAIL (products.html)
   ============================================================ */

/* ============================================================
   VALUES / CERTS
   ============================================================ */
/* Two wide rows rather than three narrow cards: at 3-up the body text was
   only ~293px wide and centred, which is the hardest combination to read. */
.val-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 42px 56px }
/* Below ~860px the 68px disc and its gutter leave the text column under 250px
, roughly 38 characters, too narrow for paragraphs this long. One column
   from here down gives it the full width back. */
@media (max-width: 860px) {
  .val-grid { grid-template-columns: 1fr; gap: 34px }
  /* Six values are a desktop read. On a phone the last two (Multi-Grade
     Capability, Flexible Supply Formats) repeat catalogue facts the page
     already states, so the list stops at the four real values. */
  .val-card:nth-child(n+5) { display: none }
}
.val-card {
  display: grid; grid-template-columns: 68px 1fr; gap: 20px;
  align-items: center; text-align: left;
  padding: 0; background: none; border: none; border-radius: 0;
}
/* Without this the card stretches to the tallest in its row, and the icon
   would centre on that borrowed height rather than on its own paragraph. */
.val-card { align-self: start }
/* Same tinted disc as the process strip and the certification icons, so the
   About page now carries one circle treatment end to end. */
.val-icon {
  width: 68px; height: 68px; border-radius: 50%;
  background: var(--navy-tint); border: 1px solid rgba(107,31,58,.16);
  display: grid; place-items: center;
  font-size: 2rem; line-height: 1; margin: 0;
}
.val-title {
  font-family: var(--font-body); font-weight: 700;
  font-size: 1rem; color: var(--ink); margin: 0 0 7px;
}
/* Capped measure. Two columns never reach this (54ch at 1280px), but one
   column at 860px would otherwise run to 87 characters a line. */
.val-text { font-size: .9rem; color: var(--text-sub); line-height: 1.7; max-width: 62ch }

.cert-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px }
.cert-card {
  border: 1px solid var(--border); border-radius: var(--r-md);
  padding: 24px 18px; text-align: center; background: var(--white);
}
/* Tinted disc + line-art mark + a check badge notched into the corner. Three
   identical seals told the reader nothing; the icon now names the credential
   and the badge carries the "approved" signal. Hues are per-card so the row
   reads as three separate approvals. font-size:0 kills the inline-SVG
   whitespace baseline gap. */
.cert-icon {
  position: relative;
  width: 66px; height: 66px; margin: 0 auto 18px;
  border-radius: 50%;
  background: var(--ci-tint); border: 1px solid var(--ci-ring);
  color: var(--ci-ink);
  display: grid; place-items: center; font-size: 0;
}
.cert-icon .ci-main { width: 28px; height: 28px }
.cert-icon .ci-check {
  position: absolute; right: -1px; bottom: -1px;
  width: 23px; height: 23px; border-radius: 50%;
  /* The badge is the "approved" signal, so it takes the confirmation green
     on all three cards; only the main mark keeps the per-card hue. */
  background: var(--green); color: #fff;
  border: 2.5px solid var(--white);
  display: grid; place-items: center;
}
.cert-icon .ci-check svg { width: 11px; height: 11px }
/* Amber, indigo, green. Every --ci-ink measures at least 4.5:1 on its own tint,
   comfortably past the 3:1 WCAG asks of a meaningful graphic. The client wants
   these three hues kept as they are (2026-09-09); do not fold them into aqua. */
.cert-card:nth-child(1) { --ci-tint: #FCF2E0; --ci-ring: #EEDCB6; --ci-ink: #9A6A15 }
.cert-card:nth-child(2) { --ci-tint: #ECEFFC; --ci-ring: #CFD8F5; --ci-ink: #2F4FC9 }
.cert-card:nth-child(3) { --ci-tint: #E7F6EC; --ci-ring: #C2E5CF; --ci-ink: #1F7A32 }
.cert-title { font-family: var(--font-body); font-weight: 700; font-size: .88rem; color: var(--ink) }
.cert-sub { font-size: .84rem; color: var(--text-sub); margin-top: 5px; line-height: 1.6 }
/* Lead answers the heading before the cards get to it. */
.qa-lead {
  max-width: 66ch; margin: -6px auto 40px; text-align: center;
  font-size: 1rem; line-height: 1.8; color: var(--text-sub);
}
/* The global rule is `a { color: inherit; text-decoration: none }`, so an
   inline link inside body copy is invisible without this. */
.qa-lead a {
  color: var(--navy); font-weight: 600;
  text-decoration: underline; text-underline-offset: 3px;
}
.qa-lead a:hover { text-decoration-thickness: 2px }

.check   { color: var(--gold-dark); font-weight: 700 }

/* Industry Dense Grid stays here */

/* ============================================================
   UTILITIES
   ============================================================ */
.mt-16{margin-top:16px}

.d-flex{display:flex}

.gap-12{gap:12px}

.fw{flex-wrap:wrap}
/* ============================================================
   /* Responsive section moved to end */

/* ============================================================
   INDUSTRY DENSE GRID (product pages)
   ============================================================ */

/* Removed redundant media queries, consolidated in previous block */

/* ============================================================
   INDUSTRY CARDS, Horizontal Expandable (v2)
   ============================================================ */
.ind-grid-h {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  align-items: start;
}

.ind-card-h {
  background: var(--white);
  border-radius: 14px;
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--cat, var(--navy));
  box-shadow: var(--sh-xs);
  padding: 20px 20px 16px 20px;
  cursor: default;
  transition: box-shadow .3s ease, transform .3s ease, background .3s ease;
  /* scroll reveal */
  opacity: 0;
}
/* The 50px pre-reveal offsets poke past the viewport on narrow screens and
   create a 5px horizontal scroll until the cards animate in. Clipping the
   section keeps the animation and removes the scrollbar. */
#industries { overflow-x: clip }
.ind-card-h.from-left  { transform: translateX(-50px); }
.ind-card-h.from-right { transform: translateX(50px); }
.ind-card-h.visible {
  opacity: 1;
  transform: translateX(0);
  transition: opacity .55s ease, transform .55s cubic-bezier(.22,.68,0,1.2), box-shadow .3s ease;
}
/* Hover tints the card with its own category colour and does nothing else. The
   old hover also lifted the card and deepened its shadow, which is the vocabulary
   of a button, and these cards are no longer clickable. A background shift alone
   reads as "the pointer is here" rather than "click me".
   The tints run 1.03 to 1.11 against white, so body copy stays above 11:1 on all
   sixteen of them. Guarded by hover:hover because on a touchscreen :hover sticks
   after a tap and the card would stay tinted until something else was tapped. */
@media (hover: hover) {
  .ind-card-h:hover { background: var(--cat-bg, var(--snow)); }
}

.ind-head-h {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 12px;
}
.ind-icon-h {
  width: 54px; height: 54px;
  border-radius: 12px;
  background: var(--cat-bg, var(--pearl));
  display: flex; align-items: center; justify-content: center;
  font-size: 1.75rem; flex-shrink: 0;
  transition: transform .25s ease;
}
.ind-title-wrap-h { flex: 1; min-width: 0; }
.ind-title-h {
  font-size: 1rem; font-weight: 700;
  color: var(--ink); line-height: 1.3; margin-bottom: 3px;
}
.ind-tag-h {
  font-size: .62rem; font-weight: 600;
  letter-spacing: .5px; text-transform: uppercase;
  color: var(--cat, var(--navy)); opacity: .8;
}
.ind-p1-h {
  font-size: .82rem; color: var(--slate);
  line-height: 1.7; margin-bottom: 0;
}
.ind-p1-h strong { color: var(--charcoal); font-weight: 600; }

/* Applications band: a bold navy field with a soft gold dot pattern in the
   corner, all eight application tiles in full view on top of it, bleeding past
   the band's lower edge. Each tile is a photo with a solid name bar; hover
   zooms the photo, flips the bar to gold and fades the description up over
   the image. Descriptions stay in the markup for search engines. */
.industries-band { position: relative; background: var(--white); overflow: hidden; }

.app-tiles { --tile-img: 190px; display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; position: relative; }
/* Navy strap behind the cards: fades in softly at the top and stops short of the
   bottom so the lower fifth of the grid bleeds onto white. A faint gold dot
   texture sits over the navy. */
.app-tiles::before { content: ""; position: absolute; z-index: 0; pointer-events: none;
  left: 50%; transform: translateX(-50%); width: 100vw; top: 14%; bottom: 14%;
  background: var(--navy-dark, #0F2A44); }
.app-tile { position: relative; z-index: 1; background: var(--white); border-radius: 14px; overflow: hidden;
  box-shadow: 0 14px 32px rgba(6,16,30,.30), 0 3px 9px rgba(6,16,30,.18); transition: transform .3s ease, box-shadow .3s ease; }
.app-tile-media { aspect-ratio: 3 / 2; overflow: hidden; background: var(--pearl); }
.app-tile-media picture, .app-tile-media img { display: block; width: 100%; height: 100%; }
.app-tile-media img { object-fit: cover; transition: transform .6s cubic-bezier(.2,.7,.2,1); }
.app-tile-bar { padding: 14px 16px; background: var(--white); color: var(--navy); text-align: center;
  border-top: 1px solid rgba(15,42,68,.09); }
.app-tile-name { font-weight: 700; font-size: .96rem; line-height: 1.3; }
.app-tile-tag, .app-tile-desc { display: none; }
.app-more { text-align: center; margin: 40px auto 0; max-width: 680px; color: var(--ink); font-size: 1.08rem; font-weight: 500; }
.app-more strong { font-weight: 800; color: var(--navy); }
.app-more a { color: var(--acc-gold2, #8a6205); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
/* Phones keep the navy strap: the tiles run two to a row here, not one tall
   column, so the strap sits behind the middle of the grid exactly as it does
   on desktop. */
@media (max-width: 620px) {
  .app-tiles { gap: 16px; }
  /* Applications header is tighter on phones; the lead just restates the
     heading, so it is hidden here to bring the tiles up sooner. */
  .industries-band .sh { margin-bottom: 20px; }
  .industries-band .sh .lead { display: none; }
}

/* Powder grades: product-image cards (photo on top, then name, tier, copy and a
   sample CTA). The top grade carries a gold accent. */
.grade-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 56px; max-width: 860px; margin-inline: auto; }
.grade-card { display: flex; flex-direction: column; background: var(--white); border: 1px solid var(--border);
  border-radius: var(--r-lg); overflow: hidden;
  transition: border-color .3s ease; }
.grade-card:hover { border-color: var(--gold-light, #e6cf8f); }
.grade-media { aspect-ratio: 1 / 1; background: var(--pearl); overflow: hidden; }
.grade-media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .5s ease; }
.grade-card:hover .grade-media img { transform: none; }
.grade-body { padding: 15px 17px 17px; display: flex; flex-direction: column; flex: 1; }
.grade-name { font-family: var(--font-head, "Nunito", sans-serif); font-size: 1.2rem; color: var(--ink); margin: 0 0 8px; }
.grade-desc { font-size: .85rem; color: var(--slate); line-height: 1.6; margin: 0 0 14px; }
.grade-cta { margin-top: auto; align-self: flex-start; font-weight: 700; font-size: .9rem; color: var(--navy);
  text-decoration: underline; text-underline-offset: 3px; }
.grade-cta:hover { color: var(--acc-gold2, #8a6205); }
@media (max-width: 720px) { .grade-grid { grid-template-columns: 1fr; } }
@media (hover: hover) {
  .app-tile:hover { transform: translateY(-6px); box-shadow: 0 18px 40px rgba(0,0,0,.32); }
  .app-tile:hover .app-tile-media img { transform: scale(1.06); }
}
@media (max-width: 1000px) { .app-tiles { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) {
  .app-tiles { --tile-img: 170px; grid-template-columns: repeat(2, 1fr); gap: 12px; }
  /* 2-col phone grid: reserve two lines for the name so 1-line and 2-line
     names give every tile the same height and the row bottoms line up. */
  .app-tile-bar { padding: 10px 12px; }
  .app-tile-name { display: flex; align-items: center; justify-content: center; min-height: 2.6em; }
}

/* Removed redundant media query */

/* ============================================================
   RESPONSIVE (Consolidated)
   ============================================================ */

@media(max-width:900px) {
  .prod-page-hero-inner { grid-template-columns: 1fr; gap: 0; }
  /* Stacked, the photograph moves up under the title: h1, identity line,
     photo, then the description and the rest. In source the image sits
     after the whole text column; display: contents dissolves the text
     wrapper so its children and the image share one grid and can be
     ordered. The grid gap is dropped because every child now brings its
     own margin. */
  .prod-page-hero-inner > div:first-child { display: contents; }
  .prod-page-hero-inner > div:first-child > .breadcrumb { order: 0; }
  .prod-page-hero-inner > div:first-child > h1 { order: 1; }
  .prod-page-hero-inner > div:first-child > .prod-ident { order: 2; }
  .prod-page-hero-img { order: 3; margin: 12px 0 16px; }
  /* The stats sit directly under the photo as its caption, then the
     description, then the buttons close the hero. Between the lead and the
     buttons the strip floated in its own gap and split the text from its
     call to action. */
  .prod-page-hero-inner > div:first-child > .hero-spec-strip { order: 4; margin: 6px 0 24px; padding-top: 18px; }
  .prod-page-hero-inner > div:first-child > .lead { order: 5; margin-bottom: 22px; }
  .prod-page-hero-inner > div:first-child > .d-flex { order: 6; }
  .prod-page-hero .mt-28 { margin-top: 0; }
  .form-wrap { padding: 28px 22px; }
  .form-row { display: flex !important; flex-direction: column !important; margin-bottom: 0; }
  .form-group { width: 100% !important; margin-bottom: 24px !important; }

  /* footer-grid handled in its own block above; duplicate removed */
  .nav-inner { height: 80px; padding: 0 var(--gutter); }
  .nav-logo img { height: 62px; }
}
@media(max-width:768px) {
  .btn { width: 100%; justify-content: center; }

  .ind-grid-h { grid-template-columns: 1fr !important; }
  .val-grid { grid-template-columns: 1fr }
  .cert-grid { grid-template-columns: 1fr !important; gap: 16px; }

  /* Three across in one compact row instead of three stacked full-width
     rows: the values are short ("Up to 96%", "250 to 400"), so stacked they
     spent ~250px of screen on ~40 characters. The gold left rules stay, at
     2px, and the type steps down to fit three columns on a 320px screen. */
  .hero-spec-strip { gap: 0; justify-content: space-between; margin-top: 26px; padding-top: 24px; }
  .hero-spec-item { flex: 1 1 0; min-width: 0; padding-left: 10px; border-left: 2px solid var(--gold); }
  .hero-spec-item + .hero-spec-item { margin-left: 12px; }
  .hero-spec-val { font-size: 1.02rem; }
  .hero-spec-lbl { font-size: .64rem; margin-top: 3px; }
}

@media(max-width:480px) {
  .section { padding: 56px 0 }
  .section-alt { padding: 56px 0 }

  .cert-grid { grid-template-columns: 1fr !important }
}

/* Phones: the product hero and the Overview below it are both white, so the
   hero's 80px bottom padding and the section's top padding stacked into one
   large empty band under the buttons. Tightened to a normal mobile gap. Only
   the product hero and the section directly after it are touched; desktop and
   every other section keep their spacing. */
@media (max-width: 768px) {
  .prod-page-hero { padding-bottom: 28px }
  .prod-page-hero + .section { padding-top: 32px }
}

.whatsapp-float {
  position: fixed;
  bottom: 28px; right: 28px;
  width: 60px; height: 60px;
  background: #25D366;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 20px rgba(37,211,102,.4);
  z-index: 999;
  transition: transform .2s ease, box-shadow .2s ease;
}
.whatsapp-float:hover {
  transform: scale(1.1);
  box-shadow: 0 8px 28px rgba(37,211,102,.5);
}

/* ============================================================
   ACCESSIBILITY
   ============================================================ */

/* Skip link, lets keyboard and screen-reader users jump past the nav
   instead of tabbing through every menu item on every page. */
.skip-link {
  position: absolute; top: -100px; left: 16px;
  z-index: 2000;
  background: var(--navy); color: #fff;
  padding: 12px 22px; border-radius: 0 0 var(--r-sm) var(--r-sm);
  font-size: .85rem; font-weight: 600;
  transition: top var(--t-fast);
}
.skip-link:focus { top: 0 }

/* Visible focus ring. The site previously had no focus styling at all, so a
   keyboard user had no way to tell where they were on the page. */
:focus-visible {
  outline: 3px solid var(--navy);
  outline-offset: 2px;
  border-radius: 3px;
}
/* The hero is no longer a dark photograph, so it takes the default focus
   ring. Gold on white measures 2.66:1, under the 3:1 a focus indicator needs. */
.footer :focus-visible {
  outline-color: var(--gold-light);
}
.form-control:focus-visible { outline-offset: 0 }

/* Honeypot, hidden from people, visible to bots. Kept off-screen rather than
   display:none, because some bots skip fields that are explicitly hidden. */
.hp-field {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* Screen-reader-only text */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ============================================================
   UTILITY CLASSES (replacing repeated inline styles)
   ============================================================ */
.btn-block   { width: 100%; justify-content: center }
.container-narrow  { max-width: 800px }

/* The 404 and thank-you pages centre their two buttons as a row. The plain
   .cta-actions became a left column for the homepage CTA card, so this
   compound variant restores the row at every width; the compound selector
   outranks both the base rule and its media overrides. */
.cta-actions.cta-actions-center {
  flex-direction: row; align-items: center; justify-content: center;
  width: auto; flex-wrap: wrap; gap: 14px; margin-top: 30px;
}
.text-lead-center  { margin: 0 auto }   /* the 40px bottom margin that sat here never reached the page: .page-hero .lead is two classes and outranks it, so the buttons touched the text. The gap now belongs to .cta-actions-center above, which also covers 404.html, where the paragraph carries no centring class at all. */

.mt-28             { margin-top: 28px }

.prose {
  font-size: 1rem; line-height: 1.75;
  max-width: 780px; color: var(--text-sub);
}
.prose + .prose { margin-top: 10px }
.prose + .story-more > .prose:first-child { margin-top: 10px }

/* Overview: prose left, the six figures in a quiet key-value panel on the
   right, replacing the gold-tick checklist and the empty right half. */
.ovA { display: grid; grid-template-columns: 1.2fr .8fr; gap: 64px; align-items: start }
.ovA > * { min-width: 0 }
.ovA .eyebrow { justify-content: flex-start }
.ovA-img { align-self: center; }
.ovA-img img { width: 100%; height: auto; display: block; border-radius: var(--r-lg);
  box-shadow: 0 14px 36px rgba(15,42,68,.14); }
@media (max-width: 900px) { .ovA-img { max-width: 420px; margin: 4px auto 0; } }
.ovA-panel { border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--snow); padding: 6px 26px; margin-top: 44px }
.ovA-row { display: flex; justify-content: flex-start; align-items: baseline; gap: 16px;
  padding: 13px 0; border-bottom: 1px solid var(--border); font-size: .9rem }
.ovA-row:last-child { border-bottom: none }
.ovA-row b { font-weight: 600; color: var(--ink); white-space: nowrap; flex: 0 0 134px }
.ovA-row span { color: var(--text-sub); text-align: left; flex: 1 }
.ovA-row .ovA-stack { display: flex; flex-direction: column; gap: 6px }
/* Same round marker the Applications list on this page already uses, at the
   smaller size the panel text calls for. */
.ovA-row .ovA-stack > span { position: relative; padding-left: 16px }
.ovA-row .ovA-stack > span::before { content: ""; position: absolute; left: 0;
  top: .48em; width: 6px; height: 6px; border-radius: 50%; background: #0891B2 }
/* The panel is the short column next to the overview prose. Letting it
   stretch and share the leftover space between its rows keeps the two
   columns finishing level instead of the box stopping short. */
@media (min-width: 901px) {
  .ovA { align-items: stretch }
  .ovA-panel { display: flex; flex-direction: column; justify-content: space-between }
}
@media (max-width: 900px) { .ovA { grid-template-columns: 1fr; gap: 30px }
  .ovA-panel { margin-top: 0 } }

/* Full-height centred hero, used by the thank-you and 404 pages */
.page-hero-tall {
  min-height: 70vh;
  display: flex; align-items: center; justify-content: center;
  text-align: center;
}
.page-hero-tall h1 { font-size: clamp(2.2rem, 6vw, 3.5rem); margin-bottom: 16px }

/* Confirmation tick on the thank-you page */
.success-icon {
  width: 80px; height: 80px;
  background: var(--green); color: #fff;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 32px;
}

/* 404 numeral */
.error-code {
  font-family: var(--font-display);
  font-size: clamp(4rem, 14vw, 7rem);
  font-weight: 700; line-height: 1;
  color: var(--navy); opacity: .18;
  margin-bottom: 8px;
}
.val-card .btn { margin-top: 16px }

/* ============================================================
   REDUCED MOTION
   ============================================================
   This site runs infinite animations, a scaling 1920px hero background and
   three 90px-blur orbs. That is a genuine problem for users with vestibular
   disorders, and it drains battery on phones. Everything decorative stops
   here; nothing becomes unreadable.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }

  html { scroll-behavior: auto }

  /* Reveal-on-scroll elements start at opacity 0 and are shown by JavaScript.
     With motion disabled, or if main.js fails to load, they must be
     visible regardless, or the page renders blank. */
  .reveal, .reveal-item, .ind-card-h {
    opacity: 1 !important;
    transform: none !important;
  }

  /* The process strip animates via its connector fill and the numerals,
     neither of which the rule above reaches. Without these the line would
     stay unfilled and the numbers would stay shrunk. */
  .process-rail-fill { transform: scaleX(1) !important }
  .process-num, .process-title, .process-text { transform: none !important; opacity: 1 !important }

  /* Hover-lift effects */
  .feat:hover, .val-card:hover, .btn:hover {
    transform: none !important;
  }
}

/* NOTE: if JavaScript is disabled, reveal-animated content never receives its
   .visible class and the page would render blank. Each page therefore carries
   a <noscript><style> block in <head> that forces those elements visible. */

/* ============================================================
   SPEC TABLE, horizontal scroll on narrow screens
   ============================================================
   Specification tables have too many columns for a phone. Rather than let the
   whole page scroll sideways, the table scrolls inside its own container. */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: var(--r-sm);
  margin-bottom: 8px;
}
.table-scroll .spec-table { min-width: 560px }
/* The packing tables are label + value only. On a phone a sideways scroll
   there reads as a broken layout, so the flat table drops its min-width and
   the value wraps in place; the label column keeps a fixed share. */
@media (max-width: 600px) {
  .table-scroll .spec-table--flat { min-width: 0; font-size: .86rem }
  .spec-table--flat tbody th, .spec-table--flat tbody td { padding: 12px 14px; vertical-align: top }
  .spec-table--flat tbody th[scope="row"] { width: 36%; white-space: normal }
}

.table-scroll:focus-visible { outline: 3px solid var(--navy); outline-offset: 2px }

/* ============================================================
   FAQ, native disclosure, no JavaScript required
   ============================================================ */
/* Each question is its own card rather than a row in an undivided white slab.
   The old version had only a bottom hairline and 4px of horizontal padding, so
   the text sat hard against the edge of the white and the rows read as an
   unfinished table. Separate cards also make the click target obvious, which
   matters because the answer is genuinely hidden until you open it. */
.faq-list { max-width: 820px; margin: 0 auto; display: grid; gap: 12px }
.faq-item {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.faq-item:hover { border-color: var(--mist) }
/* Open card is marked by the border and a soft lift, not by a colour fill, so
   the answer keeps a plain white ground to be read against. */
.faq-item[open] {
  border-color: var(--navy);
  box-shadow: var(--sh-sm);
}
.faq-item summary {
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 19px 22px; cursor: pointer;
  font-size: .98rem; font-weight: 600; color: var(--ink);
  list-style: none; line-height: 1.5;
  transition: color var(--t-fast);
  border-radius: var(--r-md);
}
.faq-item summary::-webkit-details-marker { display: none }
/* The plus sits in its own ring so it reads as a control rather than as a
   stray character at the end of the sentence. */
.faq-item summary::after {
  content: '+'; flex-shrink: 0;
  width: 26px; height: 26px; border-radius: var(--r-full);
  border: 1px solid var(--mist);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.15rem; font-weight: 400; line-height: 1;
  color: var(--navy);
  transition: transform var(--t-med), background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.faq-item summary:hover { color: var(--navy) }
.faq-item summary:hover::after { border-color: var(--navy) }
.faq-item[open] summary { color: var(--navy) }
.faq-item[open] summary::after {
  content: '\2212';
  background: var(--navy); border-color: var(--navy); color: #fff;
}
.faq-item summary:focus-visible { outline: 2px solid var(--navy); outline-offset: -2px }
.faq-answer {
  padding: 0 22px 22px;
  font-size: .92rem; color: var(--text-sub); line-height: 1.75;
  max-width: 70ch;
}
.faq-answer p + p { margin-top: 12px }
@media (max-width: 560px) {
  .faq-item summary { padding: 16px 16px; gap: 12px }
  .faq-answer { padding: 0 16px 18px }
}

/* ── FORM VALIDATION MESSAGES ──────────────────────────────────────────────
   The browser's own bubble was the only feedback here: unstyled, one field at
   a time, gone the moment you scroll, and for a pattern mismatch it says only
   "Please match the requested format." These messages sit under the field
   instead, all of them at once, and are announced because the container is a
   live region. Native validation still runs when JavaScript does not: the
   `novalidate` attribute is added by script, never in the markup. */
.form-error {
  display: none;
  margin-top: 7px;
  font-size: .82rem;
  line-height: 1.45;
  color: var(--navy);
  font-weight: 500;
}
.form-error::before {
  content: '!';
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; margin-right: 7px;
  border-radius: var(--r-full);
  background: var(--navy); color: #fff;
  font-size: .66rem; font-weight: 700; line-height: 1;
  vertical-align: -2px;
}
.form-group.has-error .form-error { display: block }
.form-group.has-error .form-control {
  border-color: var(--navy);
  background: var(--navy-tint);
}
.form-group.has-error .form-control:focus {
  border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(15, 62, 102, .16);
}
/* The phone control is a two-part grid, so its error belongs under the pair
   rather than under either half. */
.form-group.has-error .phone-field .form-control { border-color: var(--navy) }

/* Summary above the button, so a keyboard user who submits from the bottom of
   a long form is told what happened without hunting for red fields. */
.form-summary {
  display: none;
  margin-bottom: 18px; padding: 13px 16px;
  border: 1px solid var(--navy);
  border-left: 3px solid var(--navy);
  border-radius: var(--r-sm);
  background: var(--navy-tint);
  color: var(--navy-dark);
  font-size: .86rem; line-height: 1.55;
}
.form-summary.is-shown { display: block }

@keyframes menu-drop {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: none; }
}

/* ============================================================
   CONTENT PROTECTION, at the client's explicit request
   ============================================================
   Text selection is off everywhere except form controls, which need it for
   typing and correcting. A deterrent, not a lock (view-source still shows
   everything); the client chose it knowing that, and knowing a visitor
   cannot select-copy the address either. Phone and email stay usable
   because they are tap-to-call / tap-to-mail links. */
body { -webkit-user-select: none; user-select: none; }
input, textarea, select { -webkit-user-select: text; user-select: text; }

/* ============================================================
   LAYOUT v2 — Tara Polymers
   Section system built around the sales story a processor
   actually follows: problem -> mechanism -> form -> grade ->
   application -> proof. Reuses the existing design tokens.
   ============================================================ */

/* --- shared section heading --- */
.v2-head { max-width: 780px; margin: 0 auto 52px; text-align: center }
.v2-head h2 { font-size: clamp(1.8rem, 3.3vw, 2.7rem); line-height: 1.1; letter-spacing: -.025em; margin-top: 12px }
.v2-head p { margin-top: 16px; color: var(--text-sub); font-size: clamp(1rem,1.2vw,1.1rem); line-height: 1.65 }

/* ============ HERO ============ */
.btn.v2-btn-ghost { background: transparent; color: var(--navy); border: 1.5px solid rgba(15,62,102,.32) }
.btn.v2-btn-ghost:hover { background: var(--navy-tint); border-color: var(--navy); color: var(--navy) }

/* ============ CTA BAND ============ */
.v2-cta { background: linear-gradient(140deg, var(--navy-tint) 0%, #FFFFFF 46%, var(--gold-tint) 100%);
  color: var(--ink); border: 1px solid var(--border); box-shadow: var(--sh-sm);
  border-radius: var(--r-xl); padding: clamp(36px,5vw,60px);
  display: grid; grid-template-columns: 1.4fr auto; gap: 30px; align-items: center; position: relative; overflow: hidden }
.v2-cta::after { content: ""; position: absolute; right: -90px; top: -90px; width: 340px; height: 340px;
  border-radius: 50%; background: radial-gradient(circle, rgba(201,153,5,.20) 0%, rgba(201,153,5,0) 70%) }
.v2-cta h2 { font-size: clamp(1.5rem,2.6vw,2.15rem); line-height: 1.18; letter-spacing: -.02em; color: var(--ink); max-width: 22ch }
.v2-cta p { margin-top: 12px; color: var(--text-sub); max-width: 52ch; line-height: 1.65 }
.v2-cta-actions { display: flex; gap: 14px; flex-wrap: wrap; position: relative; z-index: 1 }

/* ============ RESPONSIVE ============ */
@media (max-width: 1000px) {
  .v2-cta { grid-template-columns: 1fr }
}
@media (max-width: 620px) {
  .v2-hero-actions .btn { width: 100% }
}

/* ============================================================
   PREMIUM PASS — craft layer over LAYOUT v2
   A technical mono for every label, fine grain over the dark
   ground, tighter optical tracking, and considered hover states.
   ============================================================ */
:root { --font-mono: 'Inter', -apple-system, system-ui, sans-serif }

/* --- Technical labels ------------------------------------------------
   The single strongest signal that this is an engineering supplier and
   not a brochure: every label-grade element set in a technical mono. */
.eyebrow, .footer-col-title, .hero-spec-lbl, .ovA-row b {
  font-family: var(--font-mono);
  font-variant-ligatures: none;
}

/* --- Display type: tighter, more optical ---------------------------- */
.v2-head h2    { letter-spacing: -.028em }
.v2-cta h2 { letter-spacing: -.025em }
.v2-head p     { text-wrap: pretty }

/* --- Material: fine grain over the dark ground ----------------------
   ::before on the hero is the gradient scrim and ::after on the CTA is
   the gold bloom, so each uses the pseudo-element the other left free. */
.v2-cta::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: .035; mix-blend-mode: multiply;
}
.v2-cta > *    { position: relative; z-index: 1 }

/* --- Hairline dividers between alternating bands -------------------- */
.section + .section-alt, .section-alt + .section { position: relative }
.section + .section-alt::before, .section-alt + .section::before {
  content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: min(1320px, 92vw); height: 1px;
  background: linear-gradient(90deg, transparent, var(--mist), transparent);
}


.btn { transition: transform var(--t-fast), box-shadow var(--t-fast), background var(--t-fast), border-color var(--t-fast), color var(--t-fast) }
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 12px 28px rgba(15,62,102,.30) }
.btn.v2-btn-ghost:hover { transform: translateY(-2px) }

/* --- Selection ------------------------------------------------------- */
::selection { background: var(--gold); color: #14202E }


/* --- Honour reduced motion ------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .btn-primary:hover, .btn.v2-btn-ghost:hover { transform: none }
}

/* ============================================================
   v2 ROLLOUT — bring About / product / contact / 404 up to the
   same light section language as the homepage, by restyling the
   components they already use. No markup changes, so the
   enquiry forms, country <select> and spec tables stay intact.
   ============================================================ */

/* --- Page heroes share the homepage's light artwork ground ---------- */
.page-hero,
.prod-page-hero {
  background-color: var(--white);
  background-image: none;
  background-size: cover;
  background-position: center right;
  position: relative;
}
/* The old decorative blur discs were tuned for a flat --snow ground and
   fight the artwork now, so they come off. */
.page-hero::before,
.page-hero::after { display: none }

.page-hero h1,
.prod-page-hero h1 { letter-spacing: -.03em }
.prod-ident { font-family: var(--font-mono); letter-spacing: .04em; font-size: .85rem }

/* --- One card language across every page ---------------------------- */
.val-card,
.cert-card,
.ind-card-h {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-xs);
  transition: transform var(--t-med), box-shadow var(--t-med), border-color var(--t-med);
}
.val-card:hover,
.cert-card:hover,
.ind-card-h:hover {
  transform: translateY(-4px);
  box-shadow: var(--sh-md);
  border-color: var(--gold-light);
}
.val-title,
.ind-title-h { letter-spacing: -.015em }
.ind-tag-h { font-family: var(--font-mono); letter-spacing: .1em; font-size: .68rem }

/* --- The old CTA box becomes the light v2 band ---------------------- */
.cta-box {
  background: linear-gradient(140deg, var(--navy-tint) 0%, #FFFFFF 46%, var(--gold-tint) 100%);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-sm);
}
.cta-box h2 { color: var(--ink); letter-spacing: -.025em }

/* --- Process rail (About) picks up the v2 step treatment ------------ */
.process-num {
  border: 2px solid var(--gold);
  background: var(--white);
  box-shadow: 0 6px 22px rgba(15,62,102,.12);
}
.process-title { letter-spacing: -.015em }

/* --- Spec tables: quieter rules, mono row labels -------------------- */
.spec-table th[scope="row"] {
  font-family: var(--font-mono);
  font-weight: 500;
  letter-spacing: .02em;
}
.spec-table td, .spec-table th { border-color: var(--border-soft) }

/* --- FAQ: softer container, gold marker on open --------------------- */
.faq-item {
  border-radius: var(--r-md);
  border: 1px solid var(--border);
  background: var(--white);
  transition: border-color var(--t-med), box-shadow var(--t-med);
}
.faq-item:hover { border-color: var(--gold-light) }
.faq-item[open] { box-shadow: var(--sh-sm); border-color: var(--gold-light) }

/* --- Contact banner sits flush under the fixed nav ------------------ */
.contact-hero-img img { object-position: center 50% }

/* ============================================================
   IMAGE STRIP — decorative artwork removed; visuals to be
   rebuilt section by section. Reversible: delete this block.
   ============================================================ */
.page-hero, .prod-page-hero { background-image: none; }
.v2-cta::before { display: none; }
.prod-page-hero-img { display: none; }
.prod-page-hero-inner { grid-template-columns: 1fr; }
/* Centered product title above the split hero. */
.prod-hero-head { max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter) 30px; text-align: center; }
.prod-hero-head h1 { color: var(--ink); margin-bottom: 9px; }
.prod-hero-head .prod-ident { margin-bottom: 0; }

/* A product page that does have a hero photo opts back in with .has-hero-img:
   two-column hero on desktop, and a clean rounded photo with a soft layered
   shadow (no corner brackets) beside the copy. */
.prod-page-hero.has-hero-img .prod-page-hero-img { display: block; padding: 0; }
.prod-page-hero.has-hero-img .prod-page-hero-img::before,
.prod-page-hero.has-hero-img .prod-page-hero-img::after { display: none; }
.prod-page-hero.has-hero-img .prod-img-inner { border: none;
  box-shadow: 0 18px 44px rgba(15,42,68,.16), 0 4px 12px rgba(15,42,68,.08); }
.prod-page-hero.has-hero-img .prod-page-hero-img img { transform: scale(1.35); }
.prod-page-hero.has-hero-img .prod-page-hero-img:hover img { transform: scale(1.4); }
@media (min-width: 901px) {
  .prod-page-hero.has-hero-img .prod-page-hero-inner { grid-template-columns: 1.08fr 1fr; }
  .prod-page-hero.has-hero-img .prod-page-hero-img { order: -1; }
}
.contact-hero-img picture { display: none; }
.contact-hero-img { padding-top: 101px; height: auto; min-height: 0; }
/* Nunito on h3-level and div-based titles too */
h3, .val-title, .ind-title-h { font-family: var(--font-display); }

/* ============================================================
   KOTHARI-ADAPTED HERO — bold highlighted headline + feature
   cards that overlap the hero band. Tara's light navy/gold (no red).
   ============================================================ */
.k-hero { position: relative; }
.k-hero-band {
  background: linear-gradient(165deg, #EEF4FA 0%, #E1ECF6 100%);
  padding: clamp(128px,15vh,188px) 0 clamp(118px,14vh,148px);
  position: relative; overflow: hidden;
}
/* faint granule dots, top-right — subtle nod to Kothari's patterned band */
.k-hero-band::after {
  content: ""; position: absolute; top: 0; right: 0; width: 42%; height: 100%;
  background-image: radial-gradient(var(--navy) 1.4px, transparent 1.6px);
  background-size: 26px 26px; opacity: .05; pointer-events: none;
  -webkit-mask-image: linear-gradient(255deg, #000, transparent 70%);
  mask-image: linear-gradient(255deg, #000, transparent 70%);
}
.k-hero-band > .container { position: relative; z-index: 1; }
.k-title { font-family: var(--font-display); font-size: clamp(2.3rem,5.6vw,4.1rem);
  line-height: 1.06; letter-spacing: -.03em; font-weight: 800; margin: 16px 0 0; max-width: 18ch; color: var(--ink); }
.k-lead { margin-top: 20px; max-width: 60ch; font-size: clamp(1rem,1.3vw,1.15rem);
  line-height: 1.65; color: var(--text-sub); text-wrap: pretty; }
.k-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 30px; }

.k-features { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: 22px;
  margin-top: -96px; position: relative; z-index: 2; }
.k-feature { background: var(--white); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: 26px 22px 28px; box-shadow: var(--sh-lg);
  transition: transform var(--t-med), box-shadow var(--t-med); }
.k-feature:hover { transform: translateY(-5px); box-shadow: 0 18px 44px rgba(15,62,102,.14); }
.k-feat-ico { width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center;
  background: var(--navy-tint); margin-bottom: 16px; }
.k-feat-ico svg { width: 24px; height: 24px; fill: none; stroke: var(--navy); stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; }
.k-feature h3 { font-size: 1.08rem; font-weight: 700; letter-spacing: -.015em; }
.k-feature p { margin-top: 8px; font-size: .92rem; line-height: 1.6; color: var(--text-sub); }

@media (max-width: 1000px) { .k-features { grid-template-columns: repeat(2,minmax(0,1fr)); margin-top: -52px; } }
@media (max-width: 560px)  { .k-features { grid-template-columns: 1fr; margin-top: -42px; } .k-actions .btn { width: 100%; } }
/* ============================================================
   STICKY QUOTE TAB + MOTION LAYER
   ============================================================ */
.quote-tab {
  position: fixed; right: 0; top: 50%; transform: translateY(-50%); z-index: 60;
  writing-mode: vertical-rl; background: var(--navy); color: #fff;
  font-family: var(--font-mono); font-size: .72rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; text-decoration: none;
  padding: 18px 11px; border-radius: 10px 0 0 10px;
  box-shadow: -4px 6px 20px rgba(15,62,102,.22);
  transition: background var(--t-med), padding-right var(--t-med), color var(--t-med);
}
.quote-tab::before { content: ""; display: block; width: 7px; height: 7px; border-radius: 50%;
  background: var(--gold); margin: 0 auto 9px; }
.quote-tab:hover { background: var(--gold); color: var(--navy-dark); padding-right: 15px; }
.quote-tab:hover::before { background: var(--navy-dark); }
@media (max-width: 820px) { .quote-tab { display: none; } }

.k-feat-ico { transition: background var(--t-med), transform var(--t-med); }
.k-feature:hover .k-feat-ico { transform: translateY(-3px) rotate(-4deg); }

@media (prefers-reduced-motion: no-preference) {
  .k-title, .k-lead, .k-actions { animation: kRise .75s var(--ease) both; }
  .k-title { animation-delay: .16s }
  .k-lead { animation-delay: .30s } .k-actions { animation-delay: .44s }
  @keyframes kRise { from { transform: translateY(18px) } to { transform: none } }
  .k-title .k-mark { background: transparent; background-image: linear-gradient(var(--gold),var(--gold));
    background-repeat: no-repeat; background-size: 0% 100%; animation: kWipe .6s var(--ease) .52s forwards; }
  @keyframes kWipe { to { background-size: 100% 100% } }
  .quote-tab { animation: qIn .6s var(--ease) .9s both; }
  @keyframes qIn { from { transform: translateY(-50%) translateX(100%) } to { transform: translateY(-50%) translateX(0) } }
}
/* ============================================================
   COLOR + LIFE — curated accent palette (navy · gold · teal ·
   green — no red) across icons, grades, steps, chips + warmer bands.
   ============================================================ */
:root {
  --acc-blue:#1E6FA8; --acc-blue-t:#E5F0FA;
  --acc-teal:#0E8E9E; --acc-teal-t:#E1F4F6;
  --acc-gold2:#B07C08; --acc-gold-t2:#FBF0D6;
  --acc-green:#2E7D5B; --acc-green-t:#E6F3EC;
}
/* hero feature cards — one accent each */
.k-features .k-feature:nth-child(1) .k-feat-ico{background:var(--acc-blue-t)}  .k-features .k-feature:nth-child(1) .k-feat-ico svg{stroke:var(--acc-blue)}
.k-features .k-feature:nth-child(2) .k-feat-ico{background:var(--acc-teal-t)}  .k-features .k-feature:nth-child(2) .k-feat-ico svg{stroke:var(--acc-teal)}
.k-features .k-feature:nth-child(3) .k-feat-ico{background:var(--acc-gold-t2)} .k-features .k-feature:nth-child(3) .k-feat-ico svg{stroke:var(--acc-gold2)}
.k-features .k-feature:nth-child(4) .k-feat-ico{background:var(--acc-green-t)} .k-features .k-feature:nth-child(4) .k-feat-ico svg{stroke:var(--acc-green)}
/* warmer alternate band */
.section-alt{background:#F2F7FC}
/* subtle life: hero granule dots drift slowly */
@media (prefers-reduced-motion: no-preference){
  .k-hero-band::after{ animation: dotDrift 46s linear infinite; }
  @keyframes dotDrift{ to { background-position: 312px 0 } }
}
.app-more { text-align: center; margin: 40px auto 0; color: var(--ink); font-size: 1.08rem; font-weight: 500; }
/* ============================================================
   PHOTO HERO — full-bleed granules image + navy overlay (Kothari
   energy, Tara colours). White type; gold primary CTA.
   ============================================================ */
.k-hero--photo .k-hero-band { background: #EDF1F5; }
.k-hero--photo .k-hero-band::after { display: none; }
.k-hero-bg { position: absolute; inset: 0; z-index: 0; }
.k-hero-bg img { width: 100%; height: 100%; object-fit: cover; display: block; }
.k-hero-bg::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, rgba(255,255,255,.98) 0%, rgba(255,255,255,.95) 40%, rgba(255,255,255,.70) 56%, rgba(255,255,255,.16) 80%, rgba(255,255,255,0) 94%); }
.k-hero--photo .k-hero-band > .container { position: relative; z-index: 1; }
.k-hero--photo .k-eyebrow { color: var(--gold-light); }
.k-hero--photo .k-title { color: var(--navy); }
.k-hero--photo .k-lead { color: var(--charcoal); }
.k-hero--photo .v2-hero-call { color: var(--text-sub); }
.k-hero--photo .v2-hero-call a { color: var(--navy); border-color: var(--gold); }
.k-hero--photo .v2-btn-ghost { color: var(--navy); border-color: var(--navy); background: rgba(255,255,255,.72); }
.k-hero--photo .v2-btn-ghost:hover { background: #fff; border-color: var(--navy); color: var(--navy); }
.k-hero--photo .k-actions .btn-primary { background: var(--gold); color: var(--navy-dark); }
.k-hero--photo .k-actions .btn-primary:hover { background: var(--gold-dark); color: var(--navy-dark); }

/* ============================================================
   REFERENCE ENERGY PASS — bolder colour + a little more motion,
   the kotharipolymers.com layout language translated into Tara's
   navy/gold multi-accent palette (no red). Reversible: delete
   this whole block to fall back to the quieter tinted version.
   ============================================================ */

/* --- Solid-colour icon chips (ref uses filled chips + white glyph) --------- */
.k-feat-ico { box-shadow: 0 12px 24px -12px rgba(15,62,102,.6); }

/* hero feature chips: one saturated accent each, white glyph */
.k-features .k-feature:nth-child(1) .k-feat-ico { background: var(--acc-blue); }
.k-features .k-feature:nth-child(2) .k-feat-ico { background: var(--acc-teal); }
.k-features .k-feature:nth-child(3) .k-feat-ico { background: var(--acc-gold2); }
.k-features .k-feature:nth-child(4) .k-feat-ico { background: var(--acc-green); }
.k-features .k-feature:nth-child(1) .k-feat-ico svg,
.k-features .k-feature:nth-child(2) .k-feat-ico svg,
.k-features .k-feature:nth-child(3) .k-feat-ico svg,
.k-features .k-feature:nth-child(4) .k-feat-ico svg { stroke: #fff; }

/* --- Hero feature cards: plain text kicker instead of an icon chip -------- */
.k-features .k-feature:nth-child(1) .k-feat-kick { color: var(--acc-blue); }
.k-features .k-feature:nth-child(2) .k-feat-kick { color: var(--acc-teal); }
.k-features .k-feature:nth-child(3) .k-feat-kick { color: var(--acc-gold2); }
.k-features .k-feature:nth-child(4) .k-feat-kick { color: var(--acc-green); }

/* --- About (home) intro: image + text, links to the full story ----------- */
.home-about .ha-grid { display: grid; grid-template-columns: 1fr; }
.home-about .ha-body { max-width: 720px; margin-inline: auto; text-align: center; }
.home-about .ha-media { border-radius: var(--r-xl); overflow: hidden; box-shadow: var(--sh-md); aspect-ratio: 7/5; }
.home-about .ha-media img,
.home-about .ha-media video { width: 100%; height: 100%; object-fit: cover; display: block; }
.home-about .ha-body h2 { letter-spacing: -.025em; margin-top: 8px; }
.home-about .ha-body p { margin-top: 16px; color: var(--text-sub); line-height: 1.7; }
.home-about .ha-body .btn { margin-top: 26px; }
@media (max-width: 820px) { .home-about .ha-grid { grid-template-columns: 1fr; } .home-about .ha-media { aspect-ratio: 16/9; } }

/* --- Feature cards: white with a thick yellow border (client-specified) --- */
.k-features .k-feature { background: var(--white); border: 3px solid #EFC93E; box-shadow: 0 4px 14px rgba(15,42,68,.08), 0 18px 40px rgba(15,42,68,.14); }
.k-features .k-feature h3 { color: var(--navy-dark); }
.k-features .k-feature p  { color: var(--text-sub); }
.k-features .k-feature:nth-child(1) .k-feat-kick,
.k-features .k-feature:nth-child(2) .k-feat-kick,
.k-features .k-feature:nth-child(3) .k-feat-kick,
.k-features .k-feature:nth-child(4) .k-feat-kick { color: var(--navy-dark); opacity: .6; }
.k-features .k-feature:hover { border-color: #E0B92C; box-shadow: 0 8px 20px rgba(15,42,68,.12), 0 28px 58px rgba(15,42,68,.22); }

/* --- Sticky quote tab removed (redundant with the nav Request Quote button) */
.quote-tab { display: none; }

/* ============================================================
   HERO — centered content box variant (client trying this look).
   Reversible: delete this block to return to the left-aligned hero.
   ============================================================ */
.k-hero-bg::after { background: rgba(255,255,255,.12); }
.k-hero--photo .k-hero-band > .container {
  max-width: 860px; margin: clamp(40px,7vw,84px) auto; text-align: center;
  background: rgba(255,255,255,.97); border: 1px solid rgba(15,42,68,.08);
  border-radius: var(--r-xl); padding: clamp(36px,5vw,58px);
  box-shadow: 0 24px 64px rgba(15,42,68,.22);
}
.k-hero--photo .k-actions { justify-content: center; }
.k-hero--photo .k-lead { margin-inline: auto; }

/* ============================================================
   FLOATING PILL NAVBAR (client choice). Reversible: delete block.
   ============================================================ */
.nav {
  top: 14px; left: 50%; transform: translateX(-50%);
  width: calc(100% - 28px); max-width: 1180px;
  border: 1px solid rgba(15,42,68,.07);
  border-radius: 18px;
  box-shadow: 0 12px 34px rgba(15,42,68,.14);
}
.nav.scrolled { box-shadow: 0 16px 44px rgba(15,42,68,.22); border-bottom-color: rgba(15,42,68,.07); }
.nav-inner { height: 74px; padding: 0 clamp(20px,2.6vw,34px); }
.nav-logo img { height: 52px; }
@media (max-width: 640px) {
  .nav { top: 10px; width: calc(100% - 20px); border-radius: 14px; }
  .nav-inner { height: 70px; }
}

/* --- Scale-down pass (client felt the hero ran too big) ------------------- */
.k-hero--photo .k-hero-band { min-height: 100vh; display: flex; align-items: center; padding-top: clamp(96px,11vh,124px); }
.k-hero--photo .k-hero-band > .container { max-width: 680px; margin: clamp(20px,3vw,44px) auto; padding: clamp(24px,3vw,40px); }
.k-hero--photo .k-title { font-size: clamp(1.9rem,4vw,2.95rem); margin-inline: auto; }
.k-hero--photo .k-lead { font-size: clamp(.95rem,1.05vw,1.02rem); margin-top: 16px; }
.k-hero--photo .k-actions { margin-top: 24px; }
.k-hero--photo .k-actions .btn-lg { padding: 13px 26px; font-size: .95rem; width: auto; }
/* Phones: the white card keeps a 16px gutter so the photo frames it on every
   side (it ran edge to edge with its rounded corners clipped by the screen);
   the band uses the small-viewport height so the browser bar cannot push the
   card off centre; and the photo takes a slightly firmer wash because the
   close-up pellets read busier at this size. */
@media (max-width: 640px) {
  .k-hero--photo .k-hero-band { min-height: 100vh; min-height: 100svh; }
  .k-hero--photo .k-hero-band > .container { width: calc(100% - 32px); margin: 0 auto; padding: 28px 20px 26px; border-radius: 22px; }
  .k-hero-bg::after { background: rgba(255,255,255,.2); }
}

/* ============================================================
   COLOUR BACK — vibrant feature cards + gold headline accent.
   The white-on-white pass drained the colour the client wanted;
   this brings it back boldly. Reversible: delete this block.
   ============================================================ */
.k-features .k-feature { border: none; box-shadow: 0 16px 36px rgba(15,42,68,.22); }
.k-features .k-feature:nth-child(1) { background: linear-gradient(158deg,#2A80B9 0%,#1E6FA8 100%); }
.k-features .k-feature:nth-child(2) { background: linear-gradient(158deg,#13A1B1 0%,#0E8E9E 100%); }
.k-features .k-feature:nth-child(3) { background: linear-gradient(158deg,#DAA916 0%,#C99905 100%); }
.k-features .k-feature:nth-child(4) { background: linear-gradient(158deg,#38966C 0%,#2E7D5B 100%); }
.k-features .k-feature h3 { color: #fff; }
.k-features .k-feature p  { color: rgba(255,255,255,.92); }
.k-features .k-feature:nth-child(1) .k-feat-kick,
.k-features .k-feature:nth-child(2) .k-feat-kick,
.k-features .k-feature:nth-child(3) .k-feat-kick,
.k-features .k-feature:nth-child(4) .k-feat-kick { color: rgba(255,255,255,.82); opacity: 1; }
/* gold card reads better with dark ink */
.k-features .k-feature:nth-child(3) h3 { color: var(--navy-dark); }
.k-features .k-feature:nth-child(3) p  { color: rgba(15,42,68,.82); }
.k-features .k-feature:nth-child(3) .k-feat-kick { color: rgba(15,42,68,.66); }
.k-features .k-feature:hover { transform: translateY(-6px); box-shadow: 0 24px 50px rgba(15,42,68,.30); }

/* headline gold accent */
.k-hero--photo .k-title .hl { color: var(--gold); }

/* ============================================================
   FEATURE CARDS — Kothari style (client: "kothari jaisa"):
   white card, single-colour icon chip, dark heading, grey body.
   Authoritative over the card passes above.
   ============================================================ */
.k-features .k-feature,
.k-features .k-feature:nth-child(1),
.k-features .k-feature:nth-child(2),
.k-features .k-feature:nth-child(3),
.k-features .k-feature:nth-child(4) {
  background: #fff; border: 1px solid var(--border);
  box-shadow: 0 14px 34px rgba(15,42,68,.10);
}
.k-features .k-feature h3,
.k-features .k-feature:nth-child(3) h3 { color: var(--ink); }
.k-features .k-feature p,
.k-features .k-feature:nth-child(3) p { color: var(--text-sub); }
.k-features .k-feature:hover { transform: translateY(-6px); box-shadow: 0 22px 48px rgba(15,42,68,.16); border-color: var(--gold-light); }
.k-features .k-feat-ico { width: 54px; height: 54px; border-radius: 14px; margin-bottom: 18px;
  box-shadow: 0 12px 24px -10px rgba(15,42,68,.5); }
.k-features .k-feature:nth-child(1) .k-feat-ico,
.k-features .k-feature:nth-child(2) .k-feat-ico,
.k-features .k-feature:nth-child(3) .k-feat-ico,
.k-features .k-feature:nth-child(4) .k-feat-ico { background: var(--navy); }
.k-features .k-feat-ico svg { width: 26px; height: 26px; stroke: #fff; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* --- Feature cards: choreographed entrance ---------------------------------
   Each card zooms in as an empty tinted shell (the Kothari reference's zoomIn:
   30% scale to full over 2s ease, opaque by halfway, anchored low so it
   grows upward),
   then its own content follows in order: the gauge pops in and its ring
   fills, then the heading, then the copy. Cards take turns: left to right
   on a row, one at a time as they scroll in when stacked (main.js,
   data-reveal="each"). The entrance is keyframe animations with backwards
   fill, and transform is the same in the hidden and shown states, so no
   transition fights the keyframes and the hover lift stays snappy after.
   Hidden states exist only under no-preference: reduced-motion visitors and
   the <noscript> override always get the finished cards. The heading and
   copy wait until half the card is on screen (content-in, main.js): on
   desktop the cards only peek under the hero, so otherwise their rise
   would play below the fold. */
@property --ring { syntax: '<percentage>'; inherits: false; initial-value: 76%; }
.k-features .k-feature.reveal-item {
  transform: none; transform-origin: 50% 80%;
  transition: transform .35s cubic-bezier(.22,1,.36,1), box-shadow .35s ease;
}
.k-features .k-feature.reveal-item.visible:hover { transform: translateY(-6px); }
.k-features .k-feature.reveal-item .k-feat-ico {
  transition: --ring 1.2s cubic-bezier(.22,1,.36,1) 1.15s, transform .3s ease;
}
@media (prefers-reduced-motion: no-preference) {
  .k-features .k-feature.reveal-item:not(.visible),
  .k-features .k-feature.reveal-item:not(.visible) > .k-feat-ico,
  .k-features .k-feature.reveal-item:not(.content-in) > h3,
  .k-features .k-feature.reveal-item:not(.content-in) > p { opacity: 0; }
  .k-features .k-feature.reveal-item:not(.visible) .k-feat-ico { --ring: 0%; }
  .k-features .k-feature.reveal-item.visible { animation: kfShellIn 2s ease backwards; }
  .k-features .k-feature.reveal-item.visible > .k-feat-ico { animation: kfIconIn .7s cubic-bezier(.34,1.56,.64,1) 1s backwards; }
  .k-features .k-feature.reveal-item.content-in > h3 { animation: kfRiseIn .6s cubic-bezier(.22,1,.36,1) backwards; }
  .k-features .k-feature.reveal-item.content-in > p { animation: kfRiseIn .62s cubic-bezier(.22,1,.36,1) .12s backwards; }
}
@keyframes kfShellIn { 0% { opacity: 0; transform: scale3d(.3, .3, .3); } 50% { opacity: 1; } 100% { opacity: 1; transform: none; } }
@keyframes kfIconIn  { from { opacity: 0; transform: scale(.35) rotate(-50deg); } to { opacity: 1; transform: none; } }
@keyframes kfRiseIn  { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }

/* --- Feature cards: crisp white panels that lift off the light granules photo
   on a deep, soft, layered shadow. A hairline accent line at the top and a
   soft-tint icon chip give each card a quiet pop of colour. Light and
   understated, but clearly separated from the busy background. ------------- */
.k-features .k-feature,
.k-features .k-feature:nth-child(1),
.k-features .k-feature:nth-child(2),
.k-features .k-feature:nth-child(3),
.k-features .k-feature:nth-child(4) {
  background: #ffffff;
  border: 1px solid rgba(15,42,68,.06);
  box-shadow: 0 1px 2px rgba(15,42,68,.05), 0 10px 22px rgba(15,42,68,.08), 0 26px 50px rgba(15,42,68,.11);
  position: relative; overflow: hidden;
}
.k-features .k-feature::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 3px; }
.k-features .k-feature:nth-child(1)::before { background: var(--acc-blue); }
.k-features .k-feature:nth-child(2)::before { background: var(--acc-teal); }
.k-features .k-feature:nth-child(3)::before { background: var(--acc-gold2); }
.k-features .k-feature:nth-child(4)::before { background: var(--acc-green); }
.k-features .k-feature h3,
.k-features .k-feature:nth-child(3) h3 { color: var(--ink); }
.k-features .k-feature p,
.k-features .k-feature:nth-child(3) p { color: var(--text-sub); }
.k-features .k-feature:nth-child(1) .k-feat-ico { background: var(--acc-blue-t); }
.k-features .k-feature:nth-child(2) .k-feat-ico { background: var(--acc-teal-t); }
.k-features .k-feature:nth-child(3) .k-feat-ico { background: var(--acc-gold-t2); }
.k-features .k-feature:nth-child(4) .k-feat-ico { background: var(--acc-green-t); }
.k-features .k-feature:nth-child(1) .k-feat-ico svg { stroke: var(--acc-blue); }
.k-features .k-feature:nth-child(2) .k-feat-ico svg { stroke: var(--acc-teal); }
.k-features .k-feature:nth-child(3) .k-feat-ico svg { stroke: var(--acc-gold2); }
.k-features .k-feature:nth-child(4) .k-feat-ico svg { stroke: var(--acc-green); }
.k-features .k-feat-ico { box-shadow: none; }
.k-features .k-feature:hover {
  transform: translateY(-8px); border-color: rgba(15,42,68,.10);
  box-shadow: 0 2px 4px rgba(15,42,68,.06), 0 16px 32px rgba(15,42,68,.12), 0 40px 72px rgba(15,42,68,.17);
}

/* --- Contact page: header banner image (un-hides the IMAGE STRIP block) ---- */
.contact-hero-img {
  position: relative; padding-top: 0; min-height: 0; overflow: hidden;
  height: clamp(200px, 27vw, 340px); background: #EDF1F5;
}
.contact-hero-img picture { display: block; position: absolute; inset: 0; }
/* The floating nav covers the top of the banner, so bias the focal point
   (the blocks) downward to sit centred in the strip visible below the nav. */
.contact-hero-img img { width: 100%; height: 100%; object-fit: cover; object-position: center 58%; display: block; }

/* ============================================================
   NAV DROPDOWN — product grades under Anti-Moisture Powder / Masterbatch.
   ============================================================ */
.nav-links .has-dropdown { position: relative; }
.nav-dropdown {
  list-style: none; margin: 0; padding: 7px;
  position: absolute; top: 100%; left: -8px; margin-top: 28px; min-width: 190px;
  background: var(--white); border: 1px solid var(--border); border-radius: 14px;
  box-shadow: 0 18px 40px rgba(15,42,68,.16);
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity .18s ease, transform .18s ease, visibility .18s; z-index: 200;
}
/* invisible bridge so the pointer can cross the gap without the menu closing */
.nav-dropdown::before { content: ""; position: absolute; left: 0; right: 0; top: -28px; height: 28px; }
.has-dropdown:hover > .nav-dropdown,
.has-dropdown:focus-within > .nav-dropdown { opacity: 1; visibility: visible; transform: translateY(0); }
.nav-dropdown li { width: auto; margin: 0; }
.nav-dropdown a {
  display: block; padding: 9px 14px; border-radius: 9px;
  font-size: .9rem; font-weight: 600; letter-spacing: 0; text-transform: none;
  color: var(--charcoal); text-decoration: none; white-space: nowrap; transition: background .15s, color .15s;
}
.nav-dropdown a:hover, .nav-dropdown a:focus { background: var(--navy-tint); color: var(--navy); }
/* The base .nav-link::after is the animated underline; for dropdown parents we
   repurpose it as a small inline caret, resetting its absolute positioning so it
   sits after the text instead of below it. */
.has-dropdown > .nav-link::after {
  content: ""; position: static; inset: auto; background: none;
  display: inline-block; width: 0; height: 0; margin-left: 8px; vertical-align: middle;
  border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid currentColor;
  transform: none; opacity: .5; transition: transform .2s ease;
}
.has-dropdown:hover > .nav-link::after { transform: rotate(180deg); }

/* Mobile: the burger menu shows only the top-level links; the grade sub-lists
   are hidden to keep it short (they stay as hover dropdowns on desktop). */
@media (max-width: 1240px) {
  .nav-dropdown { display: none; }
  .has-dropdown > .nav-link::after { display: none; }
}
/* ============================================================
   HOMEPAGE PRODUCTS — open showcase (number + image + info).
   Reversible: delete this block and restore the old .v2-forms markup.
   Tone: navy numeral on a yellow highlighter swipe, and the same
   navy + amber/yellow pair carries the eyebrow, underline, sub,
   ticks and CTA.
   ============================================================ */
#products .px-head { text-align: center; max-width: 640px; margin: 0 auto 18px }

#products .px-head h2 { margin: 12px 0 8px }
#products .px-head p { color: var(--text-sub); margin: 0 }
/* These two sections stack with 80+80 padding between them, which left a
   large empty band under the shorter product column. Tighten just this join. */
#products { padding-bottom: 48px }
#applications { padding-top: 52px }

.px-rows { --acc: #0891B2; --panel: #D6F1F7 }
.px-row { display: grid; grid-template-columns: 1fr 1.08fr; gap: 48px; align-items: center; padding: 28px 0 }
.px-media { position: relative; padding: 16px }
.px-media::after { content: ""; position: absolute; z-index: 0; width: 64%; height: 70%; right: 0; bottom: 0;
  background: var(--panel); border-radius: 22px }
.px-imgwrap { position: relative; z-index: 1; border-radius: 18px; overflow: hidden; box-shadow: 0 26px 54px rgba(15,42,68,.20) }
.px-imgwrap img { width: 100%; display: block; aspect-ratio: 3/2; object-fit: cover;
  transition: transform .7s cubic-bezier(.2,.7,.2,1) }
.px-imgwrap:hover img { transform: scale(1.06) }

.px-num { position: relative; isolation: isolate; display: inline-block; font-family: var(--font-head, "Nunito", sans-serif);
  font-weight: 900; font-size: 3rem; line-height: 1; letter-spacing: -1.5px; color: var(--navy);
  padding: 0 10px; margin: 0 0 18px 2px }
.px-num::before { content: ""; position: absolute; left: 0; right: 0; bottom: 8px; height: 20px; z-index: -1;
  background: rgba(250,204,21,.82); transform: rotate(-2deg); border-radius: 4px }

.px-body h3 { font-size: 2.05rem; line-height: 1.1; margin: 0; letter-spacing: -.025em }
.px-uline { display: block; width: 54px; height: 4px; border-radius: 3px; margin: 14px 0;
  background: var(--acc) }
.px-sub { color: var(--acc); font-weight: 700; font-size: .95rem; margin: 0 0 14px;
  display: flex; flex-wrap: wrap; align-items: center; row-gap: 6px }
.px-sub span + span { margin-left: 11px; padding-left: 11px;
  border-left: 1px solid rgba(8,145,178,.34) }
.px-desc { color: var(--text-sub); line-height: 1.7; margin: 0 0 18px; font-size: 1rem }
.px-list { list-style: none; padding: 0; margin: 0 0 24px }
.px-list li { position: relative; padding-left: 28px; margin-bottom: 11px; color: var(--ink); font-size: .94rem; line-height: 1.5 }
.px-list li::before { content: ""; position: absolute; left: 2px; top: 5px; width: 14px; height: 8px;
  border-left: 2.5px solid var(--acc); border-bottom: 2.5px solid var(--acc); transform: rotate(-45deg) }
.px-foot { display: flex; align-items: center; gap: 22px; flex-wrap: wrap }
.px-best { color: var(--text-sub); font-size: .88rem }
.px-best b { color: var(--navy) }
.px-cta { display: inline-flex; align-items: center; gap: 12px; background: var(--navy); color: #fff;
  font-weight: 700; font-size: .9rem; padding: 13px 24px; border-radius: 12px; text-decoration: none;
  box-shadow: 0 10px 24px rgba(15,42,68,.24); transition: background .2s ease, box-shadow .2s ease }
.px-cta::after { content: ""; width: 8px; height: 8px; border-top: 2px solid #fff; border-right: 2px solid #fff;
  transform: rotate(45deg); transition: transform .2s ease }
.px-cta:hover { background: var(--navy-dark, #0F2A44); box-shadow: 0 14px 30px rgba(15,42,68,.30) }
.px-cta:hover::after { transform: translateX(3px) rotate(45deg) }

.px-row.flip .px-media { order: 2 }

/* Motion rides the site reveal observer (.reveal-item gains .visible).
   Defaults stay fully visible, so nothing hides when JS is off. */
@keyframes pxImgIn  { from { transform: scale(.94) } to { transform: none } }
@keyframes pxNumIn  { from { opacity: 0; transform: translateY(-10px) } to { opacity: 1; transform: none } }
@keyframes pxBodyInR { from { opacity: 0; transform: translateX(28px) } to { opacity: 1; transform: none } }
@keyframes pxBodyInL { from { opacity: 0; transform: translateX(-28px) } to { opacity: 1; transform: none } }
.px-row.visible .px-imgwrap { animation: pxImgIn .85s cubic-bezier(.2,.7,.2,1) both }
.px-row.visible .px-num { animation: pxNumIn .6s ease .18s both }
.px-row.visible .px-body { animation: pxBodyInR .75s cubic-bezier(.2,.7,.2,1) .1s both }
.px-row.flip.visible .px-body { animation-name: pxBodyInL }

@media (max-width: 900px) {
  .px-row, .px-row.flip { grid-template-columns: 1fr; gap: 10px; padding: 30px 0 }
  .px-row.flip .px-media { order: 0 }
  .px-media { padding: 14px }
  .px-media::after { width: 60%; height: 66% }
  .px-num { font-size: 2.5rem }
  .px-body h3 { font-size: 1.6rem }
  .px-row.visible .px-body, .px-row.flip.visible .px-body { animation-name: pxNumIn }
}
@media (prefers-reduced-motion: reduce) {
  .px-row.visible .px-imgwrap, .px-row.visible .px-num, .px-row.visible .px-body { animation: none }
  .px-imgwrap img { transition: none }
}
/* THE PROBLEM section: light, with drifting bubbles and four soft defect cards.
   Reversible: delete this block and restore the old .v2-defects markup. */
.fp { position: relative; overflow: hidden; padding: 80px 0;
  background: linear-gradient(180deg, #FFFFFF 0%, #F4FAFD 100%) }

/* Bubbles drift up in the background. Pure CSS, no image, and on theme:
   a bubble is itself one of the defects. */
.fp-bub { position: absolute; inset: 0; z-index: 0; pointer-events: none }
.fp-bub i { position: absolute; bottom: -90px; border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, rgba(255,255,255,.95), rgba(8,145,178,.30) 55%, rgba(8,145,178,.12));
  border: 1px solid rgba(8,145,178,.34); animation: fpRise linear infinite }
/* Negative delays start each bubble part-way through its rise, so the section
   is already full of bubbles at different heights the moment it is scrolled
   to. A positive delay would leave the section empty for that many seconds.
   The phases below are spread across the cycle: 18, 25, 39, 54, 69, 73, 86 %. */
.fp-bub i:nth-child(1) { width: 70px; height: 70px; left: 6%;  animation-duration: 28s; animation-delay: -5s }
.fp-bub i:nth-child(2) { width: 34px; height: 34px; left: 18%; animation-duration: 22s; animation-delay: -15s }
.fp-bub i:nth-child(3) { width: 96px; height: 96px; left: 31%; animation-duration: 33s; animation-delay: -8s }
.fp-bub i:nth-child(4) { width: 44px; height: 44px; left: 48%; animation-duration: 25s; animation-delay: -18s }
.fp-bub i:nth-child(5) { width: 64px; height: 64px; left: 63%; animation-duration: 30s; animation-delay: -12s }
.fp-bub i:nth-child(6) { width: 28px; height: 28px; left: 77%; animation-duration: 20s; animation-delay: -11s }
.fp-bub i:nth-child(7) { width: 84px; height: 84px; left: 88%; animation-duration: 36s; animation-delay: -31s }
@keyframes fpRise {
  0%   { transform: translateY(0) translateX(0) scale(.8); opacity: 0 }
  12%  { opacity: 1 }
  88%  { opacity: 1 }
  100% { transform: translateY(-115vh) translateX(34px) scale(1.1); opacity: 0 }
}

.fp-in { position: relative; z-index: 2; max-width: 1180px; margin: 0 auto; padding: 0 26px }
.fp-head { text-align: center; max-width: 760px; margin: 0 auto 56px }
.fp-head .eyebrow { margin-bottom: 18px }
.fp h2 { font-size: 2.5rem; line-height: 1.15; letter-spacing: -.025em; margin: 16px 0 14px; color: var(--ink) }
.fp h2 mark { background: none; color: var(--gold); padding: 0 }
.fp-lead { color: var(--text-sub); margin: 0; line-height: 1.75; font-size: 1.02rem }

.fp-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px }
.fp-c { position: relative; border-radius: 18px; padding: 26px 22px 24px; background: var(--bg);
  border: 1px solid var(--bd2); box-shadow: 0 8px 20px rgba(15,42,68,.06);
  transition: transform .3s cubic-bezier(.2,.7,.2,1), box-shadow .3s ease }
.fp-c:hover { transform: translateY(-5px); box-shadow: 0 16px 32px rgba(15,42,68,.11) }
/* One colour family across all four cards (client call: keep the icons,
   drop the multi-colour). Same aqua/cyan as the products section and the
   bubbles, so the whole homepage reads as one calm system. */
.fp-c { --bg: #E7F5FA; --bd2: #CBE7F0; --ink2: #0891B2 }
.fp-n { position: absolute; top: 14px; right: 18px; font-weight: 900; font-size: 2.5rem; line-height: 1;
  color: var(--ink2); opacity: .16; letter-spacing: -.04em }
.fp-ico { width: 64px; height: 64px; margin-bottom: 16px; display: block }
.fp-ico svg { width: 100%; height: 100%; display: block }
.fp-c h3 { font-size: 1.16rem; font-weight: 800; letter-spacing: -.02em; margin: 0 0 9px; color: var(--navy) }
.fp-c p { margin: 0; color: #3d5266; font-size: .89rem; line-height: 1.6 }

.fp-foot { margin-top: 52px; text-align: center }
.fp-foot strong { color: var(--ink); font-size: 1.24rem; font-weight: 800 }
.fp-foot strong b { color: inherit }
/* Phones: the closing line runs on one line, not two (client). It measures
   18.97em in Inter 800, so the size follows the column (viewport minus the
   52px of side padding) with ~4% to spare for font rendering, capped at the
   desktop size. No nowrap, so a wider fallback font wraps instead of
   overflowing the screen. */
@media (max-width: 560px) {
  .fp-foot strong { font-size: min(1.24rem, calc((100vw - 52px) / 19.8)) }
}
.fp-cta { display: inline-flex; align-items: center; gap: 11px; margin-top: 20px; background: var(--navy);
  color: #fff; font-weight: 700; font-size: .92rem; padding: 14px 26px; border-radius: 14px; text-decoration: none;
  box-shadow: 0 10px 24px rgba(15,42,68,.24); transition: background .2s ease, transform .2s ease }
.fp-cta::after { content: ""; width: 7px; height: 7px; border-top: 2px solid #fff; border-right: 2px solid #fff;
  transform: rotate(45deg); transition: transform .2s ease }
.fp-cta:hover { background: var(--navy-dark, #0F2A44); transform: translateY(-2px) }
.fp-cta:hover::after { transform: translateX(3px) rotate(45deg) }

@media (max-width: 1000px) { .fp h2 { font-size: 2rem } .fp-grid { grid-template-columns: repeat(2, 1fr) } }
@media (max-width: 600px) { .fp { padding: 56px 0 } .fp h2 { font-size: 1.68rem } .fp-grid { grid-template-columns: 1fr } }
@media (prefers-reduced-motion: reduce) { .fp-bub i { animation: none; opacity: .5 } .fp-c { transform: none } }

/* ============================================================
   HOW IT WORKS v4 (.hw): a clean single-screw line schematic
   (hopper, heated barrel, die, clean output) with the three
   steps aligned under the spot on the line where they happen.
   Moisture drops fall from the hopper and are gone before the
   die. Replaces .v2-how/.v2-step on the homepage (old CSS left
   in place, harmless and unused). Everything is visible by
   default; .visible only adds motion.
   ============================================================ */.hw { position: relative; padding: 80px 0; background: linear-gradient(180deg, #F4FAFD, #FFFFFF 36%) }
.hw-in { max-width: 1180px; margin: 0 auto; padding: 0 26px }
/* Headlines carry no coloured emphasis: the yellow marker swipe read as odd for
   a B2B site, and gold text drew the eye away from the sentence. These headings
   stay the same navy as every other heading; <mark>/<b> are kept only so the
   emphasis can be restyled later without touching the HTML. nowrap keeps the
   phrase from splitting awkwardly across two lines. */
.hw h2 mark, .wy h2 mark, .fp h2 mark { white-space: nowrap }
.hw h2 mark, .wy h2 mark { background: none; color: var(--gold); padding: 0 }

.hw-flow { position: relative; max-width: 1000px; margin: 6px auto 0 }
.hw-diagram { max-width: 880px; margin: 0 auto }
.hw-diagram svg { display: block; width: 100%; height: auto }
/* Moisture is carried along the barrel by the resin and is bound before it
   reaches the die, so it fades out around two thirds of the way down. It does
   not fall as free droplets: water is held inside the material. */
.hw-drops circle { opacity: 0 }
.hw-diagram.visible .hw-drops circle { animation: hwCarry 3.4s linear infinite }
.hw-diagram.visible .hw-drops circle:nth-child(2) { animation-delay: 1.1s }
.hw-diagram.visible .hw-drops circle:nth-child(3) { animation-delay: 2.2s }
@keyframes hwCarry { 0% { transform: translateX(0); opacity: 0 } 14% { opacity: .95 } 52% { opacity: .95 } 100% { transform: translateX(300px); opacity: 0 } }
/* the clean part comes out of the die */
.hw-out { transform-box: fill-box; transform-origin: left center }
@keyframes hwOut { from { transform: scaleX(0) } to { transform: scaleX(1) } }
.hw-diagram.visible .hw-out { animation: hwOut 1.1s cubic-bezier(.2,.7,.2,1) .5s both }

.hw-steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 34px; margin-top: 18px }
.hw-step { text-align: center; padding: 0 10px }
.hw-k { display: inline-block; color: #0891B2; font-weight: 800; font-size: .72rem; letter-spacing: .18em;
  text-transform: uppercase; margin-bottom: 10px }
.hw-step h3 { color: var(--navy); font-size: 1.16rem; font-weight: 800; letter-spacing: -.02em; margin: 0 0 10px }
.hw-step p { color: var(--text-sub); font-size: .95rem; line-height: 1.75; margin: 0 auto; max-width: 36ch }

@media (max-width: 700px) {
  .hw { padding: 56px 0 }
  .hw-diagram { display: none }
  .hw-steps { grid-template-columns: 1fr; gap: 34px; margin-top: 0 }
}
/* ============================================================
   WHY TARA (.wy): split editorial. The claim locked on the left
   with the highlighter, the four proofs as a checked list on the
   right, faint droplet outlines in the corners. Replaces
   .v2-proof on the homepage. Visible by default.
   ============================================================ */
.wy { position: relative; overflow: hidden; padding: 80px 0;
  background: linear-gradient(180deg, #FFFFFF, #F0F7FA 22%, #F0F7FA 78%, #FFFFFF) }
.wy-blob { position: absolute; border: 2px solid rgba(8,145,178,.12); border-radius: 0 50% 50% 50%;
  transform: rotate(45deg); pointer-events: none }
.wy-b1 { width: 300px; height: 300px; top: -90px; right: -80px }
.wy-b2 { width: 150px; height: 150px; bottom: -50px; left: -34px }
/* Header across the top, then the four proofs as a 2x2. The earlier
   side-by-side split left the whole left column empty next to a very tall
   single-file list; this fills the width evenly and halves the height. */
.wy-in { position: relative; max-width: 1120px; margin: 0 auto; padding: 0 26px }
.wy-left { max-width: 720px; margin: 0 auto 56px; text-align: center }
.wy-left h2 { color: var(--ink); font-size: 2.3rem; line-height: 1.18; letter-spacing: -.025em; margin: 14px 0 0 }
.wy-rule { display: block; width: 62px; height: 4px; border-radius: 3px; background: var(--gold); margin: 26px auto 0 }

.wy-list { display: grid; grid-template-columns: repeat(2, 1fr); gap: 44px 68px }
.wy-item { display: grid; grid-template-columns: 46px 1fr; gap: 20px; align-items: start }
.wy-tick { position: relative; width: 46px; height: 46px; border-radius: 14px;
  background: #E7F5FA; border: 1px solid #CBE7F0; transition: background .25s ease, border-color .25s ease }
.wy-tick::before { content: ""; position: absolute; left: 13px; top: 15px; width: 17px; height: 9px;
  border-left: 3px solid #0891B2; border-bottom: 3px solid #0891B2; transform: rotate(-45deg);
  transition: border-color .25s ease }
.wy-item:hover .wy-tick { background: #0891B2; border-color: #0891B2 }
.wy-item:hover .wy-tick::before { border-color: #fff }
.wy-item h3 { color: var(--navy); font-size: 1.12rem; font-weight: 800; letter-spacing: -.02em; margin: 2px 0 8px }
.wy-item p { color: var(--text-sub); font-size: .93rem; line-height: 1.7; margin: 0 }

@media (max-width: 780px) {
  .wy { padding: 56px 0 }
  .wy-left { margin-bottom: 40px }
  .wy-left h2 { font-size: 1.85rem }
  .wy-rule { margin-top: 20px }
  .wy-list { grid-template-columns: 1fr; gap: 34px }
}
@media (prefers-reduced-motion: reduce) { .hw-diagram.visible .hw-drops circle, .hw-diagram.visible .hw-out { animation: none } .hw-drops circle { opacity: .95 } }

/* ============================================================
   HOMEPAGE ABOUT INTRO (.home-about): two columns, copy left and
   the recycled-plastic photo right. The centred text-only version
   repeated the hero's moisture claim, the products section and the
   why-us batch-check line, so the copy now keeps only what is
   unique to it: Tara mills, coats and packs the absorber itself.
   These rules come after the base .home-about block AND after its
   820px media query, so the stack breakpoint is restated below.
   ============================================================ */
/* stretch, not center: the story copy is taller than a 7/5 crop, so a centred
   image would float with dead space above and below it. */
.home-about .ha-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 570px); gap: 62px; align-items: stretch }
.home-about .ha-body { max-width: none; margin-inline: 0; text-align: left }
.home-about .ha-body h2 { font-size: 2.15rem; line-height: 1.2 }
.home-about .ha-body p { margin-top: 15px }
.home-about .ha-media { aspect-ratio: 1.45; min-height: 0; align-self: center }

@media (max-width: 860px) {
  .home-about .ha-grid { grid-template-columns: 1fr; gap: 34px }
  .home-about .ha-body h2 { font-size: 1.8rem }
  .home-about .ha-media { aspect-ratio: 16/9; min-height: 0 }
}
/* Tablets (768-1180px): the fixed 570px video column left the copy 200 to
   300px wide, so the headline broke one word a line and the video floated
   beside a copy block twice its height. Tablets stack instead: the copy
   centred at a readable measure, then the video at its own landscape ratio
   (its baked-in words must not be cropped), then the button. The button
   after the video is a tablet-only copy (.ha-cta-tablet in index.html) and
   the in-copy one is hidden there, so only one link is ever exposed; keep
   the two in sync. Bounded on both sides so phones and desktop keep their
   layouts exactly (client: tablet only). */
.home-about .ha-cta-tablet { display: none }
@media (min-width: 768px) and (max-width: 1180px) {
  .home-about .ha-grid { grid-template-columns: 1fr; gap: 40px; justify-items: center }
  .home-about .ha-body { max-width: 660px; margin-inline: auto; text-align: center }
  .home-about .ha-body h2 { font-size: 2rem }
  .home-about .ha-body .btn { display: none }
  .home-about .ha-cta-tablet { display: inline-flex; width: max-content }
  .home-about .ha-media { width: 100%; max-width: 760px; aspect-ratio: 16/9; align-self: auto }
}
/* Phones get the same order the client asked for on tablet: copy, then the
   video, then the button. Only the link swaps; the tablet block's centring
   is deliberately not inherited, so phone copy stays left aligned, and the
   link after the video keeps the full width the in-copy one had. */
@media (max-width: 767px) {
  .home-about .ha-body .btn { display: none }
  .home-about .ha-cta-tablet { display: inline-flex; width: 100% }
}
/* ============================================================
   HOMEPAGE APPLICATIONS (.ap-list): a compact text band, not a
   photo gallery. Four of the six photo cards that used to sit
   here (carry bags, woven sacks, pipes, houseware) also appear on
   moisture-powder.html, so a visitor met the same pictures twice.
   The photos now belong to the product pages, where they answer
   "where does THIS product run"; the homepage answers the lighter
   "does this apply to me at all". Also drops six images from the
   landing page. The old .app-grid / .app-card rules are now unused
   by any page but are left in place in case this is reverted.
   ============================================================ */
.ap-list { list-style: none; max-width: 900px; margin: 0 auto; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px 34px }
.ap-list li { position: relative; padding-left: 25px; color: var(--ink);
  font-size: .98rem; font-weight: 600; line-height: 1.5 }
.ap-list li::before { content: ""; position: absolute; left: 3px; top: .46em;
  width: 9px; height: 9px; border-radius: 50%; background: #0891B2 }
/* "And many more" closes the list rather than adding to it: navy and bolder
   than the entries, but it keeps the same filled marker as every other item.
   It also fills the twelfth cell, so the 3-column grid ends square. */
.ap-list li.ap-more { color: var(--navy); font-weight: 800 }
.ap-note { max-width: 900px; margin: 36px auto 0; text-align: center;
  color: var(--text-sub); font-size: .95rem }
/* The note's action words link to the enquiry form, styled like the same
   invitation on the product pages (.app-more a). */
.ap-note a { color: var(--acc-gold2, #8a6205); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 760px) { .ap-list { grid-template-columns: repeat(2, 1fr); gap: 13px 22px } }
@media (max-width: 430px) { .ap-list { grid-template-columns: 1fr } }
/* ============================================================
   ABOUT PAGE BANNER: the h1 alone left a tall empty white slab.
   A stat strip was tried here and dropped, the numbers (2 product
   lines, 4 grades) were too small to carry a headline and read as
   filler. Instead the banner keeps just the heading and a one-line
   positioning lead, and earns its presence from a soft gradient
   ground matching the other light sections, on a shorter band.
   On phones it stays hidden, as the base 768px rule has it: the client asked
   for that behaviour to be kept (2026-09-09).
   ============================================================ */
.page-hero { background: linear-gradient(180deg, #FFFFFF 0%, #F4FAFD 100%);
  padding-top: 156px; padding-bottom: 64px }
.page-hero .lead { margin-top: 0; font-size: 1.04rem; line-height: 1.7 }

/* ============================================================
   ABOUT: STORY (.story-body) and HOW WE WORK (.wk-*), 2026-09-09.
   The story is cut to three short paragraphs in one readable
   column. The old version ran to ~400 words across an intro, a
   "Read more" expansion that flowed into newspaper columns, and a
   separate mobile variant, and it repeated things the page already
   says in its manufacturing and quality sections. The values block
   drops the emoji (against the client's no-odd-symbols rule, and
   rendered differently on every device) for line SVG icons, and
   goes from six cards to the four that are actually ways of
   working; raw material and packing formats live in the
   manufacturing strip. Old .val-* and .story-* rules stay in place.
   ============================================================ */
.story-body { max-width: 780px; margin: 0 auto }
.story-body p { color: var(--text-sub); line-height: 1.8; margin: 0 0 18px; font-size: 1rem }
.story-body p:last-child { margin-bottom: 0 }
.story-body .story-lead { color: var(--ink); line-height: 1.8 }

/* The story runs long on a phone, so everything after the opening paragraph
   folds behind a Read more button. Desktop shows all of it and never draws
   the button, so the JS must not leave the fold clamped shut there. */
.story-more { overflow: hidden }
.story-toggle { display: none }

@media (max-width: 900px) {
  .story-more { transition: max-height .38s ease }
  .story-toggle { display: inline-flex; align-items: center; margin-top: 14px; padding: 0;
    background: none; border: 0; cursor: pointer; font-family: inherit; font-size: .95rem;
    font-weight: 700; color: var(--navy, #143A5C); text-decoration: underline;
    text-decoration-color: var(--gold, #C99905); text-underline-offset: 5px }
}

.wk-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 22px }
.wk-card { background: #FFFFFF; border: 1px solid var(--border); border-radius: var(--r-lg); padding: 28px 24px 26px;
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease }
.wk-card:hover { transform: translateY(-4px); box-shadow: 0 14px 30px rgba(15,42,68,.08); border-color: #CBE7F0 }
.wk-ico { width: 50px; height: 50px; border-radius: 14px; background: #E7F5FA; color: #0891B2;
  display: grid; place-items: center; margin-bottom: 18px }
.wk-ico svg { width: 26px; height: 26px }
.wk-card h3 { font-size: 1.05rem; font-weight: 800; letter-spacing: -.015em; color: var(--ink); margin: 0 0 8px }
.wk-card p { font-size: .92rem; line-height: 1.7; color: var(--text-sub); margin: 0 }

@media (max-width: 1000px) { .wk-grid { grid-template-columns: repeat(2, 1fr) } }
@media (max-width: 560px) { .wk-grid { grid-template-columns: 1fr; gap: 16px } }
/* ============================================================
   CONTACT PAGE v2 (2026-09-10). Client chose a full-page stack:
   hero band, the enquiry form centred, then contact details.
   Details are a two-column grid (client's follow-up): LEFT the
   address card with the map beneath it, RIGHT the phone and email
   cards stacked. align-items:stretch makes both columns the same
   height; the map flexes to fill the left column and the phone and
   email cards flex to fill the right, so the two sides stay level.
   Old .contact-grid / .contact-info-wrap / .contact-method(s) CSS
   is now unused by any page but left in place.
   ============================================================ */
.contact-v2 .form-wrap { max-width: 820px; margin: 0 auto; }
.contact-v2 .form-wrap .eyebrow { display: block; width: fit-content; margin-left: auto; margin-right: auto; }
.cd-head { text-align: center; max-width: 640px; margin: 0 auto 32px; }
.cd-head .eyebrow { display: inline-block; }
.cd-head h2 { font-size: 1.9rem; line-height: 1.2; letter-spacing: -.02em; color: var(--ink); margin: 8px 0 12px; }
.cd-lead { font-size: 1rem; line-height: 1.7; color: var(--text-sub); margin: 0; }

.cd-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; align-items: stretch; margin-top: 44px; }

.cd-col { text-align: center; padding: 28px 22px; background: #fff; border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: 0 1px 2px rgba(15,62,102,.04), 0 8px 22px rgba(15,62,102,.05);
  display: flex; flex-direction: column; align-items: center; }
.cd-chip { width: 52px; height: 52px; border-radius: 15px; background: #E7F5FA; color: #0891B2;
  display: grid; place-items: center; margin-bottom: 16px; }
.cd-chip svg { width: 24px; height: 24px; }
.cd-label { font-size: .74rem; font-weight: 700; letter-spacing: 1.4px; text-transform: uppercase; color: var(--text-sub); margin-bottom: 8px; }
.cd-value { font-size: 1rem; font-weight: 500; line-height: 1.6; color: var(--ink); overflow-wrap: anywhere; }
a.cd-link { color: var(--navy); font-weight: 600; text-decoration: underline; text-decoration-color: var(--gold);
  text-underline-offset: 4px; transition: color .15s ease, text-decoration-color .15s ease; }
a.cd-link:hover { color: #0891B2; text-decoration-color: #0891B2; }

@media (max-width: 820px) {
  .cd-head h2 { font-size: 1.7rem; }
  .cd-cols { margin-top: 36px; }
  .cd-cols { grid-template-columns: 1fr; gap: 14px; }
}
/* Contact form: tightened spacing (2026-09-10, client "spacing thoda kam / appropriate").
   Scoped to .contact-v2 so only this page's form changes; fields stay comfortable,
   the card just gets shorter. */
.contact-v2 .form-wrap { padding: 28px 30px 26px; }
.contact-v2 .form-wrap .eyebrow { margin-bottom: 18px; }

/* The enquiry eyebrow, and only this one, wears the older rule: a short gold
   dash either side of the words instead of the corner brackets every other
   eyebrow on the site uses (client, 2026-09-17). Flex rather than inline-flex
   so the auto margins still centre it over the form. */
#enquiry > .eyebrow {
  display: flex; align-items: center; gap: 10px;
  width: fit-content; margin-left: auto; margin-right: auto;
  padding: 0;
}
#enquiry > .eyebrow::before,
#enquiry > .eyebrow::after {
  position: static; display: block; border: 0; border-radius: 2px;
  width: 24px; height: 1.5px;
  background: linear-gradient(90deg, var(--gold), var(--gold-light));
}
.contact-v2 .form-row { gap: 16px; margin-bottom: 14px; }
.contact-v2 .form-group { margin-bottom: 14px; }
.contact-v2 .form-label { margin-bottom: 5px; }
.contact-v2 .form-control { padding: 11px 16px; }
.contact-v2 textarea.form-control { min-height: 82px; }
.contact-v2 .form-wrap .btn-block { margin-top: 4px; }
/* ============================================================
   ABOUT PAGE BANNER (2026-09-10): a cluster of bold overlapping
   circles bleeding off the right edge, brand aqua + navy + gold,
   blended by translucency and mix-blend multiply (client reference:
   large soft overlapping shapes; the faint dotted version read as
   boring). Heading and lead are centred like every other section. Scoped to
   .page-hero--geo; the .ph-geo <i>s are the circles and .container
   is lifted above them. The banner also shows on phones; under 768px the
   discs are dropped and the gradient carries it, tablets keep them in the corners.
   ============================================================ */
.page-hero--geo { position: relative; overflow: hidden;
  background: linear-gradient(120deg, #FFFFFF 0%, #ECF7FA 58%, #E1F0F5 100%); }
.page-hero--geo > .container { position: relative; z-index: 2; }
.page-hero--geo h1, .page-hero--geo .lead { max-width: 560px; margin-left: auto; margin-right: auto; }

.page-hero--geo .ph-geo { position: absolute; inset: 0; z-index: 1; overflow: hidden;
  pointer-events: none; mix-blend-mode: multiply; }
.page-hero--geo .ph-geo i { position: absolute; display: block; border-radius: 50%; }
.page-hero--geo .ph-geo i:nth-child(1) { width: 380px; height: 380px; top: -84px; right: -104px;
  background: radial-gradient(circle at 34% 34%, rgba(8,145,178,.32), rgba(8,145,178,.14)); }
.page-hero--geo .ph-geo i:nth-child(2) { width: 300px; height: 300px; bottom: -128px; right: 20px;
  background: radial-gradient(circle at 40% 38%, rgba(20,58,92,.22), rgba(20,58,92,.09)); }
.page-hero--geo .ph-geo i:nth-child(3) { width: 172px; height: 172px; top: 40px; right: 150px;
  background: radial-gradient(circle at 40% 40%, rgba(201,153,5,.30), rgba(201,153,5,.12)); }

@media (max-width: 860px) {
  .page-hero--geo .ph-geo i:nth-child(1) { width: 260px; height: 260px; top: -96px; right: -96px; }
  .page-hero--geo .ph-geo i:nth-child(2) { width: 200px; height: 200px; bottom: -128px; right: -44px; }
  .page-hero--geo .ph-geo i:nth-child(3) { width: 120px; height: 120px; top: 18px; right: 24px; }
}
/* Phones: the heading and lead run the full width and the floating nav hides
   the top 82px, so any disc lands behind the text; the soft washes tried here
   read as smudges (client: "ajeeb lag rha h mobile pe"). Phones get the faint
   ripple rings the client chose to keep in Our Story instead: thin line art
   sweeping in from the top-right corner, masked to fade before the centre, so
   it reads as deliberate. Tablets (769-860px) keep the shrunk disc set above. */
@media (max-width: 768px) {
  .page-hero--geo .ph-geo { display: block; }
  .page-hero--geo .ph-geo i { display: none; }
  .page-hero--geo .ph-geo::before { content: ""; position: absolute; top: -180px; right: -260px;
    width: 480px; height: 480px; pointer-events: none;
    background: repeating-radial-gradient(circle at center, rgba(8,145,178,.2) 0 1.5px, transparent 1.5px 34px);
    -webkit-mask: radial-gradient(circle at center, #000 28%, transparent 70%);
            mask: radial-gradient(circle at center, #000 28%, transparent 70%); }
}
/* Story links (e.g. the parent company Tara Minerals) — the global reset makes
   inline links invisible, so give them a clear navy underlined treatment. */
.story-body a { color: var(--navy); font-weight: 600; text-decoration: underline; text-decoration-color: var(--border); text-underline-offset: 3px; transition: color .15s ease, text-decoration-color .15s ease; }
.story-body a:hover { text-decoration-color: #0891B2; }
.story-body a:hover { color: #0891B2; }
/* About: Mission & Vision (2026-09-10, client referenced a competitor's M/V
   block). Light theme (the competitor's was dark, which the client rejected
   before): two white cards with aqua icon chips on a soft aqua band, so it
   reads as its own section between the white story above and the tinted
   How We Work below. */
.mv-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }
.mv-card { background: #fff; border: 1px solid #CBE7F0; border-radius: var(--r-lg); padding: 34px 32px;
  box-shadow: 0 1px 2px rgba(15,62,102,.04), 0 10px 26px rgba(15,62,102,.06); }
.mv-ico { width: 54px; height: 54px; border-radius: 15px; background: #E7F5FA; color: #0891B2;
  display: grid; place-items: center; margin-bottom: 18px; }
.mv-ico svg { width: 27px; height: 27px; }
.mv-card h3 { font-size: 1.24rem; font-weight: 800; letter-spacing: -.02em; color: var(--ink); margin: 0 0 12px; }
.mv-card p { font-size: .96rem; line-height: 1.75; color: var(--text-sub); margin: 0; }
@media (max-width: 760px) { .mv-grid { grid-template-columns: 1fr; gap: 18px; } }


/* Homepage feature strip, reinstated 2026-09-12 as three overlapping cards
   under the hero (client reference: Kothari). Kept to ONE colour family per
   the brand rules: navy icon chips and a single gold top accent, overriding
   the older four-colour layer above. */
.k-features { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1000px) { .k-features { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: -76px; } }
@media (max-width: 760px)  { .k-features { grid-template-columns: 1fr; margin-top: -60px; } }

/* Problem cards now lead with a real macro photo of each defect, cropped from
   the client's moisture-problem image, replacing the old line icons. */
.fp-c { padding: 22px 22px 24px; overflow: hidden; background: #fff; border-color: var(--border); }
.fp-img { position: relative; display: block; aspect-ratio: 5 / 2; border-radius: 12px; overflow: hidden; background: #eef2f6; margin-bottom: 16px; }
.fp-img img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .5s ease; }
.fp-c:hover .fp-img img { transform: scale(1.05); }
.fp-n { top: 30px; left: 30px; right: auto; width: 30px; height: 30px; border-radius: 8px;
  background: rgba(20,58,92,0.92); color: #fff; font-size: .95rem; font-weight: 800; line-height: 1;
  display: grid; place-items: center; -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }
.fp-c h3 { margin: 0 0 8px; }
.fp-c p { margin: 0; }


/* FINAL feature cards: compact gauge rings, tinted cards (client pick). */
.k-features .k-feature,
.k-features .k-feature:nth-child(1),
.k-features .k-feature:nth-child(2),
.k-features .k-feature:nth-child(3) {
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border: 0; border-radius: 16px;
  box-shadow: 0 14px 34px rgba(15,42,68,0.10);
  padding: 22px 20px 24px; text-align: center; }
.k-features .k-feature:nth-child(1) { background: linear-gradient(145deg, #E8EDF3 0%, #FCFDFE 68%); }
.k-features .k-feature:nth-child(2) { background: linear-gradient(145deg, #E8EDF3 0%, #FCFDFE 68%); }
.k-features .k-feature:nth-child(3) { background: linear-gradient(145deg, #E8EDF3 0%, #FCFDFE 68%); }
.k-features .k-feature::before,
.k-features .k-feature:nth-child(1)::before,
.k-features .k-feature:nth-child(2)::before,
.k-features .k-feature:nth-child(3)::before { display: none; }
.k-features .k-feat-ico,
.k-features .k-feature:nth-child(1) .k-feat-ico,
.k-features .k-feature:nth-child(2) .k-feat-ico,
.k-features .k-feature:nth-child(3) .k-feat-ico {
  width: 72px; height: 72px; border-radius: 50%; margin: 0 auto 14px;
  display: grid; place-items: center; position: relative; box-shadow: none; border: none; }
.k-features .k-feature:nth-child(1) .k-feat-ico { background: conic-gradient(from 216deg, #0F3E66 0 var(--ring), rgba(15,62,102,0.14) var(--ring) 100%); }
.k-features .k-feature:nth-child(2) .k-feat-ico { background: conic-gradient(from 216deg, #0F3E66 0 var(--ring), rgba(15,62,102,0.14) var(--ring) 100%); }
.k-features .k-feature:nth-child(3) .k-feat-ico { background: conic-gradient(from 216deg, #0F3E66 0 var(--ring), rgba(15,62,102,0.14) var(--ring) 100%); }
.k-features .k-feat-ico::before { content: ""; position: absolute; inset: 8px; border-radius: 50%; background: #fff; box-shadow: 0 5px 14px rgba(15,42,68,0.12); border: none; }
.k-features .k-feat-ico svg,
.k-features .k-feature:nth-child(1) .k-feat-ico svg,
.k-features .k-feature:nth-child(2) .k-feat-ico svg,
.k-features .k-feature:nth-child(3) .k-feat-ico svg { position: relative; z-index: 1; width: 30px; height: 30px; stroke-width: 1.7; }
.k-features .k-feature:nth-child(1) .k-feat-ico svg { stroke: #0F3E66; }
.k-features .k-feature:nth-child(2) .k-feat-ico svg { stroke: #0F3E66; }
.k-features .k-feature:nth-child(3) .k-feat-ico svg { stroke: #0F3E66; }
.k-features .k-feature h3 { color: var(--ink); font-size: 1.02rem; }
.k-features .k-feature p { color: var(--text-sub); font-size: .86rem; }
.k-features .k-feature:hover { transform: translateY(-5px); box-shadow: 0 22px 48px rgba(15,42,68,0.16); border-color: rgba(15,42,68,0.06); }

/* Product-page grade rows: square product shots shown in full (no crop),
   smaller and identical, without touching the homepage product rows. */
.grade-rows .px-media { max-width: 372px; margin-inline: auto; }
.grade-rows .px-imgwrap img { aspect-ratio: 1 / 1; }
.grade-rows .px-media::after { width: 80%; height: 80%; }

/* ============================================================
   MOTION, premium pass (client: entry + exit + micro-interactions,
   all breakpoints). The scroll reveals themselves re-trigger both
   ways from main.js; this block adds the hero parallax frame, the
   product-hero image reveal, and hover / press micro-interactions.
   Every autoplaying piece is gated on prefers-reduced-motion.
   Reversible: delete this block.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  /* Homepage hero: the granule photo drifts slower than the page for depth.
     main.js drives the translate each frame; the frame is clipped and the
     image over-scaled so the drift never shows an edge. */
  .k-hero-bg { overflow: hidden; }
  .k-hero--photo .k-hero-bg img { transform: scale(1.14); will-change: transform; }

  /* Product hero photo eases up on load. It sits above the fold, so it is a
     load reveal rather than a scroll one; the inner frame animates so the
     image's own hover scale is left untouched. */
  .prod-page-hero.has-hero-img .prod-img-inner { animation: heroImgReveal .9s cubic-bezier(.2,.7,.2,1) .12s both; }
  @keyframes heroImgReveal {
    from { opacity: 0; transform: translateY(18px) scale(.985); }
    to   { opacity: 1; transform: none; }
  }
}

/* Micro-interactions. A press is useful feedback on touch too, so it runs
   unconditionally; the hover nudges are gated to real pointers so a tap does
   not leave an element stuck in its hover position. */
.btn { transition: transform var(--t-fast), box-shadow var(--t-fast), background var(--t-fast), border-color var(--t-fast), color var(--t-fast); }
.btn:active { transform: translateY(0) scale(.97); }
.px-cta:active { transform: translateY(1px) scale(.98); }
.footer-link { transition: color var(--t-fast), transform var(--t-fast); }
.grade-rows .px-imgwrap img { transition: transform .55s cubic-bezier(.2,.7,.2,1); }
@media (hover: hover) {
  .footer-link:hover { transform: translateX(3px); }
  .grade-rows .px-row:hover .px-imgwrap img { transform: scale(1.04); }
}


/* ============================================================
   ABOUT "Our Story" background, desktop only (client). Soft branded
   corner washes so the opening section is not a plain white block.
   Off on phones/tablets, where the text runs full-width and a wash
   would sit behind it. Base stays white, so the boundary with the
   aqua Mission band below still reads. Reversible: delete this block.
   ============================================================ */
@media (min-width: 901px) {
  .story-section { position: relative; overflow: hidden; }
  .story-section::before, .story-section::after {
    content: ""; position: absolute; z-index: 0; pointer-events: none; border-radius: 50%;
  }
  .story-section::before { width: 480px; height: 480px; top: -170px; left: -190px;
    background: radial-gradient(circle at 50% 50%, rgba(8,145,178,.13), rgba(8,145,178,0) 70%); }
  .story-section::after { width: 440px; height: 440px; bottom: -180px; right: -170px;
    background: radial-gradient(circle at 50% 50%, rgba(201,153,5,.12), rgba(201,153,5,0) 70%); }
  .story-section > .container { position: relative; z-index: 1; }
  /* Subtle "ripple" of concentric rings sweeping in from the right margin
     (moisture/absorption motif). Line-based, so it reads as a distinct
     element beside the soft colour washes without competing with the text;
     masked to fade out before the reading column. */
  .story-deco { position: absolute; z-index: 0; pointer-events: none;
    top: 50%; right: -330px; width: 640px; height: 640px; transform: translateY(-50%);
    background: repeating-radial-gradient(circle at center,
      rgba(8,145,178,.16) 0 1.5px, transparent 1.5px 46px);
    -webkit-mask: radial-gradient(circle at center, #000 26%, transparent 70%);
            mask: radial-gradient(circle at center, #000 26%, transparent 70%); }
}


/* ============================================================
   FIRST SCREEN: hero + feature strip (client: "open hote hi
   atleast itna toh visible ho"). The three cards rise far enough
   into the hero that their icon AND heading show on load, and the
   hero card centres in the space left above them. --kf-peek is how
   far the strip rises; the hero keeps that much plus --kf-gap free
   at its foot, so the two can never collide. This block is last in
   the file on purpose: it overrides the older per-breakpoint
   margin-tops on .k-features. Short desktop windows (<=760px tall,
   e.g. a 1366x657 laptop) tighten the hero card so the heading
   still clears the fold.
   ============================================================ */
:root { --kf-peek: 160px; --kf-gap: 36px; }
@media (max-width: 760px) { :root { --kf-peek: 150px; --kf-gap: 24px; } }
@media (min-width: 761px) and (max-height: 760px) {
  :root { --kf-peek: 150px; --kf-gap: 24px; }
  .k-hero--photo .k-hero-band > .container { margin-block: 0; padding-block: 30px; }
}
.k-features { margin-top: calc(-1 * var(--kf-peek)); }
.k-hero--photo .k-hero-band { padding-bottom: calc(var(--kf-peek) + var(--kf-gap)); }

/* Contact banner on phones: the floating nav (82px) covered the top of the
   200px photo band, hiding the icon tiles and the fingertip (client: "mobile
   pe isse bhi thik karo"). Phones start the band just below the nav instead,
   same height and crop, so nothing in the photo sits under the bar. Tablet
   and desktop keep the band flush under the nav, as approved. */
@media (max-width: 640px) {
  .contact-hero-img { margin-top: 92px; }
}
