/* =========================================================================
   ANVIAM — 2026 design system
   A ruled, typographic light canvas carrying the Anviam blue gradient: dark
   gradient bookends (header/hero and closing CTA/footer) with a colour-coded
   capability system in between. Hierarchy comes from type and whitespace;
   colour does the work of signalling and delight.
   ========================================================================= */

:root {
  /* ink */
  --ink: #08131f;
  --ink-70: #3d4c5c;
  /* Darker than the usual slate-500. Body copy no longer sits on white — it
     sits on the tinted canvas and on the deeper .wash ground — and #64748b
     measures 4.07:1 there, under the 4.5:1 that 15-16px text needs. This value
     clears it on the darkest light ground the page paints. */
  --ink-50: #59687b;
  /* Decorative only: arrow glyphs and similar. At 2.9:1 on white it must never
     be used for text — see the comment on .role-card small. */
  --ink-35: #8b9aab;

  /* rules + surfaces */
  --line: rgba(8, 60, 95, .13);
  --line-soft: rgba(8, 60, 95, .08);
  --surface: #ffffff;
  --surface-2: #f7fafc;
  --surface-3: #eef4f8;

  /* The page ground. Deliberately NOT white: cards, tiles and panels are white,
     and they only read as raised objects if the sheet behind them is a shade
     down. A long run of white sections with white cards on top is what made the
     middle of the page look unfinished. */
  --canvas: #eef5fa;

  /* ---- Anviam brand ramp: deep navy through to sky ---- */
  --brand-950: #041320;
  --brand-900: #061e33;
  --brand-800: #0a3352;
  --brand-700: #084f76;
  --brand-600: #08719b;
  --brand-500: #0d9bd3;
  --brand-400: #4cc2f0;
  --brand-300: #8ddbf8;

  /* the signature gradient, in the three angles the page needs */
  --grad-brand: linear-gradient(120deg, #08719b 0%, #0d9bd3 52%, #4cc2f0 100%);
  /* The bar tops out at #08719b rather than running on to #0d9bd3: the phone
     number and nav sit on its right half, and white text needs a ground no
     lighter than ~0.18 luminance to clear 4.5:1. #08719b is 0.14, #0d9bd3 is
     0.28 — the brighter ramp would have put the header links under the bar. */
  --grad-bar: linear-gradient(100deg, #061e33 0%, #0a3352 34%, #0a6a92 74%, #08719b 100%);
  --grad-deep: linear-gradient(168deg, #041320 0%, #061e33 34%, #0a3352 66%, #084f76 100%);
  /* Text gradients stop short of the brand's lightest tints on purpose. #4cc2f0
     on white is 1.9:1 — it looks like the brand but fails even the 3:1 bar for
     large text, so the ramp for gradient *type* tops out at #0f8fc2 (3.7:1). */
  --grad-text: linear-gradient(96deg, #05506f, #0a7ba9 55%, #0f8fc2);

  /* dark-ground helpers */
  --dark: #041320;
  --dark-2: #0a2338;
  --dark-line: rgba(140, 200, 235, .17);

  /* accent — brand blue for links, eyebrows, focus */
  --accent: #0a6f9e;
  --accent-ink: #085a80;
  --accent-tint: rgba(13, 155, 211, .09);

  /* capability hues, as space-separated triplets so rgb(var(--c) / a) works */
  --h-blue: 13 155 211;
  --h-violet: 124 58 237;
  --h-teal: 13 148 136;
  --h-sky: 2 132 199;
  --h-rose: 225 29 72;
  --h-indigo: 79 70 229;
  --h-cyan: 8 145 178;
  --h-amber: 194 105 6;
  --h-fuchsia: 174 34 190;
  --h-emerald: 5 150 105;

  --grad-text-light: linear-gradient(96deg, #4cc2f0, #8ddbf8 70%, #d8f2fe);

  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  --page: 1180px;
  --gutter: 24px;
  --r: 10px;
  --r-lg: 16px;
  --ease: cubic-bezier(.22, 1, .36, 1);

  /* tinted rather than neutral shadows — grey shadows on a blue-tinted page
     read as dirt, blue-tinted ones read as depth */
  --lift: 0 1px 2px rgba(8, 60, 95, .05), 0 12px 28px -14px rgba(8, 60, 95, .16);
  --lift-lg: 0 2px 4px rgba(8, 60, 95, .05), 0 30px 60px -28px rgba(8, 60, 95, .3);
}

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  overflow-x: hidden;
}

body {
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-70);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: 'cv11' 1;
  /* clip, NOT hidden. overflow-x:hidden here computed to "hidden auto", which
     made body a scroll container — and a sticky child sticks to its nearest
     scrolling ancestor. body never scrolls (the viewport does), so #top stuck
     to a box that never moved and scrolled off the screen with the page. clip
     does the same visual job without creating a scroll container.
     The overflow-x on html above is the real safety net: it propagates to the
     viewport, so a stray wide element still cannot produce a horizontal
     scrollbar even where clip is unsupported. */
  overflow-x: clip;
}

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

/* Icon default. Every inline glyph is sized by a class rule below; this is the
   floor so a missed one can't fall back to the 300x150 SVG default and blow up
   a layout. Lowest specificity, so every class rule still wins. */
svg {
  width: 16px;
  height: 16px;
}

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

ul,
ol {
  list-style: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 3px;
}

/* ---------- type scale ---------- */
h1,
h2,
h3,
h4 {
  color: var(--ink);
  font-weight: 600;
  letter-spacing: -.03em;
  line-height: 1.12;
}

.display {
  font-size: clamp(2.6rem, 5.6vw, 4.25rem);
  letter-spacing: -.042em;
  line-height: 1.04;
  font-weight: 600;
}

h2 {
  font-size: clamp(1.85rem, 3.3vw, 2.6rem);
  letter-spacing: -.035em;
}

h3 {
  font-size: 1.0625rem;
  letter-spacing: -.014em;
  line-height: 1.35;
}

p {
  color: var(--ink-50);
}

strong {
  color: var(--ink);
  font-weight: 550;
}

/* small uppercase label used above section headings. The gradient is painted
   into the glyphs; `color` stays set as the fallback for any engine that skips
   background-clip:text, so the eyebrow can never render invisible. */
.label {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--brand-600);
  margin-bottom: 18px;
}

.label::before {
  content: '';
  width: 26px;
  height: 2px;
  border-radius: 2px;
  background: var(--grad-brand);
}

/* gradient headline word — same fallback logic as .label */
.g {
  background: var(--grad-text);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--brand-600);
}

/* the light ramp, for gradient text on a dark ground */
.on-dark .g {
  background: var(--grad-text-light);
  -webkit-background-clip: text;
  background-clip: text;
  color: var(--brand-400);
  /* a shadow behind a transparent glyph shows through as a smear */
  text-shadow: none;
}

/* ---- capability hue selectors ----
   Each sets the --c that the tile styles read, so a service's colour is a
   single class on the tile rather than a rule per service. The default lives on
   .bento (an ancestor, so it is inherited and always loses to a hue class);
   putting it on .tile itself would be an equal-specificity rule declared later
   in this file, and every tile would come out blue. */
.h-blue { --c: var(--h-blue) }
.h-violet { --c: var(--h-violet) }
.h-teal { --c: var(--h-teal) }
.h-sky { --c: var(--h-sky) }
.h-rose { --c: var(--h-rose) }
.h-indigo { --c: var(--h-indigo) }
.h-cyan { --c: var(--h-cyan) }
.h-amber { --c: var(--h-amber) }
.h-fuchsia { --c: var(--h-fuchsia) }
.h-emerald { --c: var(--h-emerald) }

.lead {
  font-size: 1.125rem;
  line-height: 1.6;
  color: var(--ink-50);
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- layout ---------- */
.wrap {
  max-width: var(--page);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  padding: 104px 0;
}

.section-sm {
  padding: 72px 0;
}

/* In-page anchors must clear the floating header: 66px bar + the 10px it is
   detached by + a little air, so a jumped-to heading is not tucked under it. */
section[id] {
  scroll-margin-top: 92px;
}

.ruled {
  border-top: 1px solid var(--line-soft);
}

/* The deeper of the two light grounds, alternated with the plain canvas so the
   middle of the page has rhythm instead of reading as one continuous sheet.
   The radial layer is a soft off-centre brand glow — it is what stops a large
   flat tint from looking grey. */
.wash {
  background:
    radial-gradient(1000px 460px at 12% 0%, rgba(13, 155, 211, .08), transparent 68%),
    linear-gradient(180deg, #e8f2f9 0%, #ecf4fa 60%, var(--canvas) 100%);
}

.wash-up {
  background:
    radial-gradient(1000px 460px at 88% 100%, rgba(13, 155, 211, .13), transparent 68%),
    linear-gradient(0deg, #e3eff8 0%, #eaf3f9 60%, var(--canvas) 100%);
}

@media (max-width:760px) {
  .section {
    padding: 68px 0;
  }

  .section-sm {
    padding: 52px 0;
  }
}

/* section heading block */
.head {
  max-width: 720px;
  margin-bottom: 56px;
}

.head.center {
  margin-inline: auto;
  text-align: center;
}

.head p {
  margin-top: 18px;
  font-size: 1.0625rem;
}

/* ---------- actions ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 46px;
  padding: 0 22px;
  border-radius: var(--r);
  font-size: .9375rem;
  font-weight: 550;
  letter-spacing: -.008em;
  white-space: nowrap;
  transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease), opacity .2s var(--ease);
}

.btn svg {
  width: 16px;
  height: 16px;
  flex: none;
}

/* primary action carries the brand gradient. The second gradient layer is the
   hover state, cross-faded via opacity so the transition is a real animation —
   background-image itself is not interpolatable. */
.btn-solid {
  position: relative;
  isolation: isolate;
  background: var(--brand-600);
  background-image: var(--grad-brand);
  color: #fff;
  box-shadow: 0 1px 2px rgba(4, 19, 32, .18), 0 10px 24px -12px rgba(13, 155, 211, .6);
}

.btn-solid::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: linear-gradient(120deg, #084f76 0%, #08719b 52%, #0d9bd3 100%);
  opacity: 0;
  transition: opacity .25s var(--ease);
}

.btn-solid:hover::after {
  opacity: 1;
}

.btn-solid:hover {
  box-shadow: 0 1px 2px rgba(4, 19, 32, .2), 0 14px 30px -12px rgba(13, 155, 211, .75);
}

.btn-line {
  border: 1px solid var(--line);
  color: var(--ink);
  background: var(--surface);
}

.btn-line:hover {
  color: var(--brand-700);
  background: var(--accent-tint);
  border-color: rgba(13, 155, 211, .45);
}

/* inverted pair, for the dark gradient grounds (hero, closing CTA) */
.on-dark .btn-solid,
.btn-solid.invert {
  background: #fff;
  background-image: none;
  color: var(--brand-800);
  box-shadow: 0 2px 6px rgba(4, 19, 32, .28), 0 16px 34px -18px rgba(4, 19, 32, .6);
}

.on-dark .btn-solid::after,
.btn-solid.invert::after {
  background: linear-gradient(120deg, #fff, var(--brand-300));
}

/* --dark-line is too faint for a control the user is meant to click */
.on-dark .btn-line,
.btn-line.invert {
  background: rgba(255, 255, 255, .06);
  color: #fff;
  border-color: rgba(255, 255, 255, .28);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.on-dark .btn-line:hover,
.btn-line.invert:hover {
  background: rgba(140, 200, 235, .16);
  border-color: var(--brand-400);
  color: #fff;
}

.btn-sm {
  height: 38px;
  padding: 0 16px;
  font-size: .875rem;
}

.btn-block {
  width: 100%;
}

/* quiet inline text link with a nudging arrow */
.tlink {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--accent);
  font-size: .9375rem;
  font-weight: 550;
}

.tlink svg {
  width: 15px;
  height: 15px;
  transition: transform .25s var(--ease);
}

/* darker on hover, not lighter — brand-500 on white is 3.1:1, under the 4.5:1
   a 15px link needs */
.tlink:hover {
  color: var(--brand-800);
}

.tlink:hover svg {
  transform: translateX(3px);
}

/* ---------- header ----------
   Floating, in two states. At rest it is flush and transparent, sitting on the
   hero's dark gradient so there is no seam between bar and hero. Once the page
   scrolls it detaches from the viewport edge and the contents ride a rounded
   gradient plate inset to the page container. Either way the contents are
   always on a dark ground, so the nav is white throughout and the white-on-dark
   wordmark needs no plate.

   The header stays in flow (sticky, not fixed) and its height never changes
   between the two states. A fixed header would need compensating padding on
   every page, and shrinking the bar on scroll would pull the whole document up
   by the difference mid-scroll — both were rejected for that reason. Only `top`
   and the plate animate, and neither affects layout. */
#top {
  position: sticky;
  top: 0;
  z-index: 900;
  background: transparent;
  transition: top .35s var(--ease);
}

/* the detached offset — small enough that the plate still reads as the page
   header rather than a floating widget */
#top.stuck {
  top: 10px;
}

.bar {
  position: relative;
  /* so the plate's z-index:-1 stays behind the bar's own contents rather than
     escaping to the #top stacking context */
  isolation: isolate;
  display: flex;
  align-items: center;
  gap: 28px;
  height: 66px;
}

/* The floating plate. Deliberately opaque rather than a translucent blur: the
   nav, phone number and wordmark are all white, and the note on --grad-bar
   applies here too — over a blurred light page they would fall under 4.5:1.
   The gradient is the only ground that keeps them legible while scrolled. */
.bar::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: 14px;
  background: var(--grad-bar);
  border: 1px solid rgba(140, 200, 235, .18);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .06) inset,
    0 14px 38px -16px rgba(4, 19, 32, .72);
  opacity: 0;
  transform: scale(.99);
  transition: opacity .35s var(--ease), transform .35s var(--ease);
}

#top.stuck .bar::before {
  opacity: 1;
  transform: none;
}

