/* ============================================================
   Kim — Direction 2: "الغسلة" / THE WASH
   Drenched brand navy. Foam is the only light in the room, and the
   one bright surface on the page is where the value claim lands.

   The page is one descent: you enter at the surface (hero foam head),
   the ground darkens through the offer and the journey, the lime band
   is the only place the surface breaks through, and the contact
   section rinses back up into foam.

   Static design phase; class names stay Blade-conversion friendly.
   ============================================================ */

:root {
  --deep: #070C1E;          /* the water at depth: page ground        */
  --deeper: #03060F;        /* the bottom of the wash                 */
  --navy: #101A44;          /* brand navy, seated: raised surfaces    */
  --navy-2: #16225A;        /* brand navy #14205C, one step up        */
  --ice: #EDF2FF;           /* light through foam: primary text       */
  --ice-2: #AEBCE2;         /* supporting text, 11:1 on --deep        */
  --line: rgba(174, 188, 226, 0.18);
  --line-strong: rgba(174, 188, 226, 0.34);
  --zest: #C2F53F;          /* the single bright surface + every action */
  --zest-deep: #A4D91F;
  --alarm: #FF7A68;         /* form errors, readable on navy          */
  --font-display: "Alexandria", "Almarai", sans-serif;
  --font-body: "Almarai", "Alexandria", sans-serif;
  --font-mono: "Fragment Mono", ui-monospace, "SFMono-Regular", monospace;
  /* Motion scale. Everything that moves picks one of these; nothing invents
     its own number. Named by the job, not by the milliseconds, so a later
     retune changes feel everywhere at once. */
  --t-tap: 110ms;        /* press feedback: must beat the finger leaving      */
  --t-hover: 190ms;      /* pointer states                                    */
  --t-ui: 320ms;         /* bars, menus, disclosure                           */
  --t-enter: 620ms;      /* content arriving                                  */
  --t-feature: 900ms;    /* the one claim per page                            */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);        /* decelerate hard: entrances */
  --ease-ui: cubic-bezier(0.32, 0.72, 0, 1);    /* crisper: interface         */
  --ease-tap: cubic-bezier(0.2, 0, 0, 1);       /* immediate: presses         */
  --t-follow: 180ms;     /* scroll-linked smoothing: linear, not eased        */
  --t-page: 420ms;       /* cross-document navigation                         */
  --stagger: 70ms;
  --pad-x: clamp(1.25rem, 6vw, 6rem);
  --wrap: 1240px;
  /* z-index scale, so nothing ever reaches for 9999 */
  --z-field: 0;
  --z-content: 2;
  --z-bar: 40;
  --z-grain: 60;
  --z-skip: 90;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

