

:root {
  --ink: #11324D;
  --ocean: #1E5F8B;
  --mint: #25B37A;

  --brand-green-text: #0F6B46;
  --amber: #F2A65A;
  --cloud: #F5F8FB;
  --slate: #273444;
  --text: #1B2733;
  --muted: #5A6B7B;
  --line: #DCE5EE;
  --bg: #FFFFFF;
  --max: 1080px;


  --step--1: clamp(0.875rem, 0.84rem + 0.18vw, 0.95rem);
  --step-0:  clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  --step-1:  clamp(1.2rem, 1.12rem + 0.4vw, 1.35rem);
  --step-2:  clamp(1.45rem, 1.3rem + 0.75vw, 1.75rem);
  --step-3:  clamp(1.75rem, 1.5rem + 1.25vw, 2.25rem);
  --step-4:  clamp(2.1rem, 1.6rem + 2.5vw, 3.25rem);

  /* ── Spacing rhythm. Everything is a multiple of 4, so vertical
   * spacing lands on a grid instead of being eyeballed per section. */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 72px;
  --sp-9: 104px;

  /* ── Depth. Layered, low-alpha shadows read as "expensive"; a single
   * hard shadow reads as "bootstrap default". Tinted with the brand ink
   * rather than pure black so surfaces feel part of one palette. */
  --shadow-1: 0 1px 2px rgba(17, 50, 77, 0.05),
              0 1px 3px rgba(17, 50, 77, 0.04);
  --shadow-2: 0 2px 4px rgba(17, 50, 77, 0.05),
              0 6px 16px -4px rgba(17, 50, 77, 0.09);
  --shadow-3: 0 4px 8px rgba(17, 50, 77, 0.06),
              0 16px 40px -8px rgba(17, 50, 77, 0.14);

  --radius-1: 10px;
  --radius-2: 14px;
  --radius-3: 22px;

  /* One easing curve for the whole site. Mixed easings are a tell. */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;

  overflow-x: clip;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
  font-size: var(--step-0);
  line-height: 1.65;
  /* Premium type detail: kern/ligature control + optical smoothing. Cheap,
   * and the difference is visible at heading sizes. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: "kern" 1, "liga" 1;
}

a { color: var(--ocean); }
a:focus-visible,
button:focus-visible {
  outline: 3px solid var(--amber);
  outline-offset: 2px;
}

/* ---------- header ---------- */
.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 24px;
  border-bottom: 1px solid var(--line);
  background: #fff;
  position: sticky;
  top: 0;
  z-index: 10;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: var(--ink);
}
/* The wordmark and the tagline stack, so the mark sits beside BOTH rather
 * than beside the name alone -- that vertical relationship is what makes a
 * lockup read as one object. */
.brand-text {
  display: flex;
  flex-direction: column;

  line-height: 1.1;
}
.brand-name {
  font-weight: 800;
  /* ~22px on a phone, ~28px on a desktop: a real step above the 16-17px
   * nav without making the sticky header taller than it needs to be. */
  font-size: clamp(1.4rem, 1.2rem + 0.9vw, 1.75rem);
  /* Large, heavy type needs its tracking pulled IN; the default spacing
   * that suits 16px body text reads loose and amateurish at 28px. */
  letter-spacing: -0.015em;
}


.brand-tagline {
  /* Own line, guaranteed: `.brand-text` is a column flex container, so this
   * cannot share a line with the wordmark no matter how much room there is. */
  display: block;
  /* CLAIM 3: one more pixel of separation, cheap and asked for. */
  margin-top: 5px;

  font-size: clamp(0.7rem, 0.66rem + 0.12vw, 0.75rem);
  /* 🔴 NOT italic. Italic was doing the delineation work that SIZE and
   * TRACKING should do; at 12px, italic in a UI sans is the least legible
   * option available. */
  font-style: normal;
  /* 500 against the wordmark 800: enough weight to lift a small line
     off a white ground while keeping the hierarchy. */
  font-weight: 500;
  /* Tracking OPENS as size comes down -- the opposite of the wordmark's
   * tight -0.015em. Held at 0.02em because this line cannot wrap (see the
   * width table above). */
  letter-spacing: 0.02em;
  line-height: 1.25;

  color: var(--brand-green-text);
  white-space: nowrap;
}