/* Above the page width the plate lines up with the .wrap box, which already
   leaves the 24px gutter as breathing room inside the rounded corners. Below
   it the wrap fills the viewport, so the plate needs its own inset or it would
   touch both screen edges and stop reading as detached. */
@media (max-width:1180px) {
  .bar::before {
    inset: 0 10px;
  }

  #top.stuck {
    top: 8px;
  }
}

/* The wordmark asset is white-on-dark art, and its blue glyph relies on colour
   separation to read as a mark rather than a letter — flattening it to a single
   colour makes it read "NANVIAM". Every ground it sits on (header, mobile
   sheet, footer) is dark, so it is used exactly as supplied. */
.mark {
  display: inline-flex;
  align-items: center;
  flex: none;
  /* The wordmark is only 21px tall, which made the home link a 21px-high tap
     target. The bar is 66px and centres its children, so claiming 44px of it
     buys a legal target without moving the logo a pixel. */
  min-height: 44px;
}

.mark img {
  height: 21px;
  width: auto;
}

.nav {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: 6px;
}

.nav > li {
  position: relative;
}

.nav > li > a {
  display: flex;
  align-items: center;
  gap: 5px;
  height: 34px;
  padding: 0 12px;
  border-radius: 7px;
  font-size: .9375rem;
  font-weight: 500;
  /* .88, not lower: the bar's lightest stop is #08719b, and anything dimmer
     than this drops the links under 4.5:1 on it */
  color: rgba(255, 255, 255, .88);
  transition: color .2s, background .2s;
}

.nav > li > a:hover,
.nav > li[aria-current] > a {
  color: #fff;
  background: rgba(255, 255, 255, .12);
}

.nav .caret {
  width: 13px;
  height: 13px;
  color: rgba(255, 255, 255, .5);
  transition: transform .25s var(--ease);
}

.nav > li:hover .caret {
  transform: rotate(180deg);
}

/* ---------- services mega menu ----------
   Named .mega, not .panel: the legacy pages use .panel for accordion bodies,
   and a hidden/absolute rule on that name would have blanked every FAQ answer
   on the site.

   Each row carries the same hue as that service's tile on the homepage, so a
   service keeps one colour identity wherever it appears. */
.mega {
  position: absolute;
  top: calc(100% + 8px);
  left: -24px;
  width: 760px;
  padding: 12px 12px 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: var(--lift-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity .22s var(--ease), transform .22s var(--ease), visibility .22s;
}

.nav > li:hover .mega,
.nav > li:focus-within .mega {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.mega-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px;
}

/* the hue fallback lives on the grid (an ancestor, so inherited) rather than on
   the row — an equal-specificity default declared after the .h-* rules would
   win and flatten every row to blue */
.mega-grid {
  --c: var(--h-blue);
}

.mega-grid > a {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: 12px;
  padding: 11px 12px;
  border-radius: 10px;
  transition: background .18s var(--ease);
}

.mega-grid > a:hover {
  background: linear-gradient(120deg, rgb(var(--c) / .1), rgb(var(--c) / .03) 70%, transparent);
}

/* same extruded plate as the homepage tiles, at menu scale */
.mega .mi {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 9px;
  color: #fff;
  background-color: rgb(var(--c));
  background-image:
    linear-gradient(145deg, rgba(255, 255, 255, .34), rgba(255, 255, 255, 0) 55%),
    linear-gradient(145deg, transparent 45%, rgba(4, 19, 32, .2));
  box-shadow:
    0 5px 12px -5px rgb(var(--c) / .65),
    inset 0 1px 0 rgba(255, 255, 255, .36);
  transition: transform .28s var(--ease);
}

.mega .mi svg {
  width: 16px;
  height: 16px;
}

.mega-grid > a:hover .mi {
  transform: translateY(-2px) rotate(-4deg);
}

.mega strong {
  display: block;
  font-size: .90625rem;
  font-weight: 550;
  letter-spacing: -.012em;
  transition: color .18s;
}

/* the raw hue is only ~3:1 on white, which fails for 14px copy — darken it the
   same way the homepage tiles do */
.mega-grid > a:hover strong {
  color: color-mix(in srgb, rgb(var(--c)) 70%, #04121e);
}

.mega small {
  display: block;
  font-size: .8125rem;
  color: var(--ink-50);
  line-height: 1.45;
  margin-top: 2px;
}

/* a tinted closing strip, so the menu ends on a route to the index rather than
   trailing off after the tenth row */
.mega-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin: 12px -12px 0;
  padding: 14px 24px;
  border-top: 1px solid var(--line-soft);
  border-radius: 0 0 16px 16px;
  background: linear-gradient(100deg, #f2f9fd, #fbfdff 70%);
}

.mega-foot span {
  font-size: .8125rem;
  color: var(--ink-50);
}

.bar-end {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}

/* sits over the lightest end of the gradient bar, so it carries less
   transparency than the nav links do */
.bar-end .phone {
  /* same reasoning as .mark: a text-height hit area on a call link is the one
     target most worth enlarging */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: .875rem;
  font-weight: 500;
  color: rgba(255, 255, 255, .92);
  padding: 0 4px;
  white-space: nowrap;
}

.bar-end .phone:hover {
  color: #fff;
}

/* WhatsApp. Tinted at rest so it reads as part of the bar, filling to the
   brand's dark green on hover — #25d366 would only give a white glyph 1.7:1,
   while #128c7e clears the 3:1 bar that non-text contrast asks for.
   Sized to match .burger, which it sits beside once the bar collapses. */
.bar-end .wa {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 10px;
  color: #fff;
  background: rgba(37, 211, 102, .16);
  border: 1px solid rgba(37, 211, 102, .45);
  transition: background .2s, border-color .2s, transform .25s var(--ease), box-shadow .25s var(--ease);
}

/* the glyph is inlined in the markup rather than pulled from icons.svg: the
   sprite is served with a one-year Expires header and <use href> takes no
   cache-buster, so a returning visitor's cached copy has no symbol to resolve
   and the button renders empty. fill, because the sprite's own symbols carry
   that attribute themselves and a bare inline <path> would not. */
.bar-end .wa svg {
  width: 19px;
  height: 19px;
  fill: currentColor;
}

.bar-end .wa:hover {
  background: #128c7e;
  border-color: #128c7e;
  transform: translateY(-1px);
  box-shadow: 0 8px 18px -8px rgba(18, 140, 126, .8);
}

/* the header CTA sits on a dark ground, so it uses the inverted treatment */
.bar-end .btn-solid {
  background: #fff;
  background-image: none;
  color: var(--brand-800);
  box-shadow: 0 2px 10px -2px rgba(4, 19, 32, .4);
}

.bar-end .btn-solid::after {
  background: linear-gradient(120deg, #fff, var(--brand-300));
}

.burger {
  display: none;
  width: 38px;
  height: 38px;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, .28);
  color: #fff;
}

.burger svg {
  width: 18px;
  height: 18px;
}

@media (max-width:1120px) {
  .nav,
  .bar-end .phone {
    display: none;
  }

  .burger {
    display: flex;
  }
}

/* the WhatsApp button stays: once the numbers and the CTA are gone it is the
   only one-tap way to reach us from the bar */
@media (max-width:520px) {
  .bar-end .btn {
    display: none;
  }
}

/* Mobile sheet. Deliberately NOT parked off-canvas with translateX(100%): a
   fixed element pushed a full viewport sideways can extend the document past
   the viewport. A sub-pixel scale keeps every edge inside the frame. */
#sheet {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--grad-deep);
  padding: 0 var(--gutter) 40px;
  overflow-y: auto;
  visibility: hidden;
  opacity: 0;
  transform: scale(.99);
  transition: opacity .26s var(--ease), transform .3s var(--ease), visibility .3s;
}

#sheet.open {
  visibility: visible;
  opacity: 1;
  transform: none;
}

.sheet-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 66px;
  margin-bottom: 14px;
}

#sheet nav a {
  display: block;
  padding: 15px 0;
  font-size: 1.0625rem;
  font-weight: 500;
  color: #fff;
  border-bottom: 1px solid var(--dark-line);
}

/* the sheet is the mobile spelling of the mega menu, so it carries the same
   per-service hue plates rather than a plain indented list */
#sheet .sub a {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0 10px 14px;
  font-size: .9375rem;
  font-weight: 400;
  color: rgba(255, 255, 255, .78);
  border-left: 2px solid rgba(76, 194, 240, .3);
  border-bottom: 1px solid rgba(140, 200, 235, .1);
}

#sheet .sub .mi {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  color: #fff;
  background-color: rgb(var(--c));
  background-image:
    linear-gradient(145deg, rgba(255, 255, 255, .32), rgba(255, 255, 255, 0) 55%),
    linear-gradient(145deg, transparent 45%, rgba(4, 19, 32, .22));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .34);
}