body {
  /* the descent: light at the surface, darkest through the journey,
     lifting again where the page rinses out */
  background:
    linear-gradient(180deg,
      var(--deep) 0%,
      #050A18 26%,
      var(--deeper) 52%,
      #050A18 76%,
      #0A1230 100%) no-repeat;
  background-color: var(--deep);
  color: var(--ice);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.9;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  accent-color: var(--zest);
  scrollbar-width: thin;
  scrollbar-color: var(--navy-2) var(--deep);
}

::selection { background: var(--zest); color: var(--deep); }
:focus-visible { outline: 2px solid var(--zest); outline-offset: 3px; }

a { color: inherit; text-decoration-color: var(--line-strong); text-underline-offset: 0.3em; }
a:hover { text-decoration-color: var(--zest); }

h1, h2, h3 { font-family: var(--font-display); line-height: 1.3; text-wrap: balance; letter-spacing: 0; }
p { text-wrap: pretty; }

/* the digits are lab equipment, not body copy */
.station-no, .strip-no { font-variant-numeric: tabular-nums; }

.skip {
  position: absolute; inset-inline-start: 1rem; top: 1rem; z-index: var(--z-skip);
  background: var(--zest); color: var(--deep); padding: 0.6rem 1.1rem; font-weight: 700;
  /* travels on transform, not on `top`: nothing animated belongs on the layout path */
  transform: translateY(-6rem);
  transition: transform var(--t-hover) var(--ease-ui);
}
.skip:focus { transform: none; }

/* a fixed film of grain: water is never optically flat */
.grain {
  position: fixed; inset: 0; z-index: var(--z-grain);
  pointer-events: none; opacity: 0.05; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/></filter><rect width='180' height='180' filter='url(%23n)'/></svg>");
}

/* ---------- Actions ---------- */

.btn {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.0625rem;
  line-height: 1.2;
  color: var(--deep);
  background: var(--zest);
  border: 0;
  padding: 1rem 2rem;
  cursor: pointer;
  text-decoration: none;
  transition: transform var(--t-hover) var(--ease-ui), box-shadow var(--t-hover) var(--ease-ui), background-color var(--t-hover) var(--ease-ui);
}
.btn:hover, .btn:focus-visible {
  background: #D6FF63;
  transform: translateY(-2px);
  box-shadow: 0 14px 34px -14px rgba(194, 245, 63, 0.75);
}
.btn:active { transform: translateY(1px) scale(0.99); box-shadow: none; }
.btn-sm { padding: 0.55rem 1.1rem; font-size: 0.875rem; }

.ghost-link {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
  padding-bottom: 0.25rem;
  text-decoration: none;
  border-bottom: 1.5px solid var(--line-strong);
  transition: border-color var(--t-hover) var(--ease-ui), color var(--t-hover) var(--ease-ui);
}
.ghost-link:hover, .ghost-link:focus-visible { border-bottom-color: var(--zest); color: var(--zest); }

/* ---------- Top bar ---------- */

.topbar {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: var(--z-bar);
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.5rem);
  padding: 0.9rem var(--pad-x);
  transition: background-color var(--t-ui) var(--ease-ui), border-color var(--t-ui) var(--ease-ui);
  border-bottom: 1px solid transparent;
}
/* the seated bar is opaque: scrolled content must not read through it */
.topbar.is-stuck { background: var(--deep); border-bottom-color: var(--line); }
.topbar-brand { display: flex; align-items: center; }
.topbar-brand img { display: block; height: 48px; width: auto; }
.topbar-nav {
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2.2vw, 1.9rem);
  margin-inline-start: auto;
  flex-wrap: wrap;
}
.topbar-nav a {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 0.9375rem;
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
  transition: color var(--t-hover) var(--ease-ui), border-color var(--t-hover) var(--ease-ui);
}
.topbar-nav a:hover, .topbar-nav a:focus-visible { border-bottom-color: var(--zest); }
/* you always know which room you are in */
.topbar-nav a.is-here { color: var(--zest); border-bottom-color: var(--zest); }
.topbar-nav .lang-switch {
  font-size: 0.8125rem;
  font-weight: 700;
  border: 1px solid var(--line-strong);
  border-bottom-width: 1px;
  padding: 0.3rem 0.65rem;
}
.topbar-nav .lang-switch:hover { background: var(--ice); color: var(--deep); border-color: var(--ice); }
.topbar-nav .btn:hover, .topbar-nav .btn:focus-visible { border-bottom-color: transparent; }