.tagline-bubble {
  display: inline-block;
  /* Asymmetric by 2px so it does not read as a machined pill.
     Vertical padding stays 3px: the header is sticky, so every pixel
     is taken from every screenful of every page. */
  padding: 3px 13px 3px 11px;

  border-radius: 26px 9px 22px 12px / 10px 5px 8px 6px;

  background: linear-gradient(105deg,
    #11324D 0%, #1E5F8B 52%, #0F6B46 100%);
  color: #fff;
  /* An inset top highlight + a barely-there drop shadow: this is what makes
   * it look printed/moulded rather than like a flat coloured rectangle. */
  box-shadow: inset 0 1px 2px rgba(255, 255, 255, 0.18),
              0 1px 3px rgba(17, 50, 77, 0.16);

  transform: rotate(-0.45deg);
  /* White on a saturated gradient renders heavy without this. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
/* 🔴 The header is `position: sticky`, so every pixel it gains is taken
 * from every screenful of every page. Below ~900px the nav already wraps
 * and the tagline would either wrap with it or force a horizontal
 * squeeze, so the lockup degrades to mark + wordmark -- which is the part
 * that carries the brand. The tagline still appears on that page, in the
 * footer signature.
 * ⚠️ `display: none`, not `visibility`/opacity: a hidden-but-present line
 * would still occupy height, which is the thing being reclaimed. */
@media (max-width: 900px) {
  .brand-tagline { display: none; }
}

.brand-mark {
  width: 44px;
  height: 44px;
  display: block;
  flex: none;
}
.site-header nav {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}
.site-header nav a {
  text-decoration: none;
  color: var(--slate);
  font-weight: 600;
}
.site-header nav a:hover { text-decoration: underline; }
.site-header nav a[aria-current="page"] {
  color: var(--ocean);
  text-decoration: underline;
}
.site-header nav a.cta {
  background: var(--mint);
  color: #fff;
  padding: 9px 16px;
  border-radius: 8px;
}


.footer-tagline {
  margin: 2px 0 10px;
  font-size: 0.85rem;
  font-style: italic;
  opacity: 0.75;
  max-width: 24ch;
}


.site-header nav a.lang-toggle {
  border: 1.5px solid var(--slate);
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 0.9rem;
  line-height: 1.2;
  white-space: nowrap;
}
.site-header nav a.lang-toggle:hover {
  background: var(--slate);
  color: #fff;
  text-decoration: none;
}


.hero {
  position: relative;
  max-width: var(--max);
  margin: 0 auto;

  padding: clamp(40px, 7vw, 104px) var(--sp-5) clamp(28px, 4vw, 48px);
  isolation: isolate;          /* keeps the canvas behind the text */
  /* Structural guard: even if a future decorative child overflows, it can
   * never add to the page's scroll width. `clip` (not `hidden`) because it
   * does not create a scroll container. */
  overflow: clip;
}
.narrow-hero { padding-bottom: var(--sp-2); }
.hero h1 {
  margin: 0 0 var(--sp-4);
  font-size: var(--step-4);
  line-height: 1.08;
  color: var(--ink);
  /* Tighter tracking at display sizes is the single biggest "designed vs
   * default" tell in a headline. */
  letter-spacing: -0.028em;
  font-weight: 760;
  text-wrap: balance;          /* no lonely last word */
}
.lede {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--muted);
  max-width: 60ch;
  margin: 0 0 var(--sp-5);
  text-wrap: pretty;
}
.lede.narrow { max-width: 54ch; }
.hero-actions {
  display: flex;
  gap: var(--sp-3);
  flex-wrap: wrap;
  margin-top: var(--sp-6);
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 13px 22px;
  border-radius: var(--radius-1);
  border: 1px solid var(--line);
  background: #fff;
  color: var(--ink);
  text-decoration: none;
  font-weight: 650;
  font-size: var(--step-0);
  letter-spacing: -0.01em;
  margin: 0 var(--sp-2) var(--sp-2) 0;
  box-shadow: var(--shadow-1);
  /* ⚠️ Transition named properties, never `all`: `all` animates layout
   * properties too and causes jank on low-end phones. */
  transition: transform 180ms var(--ease),
              box-shadow 180ms var(--ease),
              border-color 180ms var(--ease),
              background-color 180ms var(--ease);
}
.btn:hover {
  border-color: var(--ocean);
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
}
.btn:active { transform: translateY(0); box-shadow: var(--shadow-1); }
.btn.primary {
  background: var(--ocean);
  border-color: var(--ocean);
  color: #fff;
  box-shadow: 0 1px 2px rgba(17, 50, 77, 0.12),
              0 8px 20px -6px rgba(30, 95, 139, 0.45);
}
.btn.primary:hover {
  background: #17507a;
  box-shadow: 0 2px 4px rgba(17, 50, 77, 0.14),
              0 14px 30px -8px rgba(30, 95, 139, 0.55);
}

/* ---------- panels ---------- */
.panel {
  max-width: var(--max);
  margin: 0 auto;
  padding: var(--sp-8) var(--sp-5);
}
.panel.alt {
  background: var(--cloud);
  max-width: none;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.panel.alt > * { max-width: var(--max); margin-left: auto; margin-right: auto; }
.panel.centred { text-align: center; }
.panel h2 {
  margin: 0 0 var(--sp-5);
  font-size: var(--step-3);
  line-height: 1.2;
  letter-spacing: -0.022em;
  font-weight: 720;
  color: var(--ink);
  text-wrap: balance;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--sp-4);
}
.grid.two { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.card {
  border: 1px solid var(--line);
  border-radius: var(--radius-2);
  padding: var(--sp-5);
  background: #fff;
  box-shadow: var(--shadow-1);
  transition: transform 220ms var(--ease), box-shadow 220ms var(--ease),
              border-color 220ms var(--ease);
}
.card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-2);
  border-color: #C9D8E8;
}
.card h3 {
  margin: 0 0 var(--sp-2);
  font-size: var(--step-1);
  line-height: 1.3;
  letter-spacing: -0.014em;
  font-weight: 680;
  color: var(--ocean);
}
.card p { margin: 0; color: var(--muted); }
.card.contact .contact-value {
  font-size: 19px;
  font-weight: 700;
  margin: 0 0 10px;
}