#sheet .sub .mi svg {
  width: 15px;
  height: 15px;
}

#sheet .sheet-cta {
  display: grid;
  gap: 10px;
  margin-top: 28px;
}

/* ---------- hero ----------
   The header is transparent and overlays this section, so the hero's own top
   padding has to account for the 66px bar. */
.hero {
  position: relative;
  margin-top: -66px;
  padding: 178px 0 104px;
  text-align: center;
  overflow: hidden;
  isolation: isolate;
  background: var(--grad-deep);
}

.hero-in {
  position: relative;
  max-width: 920px;
  margin-inline: auto;
}

/* ---- 3D scene ----
   Everything here is decorative: aria-hidden in the markup, pointer-events off,
   and painted behind the copy with a negative z-index inside the hero's own
   isolation context so it can never sit above the header or the nav panel. */
.scene {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  perspective: 1000px;
  perspective-origin: 50% 30%;
  transform-style: preserve-3d;
  /* smooths the pointer parallax set from site.js */
  transition: perspective-origin .35s ease-out;
}

/* drifting colour orbs give the flat gradient depth and movement */
.orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(76px);
  opacity: .5;
  will-change: transform;
}

.orb.o1 {
  width: 620px;
  height: 620px;
  top: -220px;
  left: -140px;
  background: radial-gradient(circle, #0d9bd3, transparent 68%);
  animation: drift 26s var(--ease) infinite;
}

.orb.o2 {
  width: 540px;
  height: 540px;
  top: -140px;
  right: -120px;
  background: radial-gradient(circle, #4cc2f0, transparent 66%);
  opacity: .34;
  animation: drift 32s var(--ease) infinite reverse;
}

.orb.o3 {
  width: 700px;
  height: 460px;
  bottom: -260px;
  left: 34%;
  background: radial-gradient(circle, #1e5fd0, transparent 70%);
  opacity: .3;
  animation: drift 38s var(--ease) infinite;
}

@keyframes drift {
  0%, 100% {
    transform: translate3d(0, 0, 0) scale(1);
  }

  50% {
    transform: translate3d(70px, 46px, 0) scale(1.12);
  }
}

/* the receding grid floor: a flat plane laid back in 3D and faded out with a
   mask, which is what turns a repeating gradient into a horizon */
.floor {
  position: absolute;
  left: -40%;
  right: -40%;
  bottom: -6%;
  height: 78%;
  transform-origin: 50% 100%;
  transform: rotateX(74deg);
  background-image:
    linear-gradient(to right, rgba(140, 219, 248, .55) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(140, 219, 248, .55) 1px, transparent 1px);
  background-size: 62px 62px;
  -webkit-mask: radial-gradient(64% 88% at 50% 100%, #000 12%, transparent 82%);
  mask: radial-gradient(64% 88% at 50% 100%, #000 12%, transparent 82%);
}

/* glass panes floating in real 3D space, cropped by the section edges so they
   frame the copy instead of competing with it */
.panes {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
}

.pane {
  position: absolute;
  border-radius: 18px;
  border: 1px solid rgba(140, 219, 248, .42);
  background:
    linear-gradient(140deg, rgba(140, 219, 248, .24), rgba(13, 155, 211, .07) 60%, transparent);
  box-shadow: 0 30px 70px -30px rgba(4, 19, 32, .9), inset 0 1px 0 rgba(255, 255, 255, .16);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  will-change: transform;
}

.pane.p1 {
  width: 300px;
  height: 210px;
  top: 118px;
  left: -70px;
  transform: rotateY(24deg) rotateX(9deg) rotateZ(-5deg) translateZ(40px);
  animation: bob 11s ease-in-out infinite;
}

.pane.p2 {
  width: 250px;
  height: 320px;
  top: 76px;
  right: -66px;
  transform: rotateY(-26deg) rotateX(7deg) rotateZ(4deg) translateZ(70px);
  animation: bob 13s ease-in-out infinite reverse;
}

.pane.p3 {
  width: 210px;
  height: 150px;
  bottom: 44px;
  right: 12%;
  transform: rotateY(-20deg) rotateX(22deg) translateZ(-30px);
  opacity: .7;
  animation: bob 16s ease-in-out infinite;
}

@keyframes bob {
  0%, 100% {
    translate: 0 0;
  }

  50% {
    translate: 0 -22px;
  }
}

@media (max-width:1080px) {
  .pane {
    display: none;
  }
}

/* every decorative layer is animation-only, so reduced motion just parks it */
@media (prefers-reduced-motion: reduce) {
  .orb,
  .pane {
    animation: none;
  }
}

/* .paused is set by site.js once the hero scrolls out of view */
.hero.paused .orb,
.hero.paused .pane,
.page-hero.paused .orb,
.page-hero.paused .pane {
  animation-play-state: paused;
}

/* ---- hero copy on the dark ground ---- */
.hero .display {
  color: #fff;
  text-shadow: 0 2px 30px rgba(4, 19, 32, .5);
}

.hero .lead {
  color: rgba(226, 242, 252, .78);
}

.hero-note {
  color: rgba(226, 242, 252, .55);
}

/* thin outlined eyebrow — no filled colour pill */
/* min-height, not height: this text wraps to two lines on narrow screens and a
   fixed height would let it spill out of the pill */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 32px;
  padding: 6px 16px;
  border: 1px solid rgba(140, 219, 248, .34);
  border-radius: 999px;
  background: rgba(140, 219, 248, .1);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  font-size: .8125rem;
  font-weight: 500;
  line-height: 1.4;
  color: rgba(226, 242, 252, .9);
  margin-bottom: 28px;
}

.chip svg {
  width: 13px;
  height: 13px;
  color: var(--brand-400);
}

.hero .display {
  margin-bottom: 24px;
}

.hero .lead {
  max-width: 730px;
  margin: 0 auto 34px;
  font-size: 1.1875rem;
}

.hero-act {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}

.hero-note {
  margin-top: 22px;
  font-size: .875rem;
}

@media (max-width:760px) {
  .hero {
    padding: 128px 0 76px;
  }

  .floor {
    height: 58%;
  }
}

/* ---------- trust row ---------- */
.trust {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 52px;
  flex-wrap: wrap;
  padding: 34px 0;
}

.trust figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
}

/* these are ornate laurel badges rather than flat wordmarks, so they need more
   height than a normal logo wall to stay legible — and they carry their own
   colour, so they are shown as supplied rather than desaturated */
.trust img {
  height: 58px;
  width: auto;
  transition: transform .3s var(--ease);
}

.trust figure:hover img {
  transform: translateY(-3px) scale(1.04);
}

.trust figcaption {
  font-size: .75rem;
  font-weight: 550;
  color: var(--ink-50);
  text-align: center;
}

@media (max-width:760px) {
  .trust {
    gap: 30px;
  }

  .trust img {
    height: 36px;
  }
}

/* ---------- metrics band ---------- */
.metrics {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: linear-gradient(180deg, #f4fafd, #fff 70%);
  box-shadow: var(--lift);
}

.metrics > div {
  position: relative;
  padding: 40px 28px;
}

/* A tick above each figure, so the band reads as coloured without tinting the
   numerals into illegibility. One hue per column, from the same palette the
   service tiles use. */
.metrics > div::before {
  content: '';
  position: absolute;
  top: 0;
  left: 28px;
  width: 32px;
  height: 3px;
  border-radius: 0 0 3px 3px;
  background: rgb(var(--c));
}

.metrics > div:nth-child(1) { --c: var(--h-blue) }
.metrics > div:nth-child(2) { --c: var(--h-violet) }
.metrics > div:nth-child(3) { --c: var(--h-teal) }
.metrics > div:nth-child(4) { --c: var(--h-amber) }

.metrics > div + div {
  border-left: 1px solid var(--line);
}

.metrics b {
  display: block;
  font-size: clamp(2.125rem, 3.8vw, 3rem);
  font-weight: 600;
  letter-spacing: -.045em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  background: var(--grad-text);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--brand-600);
}

/* direct child only — the animated counter lives in a span inside <b> and must
   keep the display size, not pick up the label style */
.metrics > div > span {
  display: block;
  margin-top: 10px;
  font-size: .875rem;
  color: var(--ink-50);
}

@media (max-width:820px) {
  .metrics {
    grid-template-columns: 1fr 1fr;
  }

  .metrics > div:nth-child(3) {
    border-left: 0;
  }

  .metrics > div:nth-child(n+3) {
    border-top: 1px solid var(--line);
  }
}

@media (max-width:460px) {
  .metrics > div {
    padding: 28px 18px;
  }

  .metrics > div::before {
    left: 18px;
  }
}

/* ---------- bento service grid ----------
   Tiles share hairline dividers via a 1px gap over a ruled background, so the
   grid reads as one ruled object rather than a tray of floating cards. */
.bento {
  /* inherited default for any tile without an .h-* hue class */
  --c: var(--h-blue);
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--lift);
}

/* Each tile takes its hue from --c, a space-separated RGB triplet so
   rgb(var(--c) / a) composes. --c-ink is the same hue darkened for use as text:
   the raw brand blue is only 3.1:1 on white, which fails for 12-17px copy. */
.tile {
  --c-ink: color-mix(in srgb, rgb(var(--c)) 70%, #04121e);
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 30px 28px 26px;
  background: var(--surface);
  transition: background .22s var(--ease), box-shadow .22s var(--ease);
}

.tile:hover {
  background:
    linear-gradient(165deg, rgb(var(--c) / .07), rgb(var(--c) / .015) 60%, transparent),
    var(--surface);
  box-shadow: inset 0 0 0 1px rgb(var(--c) / .28);
}

/* the icon sits on a small extruded plate in the tile's own hue: a sheen
   highlight top-left, a shade bottom-right, and a coloured cast shadow */
.tile .ti {
  width: 20px;
  height: 20px;
  flex: none;
  box-sizing: content-box;
  padding: 11px;
  border-radius: 12px;
  color: #fff;
  margin-bottom: 14px;
  background-color: rgb(var(--c));
  background-image:
    linear-gradient(145deg, rgba(255, 255, 255, .34), rgba(255, 255, 255, 0) 52%),
    linear-gradient(145deg, transparent 45%, rgba(4, 19, 32, .22));
  box-shadow:
    0 6px 16px -6px rgb(var(--c) / .6),
    inset 0 1px 0 rgba(255, 255, 255, .38);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}

.tile:hover .ti {
  transform: translateY(-2px) rotate(-3deg);
  box-shadow:
    0 12px 24px -8px rgb(var(--c) / .7),
    inset 0 1px 0 rgba(255, 255, 255, .38);
}

.tile h3 {
  padding-right: 18px;
}

.tile:hover h3 {
  color: rgb(var(--c));
  color: var(--c-ink);
}

.tile p {
  font-size: .9375rem;
  line-height: 1.58;
}

.tile .go {
  position: absolute;
  top: 30px;
  right: 26px;
  width: 15px;
  height: 15px;
  color: var(--ink-35);
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity .22s var(--ease), transform .22s var(--ease);
}

.tile:hover .go {
  opacity: 1;
  transform: translateX(0);
}

/* Chips anchor to the tile's bottom edge. In a bento row the tallest tile sets
   the height, so pinning the metadata down turns leftover space into
   intentional breathing room instead of a ragged gap under the text. */
.tile .kv {
  display: flex;
  gap: 7px;
  flex-wrap: wrap;
  margin-top: auto;
  padding-top: 8px;
}

.tile .kv span {
  font-size: .75rem;
  font-weight: 550;
  color: rgb(var(--c));
  color: var(--c-ink);
  padding: 3px 10px;
  background: rgb(var(--c) / .09);
  border: 1px solid rgb(var(--c) / .22);
  border-radius: 999px;
}

/* the lead tile carries a larger heading and sits on a tinted brand ground */
.tile.lead-tile {
  background:
    linear-gradient(150deg, rgb(var(--c) / .1), rgb(var(--c) / .02) 55%, transparent),
    var(--surface-2);
  padding: 38px 34px 34px;
}

.tile.lead-tile:hover {
  background:
    linear-gradient(150deg, rgb(var(--c) / .16), rgb(var(--c) / .04) 58%, transparent),
    var(--surface-2);
}

.tile.lead-tile h3 {
  font-size: 1.5rem;
  letter-spacing: -.028em;
  max-width: 22ch;
}

.tile.lead-tile p {
  font-size: 1rem;
  max-width: 46ch;
}

/* closing tile that links to the full index */
.tile.more {
  justify-content: center;
  background: var(--grad-deep);
}

.tile.more strong,
.tile.more p {
  color: #fff;
}

.tile.more p {
  color: rgba(226, 242, 252, .7);
}

.tile.more strong {
  font-size: 1.0625rem;
  letter-spacing: -.014em;
}

.tile.more .tlink {
  margin-top: auto;
  padding-top: 10px;
  color: var(--brand-300);
}

.tile.more:hover {
  background:
    linear-gradient(150deg, rgba(13, 155, 211, .35), transparent 60%),
    var(--grad-deep);
  box-shadow: none;
}

/* the generic .tlink:hover darkens, which would sink this one into its own
   dark ground */
.tile.more:hover .tlink {
  color: #fff;
}

.c4 {
  grid-column: span 4;
}

.c5 {
  grid-column: span 5;
}

.c6 {
  grid-column: span 6;
}

.c7 {
  grid-column: span 7;
}

@media (max-width:940px) {
  .c4,
  .c5,
  .c6,
  .c7 {
    grid-column: span 6;
  }
}

@media (max-width:620px) {
  .c4,
  .c5,
  .c6,
  .c7 {
    grid-column: span 12;
  }

  .tile,
  .tile.lead-tile {
    padding: 26px 22px;
  }
}

/* ---------- split (certified process) ---------- */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 72px;
  align-items: center;
}

@media (max-width:900px) {
  .split {
    grid-template-columns: 1fr;
    gap: 40px;
  }
}

.ticks li {
  display: flex;
  gap: 12px;
  padding: 15px 0;
  font-size: .9375rem;
  color: var(--ink-70);
  border-bottom: 1px solid var(--line-soft);
}

.ticks li:first-child {
  border-top: 1px solid var(--line-soft);
}

/* the check sits in a soft brand disc rather than floating as a bare glyph */
.ticks svg {
  width: 13px;
  height: 13px;
  flex: none;
  box-sizing: content-box;
  padding: 5px;
  margin-top: 1px;
  border-radius: 50%;
  color: #fff;
  background-image: var(--grad-brand);
  box-shadow: 0 3px 8px -3px rgba(13, 155, 211, .7);
}

/* certification plates */
.plates {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

.plate {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin: 0;
  padding: 30px 20px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: linear-gradient(160deg, #f1f9fd, #fff 62%);
  box-shadow: var(--lift);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}

.plate:hover {
  transform: translateY(-4px);
  box-shadow: var(--lift-lg);
}

.plate:first-child {
  grid-column: 1 / -1;
}

.plate img {
  height: 74px;
  width: auto;
}

.plate figcaption {
  font-size: .8125rem;
  font-weight: 500;
  color: var(--ink-70);
  text-align: center;
}

@media (max-width:520px) {
  .plates {
    grid-template-columns: 1fr;
  }

  .plate:first-child {
    grid-column: auto;
  }
}

/* ---------- work / products grid ---------- */
.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 26px;
}

@media (max-width:940px) {
  .cards {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width:600px) {
  .cards {
    grid-template-columns: 1fr;
  }
}

.item {
  display: flex;
  flex-direction: column;
}

/* the frame lifts on a slight 3D tilt on hover — perspective() is applied per
   element so no shared parent needs transform-style */
.item .frame {
  aspect-ratio: 16/10;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: linear-gradient(150deg, #e8f4fb, #f7fafc);
  box-shadow: var(--lift);
  transition: transform .45s var(--ease), box-shadow .45s var(--ease), border-color .45s var(--ease);
}

.item:hover .frame {
  transform: perspective(1000px) rotateX(2.5deg) translateY(-6px);
  border-color: rgb(var(--c) / .45);
  box-shadow: 0 2px 4px rgba(8, 60, 95, .05), 0 32px 60px -30px rgb(var(--c) / .55);
}

.item .frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  transition: transform .5s var(--ease);
}

.item:hover .frame img {
  transform: scale(1.035);
}

.item .cap {
  padding-top: 16px;
}

/* the category chip carries the card's cycled hue, so a row of work cards is
   colour-coded by discipline rather than three identical blue labels */
/* 12px is the floor for every micro-label on the site, here and on .certs span,
   .fact dt and .work-card .meta span. All four were 11px: uppercase and tracked,
   so they read larger than they measure, but Google's mobile-friendliness check
   compares the measured size against a 12px threshold and marked them as text
   too small to read. */
.item .cat {
  display: inline-block;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: rgb(var(--c));
  color: color-mix(in srgb, rgb(var(--c)) 70%, #04121e);
  padding: 3px 9px;
  border-radius: 5px;
  background: rgb(var(--c) / .1);
}

.item:hover h3 {
  color: rgb(var(--c));
  color: color-mix(in srgb, rgb(var(--c)) 70%, #04121e);
}

.item h3 {
  margin: 7px 0 6px;
}

.item p {
  font-size: .9375rem;
  line-height: 1.55;
}

/* ---------- process ----------
   The gaps between steps would break the row of gradient top rules into five
   disconnected dashes, so a dimmer continuous rule runs behind the whole grid
   and each step's own brighter rule sits on top of it. Reads as one process
   with five marked stages. */
.steps {
  position: relative;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 26px;
}

.steps::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--grad-brand);
  opacity: .28;
}

@media (max-width:940px) {
  /* the rule only reads as a single track while the steps are on one row */
  .steps::before {
    display: none;
  }
}

@media (max-width:940px) {
  .steps {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width:560px) {
  .steps {
    grid-template-columns: 1fr;
  }
}

/* border-image paints the gradient rule. It nominally applies to all four
   sides, but only border-top has a width, so only the top rule renders. */
.step {
  padding-top: 18px;
  border-top: 2px solid var(--brand-500);
  border-image: linear-gradient(90deg, #08719b, #4cc2f0) 1;
}

.step em {
  display: block;
  font-style: normal;
  font-size: 1.75rem;
  font-weight: 600;
  letter-spacing: -.03em;
  line-height: 1;
  margin-bottom: 14px;
  background: var(--grad-text);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--brand-600);
}

.step h3 {
  margin-bottom: 8px;
}

.step p {
  font-size: .90625rem;
  line-height: 1.55;
}

/* ---- dark band ----
   One dark section in the middle of the page. Without it, the run from the
   trust row to the closing CTA is eight light sections back to back, which is
   what made the middle feel empty however it was tinted. */
.band {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--grad-deep);
}

/* the same grid-and-glow language as the hero and the closing CTA */
.band::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(760px 340px at 78% 0%, rgba(13, 155, 211, .4), transparent 70%),
    radial-gradient(560px 320px at 6% 100%, rgba(76, 194, 240, .2), transparent 72%);
}

.band::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(to right, rgba(140, 219, 248, .14) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(140, 219, 248, .14) 1px, transparent 1px);
  background-size: 58px 58px;
  -webkit-mask: radial-gradient(78% 120% at 50% 0%, #000, transparent 74%);
  mask: radial-gradient(78% 120% at 50% 0%, #000, transparent 74%);
}

.band h2,
.band h3 {
  color: #fff;
}

.band p {
  color: rgba(226, 242, 252, .72);
}

/* the light ramp — the dark eyebrow and numeral gradients would disappear here */
.band .label {
  color: var(--brand-300);
}

.band .label::before {
  background: linear-gradient(90deg, #4cc2f0, #8ddbf8);
}

/* brighter than the .28 used on a light ground: the same alpha over navy leaves
   the connector invisible, so the five steps read as disconnected again */
.band .steps::before {
  background: linear-gradient(90deg, #4cc2f0, #8ddbf8);
  opacity: .42;
}

.band .step {
  border-image: linear-gradient(90deg, #4cc2f0, #8ddbf8) 1;
}

.band .step em {
  background: var(--grad-text-light);
  -webkit-background-clip: text;
  background-clip: text;
  color: var(--brand-400);
}

/* ---------- global hubs ---------- */
.hubs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--lift);
}

.hubs > div {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 34px 30px;
  background: linear-gradient(175deg, #f4fafd, #fff 55%);
}

.hubs h3 {
  font-size: 1.25rem;
  letter-spacing: -.025em;
  color: var(--brand-800);
}

.hubs .place {
  margin-top: 6px;
  font-size: .9375rem;
  color: var(--ink-50);
}

/* a live value, so it gets a live-looking treatment */
.hubs .clock {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  align-self: flex-start;
  margin-top: auto;
  padding: 6px 12px 6px 10px;
  border-radius: 999px;
  border: 1px solid rgba(13, 155, 211, .26);
  background: rgba(13, 155, 211, .08);
  font-size: .8125rem;
  font-weight: 550;
  color: var(--brand-700);
  font-variant-numeric: tabular-nums;
}

.hubs .clock svg {
  width: 14px;
  height: 14px;
  color: var(--brand-500);
}

@media (max-width:820px) {
  .hubs {
    grid-template-columns: 1fr;
  }
}

/* ---------- role links ---------- */
.roles {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.roles a {
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding: 0 15px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: .875rem;
  font-weight: 500;
  color: var(--ink-70);
  transition: border-color .2s, color .2s, background .2s;
}

.roles a:hover {
  color: #fff;
  background: var(--brand-600);
  background-image: var(--grad-brand);
  border-color: transparent;
  box-shadow: 0 8px 18px -8px rgba(13, 155, 211, .7);
}

/* ---------- FAQ (native details — no JS) ---------- */
.faq {
  max-width: 760px;
  margin-inline: auto;
  border-top: 1px solid var(--line);
}

.faq details {
  border-bottom: 1px solid var(--line);
  transition: background .25s var(--ease);
}

.faq details[open] {
  background: linear-gradient(180deg, var(--accent-tint), transparent 70%);
}

.faq summary:hover {
  color: var(--brand-700);
}

.faq summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  padding: 22px 2px;
  cursor: pointer;
  font-size: 1.0625rem;
  font-weight: 550;
  letter-spacing: -.014em;
  color: var(--ink);
  list-style: none;
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::after {
  content: '';
  flex: none;
  width: 13px;
  height: 13px;
  margin-top: 6px;
  background: currentColor;
  transition: transform .25s var(--ease);
  /* plus glyph drawn with a mask so it can animate to a minus */
  -webkit-mask: linear-gradient(#000 0 0) center/13px 1.5px no-repeat, linear-gradient(#000 0 0) center/1.5px 13px no-repeat;
  mask: linear-gradient(#000 0 0) center/13px 1.5px no-repeat, linear-gradient(#000 0 0) center/1.5px 13px no-repeat;
  color: var(--brand-500);
}

/* drop the vertical stroke to leave a minus. No rotation here: rotating 90deg
   as well would stand the remaining bar back up on end. */
.faq details[open] summary::after {
  -webkit-mask: linear-gradient(#000 0 0) center/13px 1.5px no-repeat;
  mask: linear-gradient(#000 0 0) center/13px 1.5px no-repeat;
}

.faq .answer {
  padding: 0 46px 24px 2px;
  font-size: .9375rem;
  line-height: 1.65;
  color: var(--ink-50);
}

/* ---------- closing CTA (the dark gradient bookend) ---------- */
.close {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--grad-deep);
  color: rgba(226, 242, 252, .68);
}

/* the same grid-and-glow language as the hero, so the page closes on the note
   it opened with */
.close::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(680px 320px at 82% 10%, rgba(13, 155, 211, .42), transparent 70%),
    radial-gradient(520px 300px at 8% 100%, rgba(76, 194, 240, .22), transparent 72%);
}

.close::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(to right, rgba(140, 219, 248, .16) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(140, 219, 248, .16) 1px, transparent 1px);
  background-size: 58px 58px;
  -webkit-mask: radial-gradient(80% 120% at 50% 0%, #000, transparent 72%);
  mask: radial-gradient(80% 120% at 50% 0%, #000, transparent 72%);
}

.close h2 {
  color: #fff;
  max-width: 20ch;
}

.close p {
  color: rgba(226, 242, 252, .68);
  margin-top: 18px;
  max-width: 46ch;
}

.close-in {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 40px;
  flex-wrap: wrap;
}

.close-act {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

/* ---------- related links ---------- */
.related {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.related a {
  padding: 24px 26px;
  background: var(--surface);
  transition: background .2s;
}

.related a:hover {
  background: linear-gradient(160deg, var(--accent-tint), transparent 70%), var(--surface);
}

.related a:hover strong {
  color: var(--brand-700);
}

.related strong {
  display: block;
  font-size: .96875rem;
  font-weight: 550;
  letter-spacing: -.014em;
  margin-bottom: 5px;
}

.related span {
  display: block;
  font-size: .875rem;
  line-height: 1.55;
  color: var(--ink-50);
}

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

@media (max-width:600px) {
  .related {
    grid-template-columns: 1fr;
  }
}

/* ---------- footer ---------- */
footer {
  position: relative;
  /* runs light-to-dark downward, picking up where the closing CTA's gradient
     leaves off so the two dark sections read as one continuous ground */
  background: linear-gradient(180deg, #0a3352 0%, #061e33 48%, #041320 100%);
  color: rgba(226, 242, 252, .6);
  border-top: 1px solid var(--dark-line);
}

/* a full-bleed gradient hairline reads as a seam between the CTA and footer */
footer::before {
  content: '';
  position: absolute;
  top: -1px;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--grad-brand);
}

.foot {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1fr 1.3fr;
  gap: 36px;
  padding: 72px 0 56px;
}

@media (max-width:980px) {
  .foot {
    grid-template-columns: 1fr 1fr;
    gap: 40px 28px;
  }
}

@media (max-width:560px) {
  .foot {
    grid-template-columns: 1fr;
  }
}

.foot .mark {
  margin-bottom: 18px;
}

.foot .mark img {
  height: 24px;
}

.foot p {
  font-size: .875rem;
  line-height: 1.6;
  color: rgba(226, 242, 252, .55);
  max-width: 34ch;
}

.foot h4 {
  color: var(--brand-300);
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  margin-bottom: 18px;
}

.foot li {
  margin-bottom: 11px;
}

/* inline-block with vertical padding so each link owns a ~26px band rather than
   just its 20px text box; the 11px gap between rows is kept, which is what the
   tap-target check measures as spacing */
.foot li a {
  display: inline-block;
  padding: 3px 0;
  font-size: .875rem;
  color: rgba(226, 242, 252, .6);
  transition: color .2s;
}

.foot li a:hover {
  color: var(--brand-400);
}

.office {
  margin-bottom: 16px;
  font-size: .8125rem;
  line-height: 1.55;
}

.office strong {
  display: block;
  color: #fff;
  font-size: .84375rem;
  font-weight: 550;
  margin-bottom: 3px;
}

.office a {
  color: var(--brand-300);
}

.office a:hover {
  color: #fff;
}

/* The three contact links used to be one inline run joined by <br> and a middot,
   which left them 16px tall and about 4px apart — the only tap-target failure
   left anywhere on the site. A row each, sized to the text so the hit area
   still matches what the eye reads as the link.

   Now chips rather than bare text: they are the footer's only conversion, and as
   plain --brand-300 runs they sat at the same weight as the twenty navigation
   links above them. The selector carries `a` so it outweighs `.office a`, which
   would otherwise keep winning on colour. */
.office a.office-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: fit-content;
  margin-top: 8px;
  padding: 8px 13px;
  border-radius: 9px;
  font-size: .84375rem;
  font-weight: 550;
  color: #fff;
  background: rgba(13, 155, 211, .18);
  border: 1px solid rgba(140, 200, 235, .38);
  transition: background .2s, border-color .2s, color .2s, transform .25s var(--ease);
}

.office a.office-link svg {
  flex: none;
  width: 15px;
  height: 15px;
  color: var(--brand-300);
  transition: color .2s;
}

.office a.office-link:hover {
  color: #fff;
  background: var(--brand-600);
  border-color: var(--brand-400);
  transform: translateY(-1px);
}

.office a.office-link:hover svg {
  color: #fff;
}

.social {
  display: flex;
  gap: 8px;
  margin-top: 22px;
}

.social a {
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--dark-line);
  border-radius: 8px;
  color: rgba(226, 242, 252, .65);
  transition: color .2s, border-color .2s, background .2s, transform .25s var(--ease), box-shadow .25s var(--ease);
}

.social svg {
  width: 15px;
  height: 15px;
  fill: currentColor;
}

.social a:hover {
  color: #fff;
  border-color: transparent;
  background-image: var(--grad-brand);
  transform: translateY(-2px);
  box-shadow: 0 8px 18px -8px rgba(13, 155, 211, .8);
}

.foot-end {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 22px 0;
  border-top: 1px solid var(--dark-line);
  font-size: .8125rem;
  color: rgba(226, 242, 252, .5);
}

.foot-end a:hover {
  color: var(--brand-400);
}

.certs {
  display: flex;
  gap: 7px;
  flex-wrap: wrap;
  margin-top: 20px;
}

.certs span {
  font-size: .75rem;
  font-weight: 550;
  padding: 4px 10px;
  border: 1px solid rgba(76, 194, 240, .3);
  border-radius: 999px;
  background: rgba(13, 155, 211, .12);
  color: var(--brand-300);
}

/* ---------- reveal on scroll ----------
   Gated behind .js (set by an inline snippet in <head>). Without it, a failed
   or blocked site.js would leave every .rise section permanently at opacity 0
   — i.e. the services grid, work, products and process would render blank. */
.js .rise {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}

.js .rise.in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .js .rise {
    opacity: 1;
    transform: none;
  }
}

/* =========================================================================
   INNER PAGES
   The other 60 pages carry their own long-form content under a different set
   of class names. Rather than rewrite that markup into the homepage's
   vocabulary — 60 pages of hand-editing, with a real chance of dropping copy
   that ranks — the existing names are restyled in this design language. The
   markup keeps its meaning; only the presentation moves.
   ========================================================================= */

/* A floor value for --c, so any component that paints with rgb(var(--c)) has a
   hue even outside a cycling container. On <body> it is inherited, so every
   .h-* class and every cycle rule below still overrides it. */
body {
  --c: var(--h-blue);

  /* Compatibility shim. A handful of inline styles on the inner pages name
     greys from the old stylesheet. Undefined, var() falls back to nothing and
     the declaration is dropped — silently, so the text just renders at the
     inherited colour. Mapped onto the closest ink tokens instead. */
  --gray-500: var(--ink-50);
  /* mapped to --ink-50, not --ink-35: every remaining use of this is body text
     (a de-emphasised note in a job listing), and --ink-35 is 2.9:1 on white */
  --gray-400: var(--ink-50);
}

/* ---- automatic hue rotation ----
   Inner pages hold hundreds of cards with no hue class in their markup. Rather
   than hand-tag each one, containers rotate the palette by child position, so a
   grid of six comes out in six colours and no page repeats a colour adjacently.
   Rotation is by 10s to match the ten hues. */
.grid > *:nth-child(10n+1), .timeline > *:nth-child(10n+1), .pill-grid > *:nth-child(10n+1), .cards > *:nth-child(10n+1) { --c: var(--h-blue) }
.grid > *:nth-child(10n+2), .timeline > *:nth-child(10n+2), .pill-grid > *:nth-child(10n+2), .cards > *:nth-child(10n+2) { --c: var(--h-violet) }
.grid > *:nth-child(10n+3), .timeline > *:nth-child(10n+3), .pill-grid > *:nth-child(10n+3), .cards > *:nth-child(10n+3) { --c: var(--h-teal) }
.grid > *:nth-child(10n+4), .timeline > *:nth-child(10n+4), .pill-grid > *:nth-child(10n+4), .cards > *:nth-child(10n+4) { --c: var(--h-amber) }
.grid > *:nth-child(10n+5), .timeline > *:nth-child(10n+5), .pill-grid > *:nth-child(10n+5), .cards > *:nth-child(10n+5) { --c: var(--h-rose) }
.grid > *:nth-child(10n+6), .timeline > *:nth-child(10n+6), .pill-grid > *:nth-child(10n+6), .cards > *:nth-child(10n+6) { --c: var(--h-indigo) }
.grid > *:nth-child(10n+7), .timeline > *:nth-child(10n+7), .pill-grid > *:nth-child(10n+7), .cards > *:nth-child(10n+7) { --c: var(--h-emerald) }
.grid > *:nth-child(10n+8), .timeline > *:nth-child(10n+8), .pill-grid > *:nth-child(10n+8), .cards > *:nth-child(10n+8) { --c: var(--h-fuchsia) }
.grid > *:nth-child(10n+9), .timeline > *:nth-child(10n+9), .pill-grid > *:nth-child(10n+9), .cards > *:nth-child(10n+9) { --c: var(--h-cyan) }
.grid > *:nth-child(10n+10), .timeline > *:nth-child(10n+10), .pill-grid > *:nth-child(10n+10), .cards > *:nth-child(10n+10) { --c: var(--h-sky) }

/* the darkened text-safe form of the row's hue, matching the tiles */
.card, .role-card, .fact, .pill, .step, .work-card, .office-card, .related-card {
  --c-ink: color-mix(in srgb, rgb(var(--c)) 70%, #04121e);
}

/* The 11px uppercase category chips need more headroom than the standard
   --c-ink gives. Their tinted background is translucent, so it composites over
   the page canvas rather than over white, and that costs roughly half a
   contrast point — enough to put 70% at 4.3:1, just under the bar. */
.item .cat,
.work-card .meta span {
  color: color-mix(in srgb, rgb(var(--c)) 52%, #04121e);
}

/* ---------- layout aliases ---------- */
.container {
  max-width: var(--page);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.grid {
  display: grid;
  gap: 24px;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
}

.grid.g-3 {
  grid-template-columns: repeat(3, 1fr);
}

.grid.g-4 {
  grid-template-columns: repeat(4, 1fr);
}

@media (max-width:940px) {
  .grid.g-3, .grid.g-4 {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width:620px) {
  .grid, .grid.g-3, .grid.g-4 {
    grid-template-columns: 1fr;
  }
}

/* section heading block — the inner-page spelling of .head */
.section-head {
  max-width: 760px;
  margin-bottom: 52px;
}

.section-head.center {
  margin-inline: auto;
  text-align: center;
}

.section-head p {
  margin-top: 16px;
  font-size: 1.0625rem;
}

/* Unlike .label, which draws its own gradient dash, the eyebrow carries a real
   icon in the markup — so the glyph is the accent and no ::before is added. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--brand-600);
  margin-bottom: 16px;
}

.eyebrow svg {
  width: 14px;
  height: 14px;
  color: var(--brand-500);
}

.eyebrow.on-dark {
  color: var(--brand-300);
}

.eyebrow.on-dark svg {
  color: var(--brand-400);
}

.section-head.center .eyebrow {
  justify-content: center;
}

/* full-bleed dark band, used for mid-page CTA and highlight sections */
section.dark {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--grad-deep);
  color: rgba(226, 242, 252, .7);
}

section.dark h1, section.dark h2, section.dark h3, section.dark strong {
  color: #fff;
}

section.dark p {
  color: rgba(226, 242, 252, .7);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 1200;
  padding: 12px 18px;
  background: var(--brand-800);
  color: #fff;
  border-radius: 0 0 8px 0;
  font-size: .875rem;
  font-weight: 550;
}

.skip-link:focus {
  left: 0;
}

/* ---------- inner-page hero ----------
   Same dark gradient ground and 3D scene as the homepage hero, at a shorter
   height and left-aligned to leave room for the breadcrumb. Because the header
   is transparent until scroll, the top padding absorbs the 66px bar. */
.page-hero {
  position: relative;
  margin-top: -66px;
  padding: 150px 0 74px;
  overflow: hidden;
  isolation: isolate;
  background: var(--grad-deep);
  color: rgba(226, 242, 252, .78);
}

.page-hero h1 {
  color: #fff;
  font-size: clamp(2.1rem, 4.4vw, 3.35rem);
  letter-spacing: -.04em;
  line-height: 1.06;
  max-width: 24ch;
  text-shadow: 0 2px 30px rgba(4, 19, 32, .45);
}

.page-hero .lead {
  color: rgba(226, 242, 252, .78);
  max-width: 68ch;
  margin-top: 20px;
  font-size: 1.0625rem;
}

.page-hero .hero-cta {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 30px;
}

/* Legacy heroes shipped two decorative .blob divs. They are replaced in the
   markup by the .scene layers, but the rule is kept so any straggler is a
   harmless invisible span rather than an unstyled block. */
.page-hero .blob {
  display: none;
}

.breadcrumb {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 28px;
  font-size: .8125rem;
  color: rgba(226, 242, 252, .6);
}

.breadcrumb a {
  color: var(--brand-300);
}

.breadcrumb a:hover {
  color: #fff;
}

.breadcrumb svg {
  width: 13px;
  height: 13px;
  color: rgba(140, 219, 248, .45);
}

@media (max-width:760px) {
  .page-hero {
    padding: 120px 0 58px;
  }
}

/* ---------- cards ----------
   The single highest-leverage rule set on the inner pages: 640 cards and 1300
   icon plates hang off these two class names. */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 30px 28px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--lift);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease), border-color .35s var(--ease);
}

.card:hover {
  transform: translateY(-4px);
  border-color: rgb(var(--c) / .4);
  box-shadow: 0 2px 4px rgba(8, 60, 95, .05), 0 30px 56px -30px rgb(var(--c) / .5);
}

.card h3 {
  margin-bottom: 9px;
}

.card:hover h3 {
  color: rgb(var(--c));
  color: var(--c-ink);
}

.card p {
  font-size: .9375rem;
  line-height: 1.6;
}

.card p + p {
  margin-top: 10px;
}

.card > ul {
  margin-top: 12px;
  display: grid;
  gap: 8px;
}

.card > ul li {
  position: relative;
  padding-left: 16px;
  font-size: .90625rem;
  color: var(--ink-50);
}

.card > ul li::before {
  content: '';
  position: absolute;
  left: 0;
  top: .62em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgb(var(--c) / .55);
}

/* the extruded hue plate — the same object as the homepage's .ti, at the size
   the inner-page cards need */
.ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 13px;
  margin-bottom: 18px;
  color: #fff;
  background-color: rgb(var(--c));
  background-image:
    linear-gradient(145deg, rgba(255, 255, 255, .34), rgba(255, 255, 255, 0) 52%),
    linear-gradient(145deg, transparent 45%, rgba(4, 19, 32, .22));
  box-shadow:
    0 7px 18px -7px rgb(var(--c) / .6),
    inset 0 1px 0 rgba(255, 255, 255, .38);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}

.ic svg {
  width: 20px;
  height: 20px;
}

.card:hover .ic {
  transform: translateY(-3px) rotate(-4deg);
  box-shadow:
    0 14px 26px -8px rgb(var(--c) / .7),
    inset 0 1px 0 rgba(255, 255, 255, .38);
}

/* dark card variant — used for "problem" grids, where a row of deep cards
   against the light page carries the contrast the copy is making */
.card.dark {
  background: linear-gradient(158deg, #0a3352 0%, #061e33 62%, #041320 100%);
  border-color: rgba(140, 200, 235, .16);
  box-shadow: 0 2px 4px rgba(4, 19, 32, .1), 0 26px 50px -30px rgba(4, 19, 32, .6);
}

.card.dark::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(150deg, rgb(var(--c) / .28), transparent 62%);
  opacity: .55;
  pointer-events: none;
  transition: opacity .35s var(--ease);
}

.card.dark:hover::before {
  opacity: 1;
}

.card.dark h3, .card.dark strong {
  color: #fff;
  position: relative;
}

.card.dark:hover h3 {
  color: #fff;
}

.card.dark p {
  color: rgba(226, 242, 252, .72);
  position: relative;
}

.card.dark .ic {
  position: relative;
  background-color: rgba(140, 219, 248, .16);
  background-image: none;
  border: 1px solid rgba(140, 219, 248, .3);
  box-shadow: none;
  color: var(--brand-300);
}

.card.dark > ul li {
  color: rgba(226, 242, 252, .7);
  position: relative;
}

.card.dark > ul li::before {
  background: var(--brand-400);
}

/* featured variant — a brand-tinted card that leads its grid */
.card.featured {
  background:
    linear-gradient(155deg, rgb(var(--c) / .12), rgb(var(--c) / .02) 58%, transparent),
    var(--surface);
  border-color: rgb(var(--c) / .3);
}

/* ---------- stats ---------- */
.stat-card {
  text-align: center;
  padding: 34px 20px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: linear-gradient(180deg, #f4fafd, #fff 70%);
  box-shadow: var(--lift);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}

.stat-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--lift-lg);
}

.stat-card .num {
  font-size: clamp(2rem, 3.6vw, 2.85rem);
  font-weight: 600;
  letter-spacing: -.045em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  background: var(--grad-text);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--brand-600);
}

.stat-card p {
  margin-top: 10px;
  font-size: .875rem;
}

/* ---------- pills ---------- */
.pill-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 15px;
  border-radius: 999px;
  font-size: .875rem;
  font-weight: 500;
  color: rgb(var(--c));
  color: var(--c-ink);
  background: rgb(var(--c) / .08);
  border: 1px solid rgb(var(--c) / .24);
  transition: transform .25s var(--ease), background .25s var(--ease);
}

.pill:hover {
  transform: translateY(-2px);
  background: rgb(var(--c) / .15);
}

.pill svg {
  width: 15px;
  height: 15px;
  color: rgb(var(--c));
  color: var(--c-ink);
}

/* ---------- tags ---------- */
.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 14px;
}

.tags span {
  font-size: .75rem;
  font-weight: 550;
  padding: 3px 10px;
  border-radius: 999px;
  color: rgb(var(--c));
  color: var(--c-ink);
  background: rgb(var(--c) / .09);
  border: 1px solid rgb(var(--c) / .22);
}

/* ---------- tick lists ---------- */
.check-list {
  display: grid;
  gap: 13px;
}

.check-list li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  font-size: .9375rem;
  color: var(--ink-70);
}

.check-list svg {
  width: 13px;
  height: 13px;
  flex: none;
  box-sizing: content-box;
  padding: 5px;
  margin-top: 2px;
  border-radius: 50%;
  color: #fff;
  background-image: var(--grad-brand);
  box-shadow: 0 3px 8px -3px rgba(13, 155, 211, .7);
}

section.dark .check-list li {
  color: rgba(226, 242, 252, .78);
}

/* ---------- timeline / numbered steps ----------
   Scoped under .timeline so it cannot reach the homepage's .steps > .step,
   which uses a gradient top rule and an <em> numeral instead. */
.timeline {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 24px;
}

@media (max-width:1000px) {
  .timeline {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width:560px) {
  .timeline {
    grid-template-columns: 1fr;
  }
}

.timeline .step {
  position: relative;
  padding: 26px 22px;
  border: 1px solid var(--line);
  border-top: 1px solid var(--line);
  border-image: none;
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--lift);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease), border-color .35s var(--ease);
}

.timeline .step:hover {
  transform: translateY(-4px);
  border-color: rgb(var(--c) / .4);
  box-shadow: 0 2px 4px rgba(8, 60, 95, .05), 0 26px 48px -28px rgb(var(--c) / .5);
}

/* The step number as a saturated plate, colour-coded so the process reads as a
   sequence rather than five identical boxes.
   It is filled with --c-ink rather than the raw hue, and carries no white sheen
   layer. The icon plates elsewhere use both, but they hold a *glyph*, which only
   has to clear the 3:1 non-text bar. This holds 15px text and needs 4.5:1:
   white on the raw hues measures 3.2-4.0:1, and a 34%-white sheen over even the
   darkened hue drops it to ~2.8:1. Filled flat with --c-ink it is 5.4-6.7:1
   across the palette. The remaining overlay only darkens, so it cannot hurt. */
.timeline .step .n {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  margin-bottom: 16px;
  border-radius: 11px;
  font-size: .9375rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: #fff;
  /* A var() whose value does not parse makes the property "unset" rather than
     falling back to the previous declaration — which for a background under
     white text means transparent, i.e. invisible. So the safe dark brand fill
     is unconditional and the hue is applied only where color-mix is supported. */
  background-color: var(--brand-700);
  background-image: linear-gradient(145deg, transparent 45%, rgba(4, 19, 32, .22));
  box-shadow:
    0 6px 16px -6px rgb(var(--c) / .6),
    inset 0 1px 0 rgba(255, 255, 255, .28);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}

@supports (color: color-mix(in srgb, red, blue)) {
  .timeline .step .n {
    background-color: var(--c-ink);
  }
}

.timeline .step:hover .n {
  transform: translateY(-3px) rotate(-4deg);
  box-shadow:
    0 12px 24px -8px rgb(var(--c) / .7),
    inset 0 1px 0 rgba(255, 255, 255, .28);
}

.timeline .step:hover .n {
  transform: translateY(-3px) rotate(-4deg);
}

.timeline .step h3 {
  margin-bottom: 8px;
}

.timeline .step:hover h3 {
  color: rgb(var(--c));
  color: var(--c-ink);
}

.timeline .step p {
  font-size: .90625rem;
  line-height: 1.55;
}

/* ---------- answer box (the LLM-facing summary block) ---------- */
.answer-box {
  position: relative;
  padding: 40px 38px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: linear-gradient(158deg, #f2f9fd, #fff 58%);
  box-shadow: var(--lift);
}

/* a gradient rule down the leading edge marks this as the canonical answer */
.answer-box::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 4px;
  border-radius: var(--r-lg) 0 0 var(--r-lg);
  background: var(--grad-brand);
}

.answer-q {
  font-size: clamp(1.35rem, 2.4vw, 1.75rem);
  letter-spacing: -.028em;
  margin-bottom: 14px;
}

.answer-a {
  font-size: 1rem;
  line-height: 1.7;
}

.facts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1px;
  margin-top: 28px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}

.fact {
  padding: 16px 18px;
  background: var(--surface);
}

.fact dt {
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--brand-600);
  margin-bottom: 5px;
}

