/*! GEOWAVE Pvt Ltd — built 2026-09-09 08:37 — do not edit, see assets/css/src/ */

/* ==== 00-fonts.css ==== */
/* ===========================================================================
   GEOWAVE — typefaces
   ---------------------------------------------------------------------------
   Poppins is self-hosted (latin subset, ~31 KB for four weights) so the site
   makes no third-party font request and renders the same offline.

   Arial Rounded MT, Product Sans and Neulis are licensed families and are not
   redistributed here. Each is declared with `local()` sources, so on a machine
   where GEOWAVE has them installed they are used immediately, and everywhere
   else the stack falls through to Poppins without a failed network request.

   To ship them as webfonts: drop the .woff2 files into `assets/fonts/` using
   the names listed in `assets/fonts/README.md` and run
   `php assets/build.php` — the builder detects them and adds `url()` sources
   to the rules below automatically.
   =========================================================================== */

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/poppins-latin-400.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;
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/poppins-latin-500.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;
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/poppins-latin-600.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;
}

@font-face {
  font-family: "Poppins";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/poppins-latin-700.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;
}

/* --- Licensed brand families: local sources only until webfonts are added --- */

@font-face {
  font-family: "Arial Rounded MT";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("Arial Rounded MT"), local("Arial Rounded MT Regular"), local("ArialRoundedMTRegular");
  /* @gw-webfont: arial-rounded-mt-400 */
}

@font-face {
  font-family: "Arial Rounded MT";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: local("Arial Rounded MT Bold"), local("ArialRoundedMTBold"), local("ARLRDBD");
  /* @gw-webfont: arial-rounded-mt-700 */
}

@font-face {
  font-family: "Product Sans";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: local("Product Sans Bold"), local("ProductSans-Bold"), local("Product Sans");
  /* @gw-webfont: product-sans-700 */
}

@font-face {
  font-family: "Neulis";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("Neulis Regular"), local("Neulis-Regular"), local("Neulis");
  /* @gw-webfont: neulis-400 */
}

@font-face {
  font-family: "Neulis";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: local("Neulis SemiBold"), local("Neulis-SemiBold");
  /* @gw-webfont: neulis-600 */
}

@font-face {
  font-family: "Neulis";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: local("Neulis Bold"), local("Neulis-Bold");
  /* @gw-webfont: neulis-700 */
}


/* ==== 01-tokens.css ==== */
/* ===========================================================================
   GEOWAVE — design tokens
   ---------------------------------------------------------------------------
   Foundation is gray and white. The brand navy, slate, blue and mint are held
   back for the places where they carry meaning: the dark maritime bands, the
   wave pattern, buttons, focus and active states, and the accent rules that
   run through the page.
   =========================================================================== */

:root {
  /* -- Brand primaries, exactly as specified -------------------------------- */
  --gw-navy:        #012442;   /* rgb(1, 36, 66)    */
  --gw-mint:        #91c6c4;   /* rgb(145, 198, 196)*/
  --gw-gray:        #4c4c4c;   /* rgb(76, 76, 76)   */
  --gw-black:       #010101;   /* rgb(1, 1, 1)      */

  /* -- Documented usage palette (slate 40% / blue 40% / mint 15% / white 5%) */
  --gw-slate:       #2c4a52;
  --gw-blue:        #003366;
  --gw-blue-alt:    #004080;
  --gw-mint-light:  #abd7d6;

  /* -- Neutral ramp: the dominant surface of the whole site ----------------- */
  --gw-0:   #ffffff;
  --gw-25:  #fafbfb;
  --gw-50:  #f4f6f6;
  --gw-100: #ebeeee;
  --gw-150: #e1e5e6;
  --gw-200: #d4d9da;
  --gw-300: #b9c0c2;
  --gw-400: #949c9f;
  --gw-500: #767e81;
  --gw-600: #626a6d;
  --gw-700: #4c4c4c;
  --gw-800: #2a2e30;
  --gw-900: #16191a;

  /* -- Semantic surfaces ---------------------------------------------------- */
  --surface:          var(--gw-0);
  --surface-page:     var(--gw-0);
  --surface-muted:    var(--gw-50);
  --surface-sunken:   var(--gw-100);
  --surface-dark:     var(--gw-navy);
  --surface-slate:    var(--gw-slate);

  /* -- Semantic ink --------------------------------------------------------- */
  /* Every ink value below clears WCAG AA (4.5:1) against the surfaces it is
     actually used on — white, --surface-muted, --gw-navy and --gw-slate. The
     tertiary tone is a measured value, not an eyeballed light grey. */
  --ink-heading:      var(--gw-navy);   /* 15.8:1 on white */
  --ink-body:         var(--gw-gray);   /*  8.6:1 on white */
  --ink-muted:        #5f6669;          /*  5.9:1 on white, 5.4:1 on muted */
  --ink-faint:        #667074;          /*  5.1:1 on white, 4.7:1 on muted */
  --ink-invert:       #ffffff;
  --ink-invert-body:  rgba(255, 255, 255, 0.76);  /* 9.5:1 on navy */
  --ink-invert-faint: rgba(255, 255, 255, 0.66);  /* 5.2:1 on slate */

  /* -- Lines ---------------------------------------------------------------- */
  --line:          var(--gw-150);
  --line-strong:   var(--gw-200);
  --line-invert:   rgba(255, 255, 255, 0.14);
  --line-accent:   var(--gw-mint);

  /* -- Accents -------------------------------------------------------------- */
  --accent:        var(--gw-mint);
  --accent-deep:   var(--gw-blue);
  --accent-soft:   rgba(145, 198, 196, 0.18);
  --accent-hair:   rgba(145, 198, 196, 0.34);

  /* -- Typography ----------------------------------------------------------- */
  --font-display: "Product Sans", "Neulis", "Arial Rounded MT Bold",
                  "Poppins", "Segoe UI", system-ui, sans-serif;
  --font-heading: "Neulis", "Product Sans", "Poppins",
                  "Segoe UI", system-ui, sans-serif;
  --font-body:    "Poppins", "Neulis", "Segoe UI", system-ui,
                  -apple-system, "Helvetica Neue", Arial, sans-serif;
  --font-label:   "Arial Rounded MT", "Arial Rounded MT Bold", "Product Sans",
                  "Poppins", "Segoe UI", system-ui, sans-serif;

  /* The instrument voice: indices, coordinates, readouts, unit labels. A
     system stack on purpose — it costs nothing to download and reads as a
     technical register distinct from the marketing copy. */
  --font-mono:    ui-monospace, "SF Mono", "Cascadia Mono", "Segoe UI Mono",
                  Menlo, Consolas, "Liberation Mono", monospace;

  /* Editorial scale. Size — not a contrasting serif — is what carries the
     editorial weight, because the brand's families are fixed. */
  --fs-display: clamp(2.35rem, 0.75rem + 6.8vw, 7.2rem);
  --fs-h1:      clamp(2.3rem, 1.3rem + 4vw, 4.6rem);
  --fs-h2:      clamp(1.8rem, 1.16rem + 2.6vw, 3.4rem);
  --fs-h3:      clamp(1.22rem, 1.08rem + 0.6vw, 1.6rem);
  --fs-h4:      clamp(1.05rem, 1rem + 0.25vw, 1.2rem);
  --fs-lead:    clamp(1.05rem, 0.99rem + 0.32vw, 1.28rem);
  --fs-body:    1rem;
  --fs-sm:      0.9rem;
  --fs-xs:      0.8rem;
  --fs-label:   0.72rem;

  --lh-tight:   1.06;
  --lh-snug:    1.22;
  --lh-normal:  1.5;
  --lh-relaxed: 1.72;

  --ls-display: -0.045em;
  --ls-heading: -0.024em;
  --ls-label:   0.16em;
  --ls-mono:    0.08em;

  /* -- Space ---------------------------------------------------------------- */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 3rem;
  --sp-8: 4rem;
  --sp-9: 6rem;

  --section-y:   clamp(4.5rem, 8vw, 8.75rem);
  --section-y-s: clamp(3.25rem, 5.5vw, 5.5rem);
  --gutter:      clamp(1.25rem, 4vw, 4rem);
  --container:   1280px;
  --measure:     68ch;

  /* -- Shape -----------------------------------------------------------------
     Square, everywhere. Rounded corners are the single most template-looking
     thing about a corporate site; precision suits a fuel and marine operator
     far better, and it makes the hairline grid below read as structure. */
  --r-xs: 0;
  --r-sm: 0;
  --r:    0;
  --r-lg: 0;
  --r-pill: 999px;

  /* -- The structural grid ---------------------------------------------------
     Hairline column rules ruled down the whole page, like a chart. */
  --rule:        rgba(1, 36, 66, 0.075);
  --rule-strong: rgba(1, 36, 66, 0.1);
  --rule-invert: rgba(255, 255, 255, 0.07);
  --rule-invert-strong: rgba(255, 255, 255, 0.12);

  /* Restrained on purpose: elevation is carried by rules and space, not glow. */
  --shadow-xs: 0 1px 2px rgba(1, 36, 66, 0.05);
  --shadow-sm: 0 4px 14px -8px rgba(1, 36, 66, 0.20);
  --shadow-md: 0 18px 42px -26px rgba(1, 36, 66, 0.34);

  /* -- Motion --------------------------------------------------------------- */
  --ease-out:  cubic-bezier(0.16, 1, 0.3, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  /* back.out(1.4) from the motion spec, as a cubic-bezier. Used on staggered
     grids only — never on dense informational rows, where overshoot reads
     as sloppy. */
  --ease-back:  cubic-bezier(0.34, 1.46, 0.64, 1);
  --dur-1: 160ms;
  --dur-2: 300ms;
  --dur-3: 620ms;
  --dur-4: 950ms;

  --header-h: 78px;
  /* The header sits ABOVE the mobile panel so its close button stays
     reachable while the panel is open. */
  --z-menu:   100;
  --z-header: 110;
  --z-top:    120;
}

@media (max-width: 900px) {
  :root { --header-h: 66px; }
}


/* ==== 02-base.css ==== */
/* ===========================================================================
   GEOWAVE — reset, typography, links, forms baseline
   =========================================================================== */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 24px);
}