/* Company-details table on /about/. Two columns, label + value. */
.doc-table { border-collapse: collapse; width: 100%; margin: 18px 0; }
.doc-table th, .doc-table td {
  border: 1px solid var(--line);
  padding: 10px 12px;
  text-align: left;
  vertical-align: top;
}
.doc-table th {
  background: var(--cloud);
  width: 34%;
  font-weight: 600;
  color: var(--ink);
}
@media (max-width: 520px) {
  /* Stack on small screens so a long address never forces a sideways
     scroll — the site is read on phones more than on desktops. */
  .doc-table th, .doc-table td { display: block; width: auto; }
  .doc-table th { border-bottom: 0; }
}

.roles { padding-left: 20px; margin: 0 0 18px; }
.roles li { margin-bottom: 8px; }

.note {
  margin-top: 22px;
  padding: 14px 16px;
  border-left: 4px solid var(--amber);
  background: #FFF8F0;
  border-radius: 0 8px 8px 0;
}
.panel.alt .note { background: #fff; }

/* ---------- FAQ / long-form documents ---------- */
.faq h3 {
  margin: 26px 0 6px;
  font-size: 19px;
  color: var(--ink);
}
.faq p { margin: 0 0 6px; color: var(--muted); max-width: 72ch; }

.doc { max-width: 78ch; }
.doc h1 { color: var(--ink); }
.doc h2 { margin: 28px 0 8px; color: var(--ink); font-size: 22px; }
.doc h3 { margin: 20px 0 6px; color: var(--slate); font-size: 18px; }
.doc table { border-collapse: collapse; width: 100%; margin: 16px 0; }
.doc th, .doc td {
  border: 1px solid var(--line);
  padding: 8px 10px;
  text-align: left;
  vertical-align: top;
}
.doc th { background: var(--cloud); }
.doc code {
  background: var(--cloud);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 0.92em;
}
.doc blockquote {
  margin: 16px 0;
  padding: 8px 16px;
  border-left: 4px solid var(--ocean);
  color: var(--muted);
}
.updated { color: var(--muted); font-size: 15px; }

/* ---------- footer ---------- */
.site-footer {
  border-top: 1px solid var(--line);
  background: var(--slate);
  color: #E6ECF2;
  padding: 40px 24px 20px;
}
.footer-cols {
  max-width: var(--max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 26px;
}
.site-footer h4 { margin: 0 0 10px; font-size: 15px; color: #fff; }
.site-footer a {
  display: block;
  color: #CFE0EE;
  text-decoration: none;
  margin-bottom: 7px;
}
.site-footer a:hover { text-decoration: underline; color: #fff; }
.site-footer .muted { color: #A9BCCD; margin: 0; }
.copyright {
  max-width: var(--max);
  margin: 28px auto 0;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  color: #A9BCCD;
  font-size: 14px;
}


.hero-canvas {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  pointer-events: none;
  /* Fade the field out behind the text so contrast is never reduced. */
  mask-image: radial-gradient(120% 100% at 70% 35%,
              rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.35) 45%,
              transparent 78%);
  -webkit-mask-image: radial-gradient(120% 100% at 70% 35%,
              rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.35) 45%,
              transparent 78%);
  opacity: 0;
  transition: opacity 900ms var(--ease);
}
.hero-canvas.is-ready { opacity: 1; }


@media (max-width: 620px) {

  .hero-canvas.is-ready { opacity: 0.7; }
  .hero-canvas {
    mask-image: radial-gradient(95% 62% at 82% 12%,
                rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.3) 42%,
                transparent 70%);
    -webkit-mask-image: radial-gradient(95% 62% at 82% 12%,
                rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.3) 42%,
                transparent 70%);
  }
  /* The wash is also proportionally stronger on a tall narrow hero. */
  .hero::before { opacity: 0.7; }
}

/* Dark mode keeps full strength on a phone: against #0F1720 the
   limiting factor is visibility, not dominance. */
@media (max-width: 620px) and (prefers-color-scheme: dark) {
  .hero-canvas.is-ready { opacity: 1; }
}

/* A soft brand wash under the hero, pure CSS, no JS. This alone lifts the
 * page out of "white default" territory even if the canvas never loads. */
.hero::before {
  content: "";
  position: absolute;

  inset: 0;
  z-index: -2;
  /* Gradient centres moved inboard (was 18%/82%, now 25%/78%) and radii
   * widened, so the wash still feels edge-to-edge now that it can no
   * longer physically extend past the hero. */
  background:
    radial-gradient(60% 70% at 25% 18%,
      rgba(37, 179, 122, 0.11) 0%, transparent 72%),
    radial-gradient(65% 75% at 78% 8%,
      rgba(30, 95, 139, 0.14) 0%, transparent 74%),
    radial-gradient(55% 65% at 58% 92%,
      rgba(242, 166, 90, 0.09) 0%, transparent 76%);
  pointer-events: none;
}

/* ---------- scroll reveal ----------
   Default state is VISIBLE; script opts elements into the hidden
   state, so a script failure can never leave content invisible. */
.reveal-ready .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 620ms var(--ease), transform 620ms var(--ease);
  will-change: opacity, transform;
}
.reveal-ready .reveal.is-visible {
  opacity: 1;
  transform: none;
}