.fact dd {
  font-size: .875rem;
  line-height: 1.5;
  color: var(--ink-70);
}

@media (max-width:620px) {
  .answer-box {
    padding: 28px 22px;
  }
}

/* ---------- role cards (hire developers) ---------- */
.role-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--lift);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
}

.role-card:hover {
  transform: translateY(-3px);
  border-color: rgb(var(--c) / .4);
  box-shadow: 0 2px 4px rgba(8, 60, 95, .05), 0 24px 44px -26px rgb(var(--c) / .5);
}

.role-card .info {
  display: flex;
  align-items: center;
  gap: 13px;
  min-width: 0;
}

/* smaller than the card plate — this one sits inline beside two lines of text
   rather than above a paragraph */
.role-card .ic {
  width: 38px;
  height: 38px;
  border-radius: 11px;
  margin-bottom: 0;
}

.role-card .ic svg {
  width: 18px;
  height: 18px;
}

.role-card strong {
  display: block;
  font-size: .9375rem;
  font-weight: 550;
  letter-spacing: -.012em;
}

.role-card small {
  display: block;
  font-size: .8125rem;
  color: var(--ink-50);
  line-height: 1.4;
}

.hire-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  height: 34px;
  padding: 0 14px;
  border-radius: 8px;
  font-size: .8125rem;
  font-weight: 550;
  color: rgb(var(--c));
  color: var(--c-ink);
  background: rgb(var(--c) / .09);
  border: 1px solid rgb(var(--c) / .24);
  transition: color .2s, background .2s, border-color .2s, box-shadow .2s;
}