.nav-toggle {
  display: none;
  align-items: center;
  gap: 0.55rem;
  margin-inline-start: auto;
  background: transparent;
  border: 1px solid var(--line-strong);
  color: var(--ice);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.875rem;
  padding: 0.5rem 0.85rem;
  cursor: pointer;
  transition: border-color var(--t-hover) var(--ease-ui), color var(--t-hover) var(--ease-ui);
}
.nav-toggle:hover { border-color: var(--zest); color: var(--zest); }
.nav-toggle-bars { display: grid; gap: 3px; }
.nav-toggle-bars i { display: block; width: 16px; height: 1.5px; background: currentColor; transition: transform var(--t-hover) var(--ease-ui), opacity var(--t-hover) var(--ease-ui); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars i:nth-child(1) { transform: translateY(4.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars i:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bars i:nth-child(3) { transform: translateY(-4.5px) rotate(-45deg); }

/* ---------- Reveal grammar ----------
   Four gestures, chosen by what the element IS, not applied uniformly.
   A paragraph and a plate should not arrive the same way.

     .rise   text — a short fade up
     .lift   figures, plates, forms, cards — further, with a little weight
     .slide  rows in a list — in from the reading edge, auto-staggered
     .wipe   the one claim per page — the mask below

   `--i` is the stagger index. Containers marked [data-stagger] get it
   assigned from DOM order in main.js, so it is never hand-typed and never
   drifts out of sequence. Blur was dropped from the reveal: it measured at
   almost no cost, but it was the least legible third of the gesture.
*/

.js .rise,
.js .lift,
.js .slide { opacity: 0; }

.js .rise  { transform: translateY(12px); }
.js .lift  { transform: translateY(26px) scale(0.985); }
.js .slide { transform: translateX(calc(18px * var(--flip, 1))); }

.js .rise.is-up,
.js .lift.is-up,
.js .slide.is-up {
  opacity: 1;
  transform: none;
  transition: opacity var(--t-enter) var(--ease), transform var(--t-enter) var(--ease);
  transition-delay: calc(var(--i, 0) * var(--stagger));
}
/* a plate carries more mass than a sentence, so it takes a beat longer */
.js .lift.is-up { transition-duration: calc(var(--t-enter) + 160ms); }

/* .slide arrives from the reading edge: the right in Arabic, the left in English */
:root { --flip: 1; }
:root:dir(ltr) { --flip: -1; }

/* ---------- Foam primitives: used by the hero head and the closing rinse ---------- */

.sud {
  position: absolute;
  bottom: var(--b, 0);
  inset-inline-start: var(--x);
  width: var(--size);
  height: var(--size);
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 30%, rgba(255,255,255,0.96) 0 12%, rgba(228,241,255,0.74) 40%, rgba(154,197,255,0.40) 72%, rgba(96,140,220,0.16) 100%);
  opacity: var(--o, 0.8);
  filter: blur(var(--soft, 0px));
}

.bubble {
  position: absolute;
  bottom: -12vh;
  inset-inline-start: var(--x);
  width: var(--size);
  height: var(--size);
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, rgba(255,255,255,0) 54%, rgba(190,220,255,0.14) 76%, rgba(226,240,255,0.40) 90%, rgba(255,255,255,0.78) 97%, rgba(255,255,255,0) 100%),
    radial-gradient(circle at 30% 26%, rgba(255,255,255,0.82) 0 6%, rgba(255,255,255,0) 13%);
  opacity: 0;
  filter: blur(var(--soft, 0px));
  /* no will-change: a transform/opacity animation is composited anyway, and
     pinning a layer per bubble costs GPU memory the phone would rather keep */
}
.js .bubble { animation: swell var(--dur, 18s) linear var(--delay, 0s) infinite; }
@keyframes swell {
  0%   { transform: translate3d(0, 0, 0) scale(0.9); opacity: 0; }
  12%  { opacity: var(--peak, 0.75); }
  82%  { opacity: var(--peak, 0.75); }
  100% { transform: translate3d(var(--drift, 0px), calc(-1 * var(--climb, 100vh)), 0) scale(1.08); opacity: 0; }
}

/* ---------- Hero: inside the foam ---------- */

.hero {
  position: relative;
  min-height: min(94dvh, 900px);
  display: grid;
  align-content: center;
  padding: clamp(7rem, 16vh, 11rem) var(--pad-x) clamp(4.5rem, 12vh, 8rem);
  overflow: hidden;
  /* Real foam carries the ground; the coded bubbles still rise over it.
     The scrim keeps the headline side dark and fades the photograph out
     before the section boundary, so the hero ends in ink, not in a seam. */
  background:
    linear-gradient(to bottom, rgba(7, 12, 30, 0.55) 0%, rgba(7, 12, 30, 0.35) 42%, rgba(7, 12, 30, 0.82) 88%, var(--deep) 100%),
    radial-gradient(120% 80% at 78% 12%, rgba(22, 34, 90, 0.8) 0%, rgba(22, 34, 90, 0) 62%),
    var(--hero-ground, url("media/foam-hero.webp")) center bottom / cover no-repeat,
    var(--deep);
}

.foam-field { position: absolute; inset: 0; pointer-events: none; z-index: var(--z-field); }

/* the settled foam at the bottom of the vessel: no hard top edge, it dissolves */
.foam-bed {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 26%;
  background: linear-gradient(to top, rgba(150, 196, 255, 0.22), rgba(150, 196, 255, 0.07) 45%, rgba(150, 196, 255, 0) 88%);
}

.hero-inner { position: relative; z-index: var(--z-content); max-width: var(--wrap); margin-inline: auto; width: 100%; }

.hero h1 {
  font-weight: 900;
  font-size: clamp(2.5rem, 7.4vw, 5.75rem);
  line-height: 1.22;
  margin-bottom: 1.5rem;
  max-width: 16ch;
}
.hero h1 span { display: block; color: var(--zest); }

.hero .lead {
  max-width: 46ch;
  font-size: clamp(1.0625rem, 1.6vw, 1.25rem);
  color: var(--ice-2);
  margin-bottom: 2.4rem;
}

.hero-actions { display: flex; align-items: center; gap: 1.5rem 2rem; flex-wrap: wrap; }

/* the hero's foot: three facts, set like instrument labels */
.hero-strip {
  position: relative;
  z-index: var(--z-content);
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem clamp(1.5rem, 4vw, 3.5rem);
  max-width: var(--wrap);
  width: 100%;
  margin: clamp(3rem, 8vh, 5rem) auto 0;
  padding-top: 1.1rem;
  border-top: 1px solid var(--line);
  font-size: 0.9375rem;
  color: var(--ice-2);
}
.hero-strip li { display: flex; align-items: baseline; gap: 0.6rem; }
.strip-no {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--zest);
  letter-spacing: 0.06em;
}

/* ---------- Section scaffolding ---------- */

main > section {
  position: relative;
  padding-block: clamp(3rem, 7vw, 6rem);
  /* the content box IS the measure: children align to the text edge,
     instead of each max-width block centring itself inside a wider column */
  padding-inline: max(var(--pad-x), calc((100% - var(--wrap)) / 2));
}