body > svg[aria-hidden="true"]:not(.ico),
svg.icon-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.ico {
  width: 1.1em;
  height: 1.1em;
  flex: none;
  vertical-align: -0.14em;
  /* Slightly thinner than the text it sits beside, so the icon supports
   * the label instead of competing with it. */
  opacity: 0.92;
}

/* A card heading that leads with an icon. */
.card h3 .ico,
.panel h2 .ico { margin-right: 0.42em; }


.card.contact h3 {
  display: flex;
  align-items: center;
}
.card.contact .contact-value .ico {
  width: 1em;
  height: 1em;
  margin-right: 0.4em;
  color: var(--mint);
}
.contact-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--cloud);
  text-decoration: none;
  color: var(--ink);
  font-weight: 650;
  transition: transform 180ms var(--ease), box-shadow 180ms var(--ease),
              border-color 180ms var(--ease);
}
.contact-chip:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-2);
  border-color: var(--ocean);
}


.flow {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--sp-4);
  counter-reset: flowstep;
}
.flow li {
  position: relative;
  counter-increment: flowstep;
  padding: var(--sp-5) var(--sp-4) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-2);
  background: #fff;
  box-shadow: var(--shadow-1);
}
.flow li::before {
  content: counter(flowstep);
  position: absolute;
  top: calc(-1 * var(--sp-3));
  left: var(--sp-4);
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--ocean);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
}
.flow .ico {
  width: 26px;
  height: 26px;
  color: var(--mint);
  margin-bottom: var(--sp-2);
  opacity: 1;
}
.flow strong { display: block; margin-bottom: 4px; color: var(--ink); }
.flow p { margin: 0; color: var(--muted); font-size: var(--step--1); }