.role-card:hover .hire-btn {
  color: #fff;
  background: rgb(var(--c));
  border-color: transparent;
  box-shadow: 0 8px 18px -8px rgb(var(--c) / .8);
}

/* ---------- tabs ---------- */
.tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 32px;
}

.tab-btn {
  height: 38px;
  padding: 0 16px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface);
  font-size: .875rem;
  font-weight: 500;
  color: var(--ink-70);
  transition: color .2s, background .2s, border-color .2s, box-shadow .2s;
}

.tab-btn:hover {
  color: var(--brand-700);
  border-color: rgba(13, 155, 211, .4);
}

.tab-btn.active {
  color: #fff;
  background-image: var(--grad-brand);
  border-color: transparent;
  box-shadow: 0 8px 18px -8px rgba(13, 155, 211, .7);
}

.tab-panel {
  display: none;
}

.tab-panel.active {
  display: grid;
}

/* ---------- work cards ---------- */
.work-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 26px;
}

@media (max-width:940px) {
  .work-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width:600px) {
  .work-grid {
    grid-template-columns: 1fr;
  }
}

.work-card .thumb {
  aspect-ratio: 16/10;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: linear-gradient(150deg, #e8f4fb, #f7fafc);
  box-shadow: var(--lift);
  transition: transform .45s var(--ease), box-shadow .45s var(--ease), border-color .45s var(--ease);
}

.work-card:hover .thumb {
  transform: perspective(1000px) rotateX(2.5deg) translateY(-6px);
  border-color: rgb(var(--c) / .45);
  box-shadow: 0 2px 4px rgba(8, 60, 95, .05), 0 32px 60px -30px rgb(var(--c) / .55);
}

.work-card .thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  transition: transform .5s var(--ease);
}

