/* ==========================================================================
   Blackfin — shared stylesheet
   Plain CSS, no build step, no external dependencies (safe for local IIS
   testing with no internet access). Edit variables below to retheme.
   ========================================================================== */

:root {
  --navy-900: #0a1830;
  --navy-800: #122a52;
  --navy-700: #1a3a6e;
  --blue-600: #1d4fd8;
  --blue-500: #3866e6;
  --blue-50: #eef2ff;
  --green-600: #2e9e6b;
  --gray-50: #f7f8fa;
  --gray-100: #eef0f3;
  --gray-200: #e2e5ea;
  --gray-400: #9aa3b2;
  --gray-600: #5b6472;
  --gray-900: #1c2430;
  --white: #ffffff;
  --max-width: 1320px;
  --radius: 8px;
  --shadow: 0 2px 10px rgba(10, 24, 48, 0.08);
  --shadow-lg: 0 12px 32px rgba(10, 24, 48, 0.14);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, Arial, sans-serif;
  color: var(--gray-900);
  background: var(--white);
  line-height: 1.6;
}

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

a { color: var(--blue-600); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 { line-height: 1.2; margin: 0 0 0.6em; color: var(--navy-900); }
h1 { font-size: 2.4rem; }
h2 { font-size: 1.9rem; }
h3 { font-size: 1.3rem; }
p { margin: 0 0 1em; }

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

.section { padding: 72px 0; }
.section-tight { padding: 48px 0; }
.section-alt { background: var(--gray-50); }
.section-navy { background: var(--navy-900); color: var(--white); }
.section-navy h1, .section-navy h2, .section-navy h3 { color: var(--white); }

.eyebrow {
  display: inline-block;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--green-600);
  margin-bottom: 0.6em;
}
.section-navy .eyebrow { color: #7fd6ac; }

.lede {
  font-size: 1.15rem;
  color: var(--gray-600);
  max-width: 720px;
}
.section-navy .lede { color: #c7d2e8; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-block;
  padding: 13px 26px;
  border-radius: var(--radius);
  font-weight: 600;
  font-size: 0.98rem;
  border: 2px solid transparent;
  cursor: pointer;
}
.btn:hover { text-decoration: none; }
.btn-primary { background: var(--blue-600); color: var(--white); }
.btn-primary:hover { background: var(--blue-500); }
.btn-outline { background: transparent; border-color: rgba(255,255,255,0.55); color: var(--white); }
.btn-outline:hover { background: rgba(255,255,255,0.12); }
.btn-outline-dark { background: transparent; border-color: var(--navy-900); color: var(--navy-900); }
.btn-outline-dark:hover { background: var(--navy-900); color: var(--white); }
.btn-row { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }

/* ---------- Header / Nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--white);
  border-bottom: 1px solid var(--gray-200);
}
.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 76px;
  max-width: calc(var(--max-width) + 260px);
  /* Wider than the body content column so the nav has room to breathe, but
     the left edge is pinned to the same content boundary the logo sits on:
     the extra width only extends right, toward the nav and button, never
     shifting the logo's left edge. Both are derived from --max-width rather
     than repeating the number, so raising the cap cannot knock the logo out
     of alignment with the content below it.

     100% not 100vw. 100vw includes the scrollbar, so it measured 1920 while
     the content column was centring inside the 1905 actually available. That
     pushed the logo 7px right of every heading on the page, at every width
     with a scrollbar. */
  margin-left: max(0px, calc((100% - var(--max-width)) / 2));
  margin-right: 0;
}
.logo {
  display: flex;
  align-items: center;
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--blue-600);
  letter-spacing: 0.02em;
}
.logo span { color: var(--navy-900); }
.logo img { height: 40px; width: auto; display: block; }
.footer-logo img { height: 34px; width: auto; display: block; }

.main-nav ul {
  list-style: none;
  display: flex;
  gap: 20px;
  margin: 0;
  padding: 0;
  align-items: center;
}
.main-nav a {
  color: var(--navy-900);
  font-weight: 600;
  font-size: 0.9rem;
  white-space: nowrap;
}
.main-nav a:hover { color: var(--blue-600); text-decoration: none; }
.main-nav a[aria-current="page"] { color: var(--blue-600); }
.main-nav .is-pending { color: var(--gray-400); cursor: default; }
.main-nav .is-pending:hover { text-decoration: none; color: var(--gray-400); }
.main-nav .btn-primary { color: var(--white); }
.main-nav .btn-primary:hover { color: var(--white); }

.nav-toggle {
  display: none;
  background: none;
  border: none;
  font-size: 1.6rem;
  color: var(--navy-900);
  cursor: pointer;
}

/* ---------- Hero ----------
   Default is gradient-only. To add a background photo on a specific page,
   override background-image directly with an inline style on the
   <section class="hero"> (or .page-hero) tag — see README for the exact
   snippet to copy. (Earlier draft tried routing this through a CSS custom
   property; dropped in favor of this more universally-supported approach.) */
.hero {
  background-color: var(--navy-900);
  background-image: linear-gradient(135deg, var(--navy-900) 0%, var(--navy-800) 60%, var(--navy-700) 100%);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  color: var(--white);
  padding: 88px 0 76px;
  display: flex;
  align-items: flex-start;
}
.hero .container { width: 100%; }
.hero h1, .hero h2, .hero h3 { max-width: 800px; color: var(--white); }
.hero .lede { margin-bottom: 1.6em; color: #c7d2e8; }
.hero .eyebrow { color: #7fd6ac; }

/* ---------- Intro strip (Home "Who We Are" paragraph) ---------- */
.intro-strip {
  padding: 48px 0;
}
.intro-strip-inner {
  display: flex;
  align-items: center;
  gap: 44px;
}
.intro-badge {
  width: 220px;
  flex-shrink: 0;
}
.intro-copy .eyebrow { margin-bottom: 8px; }
.intro-lead {
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--navy-900);
  line-height: 1.5;
  margin: 0 0 12px;
  max-width: 720px;
}
.intro-text {
  font-size: 1.05rem;
  line-height: 1.7;
  color: var(--gray-600);
  margin: 0;
  max-width: 720px;
}
@media (max-width: 760px) {
  .intro-strip-inner { flex-direction: column; text-align: center; gap: 24px; }
  .intro-badge { width: 150px; }
}

/* ---------- Stat bar (kept for reuse elsewhere; not used on Home anymore) ---------- */
.stat-bar {
  background: var(--blue-50);
  border-top: 1px solid var(--gray-200);
  border-bottom: 1px solid var(--gray-200);
}
.stat-bar .container {
  display: flex;
  flex-wrap: wrap;
  gap: 32px;
  justify-content: space-between;
  padding-top: 28px;
  padding-bottom: 28px;
}
.stat {
  flex: 1 1 160px;
  text-align: center;
}
.stat strong {
  display: block;
  font-size: 1.5rem;
  color: var(--navy-900);
  /* Fixed-width digits so a counting number does not jiggle as it climbs. */
  font-variant-numeric: tabular-nums;
}
.stat span {
  font-size: 0.88rem;
  color: var(--gray-600);
}

/* ---------- Card grids ---------- */
.grid {
  display: grid;
  gap: 28px;
}
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-6 { grid-template-columns: repeat(6, 1fr); }

.card {
  background: var(--white);
  border: 1px solid var(--gray-200);
  border-radius: var(--radius);
  padding: 28px;
  box-shadow: var(--shadow);
}

.pair-card {
  padding: 32px;
  border-radius: var(--radius);
  border: 1px solid var(--gray-200);
  background: var(--white);
  display: flex;
  flex-direction: column;
  height: 100%;
}
.pair-card.onshore { border-top: 4px solid var(--blue-600); }
.pair-card.offshore { border-top: 4px solid var(--navy-700); }
.pair-card h3 { font-size: 1.5rem; }
.pair-card ul { padding-left: 1.1em; color: var(--gray-600); margin-bottom: 1.4em; }
.pair-card ul li { margin-bottom: 0.4em; }
.pair-card .btn { margin-top: auto; align-self: flex-start; }

.highlight-card {
  border: 1px solid var(--gray-200);
  border-radius: var(--radius);
  padding: 24px;
  background: var(--white);
  height: 100%;
}
.tag {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 999px;
  margin-bottom: 12px;
}
.tag-onshore { background: var(--blue-50); color: var(--blue-600); }
.tag-offshore { background: #e8edf6; color: var(--navy-700); }
.tag-both { background: #eafaf1; color: var(--green-600); }

.discipline-row {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
}
.discipline-chip {
  flex: 1 1 150px;
  text-align: center;
  padding: 22px 14px;
  border: 1px solid var(--gray-200);
  border-radius: var(--radius);
  background: var(--white);
  font-weight: 600;
  font-size: 0.92rem;
  color: var(--navy-900);
}
.discipline-chip:hover { border-color: var(--blue-600); text-decoration: none; }

.why-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
}
.why-list h3 { font-size: 1.1rem; }
.why-list p { color: var(--gray-600); font-size: 0.96rem; margin-bottom: 0; }

.callout {
  border: 1px solid var(--gray-200);
  background: var(--blue-50);
  border-radius: var(--radius);
  padding: 28px 32px;
  display: flex;
  gap: 24px;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}

.cta-band {
  color: var(--white);
  padding: 44px 0;
  text-align: center;
}
.cta-band h2 { color: var(--white); }
.cta-band .lede { color: #c7d2e8; }
.cta-band .btn-row { justify-content: center; }

/* ---------- Page hero (interior pages) ----------
   Default is gradient-only. To add a photo on a specific page, override
   background-image directly with an inline style — see README. */
.page-hero {
  background-color: var(--navy-900);
  background-image: linear-gradient(135deg, var(--navy-900) 0%, var(--navy-700) 100%);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  color: var(--white);
  padding: 64px 0 56px;
  position: relative;
  overflow: hidden;
}
.page-hero h1, .page-hero h2, .page-hero h3 { color: var(--white); }
.page-hero .lede { color: #c7d2e8; }
.page-hero .eyebrow { color: #7fd6ac; }

/* Decorative hero graphic (Audit, Risk & Compliance page) */
.hero-art {
  position: absolute;
  right: -10px;
  top: 50%;
  transform: translateY(-50%);
  width: 320px;
  height: 320px;
  pointer-events: none;
}
@media (max-width: 900px) {
  .hero-art { display: none; }
}
.evidence-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 20px;
}
/* Text-only evidence cards (no photo) — the plain bulleted items */
.evidence-list li,
.evidence-item {
  border: 1px solid var(--gray-200);
  border-radius: var(--radius);
  padding: 22px 24px;
  background: var(--white);
}
.evidence-list h4,
.evidence-item h4 {
  margin: 0 0 6px;
  color: var(--navy-900);
  font-size: 1.05rem;
}
.evidence-list p,
.evidence-item p { margin: 0; color: var(--gray-600); }

/* ---------- Evidence rows with photos (small thumbnail, alternating side) ----------
   Separate class from .evidence-item above — this is the photo variant only.
   Thumbnail is a fixed small size (same scale as the leader/bio photos), text
   stays the visual lead — the photo is supporting evidence, not a hero image. */
/* Currently unused. The onshore evidence list dropped its photographs on
   2026-09-18 because only three of eight items had one. Kept in place because
   real onshore photography is expected, and the markup note in
   onshore-services.html points back here. */
.evidence-row {
  display: flex;
  align-items: flex-start;
  gap: 22px;
}
.evidence-row.evidence-row--reverse {
  flex-direction: row-reverse;
}
.evidence-media {
  flex: 0 0 200px;
  width: 200px;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.evidence-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Copy block is capped so the paragraph wraps under the title instead of
   stretching edge-to-edge, and pushed away from the photo (margin-left:auto
   when the photo is on the left / normal order, margin-right:auto when
   reversed) so there's real breathing room next to the image. */
.evidence-copy {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 480px;
  margin-left: auto;
}
.evidence-row.evidence-row--reverse .evidence-copy {
  margin-left: 0;
  margin-right: auto;
}
.evidence-row .evidence-copy h4 {
  font-size: 1.2rem;
  margin-bottom: 8px;
  text-align: right;
}
.evidence-row.evidence-row--reverse .evidence-copy h4 {
  text-align: left;
}
.evidence-row .evidence-copy p {
  font-size: 1.02rem;
  text-align: right;
}
.evidence-row.evidence-row--reverse .evidence-copy p {
  text-align: left;
}

@media (max-width: 760px) {
  .evidence-row,
  .evidence-row.evidence-row--reverse {
    flex-direction: row;
  }
  .evidence-media { flex-basis: 140px; width: 140px; }
  .evidence-copy,
  .evidence-row.evidence-row--reverse .evidence-copy {
    max-width: none;
    margin-left: 0;
    margin-right: 0;
  }
  .evidence-row .evidence-copy h4,
  .evidence-row.evidence-row--reverse .evidence-copy h4,
  .evidence-row .evidence-copy p,
  .evidence-row.evidence-row--reverse .evidence-copy p {
    text-align: left;
  }
}

/* ---------- Leadership / Team Lead photos ---------- */
.leader-photo,
.leader-photo-placeholder {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius);
  object-fit: cover;
  margin-bottom: 16px;
  display: block;
}
.leader-photo-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--blue-50);
  color: var(--blue-600);
  font-weight: 700;
  font-size: 2.4rem;
}
.leader-name-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}
.leader-name-row h3 { margin: 0; }
.linkedin-icon {
  display: inline-flex;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  margin-left: auto;
}
.linkedin-icon svg { width: 100%; height: 100%; display: block; }

.note-box {
  border-left: 4px solid var(--green-600);
  background: var(--gray-50);
  padding: 18px 22px;
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 0.94rem;
  color: var(--gray-600);
}

/* ---------- Service grid (foot of every What We Do page) ---------- */
/* One generated block per page, listing the other eight services. The icons are
   the homepage orbit's own, so the two read as one family. Everything is visible
   at once on purpose: someone who has reached the foot of a page is choosing
   where to go next, which is the wrong moment to hide options behind a control.
   Eight tiles fit in four columns without scrolling, so nothing is gained by it. */
/* The block carries its own background rather than inheriting section-alt.
   On five of the nine pages it follows another tinted section, and without
   this they merged into one unbroken slab. The hairline keeps it a distinct
   band wherever it lands, which is the point of a shared component. */
.svc-section {
  background: var(--gray-50);
  border-top: 1px solid var(--gray-200);
}
.svc-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}
.svc-tile {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--gray-200);
  border-radius: var(--radius);
  background: var(--white);
  color: var(--navy-900);
  text-decoration: none;
  transition: border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}