/* ---------- careers: the level ladder ----------
 * 🔑 Presented as an ORDERED list because the order is the point — these
 * are the six rungs of users/access_control.py's LEVEL_RANK, and the page
 * says so. Numbered by CSS counters (same technique as `.flow`) so the
 * numerals are never part of the copy and cannot drift from the list. */
.ladder {
  list-style: none;
  margin: var(--sp-5) 0 var(--sp-4);
  padding: 0;
  counter-reset: rung;
  display: grid;
  gap: var(--sp-3);
}
.ladder li {
  counter-increment: rung;
  position: relative;
  padding: var(--sp-4) var(--sp-4) var(--sp-4) 62px;
  border: 1px solid var(--line);
  border-radius: var(--radius-2);
  background: #fff;
  box-shadow: var(--shadow-1);
}
.ladder li::before {
  content: counter(rung);
  position: absolute;
  left: var(--sp-4);
  top: 50%;
  transform: translateY(-50%);
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  /* Rising weight reads as a ladder without needing six colours. */
  background: var(--ocean);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.ladder li strong { display: block; color: var(--ink); margin-bottom: 2px; }
.ladder li span { color: var(--muted); font-size: var(--step--1); }

/* ---------- careers: a department and its positions ---------- */
.dept {
  margin: var(--sp-6) 0 0;
  padding: var(--sp-5) 0 0;
  border-top: 1px solid var(--line);
}
.dept:first-of-type { border-top: 0; padding-top: var(--sp-4); }
.dept-head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
}
.dept-head .ico {
  width: 24px;
  height: 24px;
  color: var(--mint);
  flex: none;
  opacity: 1;
}
.dept-head h3 {
  margin: 0;
  font-size: var(--step-2);
  letter-spacing: -0.018em;
  color: var(--ink);
}
.dept-count {

  margin-left: auto;
  font-size: var(--step--1);
  font-weight: 650;
  color: var(--muted);
  background: var(--cloud);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 3px 11px;
  white-space: nowrap;
}
.dept-blurb {
  margin: var(--sp-3) 0 0;
  color: var(--muted);
  max-width: 66ch;
}
.roles-list {
  list-style: none;
  margin: var(--sp-4) 0 0;
  padding: 0;
  display: grid;
  /* One column on a phone, two where there is genuinely room. 320px is
   * above the widest role title, so a title never wraps mid-word. */
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--sp-3);
}
.roles-list > li {
  padding: var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-2);
  background: #fff;
  box-shadow: var(--shadow-1);
  transition: border-color 180ms var(--ease), box-shadow 180ms var(--ease),
              transform 180ms var(--ease);
}
.roles-list > li:hover {
  border-color: var(--ocean);
  box-shadow: var(--shadow-2);
  transform: translateY(-2px);
}
.role-head {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  flex-wrap: wrap;
}
.role-head strong {
  color: var(--ocean);
  font-size: var(--step-0);
  letter-spacing: -0.012em;
}
.role-level {
  margin-left: auto;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  white-space: nowrap;
}
.role-sum {
  margin: var(--sp-2) 0 0;
  color: var(--muted);
  font-size: var(--step--1);
  line-height: 1.55;
}
.role-req {
  margin: var(--sp-3) 0 0;
  padding-top: var(--sp-3);
  border-top: 1px dashed var(--line);
  color: var(--muted);
  font-size: var(--step--1);
}
.role-req-k {
  display: block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink);
  margin-bottom: 2px;
}

/* ---------- role list with icons ---------- */
ul.roles.iconic { list-style: none; padding: 0; }
ul.roles.iconic li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--line);
}
ul.roles.iconic li:last-child { border-bottom: 0; }
ul.roles.iconic .ico {
  width: 22px;
  height: 22px;
  color: var(--ocean);
  margin-top: 2px;
  opacity: 1;
}

/* ---------- video section ----------
 * 🔴 W-2: these are PUBLIC marketing videos. Private staff-training video
 * lives behind auth in the app and must never appear here. */
