/* ---------- Design tokens ---------- */
:root {
  --color-navy: #0b1f33;
  --color-navy-light: #13314f;
  --color-ink: #1a1f27;
  --color-text: #2c333d;
  --color-muted: #5b6472;
  --color-bg: #ffffff;
  --color-bg-alt: #f4f6f8;
  --color-border: #e1e5ea;
  --color-accent: #c8952c;
  --color-white: #ffffff;

  /* Hero / editorial palette */
  --color-cream: #f4efe6;
  --color-gold: #b6893a;
  --color-gold-soft: rgba(182, 137, 58, 0.4);
  --color-hairline: rgba(182, 137, 58, 0.4);

  --font-base: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --font-wordmark: Georgia, "Times New Roman", Times, serif;
  --font-nav: "Manrope", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

  --container-width: 1180px;
  --transition: 0.2s ease;
}

/* ---------- Reset ---------- */
* { box-sizing: border-box; margin: 0; padding: 0; }

/* Links glide to their section; with reduced motion they go straight there. */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  font-family: var(--font-base);
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

a { color: inherit; text-decoration: none; }

ul { list-style: none; }

.container {
  width: 100%;
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 0 24px;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-block;
  padding: 14px 32px;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  border: 1px solid transparent;
  border-radius: 2px;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
  cursor: pointer;
}

.btn-primary {
  background: var(--color-accent);
  color: var(--color-white);
}
.btn-primary:active { background: #b2811f; }
@media (hover: hover) {
  .btn-primary:hover { background: #b2811f; }
}
.btn:focus-visible,
.nav-cta:focus-visible,
.nav-toggle:focus-visible,
.brand:focus-visible { outline: 2px solid var(--color-gold); outline-offset: 3px; }

.btn-outline {
  background: transparent;
  color: var(--color-white);
  border-color: rgba(255, 255, 255, 0.6);
}
.btn-outline:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: var(--color-white);
}

.btn-light {
  background: var(--color-cream);
  color: var(--color-navy);
  border-color: var(--color-cream);
}
.btn-light:hover { background: var(--color-white); }

.btn-dark {
  background: var(--color-navy);
  color: var(--color-cream);
  border-color: var(--color-navy);
}
.btn-dark:hover { background: var(--color-navy-light); }

/* ---------- Hero -> About page-turn transition ----------
   Only applies when JS enables it (html.curl-enabled). The hero is a fixed
   sheet lying over the About page; JS drives a 0..1 page-turn progress from
   wheel / touch / keyboard input. Reduced-motion / no-JS visitors get the plain
   hero followed by About. */
.curl-enabled .hero-pin {
  position: fixed;
  inset: 0;
  z-index: 50;
  pointer-events: none;
  touch-action: none;
}
.curl-enabled .hero-pin.is-done { display: none; }
.curl-enabled .hero-runway {
  position: absolute;
  inset: 0;
}
.curl-enabled .hero-page {
  position: relative;
  min-height: 100vh; /* on phones the hero content is shorter than the screen */
  background: var(--color-white); /* ...so the extra height must be paper, not a window onto About */
  pointer-events: auto;
}
.curl-enabled .hero-page.is-curling { visibility: hidden; }
/* Without the stage (reduced motion), About runs on beneath the hero's page. With it, About is a view of the stage
   and fills the stage exactly, as every chapter does: on a phone 100vh is the screen with the browser's bars gone,
   taller than the screen the page actually has, and the view's last part would sit out of reach beneath it. */
.curl-enabled:not(.stage-on) #about { min-height: 100vh; }

.curl-stage {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  perspective: 2200px;
  perspective-origin: 50% 35%;
  pointer-events: none;
  visibility: hidden;
}
.curl-stage.is-active { visibility: visible; will-change: transform; }
.curl-page {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
}
.curl-strip {
  position: absolute;
  left: 0;
  right: 0;
  transform-style: preserve-3d;
  transform-origin: 50% 0;
}
.curl-face,
.curl-back {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  overflow: hidden;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.curl-back {
  background: var(--color-white);
  transform: rotateX(180deg);
}
.curl-clone {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  background: var(--color-white); /* matches .hero-page, keeps the sheet solid to its bottom edge */
}

/* ---------- Header ---------- */
.site-header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background: transparent;
}
/* The one nav from About onwards (#siteNav): with motion it sits above the stage (css/stage.css) and never moves;
   without, it heads the page. Its gold line (.site-nav__line) travels between ABOUT, SERVICES, GLOBAL REACH and CONTACT
   (js/main.js). */
.site-nav .primary-nav a.is-active::after { content: none; }
.site-nav__line {
  position: absolute;
  left: 0;
  top: 0;
  width: 1px;
  height: 2px;
  background: var(--color-gold);
  transform-origin: 0 0;
  pointer-events: none;
}

.header-inner {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  column-gap: 40px;
  max-width: 1024px;
  /* Keep a 16px gutter (plus any iOS side safe area) once the viewport is narrower than the pill. */
  max-width: min(1024px, calc(100% - 32px - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px)));
  margin: 28px auto 0;
  padding: 8px 32px;
  background: rgba(255, 255, 255, 0.58);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: 999px;
  box-shadow: 0 12px 28px rgba(11, 31, 51, 0.1);
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
}
.brand-logo {
  height: 85px;
  width: auto;
}
.brand-name {
  color: var(--color-navy);
  font-size: 1.55rem;
  font-weight: 700;
  letter-spacing: 0.06em;
}
.brand-sub {
  color: var(--color-muted);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.2em;
}

