/* ─────────────────────────────────────────────────────────────
   Whirlybird — site stylesheet
   Brand tokens follow the Whirlybird Design System:
   five colors (amber, white, mist, slate, navy), Inter 400/600/900,
   24px radius, flat surfaces, short flat motion.
   ───────────────────────────────────────────────────────────── */

:root {
  color-scheme: light;

  /* palette */
  --amber: #FBB33B;
  --amber-hover: #EFA52C;
  --amber-press: #DE9520;
  --white: #FFFFFF;
  --mist: #F4F4F4;
  --mist-hover: #E9E9E9;
  --mist-press: #DEDEDE;
  --slate: #5C5C5C;
  --navy: #1C244B;
  --navy-hover: #2A3564;
  --hairline: rgba(28, 36, 75, 0.14);
  --hairline-strong: rgba(28, 36, 75, 0.28);
  --hairline-on-dark: rgba(244, 244, 244, 0.18);

  /* scrims, overlay, shadows */
  /* the case-study backdrop uses neutral dark; the hero reels and video thumbnails use navy */
  --shade: 12, 14, 20;
  --navy-rgb: 28, 36, 75; /* video thumbnails sit under navy scrims */
  --media-ground: #15171C;
  --scrim-text: linear-gradient(to top, rgba(var(--navy-rgb), 0.62) 0%, rgba(var(--navy-rgb), 0.42) 55%, rgba(var(--navy-rgb), 0) 100%);
  --scrim-flat: rgba(var(--navy-rgb), 0.12);
  --overlay: rgba(var(--shade), 0.72);
  --shadow-raised: 0 2px 8px rgba(28, 36, 75, 0.06);
  --shadow-floating: 0 8px 24px rgba(28, 36, 75, 0.1);
  --shadow-modal: 0 24px 64px rgba(28, 36, 75, 0.18);
  /* white cards on a white band: a faint edge and a soft shadow (the Inflight Menu) */
  --shadow-card: 0 0 0 1px rgba(var(--navy-rgb), 0.07), 0 2px 4px rgba(var(--navy-rgb), 0.05), 0 18px 44px -14px rgba(var(--navy-rgb), 0.28);

  /* shape */
  --r-xl: 24px;
  --r-lg: 16px;
  --r-md: 12px;
  --r-sm: 8px;

  /* motion */
  --dur-instant: 90ms;
  --dur-fast: 140ms;
  --dur-base: 200ms;
  --dur-slow: 320ms;
  --dur-reveal: 480ms;
  --ease: cubic-bezier(0.2, 0, 0.2, 1);
  --ease-out: cubic-bezier(0.25, 1, 0.5, 1);

  /* type */
  --font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --fs-hero: clamp(3.5rem, 0.9rem + 10.2vw, 8.5rem);
  --fs-d1: clamp(2.75rem, 1.35rem + 5.4vw, 6rem);
  --fs-d2: clamp(2.5rem, 1.65rem + 3.1vw, 4.25rem);
  --fs-d3: clamp(2.5rem, 2.05rem + 1.3vw, 3.25rem);
  --fs-section: clamp(2.75rem, 1.5rem + 3.6vw, 4.5rem); /* every section heading, sized to About Us */
  --head-gap: clamp(16px, 19.4px - 0.24vw, 18.5px); /* heading → body text; the visible space matches eyebrow → heading */
  --eyebrow-gap: 19px; /* the standard space under an eyebrow label, before the heading or line it introduces */
  --fs-h3: clamp(1.375rem, 1.25rem + 0.4vw, 1.625rem);
  --fs-lead: clamp(1.125rem, 1.03rem + 0.4vw, 1.375rem);
  --fs-body: 1.0625rem;

  /* layout */
  --container: 1200px;
  --container-wide: 1400px;
  --gutter: clamp(16px, 4vw, 48px);
  --band-y: clamp(88px, 10.5vw, 160px);
  --band-y-tight: clamp(56px, 6vw, 88px);
  --header-h: 72px;
}

/* ── base ── */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + env(safe-area-inset-top, 0px));
}

body {
  margin: 0;
  background: var(--mist);
  color: var(--slate);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: 1.6;
  font-weight: 400;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

[hidden] { display: none !important; }
img, video { max-width: 100%; display: block; }
h1, h2, h3, p, ul { margin: 0; }
ul { padding: 0; list-style: none; }
button, input { font: inherit; color: inherit; }
p { text-wrap: pretty; }
em strong, strong em { font-weight: 700; }

a { color: var(--navy); text-decoration: none; transition: color var(--dur-fast) var(--ease); }

:focus-visible { outline: 2px solid var(--navy); outline-offset: 3px; border-radius: var(--r-sm); }
/* over the reel (the hero, and the header while it's still clear over it) the ring is amber, the design system's ring on dark */
.hero :focus-visible,
.js .site-header[data-over="dark"]:not(.is-solid):not(.menu-open) :focus-visible { outline-color: var(--amber); }

::selection { background: var(--amber); color: var(--navy); }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: 16px; top: -100px; z-index: 100;
  background: var(--amber); color: var(--navy); padding: 12px 20px; border-radius: var(--r-xl);
  font-weight: 600;
}
.skip-link:focus { top: 12px; }

.icon { width: 20px; height: 20px; flex: none; }

/* ── layout ── */
.container { width: min(100% - 2 * var(--gutter), var(--container)); margin-inline: auto; }
.container-wide { width: min(100% - 2 * var(--gutter), var(--container-wide)); margin-inline: auto; }
.band { padding-block: var(--band-y); }
.band-white { background: var(--white); }
.band-mist { background: var(--mist); }
.band-amber { background: var(--amber); color: var(--navy); }

/* ── type ── */
.display {
  font-weight: 900;
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--amber);
  text-wrap: balance;
}
.display .line { display: block; }

.eyebrow {
  font-size: 0.9375rem;
  line-height: 1.25rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--navy);
  margin-bottom: var(--eyebrow-gap);
}

.lead {
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--slate);
  max-width: 34em;
}
.band-amber .lead { color: var(--navy); }

/* ── buttons ──
   Filled at rest. On hover the fill drops away and leaves a stroke in the fill colour (a hollow
   inversion), the label takes whichever colour reads best on what shows through, and the button
   lifts: it rises 2px on a soft shadow, and settles back down when pressed. Touch screens can't
   hover, so there the hollow state shows only while the button is pressed. */
.btn,
.icon-btn-amber {
  /* the lift: two shadow layers, kept at zero at rest so they can ease in */
  --lift: 0 0 0 0 rgba(var(--navy-rgb), 0), 0 0 0 0 rgba(var(--navy-rgb), 0);
  --lift-up: 0 14px 24px -12px rgba(var(--navy-rgb), 0.42), 0 4px 10px -4px rgba(var(--navy-rgb), 0.16);
  --lift-pressed: 0 6px 12px -8px rgba(var(--navy-rgb), 0.36), 0 1px 3px 0 rgba(var(--navy-rgb), 0.12);
}
.btn {
  --btn-bg: var(--amber);
  --btn-ring: var(--btn-bg);
  --btn-ring-w: 2px;
  --btn-fg: var(--navy);
  --btn-fg-hollow: var(--navy);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
  padding: 12px 24px;
  border: 0;
  border-radius: var(--r-xl);
  background-color: var(--btn-bg);
  box-shadow: inset 0 0 0 var(--btn-ring-w) var(--btn-ring), var(--lift);
  color: var(--btn-fg);
  font-size: 1rem;
  line-height: 1.5;
  font-weight: 600;
  letter-spacing: -0.005em;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-base) var(--ease), color var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.btn:active { background-color: transparent; color: var(--btn-fg-hollow); transform: translateY(0) scale(0.98); --lift: var(--lift-pressed); transition-duration: var(--dur-instant); }