.work-card:hover .thumb img {
  transform: scale(1.035);
}

.work-card .meta {
  padding-top: 15px;
}

.work-card .meta span {
  display: inline-block;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: rgb(var(--c));
  color: var(--c-ink);
  padding: 3px 9px;
  border-radius: 5px;
  background: rgb(var(--c) / .1);
}

.work-card .meta h3 {
  margin-top: 8px;
}

.work-card:hover .meta h3 {
  color: rgb(var(--c));
  color: var(--c-ink);
}

/* ---------- photo grid (life at Anviam) ---------- */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}

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

.photo-grid figure {
  margin: 0;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--lift);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}

.photo-grid figure:hover {
  transform: translateY(-4px);
  box-shadow: var(--lift-lg);
}

.photo-grid img {
  aspect-ratio: 1;
  width: 100%;
  object-fit: cover;
}

.photo-grid figcaption {
  padding: 12px 14px;
  font-size: .8125rem;
  font-weight: 550;
  color: var(--ink-70);
}

/* ---------- device frame ---------- */
.device-frame {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: linear-gradient(150deg, #e8f4fb, #f7fafc);
  padding: 10px;
  box-shadow: var(--lift-lg);
  transition: transform .5s var(--ease);
}

.device-frame:hover {
  transform: perspective(1200px) rotateX(2deg) rotateY(-2deg) translateY(-5px);
}

.device-frame .screen {
  overflow: hidden;
  border-radius: 10px;
  background: var(--surface);
}

.device-frame .screen img {
  width: 100%;
  height: auto;
  display: block;
}

/* ---------- office cards + maps ---------- */
.office-card {
  padding: 26px 24px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: linear-gradient(175deg, #f4fafd, #fff 55%);
  box-shadow: var(--lift);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}

.office-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--lift-lg);
}