body {
  margin: 0;
  background: var(--surface-page);
  color: var(--ink-body);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-relaxed);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0 0 var(--sp-4);
  color: var(--ink-heading);
  font-family: var(--font-heading);
  font-weight: 700;
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-heading);
  text-wrap: balance;
}

h1 { font-size: var(--fs-h1); line-height: var(--lh-tight); letter-spacing: var(--ls-display); }
h2 { font-size: var(--fs-h2); line-height: 1.14; }
h3 { font-size: var(--fs-h3); }
h4 { font-size: var(--fs-h4); }

p {
  margin: 0 0 var(--sp-4);
  max-width: var(--measure);
  text-wrap: pretty;
}

p:last-child { margin-bottom: 0; }

a {
  color: var(--gw-navy);
  text-decoration: none;
  transition: color var(--dur-1) var(--ease-soft);
}

a:hover { color: var(--gw-blue-alt); }

ul, ol { margin: 0 0 var(--sp-4); padding-left: 1.15rem; }
li { margin-bottom: var(--sp-2); }

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }

/* An <svg> with a viewBox but no width resolves to 100% of its container, so
   the default icon class must carry a size of its own. Everything else that
   renders an icon sizes its own wrapper. */
.gw-icon {
  width: 1.15em;
  height: 1.15em;
  flex: 0 0 auto;
}

strong, b { font-weight: 600; color: var(--gw-navy); }

hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: var(--sp-7) 0;
}

button, input, select, textarea {
  font: inherit;
  color: inherit;
}

::selection {
  background: var(--gw-navy);
  color: #fff;
}

/* -- Focus: always visible, never a default browser ring on a dark band ----- */
:focus-visible {
  outline: 2px solid var(--gw-blue-alt);
  outline-offset: 3px;
  border-radius: var(--r-xs);
}

.gw-dark :focus-visible,
.gw-slate :focus-visible {
  outline-color: var(--gw-mint);
}

/* -- Screen-reader-only + skip link ---------------------------------------- */
.gw-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.gw-skip {
  position: fixed;
  top: 0;
  left: 50%;
  transform: translate(-50%, -120%);
  z-index: var(--z-top);
  padding: 0.75rem 1.5rem;
  background: var(--gw-navy);
  color: #fff;
  font-family: var(--font-label);
  font-size: var(--fs-sm);
  border-radius: 0 0 var(--r) var(--r);
  transition: transform var(--dur-2) var(--ease-out);
}

.gw-skip:focus { transform: translate(-50%, 0); color: #fff; }

/* -- Typographic utilities -------------------------------------------------- */
.gw-display {
  font-family: var(--font-display);
  font-size: var(--fs-display);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-display);
  font-weight: 700;
  color: var(--ink-heading);
  margin: 0;
}

.gw-lead {
  font-size: var(--fs-lead);
  line-height: 1.6;
  color: var(--ink-muted);
  max-width: 58ch;
}

.gw-small { font-size: var(--fs-sm); }

.gw-label {
  font-family: var(--font-label);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-muted);
  line-height: 1.4;
}

/* The technical metadata voice: coordinates, readouts, unit labels. */
.gw-meta {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
}

/* The numbered section index — one of the site's repeating signatures.
   Set as a bracketed monospace stamp, the way a drawing is numbered. */
.gw-index {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin-bottom: var(--sp-5);
}

.gw-index__num {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--ls-mono);
  color: var(--gw-navy);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.gw-index__num::before { content: "["; opacity: 0.4; margin-right: 0.4em; }
.gw-index__num::after  { content: "]"; opacity: 0.4; margin-left: 0.4em; }

.gw-index__line {
  flex: 0 0 auto;
  width: clamp(28px, 5vw, 64px);
  height: 1px;
  background: var(--gw-navy);
  opacity: 0.35;
  transform-origin: left center;
}

.gw-index__label {
  font-family: var(--font-label);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ink-muted);
}

.gw-dark .gw-index__num,
.gw-slate .gw-index__num { color: var(--gw-mint); }
.gw-dark .gw-index__line,
.gw-slate .gw-index__line { background: var(--gw-mint); opacity: 0.55; }
.gw-dark .gw-index__label,
.gw-slate .gw-index__label { color: var(--ink-invert-faint); }

/* -- Dark bands ------------------------------------------------------------- */
.gw-dark,
.gw-slate {
  color: var(--ink-invert-body);
}

.gw-dark { background: var(--surface-dark); }
.gw-slate { background: var(--surface-slate); }

.gw-dark h1, .gw-dark h2, .gw-dark h3, .gw-dark h4,
.gw-slate h1, .gw-slate h2, .gw-slate h3, .gw-slate h4 { color: var(--ink-invert); }

.gw-dark .gw-lead,
.gw-slate .gw-lead { color: var(--ink-invert-body); }

.gw-dark strong,
.gw-slate strong { color: var(--gw-mint); }

.gw-dark a,
.gw-slate a { color: var(--gw-mint-light); }

.gw-dark a:hover,
.gw-slate a:hover { color: #fff; }


/* ==== 03-layout.css ==== */
/* ===========================================================================
   GEOWAVE — layout primitives
   Deliberately few, deliberately composable. Sections alternate between these
   so the page never reads as one repeated grid.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   The structural grid — the site's signature device.

   A fixed set of hairline column rules ruled down the full height of the
   viewport, behind everything, like the ruling on a nautical chart or an
   engineering drawing. It costs one element, no JavaScript and no repaint on
   scroll, and it is what makes the page read as one measured system rather
   than a stack of unrelated blocks.

   The columns align to the same container the content uses, so section edges
   and rules agree. On dark bands the rules invert automatically.
   --------------------------------------------------------------------------- */
.gw-rules {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  display: flex;
  justify-content: center;
}

.gw-rules__inner {
  width: 100%;
  max-width: var(--container);
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

@media (min-width: 900px) {
  .gw-rules__inner { grid-template-columns: repeat(12, 1fr); }
}

.gw-rules__inner span {
  border-left: 1px solid var(--rule);
}

/* Sections sit above the ruling; dark bands paint over it and redraw their
   own inverted rules through the ::before below. */
.gw-section,
.gw-hero,
.gw-pagehero,
.gw-stats,
.gw-footer,
.gw-cta,
.gw-error { position: relative; z-index: 1; }

.gw-shell {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.gw-shell--wide { max-width: 1520px; }
.gw-shell--narrow { max-width: 920px; }

.gw-section {
  position: relative;
  padding-block: var(--section-y);
}

/* A dark band is opaque, so it hides the page ruling. It redraws its own in
   white, and — this is the fiddly part — at exactly the same column positions,
   or the grid visibly jumps at every light/dark boundary.

   Sizing the pseudo-element to the container and clipping the gradient to its
   content box makes `calc(100% / 12)` resolve against the same width the fixed
   ruling divides, so the two agree at any viewport. */
.gw-dark::before,
.gw-slate::before,
.gw-stats::before,
.gw-cta::before,
.gw-bunker::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(100%, var(--container));
  padding-inline: var(--gutter);
  box-sizing: border-box;
  z-index: 0;
  pointer-events: none;
  background-image: repeating-linear-gradient(
    to right,
    var(--rule-invert) 0 1px,
    transparent 1px calc(100% / var(--rule-cols, 12))
  );
  background-origin: content-box;
  background-clip: content-box;
  background-repeat: repeat-y;
}

.gw-dark > *,
.gw-slate > *,
.gw-stats > *,
.gw-cta > *,
.gw-bunker > * { position: relative; z-index: 1; }

/* The fixed ruling drops to 4 columns below 900px; the dark bands follow. */
@media (max-width: 899px) {
  .gw-dark::before,
  .gw-slate::before,
  .gw-stats::before,
  .gw-cta::before,
  .gw-bunker::before { --rule-cols: 4; }
}

.gw-section--tight { padding-block: var(--section-y-s); }
.gw-section--flush-top { padding-top: 0; }
.gw-section--flush-bottom { padding-bottom: 0; }

/* Section head: index rail on the left, heading + lead beside it. */
.gw-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-4);
  margin-bottom: clamp(2.5rem, 5vw, 4.25rem);
}

/* The head's columns are a variable so a section can align them to whatever
   split its own content uses. When the head splits 1.05/0.95 and the content
   below splits 0.85/1.15, the two right-hand columns start at different x
   positions and the whole section reads as assembled rather than designed. */
.gw-head--split {
  grid-template-columns: var(--head-cols, minmax(0, 1.05fr) minmax(0, 0.95fr));
  gap: var(--head-gap, clamp(1.5rem, 5vw, 5rem));
  align-items: end;
}

.gw-head__title { margin: 0; }
.gw-head__aside { padding-bottom: 0.35rem; }

/* On long list sections the head holds while its content scrolls past, which
   keeps the reader oriented without a second navigation element. */
@media (min-width: 1000px) {
  .gw-head--sticky {
    position: sticky;
    top: calc(var(--header-h) + 2.5rem);
    z-index: 2;
  }
}

/* Asymmetric split — the site's workhorse content layout. */
.gw-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}

@media (min-width: 900px) {
  .gw-split { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  .gw-split--even { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .gw-split--wide-left { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
  .gw-split--center { align-items: center; }
  .gw-split--reverse > :first-child { order: 2; }
}

.gw-stack > * + * { margin-top: var(--sp-4); }
.gw-stack--lg > * + * { margin-top: var(--sp-6); }
.gw-stack--sm > * + * { margin-top: var(--sp-2); }

.gw-grid {
  display: grid;
  gap: clamp(1.25rem, 2.5vw, 2rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}

.gw-grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); }
.gw-grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr)); }