.video-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--sp-4);
}
.video-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-2);
  overflow: hidden;
  background: #fff;
  box-shadow: var(--shadow-1);
}
/* 16:9 without a wrapper hack. */
.video-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--cloud);
  display: grid;
  place-items: center;
  border-bottom: 1px solid var(--line);
}
.video-frame video,
.video-frame iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  object-fit: cover;
}
.video-placeholder {
  display: grid;
  place-items: center;
  gap: var(--sp-2);
  color: var(--muted);
  text-align: center;
  padding: var(--sp-4);
}
.video-placeholder .ico {
  width: 38px;
  height: 38px;
  color: var(--ocean);
  opacity: 1;
}

#promo-reel[hidden],
.promo-card[hidden] { display: none; }
.promo-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--sp-4);
}

.video-body { padding: var(--sp-4); }
.video-body h3 {
  margin: 0 0 6px;
  font-size: var(--step-1);
  letter-spacing: -0.014em;
  color: var(--ocean);
}
.video-body p { margin: 0; color: var(--muted); font-size: var(--step--1); }



.tablist { display: none; }
.tabs-ready .tablist {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-5);
  /* 6px so the 21px chip corners nest inside the 27px frame corners. */
  padding: 6px;
  background: var(--cloud);
  border: 1px solid var(--line);
  /* Concentric by construction: chip radius (21px) + padding (6px). Holds
   * at ONE row and at FIVE, because it never depends on the box height. */
  border-radius: 27px;
  width: fit-content;
  max-width: 100%;
}
/* The pill shape is correct while the strip is a single row;
   `.is-wrapped` is set when it measures more than one. */
.tabs-ready .tablist:not(.is-wrapped) { border-radius: 999px; }
/* Once wrapped, stretch to the container so the rows are not floating
 * inside an over-wide pill sized by the longest row. */
.tabs-ready .tablist.is-wrapped { width: 100%; }
.tablist button {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-weight: 650;
  font-size: var(--step--1);
  padding: 9px 16px;
  border-radius: 999px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  transition: background-color 180ms var(--ease), color 180ms var(--ease);
}
.tablist button:hover { color: var(--ink); }
.tablist button[aria-selected="true"] {
  background: #fff;
  color: var(--ink);
  box-shadow: var(--shadow-1);
}
.tablist .ico { width: 16px; height: 16px; }

/* Panels: visible by default (no-JS), hidden only once tabs are active. */
.tabs-ready .tabpanel[hidden] { display: none; }
.tabs-ready .tabpanel {
  animation: tabfade 380ms var(--ease);
}
@keyframes tabfade {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
/* The per-panel heading is redundant once the tab strip labels it. */
.tabs-ready .tabpanel > h3.tab-heading { display: none; }

/* ---------- stat strip ---------- */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--sp-4);
  margin: var(--sp-5) 0 0;
  padding: 0;
  list-style: none;
}
.stats li {
  padding: var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-2);
  background: #fff;
  box-shadow: var(--shadow-1);
}
.stats .ico { width: 24px; height: 24px; color: var(--mint); opacity: 1; }
.stats strong {
  display: block;
  font-size: var(--step-2);
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: var(--sp-2) 0 2px;
}
.stats span { color: var(--muted); font-size: var(--step--1); }

/* ---------- section eyebrow ----------
 * Small caps label above a heading; a cheap, very effective "considered
 * layout" signal. */
.eyebrow {
  display: inline-block;
  margin: 0 0 var(--sp-3);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mint);
}