.office-card h3 {
  margin-bottom: 8px;
  color: var(--brand-800);
}

.office-card p {
  font-size: .90625rem;
}

.map-card {
  position: relative;
  margin-top: 18px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  background: var(--surface-3);
}

.map-card iframe {
  display: block;
  width: 100%;
  height: 170px;
  border: 0;
  filter: grayscale(.2);
}

.map-card-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 11px 14px;
  font-size: .8125rem;
  font-weight: 550;
  color: #fff;
  background-image: var(--grad-brand);
}

.map-card-cta svg {
  width: 14px;
  height: 14px;
  transition: transform .25s var(--ease);
}

.map-card-cta:hover svg {
  transform: translate(2px, -2px);
}

/* ---------- award / certification strips ---------- */
.trust-strip, .cert-badges {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 40px;
  flex-wrap: wrap;
}

.trust-strip figure, .cert-badge {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  margin: 0;
  max-width: 150px;
}

/* shown in full colour: these are ornate laurel badges that carry their own
   palette, and desaturating them reads as a disabled state */
.trust-strip img, .cert-badge img {
  height: 62px;
  width: auto;
  transition: transform .3s var(--ease);
}

.trust-strip figure:hover img, .cert-badge:hover img {
  transform: translateY(-3px) scale(1.04);
}

.trust-strip figcaption, .cert-badge figcaption {
  font-size: .75rem;
  font-weight: 550;
  color: var(--ink-50);
  text-align: center;
  line-height: 1.4;
}

section.dark .trust-strip figcaption, section.dark .cert-badge figcaption {
  color: rgba(226, 242, 252, .65);
}

/* ---------- AWS partner band ---------- */
.aws-partner {
  display: grid;
  grid-template-columns: 200px 1fr;
  align-items: center;
  gap: 44px;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  padding: 46px 44px;
  border-radius: var(--r-lg);
  background: var(--grad-deep);
  box-shadow: var(--lift-lg);
}

.aws-partner::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(520px 300px at 88% 12%, rgba(13, 155, 211, .4), transparent 70%);
}

.aws-mark img {
  width: 100%;
  height: auto;
}

.aws-copy h3 {
  color: #fff;
  font-size: 1.5rem;
  letter-spacing: -.028em;
  margin-bottom: 12px;
}

.aws-copy p {
  color: rgba(226, 242, 252, .72);
  font-size: .9375rem;
  line-height: 1.65;
}

.aws-tiers {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  margin-top: 20px;
}

.aws-tiers span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid rgba(140, 219, 248, .32);
  background: rgba(140, 219, 248, .12);
  font-size: .8125rem;
  font-weight: 500;
  color: rgba(226, 242, 252, .92);
}

.aws-tiers svg {
  width: 14px;
  height: 14px;
  color: var(--brand-400);
}

@media (max-width:820px) {
  .aws-partner {
    grid-template-columns: 1fr;
    gap: 26px;
    padding: 32px 24px;
  }

  .aws-mark {
    max-width: 150px;
  }
}

/* ---------- mid-page CTA banner ---------- */
.cta-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 34px;
  flex-wrap: wrap;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  padding: 46px 44px;
  border-radius: var(--r-lg);
  background: var(--grad-deep);
  box-shadow: var(--lift-lg);
}

.cta-banner::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(600px 300px at 85% 0%, rgba(13, 155, 211, .45), transparent 70%),
    radial-gradient(420px 260px at 5% 100%, rgba(76, 194, 240, .22), transparent 72%);
}

.cta-banner h2 {
  color: #fff;
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  max-width: 26ch;
}

.cta-banner p {
  color: rgba(226, 242, 252, .72);
  margin-top: 12px;
  max-width: 52ch;
  font-size: .9375rem;
}

@media (max-width:620px) {
  .cta-banner {
    padding: 32px 24px;
  }
}

/* ---------- related links ---------- */
/* The hairline dividers are the 1px gap showing the container through. The
   container is kept white rather than line-coloured, though, and each card
   paints its own 1px ring instead: these grids do not always fill their last
   row, and a line-coloured ground turns the leftover cell into a grey block. */
.related-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}

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

@media (max-width:600px) {
  .related-grid {
    grid-template-columns: 1fr;
  }
}

.related-card {
  position: relative;
  display: block;
  padding: 24px 26px;
  background: var(--surface);
  /* fills the 1px gap, so neighbouring cards meet in a crisp hairline */
  box-shadow: 0 0 0 1px var(--line);
  transition: background .22s var(--ease);
}

.related-card:hover {
  background: linear-gradient(160deg, var(--accent-tint), transparent 70%), var(--surface);
}

.related-card strong {
  display: block;
  font-size: .96875rem;
  font-weight: 550;
  letter-spacing: -.014em;
  margin-bottom: 5px;
  padding-right: 26px;
}

.related-card:hover strong {
  color: var(--brand-700);
}

.related-card span {
  display: block;
  font-size: .875rem;
  line-height: 1.55;
  color: var(--ink-50);
}

.related-card svg {
  position: absolute;
  top: 26px;
  right: 22px;
  width: 15px;
  height: 15px;
  color: var(--ink-35);
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity .22s var(--ease), transform .22s var(--ease);
}