.gw-flow > * + * { margin-top: var(--sp-5); }

.gw-prose p { color: var(--ink-body); }
.gw-prose p + p { margin-top: var(--sp-4); }
.gw-prose--lead p:first-child {
  font-size: var(--fs-lead);
  line-height: 1.62;
  color: var(--ink-heading);
}

/* Alternating surfaces keep long pages from flattening out.

   Light bands are TRANSLUCENT rather than opaque: the page ground shows
   through, and with it the fixed chart ruling behind everything. An opaque
   white here would paint the grid out completely. Dark bands stay opaque and
   redraw their own rules above. */
.gw-surface { background: transparent; }
.gw-surface--muted { background: rgba(1, 36, 66, 0.035); }
.gw-surface--sunken { background: rgba(1, 36, 66, 0.05); }

.gw-bordered-top { border-top: 1px solid var(--line); }
.gw-bordered-bottom { border-bottom: 1px solid var(--line); }

.gw-center { text-align: center; }
.gw-center .gw-lead,
.gw-center p { margin-inline: auto; }
.gw-center .gw-index { justify-content: center; }


/* ==== 04-components.css ==== */
/* ===========================================================================
   GEOWAVE — components
   =========================================================================== */

/* ---------------------------------------------------------------------------
   Buttons
   Square-ish, architectural. Hover is a mint bar that wipes in from the left
   rather than a colour flash — movement, in keeping with the brand.
   --------------------------------------------------------------------------- */
.gw-btn {
  --btn-bg: var(--gw-navy);
  --btn-ink: #fff;
  --btn-line: var(--gw-navy);

  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.95rem 1.6rem;
  border: 1px solid var(--btn-line);
  border-radius: var(--r-sm);
  background: var(--btn-bg);
  color: var(--btn-ink);
  font-family: var(--font-label);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.03em;
  line-height: 1;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: color var(--dur-2) var(--ease-soft),
              border-color var(--dur-2) var(--ease-soft),
              transform var(--dur-2) var(--ease-out);
}

.gw-btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--gw-mint);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-3) var(--ease-out);
}

.gw-btn:hover,
.gw-btn:focus-visible {
  color: var(--gw-navy);
  border-color: var(--gw-mint);
}

.gw-btn:hover::before,
.gw-btn:focus-visible::before { transform: scaleX(1); }

.gw-btn:active { transform: translateY(1px); }

.gw-btn__arrow {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  transition: transform var(--dur-2) var(--ease-out);
}

.gw-btn:hover .gw-btn__arrow { transform: translateX(4px); }

.gw-btn--ghost {
  --btn-bg: transparent;
  --btn-ink: var(--gw-navy);
  --btn-line: var(--line-strong);
}

.gw-btn--light {
  --btn-bg: transparent;
  --btn-ink: #fff;
  --btn-line: rgba(255, 255, 255, 0.32);
}

.gw-btn--mint {
  --btn-bg: var(--gw-mint);
  --btn-ink: var(--gw-navy);
  --btn-line: var(--gw-mint);
}

.gw-btn--mint::before { background: #fff; }

.gw-btn--sm { padding: 0.7rem 1.15rem; font-size: var(--fs-xs); }
.gw-btn--block { width: 100%; justify-content: center; }

/* Text link with a rule that grows on hover. */
.gw-link {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-label);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--gw-navy);
  padding-bottom: 4px;
  background-image: linear-gradient(var(--gw-mint), var(--gw-mint));
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: 0% 2px;
  transition: background-size var(--dur-3) var(--ease-out), color var(--dur-1) var(--ease-soft);
}

.gw-link:hover,
.gw-link:focus-visible { background-size: 100% 2px; }

.gw-dark .gw-link,
.gw-slate .gw-link { color: #fff; }

/* ---------------------------------------------------------------------------
   Brand wave pattern
   7–8 parallel sine lines, uniform stroke and spacing, anchored to the TOP of
   a section and hanging down over the upper portion only — as specified.
   --------------------------------------------------------------------------- */
.gw-wave {
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: clamp(74px, 9vw, 132px);
  pointer-events: none;
  overflow: hidden;
  z-index: 0;
  /* Fades out well before the content, so the pattern reads as a border
     hanging from the top edge rather than a background texture. */
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 38%, transparent 92%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 38%, transparent 92%);
}

.gw-wave svg {
  width: 200%;
  height: 100%;
  display: block;
}

.gw-wave__lines {
  fill: none;
  stroke: var(--gw-mint);
  stroke-width: 1.6;
  stroke-opacity: 0.22;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

/* On light grounds the lines step down to navy at a lower opacity so the
   pattern stays an accent rather than a texture. */
.gw-wave--ink .gw-wave__lines {
  stroke: var(--gw-navy);
  stroke-opacity: 0.12;
}

.gw-wave--strong .gw-wave__lines { stroke-opacity: 0.32; }

.gw-wave--bottom {
  top: auto;
  bottom: 0;
  transform: scaleY(-1);
}

.gw-wave--drift svg {
  animation: gw-wave-drift 26s linear infinite;
}

@keyframes gw-wave-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* A single hairline wave used as a divider between light sections. */
.gw-divider {
  position: relative;
  height: 1px;
  background: var(--line);
  overflow: visible;
}

.gw-divider::after {
  content: "";
  position: absolute;
  left: 0;
  top: -1px;
  width: clamp(60px, 12vw, 160px);
  height: 3px;
  background: var(--gw-mint);
}

/* ---------------------------------------------------------------------------
   Header + navigation
   --------------------------------------------------------------------------- */
.gw-header {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: var(--z-header);
  height: var(--header-h);
  display: flex;
  align-items: center;
  transition: background-color var(--dur-2) var(--ease-soft),
              border-color var(--dur-2) var(--ease-soft),
              transform var(--dur-3) var(--ease-out),
              backdrop-filter var(--dur-2) var(--ease-soft);
  border-bottom: 1px solid transparent;
}

.gw-header__inner {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
}

/* The header carries the white GEOWAVE wordmark in every state, so its marks
   are white throughout and the bar is never light behind them. Over the hero
   it is transparent; once scrolled it becomes a translucent navy bar. */
.gw-header { color: #fff; }
.gw-header .gw-nav__link { color: rgba(255, 255, 255, 0.82); }
.gw-header .gw-nav__link:hover,
.gw-header .gw-nav__link[aria-current="page"] { color: #fff; }
.gw-header .gw-burger span { background: #fff; }

.gw-header--pinned {
  background: rgba(1, 36, 66, 0.92);
  border-bottom-color: rgba(255, 255, 255, 0.14);
  backdrop-filter: saturate(160%) blur(12px);
  -webkit-backdrop-filter: saturate(160%) blur(12px);
}

/* Hides on scroll-down, returns on scroll-up. */
.gw-header--hidden { transform: translateY(-100%); }

.gw-logo {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  color: #fff;
  flex: 0 0 auto;
}

.gw-logo svg {
  width: auto;
  height: clamp(26px, 3.2vw, 32px);
  fill: currentColor;
  transition: opacity var(--dur-2) var(--ease-soft);
}

.gw-logo:hover svg { opacity: 0.78; }

.gw-nav {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.2vw, 2.1rem);
}

.gw-nav__link {
  position: relative;
  font-family: var(--font-label);
  font-size: 0.83rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--ink-muted);
  padding-block: 0.4rem;
  transition: color var(--dur-1) var(--ease-soft);
}

.gw-nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background: var(--gw-mint);
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform var(--dur-2) var(--ease-out);
}

.gw-nav__link:hover::after,
.gw-nav__link[aria-current="page"]::after {
  transform: scaleX(1);
  transform-origin: left center;
}

.gw-header__actions { display: flex; align-items: center; gap: var(--sp-4); }

.gw-header__phone {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-label);
  font-size: 0.83rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: inherit;
}

.gw-header__phone svg { width: 15px; height: 15px; opacity: 0.7; }

/* Burger */
.gw-burger {
  display: none;
  position: relative;
  width: 44px;
  height: 44px;
  border: 0;
  background: none;
  cursor: pointer;
  padding: 0;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.gw-burger span {
  display: block;
  width: 24px;
  height: 2px;
  background: var(--gw-navy);
  border-radius: 2px;
  transition: transform var(--dur-2) var(--ease-out),
              opacity var(--dur-1) var(--ease-soft),
              width var(--dur-2) var(--ease-out);
}

.gw-burger span:last-child { width: 16px; }

.gw-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.gw-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.gw-burger[aria-expanded="true"] span:nth-child(3) { width: 24px; transform: translateY(-8px) rotate(-45deg); }

/* ---------------------------------------------------------------------------
   Mobile menu — a full-screen navy panel with staggered item entrances.
   --------------------------------------------------------------------------- */
.gw-menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-menu);
  background: var(--gw-navy);
  display: flex;
  flex-direction: column;
  padding: calc(var(--header-h) + 1.5rem) var(--gutter) 2rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  clip-path: inset(0 0 100% 0);
  visibility: hidden;
  transition: clip-path var(--dur-3) var(--ease-out), visibility 0s linear var(--dur-3);
}

.gw-menu.is-open {
  clip-path: inset(0 0 0 0);
  visibility: visible;
  transition: clip-path var(--dur-3) var(--ease-out), visibility 0s;
}

.gw-menu__list {
  list-style: none;
  margin: 0 0 auto;
  padding: 0;
  border-top: 1px solid var(--line-invert);
}