.svc-tile:hover,
.svc-tile:focus-visible {
  border-color: var(--blue-600);
  box-shadow: var(--shadow);
  transform: translateY(-1px);
}
.svc-tile-ico {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--blue-50);
  color: var(--blue-600);
}
.svc-tile-ico svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.svc-tile-name { font-size: 0.92rem; font-weight: 600; line-height: 1.3; }

@media (max-width: 900px) {
  .svc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 480px) {
  .svc-tile { padding: 12px 13px; gap: 10px; }
  .svc-tile-ico { width: 30px; height: 30px; }
  .svc-tile-name { font-size: 0.85rem; }
}

/* ---------- Footer band (shared background for the CTA band + footer) ---------- */
/* The heritage-to-future panorama sits behind the final CTA band and the
   footer together, as one continuous image. Scrim is heaviest at the top
   where the CTA/link content is and lifts toward the bottom so the seabed,
   turbines and satellite read under the content. background-color stays as
   the fallback if the image ever fails to load. Pages with no cta-band
   section just wrap the footer alone in .footer-band. */
.footer-band {
  background-color: var(--navy-900);
  background-image:
    linear-gradient(to bottom, rgba(10,24,48,0.95) 0%, rgba(10,24,48,0.90) 40%, rgba(10,24,48,0.68) 72%, rgba(10,24,48,0.58) 100%),
    url('../img/ground/blueprint-heritage.webp');
  background-size: 100% 100%; 
  background-position: 0px -150px;
  background-repeat: no-repeat;
}
@media (max-width: 900px) {
  .footer-band { background-position: 30% 40%; }
}
@media (max-width: 620px) {
  .footer-band { background-position: 22% 40%; }
}

/* ---------- Footer ---------- */
.site-footer {
  color: #c7d2e8;
  padding: 40px 0 56px;
}
@media (max-width: 900px) {
  .site-footer { padding-bottom: 44px; }
}
@media (max-width: 620px) {
  .site-footer { padding-bottom: 36px; }
}

.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 32px;
  margin-bottom: 28px;
}
.footer-grid h4 {
  color: var(--white);
  font-size: 0.95rem;
  margin-bottom: 14px;
}
.footer-grid ul { list-style: none; margin: 0; padding: 0; }
.footer-grid li { margin-bottom: 8px; }
.footer-grid a { color: #c7d2e8; font-size: 0.92rem; }
.footer-grid a:hover { color: var(--white); }
.footer-logo { font-size: 1.3rem; font-weight: 800; line-height: 1.2; color: var(--white); margin-bottom: 10px; }
.footer-bottom {
  border-top: 1px solid rgba(255,255,255,0.12);
  padding-top: 16px;
  font-size: 0.82rem;
  color: #8ea0c4;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
}

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
  .grid-2, .grid-3, .why-list { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  h1 { font-size: 1.9rem; }
  h2 { font-size: 1.5rem; }
}

/* Nav collapses to the hamburger menu before body content does. Dropped from
   1100px to 940px when the ribbon went from 10 flat links to 5 items plus a
   CTA — fewer, shorter labels need less room, so the desktop nav now survives
   down to tablet width instead of collapsing on wide laptops. */
@media (max-width: 940px) {
  .nav-toggle { display: block; }
  .main-nav {
    display: none;
    position: absolute;
    top: 76px;
    left: 0;
    right: 0;
    background: var(--white);
    border-bottom: 1px solid var(--gray-200);
    box-shadow: var(--shadow-lg);
  }
  .main-nav.is-open { display: block; }
  .main-nav ul {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 8px 24px 20px;
  }
  .main-nav li { border-bottom: 1px solid var(--gray-100); }
  .main-nav a { display: block; padding: 14px 0; }
}

@media (max-width: 760px) {
  .discipline-row { flex-direction: column; }
  .footer-grid { grid-template-columns: 1fr; }
  .stat-bar .container { justify-content: flex-start; }
}

/* ---------- Nav dropdowns ----------
   Added when the ribbon was restructured from 10 flat links to 5 grouped
   items. Two tiers: "What We Do" and "Markets". Opens on hover/focus at
   desktop width, and on click/tap at every width (the aria-expanded rule
   below), so touch devices and keyboard users get the same menu. Mobile
   turns the same markup into a plain accordion inside the hamburger panel. */
.main-nav .has-sub { position: relative; }
.main-nav .sub-toggle {
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--navy-900);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  line-height: inherit;
}
.main-nav .sub-toggle:hover { color: var(--blue-600); }
.main-nav .has-sub.is-active > .sub-toggle { color: var(--blue-600); }
.main-nav .caret {
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  flex: none;
  transition: transform 0.15s ease;
}
.main-nav .sub-toggle[aria-expanded="true"] .caret { transform: rotate(180deg); }
.main-nav .sub-menu {
  display: none;
  list-style: none;
  margin: 0;
  padding: 8px 0;
}
.main-nav .sub-menu a { font-weight: 500; }
.main-nav .sub-toggle[aria-expanded="true"] + .sub-menu { display: block; }

@media (min-width: 941px) {
  /* Full header height so the hover target spans the whole bar and the
     panel drops from the header's bottom edge, not from the text baseline. */
  .main-nav .has-sub { display: flex; align-items: center; height: 76px; }
  .main-nav .sub-menu {
    position: absolute;
    top: 100%;
    left: -18px;
    z-index: 200;
    min-width: 236px;
    background: var(--white);
    border: 1px solid var(--gray-200);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
  }
  .main-nav .sub-menu a { display: block; padding: 10px 18px; }
  .main-nav .sub-menu a:hover { background: var(--gray-50); color: var(--blue-600); }
  .main-nav .has-sub:hover > .sub-menu,
  .main-nav .has-sub:focus-within > .sub-menu { display: block; }
}

@media (max-width: 940px) {
  .main-nav .has-sub { position: static; }
  .main-nav .sub-toggle {
    display: flex;
    width: 100%;
    justify-content: space-between;
    padding: 14px 0;
  }
  .main-nav .sub-menu { padding: 0 0 10px 16px; }
  .main-nav .sub-menu li:last-child { border-bottom: 0; }
  .main-nav .sub-menu a { padding: 11px 0; font-size: 0.88rem; color: var(--gray-600); }
}

/* ==========================================================================
   DRAFTING GROUND - reusable background
   --------------------------------------------------------------------------
   A background that carries the timeline of engineering drawing left to
   right: board drafting (hatched section, dimension lines, bolt circle,
   leader balloon) -> CAD (third-angle projection, isometric, vertex handles,
   revision triangle) -> scan (point cloud, mesh fragment, scan target).

   Drop it on any section that has dead space. Two variants:
     .ground-dark   white linework  - for navy / photo sections
     .ground-light  navy linework   - for white / gray sections

   Add .ground-right to anchor the motif to the right-hand side, which is
   where the dead space usually is on a left-aligned text section.

   Never sets the `opacity` property on the section itself - that would
   cascade to the text. The fade is carried by the pseudo-element only, so
   content above it stays at full strength.
   ========================================================================== */