.btn-lg { min-height: 56px; padding: 14px 28px; font-size: 1.0625rem; }
.btn-sm { min-height: 44px; padding: 10px 20px; font-size: 0.9375rem; }
/* already hollow: a thin navy stroke that stays navy; on hover it just lifts */
.btn-outline {
  --btn-bg: var(--white);
  --btn-ring: var(--navy);
  --btn-ring-w: 1px;
}

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 48px;
  height: 48px;
  flex: none;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  background: var(--white);
  color: var(--navy);
  transition: background-color var(--dur-base) var(--ease), color var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.icon-btn:active { transform: scale(0.96); transition-duration: var(--dur-instant); }
.icon-btn-lg { width: 64px; height: 64px; }
.icon-btn-lg .icon { width: 26px; height: 26px; }
.icon-btn-amber { background-color: var(--amber); box-shadow: inset 0 0 0 2px var(--amber), var(--lift); }
.icon-btn-amber:active { background-color: transparent; transform: translateY(0) scale(0.96); --lift: var(--lift-pressed); }
.hero-down:active { color: var(--white); }
@media (hover: hover) {
  .btn:hover { background-color: transparent; color: var(--btn-fg-hollow); transform: translateY(-2px); --lift: var(--lift-up); }
  .icon-btn-amber:hover { background-color: transparent; transform: translateY(-2px); --lift: var(--lift-up); }
  .hero-down:hover { color: var(--white); } /* over the reel, a white arrow reads best */
}
.icon-btn-plain { background: transparent; }
.icon-btn-plain:hover { background: var(--mist); }
.icon-btn-mist { background: var(--mist); }
.icon-btn-mist:hover { background: var(--mist-hover); }

.icon-disc {
  display: inline-grid;
  place-items: center;
  width: 52px;
  height: 52px;
  flex: none;
  border-radius: 50%;
  background: var(--amber);
  color: var(--navy);
}
.icon-disc .icon { width: 24px; height: 24px; }

/* ── header ──
   Fixed and solid white by default. With JS, the white backing (::before) follows
   --hdr-a, set on scroll: clear until 70% of the way through the first section,
   fully white when the header's bottom edge reaches the next section. Link colors
   flip from white to navy at the halfway point (.is-solid). */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  padding-top: env(safe-area-inset-top, 0px);
}
.site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--white);
  box-shadow: 0 1px 0 0 var(--hairline);
  opacity: var(--hdr-a, 1);
  pointer-events: none;
}
.js .site-header { --hdr-a: 0; }
.site-header.menu-open::before { opacity: 1; }
.js .site-header[data-over="dark"]:not(.is-solid):not(.menu-open) .nav a,
.js .site-header[data-over="dark"]:not(.is-solid):not(.menu-open) .nav-toggle { color: var(--white); }
.js .site-header[data-over="dark"]:not(.is-solid):not(.menu-open) .nav-toggle:hover { background: rgba(255, 255, 255, 0.16); }
/* over the reel, the hollow Say Hi button reads best with a white label */
.js .site-header[data-over="dark"]:not(.is-solid):not(.menu-open) .header-cta { --btn-fg-hollow: var(--white); }
.header-inner {
  height: var(--header-h);
  display: flex;
  align-items: center;
  gap: clamp(16px, 2.4vw, 40px);
}
.brand { display: block; flex: none; border-radius: var(--r-sm); }
/* the logo file keeps a 2% margin around the lettering, so 37px tall shows 34px of WHIRLY / BIRD */
.brand img { height: 37px; width: auto; }
.nav { margin-left: auto; }
.nav ul { display: flex; align-items: center; gap: clamp(20px, 2.2vw, 36px); }
.nav a {
  position: relative;
  display: block;
  padding: 10px 0;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--navy);
  transition: color var(--dur-fast) var(--ease);
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 4px;
  height: 2px;
  border-radius: 2px;
  background: var(--amber);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-base) var(--ease);
}
/* one section underline at a time: site.js marks the section the header has reached (.is-active);
   the current page's item (AI Video on the AI page) steps aside while another item is marked */
.nav a:hover::after,
.nav a.is-active::after,
.nav:not(.has-active) a[aria-current="page"]::after { transform: scaleX(1); }
/* text links take the design system's link-hover shade: navy to amber-press on light grounds,
   and white to amber over the reel */