.gw-menu__item {
  margin: 0;
  border-bottom: 1px solid var(--line-invert);
  opacity: 0;
  transform: translateY(18px);
}

.gw-menu.is-open .gw-menu__item {
  animation: gw-menu-in var(--dur-3) var(--ease-out) forwards;
  animation-delay: calc(var(--i, 0) * 55ms + 90ms);
}

@keyframes gw-menu-in {
  to { opacity: 1; transform: translateY(0); }
}

.gw-menu__link {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding: 1.05rem 0;
  color: #fff;
  font-family: var(--font-heading);
  font-size: clamp(1.5rem, 7vw, 2.1rem);
  font-weight: 600;
  letter-spacing: var(--ls-heading);
  line-height: 1.15;
  transition: color var(--dur-1) var(--ease-soft), padding-left var(--dur-2) var(--ease-out);
}

.gw-menu__link:hover,
.gw-menu__link[aria-current="page"] { color: var(--gw-mint); padding-left: 0.5rem; }

.gw-menu__num {
  font-family: var(--font-label);
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  color: var(--gw-mint);
  opacity: 0.9;
}

.gw-menu__foot {
  margin-top: 2.5rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--line-invert);
  color: var(--ink-invert-body);
  font-size: var(--fs-sm);
}

.gw-menu__foot a { color: #fff; }

body.gw-menu-open { overflow: hidden; }

/* While the panel is open the header drops its own bar and sits directly on
   the navy, keeping only the white logo and close button. It must never slide
   away mid-interaction. */
body.gw-menu-open .gw-header {
  background: transparent;
  border-bottom-color: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  transform: none;
}

/* ---------------------------------------------------------------------------
   Cards and panels — used sparingly, and never as the only layout on a page.
   --------------------------------------------------------------------------- */
.gw-panel {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  transition: border-color var(--dur-2) var(--ease-soft),
              transform var(--dur-3) var(--ease-out),
              box-shadow var(--dur-3) var(--ease-out);
}

.gw-panel--hover:hover {
  border-color: var(--gw-mint);
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
}

.gw-panel__icon {
  width: 42px;
  height: 42px;
  margin-bottom: var(--sp-5);
  color: var(--gw-navy);
}

.gw-panel__icon svg { width: 100%; height: 100%; }

.gw-panel h3 { margin-bottom: var(--sp-3); }
.gw-panel p { font-size: var(--fs-sm); color: var(--ink-muted); }

/* ---------------------------------------------------------------------------
   Feature list with a mint tick rule
   --------------------------------------------------------------------------- */
.gw-ticks {
  list-style: none;
  margin: 0;
  padding: 0;
}

.gw-ticks li {
  position: relative;
  padding-left: 1.7rem;
  margin-bottom: 0.7rem;
  font-size: var(--fs-sm);
  line-height: 1.6;
}

.gw-ticks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 10px;
  height: 1px;
  background: var(--gw-mint);
}

.gw-ticks li::after {
  content: "";
  position: absolute;
  left: 0;
  top: calc(0.62em - 2px);
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--gw-navy);
}

.gw-dark .gw-ticks li::after,
.gw-slate .gw-ticks li::after { background: var(--gw-mint); }

/* ---------------------------------------------------------------------------
   Forms
   --------------------------------------------------------------------------- */
.gw-field { position: relative; margin-bottom: var(--sp-5); }

.gw-field__label {
  display: block;
  margin-bottom: 0.5rem;
  font-family: var(--font-label);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.gw-field__req { color: var(--gw-blue-alt); }

.gw-input,
.gw-textarea,
.gw-select {
  width: 100%;
  padding: 0.9rem 1rem;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  color: var(--ink-heading);
  font-size: var(--fs-body);
  line-height: 1.5;
  transition: border-color var(--dur-1) var(--ease-soft),
              box-shadow var(--dur-1) var(--ease-soft);
}

.gw-textarea { min-height: 150px; resize: vertical; }

.gw-select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23012442' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 12px 8px;
  padding-right: 2.6rem;
}

.gw-input:focus,
.gw-textarea:focus,
.gw-select:focus {
  outline: none;
  border-color: var(--gw-navy);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.gw-input::placeholder,
.gw-textarea::placeholder { color: var(--ink-faint); }

.gw-field--error .gw-input,
.gw-field--error .gw-textarea,
.gw-field--error .gw-select { border-color: #b3402f; }

.gw-field__error {
  display: block;
  margin-top: 0.4rem;
  font-size: var(--fs-xs);
  color: #b3402f;
}

.gw-honey {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.gw-alert {
  padding: 1.1rem 1.35rem;
  border-radius: var(--r-sm);
  border: 1px solid;
  margin-bottom: var(--sp-5);
  font-size: var(--fs-sm);
}

.gw-alert--ok {
  background: var(--accent-soft);
  border-color: var(--gw-mint);
  color: var(--gw-navy);
}

.gw-alert--bad {
  background: #fdf1ef;
  border-color: #e6bdb5;
  color: #8e3325;
}

/* ---------------------------------------------------------------------------
   Footer
   --------------------------------------------------------------------------- */
.gw-footer {
  position: relative;
  background: var(--gw-navy);
  color: var(--ink-invert-body);
  padding-top: clamp(5rem, 9vw, 7.5rem);
  overflow: hidden;
}

.gw-footer__grid {
  position: relative;
  z-index: 1;
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  grid-template-columns: minmax(0, 1fr);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}

@media (min-width: 780px) {
  .gw-footer__grid { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr); }
}

@media (min-width: 1080px) {
  .gw-footer__grid { grid-template-columns: minmax(0, 1.7fr) repeat(3, minmax(0, 1fr)); }
}

/* Rendered at label size, but marked up as h2 so the document outline does not
   skip a level between the page sections and the footer. */
.gw-footer__heading {
  font-family: var(--font-label);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--gw-mint);
  margin-bottom: var(--sp-5);
}

.gw-footer__list { list-style: none; margin: 0; padding: 0; }
.gw-footer__list li { margin-bottom: 0.65rem; font-size: var(--fs-sm); }
.gw-footer__list a { color: var(--ink-invert-body); }
.gw-footer__list a:hover { color: #fff; }

.gw-footer__logo { color: #fff; display: block; margin-bottom: var(--sp-5); }
.gw-footer__logo svg { height: 34px; width: auto; fill: currentColor; }

.gw-footer address {
  font-style: normal;
  font-size: var(--fs-sm);
  line-height: 1.85;
}

.gw-footer__bar {
  position: relative;
  z-index: 1;
  border-top: 1px solid var(--line-invert);
  padding-block: 1.6rem;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  align-items: center;
  justify-content: space-between;
  font-size: var(--fs-xs);
  color: var(--ink-invert-faint);
}

.gw-social {
  display: flex;
  gap: 0.6rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.gw-social li { margin: 0; }

.gw-social a {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line-invert);
  border-radius: var(--r-sm);
  color: var(--ink-invert-body);
  transition: background-color var(--dur-2) var(--ease-soft),
              color var(--dur-2) var(--ease-soft),
              border-color var(--dur-2) var(--ease-soft),
              transform var(--dur-2) var(--ease-out);
}

.gw-social a:hover {
  background: var(--gw-mint);
  border-color: var(--gw-mint);
  color: var(--gw-navy);
  transform: translateY(-3px);
}

.gw-social svg { width: 17px; height: 17px; }

/* Small "info pending" flag used where the brief left a value blank. */
.gw-pending {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-family: var(--font-label);
  font-size: var(--fs-xs);
  letter-spacing: 0.05em;
  color: var(--ink-faint);
  font-style: italic;
}

.gw-dark .gw-pending,
.gw-slate .gw-pending { color: var(--ink-invert-faint); }

/* ---------------------------------------------------------------------------
   Corner registration ticks
   The small L-marks a technical drawing carries at the corners of a plate.
   Applied to panels and figures; drawn with two gradients, so no extra
   elements and nothing to keep in sync.
   --------------------------------------------------------------------------- */
.gw-ticked {
  position: relative;
}

.gw-ticked::before,
.gw-ticked::after {
  content: "";
  position: absolute;
  width: 13px;
  height: 13px;
  pointer-events: none;
  border-color: var(--gw-mint);
  border-style: solid;
  /* Visible at rest, not hover-only: a decoration nobody on a touch device
     ever sees is dead weight. Hover simply brings it up. */
  opacity: 0.5;
  transition: opacity var(--dur-2) var(--ease-soft);
}

.gw-ticked::before {
  top: -1px;
  left: -1px;
  border-width: 1px 0 0 1px;
}

.gw-ticked::after {
  right: -1px;
  bottom: -1px;
  border-width: 0 1px 1px 0;
}

.gw-ticked:hover::before,
.gw-ticked:hover::after,
.gw-ticked:focus-within::before,
.gw-ticked:focus-within::after { opacity: 1; }

/* Emphasised variant for figures, which have no hover state of their own. */
.gw-ticked--static::before,
.gw-ticked--static::after { opacity: 1; }

/* ---------------------------------------------------------------------------
   Capability ticker
   A running strip of capability statements between bands — a port information
   board, not a data feed. It carries no telemetry and claims none.

   Built from first principles: the motion database has no marquee preset. Two
   identical tracks sit side by side and the pair translates by exactly one
   track width, so the loop is seamless at any content length. Because it is a
   single transform on a composited element it costs nothing per frame.

   It pauses on hover and on keyboard focus, and stops dead (showing a static
   final state) under prefers-reduced-motion — the pattern's own requirement
   for any ticker.
   --------------------------------------------------------------------------- */
.gw-ticker {
  position: relative;
  overflow: hidden;
  padding-block: clamp(1.1rem, 2.2vw, 1.75rem);
  background: var(--gw-navy);
  border-block: 1px solid var(--rule-invert-strong);
  user-select: none;
}

.gw-ticker--mint {
  background: var(--gw-mint);
  border-color: rgba(1, 36, 66, 0.16);
}

.gw-ticker__track {
  display: flex;
  width: max-content;
  animation: gw-ticker 46s linear infinite;
}

.gw-ticker:hover .gw-ticker__track,
.gw-ticker:focus-within .gw-ticker__track { animation-play-state: paused; }

@keyframes gw-ticker {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

.gw-ticker__group {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  list-style: none;
  margin: 0;
  padding: 0;
}

.gw-ticker__item {
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: clamp(1.25rem, 3vw, 2.75rem);
  padding-inline: clamp(1.25rem, 3vw, 2.75rem);
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 2.4vw, 1.9rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  white-space: nowrap;
  color: #fff;
}

.gw-ticker--mint .gw-ticker__item { color: var(--gw-navy); }

/* The separator is the brand mark's ring, reduced to a dot. */
.gw-ticker__item::after {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--gw-mint);
  flex: 0 0 auto;
}

.gw-ticker--mint .gw-ticker__item::after { background: var(--gw-navy); }

@media (prefers-reduced-motion: reduce) {
  .gw-ticker__track { animation: none; }
  /* Without motion the strip is just a row that runs off the edge, so it
     scrolls by hand instead. */
  .gw-ticker { overflow-x: auto; }
  .gw-ticker__group + .gw-ticker__group { display: none; }
}


/* ==== 05-sections.css ==== */
/* ===========================================================================
   GEOWAVE — page sections
   Each section gets its own layout so the page reads as a sequence of rooms,
   not a stack of identical cards.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   1. Hero
   --------------------------------------------------------------------------- */
.gw-hero {
  position: relative;
  min-height: min(100svh, 940px);
  display: flex;
  flex-direction: column;
  background: var(--gw-navy);
  color: #fff;
  overflow: hidden;
  isolation: isolate;
}

/* The stage holds everything above the quick-access bar. Making it the
   containing block means the ocean scene's waterline lands exactly on the top
   edge of that bar instead of disappearing behind it. */
.gw-hero__stage {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  align-items: flex-end;
  padding-top: calc(var(--header-h) + clamp(3rem, 9vh, 7rem));
}

/* Deep-sea vertical grade: navy at the top, brand slate at the waterline. */
.gw-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background: linear-gradient(180deg, var(--gw-navy) 0%, var(--gw-navy) 42%, var(--gw-slate) 100%);
}

.gw-hero__scene {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  z-index: -1;
  height: min(52%, 440px);
  pointer-events: none;
}

.gw-hero__scene svg { width: 100%; height: 100%; }

/* The brand ring, oversized and faint, filling the space beside the headline.
   It echoes the "O" of the wordmark rather than being a generic blob. */
.gw-hero__mark {
  position: absolute;
  top: 14%;
  right: clamp(-8rem, -4vw, -2rem);
  width: min(46vw, 560px);
  aspect-ratio: 1;
  z-index: -1;
  pointer-events: none;
  color: var(--gw-mint);
  opacity: 0.13;
}

.gw-hero__mark svg { width: 100%; height: 100%; }

@media (max-width: 900px) {
  .gw-hero__mark { top: auto; bottom: 32%; right: -18%; width: 72vw; opacity: 0.09; }
}

.gw-hero__body {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  padding-bottom: clamp(3rem, 6vw, 5rem);
}

.gw-hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
  font-family: var(--font-label);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--gw-mint);
}