.ground-dark,
.ground-light { position: relative; overflow: hidden; }

.ground-dark > .container,
.ground-light > .container { position: relative; z-index: 2; }

.ground-dark::after,
.ground-light::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}

.ground-dark::after {
  background-image: url('../img/ground/ground-dark.svg');
  opacity: 0.07;
}
.ground-light::after {
  background-image: url('../img/ground/ground-light.svg');
  opacity: 0.035;
}

/* Anchor the motif right, scaled to the section height, for sections whose
   copy sits on the left. This is the whitespace-filling variant. */
.ground-right::after {
  background-position: right center;
  background-size: auto 118%;
}

/* Dial: pair with either variant when a section needs more or less. */
.ground-faint::after  { opacity: 0.022; }
.ground-strong::after { opacity: 0.11; }

/* The graph-paper base, layered under the motif where you want both. */
.ground-grid { position: relative; }
.ground-grid > .container { position: relative; z-index: 2; }
.ground-grid::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(to right,  rgba(10,24,48,0.035) 0 1px, transparent 1px 28px),
    repeating-linear-gradient(to bottom, rgba(10,24,48,0.035) 0 1px, transparent 1px 28px),
    repeating-linear-gradient(to right,  rgba(10,24,48,0.065) 0 1px, transparent 1px 140px),
    repeating-linear-gradient(to bottom, rgba(10,24,48,0.065) 0 1px, transparent 1px 140px);
}
.ground-dark.ground-grid::before {
  background-image:
    repeating-linear-gradient(to right,  rgba(255,255,255,0.07) 0 1px, transparent 1px 44px),
    repeating-linear-gradient(to bottom, rgba(255,255,255,0.07) 0 1px, transparent 1px 44px),
    repeating-linear-gradient(to right,  rgba(255,255,255,0.14) 0 1px, transparent 1px 220px),
    repeating-linear-gradient(to bottom, rgba(255,255,255,0.14) 0 1px, transparent 1px 220px);
}



/* ---------- MOCK ONLY: bottom row hero ----------
   The block runs along the base of the image instead of stacking in a corner.
   Grid puts the eyebrow above the headline on the left and drops the CTA into
   the right-hand column on the same baseline, so the line of sight travels
   left to right across the bottom and finishes on the button. No markup
   change - the three existing children are placed by grid-area. */
.hero-low {
  display: flex;
  align-items: flex-end;
  min-height: 86vh;
  padding-bottom: 88px;
}
.hero-low .container {
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "eyebrow ."
    "title   cta";
  align-items: end;
  column-gap: 56px;
  row-gap: 4px;
}
.hero-low .eyebrow {
  grid-area: eyebrow;
  margin-bottom: 18px;
}
.hero-low h1 {
  grid-area: title;
  max-width: 26ch;
  line-height: 1.12;
  margin-bottom: 0;
}
.hero-low .btn-row {
  grid-area: cta;
  margin-bottom: 6px;
}
.hero-low .btn-row .btn {
  padding: 16px 34px;
  font-size: 1rem;
  white-space: nowrap;
}

@media (max-width: 900px) {
  .hero-low .container {
    grid-template-columns: 1fr;
    grid-template-areas:
      "eyebrow"
      "title"
      "cta";
    row-gap: 0;
  }
  .hero-low h1 { max-width: none; margin-bottom: 1.4rem; }
  .hero-low .btn-row { margin-bottom: 0; }
}
@media (max-width: 760px) {
  .hero-low { min-height: 78vh; padding-bottom: 52px; }
}

/* ---------- MOCK ONLY: leader line into the CTA ----------
   A drafting leader: a hairline that fades in out of the gap after the
   headline and terminates in an arrowhead at the button, the way a callout
   points at a detail on a drawing. Drawn with pseudo-elements on .btn-row so
   the markup is untouched. Hidden once the layout stacks, where a horizontal
   leader would point at nothing. */
.hero-low .btn-row { position: relative; }
.hero-low .btn-row::before,
.hero-low .btn-row::after {
  content: "";
  position: absolute;
  top: 50%;
  pointer-events: none;
}
.hero-low .btn-row::before {
  right: calc(100% + 15px);
  transform: translateY(-50%);
  width: 72px;
  height: 1px;
  background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.7) 100%);
}
.hero-low .btn-row::after {
  right: calc(100% + 7px);
  transform: translateY(-50%);
  width: 0;
  height: 0;
  border-left: 7px solid rgba(255,255,255,0.8);
  border-top: 4.5px solid transparent;
  border-bottom: 4.5px solid transparent;
}
.hero-low .btn-row .btn {
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.hero-low .btn-row .btn:hover {
  transform: translateX(3px);
  box-shadow: 0 6px 22px rgba(10, 24, 48, 0.45);
}
@media (max-width: 900px) {
  .hero-low .btn-row::before,
  .hero-low .btn-row::after { display: none; }
}

/* ---------- MOCK ONLY: louder leader + hero CTA ----------
   The leader was too faint to pull anyone anywhere. Longer, brighter, with a
   bigger arrowhead. The button gets a hairline ring and a coloured glow so it
   lifts off a dark photograph, and the whole assembly slides right together
   on hover so the arrow reads as pushing you into the button. */
.hero-low .btn-row::before {
  right: calc(100% + 19px);
  width: 118px;
  height: 2px;
  background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.45) 35%, rgba(255,255,255,0.95) 100%);
  transition: width 0.22s ease;
}
.hero-low .btn-row::after {
  right: calc(100% + 6px);
  border-left: 11px solid #ffffff;
  border-top: 7px solid transparent;
  border-bottom: 7px solid transparent;
  transition: transform 0.22s ease;
}
.hero-low .btn-row:hover::before { width: 138px; }
.hero-low .btn-row:hover::after  { transform: translateY(-50%) translateX(5px); }

.btn-hero-cta {
  padding: 20px 42px;
  font-size: 1.08rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  border-radius: 6px;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.22), 0 12px 34px rgba(29,79,216,0.5);
}
.hero-low .btn-row .btn-hero-cta:hover {
  transform: translateX(5px);
  box-shadow: 0 0 0 1px rgba(255,255,255,0.4), 0 16px 42px rgba(29,79,216,0.62);
}
@media (max-width: 760px) {
  .btn-hero-cta { padding: 17px 32px; font-size: 1rem; }
}

/* ---------- MOCK ONLY: life on the leader and the CTA ----------
   Two slow loops, deliberately mostly at rest: the arrowhead nudges toward the
   button, and the button's glow breathes. Long cycles with a hold so it reads
   as a heartbeat rather than a blinking banner. Both stop dead for anyone who
   has asked the OS to reduce motion. */
@keyframes leader-nudge {
  0%, 62%, 100% { transform: translateY(-50%) translateX(0); }
  74%           { transform: translateY(-50%) translateX(7px); }
  86%           { transform: translateY(-50%) translateX(2px); }
}
@keyframes cta-breathe {
  0%, 100% { box-shadow: 0 0 0 1px rgba(255,255,255,0.22), 0 12px 34px rgba(29,79,216,0.50); }
  50%      { box-shadow: 0 0 0 1px rgba(255,255,255,0.38), 0 14px 44px rgba(29,79,216,0.72); }
}
.hero-low .btn-row::after {
  animation: leader-nudge 3.4s ease-in-out infinite;
}
.btn-hero-cta {
  animation: cta-breathe 3.4s ease-in-out infinite;
}
/* Hover takes over from the loop so the two never fight. */
.hero-low .btn-row:hover::after,
.hero-low .btn-row:hover .btn-hero-cta {
  animation: none;
}
@media (prefers-reduced-motion: reduce) {
  .hero-low .btn-row::after,
  .btn-hero-cta { animation: none; }
}

/* ---------- MOCK ONLY: longer leader, whole block lower ----------
   The leader now starts just past the headline and runs the full gap instead
   of floating near the button. The transparent head of the gradient means it
   self-manages as the viewport narrows - it simply fades out earlier rather
   than colliding with the headline - with explicit steps down at the widths
   where that is not enough. Bottom padding cut so the row sits lower in the
   frame. */
.hero-low { padding-bottom: 44px; }
.hero-low .btn-row { margin-bottom: 0; }

.hero-low .btn-row::before {
  width: 340px;
  background: linear-gradient(to right,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,0.18) 22%,
    rgba(255,255,255,0.55) 60%,
    rgba(255,255,255,0.95) 100%);
}
.hero-low .btn-row:hover::before { width: 366px; }

@media (max-width: 1400px) { .hero-low .btn-row::before { width: 240px; } 
                             .hero-low .btn-row:hover::before { width: 264px; } }
@media (max-width: 1150px) { .hero-low .btn-row::before { width: 150px; }
                             .hero-low .btn-row:hover::before { width: 170px; } }
@media (max-width: 760px)  { .hero-low { padding-bottom: 34px; } }

/* ---------- MOCK ONLY: leader to 460, amber CTA ----------
   The button was blue on a blue photograph, so it sank. Amber is the
   complement of the navy, picks up the sunset and the rig lighting already in
   the frame, and is the only warm element on the page. Text is navy rather
   than white because dark-on-amber is the readable pairing. */
.hero-low .btn-row::before { width: 460px; }
.hero-low .btn-row:hover::before { width: 492px; }
@media (max-width: 1400px) { .hero-low .btn-row::before { width: 300px; }
                             .hero-low .btn-row:hover::before { width: 326px; } }
@media (max-width: 1150px) { .hero-low .btn-row::before { width: 160px; }
                             .hero-low .btn-row:hover::before { width: 180px; } }

.btn-hero-cta,
.hero-low .btn-row .btn-hero-cta {
  background: #F5A524;
  color: #0A1830;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.28), 0 12px 34px rgba(245,165,36,0.42);
}
.hero-low .btn-row .btn-hero-cta:hover {
  background: #FFB53D;
  color: #0A1830;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.5), 0 16px 44px rgba(245,165,36,0.58);
}
@keyframes cta-breathe {
  0%, 100% { box-shadow: 0 0 0 1px rgba(255,255,255,0.28), 0 12px 34px rgba(245,165,36,0.42); }
  50%      { box-shadow: 0 0 0 1px rgba(255,255,255,0.45), 0 14px 46px rgba(245,165,36,0.66); }
}