.nav a:hover { color: var(--amber-press); }
.js .site-header[data-over="dark"]:not(.is-solid):not(.menu-open) .nav a:hover { color: var(--amber); }
.header-cta { flex: none; }
.nav-toggle { display: none; margin-left: auto; }
.nav-toggle .nav-toggle-close { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle-open { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle-close { display: inline-grid; }
.nav-toggle span { display: inline-grid; }

/* ── the open menu on phones and tablets: the links as large amber type in ruled rows that share the height, each
   with a navy arrow, over an amber card with the footer's Get in Touch buttons and the bird, large and faint, in
   its corner. The rows and the card rise in one after another each time the menu opens. ── */
.mobile-menu {
  position: fixed;
  inset: calc(var(--header-h) + env(safe-area-inset-top, 0px)) 0 0 0;
  z-index: 49;
  background: var(--white);
  padding: 0 var(--gutter) calc(16px + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  animation: fade-in var(--dur-base) var(--ease);
}
.mobile-menu nav { flex: 1 0 auto; display: grid; }
.mobile-menu ul { display: grid; grid-auto-rows: minmax(64px, 1fr); }
.mobile-menu li + li { border-top: 1px solid var(--hairline); }
.mobile-menu li,
.menu-card { --rise: 12px; animation: intro-rise 320ms var(--ease-out) calc(var(--i, 0) * 35ms + 40ms) backwards; }
.mobile-menu li:nth-child(2) { --i: 1; }
.mobile-menu li:nth-child(3) { --i: 2; }
.mobile-menu li:nth-child(4) { --i: 3; }
.mobile-menu li:nth-child(5) { --i: 4; }
.menu-card { --i: 5; }
.mobile-menu nav a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: 100%;
  font-size: clamp(2.5rem, 10vw, 3.5rem);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--amber);
}
.mobile-menu nav a .icon { width: 28px; height: 28px; color: var(--navy); }
.mobile-menu nav a:hover,
.mobile-menu nav a[aria-current="page"] { color: var(--amber-press); }
.menu-card {
  --bird: clamp(96px, 90vw - 198px, 140px); /* the bird's full height: as large as fits beside the buttons */
  position: relative;
  isolation: isolate;
  overflow: hidden;
  flex: none;
  display: grid;
  justify-items: start;
  gap: 10px;
  margin-top: 28px; /* room under the Contact row */
  padding: 16px 24px;
  border-radius: var(--r-xl);
  background: var(--amber);
}
.menu-card .eyebrow { margin: 0; font-size: 0.8125rem; }
.menu-card .icon-btn:hover { background: var(--mist); }
/* the bird, large and faint, coming into the card from its bottom right corner: most of it shows, with the tip of
   its tail past the right edge and its feet below the bottom one. It sits behind the label and the buttons, 8px
   below the card's top edge. */
.menu-bird {
  position: absolute;
  right: calc(var(--bird) * -0.15);
  bottom: calc(102px - var(--bird));
  z-index: -1;
  width: auto;
  max-width: none;
  height: var(--bird);
  opacity: 0.25;
  pointer-events: none;
}
/* a phone on its side: smaller type, so all five rows show without scrolling */
@media (max-height: 520px) {
  .mobile-menu ul { grid-auto-rows: minmax(52px, 1fr); }
  .mobile-menu nav a { font-size: clamp(1.75rem, 9vh, 2.5rem); }
}

/* ── cookie notice: a small white card floating over the bottom of the page until a new visitor answers. It rises in
   a moment after the page does. Decline and Accept are the same button at the same size, so neither answer is pushed;
   Customize, in outline, opens the settings pop-up. Its type and buttons are a step smaller than the rest of the
   site's, to keep it out of the way. It sits under the open menu and the pop-ups.
   On a computer (from 1101px wide) it's a card in the bottom right corner, clear of the hero's words. ── */
.consent {
  position: fixed;
  right: calc(16px + env(safe-area-inset-right, 0px));
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  z-index: 48;
  width: 420px;
  display: grid;
  gap: 12px;
  padding: 16px;
  border-radius: var(--r-xl);
  background: var(--white);
  box-shadow: 0 0 0 1px var(--hairline), var(--shadow-floating);
  --rise: 12px;
  animation: intro-rise var(--dur-slow) var(--ease-out) 600ms backwards;
}
.consent-text { font-size: 0.875rem; line-height: 1.45; color: var(--slate); }
.consent-text a,
.cookies-note a { font-weight: 600; white-space: nowrap; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.consent-text a:hover,
.cookies-note a:hover { color: var(--amber-press); }
.consent-actions { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
/* 40px tall where a mouse clicks them; 44px on the layouts below, where they are tapped */
.consent-actions .btn { min-height: 40px; padding: 8px 10px; font-size: 0.875rem; }
/* While a new visitor hasn't answered (.consent-waiting on the page, set in the page head), the hero makes room, and
   settles back once the notice is answered. --consent-h is the notice's height, measured by site.js; the figures
   here stand in until it has. On a computer only the homepage's down arrow is in the way: it sits just above the card. */
.consent-waiting { --consent-h: 125px; }
.hero-down { transition: margin-bottom var(--dur-slow) var(--ease), background-color var(--dur-base) var(--ease), color var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out); }
.consent-waiting .hero-down { margin-bottom: calc(var(--consent-h) + 32px - clamp(48px, 7vw, 96px)); }
/* On tablets, phones and narrow windows (up to 1100px) it spans the bottom of the screen, which is where the hero's
   words sit, so there the words themselves sit just above the notice. */
@media (max-width: 1100px) {
  .consent { left: calc(16px + env(safe-area-inset-left, 0px)); width: auto; }
  .consent-actions .btn { min-height: 44px; }
  .hero-content,
  .ai-hero { transition: padding-bottom var(--dur-slow) var(--ease); }
  .consent-waiting { --consent-h: 129px; }
  .consent-waiting .hero-content,
  .consent-waiting .ai-hero { padding-bottom: calc(var(--consent-h) + 48px + env(safe-area-inset-bottom, 0px)); }
  .consent-waiting .hero-down { margin-bottom: 0.4em; }
}
/* from 800px: one bar, the words beside the buttons */
@media (min-width: 800px) and (max-width: 1100px) {
  .consent { grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 20px; padding: 12px 12px 12px 20px; }
  .consent-actions .btn { padding-inline: 16px; }
  .consent-waiting { --consent-h: 68px; }
}
/* phones: the three buttons stay on one row */
@media (max-width: 599px) {
  .consent-waiting { --consent-h: 149px; }
}
/* the narrowest phones: Customize on a row of its own, above the two answers */
@media (max-width: 349px) {
  .consent-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .consent-actions .btn-outline { grid-column: 1 / -1; }
  .consent-waiting { --consent-h: 199px; }
}

/* ── cookie settings: a small pop-up over the dimmed page, opened by Customize in the notice and by Cookie Settings in
   the footer. A row for each kind of cookie: what's always on, the one switch (Google Analytics), and the kind the
   site doesn't use. Decline All and Save My Choices are the same button. ── */
.cookies {
  width: min(480px, calc(100vw - 32px));
  max-width: none;
  max-height: calc(100dvh - 32px);
  margin: auto;
  padding: clamp(20px, 5vw, 32px);
  border: 0;
  border-radius: var(--r-xl);
  background: var(--white);
  color: var(--slate);
  box-shadow: var(--shadow-modal);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.cookies[open] { animation: fade-in var(--dur-base) var(--ease); }
.cookies::backdrop { background: var(--overlay); }
.cookies-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 4px; }
.cookies-title { font-size: 1.5rem; line-height: 1.2; font-weight: 900; letter-spacing: -0.025em; color: var(--slate); }
.cookies-row { padding-block: 14px 16px; border-bottom: 1px solid var(--hairline); }
.cookies-row-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 40px; }
.cookies-row h3 { font-size: 1.0625rem; line-height: 1.4; font-weight: 600; color: var(--slate); }
.cookies-row p { max-width: 30em; font-size: 0.9375rem; line-height: 1.5; }
.cookies-fixed,
.switch-state { font-size: 0.875rem; line-height: 1.25rem; font-weight: 600; color: var(--slate); }
.cookies-note { margin-top: 16px; font-size: 0.8125rem; line-height: 1.5; }
.cookies-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin-top: 24px; }
.cookies-actions .btn { padding-inline: 12px; }
/* the switch: a real checkbox under a track and knob. Off is slate with a white knob at the left; on is amber with a
   navy knob at the right, and the word beside it says which. */
.switch { position: relative; display: inline-flex; align-items: center; gap: 10px; min-height: 40px; cursor: pointer; }
.switch input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.switch-state::before { content: "Off"; }
.switch input:checked ~ .switch-state::before { content: "On"; }
.switch-track {
  position: relative;
  flex: none;
  width: 52px;
  height: 32px;
  border-radius: 16px;
  background: var(--slate);
  transition: background-color var(--dur-fast) var(--ease);
}
.switch-track::after {
  content: "";
  position: absolute;
  top: 4px;
  left: 4px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--white);
  transition: transform var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.switch input:checked ~ .switch-track { background: var(--amber); }
.switch input:checked ~ .switch-track::after { transform: translateX(20px); background: var(--navy); }
.switch:hover input:checked ~ .switch-track { background: var(--amber-hover); }
.switch input:focus-visible ~ .switch-track { outline: 2px solid var(--navy); outline-offset: 3px; }
@media (max-width: 420px) {
  .cookies-actions { grid-template-columns: minmax(0, 1fr); }
}

@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

/* ── hero: the reel, full-bleed under the transparent header, with a subtle navy ramp down from the top and
   up from the bottom, each fading to nothing before the middle. A soft navy lift behind the headline keeps
   the words clear of the footage. The AI page's hero shares all of this. ── */