.gw-hero__eyebrow::before {
  content: "";
  width: clamp(28px, 4vw, 54px);
  height: 1px;
  background: var(--gw-mint);
}

.gw-hero__title {
  font-family: var(--font-display);
  font-size: var(--fs-display);
  line-height: 0.98;
  letter-spacing: -0.03em;
  font-weight: 700;
  color: #fff;
  margin: 0 0 clamp(1.25rem, 2.5vw, 1.9rem);
  max-width: 17ch;
}

.gw-hero__title em {
  font-style: normal;
  color: var(--gw-mint);
}

.gw-hero__text {
  font-size: var(--fs-lead);
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.8);
  max-width: 52ch;
  margin-bottom: clamp(1.75rem, 3.5vw, 2.6rem);
}

.gw-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  align-items: center;
}

/* Quick access to the important services, sitting on the hero's lower edge. */
.gw-hero__quick {
  position: relative;
  z-index: 1;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(1, 20, 38, 0.34);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

.gw-hero__quick-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  list-style: none;
  margin-block: 0;
  padding-block: 0;
}

@media (min-width: 860px) {
  .gw-hero__quick-list { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.gw-hero__quick-list li {
  margin: 0;
  border-left: 1px solid rgba(255, 255, 255, 0.13);
}

.gw-hero__quick-list li:first-child { border-left: 0; }

@media (max-width: 859px) {
  .gw-hero__quick-list li:nth-child(odd) { border-left: 0; }
  .gw-hero__quick-list li:nth-child(n + 3) { border-top: 1px solid rgba(255, 255, 255, 0.13); }
}

.gw-quick {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: clamp(1rem, 2.2vw, 1.6rem) clamp(0.75rem, 1.8vw, 1.5rem);
  height: 100%;
  color: #fff;
  transition: background-color var(--dur-2) var(--ease-soft);
}

.gw-quick:hover { background: rgba(145, 198, 196, 0.12); color: #fff; }

.gw-quick__num {
  font-family: var(--font-label);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  color: var(--gw-mint);
}

.gw-quick__label {
  font-family: var(--font-heading);
  font-size: clamp(0.92rem, 1.4vw, 1.05rem);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.gw-quick__arrow {
  width: 14px;
  height: 14px;
  margin-top: 0.15rem;
  color: var(--gw-mint);
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity var(--dur-2) var(--ease-soft), transform var(--dur-2) var(--ease-out);
}

.gw-quick:hover .gw-quick__arrow { opacity: 1; transform: translateX(0); }

.gw-hero__cue {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 1.5rem);
  transform: translateX(-50%);
  width: 1px;
  height: clamp(32px, 5vh, 56px);
  background: rgba(255, 255, 255, 0.22);
  overflow: hidden;
}

.gw-hero__cue::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 40%;
  background: var(--gw-mint);
  animation: gw-cue 2.4s var(--ease-in-out) infinite;
}

@keyframes gw-cue {
  0%   { transform: translateY(-100%); }
  60%  { transform: translateY(250%); }
  100% { transform: translateY(250%); }
}

/* ---------------------------------------------------------------------------
   2. Page hero (inner pages) — lighter, shorter, still branded.
   --------------------------------------------------------------------------- */
.gw-pagehero {
  position: relative;
  padding-top: calc(var(--header-h) + clamp(4rem, 9vw, 7rem));
  padding-bottom: clamp(3rem, 6vw, 5.5rem);
  background: var(--gw-navy);
  color: #fff;
  overflow: hidden;
  isolation: isolate;
}

.gw-pagehero::after {
  content: "";
  position: absolute;
  right: -12%;
  bottom: -55%;
  width: min(58vw, 620px);
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1px solid rgba(145, 198, 196, 0.16);
  z-index: -1;
}

.gw-pagehero__inner { position: relative; z-index: 1; }

.gw-pagehero h1 {
  color: #fff;
  max-width: 20ch;
  margin-bottom: var(--sp-5);
}

.gw-pagehero p {
  color: rgba(255, 255, 255, 0.76);
  font-size: var(--fs-lead);
  max-width: 56ch;
}

.gw-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  list-style: none;
  margin: 0 0 var(--sp-5);
  padding: 0;
  font-family: var(--font-label);
  font-size: var(--fs-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.66);
}

.gw-breadcrumb li { margin: 0; }
.gw-breadcrumb a { color: var(--gw-mint); }
.gw-breadcrumb li + li::before { content: "/"; margin-right: 0.6rem; opacity: 0.5; }

/* ---------------------------------------------------------------------------
   3. Capability index — the list/preview pattern used for services.
   --------------------------------------------------------------------------- */
/* Head and content share one split, so their right-hand columns start on the
   same line. */
.gw-capability-section {
  --head-cols: minmax(0, 0.85fr) minmax(0, 1.15fr);
  --head-gap: clamp(2rem, 5vw, 5rem);
}

.gw-capability { position: relative; }

@media (min-width: 1000px) {
  .gw-capability__grid {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: clamp(2rem, 5vw, 5rem);
    align-items: start;
  }
}

.gw-capability__preview {
  display: none;
  position: sticky;
  top: calc(var(--header-h) + 3rem);
  aspect-ratio: 4 / 5;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  overflow: hidden;
}

@media (min-width: 1000px) {
  .gw-capability__preview { display: block; }
}

.gw-capability__figure {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: scale(1.04);
  transition: opacity var(--dur-3) var(--ease-soft), transform var(--dur-4) var(--ease-out);
}

.gw-capability__figure.is-active { opacity: 1; transform: scale(1); }

.gw-capability__figure svg { width: 100%; height: 100%; }

.gw-capability__caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 1.5rem;
  background: linear-gradient(180deg, transparent, rgba(1, 36, 66, 0.92));
  color: #fff;
}

.gw-capability__caption strong {
  display: block;
  color: #fff;
  font-family: var(--font-heading);
  font-size: var(--fs-h4);
  margin-bottom: 0.25rem;
}

.gw-capability__caption span {
  font-size: var(--fs-sm);
  color: rgba(255, 255, 255, 0.75);
}

.gw-capability__list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--line);
}

.gw-capability__item {
  margin: 0;
  border-bottom: 1px solid var(--line);
}

.gw-capability__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: baseline;
  gap: clamp(0.85rem, 2vw, 1.6rem);
  width: 100%;
  padding: clamp(1.25rem, 2.6vw, 1.85rem) 0;
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  color: inherit;
  transition: padding-left var(--dur-3) var(--ease-out);
}