.related-card:hover svg {
  opacity: 1;
  transform: translateX(0);
  color: var(--brand-500);
}

/* ---------- orbit diagram ----------
   A decorative ring-and-node figure. Purely presentational, so the rotation is
   parked under reduced motion and nothing here conveys information.  */
.orbit-visual {
  position: relative;
  display: grid;
  place-items: center;
}

.orbit-visual .ring {
  position: absolute;
  border-radius: 50%;
  border: 1px dashed rgba(13, 155, 211, .3);
}

.orbit-visual .ring.r1 {
  width: 58%;
  aspect-ratio: 1;
  animation: spin 34s linear infinite;
}

.orbit-visual .ring.r2 {
  width: 88%;
  aspect-ratio: 1;
  border-color: rgba(13, 155, 211, .18);
  animation: spin 52s linear infinite reverse;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.orbit-visual .core {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 84px;
  height: 84px;
  border-radius: 50%;
  color: #fff;
  background-image: var(--grad-brand);
  box-shadow: 0 16px 40px -12px rgba(13, 155, 211, .75), inset 0 2px 0 rgba(255, 255, 255, .4);
}

.orbit-visual .core svg {
  width: 32px;
  height: 32px;
}

.orbit-visual .node {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 15px;
  color: #fff;
  background-color: rgb(var(--c));
  background-image:
    linear-gradient(145deg, rgba(255, 255, 255, .34), rgba(255, 255, 255, 0) 52%),
    linear-gradient(145deg, transparent 45%, rgba(4, 19, 32, .22));
  box-shadow: 0 10px 24px -8px rgb(var(--c) / .65), inset 0 1px 0 rgba(255, 255, 255, .38);
  animation: bob 9s ease-in-out infinite;
}

.orbit-visual .node svg {
  width: 22px;
  height: 22px;
}

.orbit-visual .node.n1 { top: 4%;  left: 50%; margin-left: -26px; --c: var(--h-violet); animation-delay: -1s }
.orbit-visual .node.n2 { top: 50%; right: 2%; margin-top: -26px;  --c: var(--h-teal);   animation-delay: -3s }
.orbit-visual .node.n3 { bottom: 4%; left: 50%; margin-left: -26px; --c: var(--h-amber); animation-delay: -5s }
.orbit-visual .node.n4 { top: 50%; left: 2%;  margin-top: -26px;  --c: var(--h-rose);   animation-delay: -7s }

@media (prefers-reduced-motion: reduce) {
  .orbit-visual .ring, .orbit-visual .node {
    animation: none;
  }
}

/* ---------- forms ---------- */
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}

@media (max-width:680px) {
  .form-grid {
    grid-template-columns: 1fr;
  }
}

.field {
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
}

.field.full {
  grid-column: 1 / -1;
}

.field label {
  font-size: .8125rem;
  font-weight: 550;
  color: var(--ink);
}

.field input,
.field select,
.field textarea {
  font: inherit;
  font-size: .9375rem;
  color: var(--ink);
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface);
  transition: border-color .2s, box-shadow .2s;
}

.field textarea {
  min-height: 130px;
  resize: vertical;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--brand-500);
  box-shadow: 0 0 0 3px rgba(13, 155, 211, .16);
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--ink-50);
}

/* honeypot: has to be reachable by a bot's DOM walk but never by a human, so it
   is positioned out of view rather than display:none */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.captcha-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.captcha-question {
  display: inline-flex;
  align-items: center;
  height: 42px;
  padding: 0 14px;
  border-radius: var(--r);
  border: 1px solid rgba(13, 155, 211, .26);
  background: rgba(13, 155, 211, .08);
  font-size: .9375rem;
  font-weight: 550;
  color: var(--brand-700);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.captcha-refresh {
  flex: none;
  width: 42px;
  height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--ink-50);
  transition: color .2s, border-color .2s, background .2s;
}

.captcha-refresh:hover {
  color: var(--brand-700);
  border-color: rgba(13, 155, 211, .4);
  background: var(--accent-tint);
}

.captcha-field .captcha-row input {
  flex: 1;
}

.file-field input {
  padding: 9px 12px;
}

/* .show is added by site.js — errors are hidden until there is one to report */
.form-error {
  display: none;
  grid-column: 1 / -1;
  padding: 11px 14px;
  border-radius: var(--r);
  border: 1px solid rgba(225, 29, 72, .3);
  background: rgba(225, 29, 72, .07);
  color: #a4123a;
  font-size: .875rem;
}

.form-error.show {
  display: block;
}

.form-note {
  grid-column: 1 / -1;
  font-size: .8125rem;
  color: var(--ink-50);
}

#form-success {
  display: none;
  padding: 26px 24px;
  border-radius: var(--r-lg);
  border: 1px solid rgba(5, 150, 105, .3);
  background: linear-gradient(160deg, rgba(5, 150, 105, .1), transparent 70%), var(--surface);
}

#form-success.show {
  display: block;
}

/* ---------- legal documents ---------- */
.legal-doc {
  max-width: 780px;
  margin-inline: auto;
}

.legal-doc h2 {
  font-size: 1.5rem;
  letter-spacing: -.028em;
  margin: 40px 0 14px;
}

.legal-doc h3 {
  margin: 26px 0 10px;
}

.legal-doc p {
  margin-bottom: 14px;
  line-height: 1.75;
}

.legal-meta {
  display: inline-block;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid rgba(13, 155, 211, .26);
  background: rgba(13, 155, 211, .08);
  font-size: .8125rem;
  font-weight: 550;
  color: var(--brand-700);
}

.legal-list {
  display: grid;
  gap: 9px;
  margin: 0 0 18px;
}

.legal-list li {
  position: relative;
  padding-left: 18px;
  font-size: .9375rem;
  line-height: 1.65;
  color: var(--ink-50);
}

.legal-list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: .68em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--brand-500);
}

.legal-address {
  padding: 22px 24px;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: linear-gradient(160deg, #f4fafd, #fff 60%);
  font-size: .9375rem;
  /* The email and two phone numbers sit on consecutive <br> lines. At 1.7 the
     three links were 19px tall and 6.5px apart, which fails the tap-target
     spacing rule; the extra leading opens that to well over 8px. */
  line-height: 2.1;
}

/* each link is preceded by its own label on the same line, so these cannot be
   blocks the way .office-link is — the padding is what gives them height */
.legal-address a {
  display: inline-block;
  padding: 2px 0;
}

/* ---------- legacy button aliases ----------
   The inner pages spell the primary/secondary pair .btn-primary/.btn-outline.
   Mapped onto the same visual objects as .btn-solid/.btn-line so there is one
   button design on the site, not two. */
.btn-primary {
  position: relative;
  isolation: isolate;
  background: var(--brand-600);
  background-image: var(--grad-brand);
  color: #fff;
  box-shadow: 0 1px 2px rgba(4, 19, 32, .18), 0 10px 24px -12px rgba(13, 155, 211, .6);
}

.btn-primary::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: linear-gradient(120deg, #084f76 0%, #08719b 52%, #0d9bd3 100%);
  opacity: 0;
  transition: opacity .25s var(--ease);
}

.btn-primary:hover::after {
  opacity: 1;
}

.btn-primary:hover {
  box-shadow: 0 1px 2px rgba(4, 19, 32, .2), 0 14px 30px -12px rgba(13, 155, 211, .75);
}

.btn-outline {
  border: 1px solid var(--line);
  color: var(--ink);
  background: var(--surface);
}

.btn-outline:hover {
  color: var(--brand-700);
  background: var(--accent-tint);
  border-color: rgba(13, 155, 211, .45);
}

/* on a dark ground the neutral border disappears, so it is raised to a
   white alpha the user can actually see */
.btn-outline.on-dark,
.on-dark .btn-outline,
section.dark .btn-outline,
.cta-banner .btn-outline {
  background: rgba(255, 255, 255, .06);
  color: #fff;
  border-color: rgba(255, 255, 255, .28);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.btn-outline.on-dark:hover,
.on-dark .btn-outline:hover,
section.dark .btn-outline:hover,
.cta-banner .btn-outline:hover {
  background: rgba(140, 200, 235, .16);
  border-color: var(--brand-400);
  color: #fff;
}

/* a dark ground needs the inverted primary, or the gradient fill competes with
   the band behind it — and on the page hero it also has to match the homepage
   hero, which inverts its own primary to white */
.on-dark .btn-primary,
section.dark .btn-primary,
.cta-banner .btn-primary,
.aws-partner .btn-primary {
  background: #fff;
  background-image: none;
  color: var(--brand-800);
  box-shadow: 0 2px 6px rgba(4, 19, 32, .28), 0 16px 34px -18px rgba(4, 19, 32, .6);
}

.on-dark .btn-primary::after,
section.dark .btn-primary::after,
.cta-banner .btn-primary::after,
.aws-partner .btn-primary::after {
  background: linear-gradient(120deg, #fff, var(--brand-300));
}

/* ---------- misc aliases ---------- */
.logo {
  display: inline-flex;
  align-items: center;
  flex: none;
}

.logo img {
  height: 21px;
  width: auto;
}

.foot .logo img {
  height: 24px;
}

.illustration {
  margin: 0;
}

/* group label above a run of related-cards, used by the service index */
.group-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 40px 0 18px;
  font-size: 1.0625rem;
  letter-spacing: -.018em;
}

.group-head::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--line), transparent);
}

.on-light {
  color: var(--ink-70);
}

/* ---------- back to top ----------
   A real <button>, not an <a href="#top">: an anchor would push a #top fragment
   into the address bar and into every copied URL, which is exactly the kind of
   duplicate-with-fragment that canonical tags then have to clean up after.

   .show is added by site.js once the page is scrolled roughly one viewport
   down. Hidden with visibility rather than display so the fade can run, and
   pointer-events are dropped so it cannot be clicked or tabbed to while
   invisible. */
.to-top {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 880;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border: 1px solid rgba(140, 200, 235, .22);
  border-radius: 50%;
  cursor: pointer;
  color: #fff;
  background: var(--brand-700);
  background-image: var(--grad-brand);
  box-shadow: 0 2px 6px rgba(4, 19, 32, .2), 0 16px 34px -14px rgba(8, 60, 95, .55);
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity .28s var(--ease), transform .28s var(--ease), visibility .28s,
    box-shadow .28s var(--ease);
}

.to-top svg {
  width: 19px;
  height: 19px;
}

.to-top.show {
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
}

.to-top:hover {
  box-shadow: 0 2px 6px rgba(4, 19, 32, .24), 0 20px 40px -12px rgba(8, 60, 95, .7);
}

.to-top.show:hover {
  transform: translateY(-2px);
}

.to-top:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

/* Clear of the thumb zone and of the sticky WhatsApp/phone chrome mobile
   browsers paint at the bottom edge. Still 44px so it stays a legal tap
   target — the audit's "enlarge/space tap targets" note applies here too. */
@media (max-width:560px) {
  .to-top {
    right: 14px;
    bottom: 14px;
    width: 44px;
    height: 44px;
  }
}

/* The button's only job is to move the viewport, and site.js honours the same
   preference for the scroll itself. */
@media (prefers-reduced-motion: reduce) {
  .to-top {
    transition: opacity .01s, visibility .01s;
    transform: none;
  }

  .to-top.show:hover {
    transform: none;
  }
}