/* ---------- MOCK ONLY: softened amber CTA ----------
   The solid amber slab was too blunt against the photograph. Now a translucent
   amber wash behind a solid amber edge, with light amber type - it still reads
   warm and is still the only warm thing on the page, but the photo shows
   through it. Hover fills it solid, so committing to the click is rewarded.
   backdrop-filter is progressive: without it the wash alone still works. */
.btn-hero-cta,
.hero-low .btn-row .btn-hero-cta {
  background: rgba(245, 165, 36, 0.16);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border: 1.5px solid rgba(245, 165, 36, 0.95);
  color: #FFDCA8;
  box-shadow: 0 8px 26px rgba(10, 24, 48, 0.38);
}
.hero-low .btn-row .btn-hero-cta:hover {
  background: rgba(245, 165, 36, 0.94);
  border-color: #FFB53D;
  color: #0A1830;
  box-shadow: 0 14px 38px rgba(245, 165, 36, 0.45);
}
@keyframes cta-breathe {
  0%, 100% { box-shadow: 0 8px 26px rgba(10,24,48,0.38), 0 0 0 0 rgba(245,165,36,0.30); }
  50%      { box-shadow: 0 8px 26px rgba(10,24,48,0.38), 0 0 0 6px rgba(245,165,36,0.10); }
}

/* ---------- MOCK ONLY: scroll cue ----------
   Sits in the dead centre-bottom of the hero, between the headline on the left
   and the CTA on the right, so it fills the one gap in the row without moving
   anything. Chevron is drawn from borders, no asset. Slow drift down and back,
   stopped for reduced-motion. Grid is told to ignore it so it does not become
   a fourth cell. */
.hero-low { position: relative; padding-bottom: 64px; }
.hero-low .container { position: relative; }