.hero {
  --ramp: 0.5; /* the navy at the very top and bottom edges */
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: flex-end;
  min-height: clamp(560px, 100svh, 1200px);
  background: var(--media-ground);
  color: var(--white);
  overflow: hidden;
}
.hero-media {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
/* streamed from Mux on the live site: the poster inside shows until the stream plays over it */
.hero-video img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* the reel fades in over its poster when it starts playing, rather than cutting to it (Matt, 2026-10-13). The
   self-hosted reel has its poster as an image underneath and stays clear until it plays; site.js does the same to the
   video inside the Mux player. Until then, or without scripts, the poster is what shows. */
.hero-poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hero-fade { opacity: 0; transition: opacity 200ms cubic-bezier(0.2, 0, 0.2, 1); }
.hero-fade.is-playing { opacity: 1; }
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to bottom,
    rgba(var(--navy-rgb), var(--ramp)) 0%,
    rgba(var(--navy-rgb), calc(var(--ramp) * 0.5)) 14%,
    rgba(var(--navy-rgb), calc(var(--ramp) * 0.15)) 30%,
    rgba(var(--navy-rgb), 0) 44%,
    rgba(var(--navy-rgb), 0) 56%,
    rgba(var(--navy-rgb), calc(var(--ramp) * 0.15)) 70%,
    rgba(var(--navy-rgb), calc(var(--ramp) * 0.5)) 86%,
    rgba(var(--navy-rgb), var(--ramp)) 100%);
}
.hero-content {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
  padding-block: clamp(48px, 7vw, 96px);
}
.hero-title {
  position: relative;
  font-size: var(--fs-hero);
  color: var(--white);
  letter-spacing: -0.04em;
  text-wrap: initial;
  text-shadow: 0 2px 6px rgba(var(--navy-rgb), 0.22), 0 10px 36px rgba(var(--navy-rgb), 0.28);
}
/* the lift: it fades in with the words */
.hero-title::before {
  content: "";
  position: absolute;
  inset: -22% -10%;
  z-index: -1;
  background: radial-gradient(closest-side, rgba(var(--navy-rgb), 0.42) 0%, rgba(var(--navy-rgb), 0.26) 45%, rgba(var(--navy-rgb), 0) 100%);
  pointer-events: none;
}
.js:not(.intro-go) .hero-title::before { opacity: 0; animation: intro-failsafe 1ms 3s forwards; }
.js.intro-go .hero-title::before { animation: fade-in 900ms var(--ease-out) 320ms backwards; }
.hero-accent { color: var(--amber); }
.hero-down { margin-bottom: 0.4em; }

/* ── intro: on load the wordmark drops into place, then the menu items and the hero
   headline rise in turn. site.js adds .intro-go once Inter has loaded (a second at most),
   so the type never swaps mid-move. If that never happens, the failsafe shows everything. ── */
@keyframes intro-rise {
  from { opacity: 0; transform: translate3d(0, var(--rise, 10px), 0); }
  to { opacity: 1; transform: none; }
}
@keyframes intro-failsafe { to { opacity: 1; } }
.js:not(.intro-go) .intro { opacity: 0; animation: intro-failsafe 1ms 3s forwards; }
.js.intro-go .intro { animation: intro-rise var(--intro-dur, 600ms) var(--ease-out) var(--d, 0ms) backwards; }
.brand.intro { --rise: -12px; --intro-dur: 900ms; }
.nav li:nth-child(1) { --d: 160ms; }
.nav li:nth-child(2) { --d: 230ms; }
.nav li:nth-child(3) { --d: 300ms; }
.nav li:nth-child(4) { --d: 370ms; }
.nav li:nth-child(5) { --d: 440ms; }
.header-cta.intro { --d: 510ms; }
.nav-toggle.intro { --d: 160ms; }
.hero-title .line.intro,
.ai-title .line.intro { --rise: 28px; --intro-dur: 900ms; }
.hero-title .line:nth-child(1),
.ai-title .line:nth-child(1) { --d: 320ms; }
.hero-title .line:nth-child(2),
.ai-title .line:nth-child(2) { --d: 440ms; }
.hero-down.intro { --rise: 16px; --d: 640ms; }
.ai-intro.intro { --rise: 16px; --d: 600ms; --intro-dur: 800ms; }

/* ── media frame + play button ── */
.media-frame {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  max-width: 100%;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--media-ground);
  transition: box-shadow var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.media-frame img,
.media-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 0;
}
.media-scrim { position: absolute; inset: 0; background: var(--scrim-flat); transition: background-color var(--dur-fast) var(--ease); }
.play-btn {
  position: absolute;
  top: 50%;
  left: 50%;
  display: grid;
  place-items: center;
  width: 80px;
  height: 80px;
  margin: -40px 0 0 -40px;
  border-radius: 50%;
  background: var(--amber);
  color: var(--navy);
  transition: opacity var(--dur-base) var(--ease), transform var(--dur-instant) var(--ease);
}
.play-btn .icon { width: 30px; height: 30px; margin-left: 4px; fill: currentColor; }
a.media-frame:hover { transform: translateY(-1px); box-shadow: var(--shadow-floating); }
a.media-frame:hover .media-scrim { background: rgba(var(--navy-rgb), 0); }
a.media-frame:active .play-btn { transform: scale(0.96); }

/* ── about ── */
.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.12fr);
  gap: clamp(40px, 6vw, 96px);
  align-items: center;
}
.about-title { font-size: var(--fs-section); margin-bottom: var(--head-gap); }
.about-copy .lead { margin-bottom: 36px; }

/* ── clients ── */
/* 6px less below: the logo boxes carry transparent space under the marks, so this keeps the group optically centered */
.band.clients { padding-block: var(--band-y-tight) calc(var(--band-y-tight) - 6px); }
/* a soft lift: the band sits just above its neighbors and casts a gentle shadow onto both */
.band.clients {
  position: relative;
  z-index: 1;
  box-shadow: 0 -10px 36px -14px rgba(var(--navy-rgb), 0.14), 0 14px 40px -14px rgba(var(--navy-rgb), 0.18);
}
.clients-head {
  display: grid;
  justify-items: center;
  gap: var(--head-gap);
  text-align: center;
}
.clients-title { font-size: clamp(2.125rem, 1.4rem + 2.6vw, 3.5rem); } /* kept a step below the other section headings */
.clients-head .lead { max-width: 34em; }
.marquee {
  margin-top: clamp(16px, 1.6vw, 24px);
  overflow: hidden;
}
.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee 43s linear infinite;
}
.marquee:hover .marquee-track,
.marquee.is-offscreen .marquee-track { animation-play-state: paused; } /* site.js marks it off screen, so it isn't animated for nobody */
.marquee-list { display: flex; align-items: center; gap: clamp(32px, 3.4vw, 56px); padding-right: clamp(32px, 3.4vw, 56px); }
/* The logo files are 150px square, so boxes stay at 75px or less to keep them sharp on Retina screens. */
.marquee-list li { width: clamp(60px, 5.2vw, 75px); aspect-ratio: 1; flex: none; }
.marquee-list img { width: 100%; height: 100%; object-fit: contain; }
@keyframes marquee { to { transform: translate3d(-50%, 0, 0); } }

/* ── services ── */
.section-head {
  display: grid;
  gap: var(--head-gap);
  justify-items: start;
  margin-bottom: clamp(48px, 5.5vw, 80px);
}
.services-title { font-size: var(--fs-section); }
.section-head-aside { display: grid; gap: 36px; justify-items: start; }
.cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}
.card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  padding: clamp(28px, 2.6vw, 40px);
  border-radius: var(--r-xl);
  background: var(--mist);
}
.card h3 {
  margin-top: 16px;
  font-size: var(--fs-h3);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--navy);
}
.card h3 .line { display: block; }
.card p { font-size: 1rem; line-height: 1.6; }
.card .btn { margin-top: auto; }
.card p + .btn { margin-top: 8px; }

/* The studio set sits faintly behind the menu and fades out toward the bottom of the
   section. As the section scrolls up, site.js fades out a soft copy laid over the sharp
   one, so the set racks into focus. Without JS, or with reduced motion, it is simply sharp. */
.services { position: relative; isolation: isolate; overflow: hidden; }
.set {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: -1;
  aspect-ratio: 1640 / 1079;
  max-height: 100%;
  opacity: 0.26;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0%, #000 40%, #000 62%, transparent 100%);
          mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0%, #000 40%, #000 62%, transparent 100%);
}
.set img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}
.set-soft { opacity: 0; }
/* a faint pool of white behind the heading block and a soft white glow on the type, so the set
   fades as it reaches the letters but stays in view around them */