.sec-head { margin-bottom: clamp(2rem, 5vw, 3.5rem); }
.sec-head h2 { font-weight: 800; font-size: clamp(1.875rem, 4.2vw, 3rem); margin-bottom: 0.7rem; }
.sec-head p { color: var(--ice-2); max-width: 58ch; }

/* ---------- Offer: rows argue it, the bag shows it ---------- */

.offer::before {
  content: "";
  position: absolute;
  inset-inline: 0; top: 0; height: 70%;
  background: radial-gradient(80% 100% at 82% 0%, rgba(30, 52, 128, 0.45) 0%, rgba(30, 52, 128, 0) 70%);
  pointer-events: none;
}
.offer > * { position: relative; }

.offer-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}

.offer-rows { list-style: none; border-top: 1px solid var(--line); }
.offer-rows li {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  gap: clamp(1.25rem, 3.5vw, 2.75rem);
  align-items: start;
  padding-block: clamp(1.5rem, 3.5vw, 2.5rem);
  border-bottom: 1px solid var(--line);
  transition: background-color var(--t-ui) var(--ease-ui);
}
.offer-rows li:hover { background: rgba(22, 34, 90, 0.4); }
/* The rows used to lead with a ghost numeral. An ordinal told you where you
   were in the list but nothing about the step, and the <ol> already carries it.
   Each row now leads with the thing itself — a flask, a hopper over a pack, a
   pack with your plate on it, a loaded ship — drawn on one 24-grid at one
   stroke weight, so icon + heading is the whole point and the paragraph is
   only the detail. One lime part per icon marks what the row is actually
   about: the batch, the powder falling, your label, the container that ships. */
.row-icon {
  display: block;
  width: clamp(2.5rem, 5vw, 3.5rem);
  margin-block-start: 0.2rem;
  color: var(--ice-2);
  transition: color var(--t-ui) var(--ease-ui);
}
.row-icon svg { display: block; width: 100%; height: auto; overflow: visible; }
.row-icon .zs { stroke: var(--zest); transition: stroke var(--t-ui) var(--ease-ui); }
.row-icon .zf { fill: var(--zest); fill-opacity: 0.92; transition: fill var(--t-ui) var(--ease-ui); }
/* On hover the whole glyph lights lime, the way the old numeral's stroke did.
   The lime part flips to foam-white in the same move, so the icon keeps its
   inner contrast instead of flattening into one solid shape. */
.offer-rows li:hover .row-icon { color: var(--zest); }
.offer-rows li:hover .row-icon .zs { stroke: var(--ice); }
.offer-rows li:hover .row-icon .zf { fill: var(--ice); }
.row-body h3 { font-weight: 700; font-size: clamp(1.25rem, 2.4vw, 1.75rem); margin-bottom: 0.35rem; }
.row-body p { color: var(--ice-2); max-width: 62ch; }

/* ---------- The product: the client's own pack, photographed ---------- */

/* the bag holds its ground while the four rows scroll past it */
.bag-fig { position: sticky; top: clamp(6rem, 12vh, 8rem); margin: 0; }
.bag-photo {
  display: block;
  width: 100%;
  max-width: 400px;
  height: auto;
  margin-inline: auto;
  filter: drop-shadow(0 30px 34px rgba(3, 6, 15, 0.6));
}
.bag-fig figcaption {
  margin-top: clamp(1.25rem, 3vw, 2rem);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
  color: var(--ice);
  text-align: center;
}
.bag-fig figcaption span {
  display: block;
  margin-top: 0.5rem;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 0.8125rem;
  line-height: 1.7;
  color: var(--ice-2);
}

/* ---------- The value band: the one bright surface ---------- */