.gw-capability__item:hover .gw-capability__row,
.gw-capability__item.is-active .gw-capability__row { padding-left: clamp(0.5rem, 1.4vw, 1.1rem); }

.gw-capability__num {
  font-family: var(--font-label);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  transition: color var(--dur-2) var(--ease-soft);
}

.gw-capability__item:hover .gw-capability__num,
.gw-capability__item.is-active .gw-capability__num { color: var(--gw-navy); }

.gw-capability__title {
  font-family: var(--font-heading);
  font-size: clamp(1.15rem, 2.1vw, 1.55rem);
  font-weight: 600;
  letter-spacing: var(--ls-heading);
  color: var(--ink-heading);
  line-height: 1.25;
  margin: 0;
}

.gw-capability__tag {
  display: block;
  margin-top: 0.3rem;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 400;
  color: var(--ink-muted);
  letter-spacing: 0;
}

.gw-capability__plus {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  color: var(--gw-navy);
  opacity: 0.4;
  transition: opacity var(--dur-2) var(--ease-soft), transform var(--dur-3) var(--ease-out);
}

.gw-capability__item.is-active .gw-capability__plus { opacity: 1; transform: rotate(45deg); }

.gw-capability__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-3) var(--ease-out);
}

.gw-capability__item.is-active .gw-capability__panel { grid-template-rows: 1fr; }

.gw-capability__panel > div { overflow: hidden; }

.gw-capability__content {
  padding: 0 0 clamp(1.5rem, 3vw, 2rem);
  max-width: 62ch;
}

.gw-capability__content p { font-size: var(--fs-sm); margin-bottom: var(--sp-4); }

.gw-capability__mobile-figure {
  margin-bottom: var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  overflow: hidden;
  aspect-ratio: 16 / 9;
}

@media (min-width: 1000px) { .gw-capability__mobile-figure { display: none; } }

.gw-capability__mobile-figure svg { width: 100%; height: 100%; }

/* ---------------------------------------------------------------------------
   4. Statistics band
   --------------------------------------------------------------------------- */
.gw-stats {
  position: relative;
  background: var(--gw-slate);
  color: #fff;
  overflow: hidden;
  padding-block: clamp(6.5rem, 11vw, 10rem) clamp(3.5rem, 6vw, 5.5rem);
}

.gw-stats__grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.14);
}

@media (min-width: 900px) {
  .gw-stats__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.gw-stat {
  background: var(--gw-slate);
  padding: clamp(1.5rem, 3vw, 2.4rem);
}

/* Read as an instrument panel: the figure oversized and tabular, its label
   stamped above it in the technical voice, a hairline rule between. */
.gw-stat__value {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.9rem, 7vw, 5rem);
  font-weight: 700;
  line-height: 0.92;
  letter-spacing: -0.045em;
  color: #fff;
  font-variant-numeric: tabular-nums;
  margin-bottom: 0;
  order: 2;
  padding-block: 0.5rem 0.9rem;
}

.gw-stat {
  display: flex;
  flex-direction: column;
}

.gw-stat__label {
  display: block;
  order: 1;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  color: var(--gw-mint);
  padding-bottom: 0.9rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
}

.gw-stat__caption {
  order: 3;
  font-size: var(--fs-xs);
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.7);
  margin: 0;
}

/* ---------------------------------------------------------------------------
   5. Products — editorial rows, not cards.
   --------------------------------------------------------------------------- */
.gw-products { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }

.gw-product {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-4);
  padding-block: clamp(1.75rem, 3.5vw, 2.75rem);
  border-bottom: 1px solid var(--line);
  margin: 0;
  transition: background-color var(--dur-2) var(--ease-soft);
}

@media (min-width: 820px) {
  .gw-product {
    grid-template-columns: 56px minmax(0, 4fr) minmax(0, 5fr);
    gap: clamp(1.5rem, 3vw, 3rem);
    align-items: start;
  }
}

.gw-product:hover { background: var(--surface); }

.gw-product__icon {
  width: 44px;
  height: 44px;
  color: var(--gw-navy);
}

.gw-product__icon svg { width: 100%; height: 100%; }

.gw-product__name {
  font-family: var(--font-heading);
  font-size: clamp(1.3rem, 2.4vw, 1.8rem);
  font-weight: 600;
  letter-spacing: var(--ls-heading);
  color: var(--ink-heading);
  margin: 0 0 var(--sp-2);
}

.gw-product__summary { font-size: var(--fs-sm); color: var(--ink-muted); margin: 0; }

.gw-product__meta {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 560px) {
  .gw-product__meta { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.gw-product__meta dt {
  font-family: var(--font-label);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.4rem;
}

.gw-product__meta dd {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--ink-body);
  padding-left: 0.9rem;
  border-left: 2px solid var(--gw-mint);
}

/* ---------------------------------------------------------------------------
   6. Bunkering — dark maritime band with a numbered process ladder.
   --------------------------------------------------------------------------- */
.gw-bunker {
  position: relative;
  background: var(--gw-navy);
  color: var(--ink-invert-body);
  overflow: hidden;
  isolation: isolate;
}

/* The illustration is a 4:5 portrait. Stretched full-bleed across a wide band
   it cropped to a fragment and blew that fragment up until it competed with
   the copy, so it is held to its own aspect ratio, anchored bottom right in
   the whitespace under the key-services list, and dropped to a texture. */
.gw-bunker__scene {
  position: absolute;
  right: clamp(-6rem, -3vw, -1rem);
  bottom: 0;
  width: min(44vw, 480px);
  aspect-ratio: 4 / 5;
  z-index: -1;
  opacity: 0.2;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to top, #000 40%, transparent 100%);
          mask-image: linear-gradient(to top, #000 40%, transparent 100%);
}

.gw-bunker__scene svg { width: 100%; height: 100%; }

@media (max-width: 780px) {
  .gw-bunker__scene { width: 78vw; right: -12%; opacity: 0.14; }
}

.gw-keylist {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: keylist;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  border-top: 1px solid var(--line-invert);
}

@media (min-width: 700px) {
  .gw-keylist {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: clamp(1.5rem, 4vw, 4rem);
    /* Equal rows keep the left and right rules on the same line even when one
       label wraps to three lines and its neighbour wraps to two. */
    grid-auto-rows: 1fr;
  }
}

.gw-keylist li {
  counter-increment: keylist;
  margin: 0;
  padding: clamp(0.9rem, 2vw, 1.25rem) 0;
  border-bottom: 1px solid var(--line-invert);
  display: flex;
  align-items: baseline;
  gap: 1rem;
  font-size: clamp(0.95rem, 1.5vw, 1.08rem);
  color: #fff;
  transition: padding-left var(--dur-3) var(--ease-out), color var(--dur-2) var(--ease-soft);
}

.gw-keylist li::before {
  content: counter(keylist, decimal-leading-zero);
  flex: 0 0 auto;
  font-family: var(--font-label);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--gw-mint);
}

.gw-keylist li:hover { padding-left: 0.6rem; color: var(--gw-mint-light); }

/* ---------------------------------------------------------------------------
   7. Network map
   --------------------------------------------------------------------------- */
.gw-map {
  display: grid;
  gap: clamp(2rem, 5vw, 4.5rem);
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

@media (min-width: 940px) {
  .gw-map { grid-template-columns: minmax(0, 360px) minmax(0, 1fr); }
}

.gw-map__figure {
  position: relative;
  aspect-ratio: 320 / 560;
  max-width: 380px;
  width: 100%;
  margin-inline: auto;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background:
    linear-gradient(180deg, var(--surface) 0%, var(--surface-muted) 100%);
  overflow: hidden;
}

.gw-slate .gw-map__figure,
.gw-dark .gw-map__figure {
  border-color: rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.03);
}

.gw-map__svg { position: absolute; inset: 0; width: 100%; height: 100%; }

.gw-map__pin {
  position: absolute;
  width: 14px;
  height: 14px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--gw-navy);
  border: 2px solid var(--surface);
  cursor: pointer;
  transition: transform var(--dur-2) var(--ease-out), background-color var(--dur-2) var(--ease-soft);
}

.gw-slate .gw-map__pin,
.gw-dark .gw-map__pin { border-color: var(--gw-slate); background: var(--gw-mint); }

.gw-map__pin::after {
  content: "";
  position: absolute;
  inset: -8px;
  border-radius: 50%;
  border: 1px solid var(--gw-mint);
  opacity: 0;
  transform: scale(0.6);
  transition: opacity var(--dur-2) var(--ease-soft), transform var(--dur-3) var(--ease-out);
}

.gw-map__pin.is-active,
.gw-map__pin:hover { transform: translate(-50%, -50%) scale(1.25); background: var(--gw-mint); }
.gw-map__pin.is-active::after { opacity: 1; transform: scale(1); }

.gw-map__pin--hq {
  width: 18px;
  height: 18px;
  /* Distinct by shape and colour, not only by the pulse — the pulse is off
     under prefers-reduced-motion. */
  background: var(--gw-mint);
  border-color: var(--gw-navy);
  box-shadow: 0 0 0 2px var(--surface);
}

.gw-slate .gw-map__pin--hq,
.gw-dark .gw-map__pin--hq {
  background: #fff;
  border-color: var(--gw-mint);
  box-shadow: 0 0 0 2px var(--gw-slate);
}

.gw-map__pin--hq::before {
  content: "";
  position: absolute;
  inset: -14px;
  border-radius: 50%;
  border: 1px solid var(--gw-mint);
  opacity: 0.55;
  animation: gw-ping 3.2s var(--ease-out) infinite;
}

@keyframes gw-ping {
  0%   { transform: scale(0.45); opacity: 0.65; }
  70%  { transform: scale(1.25); opacity: 0; }
  100% { transform: scale(1.25); opacity: 0; }
}