.services .section-head { position: relative; }
.services .section-head::before {
  content: "";
  position: absolute;
  inset: -18% -4% -18% -14%;
  z-index: -1;
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0.6) 40%, rgba(255, 255, 255, 0) 100%);
  pointer-events: none;
}
.services .section-head .eyebrow,
.services .section-head .display,
.services .section-head .lead {
  text-shadow: 0 0 2px rgba(255, 255, 255, 0.9), 0 0 14px rgba(255, 255, 255, 0.85), 0 0 30px rgba(255, 255, 255, 0.6);
}
/* solid white cards with a faint edge and a soft shadow, so they stand off the set and the white below it */
.services .card {
  background: var(--white);
  box-shadow: var(--shadow-card);
}

/* ── work: a full-bleed grid of stills, edge to edge, square corners, no gaps ── */
.work { background: var(--media-ground); }
.work-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.tile {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--media-ground);
  color: var(--white);
}
.tile img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease);
}
.tile:hover img { transform: scale(1.03); }
.tile:focus-visible { outline: 3px solid var(--amber); outline-offset: -3px; }
/* The image stays untouched except for a navy shade behind the text, sized to the text block
   and fading out just above it. */
.tile-text {
  --tile-pad: clamp(20px, 2.4vw, 36px);
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  display: grid;
  gap: 10px;
  padding: calc(var(--tile-pad) + 56px) var(--tile-pad) var(--tile-pad);
  background: var(--scrim-text);
  text-shadow: 0 1px 2px rgba(var(--navy-rgb), 0.55), 0 0 18px rgba(var(--navy-rgb), 0.45);
}
/* client as a small amber label, the project title large and white */
.tile-client {
  font-size: 0.9375rem;
  line-height: 1.2;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--amber);
}
.tile-title {
  font-size: clamp(1.75rem, 1rem + 2vw, 2.75rem);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--white);
}
.tile-desc {
  margin-top: 2px;
  max-width: 34em;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--white);
}
.tile-play {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  width: clamp(48px, 4.4vw, 72px);
  height: clamp(48px, 4.4vw, 72px);
  margin: auto;
  border-radius: 50%;
  background: var(--amber);
  color: var(--navy);
  transition: opacity var(--dur-base) var(--ease);
}
.tile-play .icon { width: 36%; height: 36%; margin-left: 5%; fill: currentColor; }
/* Play buttons sit at 40% until the thumbnail is hovered or focused. Touch screens can't hover, so they stay solid there. */
@media (hover: hover) {
  .play-btn,
  .tile-play { opacity: 0.4; }
  a.media-frame:hover .play-btn,
  a.media-frame:focus-visible .play-btn,
  .cs-watch:hover .play-btn,
  .cs-watch:focus-visible .play-btn,
  .tile:hover .tile-play,
  .tile:focus-visible .tile-play { opacity: 1; }
}
/* the tile's description drops out when the tile is too narrow for it to clear the centered button */
.tile { container-type: inline-size; }
@container (max-width: 719px) {
  .tile-desc { display: none; }
}
@media (max-width: 899px) {
  .work-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (min-width: 2200px) {
  .work-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .tile-title { font-size: 2.25rem; }
}

/* ── case study dialog: the player, its stills and the text share one side inset (--cs-pad), so they line up ── */
.cs {
  --cs-pad: clamp(20px, 4vw, 48px);
  /* on a short screen the card narrows until the whole video fits under the bar (74px) with the side inset below it,
     so its controls are never cut off */
  width: min(1120px, calc(100vw - 32px), max(320px, calc((100dvh - 32px - 74px - var(--cs-pad)) * 16 / 9 + 2 * var(--cs-pad))));
  max-width: none;
  max-height: calc(100dvh - 32px);
  margin: auto;
  padding: 0;
  border: 0;
  border-radius: var(--r-xl);
  background: var(--white);
  color: var(--slate);
  box-shadow: var(--shadow-modal);
  overflow: hidden;
}
.cs[open] { display: flex; flex-direction: column; animation: fade-in var(--dur-base) var(--ease); }
.cs::backdrop { background: var(--overlay); }
/* while a case study is open the page behind it holds still, and its scrollbar goes */
html.is-modal { overflow: hidden; }
/* the case study scrolls inside the card, under the bar */
.cs-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
/* On mouse-and-trackpad screens the scrollbar is the site's own: a static mist rail centred in the card's right margin, running from
   the top of the video (the bar's height, measured when the dialog opens) to the same distance above the card's bottom edge, with an
   amber knob that follows the scroll position: at the very top when a case study opens, at the very bottom at the end. The knob can be
   dragged, and a press on the rail jumps there. The rail only shows when the case study is taller than the card, fading in quickly
   when it becomes needed. Touch screens, where scrolling is done by hand, never show it. */
.cs-rail { display: none; }
@media (hover: hover) and (pointer: fine) {
  .cs-scroll { scrollbar-width: none; }
  .cs-scroll::-webkit-scrollbar { display: none; }
  .cs-rail {
    display: block;
    position: absolute;
    top: var(--cs-bar-h, 74px);
    bottom: var(--cs-bar-h, 74px);
    right: calc(var(--cs-pad) / 2 - 3px);
    z-index: 3;
    width: 6px;
    border-radius: 999px;
    background: var(--mist);
    cursor: pointer;
    touch-action: none;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--dur-fast) var(--ease), visibility 0s linear var(--dur-fast);
  }
  .cs-rail.is-on { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity var(--dur-fast) var(--ease), visibility 0s; }
  .cs-rail::before { content: ""; position: absolute; inset: 0 -7px; } /* a wider target than the rail itself */
  .cs-knob {
    position: absolute;
    top: 0;
    left: 50%;
    width: 14px;
    height: 14px;
    margin-left: -7px;
    border-radius: 50%;
    background: var(--amber);
    cursor: grab;
    transition: background-color var(--dur-fast) var(--ease);
  }
  .cs-knob:hover,
  .cs-rail.is-dragging .cs-knob { background: var(--amber-hover); }
  .cs-rail.is-dragging,
  .cs-rail.is-dragging .cs-knob { cursor: grabbing; }
}
.cs-bar {
  position: relative;
  z-index: 2;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px var(--cs-pad) 12px;
  background: var(--white);
}
/* the bar's lower corners curve in over the media column, so the video keeps its round corners as it scrolls under the bar */
.cs-bar::before,
.cs-bar::after {
  content: "";
  position: absolute;
  top: 100%;
  width: var(--r-lg);
  height: var(--r-lg);
  pointer-events: none;
}
.cs-bar::before { left: var(--cs-pad); background: radial-gradient(circle at 100% 100%, transparent calc(var(--r-lg) - 0.5px), var(--white) var(--r-lg)); }
.cs-bar::after { right: var(--cs-pad); background: radial-gradient(circle at 0 100%, transparent calc(var(--r-lg) - 0.5px), var(--white) var(--r-lg)); }
.cs-count { font-size: 0.875rem; font-weight: 600; color: var(--slate); font-variant-numeric: tabular-nums; letter-spacing: 0.02em; }
.cs-controls { display: flex; gap: 4px; }
.cs-media {
  position: relative;
  aspect-ratio: 16 / 9;
  margin-inline: var(--cs-pad);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--media-ground);
}
.cs-media video,
.cs-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cs-media video { object-fit: contain; background: #000; }

/* four stills under the player; each opens the stills gallery */
.cs-stills {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin: 12px var(--cs-pad) 0;
  padding: 0;
  list-style: none;
}
.cs-still {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  padding: 0;
  border: 0;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--mist);
  cursor: zoom-in;
  transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease);
}
.cs-still img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-base) var(--ease-out); }
.cs-still:focus-visible { border-radius: var(--r-md); }
.cs-still:active { transform: scale(0.98); transition-duration: var(--dur-instant); }
@media (hover: hover) {
  .cs-still:hover { transform: translateY(-2px); box-shadow: var(--shadow-floating); }
  .cs-still:hover img { transform: scale(1.05); }
  .cs-still:hover .still-ph { color: var(--navy); }
}
/* until the real frames are in, each still is a placeholder */
.still-ph {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 6px;
  background: linear-gradient(135deg, var(--mist) 0%, var(--mist-hover) 100%);
  color: rgba(var(--navy-rgb), 0.5);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  transition: color var(--dur-fast) var(--ease);
}
.still-ph .icon { width: 24px; height: 24px; }