.band {
  position: relative;
  background: var(--zest);
  color: var(--deep);
  padding-block: clamp(3rem, 7vw, 5rem) clamp(3rem, 7vw, 5rem);
}
/* the one place the foam inverts: dark suds on the bright surface */
.band-foam {
  position: absolute;
  inset-block: 0;
  inset-inline-end: 0;
  width: min(52%, 620px);
  overflow: hidden;
  pointer-events: none;
  /* densest at the outer edge, thinning out before it reaches the claim */
  -webkit-mask-image: linear-gradient(to left, rgba(0,0,0,0), #000 62%);
  mask-image: linear-gradient(to left, rgba(0,0,0,0), #000 62%);
}
.band-kicker, .band h2, .band > p { position: relative; z-index: 1; }
.sud-ink {
  position: absolute;
  bottom: var(--b, 0);
  inset-inline-start: var(--x);
  width: var(--size);
  height: var(--size);
  border-radius: 50%;
  background: radial-gradient(circle at 36% 32%, rgba(7,12,30,0.05) 0 46%, rgba(7,12,30,0.16) 82%, rgba(7,12,30,0.05) 100%);
  border: 1.5px solid rgba(7, 12, 30, 0.16);
  opacity: var(--o, 0.8);
}
/* the band surfaces through foam above and breaks into foam below:
   two bubble scales on each edge so the line never reads as a scallop stamp */
.band::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 100%;
  height: 40px;
  background-image:
    radial-gradient(circle at 21px 100%, var(--zest) 0 20px, transparent 21px),
    radial-gradient(circle at 11px 100%, var(--zest) 0 10px, transparent 11px);
  background-size: 42px 40px, 22px 40px;
  background-position: 0 0, 13px 0;
  background-repeat: repeat-x;
  pointer-events: none;
}
.band::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 100%;
  height: 30px;
  background-image:
    radial-gradient(circle at 14px 0, var(--zest) 0 13px, transparent 14px),
    radial-gradient(circle at 8px 0, var(--zest) 0 7px, transparent 8px);
  background-size: 28px 30px, 16px 30px;
  background-position: 0 0, 9px 0;
  background-repeat: repeat-x;
  pointer-events: none;
}
.band-kicker {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  color: rgba(7, 12, 30, 0.7);
  margin-bottom: 0.9rem;
}
.band h2 {
  font-weight: 900;
  font-size: clamp(2rem, 5.5vw, 4rem);
  line-height: 1.24;
  max-width: 18ch;
  margin-bottom: 1.2rem;
}
.band > p { max-width: 54ch; font-size: clamp(1.0625rem, 1.5vw, 1.1875rem); color: rgba(7, 12, 30, 0.85); }

/* ---------- Journey ---------- */

/* the journey runs in a narrower measure than the section: the plate stays
   near its text instead of drifting to the far edge of a 1240px row */
.stations { list-style: none; position: relative; max-width: min(100%, 1060px); }
/* the rail, and the wash running down it as you scroll */
.stations::before {
  content: "";
  position: absolute;
  top: 0.75rem; bottom: 3rem;
  inset-inline-start: 1.4rem;
  border-inline-start: 1px solid var(--line);
}
.stations::after {
  content: "";
  position: absolute;
  top: 0.75rem;
  inset-inline-start: calc(1.4rem - 1px);
  width: 3px;
  height: calc(100% - 3.75rem);
  background: linear-gradient(to bottom, rgba(194, 245, 63, 0.06), rgba(194, 245, 63, 0.55) 55%, var(--zest));
  box-shadow: 0 0 14px rgba(194, 245, 63, 0.45);
  /* scaled, not resized: this runs on every scroll frame, so it stays off
     the layout path. Squashing the gradient keeps the lit end at the front. */
  transform: scaleY(var(--rail, 0));
  transform-origin: top;
  transition: transform var(--t-follow) linear;
}
.stations li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.6fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
}
.station-text { padding-inline-start: 4.5rem; position: relative; }
.station-no {
  position: absolute;
  inset-inline-start: 0;
  top: 0.1rem;
  width: 2.8rem; height: 2.8rem;
  display: grid; place-items: center;
  background: var(--deeper);
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  /* above the rail: the line runs behind each counter, not across it */
  z-index: 1;
  transition: border-color var(--t-ui) var(--ease-ui), color var(--t-ui) var(--ease-ui), box-shadow var(--t-ui) var(--ease-ui);
}
.stations li:hover .station-no {
  border-color: var(--zest);
  color: var(--zest);
  box-shadow: 0 0 0 4px rgba(194, 245, 63, 0.08);
}
.stations h3 { font-weight: 700; font-size: clamp(1.25rem, 2.6vw, 1.75rem); margin-bottom: 0.3rem; }
.stations p { color: var(--ice-2); max-width: 52ch; }

.plate { margin: 0; }
.plate img { display: block; width: 100%; height: auto; aspect-ratio: var(--ar, 16 / 9); object-fit: cover; }
/* a lit plate of glass: the coded station diagram sits behind it until a
   photograph replaces the whole figure */
.plate-art {
  position: relative;
  aspect-ratio: var(--ar, 16 / 9);
  display: grid;
  place-items: center;
  padding: clamp(0.75rem, 2vw, 1.5rem);
  background:
    radial-gradient(120% 90% at 50% -10%, rgba(46, 74, 168, 0.5) 0%, rgba(46, 74, 168, 0) 68%),
    linear-gradient(160deg, rgba(22, 34, 90, 0.9), rgba(10, 18, 51, 0.92));
  border: 1px solid var(--line);
  box-shadow: inset 0 1px 0 rgba(233, 242, 255, 0.09), 0 24px 48px -30px rgba(3, 6, 15, 0.9);
  transition: border-color var(--t-ui) var(--ease-ui), transform var(--t-ui) var(--ease-ui), box-shadow var(--t-ui) var(--ease-ui);
}
.stations li:hover .plate-art {
  border-color: var(--line-strong);
  transform: translateY(-3px);
  box-shadow: inset 0 1px 0 rgba(233, 242, 255, 0.14), 0 30px 56px -30px rgba(3, 6, 15, 1);
}
.plate-art svg { display: block; width: 100%; height: 100%; }