.gw-map__list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.gw-slate .gw-map__list, .gw-dark .gw-map__list { border-top-color: var(--line-invert); }

.gw-map__row {
  margin: 0;
  border-bottom: 1px solid var(--line);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(0.9rem, 2vw, 1.8rem);
  padding-block: clamp(0.95rem, 2vw, 1.35rem);
  cursor: pointer;
  transition: padding-left var(--dur-3) var(--ease-out), background-color var(--dur-2) var(--ease-soft);
}

.gw-slate .gw-map__row, .gw-dark .gw-map__row { border-bottom-color: var(--line-invert); }

.gw-map__row:hover,
.gw-map__row.is-active { padding-left: 0.6rem; }

.gw-map__index {
  font-family: var(--font-label);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--gw-mint);
  font-variant-numeric: tabular-nums;
}

.gw-map__name {
  font-family: var(--font-heading);
  font-size: clamp(1.05rem, 1.9vw, 1.35rem);
  font-weight: 600;
  letter-spacing: var(--ls-heading);
  color: var(--ink-heading);
  margin: 0;
}

.gw-slate .gw-map__name, .gw-dark .gw-map__name { color: #fff; }

.gw-map__note {
  display: block;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 400;
  letter-spacing: 0;
  color: var(--ink-muted);
  margin-top: 0.2rem;
}

.gw-slate .gw-map__note, .gw-dark .gw-map__note { color: var(--ink-invert-faint); }

.gw-map__coords {
  font-family: var(--font-label);
  font-size: var(--fs-xs);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.gw-slate .gw-map__coords, .gw-dark .gw-map__coords { color: var(--ink-invert-faint); }

.gw-map__badge {
  display: inline-block;
  margin-left: 0.6rem;
  padding: 0.15rem 0.5rem;
  border-radius: var(--r-xs);
  background: var(--accent-soft);
  border: 1px solid var(--accent-hair);
  font-family: var(--font-label);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gw-mint);
  vertical-align: middle;
}

/* ---------------------------------------------------------------------------
   8. Fleet — horizontal rail with scroll snapping.
   --------------------------------------------------------------------------- */
.gw-rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(78vw, 340px);
  gap: clamp(1rem, 2vw, 1.5rem);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--gutter);
  padding-bottom: 1.25rem;
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
  scrollbar-width: thin;
  scrollbar-color: var(--gw-mint) transparent;
}

.gw-rail::-webkit-scrollbar { height: 4px; }
.gw-rail::-webkit-scrollbar-track { background: var(--line); }
.gw-rail::-webkit-scrollbar-thumb { background: var(--gw-mint); }

.gw-asset {
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  transition: border-color var(--dur-2) var(--ease-soft), transform var(--dur-3) var(--ease-out);
}

.gw-asset:hover { border-color: var(--gw-mint); transform: translateY(-4px); }

.gw-asset__figure {
  aspect-ratio: 16 / 10;
  background: var(--gw-navy);
  position: relative;
  overflow: hidden;
}

.gw-asset__figure svg { width: 100%; height: 100%; }

.gw-asset__body { padding: clamp(1.15rem, 2.4vw, 1.6rem); flex: 1; }

.gw-asset__name {
  font-family: var(--font-heading);
  font-size: var(--fs-h3);
  font-weight: 600;
  letter-spacing: var(--ls-heading);
  color: var(--ink-heading);
  margin: 0 0 var(--sp-2);
}

.gw-asset__summary { font-size: var(--fs-sm); color: var(--ink-muted); margin: 0 0 var(--sp-3); }

.gw-asset__capability {
  font-family: var(--font-label);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  color: var(--gw-navy);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--line);
}

.gw-asset__flag {
  position: absolute;
  top: 0.9rem;
  left: 0.9rem;
  z-index: 1;
  padding: 0.28rem 0.6rem;
  border-radius: var(--r-xs);
  background: var(--gw-mint);
  color: var(--gw-navy);
  font-family: var(--font-label);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.gw-asset--placeholder { border-style: dashed; border-color: var(--line-strong); background: var(--surface-muted); }
.gw-asset--placeholder .gw-asset__figure { background: var(--gw-slate); }

/* ---------------------------------------------------------------------------
   9. Clients — typographic, no invented logos.
   --------------------------------------------------------------------------- */
.gw-clients {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}

.gw-client {
  margin: 0;
  background: var(--surface);
  padding: clamp(1.5rem, 3vw, 2.4rem);
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  transition: background-color var(--dur-2) var(--ease-soft);
}

.gw-client:hover { background: var(--gw-navy); }

.gw-client__mark {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 3.6vw, 2.5rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--gw-navy);
  transition: color var(--dur-2) var(--ease-soft);
}

.gw-client:hover .gw-client__mark { color: var(--gw-mint); }

.gw-client__name {
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--ink-muted);
  transition: color var(--dur-2) var(--ease-soft);
}

.gw-client:hover .gw-client__name { color: rgba(255, 255, 255, 0.78); }

.gw-client__rule { width: 26px; height: 2px; background: var(--gw-mint); }

/* ---------------------------------------------------------------------------
   10. Values / mission / vision
   --------------------------------------------------------------------------- */
.gw-pillars {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: pillar;
}

.gw-pillar {
  counter-increment: pillar;
  margin: 0;
  padding: clamp(1.4rem, 3vw, 2rem) 0;
  border-top: 1px solid var(--line);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(1rem, 2.5vw, 2rem);
  align-items: start;
}

.gw-dark .gw-pillar, .gw-slate .gw-pillar { border-top-color: var(--line-invert); }

.gw-pillar:last-child { border-bottom: 1px solid var(--line); }
.gw-dark .gw-pillar:last-child, .gw-slate .gw-pillar:last-child { border-bottom-color: var(--line-invert); }

.gw-pillar::before {
  content: counter(pillar, decimal-leading-zero);
  font-family: var(--font-label);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--gw-mint);
  padding-top: 0.4em;
}

.gw-pillar p { margin: 0; font-size: clamp(0.98rem, 1.5vw, 1.1rem); line-height: 1.65; }

.gw-valuecard {
  position: relative;
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}

.gw-valuecard::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--gw-mint);
  transform: scaleY(0);
  transform-origin: top center;
  transition: transform var(--dur-3) var(--ease-out);
}

.gw-valuecard:hover::before { transform: scaleY(1); }

.gw-valuecard h3 { font-size: var(--fs-h4); margin-bottom: var(--sp-2); }
.gw-valuecard p { font-size: var(--fs-sm); color: var(--ink-muted); margin: 0; }

/* A pulled quote for the core-values sentence. */
.gw-quote {
  position: relative;
  padding-left: clamp(1.25rem, 3vw, 2.5rem);
  border-left: 2px solid var(--gw-mint);
  font-family: var(--font-heading);
  font-size: clamp(1.2rem, 2.6vw, 1.85rem);
  line-height: 1.42;
  letter-spacing: var(--ls-heading);
  color: var(--ink-heading);
  max-width: 30ch;
  margin: 0;
}