.hero-scroll {
  position: absolute;
  left: 50%;
  bottom: -46px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  text-decoration: none;
  color: rgba(255,255,255,0.72);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
  transition: color 0.2s ease;
}
.hero-scroll:hover { color: #FFDCA8; text-decoration: none; }
.hero-scroll i {
  width: 11px;
  height: 11px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  animation: scroll-drift 2.6s ease-in-out infinite;
}
@keyframes scroll-drift {
  0%, 100% { transform: rotate(45deg) translate(0, 0); opacity: 0.75; }
  50%      { transform: rotate(45deg) translate(3px, 3px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .hero-scroll i { animation: none; } }
@media (max-width: 900px) { .hero-scroll { display: none; } }

/* ---------- MOCK ONLY: partnership row ----------
   Four ways in, sized to the problem rather than four feature cards. Plain
   columns with a rule on top - no boxes, because this is a statement about how
   you engage, not a product grid. grid-4 does not exist in the base sheet. */
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.engage-row { margin-top: 34px; }
.engage-row > div { border-top: 2px solid var(--navy-800); padding-top: 14px; }
.engage-row h4 { font-size: 0.98rem; margin: 0 0 8px; color: var(--navy-900); }
.engage-row p  { font-size: 0.9rem; color: var(--gray-600); margin: 0; line-height: 1.55; }
@media (max-width: 1000px) { .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px)  { .grid-4 { grid-template-columns: 1fr; } }

/* ---------- MOCK ONLY: partnership ground ----------
   Six separate runs converging through a tie-in and leaving as one, drawn in
   the same fine-line language as everything else. Over it, a very faint warm
   wash pulled from the CTA amber, which is where the warmth comes from rather
   than from anything literal. Both on pseudo-elements so no opacity cascades
   onto the text. */
.ground-join { position: relative; overflow: hidden; }
.ground-join > .container { position: relative; z-index: 2; }
.ground-join::before,
.ground-join::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.ground-join::before {
  z-index: 0;
  background:
    radial-gradient(120% 85% at 78% 55%, rgba(245,165,36,0.075) 0%, rgba(245,165,36,0.028) 45%, rgba(245,165,36,0) 72%);
}
.ground-join::after {
  z-index: 1;
  background-image: url('../img/ground/ground-join.svg');
  background-repeat: no-repeat;
  background-position: center right;
  background-size: cover;
  opacity: 0.055;
}
@media (max-width: 900px) { .ground-join::after { opacity: 0.04; background-position: 70% center; } }

/* ---------- MOCK ONLY: blueprint handshake ground ----------
   The drawing is a blueprint, so the section goes navy and lets it read as one
   rather than being bleached out behind white. The scrim is heaviest on the
   left where the copy sits and lifts to the right so the clasp, the dimension
   arrows and the construction circles come through in the open half.
   The engage row is re-coloured for the dark ground. */
.ground-handshake {
  position: relative;
  overflow: hidden;
  background-color: var(--navy-900);
  background-image:
    linear-gradient(to right, rgba(10,24,48,0.96) 0%, rgba(10,24,48,0.90) 34%, rgba(10,24,48,0.62) 62%, rgba(10,24,48,0.48) 100%),
    url('../img/ground/blueprint-handshake.webp');
  background-size: cover;
  background-position: center right;
  background-repeat: no-repeat;
}
.ground-handshake > .container { position: relative; z-index: 2; }
.ground-handshake h2 { color: var(--white); }
.ground-handshake .eyebrow { color: #7fd6ac; }
.ground-handshake .lede { color: #c7d2e8; }
.ground-handshake .engage-row > div { border-top-color: rgba(255,255,255,0.45); }
.ground-handshake .engage-row h4 { color: var(--white); }
.ground-handshake .engage-row p  { color: #a9bcd9; }
@media (max-width: 900px) {
  .ground-handshake {
    background-image:
      linear-gradient(to bottom, rgba(10,24,48,0.95) 0%, rgba(10,24,48,0.88) 55%, rgba(10,24,48,0.72) 100%),
      url('../img/ground/blueprint-handshake.webp');
    background-position: center center;
  }
}

/* ---------- MOCK ONLY: badge to the right ----------
   The badge was pushing the copy inward, so this was the only section whose
   text did not start on the same left margin as the rest of the page. Order
   rather than row-reverse, so alignment and gap behaviour stay as they were.
   Stacks back to badge-first on narrow screens, where a trailing badge would
   just dangle under the paragraph. */
.intro-badge { order: 2; }
.intro-copy  { order: 1; }
@media (max-width: 760px) {
  .intro-strip-inner { flex-direction: column; align-items: flex-start; gap: 24px; }
  .intro-badge { order: 1; }
  .intro-copy  { order: 2; }
}

/* ---------- MOCK ONLY: markets grid ----------
   Six sector markets in place of the onshore/offshore pair. Rule on top rather
   than a box, matching the engagement row, so the page has one card language
   instead of three. */
.market-row { margin-top: 30px; row-gap: 30px; }
.market-card { border-top: 3px solid var(--navy-800); padding-top: 16px; }
.market-card h3 { font-size: 1.12rem; margin: 0 0 9px; }
.market-card p  { font-size: 0.92rem; color: var(--gray-600); margin: 0; line-height: 1.6; }

/* ---------- MOCK ONLY: thin proof strip ----------
   Three named jobs with their scale figure, each a quiet route into Our Work.
   A rule top and bottom rather than cards, so it reads as a band of facts
   between two heavier sections rather than a third grid. */
.proof-strip { border-top: 1px solid var(--gray-200); border-bottom: 1px solid var(--gray-200); }
.proof-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
  align-items: center;
  gap: 34px;
}
.proof-item { display: block; text-decoration: none; border-left: 2px solid var(--gray-200); padding-left: 16px; transition: border-color 0.18s ease; }
.proof-item:hover { text-decoration: none; border-left-color: #F5A524; }
.proof-scale {
  display: block;
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: var(--gray-400);
  margin-bottom: 5px;
}
.proof-name { display: block; font-size: 0.97rem; font-weight: 600; color: var(--navy-900); line-height: 1.35; }
.proof-item:hover .proof-name { color: var(--blue-600); }
.proof-all {
  white-space: nowrap;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--gray-600);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.proof-all:hover { color: var(--blue-600); text-decoration: none; }
.proof-all i { width: 7px; height: 7px; border-top: 1.5px solid currentColor; border-right: 1.5px solid currentColor; transform: rotate(45deg); }
@media (max-width: 1000px) { .proof-row { grid-template-columns: repeat(2, minmax(0,1fr)); row-gap: 26px; } .proof-all { grid-column: 1 / -1; } }
@media (max-width: 620px)  { .proof-row { grid-template-columns: 1fr; } }

/* ---------- MOCK ONLY: capability grid ----------
   Six benches with hand-drawn line icons. One stroke weight, one optical size,
   one level of detail across the whole set, drawn in currentColor so they
   recolour with the card and work on light or dark. No icon font, nothing
   external. */
.cap-grid { margin-top: 34px; row-gap: 38px; }
.cap-card { }
.cap-icon {
  width: 46px;
  height: 46px;
  display: block;
  margin-bottom: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--blue-600);
}
.cap-card h3 { font-size: 1.1rem; margin: 0 0 9px; }
.cap-card p  { font-size: 0.92rem; color: var(--gray-600); margin: 0; line-height: 1.6; }
.cap-section .eyebrow { margin-bottom: 8px; }
@media (max-width: 620px) { .cap-icon { width: 40px; height: 40px; } }

/* ---------- MOCK ONLY: capability orbit ----------
   Six benches on a slow revolving ring, one selected at a time, detail beside
   it. The ring animates and each node counter-animates at the same rate, so
   the icons stay upright while the ring turns. Rotation pauses on hover and on
   selection so nothing moves while you are reading. Navy ground with a radial
   glow behind the hub for the atmosphere. Everything degrades to a readable
   stack with no JS. */
/* The photographic ground under the orbit: rig, subsea spread, globe,
   drillship and onshore refinery in one plate, so the section reads both
   markets at a glance rather than offshore alone. It sits UNDER the ::before
   grid and glow, and the scrim is deliberately heavy - this is a ground, not
   a picture. Content stays on z-index 2 and is never fighting it. */
.cap-orbit-section {
  position: relative;
  overflow: hidden;
  background-color: var(--navy-900);
  color: #c7d2e8;
}
.cap-orbit-section::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(48% 62% at 26% 58%, rgba(56,102,230,0.30) 0%, rgba(56,102,230,0.10) 42%, rgba(10,24,48,0) 72%),
    repeating-linear-gradient(to right,  rgba(255,255,255,0.05) 0 1px, transparent 1px 46px),
    repeating-linear-gradient(to bottom, rgba(255,255,255,0.05) 0 1px, transparent 1px 46px);
}
.cap-orbit-section > .container { position: relative; z-index: 2; }
.cap-orbit-section h2 { color: var(--white); }
.cap-orbit-section .eyebrow { color: #7fd6ac; }

.orbit-wrap {
  display: grid;
  grid-template-columns: 460px minmax(0, 1fr);
  align-items: center;
  gap: 60px;
  margin-top: 30px;
}

/* --- the stage --- */
.orbit-stage { position: relative; width: 460px; height: 460px; }
.orbit-ring-line {
  position: absolute;
  top: 50%; left: 50%;
  border: 1px solid rgba(255,255,255,0.13);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.orbit-ring-1 { width: 360px; height: 360px; }
.orbit-ring-2 { width: 262px; height: 262px; border-style: dashed; border-color: rgba(255,255,255,0.09); }
.orbit-hub {
  position: absolute;
  top: 50%; left: 50%;
  width: 11px; height: 11px;
  margin: -5.5px 0 0 -5.5px;
  border-radius: 50%;
  background: rgba(127,214,172,0.9);
  box-shadow: 0 0 0 7px rgba(127,214,172,0.14), 0 0 26px rgba(127,214,172,0.45);
  pointer-events: none;
}
.orbit-ring {
  position: absolute;
  inset: 0;
  animation: orbit-spin 72s linear infinite;
}
.orbit-node {
  position: absolute;
  top: 50%; left: 50%;
  width: 78px; height: 78px;
  margin: -39px 0 0 -39px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  cursor: pointer;
  background: rgba(10,24,48,0.72);
  border: 1px solid rgba(255,255,255,0.22);
  color: #9fb6d8;
  padding: 0;
  transform: rotate(var(--a)) translate(180px) rotate(calc(-1 * var(--a)));
  animation: orbit-spin-rev 72s linear infinite;
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}
.orbit-node svg { width: 38px; height: 38px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.orbit-node:hover { color: #ffffff; border-color: rgba(255,255,255,0.55); }
.orbit-node.is-active {
  color: #0A1830;
  background: #F5A524;
  border-color: #F5A524;
  box-shadow: 0 0 0 8px rgba(245,165,36,0.16), 0 10px 30px rgba(245,165,36,0.35);
}
@keyframes orbit-spin     { to { transform: rotate(360deg); } }
@keyframes orbit-spin-rev { to { transform: rotate(var(--a)) translate(180px) rotate(calc(-1 * var(--a) - 360deg)); } }

.orbit-stage:hover .orbit-ring,
.orbit-stage:hover .orbit-node,
.orbit-wrap.is-held .orbit-ring,
.orbit-wrap.is-held .orbit-node { animation-play-state: paused; }

/* --- the detail --- */
.orbit-detail { position: relative; min-height: 330px; }
.cap-panel { display: none; }
.cap-panel.is-active { display: block; animation: cap-in 0.28s ease both; }
@keyframes cap-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.cap-panel h3 { color: var(--white); font-size: 1.55rem; margin: 0 0 12px; }
.cap-panel > p { color: #c7d2e8; font-size: 1.02rem; max-width: 52ch; margin: 0 0 20px; }
.cap-panel ul {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 30px;
}
.cap-panel li {
  padding: 9px 0 9px 17px;
  border-bottom: 1px solid rgba(255,255,255,0.11);
  font-size: 0.92rem;
  color: #a9bcd9;
  position: relative;
}
.cap-panel li::before {
  content: "";
  position: absolute;
  left: 0; top: 18px;
  width: 8px; height: 1px;
  background: rgba(245,165,36,0.8);
}

@media (prefers-reduced-motion: reduce) {
  .orbit-ring, .orbit-node { animation: none; }
  .cap-panel.is-active { animation: none; }
}
@media (max-width: 1150px) {
  .orbit-wrap { grid-template-columns: 380px minmax(0,1fr); gap: 40px; }
  .orbit-stage { width: 380px; height: 380px; }
  .orbit-node { transform: rotate(var(--a)) translate(148px) rotate(calc(-1 * var(--a))); width: 66px; height: 66px; margin: -33px 0 0 -33px; }
  @keyframes orbit-spin-rev { to { transform: rotate(var(--a)) translate(148px) rotate(calc(-1 * var(--a) - 360deg)); } }
  .orbit-ring-1 { width: 296px; height: 296px; }
  .orbit-ring-2 { width: 214px; height: 214px; }
}
@media (max-width: 900px) {
  .orbit-wrap { grid-template-columns: 1fr; gap: 34px; }
  .orbit-stage { width: 300px; height: 300px; margin: 0 auto; }
  .orbit-node { transform: rotate(var(--a)) translate(116px) rotate(calc(-1 * var(--a))); width: 56px; height: 56px; margin: -28px 0 0 -28px; }
  .orbit-node svg { width: 28px; height: 28px; }
  @keyframes orbit-spin-rev { to { transform: rotate(var(--a)) translate(116px) rotate(calc(-1 * var(--a) - 360deg)); } }
  .orbit-ring-1 { width: 232px; height: 232px; }
  .orbit-ring-2 { width: 168px; height: 168px; }
  .orbit-detail { min-height: 0; }
  .cap-panel ul { grid-template-columns: 1fr; }
}

/* ---------- MOCK ONLY: orbit core illustration ----------
   The selected capability's drawing sits at the centre and the ring turns
   around it. Flattened onto the section navy so the JPEGs need no alpha and
   stay tiny. Cross-fades with a slight lift on change. */
.orbit-core {
  position: absolute;
  top: 50%; left: 50%;
  width: 250px; height: 250px;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 1;
}
.orbit-core img {
  position: absolute;
  inset: 0;
  margin: auto;
  max-width: 100%;
  max-height: 100%;
  width: auto; height: auto;
  opacity: 0;
  transform: scale(0.94);
  transition: opacity 0.32s ease, transform 0.32s ease;
  mix-blend-mode: screen;
}
.orbit-core img.is-active { opacity: 1; transform: scale(1); }
.orbit-ring { z-index: 2; }

@media (max-width: 1150px) { .orbit-core { width: 200px; height: 200px; } }
@media (max-width: 900px)  { .orbit-core { width: 155px; height: 155px; } }
@media (prefers-reduced-motion: reduce) { .orbit-core img { transition: none; } }

/* ---------- MOCK ONLY: orbit core, second icon set ----------
   The new drawings carry their own pale blueprint ground, so the screen blend
   has to go or it blows them out. They read as a plate held up against the
   navy instead: soft corner, hairline edge, and a drop shadow to lift them off
   the section. */
.orbit-core { width: 268px; height: 268px; }
.orbit-core img {
  mix-blend-mode: normal;
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,0.22);
  box-shadow: 0 18px 44px rgba(0,0,0,0.45);
}
@media (max-width: 1150px) { .orbit-core { width: 214px; height: 214px; } }
@media (max-width: 900px)  { .orbit-core { width: 162px; height: 162px; } }

/* ---------- MOCK ONLY: careers strip ----------
   A line, not a section. Same rule-topped band language as the proof strip, so
   the page closes on a quiet recruiting note without the homepage having to
   argue two cases at once. */
.hire-strip { border-top: 1px solid var(--gray-200); }
.hire-row { display: flex; align-items: center; justify-content: space-between; gap: 40px; }
.hire-eyebrow {
  display: block;
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gray-400); margin-bottom: 7px;
}
.hire-line { font-size: 1.04rem; color: var(--navy-900); margin: 0; max-width: 64ch; font-weight: 500; }
.hire-cta {
  white-space: nowrap; flex: none;
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 0.95rem; font-weight: 600;
  color: var(--navy-900); text-decoration: none;
  border: 1.5px solid var(--navy-900);
  border-radius: 6px; padding: 13px 26px;
  transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease;
}
.hire-cta:hover { background: var(--navy-900); color: var(--white); text-decoration: none; transform: translateX(3px); }
.hire-cta i { width: 7px; height: 7px; border-top: 1.6px solid currentColor; border-right: 1.6px solid currentColor; transform: rotate(45deg); }
@media (max-width: 760px) { .hire-row { flex-direction: column; align-items: flex-start; gap: 22px; } }

/* ---------- MOCK ONLY: dossier ----------
   Not a value proposition. Two columns of facts a project director scans
   before deciding whether you are even eligible: what clears procurement, and
   what has actually been delivered at scale. Mono labels, hairline rows, no
   adjectives. */
.dossier-grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 52px; margin-top: 32px; }
.dossier-h {
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  font-size: 0.76rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--gray-400); margin: 0 0 4px; font-weight: 600;
  border-bottom: 2px solid var(--navy-800); padding-bottom: 12px;
}
.spec-list { margin: 0; }
.spec-list > div { display: grid; grid-template-columns: 116px minmax(0,1fr); gap: 18px; padding: 14px 0; border-bottom: 1px solid var(--gray-200); }
.spec-list dt {
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  font-size: 0.7rem; letter-spacing: 0.1em; color: var(--gray-400); padding-top: 2px;
}
.spec-list dd { margin: 0; font-size: 0.94rem; color: var(--navy-900); line-height: 1.5; }
.dossier-foot {
  margin: 34px 0 0; padding-top: 22px; border-top: 2px solid var(--navy-800);
  font-size: 1.05rem; font-weight: 500; color: var(--navy-900); max-width: 78ch;
}
@media (max-width: 900px) {
  .dossier-grid { grid-template-columns: 1fr; gap: 34px; }
  .spec-list > div { grid-template-columns: 96px minmax(0,1fr); gap: 12px; }
}

/* ---------- MOCK ONLY: why blackfin, plain ----------
   One paragraph. No heading, no table, no cards. Set a little larger than body
   copy and given room, so it reads as the firm speaking quietly rather than
   selling. */
.why-plain { padding-top: 64px; padding-bottom: 64px; }
.why-statement {
  max-width: 62ch;
  font-size: 1.22rem;
  line-height: 1.68;
  color: var(--navy-900);
  margin: 6px 0 22px;
}
.why-closer { max-width: 62ch; font-size: 1rem; color: var(--gray-600); margin: 0; }
.why-closer a { font-weight: 600; }
@media (max-width: 760px) { .why-statement { font-size: 1.1rem; } }

/* ---------- MOCK ONLY: why blackfin balance ----------
   The statement left, a quiet credentials column right, so the band is not
   half empty. The credentials are the procurement facts that were in the
   dossier, returned at a whisper instead of as a twelve-row table. Padding
   pulled in so this and the careers strip stop reading as two pale voids in
   a row. */
.why-plain { padding-top: 56px; padding-bottom: 48px; }
.why-split { display: grid; grid-template-columns: minmax(0,1fr) 300px; gap: 64px; align-items: start; }
.why-statement { max-width: none; font-size: 1.16rem; margin: 6px 0 18px; }
.why-closer { max-width: none; }
.why-creds { margin: 8px 0 0; border-top: 2px solid var(--navy-800); padding-top: 4px; }
.why-creds > div { padding: 11px 0; border-bottom: 1px solid var(--gray-200); }
.why-creds dt {
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gray-400); margin-bottom: 3px;
}
.why-creds dd { margin: 0; font-size: 0.87rem; color: var(--navy-900); line-height: 1.45; }
.hire-strip { padding-top: 26px; padding-bottom: 26px; }
@media (max-width: 900px) { .why-split { grid-template-columns: 1fr; gap: 32px; } }

/* ---------- MOCK ONLY: closing band + section transitions ----------
   The page now closes on careers, because Contact sits in the sticky header
   at all times and the hero already makes the client ask properly.
   Dark sections also get a soft edge top and bottom so they meet the light
   ones with a fade rather than a hard cut. */
.close-band .eyebrow { color: #7fd6ac; }
.close-band h2 { max-width: 22ch; margin-left: auto; margin-right: auto; }
.close-band .lede { max-width: 56ch; margin: 0 auto 1.7em; text-align: center; }

.ground-handshake, .cap-orbit-section { position: relative; }
.ground-handshake::after,
.cap-orbit-section::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  height: 86px;
  pointer-events: none;
  z-index: 3;
}
.ground-handshake::after  { top: 0; background: linear-gradient(to bottom, rgba(247,248,250,0.55) 0%, rgba(10,24,48,0) 100%); }
.cap-orbit-section::after { top: 0; background: linear-gradient(to bottom, rgba(255,255,255,0.5) 0%, rgba(10,24,48,0) 100%); }

/* ---------- MOCK ONLY: closing band as a single line ----------
   Eyebrow and statement left, button right, all on one baseline. The band
   loses its centred heading and its height, so the page finishes on a line
   rather than a block. */
.close-band { padding-top: 38px; padding-bottom: 38px; text-align: left; }
.close-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 48px;
}
.close-band .eyebrow { color: #7fd6ac; margin-bottom: 7px; }
.close-line {
  margin: 0;
  font-size: 1.16rem;
  font-weight: 500;
  color: var(--white);
  max-width: 60ch;
  line-height: 1.45;
}
.close-cta { flex: none; white-space: nowrap; padding: 15px 32px; }
@media (max-width: 760px) {
  .close-row { flex-direction: column; align-items: flex-start; gap: 22px; }
}

/* ---------- MOCK ONLY: scroll cue, quieter ----------
   Smaller, dimmer, tighter. It is a hint, not a label. */
.hero-scroll { font-size: 0.62rem; letter-spacing: 0.2em; gap: 7px; color: rgba(255,255,255,0.5); bottom: -42px; }
.hero-scroll:hover { color: #FFDCA8; }
.hero-scroll i { width: 8px; height: 8px; border-right-width: 1.5px; border-bottom-width: 1.5px; }

/* ---------- MOCK ONLY: orbit polish ----------
   1. Panels stack in one grid cell instead of display none/block, so the box
      is always the height of the tallest and nothing below it shifts when the
      short Digitalization panel is selected. It also fixes the vertical alignment against
      the ring, because the box stops changing size.
   2. Idle nodes brightened. They were reading as disabled rather than
      available.
   3. A hint line, because nothing else said the section does anything. */
.orbit-detail { display: grid; min-height: 0; }
.cap-panel {
  grid-area: 1 / 1;
  display: block;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(8px);
  transition: opacity 0.3s ease, transform 0.3s ease, visibility 0s linear 0.3s;
  animation: none;
}
.cap-panel.is-active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none;
  transition: opacity 0.3s ease, transform 0.3s ease, visibility 0s;
  animation: none;
}

.orbit-node {
  color: #cfe0f6;
  border-color: rgba(255,255,255,0.42);
  background: rgba(10,24,48,0.6);
}
.orbit-node:hover {
  color: #ffffff;
  border-color: #ffffff;
  background: rgba(23,48,92,0.82);
  box-shadow: 0 0 0 6px rgba(255,255,255,0.07);
}
.orbit-node.is-active { color: #0A1830; border-color: #F5A524; }

.orbit-hint {
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  font-size: 0.72rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.45);
  margin: 12px 0 0;
}
@media (prefers-reduced-motion: reduce) { .cap-panel { transition: none; } }

/* ---------- MOCK ONLY: What We Do as a two-column dropdown ----------
   Seven items in one column is a long drop. Two columns keeps it to four rows
   and lets the two market-split service pages sit together at the front. */
@media (min-width: 941px) {
  .main-nav .sub-menu-wide {
    min-width: 470px;
    columns: 2;
    column-gap: 8px;
    padding: 10px 6px;
  }
  .main-nav .sub-menu-wide li { break-inside: avoid; }
  .main-nav .sub-menu-wide a { padding: 9px 16px; }
}

/* Sector cards route into Our Work rather than dead-ending. */
a.market-card { display: block; text-decoration: none; transition: border-color 0.18s ease; }
a.market-card:hover { text-decoration: none; border-top-color: #F5A524; }
a.market-card:hover h3 { color: var(--blue-600); }

/* ---------- MOCK ONLY: What We Do mega menu ----------
   Three headed columns instead of nine flat links: where the work happens,
   what produces it, what assures it. The panel is a div rather than a ul, so
   the base .main-nav ul flex rule does not apply to it. On mobile it flattens
   back to a stacked accordion with the headings kept as dividers. */
.main-nav .sub-mega { display: none; }
.main-nav .sub-toggle[aria-expanded="true"] + .sub-mega { display: block; }

@media (min-width: 941px) {
  .main-nav .sub-mega {
    position: absolute;
    top: 100%;
    left: -22px;
    z-index: 200;
    background: var(--white);
    border: 1px solid var(--gray-200);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 22px 26px 20px;
    grid-template-columns: repeat(3, minmax(170px, auto));
    gap: 0 38px;
  }
  .main-nav .has-sub:hover > .sub-mega,
  .main-nav .has-sub:focus-within > .sub-mega,
  .main-nav .sub-toggle[aria-expanded="true"] + .sub-mega { display: grid; }
  .main-nav .sub-mega ul { display: block; margin: 0; padding: 0; list-style: none; }
  .main-nav .sub-mega li { border: 0; }
  .main-nav .sub-mega a { display: block; padding: 7px 0; font-weight: 500; white-space: nowrap; }
  .main-nav .sub-mega a:hover { color: var(--blue-600); }
}
.mega-h {
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gray-400);
  margin: 0 0 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--gray-200);
}
@media (max-width: 940px) {
  .main-nav .sub-mega { padding: 0 0 10px 16px; }
  .main-nav .sub-mega ul { list-style: none; margin: 0; padding: 0; display: block; }
  .main-nav .sub-mega a { padding: 11px 0; font-size: 0.88rem; color: var(--gray-600); display: block; }
  .mega-h { margin-top: 12px; }
}

/* ---------- MOCK ONLY: mega menu overflow guard ----------
   Three columns at the previous widths pushed past the right edge of the
   viewport and forced a horizontal scrollbar. Tighter columns and gaps, and
   the panel is pinned so it can never extend beyond the page. */
@media (min-width: 941px) {
  .main-nav .sub-mega {
    grid-template-columns: repeat(3, minmax(0, max-content));
    gap: 0 30px;
    padding: 20px 24px 18px;
    max-width: calc(100vw - 40px);
    left: auto;
    right: 0;
  }
  .main-nav .sub-mega a { font-size: 0.92rem; padding: 6px 0; }
  .mega-h { font-size: 0.62rem; }
}
/* the panel is absolutely positioned, so nothing it does should scroll the page */
body { overflow-x: hidden; }

/* ---------- MOCK ONLY: mega menu positioning, corrected ----------
   Anchored to the nav rather than to the button. The nav is right-aligned in
   the header, so pinning the panel's right edge to the nav's right edge means
   it opens leftward into space that always exists, and can never run off the
   screen. The button keeps position static at desktop so the nav is the
   positioning context. */
@media (min-width: 941px) {
  .main-nav { position: relative; }
  .main-nav .has-sub { position: static; }
  .main-nav .sub-mega {
    left: auto;
    right: 0;
    width: max-content;
    max-width: min(700px, calc(100vw - 48px));
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0 34px;
  }
}
@media (min-width: 941px) and (max-width: 1150px) {
  .main-nav .sub-mega { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: calc(100vw - 48px); }
}

/* ---------- MOCK ONLY: engineering disciplines datasheet ----------
   Lifted out of the v6 experiment so the page stops carrying its own
   <style> block. Sheets, title blocks, plates and the toolset table. */


.sheet-intro { max-width: 68ch; }

.sheet-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  margin-top: 32px;
}
.sheet {
  border: 1px solid var(--gray-200);
  border-top: 3px solid var(--navy-800);
  border-radius: 0;
  background: var(--white);
  display: flex;
  flex-direction: column;
}
.sheet-head { padding: 20px 22px 0; }
.sheet-head h3 { margin: 0 0 6px; font-size: 1.15rem; }
.sheet-head p { color: var(--gray-600); font-size: 0.93rem; margin: 0 0 14px; }

.sheet-body { padding: 0 22px 18px; flex: 1; }
.sheet-body ul {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--gray-100);
}
.sheet-body li {
  font-size: 0.88rem;
  color: var(--gray-900);
  padding: 7px 0 7px 16px;
  border-bottom: 1px solid var(--gray-100);
  position: relative;
}
.sheet-body li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 15px;
  width: 7px;
  height: 1px;
  background: var(--gray-400);
}