.terminus {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.375rem, 3.2vw, 2.25rem);
  line-height: 1.4;
  padding-inline-start: 4.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  text-wrap: balance;
}

/* ---------- Why: claims ranked, and laid out by rank ---------- */

.why { padding-bottom: clamp(1.5rem, 3vw, 2.5rem); }
.why .sec-head { margin-bottom: clamp(1.5rem, 3vw, 2.25rem); }
.claims { list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 clamp(2rem, 5vw, 4rem); }
.claims li { padding-block: clamp(1.75rem, 4vw, 2.75rem); border-bottom: 1px solid var(--line); }
.claims h3 { margin-bottom: 0.6rem; }
.claims p { color: var(--ice-2); max-width: 62ch; }

/* the light behind the first claim bleeds off the page edge instead of
   ending on a content boundary, which would read as a lit rectangle */
.why::before {
  content: "";
  position: absolute;
  inset-inline: 0; top: 0; height: 66%;
  background: radial-gradient(52% 78% at 72% 34%, rgba(46, 74, 168, 0.5) 0%, rgba(46, 74, 168, 0) 74%);
  pointer-events: none;
}
.why > * { position: relative; }
.claims .rank-1 {
  grid-column: 1 / -1;
  border-bottom-color: var(--zest);
}
.claims .rank-1 h3 { font-size: clamp(2rem, 5.4vw, 3.75rem); font-weight: 900; line-height: 1.2; }
.claims .rank-1 p { color: var(--ice); font-size: clamp(1.0625rem, 1.6vw, 1.25rem); max-width: 56ch; }
.claims .rank-2 h3 { font-size: clamp(1.5rem, 3.4vw, 2.25rem); font-weight: 800; }
.claims .rank-3 h3 { font-size: clamp(1.25rem, 2.4vw, 1.625rem); font-weight: 700; }
.claims .rank-2, .claims .rank-3 { border-bottom: 0; }

/* ---------- Contact ---------- */

.contact {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
  padding-bottom: clamp(4rem, 9vw, 7rem);
}
.contact::before {
  content: "";
  position: absolute;
  inset-inline: 0; bottom: 0; height: 80%;
  background: radial-gradient(70% 100% at 50% 100%, rgba(46, 74, 168, 0.4) 0%, rgba(46, 74, 168, 0) 72%);
  pointer-events: none;
}
.contact > * { position: relative; max-width: none; }
.contact-text h2 { font-weight: 800; font-size: clamp(1.875rem, 4.2vw, 3rem); margin-bottom: 0.8rem; }
.contact-text p { color: var(--ice-2); max-width: 46ch; }
.checklist {
  margin-top: 1.5rem;
  padding: 1.1rem 1.3rem;
  border: 1px solid var(--line);
  border-inline-start: 2px solid var(--zest);
  background: rgba(16, 26, 68, 0.5);
  color: var(--ice) !important;
  font-size: 0.9375rem;
}

.wash-form {
  background: linear-gradient(160deg, rgba(22, 34, 90, 0.85), rgba(16, 26, 68, 0.95));
  padding: clamp(1.25rem, 3vw, 2.5rem);
  border: 1px solid var(--line);
  box-shadow: inset 0 1px 0 rgba(233, 242, 255, 0.08), 0 30px 60px -40px rgba(3, 6, 15, 1);
}
.form-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0.5rem 1.75rem; }
.field { margin-bottom: 1.3rem; min-width: 0; }
.field-wide { grid-column: 1 / -1; }
.field label {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.875rem;
  margin-bottom: 0.4rem;
}
.field input, .field textarea {
  width: 100%;
  font-family: inherit;
  font-size: 1rem;
  color: var(--ice);
  /* underline fields still need a footprint before focus */
  background: rgba(174, 188, 226, 0.05);
  border: 0;
  border-bottom: 1.5px solid var(--line-strong);
  padding: 0.5rem 0.6rem;
  caret-color: var(--zest);
  transition: border-color var(--t-hover) var(--ease-ui), background-color var(--t-hover) var(--ease-ui);
}
.field textarea { resize: vertical; min-height: 5.5rem; line-height: 1.7; }
.field input:focus, .field textarea:focus {
  outline: none;
  background: rgba(174, 188, 226, 0.09);
  border-bottom-color: var(--zest);
  border-bottom-width: 2px;
}
.field.has-error input, .field.has-error textarea,
.field.has-error input:focus, .field.has-error textarea:focus { border-bottom-color: var(--alarm); }
.field .field-error { display: none; font-size: 0.8125rem; color: var(--alarm); margin-top: 0.3rem; }
.field.has-error .field-error { display: block; }
.form-alert { flex-basis: 100%; font-size: 0.875rem; color: var(--alarm); }