.gw-dark .gw-quote, .gw-slate .gw-quote { color: #fff; }

/* ---------------------------------------------------------------------------
   11. Contact
   --------------------------------------------------------------------------- */
.gw-contact {
  display: grid;
  gap: clamp(2rem, 5vw, 4.5rem);
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

@media (min-width: 940px) {
  .gw-contact { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
}

.gw-contact__card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: clamp(1.5rem, 3.5vw, 2.5rem);
}

.gw-contact__list { list-style: none; margin: 0; padding: 0; }

.gw-contact__item {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: var(--sp-4);
  padding-block: clamp(1rem, 2vw, 1.35rem);
  border-bottom: 1px solid var(--line);
  margin: 0;
}

.gw-contact__item:last-child { border-bottom: 0; padding-bottom: 0; }
.gw-contact__item:first-child { padding-top: 0; }

.gw-contact__icon { width: 22px; height: 22px; color: var(--gw-navy); margin-top: 0.25rem; }
.gw-contact__icon svg { width: 100%; height: 100%; }

.gw-contact__key {
  display: block;
  font-family: var(--font-label);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.35rem;
}

.gw-contact__value { font-size: var(--fs-sm); line-height: 1.65; color: var(--ink-body); }
.gw-contact__value a { color: var(--gw-navy); font-weight: 500; }

.gw-form__grid {
  display: grid;
  gap: 0 var(--sp-5);
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 620px) {
  .gw-form__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .gw-form__grid .gw-field--full { grid-column: 1 / -1; }
}

/* ---------------------------------------------------------------------------
   12. Closing call to action
   --------------------------------------------------------------------------- */
.gw-cta {
  position: relative;
  background: var(--gw-slate);
  color: #fff;
  overflow: hidden;
  isolation: isolate;
}

.gw-cta__inner {
  position: relative;
  z-index: 1;
  display: grid;
  gap: clamp(1.75rem, 4vw, 3.5rem);
  grid-template-columns: minmax(0, 1fr);
  align-items: end;
}

@media (min-width: 880px) {
  .gw-cta__inner { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); }
}

.gw-cta h2 { color: #fff; max-width: 18ch; margin-bottom: var(--sp-4); }
.gw-cta p { color: rgba(255, 255, 255, 0.76); }

.gw-cta__actions { display: flex; flex-wrap: wrap; gap: var(--sp-4); }

/* ---------------------------------------------------------------------------
   13. Error pages
   --------------------------------------------------------------------------- */
.gw-error {
  min-height: 78svh;
  display: grid;
  place-items: center;
  text-align: center;
  padding-top: calc(var(--header-h) + 4rem);
  padding-bottom: 4rem;
}

.gw-error__code {
  font-family: var(--font-display);
  font-size: clamp(4.5rem, 16vw, 11rem);
  line-height: 1;
  font-weight: 700;
  letter-spacing: -0.04em;
  color: var(--gw-navy);
  opacity: 0.12;
  margin: 0 0 -0.3em;
}


/* ==== 06-motion.css ==== */
/* ===========================================================================
   GEOWAVE — motion
   ---------------------------------------------------------------------------
   Everything animated here moves on transform and opacity only, so nothing
   triggers layout. Reveals are driven by an IntersectionObserver that adds
   `.is-in`; if JavaScript never runs, `.gw-reveal` elements are visible by
   default and nothing is hidden from the reader.
   =========================================================================== */

/* The no-JS safe default: visible. The class below is added by app.js on load,
   and only then do reveal elements start hidden. */
.js .gw-reveal {
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity var(--dur-3) var(--ease-soft),
    transform var(--dur-4) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

.js .gw-reveal.is-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Variants */
.js .gw-reveal--left  { transform: translateX(-26px); }
.js .gw-reveal--right { transform: translateX(26px); }

/* Below the split breakpoint the two-column layouts have collapsed to a single
   stack, so a sideways entrance no longer means anything — and worse, 26px of
   translate is wider than the 20px gutter, which pushed the document 6px past
   the viewport. Vertical below 900px on both counts. */
@media (max-width: 899px) {
  .js .gw-reveal--left,
  .js .gw-reveal--right { transform: translateY(22px); }
}
.js .gw-reveal--scale { transform: scale(0.965); }
.js .gw-reveal--fade  { transform: none; }

.js .gw-reveal--left.is-in,
.js .gw-reveal--right.is-in,
.js .gw-reveal--scale.is-in { transform: none; }

/* Staggered grid entrance, from the motion spec: opacity 0, scale 0.92,
   y 16, ~400ms, back.out(1.4). The slight overshoot gives a grid of cards a
   wave rather than a flat fade.

   Applied to grids of equal items ONLY. The spec is explicit that overshoot
   reads as sloppy on dense informational rows, so the products list, the
   capability index and the location table keep the plain reveal. */
.js .gw-pop {
  opacity: 0;
  transform: translateY(16px) scale(0.92);
  transition:
    opacity 400ms var(--ease-soft),
    transform 400ms var(--ease-back);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

.js .gw-pop.is-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* A rule that draws itself in from the left. */
.js .gw-draw {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-4) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .gw-draw.is-in { transform: scaleX(1); }

/* Line-by-line headline entrance: each .gw-line is a masked row. */
.gw-lines { display: block; }

.gw-lines .gw-line {
  display: block;
  overflow: hidden;
}

.js .gw-lines .gw-line > span {
  display: block;
  transform: translateY(105%);
  transition: transform var(--dur-4) var(--ease-out);
  transition-delay: calc(var(--i, 0) * 90ms);
}

.js .gw-lines.is-in .gw-line > span { transform: translateY(0); }

/* Parallax: the JS writes --shift, the element only ever translates. */
.gw-parallax { will-change: transform; }

/* The hero recedes as it leaves: the JS writes --exit (0 → 1) from scroll
   position and nothing else changes, so this stays on the compositor. */
.js .gw-hero__body {
  opacity: calc(1 - var(--exit, 0));
  transform: translate3d(0, calc(var(--exit, 0) * -40px), 0);
}

/* Counters hold their final value in the markup; JS animates from zero. */
.gw-counter { display: inline-block; font-variant-numeric: tabular-nums; }

/* Page-transition curtain: a navy panel that wipes up on navigation. */
.gw-curtain {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: var(--gw-navy);
  transform: scaleY(0);
  transform-origin: bottom center;
  pointer-events: none;
  visibility: hidden;
}

.gw-curtain.is-leaving {
  visibility: visible;
  transform: scaleY(1);
  transform-origin: bottom center;
  transition: transform 420ms var(--ease-out);
}

/* Entrance wipe on first paint of a new page. */
.gw-curtain.is-entering {
  visibility: visible;
  transform: scaleY(1);
  transform-origin: top center;
  animation: gw-curtain-out 520ms var(--ease-out) forwards;
}

@keyframes gw-curtain-out {
  to { transform: scaleY(0); visibility: hidden; }
}

/* Soft float used on hero scene layers. */
@keyframes gw-float {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, -10px, 0); }
}

.gw-float { animation: gw-float 9s var(--ease-in-out) infinite; }
.gw-float--slow { animation-duration: 13s; }
.gw-float--delay { animation-delay: -4s; }

/* Slow horizontal drift for the hero's water bands. */
/* Hero swells repeat every 480 user units, so translating exactly -480px
   (px maps 1:1 to user units inside an SVG) loops with no visible seam. */
@keyframes gw-swell {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-480px, 0, 0); }
}

.gw-swell { animation: gw-swell 34s linear infinite; }
.gw-swell--fast { animation-duration: 22s; }
.gw-swell--slow { animation-duration: 48s; }

/* ---------------------------------------------------------------------------
   Reduced motion: everything resolves to its final state instantly.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  .js .gw-reveal,
  .js .gw-pop,
  .js .gw-lines .gw-line > span {
    opacity: 1 !important;
    transform: none !important;
  }

  .js .gw-hero__body { opacity: 1; transform: none; }

  .js .gw-draw { transform: scaleX(1) !important; }

  .gw-curtain { display: none; }
  .gw-hero__cue::after { display: none; }
}


/* ==== 07-responsive.css ==== */
/* ===========================================================================
   GEOWAVE — responsive adjustments
   ---------------------------------------------------------------------------
   The layouts above are mobile-first, so this file only holds the places where
   a layout is genuinely *rethought* for a smaller screen rather than scaled.
   =========================================================================== */

/* -- Tablet and below -------------------------------------------------------- */
@media (max-width: 1000px) {
  .gw-head--split {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: var(--sp-5);
  }

  .gw-head__aside { padding-bottom: 0; }

  /* The sticky preview panel is desktop-only; on smaller screens each
     capability carries its own illustration inside its opened panel. */
  .gw-capability__preview { display: none; }
}

/* -- Where the nav collapses ------------------------------------------------- */
@media (max-width: 940px) {
  .gw-nav,
  .gw-header__phone { display: none; }

  .gw-burger { display: flex; }

  .gw-header__actions .gw-btn { display: none; }
}

@media (min-width: 941px) {
  .gw-menu { display: none; }
}

/* -- Phone ------------------------------------------------------------------- */
@media (max-width: 720px) {
  .gw-hero { min-height: auto; }

  /* The stage owns the top padding — setting it on .gw-hero as well stacked
     two gaps on top of each other and pushed the headline off the fold. */
  .gw-hero__stage { padding-top: calc(var(--header-h) + 2.5rem); }

  .gw-hero__body { padding-bottom: 3rem; }

  .gw-quick { padding: 0.9rem 0.85rem; gap: 0.3rem; }

  .gw-hero__title { max-width: 100%; }

  /* The masked per-line entrance assumes exactly one line inside each mask.
     At this width the phrases wrap, and the mask would clip the wrapped line
     out of sight, so the headline reveals as a single block instead. */
  .js .gw-lines .gw-line { overflow: visible; }
  .js .gw-lines .gw-line > span { transform: none; transition: none; }

  .js .gw-lines {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity var(--dur-3) var(--ease-soft),
                transform var(--dur-4) var(--ease-out);
  }

  .js .gw-lines.is-in { opacity: 1; transform: none; }

  .gw-hero__scene { height: 46%; opacity: 0.85; }

  .gw-hero__actions { flex-direction: column; align-items: stretch; }
  .gw-hero__actions .gw-btn { justify-content: center; }

  .gw-hero__cue { display: none; }

  /* Products stop being three columns of dense text and become a simple
     stack with the metadata below the description. */
  .gw-product { grid-template-columns: minmax(0, 1fr); }
  .gw-product__icon { width: 34px; height: 34px; }

  .gw-stats__grid { grid-template-columns: minmax(0, 1fr); }

  .gw-map__row { grid-template-columns: auto minmax(0, 1fr); }
  .gw-map__coords { display: none; }

  .gw-contact__item { grid-template-columns: minmax(0, 1fr); gap: var(--sp-2); }
  .gw-contact__icon { display: none; }

  .gw-footer__bar { flex-direction: column; align-items: flex-start; }

  .gw-capability__row { grid-template-columns: auto minmax(0, 1fr); }
  .gw-capability__plus { display: none; }

  .gw-cta__inner { align-items: start; }
  .gw-cta__actions { flex-direction: column; align-items: stretch; }
  .gw-cta__actions .gw-btn { justify-content: center; }

  .gw-btn { width: auto; }
}

@media (max-width: 480px) {
  .gw-clients { grid-template-columns: minmax(0, 1fr); }
  .gw-keylist { grid-template-columns: minmax(0, 1fr); }
  .gw-quote { padding-left: 1rem; }
}

/* -- Very wide screens: stop the measure from stretching --------------------- */
@media (min-width: 1600px) {
  :root { --container: 1360px; }
}

/* -- Print ------------------------------------------------------------------- */
@media print {
  .gw-header,
  .gw-menu,
  .gw-burger,
  .gw-wave,
  .gw-hero__scene,
  .gw-hero__quick,
  .gw-curtain,
  .gw-cta { display: none !important; }

  body { background: #fff; color: #000; }

  .gw-hero,
  .gw-pagehero,
  .gw-dark,
  .gw-slate,
  .gw-stats,
  .gw-bunker,
  .gw-footer {
    background: #fff !important;
    color: #000 !important;
  }

  .gw-hero h1, .gw-hero__title,
  .gw-pagehero h1,
  .gw-dark h2, .gw-slate h2 { color: #000 !important; }

  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.75em; }

  .gw-section { padding-block: 1.5rem; break-inside: avoid; }
}