.cs-body {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: 24px 56px;
  padding: clamp(28px, 4vw, 44px) var(--cs-pad) var(--cs-pad);
}
.cs-title { font-size: var(--fs-d3); }
.cs-client { margin-top: 16px; font-size: 1.0625rem; font-weight: 600; color: var(--navy); }
.cs-copy { display: grid; gap: 24px; align-content: start; }
.cs-copy p { font-size: 1.0625rem; line-height: 1.65; }

/* the result: an amber card with the label and a navy ribbon badge across the top, and the line in big white type right under the label.
   The badge sits in the top-right corner and the text keeps clear of its column, so the line never runs under it.
   The top of the RESULT caps and the baseline of the last line sit the same distance (--result-edge) from the top and bottom edges.
   The caps are centred on the badge, so their top is the badge's centre less half their height (Inter's cap height is 0.72754 of the
   font size). Below the last baseline, a line box holds Inter's descender (0.24121) plus half its leading (line height less 1.20996).
   The label sits the standard eyebrow gap above the line, like the section eyebrows. */
.cs-result {
  --result-inset: 20px; /* badge to the top and right edges */
  --result-side: 24px; /* text to the left edge */
  --result-badge: 48px;
  --result-label-size: 0.8125rem;
  --result-label-lh: 1.25rem;
  --result-size: clamp(1.5rem, 1.2rem + 0.9vw, 1.625rem);
  --result-lh: 1.15;
  --result-edge: calc(var(--result-inset) + var(--result-badge) / 2 - 0.36377 * var(--result-label-size));
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: var(--eyebrow-gap);
  padding:
    calc(var(--result-inset) + (var(--result-badge) - var(--result-label-lh)) / 2)
    calc(var(--result-inset) + var(--result-badge) + 16px)
    calc(var(--result-edge) - var(--result-size) * ((var(--result-lh) - 1.20996) / 2 + 0.24121))
    var(--result-side);
  border-radius: var(--r-xl);
  background: var(--amber);
  color: var(--navy);
}
.cs-result-icon {
  position: absolute;
  top: var(--result-inset);
  right: var(--result-inset);
  display: grid;
  place-items: center;
  width: var(--result-badge);
  height: var(--result-badge);
  border-radius: 50%;
  background: var(--navy);
  color: var(--amber);
}
.cs-result-icon .icon { width: 24px; height: 24px; }
.cs-result .cs-result-label {
  font-size: var(--result-label-size);
  line-height: var(--result-label-lh);
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--navy);
}
.cs-result .cs-result-text {
  font-size: var(--result-size);
  line-height: var(--result-lh);
  font-weight: 900;
  letter-spacing: -0.01em;
  color: var(--white);
  text-wrap: pretty;
}

/* ── stills gallery: a smaller window over the case study ── */
.csg {
  /* on a short screen it narrows until the still and its bar (58px) fit inside the 12px padding */
  width: min(760px, calc(100vw - 48px), max(280px, calc((100dvh - 48px - 24px - 58px) * 16 / 9 + 24px)));
  max-width: none;
  max-height: calc(100dvh - 48px);
  margin: auto;
  padding: 12px;
  border: 0;
  border-radius: var(--r-xl);
  background: var(--white);
  color: var(--slate);
  box-shadow: var(--shadow-modal);
  overflow: hidden;
}
.csg[open] { animation: fade-in var(--dur-base) var(--ease); }
.csg::backdrop { background: rgba(var(--navy-rgb), 0.4); }
.csg-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--mist);
  touch-action: pan-y;
}
.csg-frame img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.csg-frame .still-ph { gap: 10px; font-size: 0.9375rem; }
.csg-frame .still-ph .icon { width: 40px; height: 40px; }
.csg-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 0 0 12px;
}

.cs-watch { position: absolute; inset: 0; display: block; }
.cs-watch:hover .media-scrim { background: rgba(var(--navy-rgb), 0); }

/* ── Mux Player: the About video and the case studies on the live site, themed to the site.
   Its look is set here; nothing is styled in the Mux dashboard. ── */
.media-frame mux-player,
.cs-media mux-player { position: absolute; inset: 0; width: 100%; height: 100%; }
mux-player {
  --media-primary-color: var(--white);
  --media-accent-color: var(--amber);
  --media-font-family: var(--font);
  --media-font-weight: 600;
  --media-tooltip-background-color: var(--navy);
  --media-tooltip-border-radius: var(--r-sm);
  /* just play, the scrubber, time, volume, captions (when a video has them) and fullscreen */
  --seek-backward-button: none;
  --seek-forward-button: none;
  --playback-rate-menu-button: none;
  --rendition-menu-button: none;
  --audio-track-menu-button: none;
  --airplay-button: none;
  --cast-button: none;
  --pip-button: none;
}
/* navy shade under the controls, where the player's own is black */
mux-player::part(control-bar) {
  --gradient-steps: rgba(var(--navy-rgb), 0) 0%, rgba(var(--navy-rgb), 0.05) 15%, rgba(var(--navy-rgb), 0.18) 29%,
    rgba(var(--navy-rgb), 0.36) 41%, rgba(var(--navy-rgb), 0.56) 53%, rgba(var(--navy-rgb), 0.74) 65%,
    rgba(var(--navy-rgb), 0.9) 78%, rgba(var(--navy-rgb), 0.98) 92%, rgb(var(--navy-rgb)) 100%;
}
/* control icons go amber on hover, like links on dark (the player's own hover is an amber square) */
mux-player::part(bottom button) { --media-control-hover-background: transparent; }
mux-player::part(bottom button):hover { --media-icon-color: var(--amber); }
mux-player::part(time range) {
  --media-time-range-buffered-color: rgba(255, 255, 255, 0.5);
  --media-range-track-background: rgba(255, 255, 255, 0.25);
  --media-range-thumb-background: radial-gradient(circle, var(--navy) 0 28%, var(--amber) 28%);
  --media-text-color: var(--navy); /* the time shown over the scrubber's preview */
}
mux-player::part(volume range) { --media-range-thumb-background: radial-gradient(circle, var(--navy) 0 28%, var(--white) 28%); }
mux-player::part(time display) { font-variant-numeric: tabular-nums; }
/* before a video starts (after moving to another case study), its big play button matches the site's */
mux-player::part(pre-play) {
  width: 80px;
  height: 80px;
  padding: 25px;
  --media-control-background: var(--amber);
  --media-control-hover-background: var(--amber);
  --media-icon-color: var(--navy);
}