.form-foot { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; margin-top: 1.4rem; }
.form-note { font-size: 0.8125rem; color: var(--ice-2); }

.form-done {
  display: none;
  background: var(--zest);
  color: var(--deep);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.125rem;
  padding: 1.5rem 1.4rem;
}
.wash-form.is-done .form-done { display: block; }
.wash-form.is-done .form-fields, .wash-form.is-done .form-foot { display: none; }

/* ---------- The rinse: foam along the last edge ---------- */

.rinse {
  position: relative;
  height: clamp(90px, 12vw, 150px);
  overflow: hidden;
  background: linear-gradient(to top, rgba(150, 196, 255, 0.16), rgba(150, 196, 255, 0) 82%);
}

/* ---------- Footer ---------- */

.foot {
  position: relative;
  padding: clamp(2.5rem, 6vw, 4rem) var(--pad-x) clamp(2rem, 5vw, 3rem);
  border-top: 1px solid var(--line);
  display: grid;
  gap: 0.4rem;
  color: var(--ice-2);
  font-size: 0.9375rem;
}
.foot > * { max-width: var(--wrap); margin-inline: auto; width: 100%; }
.foot-brand { font-family: var(--font-display); font-weight: 700; font-size: 1.125rem; color: var(--ice); }
.foot-todo span { display: inline-block; border: 1px dashed var(--line-strong); padding: 0.2rem 0.7rem; font-size: 0.8125rem; }
.foot-ref { margin-top: 0.9rem; font-size: 0.8125rem; }

/* ---------- Responsive ---------- */

@media (max-width: 1080px) {
  .offer-grid { grid-template-columns: 1fr; }
  .bag-fig { position: static; max-width: 340px; margin-inline: auto; }
}

@media (max-width: 960px) {
  .band-foam { width: 62%; opacity: 0.75; }
  .stations li { grid-template-columns: 1fr; gap: 1.25rem; }
  .plate { padding-inline-start: 4.5rem; }
  .contact { grid-template-columns: 1fr; }
  .claims { grid-template-columns: 1fr; }
  .claims .rank-2 { border-bottom: 1px solid var(--line); }
  .topbar-brand img { height: 40px; }
}

/* below this the nav collapses into a real menu instead of hiding links */
@media (max-width: 900px) {
  .nav-toggle { display: inline-flex; }
  .topbar-nav {
    position: absolute;
    inset-inline: 0;
    top: 100%;
    display: grid;
    justify-items: start;
    gap: 0;
    margin: 0;
    padding: 0.5rem var(--pad-x) 1.25rem;
    background: var(--deep);
    border-bottom: 1px solid var(--line);
    box-shadow: 0 24px 40px -30px rgba(3, 6, 15, 1);
    clip-path: inset(0 0 100% 0);
    opacity: 0;
    pointer-events: none;
    transition: clip-path var(--t-ui) var(--ease-ui), opacity var(--t-hover) var(--ease-ui);
  }
  .topbar.is-open .topbar-nav { clip-path: inset(0 0 0 0); opacity: 1; pointer-events: auto; }
  .topbar-nav a { width: 100%; padding: 0.7rem 0; font-size: 1.0625rem; border-bottom: 1px solid var(--line); }
  .topbar-nav a:hover, .topbar-nav a:focus-visible, .topbar-nav a.is-here { border-bottom-color: var(--zest); }
  .topbar-nav .lang-switch { width: auto; margin-top: 1rem; border: 1px solid var(--line-strong); padding: 0.35rem 0.8rem; }
  .topbar-nav .btn { width: auto; margin-top: 1rem; border-bottom: 0; }
}

@media (max-width: 640px) {
  body { font-size: 1rem; }
  .topbar { padding-inline: var(--pad-x); gap: 0.75rem; }
  /* the foam head is proportionally taller on a narrow screen: keep the
     closing strip off it rather than letting suds eat the contrast */
  .hero { min-height: 88dvh; padding-top: clamp(6rem, 22vh, 9rem); padding-bottom: clamp(6.5rem, 20vh, 9rem); }
  .foam-bed { height: 18%; }
  .hero h1 { font-size: clamp(2.125rem, 10.5vw, 3rem); }
  .hero-strip { gap: 0.5rem 1.5rem; font-size: 0.875rem; }
  /* the icon stays beside the heading here too, at the clamp's floor —
     dropping it above the title breaks the icon+title pairing the row is built on */
  .offer-rows li { grid-template-columns: auto minmax(0, 1fr); gap: 0.9rem; }
  .station-text, .plate, .terminus { padding-inline-start: 0; }
  .station-no { position: static; margin-bottom: 0.75rem; }
  .stations::before, .stations::after { display: none; }
  .btn { padding: 0.9rem 1.5rem; }
}