/* The title block: densest information on the sheet, anchored at the foot. */
.spec {
  border-top: 1px solid var(--gray-200);
  background: var(--gray-50);
  padding: 12px 22px 14px;
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  font-size: 0.73rem;
  line-height: 1.6;
}
.spec div { display: flex; gap: 10px; }
.spec div + div { margin-top: 4px; }
.spec dt {
  color: var(--gray-400);
  letter-spacing: 0.08em;
  flex: none;
  width: 74px;
}
.spec dd { margin: 0; color: var(--navy-800); }

.toolset { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px; margin-top: 28px; }
.tool-group { border-top: 2px solid var(--navy-800); padding-top: 12px; }
.tool-group h4 { font-size: 0.82rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--gray-600); margin: 0 0 10px; }
.tool-group ul { list-style: none; margin: 0; padding: 0; font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace; font-size: 0.8rem; }
.tool-group li { padding: 4px 0; border-bottom: 1px solid var(--gray-100); display: flex; justify-content: space-between; gap: 12px; }
.tool-group li span { color: var(--gray-400); font-size: 0.72rem; text-align: right; }

.plate { border: 1px solid var(--gray-200); background: var(--white); }
.plate img { width: 100%; height: 190px; object-fit: cover; display: block; }
.plate figcaption {
  padding: 10px 14px;
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  font-size: 0.74rem;
  color: var(--gray-600);
  border-top: 1px solid var(--gray-200);
}