.primary-nav {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
.primary-nav ul {
  display: flex;
  align-items: center;
  gap: 46px;
}
/* Desktop: the word SERVICES is the anchor. The nav is centred in the pill, and the pill in the viewport; two equal
   outer columns put the middle one, SERVICES, exactly on that centre whatever the widths of ABOUT and GLOBAL REACH,
   each 52px from it. The item holds only the word (its chevron hangs outside it), so the word itself is what is
   centred. The <=900px dropdown keeps its own layout. */
@media (min-width: 901px) {
  .primary-nav > ul {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    column-gap: 52px;
  }
  .primary-nav > ul > li:first-child { justify-self: end; }
  .primary-nav > ul > li:last-child { justify-self: start; }
}
@media (min-width: 901px) and (pointer: coarse) {
  .primary-nav a:not(.btn)::before { content: ""; position: absolute; inset: -10px -10px; }
  .nav-cta { position: relative; }
  .nav-cta::before { content: ""; position: absolute; inset: -5px -3px; }
}
.primary-nav a:not(.btn) {
  position: relative;
  display: inline-block;
  padding-bottom: 6px;
  color: var(--color-navy);
  font-family: var(--font-nav);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  transition: opacity var(--transition);
}
.primary-nav a:not(.btn):focus-visible {
  opacity: 0.6;
}
/* Hover dimming only where a real hover exists: on touch, :hover sticks after a
   tap and would leave the tapped link washed out. */
@media (hover: hover) {
  .primary-nav a:not(.btn):hover { opacity: 0.6; }
}
.primary-nav a,
.nav-cta,
.nav-toggle,
.brand { -webkit-tap-highlight-color: transparent; }
.primary-nav a.is-active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--color-gold);
}

/* SERVICES opens its two chapters on hover (or keyboard focus): a compact panel that hangs from the word itself,
   centred under it, 10px below it. The menu's box begins at the item's foot and that 10px is its own padding, so the
   pointer never crosses a gap; it fades in with a slight rise and closes a moment after the pointer leaves, so it
   never flickers. js/main.js closes it once one is chosen. In the <=900px menu the two are listed beneath SERVICES. */