@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0F1720;
    --text: #E8EEF4;
    --muted: #A9BCCD;
    --line: #24323F;
    --cloud: #16212C;
    --ink: #DCE9F5;

    --brand-green-text: #4FD6A0;

  }

  .site-header nav a { color: #C6D6E5; }
  .doc h3 { color: #C6D6E5; }





  .flow li,
  .video-card { background: #131E28; border-color: #263544; }
  .video-frame { background: #16212C; border-bottom-color: #263544; }
  .contact-chip {
    background: #16212C;
    border-color: #263544;
    color: var(--text);
  }
  .contact-chip:hover { border-color: #7FC4EE; }
  .flow strong { color: var(--ink); }
  /* Card/flow/video headings use --ocean, which stays dark in :root, so
   * they need the same light treatment as `.card h3`. */
  .video-body h3 { color: #7FC4EE; }
  ul.roles.iconic .ico { color: #7FC4EE; }
  ul.roles.iconic li { border-bottom-color: #263544; }
  .video-placeholder .ico { color: #7FC4EE; }


  .ladder li,
  .roles-list > li { background: #131E28; border-color: #263544; }
  .roles-list > li:hover { border-color: #35495C; }
  .role-head strong { color: #7FC4EE; }
  .role-req { border-top-color: #263544; }
  .role-req-k { color: var(--ink); }
  .dept { border-top-color: #263544; }
  .dept-count { background: #16212C; border-color: #263544; }


  .tabs-ready .tablist { background: #16212C; border-color: #263544; }
  .tablist button[aria-selected="true"] {
    background: #1F2E3C;
    color: var(--ink);
  }
  .stats li { background: #131E28; border-color: #263544; }
  .stats strong { color: var(--ink); }

  a,
  .card h3,
  .site-header nav a[aria-current="page"] { color: #7FC4EE; }
  /* Filled controls keep the DARK brand colour behind light text, so their
   * contrast is unchanged from light mode. */
  .btn.primary { background: var(--ocean); border-color: var(--ocean); color: #fff; }
  .site-header nav a.cta { background: var(--mint); color: #06281B; }
  .site-header, .card { background: #131E28; }
  .btn { background: #131E28; color: var(--text); }
  .note { background: #1B2632; }
  .panel.alt .note { background: #131E28; }
  /* Shadows are invisible on dark surfaces, so depth has to come from a
   * lighter border instead. Keeping the same shadow vars would make every
   * card look flat in dark mode. */
  .card { border-color: #263544; box-shadow: none; }
  .card:hover { border-color: #35495C; transform: translateY(-2px); }
  .btn { box-shadow: none; }
  /* The hero wash is tuned for a white page; at these alphas on #0F1720 it
   * turns muddy, so re-weight it rather than reuse it. */
  .hero::before {
    /* Geometry kept in step with the light-mode rule above — if only one
     * copy is updated the two themes drift apart silently. */
    background:
      radial-gradient(60% 70% at 25% 18%,
        rgba(37, 179, 122, 0.16) 0%, transparent 72%),
      radial-gradient(65% 75% at 78% 8%,
        rgba(70, 150, 205, 0.18) 0%, transparent 74%),
      radial-gradient(55% 65% at 58% 92%,
        rgba(242, 166, 90, 0.10) 0%, transparent 76%);
  }
}


/* Sample application gallery on /brand/. Photographs, not a drawing, so
 * the grid must cope with three different aspect ratios (1.92, 2.63 and
 * 3.40) without cropping any of them: a printer is judging placement. */
.sample-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--sp-4);
  margin-top: var(--sp-4);
}

.sample-card {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-2);
  overflow: hidden;
  background: #fff;
  box-shadow: var(--shadow-1);
  display: flex;
  flex-direction: column;
}

.sample-card img {
  display: block;
  width: 100%;
  height: auto;
  border-bottom: 1px solid var(--line);
}

.sample-card figcaption {
  padding: var(--sp-4);
  font-size: var(--step--1);
  color: var(--muted);
}

.sample-card figcaption strong {
  display: block;
  margin-bottom: 4px;
  font-size: var(--step-0);
  font-weight: 680;
  letter-spacing: -0.014em;
  color: var(--ocean);
}

/* The close-up carries the only fully legible tagline in the gallery,
 * so it spans the row rather than shrinking into a column.
 *
 * But `width:100%` on a 606px-wide source then UPSCALED it to ~1000px
 * and visibly softened the small print -- the opposite of the card's
 * whole purpose. An image may be shown smaller than its pixels, never
 * larger, so the width is capped at native and the figure centres it. */
.sample-card.wide { grid-column: 1 / -1; }
.sample-card.wide img {
  max-width: 606px;
  margin: 0 auto;
  border-bottom: 0;
  border-radius: var(--radius-1);
}
.sample-card.wide figcaption { border-top: 1px solid var(--line); }



@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
  /* The blanket rule above disables TRANSITIONS, not the effects
     themselves, so two cases need explicit handling: the canvas is
     hidden, and .reveal elements are forced visible -- without that
     they stay at opacity 0 and the page looks broken. */
  .hero-canvas { display: none !important; }
  .reveal-ready .reveal {
    opacity: 1 !important;
    transform: none !important;
  }
  .btn:hover, .card:hover { transform: none !important; }
}