/* ---------- Reduced motion: the room stops moving, nothing disappears ---------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .rise, .js .lift, .js .slide { opacity: 1; transform: none; transition: none; }
  .js .bubble { animation: none; opacity: var(--peak, 0.7); transform: translate3d(0, calc(-1 * var(--rest, 40vh)), 0); }
  .btn, .offer-rows li, .row-icon, .row-icon *, .topbar, .plate-art { transition: none; }
  .stations::after { transition: none; }
}


/* ============================================================
   Cross-document view transitions. Every page shares this
   stylesheet, so navigation morphs instead of blinking white.
   The bar and the footer are named, so they hold still while the
   content between them changes — which is what makes a static
   multi-page site feel like one place.
   ============================================================ */

@view-transition { navigation: auto; }

.topbar { view-transition-name: topbar; }
.foot { view-transition-name: sitefoot; }

/* The shared element. Every page opens on the same band of water — a tall
   hero on the homepage, a shorter head inside — so naming both makes the
   water level rise or drop between pages instead of the whole page blinking.
   Navigation resets scroll to the top, so old and new are always both on
   screen and the morph is well behaved. */
.hero, .page-head { view-transition-name: pagehead; }
::view-transition-group(pagehead) { animation-duration: var(--t-page); animation-timing-function: var(--ease); }
::view-transition-old(pagehead),
::view-transition-new(pagehead) { animation-duration: calc(var(--t-page) * 0.62); }

::view-transition-old(root) { animation: vt-sink calc(var(--t-page) * 0.55) var(--ease-ui) both; }
::view-transition-new(root) { animation: vt-surface var(--t-page) var(--ease) both; }

@keyframes vt-sink { to { opacity: 0; transform: translateY(-10px); } }
@keyframes vt-surface { from { opacity: 0; transform: translateY(16px); } }

/* Going back should not feel like going forward. main.js tags the transition
   from the navigation type, and the descent simply runs the other way. */
@keyframes vt-sink-back { to { opacity: 0; transform: translateY(10px); } }
@keyframes vt-surface-back { from { opacity: 0; transform: translateY(-16px); } }

html:active-view-transition-type(back)::view-transition-old(root) { animation-name: vt-sink-back; }
html:active-view-transition-type(back)::view-transition-new(root) { animation-name: vt-surface-back; }

/* ---------- Wipe reveal: reserved for the one claim per page ---------- */

/* A mask, not clip-path: Chromium folds a target's own clip-path into the
   IntersectionObserver rect, so a clipped heading never reports as visible
   and the reveal that was supposed to fire on it never does. Masks are
   ignored by IO, and mask-size animates just as smoothly. */
.js .wipe {
  -webkit-mask-image: linear-gradient(to left, #000 0 82%, rgba(0, 0, 0, 0) 100%);
  mask-image: linear-gradient(to left, #000 0 82%, rgba(0, 0, 0, 0) 100%);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: right center;
  mask-position: right center;
  -webkit-mask-size: 0% 100%;
  mask-size: 0% 100%;
}
.js .wipe.is-up {
  -webkit-mask-size: 145% 100%;
  mask-size: 145% 100%;
  transition: -webkit-mask-size var(--t-feature) var(--ease), mask-size var(--t-feature) var(--ease);
  transition-delay: calc(var(--i, 0) * var(--stagger));
}

@media (prefers-reduced-motion: reduce) {
  /* belt and braces: not every engine honours @view-transition inside a
     media query yet, so the animations are neutralised as well */
  @view-transition { navigation: none; }
  ::view-transition-old(root),
  ::view-transition-new(root),
  ::view-transition-old(pagehead),
  ::view-transition-new(pagehead),
  ::view-transition-group(pagehead) { animation: none !important; }
  .js .wipe, .js .wipe.is-up { -webkit-mask-image: none; mask-image: none; transition: none; }
}

/* ============================================================
   Scroll-linked motion, run by the compositor where the browser
   can do it natively.

   The journey rail is a pure function of scroll
   position — exactly what a scroll timeline is for. Where `view()` exists
   (Chrome, Edge, Safari 26+) this drives the rail off the main thread; where
   it does not (Firefox today) the JS in main.js keeps setting --rail and
   nothing changes. No branch is needed in the CSS, because an active
   animation always beats a plain declaration.
   ============================================================ */

@supports (animation-timeline: view()) {
  .stations { view-timeline-name: --rail-run; }
  .stations::after {
    animation: rail-fill linear both;
    animation-timeline: --rail-run;
    animation-range: cover 16% cover 84%;
  }
  @keyframes rail-fill { from { transform: scaleY(0); } to { transform: scaleY(1); } }
}