.nav-drop { position: relative; }
@media (min-width: 901px) {
  /* The hint: a small gold chevron just after the word, outside the item so it takes no part in the centring. */
  .nav-drop::after {
    content: "";
    position: absolute;
    left: calc(100% + 8px);
    top: calc(50% - 7px);
    width: 5px;
    height: 5px;
    border-right: 1.5px solid var(--color-gold);
    border-bottom: 1.5px solid var(--color-gold);
    transform: rotate(45deg);
    pointer-events: none;
  }
  .nav-drop__menu {
    position: absolute;
    top: 100%;
    left: 50%;
    padding-top: 10px;
    transform: translate(-50%, 4px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease 0.1s, transform 0.2s ease 0.1s, visibility 0s linear 0.3s;
  }
  .nav-drop:hover .nav-drop__menu,
  .nav-drop:has(:focus-visible) .nav-drop__menu {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
    transition-delay: 0s;
  }
  .nav-drop.is-dismissed .nav-drop__menu { opacity: 0; visibility: hidden; transition: none; }
  /* The panel: the pill's white, a hairline edge and a soft shadow, with a short gold rule under SERVICES. */
  .primary-nav .nav-drop__menu ul {
    position: relative;
    display: block;
    padding: 6px;
    background: var(--color-white);
    border: 1px solid rgba(11, 31, 51, 0.06);
    border-radius: 14px;
    box-shadow: 0 10px 26px rgba(11, 31, 51, 0.08), 0 1px 2px rgba(11, 31, 51, 0.04);
  }
  .primary-nav .nav-drop__menu ul::before {
    content: "";
    position: absolute;
    top: -1px;
    left: 50%;
    width: 20px;
    height: 2px;
    margin-left: -10px;
    background: var(--color-gold);
  }
  .primary-nav .nav-drop__menu li + li { border-top: 1px solid rgba(182, 137, 58, 0.14); margin: 0 10px; }
  .primary-nav .nav-drop__menu li + li a:not(.btn) { margin: 0 -10px; }
  .primary-nav .nav-drop__menu a:not(.btn) {
    display: block;
    padding: 11px 18px;
    border-radius: 9px;
    font-size: 0.84rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: none;
    white-space: nowrap;
    transition: background-color 0.2s ease, padding 0.2s ease;
  }
  /* The option under the pointer: a faint warm ground, a short gold mark at its edge, the words a step in. */
  .primary-nav .nav-drop__menu a:not(.btn)::after {
    content: "";
    position: absolute;
    left: 7px;
    top: 50%;
    width: 2px;
    height: 14px;
    margin-top: -7px;
    border-radius: 1px;
    background: var(--color-gold);
    opacity: 0;
    transform: scaleY(0.4);
    transition: opacity 0.2s ease, transform 0.2s ease;
  }
}
@media (min-width: 901px) and (hover: hover) {
  .primary-nav .nav-drop__menu a:not(.btn):hover { opacity: 1; padding-left: 21px; background: rgba(244, 239, 230, 0.55); }
  .primary-nav .nav-drop__menu a:not(.btn):hover::after { opacity: 1; transform: none; }
}
.primary-nav .nav-drop__menu a:not(.btn):focus-visible { opacity: 1; background: rgba(244, 239, 230, 0.55); outline: none; }

.header-actions {
  grid-column: 3;
  display: flex;
  align-items: center;
  gap: 16px;
}

.nav-cta {
  display: inline-flex;
  align-items: center;
  padding: 10px 22px;
  font-family: var(--font-nav);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: var(--color-navy);
  color: var(--color-cream);
  border: none;
  border-bottom: 1px solid var(--color-gold);
  border-radius: 9999px;
}
/* The thicker gold underline is an inset shadow, so hover/press never changes the button's height. */
.nav-cta:active { background: var(--color-navy-light); box-shadow: inset 0 -1px 0 var(--color-gold); }
@media (hover: hover) {
  .nav-cta:hover { background: var(--color-navy-light); box-shadow: inset 0 -1px 0 var(--color-gold); }
}

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  background: transparent;
  border: none;
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  height: 2px;
  width: 100%;
  background: var(--color-navy);
  transition: transform var(--transition), opacity var(--transition);
}

/* ---------- Scroll indicator (js/scroll-indicator.js) ----------
   A thin, quiet track at the right with a dark thumb: it comes up while the visitor scrolls and fades away a moment
   after. Its top and height are set from the nav's size (js/scroll-indicator.js); it never takes the pointer. On a
   dark chapter (Customs' navy) it turns light. */
.scroll-indicator {
  position: fixed;
  z-index: 60; /* above the hero sheet (.hero-pin, 50) as well as the stage */
  right: clamp(8px, 1.3vw, 24px); /* clear of the Contact map's controls (css/contact.css, 2.6vw from the edge) */
  top: 0;
  width: 6px;
  border-radius: 999px;
  background: rgba(11, 31, 51, 0.07);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.45s ease, background-color 0.4s ease;
}
.scroll-indicator.is-on {
  opacity: 1;
  transition: opacity 0.15s ease, background-color 0.4s ease;
}
.scroll-indicator__thumb {
  display: block;
  width: 100%;
  border-radius: inherit;
  background: rgba(26, 31, 39, 0.82);
  will-change: transform;
  transition: background-color 0.4s ease;
}
.scroll-indicator.is-light { background: rgba(255, 255, 255, 0.12); }
.scroll-indicator.is-light .scroll-indicator__thumb { background: rgba(244, 239, 230, 0.85); }
@media (max-width: 899px) {
  .scroll-indicator { right: 4px; width: 4px; } /* outside the Contact map's attribution, 10px in */
}
@media (prefers-reduced-motion: reduce) {
  .scroll-indicator,
  .scroll-indicator.is-on,
  .scroll-indicator__thumb { transition: none; }
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  background: var(--color-white);
  padding-bottom: 26px;
}
/* The pale-blue air of the Our Services wave (css/services-intro.css, .svx-curve), beneath the hero's curve too.
   Two copies of the frame's box, clipped by the same curve and set a little lower behind it, show below its edge as
   the Services wave's soft blue band and then its paler one, over the same palest blue; their depths follow the
   Services wave's height (--mist) exactly. They share the frame's grid cell, so they are exactly its size; a relative
   offset (no effect on layout) sets them lower. The frame and its curve are untouched. */