@media (max-width: 900px) {
  .sheet-grid { grid-template-columns: 1fr; }
  .toolset { grid-template-columns: 1fr; }
}

/* ============================================================
   BLUEPRINT GROUND
   Never uses the `opacity` property - that cascades to children and
   washes out the text with it. The fade lives inside rgba() in the
   gradients, painted by a pseudo-element that sits behind content and
   ignores the mouse. Two tiers of line, like real drafting paper:
   fine minor divisions plus a heavier major, which also stops the fine
   grid moireing on scroll.
   Pure CSS gradients - no image asset, no external dependency, so this
   still works on local IIS with no internet.
   ============================================================ */

/* --- Hero: white lines on blue. This is the actual blueprint. --- */
.page-hero { position: relative; overflow: hidden; }
.page-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background-image:
    repeating-linear-gradient(to right,  rgba(255,255,255,0.13) 0 1px, transparent 1px 44px),
    repeating-linear-gradient(to bottom, rgba(255,255,255,0.13) 0 1px, transparent 1px 44px),
    repeating-linear-gradient(to right,  rgba(255,255,255,0.26) 0 1px, transparent 1px 220px),
    repeating-linear-gradient(to bottom, rgba(255,255,255,0.26) 0 1px, transparent 1px 220px);
}
.page-hero .container { position: relative; z-index: 2; }

/* Registration marks, bottom corners of the hero - the drafting detail
   that does the work without announcing itself. */
.page-hero::before {
  content: "";
  position: absolute;
  left: 28px;
  bottom: 22px;
  width: 26px;
  height: 26px;
  border-left: 1px solid rgba(255,255,255,0.40);
  border-bottom: 1px solid rgba(255,255,255,0.40);
  z-index: 2;
  pointer-events: none;
}

/* --- Body: drafting paper, barely there. Under a 5% luminance delta
       so body copy never has to fight it. --- */
.section-alt { position: relative; }
.section-alt::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image:
    repeating-linear-gradient(to right,  rgba(10,24,48,0.035) 0 1px, transparent 1px 28px),
    repeating-linear-gradient(to bottom, rgba(10,24,48,0.035) 0 1px, transparent 1px 28px),
    repeating-linear-gradient(to right,  rgba(10,24,48,0.065) 0 1px, transparent 1px 140px),
    repeating-linear-gradient(to bottom, rgba(10,24,48,0.065) 0 1px, transparent 1px 140px);
}
.section-alt .container { position: relative; z-index: 1; }

/* --- The sheets sit ON the paper: solid white knocks the grid out
       behind them, so the cards read as drawings laid on a desk. --- */
.sheet { position: relative; background: var(--white); }

/* Corner tick, top-right of each sheet - a drawing-sheet cue at the
   scale where it reads as precision rather than decoration. */
.sheet::after {
  content: "";
  position: absolute;
  top: 10px;
  right: 10px;
  width: 12px;
  height: 12px;
  border-top: 1px solid var(--gray-400);
  border-right: 1px solid var(--gray-400);
  pointer-events: none;
}

/* --- CTA band gets the blue ground too, closing the page the way it
       opened. --- */
.cta-band { position: relative; overflow: hidden; }
.cta-band::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image:
    repeating-linear-gradient(to right,  rgba(255,255,255,0.06) 0 1px, transparent 1px 44px),
    repeating-linear-gradient(to bottom, rgba(255,255,255,0.06) 0 1px, transparent 1px 44px),
    repeating-linear-gradient(to right,  rgba(255,255,255,0.12) 0 1px, transparent 1px 220px),
    repeating-linear-gradient(to bottom, rgba(255,255,255,0.12) 0 1px, transparent 1px 220px);
}
.cta-band .container { position: relative; z-index: 1; }

/* --- Toolset reads as a parts schedule on the paper. --- */
.tool-group { background: transparent; }

@media (prefers-reduced-motion: no-preference) {
  /* nothing animates - noted deliberately so nobody adds a parallax grid later */
}

/* --- One sheet per row, deliverables in three columns. The items are short
       phrases: at 1320px a three-column flow gives each about 50 characters,
       which is wide enough that almost nothing wraps and narrow enough that
       no row trails off into dead space. Cards become wide and short instead
       of narrow and tall - a datasheet rather than a list. --- */
.sheet-grid { grid-template-columns: 1fr; gap: 20px; }
.sheet-head p { max-width: 78ch; }
.sheet-body ul { column-count: 3; column-gap: 32px; }
.sheet-body li { break-inside: avoid; page-break-inside: avoid; }
@media (max-width: 1100px) { .sheet-body ul { column-count: 2; } }
@media (max-width: 760px)  { .sheet-body ul { column-count: 1; } }



/* ---------- MOCK ONLY: standard interior hero ----------
   Two things were wrong. Height was coming from however long that page's
   headline happened to be, so About shrank the moment its h1 went from two
   lines to one - fixed with a floor and the copy bottom-aligned. Then the
   floor itself was set far too high: 72px of padding on top of a band that
   already sat under a 77px sticky header put nearly 480px between the top of
   the window and the first line of real content. The header is in flow, so
   none of that padding was clearing anything. Numbers below are tight on
   purpose - the band should frame the headline, not be the page.

   The measure is set so a headline of about sixty characters wraps to two
   lines and a lede of about a hundred and twenty wraps to one, which is the
   budget every interior headline is now written to. */
.page-hero {
  /* Was a flat 300px. That is right on a laptop but a letterbox on a wide
     monitor: the hero artwork is roughly 2.4:1, so at 1920 it wants 799px of
     height and a 300px band showed 38% of it, cropping the middle out of the
     picture. Fluid between 300 and 440 keeps the laptop look unchanged and
     lets the band breathe on a big screen. */
  min-height: clamp(300px, 21vw, 440px);
  display: flex;
  align-items: flex-end;
  padding-top: 40px;
  padding-bottom: 38px;
}
.page-hero > .container { width: 100%; }
.page-hero h1 { max-width: 30ch; margin-bottom: 14px; }
.page-hero .lede { max-width: 62ch; margin-bottom: 0; }
@media (max-width: 760px) {
  .page-hero { min-height: 210px; padding-top: 32px; padding-bottom: 28px; }
  .page-hero h1, .page-hero .lede { max-width: none; }
}

/* ---------- MOCK ONLY: Meet the team banner ----------
   A divider announcing the three people sections below it - not evidence, and
   not a hero. It takes the same 300px band and the same heading size as every
   other section on the site so it reads as punctuation rather than a claim.

   An earlier pass held the plate's own 2154x730 proportion, which made it
   482px tall at 1440 and 644px on a wide monitor - taller than the page hero
   above it, for a section that is only saying "here comes the team". Fixed
   band height with a cover crop instead; the group is centred in the artwork
   so it survives the crop at every width.

   No cache-buster needed here any more: the move to WebP changed the filename,
   which is what defeats the week-long assets/img cache. */
.team-banner {
  min-height: 300px;
  background-color: var(--navy-900);
  background-image:
    linear-gradient(to bottom, rgba(10,24,48,0.55) 0%, rgba(10,24,48,0.30) 45%, rgba(10,24,48,0.45) 100%),
    url('../img/ground/meet-the-team.webp');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--white);
  padding: 40px 0;
}
.team-banner > .container { width: 100%; }
.team-banner h2 {
  color: var(--white);
  margin-bottom: 10px;
}
.team-banner p {
  color: #dbe4f5;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 0.85rem;
  margin-bottom: 0;
}
@media (max-width: 760px) {
  .team-banner { min-height: 220px; padding: 32px 0; }
  .team-banner p { letter-spacing: 0.12em; font-size: 0.75rem; }
}

/* ---------- MOCK ONLY: rising-figure marker ----------
   The man-hours figure is not a fixed achievement, it keeps accruing. The
   caret says so without needing a word for it. aria-hidden in the markup so
   a screen reader announces the number rather than a stray triangle, and it
   is an HTML entity rather than an icon font so it renders offline on the
   local IIS box like everything else here. */
.stat span .stat-rising,
.stat-rising {
  color: var(--green-600);
  font-size: 0.62em;
  vertical-align: 0.28em;
  margin-left: 3px;
  letter-spacing: 0;
}

/* ---------- MOCK ONLY: the ground under the orbit, on a rotation ----------
   A continuous one-way pan, not a bounce. The problem with looping a
   photograph is the seam: this plate opens on a sunset sky and closes on a
   refinery, so butting copies end to end gives you a hard cut every cycle.

   Solved by mirroring. The track is four tiles - A, A-flipped, A, A-flipped.
   Where two tiles meet, the flipped one presents the same pixels as its
   neighbour's edge, so every join is invisible. The pattern repeats every two
   tiles, so translating the track exactly -50% of its width lands on a frame
   pixel-identical to the start: the loop closes with nothing to see.

   It animates transform, not background-position. background-position
   repaints the whole 2.3MB plate every frame; a transform on its own layer is
   composited on the GPU and costs the main thread nothing, which matters
   because the orbit sitting on top of it is animating too.

   linear, not ease - a rotation runs at constant speed. 140s covers two full
   section widths of travel, slow enough that it registers as depth rather
   than as something moving.

   z-index 0 keeps the whole thing under the ::before grid and glow and under
   the content, so the section holds its drawing-board character and the photo
   only ever adds depth behind it. The scrim rides on ::after, above the
   tiles, so it does not travel with them. */
.orbit-ground {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.orbit-ground-track {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 400%;
  display: flex;
  will-change: transform;
  animation: orbit-ground-rotate 140s linear infinite;
}
.orbit-ground-tile {
  flex: 0 0 25%;
  background-image: url('../img/ground/capability-orbit.webp');
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.orbit-ground-tile.is-flipped { transform: scaleX(-1); }
.orbit-ground::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom,
    rgba(10,24,48,0.93) 0%,
    rgba(10,24,48,0.84) 32%,
    rgba(10,24,48,0.86) 70%,
    rgba(10,24,48,0.94) 100%);
}
@keyframes orbit-ground-rotate {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}
/* Anyone who has asked their OS for less motion gets the plate held still. */
@media (prefers-reduced-motion: reduce) {
  .orbit-ground-track { animation: none; }
}

/* ---------- MOCK ONLY: vision and core principles ----------
   Replaces the offices block on About. The vision line is set as a statement
   rather than a heading-sized slab - it is one sentence and it should read
   like one. The principles are a definition list because that is literally
   what they are: a term and its meaning. Two columns on desktop so five
   items do not become a long scroll, one column below 760px. */