/* ── contact ── */
.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(48px, 6vw, 96px);
  align-items: start;
}
.contact-title { font-size: var(--fs-section); margin-bottom: var(--head-gap); }
.band-amber .contact-title { color: var(--white); }
/* white on the amber band: hollow, it keeps a white stroke with the navy label */
.band-amber .btn { --btn-bg: var(--white); }
.contact-copy .lead { margin-bottom: 36px; max-width: 26em; }
.inline-icon { display: inline-block; vertical-align: -0.2em; color: var(--amber-press); }
.band-amber .inline-icon { color: var(--navy); }
.inline-icon .icon { width: 1.15em; height: 1.15em; }
.scheduler {
  position: relative;
  border-radius: var(--r-xl);
  background: var(--white);
  overflow: hidden;
}
/* Calendly's inline widget, sized as in Calendly's embed code (taller on phones, where the
   times stack under the calendar). The link card sits over it until the calendar has loaded. */
.calendly-inline-widget { min-width: min(320px, 100%); height: 700px; }
.scheduler.is-loaded .scheduler-fallback { display: none; }
.is-preview .calendly-inline-widget { display: none; }
.scheduler-fallback {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  padding: 32px;
  color: var(--navy);
  font-weight: 600;
  text-align: center;
}
.scheduler-link { max-width: 100%; overflow-wrap: anywhere; }
.scheduler-link .icon { display: inline-block; width: 18px; height: 18px; vertical-align: -3px; }
.scheduler-fallback:hover { color: var(--amber-press); }
.is-preview .scheduler { min-height: 0; aspect-ratio: 4 / 3; }

/* ── footer ── */
.site-footer {
  background: var(--white);
  color: var(--slate);
  padding-block: clamp(64px, 7vw, 104px) calc(28px + env(safe-area-inset-bottom, 0px));
}
.site-footer a { color: var(--navy); }
.footer-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.5fr);
  gap: 48px;
  align-items: start;
}
.footer-title {
  margin-bottom: 20px;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--slate);
}
.footer-email { display: inline-block; font-weight: 600; margin-bottom: 20px; }
.footer-email:hover,
.footer-links a:hover { color: var(--amber-press); text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
.socials { display: flex; gap: 12px; }
.footer-links { display: grid; gap: 10px; }
.footer-links a { font-weight: 600; }
.newsletter {
  border-radius: var(--r-xl);
  background: var(--mist);
  overflow: hidden;
}
.newsletter iframe { display: block; width: 100%; height: 330px; border: 0; background: transparent; }
.newsletter-fallback { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; padding: clamp(24px, 2.6vw, 36px); color: var(--slate); }
.newsletter-title { font-size: 1.5rem; line-height: 1.2; font-weight: 900; letter-spacing: -0.025em; color: var(--slate); }
.newsletter-fallback p { font-size: 1rem; line-height: 1.55; }
.newsletter-row { display: flex; gap: 8px; margin-top: 8px; min-width: 0; }
.newsletter-row .btn { flex: none; }
.newsletter-row input {
  flex: 1;
  min-width: 0;
  min-height: 48px;
  padding: 12px 16px;
  border: 1px solid var(--navy);
  border-radius: var(--r-md);
  background: var(--white);
  color: var(--navy);
}
.newsletter-row input::placeholder { color: var(--slate); }
.newsletter-row input:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(28, 36, 75, 0.24); }
/* the privacy line under the field. On the live site it moves under Beehiiv's form, in the same card. */
.newsletter .newsletter-note { margin-top: -4px; font-size: 0.75rem; line-height: 1.4; color: var(--slate); }
.newsletter > .newsletter-note { margin: 0; padding: 0 clamp(24px, 2.6vw, 36px) clamp(24px, 2.6vw, 36px); }
/* the fine print: the copyright and the two legal links at one end, where it's made at the other in tiny print on
   the same baseline; one under the other on phones */
.footer-sign {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 24px;
  margin-top: clamp(48px, 5vw, 72px);
  padding-top: 28px;
  border-top: 1px solid var(--hairline);
}
.copyright,
.made-in { font-size: 0.875rem; font-weight: 600; color: var(--slate); }
.made-in { margin-left: auto; font-size: 0.5rem; }
.footer-legal { display: flex; flex-wrap: wrap; gap: 6px 20px; font-size: 0.875rem; font-weight: 600; }
/* Cookie Settings opens the cookie notice again: a button that reads as a link */
.footer-legal button,
.prose button { padding: 0; border: 0; background: none; font: inherit; color: var(--navy); cursor: pointer; transition: color var(--dur-fast) var(--ease); }
.footer-legal a:hover,
.footer-legal button:hover { color: var(--amber-press); text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }

/* ── 404: one band under the header, which is solid white on this page ── */
.notfound { padding-top: calc(var(--header-h) + env(safe-area-inset-top, 0px) + var(--band-y)); }
.notfound-title { font-size: var(--fs-section); margin-bottom: var(--head-gap); }
.notfound .lead { margin-bottom: 36px; }

/* ── privacy policy: one band of reading text under the header, which is solid white on this page. The text column
   is narrow enough to read comfortably (about 75 characters a line). Its section headings are the newsletter title's
   size, a step below every section heading on the site. ── */
.legal { padding-top: calc(var(--header-h) + env(safe-area-inset-top, 0px) + var(--band-y)); }
.legal-title { font-size: var(--fs-section); margin-bottom: var(--head-gap); }
.legal-date { margin-bottom: 36px; font-size: 0.875rem; font-weight: 600; color: var(--slate); }
.prose { max-width: 40rem; }
.prose > * + * { margin-top: 16px; }
.prose .lead { max-width: none; }
.prose h2 { margin-top: 56px; font-size: 1.5rem; line-height: 1.2; font-weight: 900; letter-spacing: -0.025em; color: var(--slate); }
.prose h3 { margin-top: 32px; font-size: 1.0625rem; line-height: 1.4; font-weight: 600; color: var(--slate); }
.prose h2 + h3 { margin-top: 20px; }
.prose ul { display: grid; gap: 10px; padding-left: 1.25em; list-style: disc; }
.prose li::marker { color: var(--amber-press); }
.prose strong { font-weight: 600; }
.prose a,
.prose button { font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.prose a:hover,
.prose button:hover { color: var(--amber-press); }

/* ── AI page: hero ──
   The homepage hero, centered, over the AI reel, with the same navy ramp and lift. A shadow under the intro
   keeps it clear of the footage too. The header covers the top of the hero, so the extra padding above
   centers the content in the space below it. */
.ai-hero {
  align-items: center;
  padding-block: calc(var(--header-h) + env(safe-area-inset-top, 0px) + clamp(48px, 7vw, 96px)) clamp(48px, 7vw, 96px);
}
.ai-hero-head { display: grid; justify-items: center; text-align: center; }
/* the homepage hero's size, held down on narrow phones so "The Machines" stays on one line */
.ai-title {
  font-size: min(var(--fs-hero), calc((100vw - 2 * var(--gutter)) / 6.6));
  margin-bottom: var(--head-gap);
  color: var(--amber);
}
.ai-intro { display: grid; justify-items: center; }
.ai-intro .lead {
  max-width: 24em;
  margin-bottom: 36px;
  color: var(--white);
  font-weight: 600;
  text-shadow: 0 1px 2px rgba(var(--navy-rgb), 0.65), 0 2px 16px rgba(var(--navy-rgb), 0.6);
}
/* over the reel, the hollow button reads best with a white label, like the header's Say Hi over the homepage reel */
.ai-hero .btn { --btn-fg-hollow: var(--white); }

/* ── AI page: ethics ── */
.ethics-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(40px, 6vw, 96px);
  align-items: center;
}
.ethics-title { font-size: var(--fs-section); margin-bottom: var(--head-gap); }
/* the subhead's lines are evened out, so no screen size leaves a word or two alone on its last line */
.ethics-head .lead { text-wrap: balance; }
.ethics-list { display: grid; gap: 16px; }
.ethics-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 20px;
  align-items: center;
  padding: clamp(20px, 2vw, 28px);
  border-radius: var(--r-xl);
  background: var(--white);
}
.ethics-item p { font-size: 1.125rem; line-height: 1.45; font-weight: 600; color: var(--navy); text-wrap: pretty; }