.hero {
  --mist: clamp(120px, 21vh, 210px);
  display: grid;
  grid-template-columns: 100%;
  grid-auto-rows: max-content; /* each row exactly its content, as in the block flow (the frame clips its overflow) */
  align-content: start;
  isolation: isolate;
  background: linear-gradient(180deg, #f7fbff calc(100% - 18px), var(--color-white) 100%);
}
.hero-frame { grid-area: 1 / 1; }
.hero > .wave-accent { grid-area: 1 / 1; }
.hero-scroll { grid-area: 2 / 1; }
.hero::before,
.hero::after {
  content: "";
  grid-area: 1 / 1;
  position: relative;
  clip-path: url(#heroCurveClip);
  pointer-events: none;
}
.hero::before {
  z-index: -2;
  top: calc(var(--mist) * 0.121);
  background: #eaf5ff;
}
.hero::after {
  z-index: -1;
  top: calc(var(--mist) * 0.066);
  background: linear-gradient(90deg, #b9d9f4 0, #cfe6fa 50%, #dceeff 100%);
  opacity: 0.85;
}
@media (max-width: 859px) {
  .hero { --mist: clamp(80px, 12vh, 120px); }
}

/* ---------- The wave's gold (the hero and About; the Our Services wave draws the same in its own SVG) ----------
   A quiet architectural edge, not a feature: a gold hairline along the curve, a fainter one where the pale band
   settles into white, and at the centre a small gold point on the curve with a short thread falling from it.
   The accent shares the grid cell of the box the curve clips (#heroCurveClip), so its SVGs, drawn in the same
   0..1 box, follow the curve exactly at every size; the lower hairline sits as far down as the palest band
   (--mist * 0.121, as .hero::before / .about-page::before). */
.wave-accent {
  position: relative;
  z-index: 2;
  pointer-events: none;
}
.wave-accent__edge {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.wave-accent__edge path {
  fill: none;
  stroke: url(#waveGold);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  opacity: 0.6;
}
.wave-accent__edge--low { transform: translateY(calc(var(--mist) * 0.121)); }
.wave-accent__edge--low path { opacity: 0.26; }
/* The centre of the curve lies 96.93% of the way down its box. */
.wave-accent__dot {
  position: absolute;
  left: 50%;
  top: 96.93%;
  width: 7px;
  height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border-radius: 50%;
  background: #d4aa3a;
  box-shadow: 0 0 0 3px rgba(212, 170, 58, 0.14);
}
.wave-accent__thread {
  position: absolute;
  left: 50%;
  top: 96.93%;
  width: 1px;
  height: 56px;
  margin-left: -0.5px;
  background: linear-gradient(180deg, rgba(199, 154, 43, 0.8), rgba(199, 154, 43, 0));
}
/* ---------- The contour lines in the white beneath the waves (#clarionContours, index.html) ----------
   A finishing detail only: faint, hairline topographic lines, champagne beneath the gold point and pale blue outward,
   fading into the white. On the hero and About they lie behind everything (under the photograph, its curve and the
   pale bands, which cover their upper edge), filling the white below the curved box's cell; the Our Services wave
   draws them in its own white. Fewer on smaller screens. */
.contours path {
  fill: none;
  stroke: url(#contourFade);
  stroke-width: 0.8;
  vector-effect: non-scaling-stroke;
}
.wave-contours { opacity: 0.55; pointer-events: none; }
svg.wave-contours {
  position: absolute;
  inset: 0;
  z-index: -3;
  width: 100%;
  height: 100%;
}
.hero > .wave-contours { grid-area: 2 / 1 / auto / 2; } /* from the foot of the hero's frame to the foot of the hero */
@media (max-width: 899px) {
  .contours__fine { display: none; }
}

/* The hero's thread runs on to its scroll cue, 10px above the words. */
.hero {
  --cue: 24px; /* the words' distance below the hero's box */
}
.hero .wave-accent__thread {
  height: auto;
  bottom: calc(10px - var(--cue));
  background: var(--color-gold);
}

.hero-frame {
  position: relative;
  height: calc(100vh - 75px);
  min-height: 500px;
  max-height: 925px;
  overflow: hidden;
  background: var(--color-navy);
  clip-path: url(#heroCurveClip);
}

.hero-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
}

/* The water, gently moving. The same photograph again, placed exactly as .hero-image, shown only where the water is
   (images/hero-water-mask.svg, in the photograph's own pixels, placed as the photograph is placed) and displaced a few
   pixels by #heroWater (index.html), whose flow js/hero-water.js moves. Everything else in the frame is the still
   photograph beneath. Not in the page-turn's copies of the hero, nor with reduced motion. */
.hero-water {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
  -webkit-mask: url(../images/hero-water-mask.svg) center 30% / cover no-repeat;
  mask: url(../images/hero-water-mask.svg) center 30% / cover no-repeat;
  filter: url(#heroWater);
  pointer-events: none;
}
.curl-clone .hero-water { display: none; }
@media (prefers-reduced-motion: reduce) {
  .hero-water { display: none; }
}

.hero-top-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0.72) 0%,
    rgba(255, 255, 255, 0.5) 24%,
    rgba(255, 255, 255, 0.3) 42%,
    rgba(255, 255, 255, 0.12) 58%,
    rgba(255, 255, 255, 0.02) 72%,
    rgba(255, 255, 255, 0) 85%
  );
  pointer-events: none;
}

.hero-label {
  position: absolute;
  top: 348px;
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.7;
  color: var(--color-navy);
  z-index: 3;
  text-shadow: 0 2px 20px rgba(255, 255, 255, 0.85), 0 1px 3px rgba(255, 255, 255, 0.6);
}
.hero-label::before {
  content: "";
  display: block;
  width: 24px;
  height: 1px;
  background: var(--color-gold);
  margin-bottom: 14px;
}
.hero-label-left { left: 56px; top: 254px; }
.hero-label-right { right: 56px; top: 254px; text-align: right; }
.hero-label-right::before { margin-left: auto; }
@media (min-width: 901px) and (max-width: 1000px) {
  .hero-label-left { left: 24px; }
  .hero-label-right { right: 24px; }
}

.hero-overlay {
  position: absolute;
  z-index: 3;
  top: 172px;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: 900px;
  padding: 0 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  color: var(--color-navy);
  user-select: none;
  text-shadow: 0 2px 28px rgba(255, 255, 255, 0.85), 0 1px 4px rgba(255, 255, 255, 0.6);
}

.hero-est {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  margin-bottom: 20px;
}
.hero-est::before,
.hero-est::after {
  content: "";
  width: 46px;
  height: 1px;
  background: var(--color-gold);
}
/* The text's trailing letter-space would leave the right gap wider than the left; pull the right line in by
   exactly that amount so both gold lines sit the same distance from the letters. */
.hero-est::after { margin-left: -0.28em; }

.hero-type {
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Wordmark is set in Georgia. Georgia Bold runs ~11% wider than Playfair at the same size, so the
   size is reduced by the same ratio (x0.903) to keep the lockup's footprint, and line-height is raised
   (x1/0.903) so the line box is exactly as tall as before. */
.hero-type-main {
  font-family: var(--font-wordmark);
  font-weight: 700;
  font-size: 7.59rem;
  line-height: 1.107;
  letter-spacing: -0.01em;
}

/* "Logistics Limited" (title case). Naturally tracked (0.15em) so it reads as a typeset subtitle rather than a
   stretched line; it spans ~83% of Clarion's width. padding-left is solved so the line's ink is centred under
   Clarion's letters (it cancels the trailing letter-space). Both are in em, and the font-size scales with the
   wordmark at each breakpoint, so the proportions hold at every viewport width. */
.hero-type-sub {
  font-family: var(--font-wordmark);
  font-weight: 400;
  font-size: 2.375rem;
  line-height: 1.246;
  letter-spacing: 0.15em;
  padding-left: 0.202em;
  margin-top: 12px;
}

.hero-divider {
  width: 48px;
  height: 1px;
  background: var(--color-gold);
  margin: 14px 0 0;
}

.hero-tagline {
  font-family: var(--font-display);
  font-size: 1.7rem;
  font-weight: 600;
}

.hero-scroll {
  position: relative;
  z-index: 3;
  width: fit-content;
  margin: var(--cue) auto 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  color: var(--color-navy);
}
.hero-scroll span {
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.hero-scroll svg { width: 14px; height: 14px; color: var(--color-gold); }

/* ---------- Hero entrance ----------
   Plays once per visit (about 2.9s). html.hero-intro is set by the inline script in <head> before first paint
   (never with reduced motion, and not again in a tab that has already seen it); every animation here holds on its
   first frame until js/main.js adds html.hero-intro-play once the photograph is ready, then removes both classes.
   Each one ends exactly on the element's normal style, so removing them changes nothing on screen. Transform,
   opacity and background position only: no layout property moves, and the photograph itself is never touched.

   One gesture, not separate effects: the scene opens slightly restrained, with Clarion quiet. EST. 2006 appears.
   A warm reflection crosses Clarion and the letters come up rich where it touches them. As it passes the middle
   of the word, the same light carries on down into the photograph: the restraint lifts along a very soft curved
   front that starts under the right half of the wordmark and travels down and slightly right, over the sky, the
   skyline, the water and then the port, with a broad warm exposure riding just behind it that settles away to
   nothing. Logistics Limited and the gold rule close the sequence. */
@media (prefers-reduced-motion: no-preference) {
  .hero-intro { --intro-state: paused; }
  .hero-intro-play { --intro-state: running; }

  /* The two photographic layers below sit between the photograph and the white top scrim, so the bright sky
     under the scrim moves least and the city and water most, as real light would read. */
  .hero-intro .hero-top-scrim { z-index: 2; }

  /* The restraint: a cool multiply veil (about 5% under the natural exposure, a touch cooler) with a hole that is
     a very large ellipse softened over half its radius, so its front has no visible edge. The element's top edge
     runs through the ellipse's centre, always inside the clear core, so nothing above the front is veiled. It
     rests (its normal style) with the whole frame inside the clear core. */
  .hero-intro .hero-frame::before {
    content: "";
    position: absolute;
    z-index: 1;
    left: -38%;
    top: 58%;
    width: 200%;
    height: 260%;
    pointer-events: none;
    background: radial-gradient(
      ellipse 80% 56% at 50% 0,
      rgba(238, 241, 248, 0) 50%,
      rgba(238, 241, 248, 0.043) 56.25%,
      rgba(238, 241, 248, 0.156) 62.5%,
      rgba(238, 241, 248, 0.316) 68.75%,
      rgba(238, 241, 248, 0.5) 75%,
      rgba(238, 241, 248, 0.684) 81.25%,
      rgba(238, 241, 248, 0.844) 87.5%,
      rgba(238, 241, 248, 0.957) 93.75%,
      rgb(238, 241, 248) 100%
    );
    mix-blend-mode: multiply;
    animation: heroVeil 1850ms cubic-bezier(0.1, 0.25, 0.45, 0.85) 900ms both;
    animation-play-state: var(--intro-state);
  }

  /* The light: a broad warm exposure (colour dodge, so highlights and the water lift most and nothing turns
     orange), shaped as a wide soft ellipse with no edge, riding just behind the veil's front on the same curve.
     It fades up as it leaves the wordmark, is strongest over the skyline and the water, then settles away. */
  .hero-intro .hero-frame::after {
    content: "";
    position: absolute;
    z-index: 1;
    left: -20%;
    top: 105%;
    width: 180%;
    height: 100%;
    pointer-events: none;
    background: radial-gradient(
      closest-side,
      rgba(26, 17, 7, 0.34),
      rgba(26, 17, 7, 0.31) 20%,
      rgba(26, 17, 7, 0.23) 40%,
      rgba(26, 17, 7, 0.13) 60%,
      rgba(26, 17, 7, 0.05) 80%,
      rgba(26, 17, 7, 0.014) 92%,
      rgba(26, 17, 7, 0)
    );
    mix-blend-mode: color-dodge;
    opacity: 0;
    animation:
      heroLightPath 1850ms cubic-bezier(0.1, 0.25, 0.45, 0.85) 900ms both,
      heroLightFade 1850ms linear 900ms both;
    animation-play-state: var(--intro-state);
  }

  /* EST. 2006 fades up while its two gold rules grow outward from the text. */
  .hero-intro .hero-est {
    animation: heroFadeIn 650ms cubic-bezier(0.33, 0, 0.2, 1) 180ms both;
    animation-play-state: var(--intro-state);
  }
  .hero-intro .hero-est::before,
  .hero-intro .hero-est::after {
    animation: heroRuleExtend 700ms cubic-bezier(0.25, 0.55, 0.3, 1) 230ms both;
    animation-play-state: var(--intro-state);
  }
  .hero-intro .hero-est::before { transform-origin: 100% 50%; }
  .hero-intro .hero-est::after { transform-origin: 0 50%; }

  /* Clarion is fully drawn from the first frame; ::after lies exactly over its letters and is painted only inside
     them. Ahead of the light it is a pale cool film, so the word reads quiet; the light itself is a narrow
     warm-white core in a very soft warm falloff; behind it there is nothing, so the letters are left in their own
     rich navy. Sliding that one gradient across the word is the whole effect: no mask, no glow outside the
     letters, and at rest it shows only its clear end. */
  .hero-intro .hero-type-main { position: relative; }
  .hero-intro .hero-type-main::after {
    content: attr(data-text);
    position: absolute;
    inset: 0;
    white-space: nowrap;
    color: transparent;
    text-shadow: none;
    pointer-events: none;
    background: linear-gradient(
      104deg,
      rgba(222, 160, 62, 0) 41.2%,
      rgba(222, 160, 62, 0.035) 45.5%,
      rgba(224, 162, 64, 0.09) 48.2%,
      rgba(228, 170, 74, 0.32) 49.35%,
      rgba(255, 233, 184, 0.92) 49.8%,
      rgba(228, 170, 74, 0.32) 50.25%,
      rgba(224, 164, 68, 0.1) 51.4%,
      rgba(222, 186, 132, 0.12) 54.1%,
      rgba(216, 226, 238, 0.3) 58.4%
    ) 0 0 / 255% 100% no-repeat;
    -webkit-background-clip: text;
    background-clip: text;
    animation: heroSweep 1050ms cubic-bezier(0.2, 0.4, 0.7, 0.8) 600ms both;
    animation-play-state: var(--intro-state);
  }

  /* Logistics Limited settles in just after Clarion has resolved. */
  .hero-intro .hero-type-sub {
    animation: heroRise 560ms cubic-bezier(0.25, 0.46, 0.35, 1) 1780ms both;
    animation-play-state: var(--intro-state);
  }

  /* The gold rule beneath draws out from its centre, the last mark. */
  .hero-intro .hero-divider {
    animation: heroDraw 420ms cubic-bezier(0.45, 0, 0.2, 1) 2240ms both;
    animation-play-state: var(--intro-state);
  }
}

@keyframes heroFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes heroRuleExtend {
  from { transform: scaleX(0); }
  to { transform: none; }
}
@keyframes heroSweep {
  from { background-position: 100% 0; }
  to { background-position: 0 0; }
}
@keyframes heroRise {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
/* Veil and light travel on the same curve. Percentages are of each element's own box: the veil's ellipse centre
   goes from (54%, -146%) of the frame to (62%, 58%); the light's centre from (52%, -46%) to (70%, 155%). */
@keyframes heroVeil {
  from { transform: translate(-4%, -78.3%); }
  to { transform: none; }
}
@keyframes heroLightPath {
  from { transform: translate(-10%, -201%); }
  to { transform: none; }
}
@keyframes heroLightFade {
  0% { opacity: 0; animation-timing-function: cubic-bezier(0.4, 0, 0.6, 1); }
  24% { opacity: 1; }
  40% { opacity: 1; animation-timing-function: cubic-bezier(0.35, 0, 0.45, 1); }
  100% { opacity: 0; }
}
@keyframes heroDraw {
  from { transform: scaleX(0); }
  to { transform: none; }
}

/* ---------- Sections ---------- */
.section { padding: 100px 0; }

.section-heading {
  font-size: 1.9rem;
  font-weight: 700;
  color: var(--color-navy);
  letter-spacing: -0.01em;
  margin-bottom: 48px;
}

/* Intro */
.intro { background: var(--color-bg); }
.intro-inner { max-width: 780px; }
.intro-text {
  font-size: 1.2rem;
  color: var(--color-muted);
  line-height: 1.75;
}

/* Services */
.services { background: var(--color-bg-alt); }

.services-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--color-border);
  border: 1px solid var(--color-border);
}

.service {
  background: var(--color-bg);
  padding: 44px 36px;
  transition: background var(--transition);
}
.service:hover { background: var(--color-bg-alt); }

.service h3 {
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--color-navy);
  margin-bottom: 12px;
  padding-bottom: 14px;
  border-bottom: 2px solid var(--color-accent);
  display: inline-block;
}

.service p {
  color: var(--color-muted);
  font-size: 0.98rem;
}

/* Strengths */
.strengths { background: var(--color-navy); }
.strengths .section-heading { color: var(--color-white); }

.strengths-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 32px;
}

.strength {
  padding: 28px 20px;
  border-top: 2px solid var(--color-accent);
}

.strength-label {
  color: var(--color-white);
  font-size: 1.05rem;
  font-weight: 600;
}

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  .services-grid { grid-template-columns: 1fr; }
  .strengths-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 900px) {
  .nav-toggle { display: flex; }

  .primary-nav {
    position: absolute;
    top: calc(100% + 12px);
    left: 0;
    right: 0;
    background: var(--color-cream);
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    padding: 8px 24px 24px;
    border-top: 1px solid var(--color-hairline);
    box-shadow: 0 12px 24px rgba(22, 40, 31, 0.08);
    transform: translateY(-8px);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--transition), transform var(--transition);
  }

  .primary-nav.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateY(0);
  }

  .primary-nav ul {
    flex-direction: column;
    width: 100%;
    gap: 0;
  }
  .primary-nav ul li { width: 100%; }
  .primary-nav ul li a {
    display: block;
    padding: 14px 0;
    border-bottom: 1px solid var(--color-hairline);
  }
  .primary-nav .nav-drop__menu ul li a {
    padding: 12px 0 12px 18px;
    font-size: 0.85rem;
    text-transform: none;
    letter-spacing: 0.02em;
  }

  .nav-cta { position: relative; padding: 10px 16px; font-size: 0.72rem; }
  /* Same look, larger tap target for the compact pill. */
  .nav-cta::before { content: ""; position: absolute; inset: -5px -3px; }
  .nav-toggle::before { content: ""; position: absolute; inset: -5px -9px; }
  .nav-toggle { position: relative; }
  /* In the menu the chapter is marked like the hero's, on the link itself. */
  .site-nav .primary-nav a.is-active::after { content: ""; }
  .site-nav__line { display: none; }

  .section { padding: 64px 0; }
  .strengths-grid { grid-template-columns: 1fr 1fr; gap: 20px; }
}