/* Runs out to within about 60px of the principles grid below it, so the two
   blocks read as one column rather than a narrow statement floating above a
   wide grid. 60ch lands it on two lines; the cap stops it becoming one very
   long line on a wide monitor. */
.vision-line {
  max-width: 60ch;
  margin-bottom: 44px;
}
.principles-eyebrow { margin-bottom: 18px; }
.principles {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 28px 48px;
  margin: 0;
}
.principles > div {
  border-top: 1px solid var(--gray-200);
  padding-top: 16px;
}
.principles dt {
  font-weight: 700;
  color: var(--navy-900);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.86rem;
  margin-bottom: 7px;
}
/* The tagline rides on the same line as the term, in the body colour, so the
   term stays the thing you scan for. */
.principles dt span {
  display: inline;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.95rem;
  color: var(--green-600);
  margin-left: 10px;
}
.principles dd {
  margin: 0;
  color: var(--gray-700);
  font-size: 0.95rem;
  line-height: 1.6;
}
@media (max-width: 760px) {
  .principles { grid-template-columns: 1fr; gap: 22px; }
  .principles dt span { display: block; margin-left: 0; margin-top: 3px; }
}

/* ---------- MOCK ONLY: joined closing band ----------
   The default .close-row pushes the statement hard left and the button hard
   right with the whole container between them, so the two read as unrelated
   furniture at opposite ends of a dark strip. This variant centres them as a
   pair and runs a drafting leader from the statement into the button, so the
   question and its answer are visibly one thing.

   Same leader as the homepage hero - hairline fading in out of the gap,
   terminating in an arrowhead at the button - reused rather than reinvented,
   and it extends on hover so the arrow reads as pushing you into the button.
   The margin on the button is what opens the gap the leader spans. Below
   760px the row stacks and a horizontal leader would point at nothing, so it
   goes away and the margin resets. */
.close-row--joined {
  justify-content: center;
  gap: 0;
}
.close-row--joined .close-line { max-width: none; }
.close-row--joined .close-cta {
  position: relative;
  margin-left: 152px;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.close-row--joined .close-cta::before,
.close-row--joined .close-cta::after {
  content: "";
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
}
.close-row--joined .close-cta::before {
  right: calc(100% + 19px);
  width: 118px;
  height: 2px;
  background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.45) 35%, rgba(255,255,255,0.95) 100%);
  transition: width 0.22s ease;
}
.close-row--joined .close-cta::after {
  right: calc(100% + 6px);
  width: 0;
  height: 0;
  border-left: 11px solid #ffffff;
  border-top: 7px solid transparent;
  border-bottom: 7px solid transparent;
  transition: transform 0.22s ease;
}
.close-row--joined .close-cta:hover::before { width: 138px; }
.close-row--joined .close-cta:hover::after  { transform: translateY(-50%) translateX(5px); }
.close-row--joined .close-cta:hover {
  transform: translateX(3px);
  box-shadow: 0 6px 22px rgba(10, 24, 48, 0.45);
}
@media (max-width: 760px) {
  .close-row--joined { justify-content: flex-start; }
  .close-row--joined .close-cta { margin-left: 0; }
  .close-row--joined .close-cta::before,
  .close-row--joined .close-cta::after { display: none; }
}

/* ---------- MOCK ONLY: hero back into proportion ----------
   The hero was min-height: 86vh, so it scaled with the window and took 774px
   of a 900px screen - with the 77px header above it, the whole first screen
   was hero and nothing else. On a tall monitor it got worse, because vh has
   no ceiling.

   clamp gives it a floor and a roof: never shorter than 420px on a laptop in
   a short window, never taller than 620px on a big display, and 62vh in
   between. At 900px tall that lands around 560px, which leaves roughly 260px
   of the section below showing - enough that the page reads as having
   somewhere to go, which is the whole job of the scroll cue sitting in it. */
.hero-low {
  min-height: clamp(420px, 62vh, 620px);
  padding-bottom: 64px;
}
@media (max-width: 760px) {
  .hero-low { min-height: clamp(360px, 62vh, 520px); padding-bottom: 44px; }
}

/* ---------- Capability layout (Offshore Services) ----------
   A section head with a strapline rule beside it, a photographic panel paired
   with capability cards, a dark coverage band, selected work, and a lifecycle
   bar. The first version of this had no imagery in the body at all and read as
   a spec sheet; the panel and the dark band are what give the page weight. */
.sec-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 40px;
  align-items: end;
}
.sec-head h2 { max-width: 30ch; margin-bottom: 0; font-size: clamp(1.6rem, 2.4vw, 2.2rem); }
.sec-strap { border-left: 2px solid var(--gray-200); padding-left: 20px; max-width: 220px; }
.sec-strap p {
  margin: 0; font-size: 0.74rem; letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--navy-800); font-weight: 600; line-height: 2;
}
.sec-strap span { display: block; width: 36px; height: 3px; background: var(--green-600); margin-top: 14px; }

/* Photo panel beside the cards. */
.cap-split {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.5fr);
  gap: 24px;
  margin-top: 36px;
  align-items: stretch;
}
.cap-figure {
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  min-height: 460px;
  box-shadow: var(--shadow-lg);
  background: var(--navy-900);
}
.cap-figure img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cap-figure figcaption {
  position: absolute; inset: auto 0 0 0;
  padding: 22px 22px 20px;
  background: linear-gradient(to top, rgba(10,24,48,0.92) 0%, rgba(10,24,48,0.55) 60%, rgba(10,24,48,0) 100%);
  color: #fff;
}
.cap-figure .kicker {
  font-size: 0.68rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: #7fd6ac; margin: 0 0 6px;
}
.cap-figure strong { display: block; font-size: 1.02rem; line-height: 1.35; font-weight: 600; }

.cap-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; align-content: start; }
/* Five services into a two-column grid leaves the last one orphaned, so it
   takes the full width of the final row instead of half of it. */
.cap-cards > :last-child:nth-child(odd) { grid-column: 1 / -1; }
.cap-card {
  border: 1px solid var(--gray-200);
  border-radius: var(--radius);
  background: var(--white);
  padding: 22px;
  transition: border-color 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}
.cap-card:hover { border-color: var(--blue-600); box-shadow: var(--shadow); transform: translateY(-2px); }
.cap-card-ico {
  display: grid; place-items: center; width: 48px; height: 48px;
  border-radius: 12px; background: var(--blue-50); color: var(--blue-600); margin-bottom: 16px;
}
.cap-card-ico svg {
  width: 28px; height: 28px; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
.cap-card h3 { font-size: 1.05rem; margin-bottom: 8px; }
.cap-card p { font-size: 0.92rem; color: var(--gray-600); margin: 0; line-height: 1.6; }

/* Dark coverage band: the page needs one anchor that is not white. */
.coverage-band {
  background-color: var(--navy-900);
  background-image:
    linear-gradient(to right, rgba(10,24,48,0.96) 0%, rgba(10,24,48,0.80) 55%, rgba(10,24,48,0.62) 100%),
    url('../img/ground/blueprint-heritage.webp');
  background-size: cover;
  background-position: center;
  color: #fff;
}
.coverage-band h2 { color: #fff; max-width: 24ch; margin-bottom: 0; }
.coverage-band .eyebrow { color: #7fd6ac; }
.coverage-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); gap: 40px; align-items: start; }
.coverage-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px 28px; }
.coverage-list li {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 9px 0; font-size: 0.95rem; color: #dbe5f5;
  border-bottom: 1px solid rgba(255,255,255,0.10);
}
.coverage-list li svg {
  flex: 0 0 auto; width: 18px; height: 18px; margin-top: 2px;
  fill: none; stroke: #7fd6ac; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
}
.coverage-foot {
  margin: 18px 0 0; font-size: 0.7rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: #8fa3c4; line-height: 1.9;
}

/* Selected work. */
.work-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: 18px; margin-top: 30px; }
.work-card {
  border: 1px solid var(--gray-200); border-radius: var(--radius); background: var(--white);
  padding: 22px; display: flex; flex-direction: column;
  border-top: 3px solid var(--blue-600);
  transition: box-shadow 0.18s ease, transform 0.18s ease;
}
.work-card:hover { box-shadow: var(--shadow); transform: translateY(-2px); }
.work-card .where {
  font-size: 0.68rem; letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--green-600); margin-bottom: 9px; font-weight: 600;
}
.work-card h3 { font-size: 1rem; margin-bottom: 9px; line-height: 1.35; }
.work-card p { font-size: 0.88rem; color: var(--gray-600); line-height: 1.6; margin-bottom: 16px; }
.work-tags { margin-top: auto; display: flex; flex-wrap: wrap; gap: 6px; }
.work-tags span {
  font-size: 0.72rem; background: var(--blue-50); color: var(--navy-800);
  border-radius: 100px; padding: 4px 11px;
}
.head-row { display: flex; align-items: baseline; justify-content: space-between; gap: 24px; flex-wrap: wrap; }

/* Lifecycle bar. Arrow shape on wide screens, plain stacked rows below. */
.flow { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; margin-top: 30px; }
.flow-step {
  background: var(--gray-50); border: 1px solid var(--gray-200);
  padding: 20px 20px 20px 32px;
  clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 50%, calc(100% - 16px) 100%, 0 100%, 16px 50%);
}
.flow-step:first-child { clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 50%, calc(100% - 16px) 100%, 0 100%); padding-left: 22px; }
.flow-step:last-child  { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 16px 50%); }
.flow-step em { display: block; font-style: normal; font-size: 0.7rem; letter-spacing: 0.12em; color: var(--green-600); font-weight: 700; margin-bottom: 4px; }
.flow-step strong { display: block; font-size: 0.95rem; color: var(--navy-900); }
.flow-step span { display: block; font-size: 0.8rem; color: var(--gray-600); margin-top: 3px; line-height: 1.45; }

@media (max-width: 1100px) {
  .cap-split { grid-template-columns: minmax(0, 1fr); }
  .cap-figure { min-height: 320px; }
  .coverage-grid { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .flow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .flow-step, .flow-step:first-child, .flow-step:last-child { clip-path: none; padding: 16px; border-radius: var(--radius); }
}
@media (max-width: 760px) {
  .sec-head { grid-template-columns: minmax(0, 1fr); gap: 20px; align-items: start; }
  .sec-strap { border-left: 0; border-top: 2px solid var(--gray-200); padding-left: 0; padding-top: 14px; max-width: none; }
  .cap-cards { grid-template-columns: minmax(0, 1fr); }
  .coverage-list { grid-template-columns: minmax(0, 1fr); }
  .flow { grid-template-columns: minmax(0, 1fr); }
}