.process-head {
  display: grid;
  gap: var(--head-gap);
  justify-items: start;
}
.process-title { font-size: var(--fs-section); color: var(--white); }
/* On the band itself, like the contact section: the 9:16 frame on the left, the heading, intro and menu on the right.
   Each service carries its own loop. Down to tablet size the loops sit stacked over the frame, and picking a service
   opens its description and crossfades the frame to its loop. On phones the services run as a list, each loop above
   its title and text. */
.process-layout {
  --frame-w: clamp(260px, 28vw, 380px);
  position: relative;
  display: grid;
  grid-template-columns: var(--frame-w) minmax(0, 1fr);
  grid-template-rows: 1fr auto auto 1fr;
  grid-template-areas: "media ." "media head" "media menu" "media .";
  column-gap: clamp(48px, 7vw, 112px);
}
.process-head { grid-area: head; }
.process-media {
  grid-area: media;
  aspect-ratio: 9 / 16;
  border-radius: var(--r-lg);
  background: var(--amber-press);
}
/* the loops sit over the frame, which is the layout's top-left corner */
.process-loop {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--frame-w);
  aspect-ratio: 9 / 16;
  object-fit: cover;
  border-radius: var(--r-lg);
  background: var(--amber-press);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease);
}
.process-loop.is-on { opacity: 1; }
.process-menu { grid-area: menu; margin-top: clamp(32px, 3.5vw, 48px); border-top: 1px solid var(--hairline); }
.process-item { border-bottom: 1px solid var(--hairline); }
.process-item-title button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  width: 100%;
  min-height: 48px;
  padding: clamp(16px, 1.6vw, 22px) 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: clamp(1.75rem, 1.3rem + 1.2vw, 2.5rem);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -0.03em;
  text-align: left;
  color: var(--white);
  cursor: pointer;
}
/* the toggle: a white ring while closed, a white disc once open (and on hover), its chevron turning over */
.process-toggle {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 40px;
  height: 40px;
  border: 2px solid var(--white);
  border-radius: 50%;
  color: var(--white);
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.process-toggle .icon { width: 20px; height: 20px; transition: transform var(--dur-slow) var(--ease); }
.process-item-title button:hover .process-toggle,
.process-item.is-open .process-toggle { background: var(--white); color: var(--navy); }
.process-item.is-open .process-toggle .icon { transform: rotate(180deg); }
.process-desc { display: grid; grid-template-rows: 1fr; transition: grid-template-rows var(--dur-slow) var(--ease); }
.js .process-item:not(.is-open) .process-desc { grid-template-rows: 0fr; }
.process-desc > div { overflow: hidden; }
.process-desc p { max-width: 32em; padding-bottom: clamp(18px, 1.8vw, 24px); font-size: 1.0625rem; line-height: 1.5; font-weight: 600; color: var(--navy); }

/* ── responsive ── */
@media (max-width: 1024px) {
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .newsletter { grid-column: 1 / -1; }
  .cs-body { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 960px) {
  :root { --header-h: 64px; }
  .nav, .header-cta { display: none; }
  .nav-toggle { display: inline-grid; }
  .brand img { height: 33px; }
  .about-grid,
  .ethics-grid,
  .contact-grid { grid-template-columns: minmax(0, 1fr); }
  /* tablets keep the AI process side by side, with a narrower frame */
  .process-layout { --frame-w: clamp(200px, 30vw, 260px); column-gap: clamp(32px, 5vw, 48px); }
  .is-preview .scheduler { aspect-ratio: auto; min-height: 240px; }
}

@media (max-width: 720px) {
  .cards,
  .work-grid { grid-template-columns: minmax(0, 1fr); }
  /* The AI process on phones: a centered stack of story cards, the format vertical video lives in on a phone. Each loop
     fills its card, and its title and text sit in the lower-left over a navy scrim, the site's treatment for a title on
     footage (as on the Work tiles). The service titles run a word or two to a line, a step below the section heading,
     and no text runs wider than the heading above it: the intro and each description add no width of their own. */
  .process-layout {
    --section-h: min(var(--fs-section), calc((100vw - 2 * var(--gutter)) / 6.9)); /* "Our AI Process" on one line */
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    grid-template-areas: "head" "menu";
    text-align: center;
  }
  .process-head { width: fit-content; max-width: 100%; margin-inline: auto; justify-items: stretch; }
  .process-title { font-size: var(--section-h); white-space: nowrap; }
  .process-head .lead,
  .process-desc { width: 0; min-width: 100%; }
  .process-media { display: none; }
  .process-menu { display: grid; justify-items: center; gap: 24px; margin-top: 40px; border-top: 0; }
  .process-item {
    position: relative;
    width: clamp(260px, 78vw, 340px);
    border: 0;
    border-radius: var(--r-lg);
    overflow: hidden;
    background: var(--amber-press);
    text-align: left;
  }
  .process-loop { position: static; width: 100%; border-radius: 0; opacity: 1; }
  .process-text {
    position: absolute;
    inset: auto 0 0 0;
    display: grid;
    justify-content: start;
    padding: 96px 20px 20px;
    background: linear-gradient(to top, rgba(var(--navy-rgb), 0.78) 0%, rgba(var(--navy-rgb), 0.5) 55%, rgba(var(--navy-rgb), 0) 100%);
  }
  .process-text > * { grid-column: 1; }
  .process-item-title button {
    display: block;
    min-height: 0;
    padding: 0;
    font-size: min(calc(var(--section-h) * 0.8), calc((100vw - 2 * var(--gutter) - 40px) / 6.9));
    line-height: 0.95;
    color: var(--white);
    text-align: left;
    white-space: nowrap;
    cursor: default;
  }
  .process-item-title .w { display: block; }
  .process-toggle { display: none; }
  .js .process-item:not(.is-open) .process-desc { grid-template-rows: 1fr; }
  .process-desc p { padding: 10px 0 0; font-size: 0.875rem; line-height: 1.35; color: var(--white); }
  .footer-grid { grid-template-columns: minmax(0, 1fr); }
  .footer-sign { flex-direction: column; align-items: flex-start; gap: 10px; }
  .made-in { margin-left: 0; }
  .hero-content { flex-direction: column; align-items: flex-start; }
  .hero-down { display: none; }
  .newsletter-row { flex-direction: column; }
  .cs-stills { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .cs-result { --result-inset: 16px; --result-side: 20px; --result-badge: 40px; --result-size: 1.375rem; }
  .cs-result-icon .icon { width: 20px; height: 20px; }
  .csg { width: min(calc(100vw - 24px), max(280px, calc((100dvh - 48px - 16px - 58px) * 16 / 9 + 16px))); padding: 8px; }
  .calendly-inline-widget { height: 1000px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
  .marquee-track { animation: none; width: auto; }
  .marquee-list { flex-wrap: wrap; justify-content: center; row-gap: 32px; padding-inline: var(--gutter); }
  .marquee-list[aria-hidden="true"] { display: none; }
  .js .intro { opacity: 1 !important; animation: none !important; }
  .mobile-menu li,
  .menu-card,
  .consent { animation: none; }
}