@media (max-width: 480px) {
  .strengths-grid { grid-template-columns: 1fr; }
  .btn { text-align: center; width: 100%; }
}

/* ---------- Hero responsive ---------- */
/* Large portrait screens (e.g. iPad Pro): let the hero fill the height instead of stopping at the desktop cap. */
@media (min-width: 901px) and (orientation: portrait) {
  .hero-frame { max-height: none; }
}
@media (max-width: 900px) {
  .hero-frame { height: calc(100vh - 221px); height: calc(100svh - 221px); min-height: 620px; max-height: none; }
  .hero-label { display: none; }
  .hero-overlay { top: 167px; padding: 0 20px; }
  .hero-type-main { font-size: clamp(3.07rem, 14.45vw, 5.06rem); }
  .hero-type-sub { font-size: 1.583rem; margin-top: 9px; }
  .hero-est { font-size: 0.65rem; gap: 12px; margin-bottom: 11px; }
  .hero-est::before, .hero-est::after { width: 30px; }
  .hero-tagline { font-size: 1.3rem; }
  .hero { padding-bottom: 40px; --cue: 72px; }
}

@media (max-width: 560px) {
  .header-inner { margin-top: 16px; padding: 10px 20px; column-gap: 16px; }
  .brand-logo { height: 60px; }
  .hero-frame { height: calc(100vh - 177px); height: calc(100svh - 177px); min-height: 560px; }
  .hero-overlay { top: 126px; padding: 0 16px; }
  .hero-type-main { font-size: clamp(2.35rem, 16.25vw, 3.25rem); }
  .hero-est { margin-bottom: 5px; }
  .hero-type-sub { font-size: 1.017rem; margin-top: 7px; }
  .hero-tagline { font-size: 1.15rem; }
  .hero-divider { width: 36px; margin: 12px 0; }
}
