/* =========================================================================
   InFlightAI — Homepage
   Tokens + styles pulled from Figma "InFlightAI-2026" (node 2373:2388).
   Fonts: Outfit (display/body), IBM Plex Mono (dashboard).
   ========================================================================= */

:root {
  /* brand */
  --black: #000f23;
  --white: #ffffff;
  /* same hue/saturation as the original #8898AA, darkened to L46% so body copy
     clears WCAG AA on white (2.95:1 -> 4.8:1) */
  --gray: #627489;
  --gray-600: #b8c1cc;
  --light: #dfe0e6;
  --light-300: #f5f6f8;
  --blue: #2e88fe;
  --blue-100: #eaf3ff;
  --blue-300: #c0dbff;
  --blue-800: #579ffe;
  --green: #3fc364;
  --purple: #8e46d0;

  /* signature brand gradient (green -> blue -> purple) */
  --grad-brand: linear-gradient(168.8deg, #3fc364 9%, #2e88fe 36.6%, #8e46d0 82.3%);
  --grad-brand-h: linear-gradient(90deg, #3fc364 0%, #2e88fe 45%, #8e46d0 100%);

  --gutter: clamp(20px, 4vw, 48px);
  --maxw: 1440px;
  --radius-lg: 24px;
  --radius-md: 16px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Model-card lift. Both states share one geometry — a 50px blur sitting ~33px
     below the card — so hover reads as the same shadow deepening rather than a
     different, larger one growing underneath. Only the alpha changes.
     Used by .mcard alone (rows, mobile carousel, and the Platform page's row),
     so these two lines are the single place to retune the cards' shadow. */
  --shadow-card: 0 18px 50px -10px rgba(0, 15, 35, 0.32), 0 4px 12px -4px rgba(0, 15, 35, 0.12);
  --shadow-float: 0 18px 50px -10px rgba(0, 15, 35, 0.55), 0 6px 16px -4px rgba(0, 15, 35, 0.22);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  font-family: "Outfit", system-ui, -apple-system, sans-serif;
  color: var(--black);
  background: #fff;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; }

.container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }

.sr-only {
  position: absolute; 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: 12px; top: -60px; z-index: 200;
  background: var(--black); color: #fff; padding: 10px 16px; border-radius: 8px;
  transition: top .2s var(--ease);
}
.skip-link:focus { top: 12px; }

/* =========================================================================
   Dark top cap: mini bar + header + hero share the dark scene
   ========================================================================= */
.topcap {
  position: relative;
  background: #040c1f;
  overflow: hidden;
}
/* header background image — always spans the full header (mini bar + nav) height.
   The image lives on a ::before so we can fade its bottom edge into the hero without
   touching the nav content. */
.topcap__head {
  position: relative; z-index: 3;
  /* solid color grades to the hero-bg's exact top color (#000f21) so the header
     meets the hero with no seam */
  background: linear-gradient(to bottom, #071634 66%, #000f21 100%);
}
.topcap__head::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: url("../img/bg/header-gradient.webp") center / cover no-repeat;
  /* fade the image out over the same stretch so it dissolves into that color */
  -webkit-mask-image: linear-gradient(to bottom, #000 60%, transparent 96%);
  mask-image: linear-gradient(to bottom, #000 60%, transparent 96%);
}

/* mini bar */
.topbar { position: relative; z-index: 3; border-bottom: 1px solid rgba(255,255,255,.06); }
.topbar__inner { display: flex; align-items: center; justify-content: space-between; height: 40px; }
.topbar__tag, .topbar__links {
  font-size: 11px; letter-spacing: .09em; text-transform: uppercase;
  color: rgba(255,255,255,.62); font-weight: 500;
}
.topbar__links { display: flex; align-items: center; gap: 14px; }
.topbar__links a:hover { color: #fff; }
.topbar__div { opacity: .4; }

/* header */
.site-header { position: relative; z-index: 3; }
.site-header__inner {
  display: flex; align-items: center; gap: 36px;
  padding-block: 24px 30px;
}
.brand { display: flex; align-items: center; flex: 0 0 auto; }
.brand__logo { height: 40px; width: auto; }

.mainnav {
  flex: 1 1 auto; display: flex; align-items: center; justify-content: center; gap: 48px;
}
.mainnav a {
  font-size: 12px; font-weight: 600; letter-spacing: .05em; color: #fff;
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  opacity: .92; transition: opacity .2s var(--ease);
}
.mainnav a:hover { opacity: 1; }
.mainnav__has-sub svg { opacity: .8; }

/* split CTA pill */
.cta-split {
  flex: 0 0 auto; display: inline-flex; align-items: stretch; height: 40px;
  border-radius: 100px; overflow: hidden; background: var(--grad-brand);
  box-shadow: 0 8px 22px -10px rgba(46,136,254,.6);
  position: relative; isolation: isolate;
}
.cta-split__seg {
  position: relative; z-index: 1; display: inline-flex; align-items: center;
  font-family: "Outfit", sans-serif; font-size: 12px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase;
  color: #fff; padding: 0 22px; height: 100%; background: none; border: 0; cursor: pointer;
}
/* active (its menu panel is open) — same subtle brighten as hover */
.cta-split__seg[aria-expanded="true"]::before { opacity: 1; }
/* diagonal hover highlight — inner edge is skewed to match the "/" divider */
.cta-split__seg::before {
  content: ""; position: absolute; top: 0; bottom: 0; z-index: -1;
  background: rgba(255,255,255,.20); transform: skewX(-18deg);
  opacity: 0; transition: opacity .2s var(--ease);
}
.cta-split__seg--a::before { left: -40px; right: -1px; }
.cta-split__seg--b::before { left: -1px; right: -40px; }
.cta-split__seg:hover::before { opacity: 1; }
/* dark diagonal separator */
.cta-split__slash { width: 0; align-self: stretch; position: relative; z-index: 2; }
.cta-split__slash::before {
  content: ""; position: absolute; top: -1px; bottom: -1px; left: -1px;
  width: 2px; background: var(--black); transform: skewX(-18deg);
}
/* sticky + open-menu header: white divider between the two CTA segments */
.cta-split--onlight .cta-split__slash::before { background: #fff; }
.cta-split:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

/* mobile nav toggle + slide-in menu (hidden on desktop) */
.navtoggle { display: none; width: 44px; height: 44px; background: none; border: 0; flex-direction: column; gap: 5px; align-items: center; justify-content: center; }
.navtoggle span { width: 24px; height: 2px; background: #fff; border-radius: 2px; transition: transform .28s var(--ease), opacity .2s var(--ease); }
body.nav-open .navtoggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
body.nav-open .navtoggle span:nth-child(2) { opacity: 0; }
body.nav-open .navtoggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Above .stickyhead (100): the open menu owns the screen. At equal z-index
   the sticky header won on DOM order and painted over the panel. */
.navscrim { position: fixed; inset: 0; z-index: 115; background: rgba(0,7,20,.55); opacity: 0; transition: opacity .35s var(--ease); }
body.nav-open .navscrim { opacity: 1; }
.mobilemenu {
  position: fixed; top: 0; right: 0; z-index: 120; height: 100dvh; width: min(85vw, 370px);
  background: linear-gradient(180deg, #0b1e44 0%, #06122b 100%);
  padding: 88px clamp(24px, 7vw, 36px) 36px; display: flex; flex-direction: column; gap: 26px;
  transform: translateX(105%); transition: transform .4s var(--ease);
  overflow-y: auto; overscroll-behavior: contain;
}
/* The shadow only exists while the menu is open. On a closed off-canvas panel
   its 26px offset + 70px blur reaches back onto the page and greys the right
   edge — invisible over the dark hero, obvious over light content. */
body.nav-open .mobilemenu { transform: translateX(0); box-shadow: -26px 0 70px -32px rgba(0,0,0,.7); }
.mobilemenu__links { display: flex; flex-direction: column; }
.mobilemenu__links a { color: #fff; font-family: "Outfit", sans-serif; font-size: 20px; font-weight: 600; letter-spacing: -.01em; padding: 15px 0; border-bottom: 1px solid rgba(255,255,255,.09); }
.mobilemenu__links a:active { color: var(--blue-800); }
.mobilemenu__cta { display: flex; flex-direction: column; gap: 12px; margin-top: 6px; }
.mm-btn { display: flex; align-items: center; justify-content: center; height: 52px; border-radius: 100px; font-size: 13px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; }
/* both CTAs share ONE gradient that flows continuously across the stacked pair:
   the top button shows the top half of the gradient, the bottom button the bottom half
   (background sized to span both 52px buttons + the 12px gap between them) */
.mobilemenu__cta .mm-btn {
  color: #fff; border: 0;
  background-image: var(--grad-brand); background-repeat: no-repeat;
  background-size: 100% calc(200% + 12px);
  box-shadow: 0 10px 24px -14px rgba(46,136,254,.55);
}
.mm-btn--ghost { background-position: left top; }
.mm-btn--fill  { background-position: left bottom; }
.mobilemenu__cta .mm-btn:active { filter: brightness(1.08); }
.mobilemenu__util { margin-top: auto; display: flex; flex-direction: column; gap: 12px; padding-top: 8px; }
.mobilemenu__util a { color: rgba(255,255,255,.6); font-size: 11px; font-weight: 500; letter-spacing: .09em; text-transform: uppercase; }

/* =========================================================================
   Sticky header + mega-menu (reveals on scroll >100vh; opened by CTA buttons)
   ========================================================================= */
.stickyhead {
  position: fixed; top: 0; left: 0; width: 100%; z-index: 100; background: #fff;
  box-shadow: 0 2px 22px -10px rgba(0,15,35,.14);
  transform: translateY(-100%); transition: transform .4s var(--ease);
}
.stickyhead.is-stuck, body.menu-open .stickyhead { transform: translateY(0); }
/* The mobile menu is the same menu whether it was opened from the page-top
   header or the sticky one — so the sticky bar steps aside while it's open,
   and both entry points look identical. */
body.nav-open .stickyhead { transform: translateY(-100%); }
.stickyhead__bar { display: flex; align-items: center; gap: 36px; height: 82px; }
.stickyhead .brand__logo { height: 38px; }
.stickyhead .mainnav { flex: 1 1 auto; }
.mainnav--light a { color: rgba(0,15,35,.55); opacity: 1; }
.mainnav--light a:hover { color: var(--black); }

/* backdrop: blur + dark dim over the page while a menu is open */
.menu-backdrop {
  position: fixed; inset: 0; z-index: 90; background: rgba(0,7,20,.55);
  -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
  opacity: 0; visibility: hidden; transition: opacity .3s var(--ease), visibility .3s;
}
body.menu-open .menu-backdrop { opacity: 1; visibility: visible; }
body.menu-open { overflow: hidden; }

/* dropdown panels below the sticky bar */
.menu-panels { position: absolute; top: 100%; left: 0; width: 100%; }
.menu-panel {
  position: absolute; top: 0; left: 0; width: 100%; background: #fff;
  border-top: 1px solid #eef0f5; box-shadow: 0 24px 44px -26px rgba(0,15,35,.18);
  opacity: 0; visibility: hidden; transform: translateY(-14px); pointer-events: none;
  transition: opacity .32s var(--ease), transform .32s var(--ease), visibility .32s;
}
.menu-panel.is-open { opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto; }
/* inline padding = var(--gutter) so the info column's left edge lines up with the header logo */
.menu-panel__inner { display: grid; grid-template-columns: minmax(280px, .95fr) 1.4fr; padding: 44px var(--gutter) 50px; }
.menu-panel__info { padding-right: clamp(30px, 5vw, 64px); border-right: 1px solid #e6e9f0; }
.menu-panel__head { font-size: clamp(24px, 3vw, 34px); font-weight: 700; line-height: 1.18; letter-spacing: -.02em; color: var(--black); }
.grad-text { background: linear-gradient(96deg, #2e88fe, #7b5be6); -webkit-background-clip: text; background-clip: text; color: transparent; }
.menu-panel__sub { margin-top: 22px; font-size: 15px; line-height: 1.62; color: var(--gray); max-width: 400px; }
.menu-contact { list-style: none; display: flex; flex-direction: column; gap: 20px; margin-top: 30px; }
.menu-contact li { display: flex; gap: 14px; font-size: 14px; line-height: 1.5; color: var(--gray); align-items: flex-start; }
.menu-contact__i { width: 22px; height: 22px; flex: 0 0 auto; color: var(--black); margin-top: 1px; }
.menu-contact b { color: var(--black); font-weight: 600; }
.menu-contact a { color: var(--black); }
.menu-contact a:hover { color: var(--blue); }
.menu-contact__social { display: inline-flex; gap: 10px; color: #c3cad4; }
.menu-contact__social a { font-weight: 500; }

.menu-form { display: flex; flex-direction: column; padding-left: clamp(30px, 5vw, 64px); }
.menu-form__label { font-size: 17px; font-weight: 600; color: var(--black); margin-bottom: 18px; }
.menu-form__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.menu-form input, .menu-form select, .menu-form textarea {
  width: 100%; font-family: "Outfit", sans-serif; font-size: 14px; color: var(--black);
  border: 1px solid #dfe3ea; border-radius: 10px; padding: 15px 18px; background: #fff;
  transition: border-color .2s var(--ease);
}
.menu-form input::placeholder, .menu-form textarea::placeholder { color: #9aa6b4; }
.menu-form select { color: #9aa6b4; appearance: none; -webkit-appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2 4l4 4 4-4' fill='none' stroke='%239aa6b4' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 16px center; padding-right: 40px; }
.menu-form textarea { margin-top: 16px; min-height: 122px; resize: vertical; }
.menu-form :focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(46,136,254,.12); }
.menu-submit {
  margin-top: 18px; align-self: flex-end; display: inline-flex; align-items: center; gap: 10px;
  background: #fff; border-radius: 30px; padding: 12px 24px;
  font-size: 12px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
  transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease), box-shadow .2s var(--ease);
}
/* disabled (form incomplete): greyed-out outline */
.menu-submit:disabled { border: 1px solid #d3d9e2; color: #8a95a5; cursor: not-allowed; }
/* ready (form valid): blue outline + blue text with a soft glow */
.menu-submit:not(:disabled) { border: 1px solid #bcd8ff; color: var(--blue); cursor: pointer; box-shadow: 0 6px 18px -8px rgba(46,136,254,.4); }
.menu-submit:not(:disabled):hover { background: var(--blue); color: #fff; border-color: var(--blue); }

/* =========================================================================
   Flamingo Form inside a header CTA panel (WordPress only).
   The plugin renders .ff-form > .ff-fields > .ff-field with visible labels and
   its own submit. The design is a two-column grid of placeholder-only fields
   with the message spanning both, so labels go visually hidden and the plugin's
   controls inherit the panel's own styling above.
   ========================================================================= */
.menu-form--ff .ff-form { display: flex; flex-direction: column; }
/* Six columns rather than two, so a row can hold either two fields or three.
   The plugin only knows "half" and "full", and its widths are meaningless
   inside a grid anyway — the columns are set here. */
.menu-form--ff .ff-fields { display: grid; grid-template-columns: repeat(6, 1fr); gap: 16px; }
/* The plugin sizes fields for its own flex row — .ff-field-half is
   calc(50% - 10px). Inside the grid the cell is already sized, so that would
   shrink it again. The grid owns the columns; the field just fills its cell. */
.menu-form--ff .ff-field { width: 100%; grid-column: span 3; }
/* the message field spans the row, matching the original layout */
.menu-form--ff .ff-field-full { grid-column: 1 / -1; }

/* First name, last name and email share the opening row — a third each. Matched
   on the input they contain rather than on position, so reordering fields in
   the admin can't silently break the layout. The Library's sign-up form is a
   narrow rail and is deliberately not scoped here: its fields stay full width. */
.menu-form--ff .ff-field:has(> [name="ff[first_name]"]),
.menu-form--ff .ff-field:has(> [name="ff[last_name]"]),
.menu-form--ff .ff-field:has(> [name="ff[email]"]) { grid-column: span 2; }


/* announced, not drawn — the placeholder carries the design */
.menu-form--ff .ff-label {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.menu-form--ff .ff-field { display: flex; flex-direction: column; }
.menu-form--ff textarea.ff-input { margin-top: 0; min-height: 122px; resize: vertical; }
.menu-form--ff .ff-error { font-size: 12px; color: #c0392b; margin-top: 4px; }
.menu-form--ff .ff-error:empty { display: none; }

/* the plugin's submit takes the panel's pill treatment */
.menu-form--ff .ff-submit-wrap { margin-top: 18px; display: flex; justify-content: flex-end; }
.menu-form--ff .ff-submit {
  min-width: 0; display: inline-flex; align-items: center; gap: 10px;
  background: #fff; border: 1px solid #bcd8ff; border-radius: 30px; padding: 12px 24px;
  font-family: "Outfit", sans-serif; font-size: 12px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--blue); cursor: pointer;
  box-shadow: 0 6px 18px -8px rgba(46,136,254,.4);
  transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.menu-form--ff .ff-submit:hover { background: var(--blue); color: #fff; border-color: var(--blue); }
.menu-form--ff .ff-submit:disabled { border-color: #d3d9e2; color: #8a95a5; box-shadow: none; cursor: not-allowed; }
.menu-form--ff .ff-message { margin-top: 16px; font-size: 14px; line-height: 22px; }

/* Success: the plugin message is hidden; only the green pill shows. */
.menu-form--ff:has(.ff-message-success) .menu-form__label { display: none; }
.menu-form--ff .ff-message-success {
  display: flex;
  justify-content: flex-end;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font-size: 0;
  line-height: 0;
  color: transparent;
}
.menu-form--ff .ff-message-success::after {
  content: "Thank you for reaching out, we'll be in touch.";
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
  min-height: 44px;
  max-width: 360px;
  padding: 10px 18px 10px 44px;
  border: 1px solid rgba(63, 195, 100, 0.45);
  border-radius: 80px;
  background: rgba(63, 195, 100, 0.06)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none'%3E%3Ccircle cx='12' cy='12' r='9.25' stroke='%233fc364' stroke-width='1.5'/%3E%3Cpath d='M8 12.3l2.7 2.7L16 9.7' stroke='%233fc364' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
    no-repeat left 15px center;
  font-family: "Outfit", sans-serif;
  font-size: 13px;
  font-weight: 500;
  line-height: 18px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--green);
}

@media (max-width: 860px) {
  .menu-form--ff .ff-fields { grid-template-columns: 1fr; }
  /* one column, so nothing spans — without this the three-across rule above
     would ask for two tracks and the grid would grow an implicit one. */
  .menu-form--ff .ff-field,
  .menu-form--ff .ff-field:has(> [name="ff[first_name]"]),
  .menu-form--ff .ff-field:has(> [name="ff[last_name]"]),
  .menu-form--ff .ff-field:has(> [name="ff[email]"]) { grid-column: 1 / -1; }
}

/* =========================================================================
   HERO
   ========================================================================= */
/* The hero is ONE proportional stage: it scales as a unit with viewport width,
   everything inside is positioned in % of the stage (matched to the Figma). */
.hero { position: relative; z-index: 2; }
.hero__stage {
  position: relative; width: 100%; aspect-ratio: 2880 / 950;   /* hero-bg native ratio */
  background: url("../img/bg/hero-bg.webp") center / 100% 100% no-repeat;
}
.hero__video {
  position: absolute; left: 50%; top: 3.2%; transform: translateX(-50%); z-index: 1;
  width: 72.9%; aspect-ratio: 2100 / 730;   /* one ultrawide video (split done in the file) */
}
.hero__video-main {
  width: 100%; height: 100%; object-fit: cover; background: #0a1730;
  border-radius: clamp(10px, 1.1vw, 22px); box-shadow: 0 24px 60px -24px rgba(0,0,0,.7);
}
/* faux blurred reflection under the video — very subtle */
.hero__video-refl {
  position: absolute; left: 0; top: 100%; width: 100%; height: 100%;
  object-fit: cover; transform: scaleY(-1); border-radius: clamp(10px, 1.1vw, 22px);
  filter: blur(9px); opacity: .24; pointer-events: none;
  -webkit-mask-image: linear-gradient(to top, rgba(0,0,0,.95), transparent 46%);
  mask-image: linear-gradient(to top, rgba(0,0,0,.95), transparent 46%);
}

/* facility overlays — sit ABOVE the videos, overlapping their bottom corners slightly */
.hero__facility { position: absolute; z-index: 2; pointer-events: none; }
.hero__facility--l { left: -8%; bottom: -2%; width: 31%; }
.hero__facility--r { right: -2%; bottom: -3%; width: 28%; }

/* drones — sized/positioned in % so they scale with the stage.
   back layer (small drone) peeks from BEHIND the videos; front layer (large) is in front. */
.hero__drones { position: absolute; inset: 0; pointer-events: none; }
.hero__drones--back { z-index: 0; }
.hero__drones--front { z-index: 3; }

/* each drone = two stacked, mirror-facing images (l/r); crossfading them at the
   ends reads as the drone turning around. bodies aligned via the --l offset. */
.drone2 { position: absolute; aspect-ratio: 1; will-change: left, top; }
.drone2 img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; opacity: 0; z-index: 1; will-change: opacity; }
/* CSS light glow — a soft cone that extends beyond the drone in its travel direction.
   The element is 2x the wrap (so the beam isn't clipped); --ga rotates it around the drone. */
.drone2__glow {
  position: absolute; left: -60%; top: -60%; width: 220%; height: 220%;
  z-index: 0; pointer-events: none;
  filter: blur(6px);                 /* blurs the whole clipped cone -> soft edges all around */
  transform-origin: 50% 50%;
  transform: rotate(var(--ga, 0deg));
  transition: transform .5s var(--ease);
}
.drone2__glow::before {
  content: ""; position: absolute; inset: 0;
  /* bright at the drone (apex) fading out along the axis... */
  background:
    linear-gradient(90deg, rgba(150,222,255,.9) 50%, rgba(96,192,255,.42) 74%, rgba(96,192,255,.1) 90%, transparent 99%),
    radial-gradient(ellipse 6% 12% at 51% 50%, rgba(235,249,255,.85) 0%, transparent 72%);
  /* ...clipped into a cone that widens away from the drone */
  clip-path: polygon(50% 48.4%, 99% 40.5%, 99% 59.5%, 50% 51.6%);
}

/* =========================================================================
   CLIENTS
   ========================================================================= */
/* shared purple/blue backdrop spanning clients + models + platform */
.midbg { position: relative; background: url("../img/bg/purple-and-blue-bg.webp") center top / cover no-repeat, #fbfbfe; }

/* clients row is full-bleed: the logos fill the page width and scale up on large screens */
.clients { padding: clamp(30px, 4vw, 48px) clamp(12px, 1.6vw, 28px) 20px; }
.clients__grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 4px clamp(2px, 0.5vw, 10px); align-items: center; }
.client-logo { display: grid; place-items: center; height: clamp(60px, 5.4vw, 108px); }
.client-logo img { max-width: 100%; max-height: clamp(40px, 3.8vw, 78px); object-fit: contain; opacity: 1; }

/* small screens: horizontal scrolling marquee instead of the grid */
.clients__marquee { display: none; overflow: hidden; }
.clients__track { display: flex; width: max-content; gap: clamp(36px, 11vw, 60px); align-items: center; animation: clients-marquee 60s linear infinite; }
.clients__track .client-logo { flex: 0 0 auto; height: 88px; }
.clients__track .client-logo img { max-height: 64px; width: auto; }
.clients__marquee:active .clients__track { animation-play-state: paused; }
@keyframes clients-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* =========================================================================
   AI MODELS  (3 rows, marquee, hover-expand, simplified card)
   ========================================================================= */
.models {
  position: relative; padding: 16px 0 0;
  background: transparent;   /* shows the shared .midbg backdrop */
  /* Fallback for browsers without overflow:clip — the horizontal bleed must be
     contained even at the cost of clipping the shadow, or the page scrolls
     sideways. */
  overflow: hidden;
}
/* The clip exists ONLY to contain the rows' 100vw bleed. As `hidden` it also cut
   the bottom row's shadow off in a straight line where the section meets the
   Platform band. `clip` confines the bleed on one axis without forcing the other
   to become a scroll container, which `hidden` would, so the shadow can spill
   vertically as intended. */
@supports (overflow: clip) {
  .models { overflow-x: clip; overflow-y: visible; }
}
.models__title {
  max-width: 900px; margin: 0 auto clamp(28px, 4vw, 44px);
  text-align: center; font-weight: 600; letter-spacing: -.02em;
  /* Deliberately smaller than the other section titles (2.6rem): this one
     runs long and read a step too large. Still an <h2> — presentation only. */
  font-size: clamp(1.35rem, 2.4vw, 2.05rem); line-height: 1.2; color: var(--black);
}
.models__rows { display: flex; flex-direction: column; gap: 8px; }

.model-row {
  width: 100vw; margin-left: calc(50% - 50vw);
  overflow: visible; padding: 20px 0; cursor: grab;   /* visible so hover shadows aren't clipped; .models clips the horizontal bleed */
  user-select: none; -webkit-user-select: none;   /* click-drag-to-scroll shouldn't text-select the cards */
}
.model-row:active { cursor: grabbing; }
.model-track { display: flex; gap: 26px; width: max-content; will-change: transform; padding-inline: clamp(24px, 5vw, 80px); }

/* card: 200 x 288 portrait */
.mcard {
  /* width scales with viewport; narrowed a step from 6.2 to 6.6 cards in frame */
  --mw: clamp(150px, calc(100vw / 6.6 - 24px), 340px);
  /* details-panel width; min is set by the "More Information" pill, which must not wrap */
  --dw: clamp(208px, 16vw, 238px);
  position: relative; flex: 0 0 auto;
  /* 1.394, not 1.3 — the card was narrowed without losing height, so it reads
     skinnier rather than merely smaller. Nearer the design's 200x288. */
  width: var(--mw); height: calc(var(--mw) * 1.394);
  border-radius: var(--radius-md); overflow: hidden;
  background: #d2d7dd; box-shadow: var(--shadow-card);
  transition: width .5s var(--ease), box-shadow .45s var(--ease);
  cursor: pointer;
}
.mcard.is-expanded { width: calc(var(--mw) + var(--dw)); z-index: 20; box-shadow: var(--shadow-float); }
.mcard__hit {
  position: absolute; left: 0; top: 0; bottom: 0; width: var(--mw); z-index: 3;
}
/* The card's z-index alone is not enough: .model-track is transformed for the
   marquee (plus will-change), which makes it a stacking context, so z-index 20
   only ranks the card WITHIN its own row. The row below then paints over the
   shadow and cuts it off in a straight line. Lifting the whole row while one of
   its cards is open puts the shadow back on top, where it can fall across the
   next row as it should. */
.model-row:has(.mcard.is-expanded) { position: relative; z-index: 5; }
.mcard__media { position: absolute; left: 0; top: 0; bottom: 0; width: var(--mw); }
.mcard__media img { width: 100%; height: 100%; object-fit: cover; }
.mcard__media.is-blank { background: #d2d7dd; }

/* default overlay: name at bottom over a scrim */
.mcard__cover {
  /* Pinned to --mw like .mcard__media, not inset:0. Stretching with the card on
     expand re-flowed the name from two lines to one mid-transition, and put the
     dark scrim over the white details panel. */
  position: absolute; left: 0; top: 0; bottom: 0; width: var(--mw); z-index: 2;
  display: flex; flex-direction: column; justify-content: flex-end; padding: 20px;
  background: linear-gradient(to top, rgba(0,7,20,.82) 0%, rgba(0,7,20,.35) 28%, transparent 60%);
  transition: opacity .3s var(--ease);
}
.mcard__name { color: #fff; font-weight: 600; font-size: 24px; line-height: 1.15; letter-spacing: -.02em; text-shadow: 0 1px 10px rgba(0,7,20,.5); }
/* The cover spans the whole card at z-index 2, above the details panel. Fading
   it alone left an invisible sheet over the panel that swallowed every click on
   "More Information" — opacity: 0 still hit-tests. */
.mcard.is-expanded .mcard__cover { opacity: 0; pointer-events: none; }

/* details panel (revealed to the right of the image on expand) */
.mcard__details {
  position: absolute; left: var(--mw); top: 0; bottom: 0;
  width: var(--dw); z-index: 1;   /* FIXED width so the text never re-wraps as the card expands */
  background: #fff; padding: 20px 20px 18px; display: flex; flex-direction: column;
  opacity: 0; transition: opacity .3s var(--ease) .05s;
}
.mcard.is-expanded .mcard__details { opacity: 1; }
.mcard__dtitle { font-weight: 600; font-size: 24px; line-height: 1.15; letter-spacing: -.02em; }
.mcard__dbody { margin-top: 10px; margin-bottom: 14px; font-size: 12px; line-height: 1.55; color: var(--black); overflow: hidden;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 6; }
/* same outlined pill as .lcard__cta in The Latest, sized down for the narrow details panel */
.mcard__cta {
  margin-top: auto; align-self: flex-start; display: inline-flex; align-items: center; gap: 8px;
  font-size: 10px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: #1668d6;
  border: 1px solid var(--blue-300); border-radius: 30px; padding: 10px 14px; white-space: nowrap;
  transition: background .2s var(--ease), color .2s var(--ease);
}
.mcard__cta:hover { background: var(--blue); color: #fff; border-color: var(--blue); }

/* AI Models — mobile centered carousel (single row, swipe/arrows) */
.models__mobile { display: none; }
.mcarousel {
  position: relative; display: flex; gap: 16px; overflow-x: auto; scroll-snap-type: x mandatory;
  /* overflow-x:auto makes overflow-y compute to auto, so this padding is the
     shadow's only room. The current card carries --shadow-float
     (0 30px 70px -24px) which needs ~70px; the negative margin keeps the
     section's spacing where it was. */
  padding: 80px 14vw; margin-block: -38px; align-items: center;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.mcarousel::-webkit-scrollbar { display: none; }
.mcarousel .mcard {
  --mw: 72vw; flex: 0 0 72vw; width: 72vw; height: auto; scroll-snap-align: center;
  border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-card);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}
.mcarousel .mcard:not(.is-current) { transform: scale(.93); }
.mcarousel .mcard.is-current { box-shadow: var(--shadow-float); }
.mcarousel .mcard__media { position: relative; inset: auto; width: 100%; aspect-ratio: 200 / 236; }
.mcarousel .mcard__hit {
  position: absolute; left: 0; right: 0; top: 0; bottom: auto;
  width: 100%; height: auto; aspect-ratio: 200 / 236;
}
/* On mobile every card shows its image, title and description — not just the
   centred one. The cover overlay is dropped entirely: the details block already
   carries the name, so showing both would print it twice. */
.mcarousel .mcard__details { position: static; width: 100%; opacity: 1; display: flex; padding: 18px; }
.mcarousel .mcard__cover { display: none; }
.mcarousel .mcard__dbody { -webkit-line-clamp: 4; }
.mcarousel__nav { display: flex; justify-content: center; gap: 14px; margin-top: 22px; }
.mcarousel__arrow { width: 48px; height: 48px; border-radius: 50%; border: 1px solid var(--light); background: #fff; color: var(--black); font-size: 18px; display: grid; place-items: center; }
.mcarousel__arrow:active { background: var(--black); color: #fff; }

/* =========================================================================
   PLATFORM
   ========================================================================= */
.platform {
  position: relative; padding: 36px 0 36px;
  background: transparent;   /* shows the shared .midbg backdrop */
}
.platform__head { --gutter: clamp(20px, 8vw, 120px); text-align: center; margin-top: 10px; margin-bottom: clamp(28px, 4vw, 44px); }
/* platform dashboard + feature columns: full-bleed to the same left edge as The Latest cards */
.platform__body { max-width: none; padding-inline: clamp(20px, 8vw, 120px); }
.platform__title { font-size: clamp(1.7rem, 3.4vw, 2.6rem); font-weight: 600; letter-spacing: -.02em; line-height: 1.15; }
/* top tuned so the ™ glyph's top edge sits flush with the cap height of "AI" */
.platform__title sup { position: relative; font-size: .42em; top: -.151em; }
.platform__sub { margin-top: 0; color: var(--gray); font-size: clamp(.95rem, 1.4vw, 1.05rem); }

/* platform slideshow (each slide is a pre-rendered image, 16px radius) */
.pslides {
  position: relative; width: 100%; aspect-ratio: 2400 / 1040;
  border-radius: 16px; overflow: hidden;   /* no drop shadow on the slider window — the cards inside keep theirs */
  background: #05070d;   /* fade to black (not white) between slide transitions */
  container-type: inline-size;   /* so live tooltip cards (.ptip) scale with the slide */
}
.pslide {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity .55s var(--ease); pointer-events: none;
}
.pslide.is-active { opacity: 1; }

/* layered slide (slide 1): background image + positioned layers that animate in */
.pslide__bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.pslayer { position: absolute; height: auto; display: block; will-change: transform, opacity; }
/* live tooltip card — real text + info icon (replaces baked-in tooltip images);
   sized in cqw so it scales with the slide */
.ptip {
  display: flex; align-items: flex-start; gap: .95cqw; overflow: hidden;
  background: #fff; border-radius: 1.15cqw;
  padding: 1.05cqw 1.35cqw 1.3cqw .95cqw;   /* bottom clears the .34cqw gradient bar */
  box-shadow: 0 1cqw 2.6cqw -1.1cqw rgba(10,20,50,.32);
}
.ptip__icon {
  flex: 0 0 auto; width: 2cqw; height: 2cqw; margin-top: .28cqw;   /* optically centers the mark on line 1 */
  background: url("../img/platform/icons/trilight.svg") no-repeat center / contain;
}
.ptip p {
  margin: 0; font-size: 1.16cqw; line-height: 1.25;
  font-weight: 500; color: #0d1b3e; letter-spacing: -.01em;
}
.ptip::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: .34cqw;
  background: linear-gradient(90deg, #2e88fe, #8e46d0);
}
.pslide--layers.is-active .pslayer { animation: pslayer-in .7s var(--ease) both; animation-delay: var(--d, 0s); }
@keyframes pslayer-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }

/* platform — mobile swipe carousel (slide image + its feature, combined) */
.platform__mobile { display: none; }
.pcarousel { position: relative; display: flex; gap: 16px; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.pcarousel::-webkit-scrollbar { display: none; }
.pcslide { flex: 0 0 100%; scroll-snap-align: center; display: flex; flex-direction: column; gap: 18px; }
.pcslide__img { width: 100%; aspect-ratio: 2400 / 1040; object-fit: cover; border-radius: 16px; background: #05070d; box-shadow: 0 24px 50px -30px rgba(10,20,50,.5); }
.pcslide__feat { display: flex; flex-direction: column; gap: 12px; }
.pcslide__bar { height: 4px; border-radius: 4px; background: linear-gradient(90deg, #C0DBFF 0%, #2E88FE 50%, #8E46D0 100%); }
.pcslide__icon { width: 48px; height: 48px; background: center / contain no-repeat; }
.pcslide__feat p { font-size: 14px; line-height: 1.55; color: var(--gray); }
.pcslide__feat p b { color: var(--black); font-weight: 600; }
.pcarousel__dots { display: flex; justify-content: center; gap: 8px; margin-top: 22px; }
.pcarousel__dots button { width: 8px; height: 8px; border-radius: 20px; border: 0; padding: 0; background: #c8d1dd; transition: background .25s var(--ease), width .25s var(--ease); }
.pcarousel__dots button.is-active { background: var(--blue); width: 24px; }

/* 4 feature columns — act as tabs driving the slideshow */
.pfeatures { list-style: none; display: grid; grid-template-columns: repeat(4, 1fr); gap: 40px; margin-top: clamp(28px, 3.5vw, 44px); }
.pfeature {
  display: flex; flex-direction: column; gap: 14px; text-align: left;
  background: none; border: 0; padding: 0; width: 100%; cursor: pointer;
}
.pfeatures__bar { height: 4px; border-radius: 4px; background: #dfe3ea; position: relative; overflow: hidden; }
.pfeatures__fill { position: absolute; inset: 0; border-radius: 4px; will-change: clip-path;
  background: linear-gradient(90deg, #C0DBFF 0%, #2E88FE 50%, #8E46D0 100%); clip-path: inset(0 100% 0 0); }
/* The four icons under the slider were removed on 2026-08-31. Hidden rather
   than deleted from the markup: home.js reads data-i off this element to build
   the mobile carousel's slides, so removing it would break that. The rules
   below still resolve; nothing paints. */
.pfeatures__icon { display: none; }
.pfeatures__icon--legacy { width: 48px; height: 48px; background: center / contain no-repeat; transition: filter .25s var(--ease); }
.pfeature.is-active .pfeatures__icon, .pfeature:hover .pfeatures__icon { filter: drop-shadow(0 2px 5px rgba(0, 0, 0, .15)); }
.pfeatures__icon[data-i="1"] { background-image: url("../img/platform/icons/platform-feature-icon-1.svg"); }
.pfeatures__icon[data-i="2"] { background-image: url("../img/platform/icons/platform-feature-icon-2.svg"); }
.pfeatures__icon[data-i="3"] { background-image: url("../img/platform/icons/platform-feature-icon-3.svg"); }
.pfeatures__icon[data-i="4"] { background-image: url("../img/platform/icons/platform-feature-icon-4.svg"); }
.pfeature.is-active .pfeatures__icon[data-i="1"], .pfeature:hover .pfeatures__icon[data-i="1"] { background-image: url("../img/platform/icons/platform-feature-icon-1-active.svg"); }
.pfeature.is-active .pfeatures__icon[data-i="2"], .pfeature:hover .pfeatures__icon[data-i="2"] { background-image: url("../img/platform/icons/platform-feature-icon-2-active.svg"); }
.pfeature.is-active .pfeatures__icon[data-i="3"], .pfeature:hover .pfeatures__icon[data-i="3"] { background-image: url("../img/platform/icons/platform-feature-icon-3-active.svg"); }
.pfeature.is-active .pfeatures__icon[data-i="4"], .pfeature:hover .pfeatures__icon[data-i="4"] { background-image: url("../img/platform/icons/platform-feature-icon-4-active.svg"); }
.pfeature p { font-size: 16px; line-height: 1.55; color: var(--gray); }
.pfeature p b { color: var(--black); font-weight: 600; }
.pfeature:focus-visible { outline: 2px solid var(--blue); outline-offset: 4px; border-radius: 4px; }

/* =========================================================================
   THE LATEST
   ========================================================================= */
.latest {
  position: relative; padding: 10px 0 clamp(88px, 9.5vw, 132px);
  background: url("../img/bg/the-latest-bg.webp") center bottom / cover no-repeat, #fff;
}
/* head mirrors .platform__head so the two section headlines read as one system */
.latest__head { --gutter: clamp(20px, 8vw, 120px); text-align: center; margin-bottom: clamp(28px, 4vw, 44px); }
.latest__title { font-size: clamp(1.7rem, 3.4vw, 2.6rem); font-weight: 600; letter-spacing: -.02em; line-height: 1.15; }
.latest__sub { margin-top: 0; color: var(--gray); font-size: clamp(.95rem, 1.4vw, 1.05rem); }

/* padding-block gives the cards' shadow room to render before the overflow clip catches it;
   the matching negative margin cancels the padding's effect on surrounding layout */
.latest__viewport {
  /* overflow-y is hidden, so this padding is the shadow's only room. The
     card shadow is `0 24px 54px -20px`; a 54px blur's tail runs past
     blur/2, so 40px clipped it with visible strength still left. */
  overflow: auto hidden; padding-block: 64px; margin-block: -64px;
  scroll-snap-type: x mandatory; scroll-padding-inline: clamp(20px, 8vw, 120px);
  scrollbar-width: none; cursor: grab; overscroll-behavior-x: contain;
}
.latest__viewport::-webkit-scrollbar { display: none; }
.latest__viewport:focus-visible { outline: 2px solid var(--blue); outline-offset: -6px; border-radius: 8px; }
/* snapping is off from grab until the release animation settles, so neither the pointer
   nor the commit-scroll fights the browser re-snapping */
.latest__viewport.is-free { scroll-snap-type: none; }
.latest__viewport.is-dragging { cursor: grabbing; user-select: none; }
/* the gutter lives on the track, not the scroll container, so the trailing edge survives scrolling */
.latest__track { position: relative; display: flex; gap: 26px; padding-inline: clamp(20px, 8vw, 120px); }
/* Trailing spacer so the See All card doesn't finish flush against the browser
   edge. padding-right on the track does nothing here — the cards overflow its
   box, so the padding lands behind them rather than after the last one — and
   `width: max-content` fixes that but resolves the cards to their longest
   unbroken line (6097px each at 768). A flex item has neither problem. */
.latest__track::after { content: ""; flex: 0 0 clamp(20px, 6vw, 110px); }
.lcard {
  scroll-snap-align: start;
  flex: 0 0 min(1120px, 92vw); display: flex; gap: 26px;
  background: #fff; border-radius: var(--radius-lg); padding: 20px;
  box-shadow: 0 24px 54px -20px rgba(8,18,40,.4), 0 8px 18px -8px rgba(8,18,40,.18);
}
.lcard__rail { flex: 0 0 250px; display: flex; flex-direction: column; padding: 8px; }
.lcard__logo { height: clamp(30px, 2.4vw, 42px); width: auto; max-width: 200px; object-fit: contain; align-self: flex-start; margin-bottom: 22px; }
.lcard__title { font-size: clamp(19px, 1.5vw, 23px); font-weight: 700; line-height: 1.18; letter-spacing: -.01em; }
.lcard__excerpt { margin-top: 14px; font-size: 14px; line-height: 1.55; color: var(--gray); }
.lcard__cta { margin-top: auto; align-self: flex-start; display: inline-flex; align-items: center; gap: 10px;
  font-size: 12px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: #1668d6;
  border: 1px solid var(--blue-300); border-radius: 30px; padding: 12px 20px; white-space: nowrap; transition: background .2s var(--ease), color .2s var(--ease); }
.lcard__cta:hover { background: var(--blue); color: #fff; border-color: var(--blue); }
/* the → sits at 1.5em so it reads at the same weight as the uppercase label */
.lcard__cta span, .mcard__cta span { font-size: 1.5em; line-height: 1; }

.lcard__media { flex: 1 1 auto; display: flex; gap: 12px; height: clamp(340px, 27vw, 430px); }
.lcard__big { flex: 1.55; border-radius: 14px; overflow: hidden; }
.lcard--bigright .lcard__big { order: 2; }
.lcard__big img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lcard__col { flex: 1; display: flex; flex-direction: column; gap: 12px; }
.lcard__col img { width: 100%; flex: 1 1 0; min-height: 0; object-fit: cover; border-radius: 14px; display: block; }
/* A story with no imagery yet keeps the collage's shape rather than collapsing
   it — the same placeholder tile the model library uses. */
.lcard__shot--empty {
  display: block; width: 100%; height: 100%; flex: 1 1 0; min-height: 0; border-radius: 14px;
  background: repeating-conic-gradient(rgba(255,255,255,.10) 0% 25%, rgba(255,255,255,.03) 0% 50%) 0 0 / 22px 22px;
}

/* 6th slide — narrow "See All" gradient card linking to the blog */
.lcard--all {
  flex: 0 0 min(300px, 78vw); border-radius: var(--radius-lg); overflow: hidden; position: relative;
  display: grid; place-items: center; text-decoration: none;
  background: url("../img/latest/see-all-bg.webp") center / cover no-repeat, #fff;
}
.lcard--all__inner { position: relative; z-index: 1; }
/* The artwork behind this is white now, so the button takes .btn-pill's blue
   outline rather than the white-on-purple it used to carry. */
.lcard--all__btn { display: inline-flex; align-items: center; gap: 10px; color: var(--blue);
  border: 1px solid var(--blue-300); border-radius: 40px; padding: 15px 30px; background: transparent;
  font-size: 12px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
  transition: background-color .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease); }
.lcard--all:hover .lcard--all__btn { background: var(--blue); border-color: var(--blue); color: #fff; }
.lcard--all:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }

.btn-pill {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 15px 30px; border: 1px solid var(--blue-300); border-radius: 40px;
  font-size: 12px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
  color: var(--blue); background: transparent;
  transition: background-color .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.btn-pill:hover { background: var(--blue); border-color: var(--blue); color: #fff; }
.btn-pill:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .btn-pill { transition: none; } }

/* mobile media-slideshow dots (built in js; hidden on desktop where all 3 images show) */
.lcard__dots { display: none; }
.lcard__dot { width: 7px; height: 7px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.6); box-shadow: 0 1px 3px rgba(0,0,0,.45); cursor: pointer;
  transition: background .25s var(--ease), width .25s var(--ease); }
.lcard__dot.is-active { background: #fff; width: 20px; border-radius: 4px; }

/* =========================================================================
   FOOTER
   ========================================================================= */
.footer {
  background: #fff;
  padding: clamp(44px, 5vw, 60px) 0 34px; color: var(--black);
}
.footer__inner { --gutter: clamp(20px, 8vw, 120px); }
.footer__cols { display: grid; grid-template-columns: 1.4fr repeat(3, 1fr); gap: 30px; }
.footer__brand img { height: 52px; width: auto; display: block; }
/* The contact block was flush against the logo — 0px between them. */
.footer__contact { margin-top: 20px; }
.footer__col h3 { font-size: 13px; font-weight: 700; margin-bottom: 16px; }
.footer__col a { display: block; font-size: 14px; color: var(--gray); padding: 5px 0; }
.footer__col a:hover { color: var(--black); }
.footer__rule { border: 0; border-top: 1px solid rgba(0,15,35,.12); margin: 34px 0 20px; }
.footer__bottom { display: flex; align-items: center; justify-content: space-between; font-size: 13px; color: var(--gray); }
.footer__legal { display: flex; align-items: center; gap: 24px; }
.footer__legal a:hover { color: var(--black); }

/* UserWay floating badge — the footer Accessibility link opens the widget instead. */
#userwayAccessibilityIcon { display: none !important; }
.footer__social { display: flex; gap: 24px; }
.footer__social a:hover { color: var(--black); }

/* =========================================================================
   Responsive
   ========================================================================= */
@media (max-width: 1024px) {
  .footer__cols { grid-template-columns: 1fr 1fr 1fr; }
  .footer__brand { grid-column: 1 / -1; }
  .pfeatures { grid-template-columns: 1fr 1fr; }
  /* clients: switch grid -> scrolling marquee */
  .clients__grid { display: none; }
  .clients__marquee { display: block; }
}
@media (max-width: 860px) {
  .mainnav, .cta-split { display: none; }
  /* centred on the logo row (logo sits at 65-105, so a 44px button starts at 63)
     and inset by the same gutter as the logo, rather than floating in the
     utility bar above it */
  /* Absolute, not fixed: the icon belongs to the header and scrolls away with
     it rather than floating over the page on its own. */
  .navtoggle { display: flex; position: absolute; top: 63px; right: var(--gutter); z-index: 110; }
  /* It becomes fixed again only when something is pinned to the viewport — the
     sticky bar (82px tall, so centred at 19px) or an open menu. */
  body.is-stuck .navtoggle,
  body.menu-open .navtoggle,
  body.nav-open .navtoggle { position: fixed; top: 19px; }
  /* above the panel it closes */
  .navtoggle { z-index: 130; }
  .site-header__inner { justify-content: flex-start; }
  .topbar__tag { display: none; }
  /* AI Models: desktop 3-row marquee -> single centered carousel */
  .models__rows { display: none; }
  .models__mobile { display: block; }
  /* Platform: desktop slideshow+tabs -> single swipe carousel */
  .pslides, .pfeatures { display: none; }
  .platform__mobile { display: block; }
  /* The Latest cards stack on mobile */
  .lcard { flex-direction: column; }
  .lcard:not(.lcard--all) { flex-basis: 100%; }   /* full-width card: only the in-focus card is visible */
  .lcard__rail { flex: 0 0 auto; }
  /* the 3 media images collapse into one auto-rotating crossfade slideshow (js: latestMobileSlides) */
  .lcard__media { position: relative; display: block; height: auto; aspect-ratio: 16 / 10; border-radius: 14px; overflow: hidden; }
  .lcard__media > .lcard__big, .lcard__media > .lcard__col { position: absolute; inset: 0; display: block; }
  .lcard__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 0;
    opacity: 0; transition: opacity .7s var(--ease); }
  .lcard__media img.is-slide-active { opacity: 1; }
  /* faint bottom scrim so the white dots stay visible over light images */
  .lcard__media::after { content: ""; position: absolute; z-index: 1; left: 0; right: 0; bottom: 0; height: 64px;
    background: linear-gradient(to top, rgba(0,7,20,.34), transparent); pointer-events: none; }
  .lcard__dots { position: absolute; z-index: 2; left: 0; right: 0; bottom: 10px; display: flex; justify-content: center; gap: 7px; }
  .footer__cols { grid-template-columns: 1fr 1fr; }
  /* mega-menu: stack columns, full-height scroll */
  .menu-panel__inner { grid-template-columns: 1fr; padding: 24px var(--gutter) 32px; }
  .menu-panel__info { border-right: 0; border-bottom: 1px solid #e6e9f0; padding: 0 0 24px; margin-bottom: 24px; }
  .menu-form { padding-left: 0; }
  .menu-form__grid { grid-template-columns: 1fr; }
  .menu-submit { align-self: stretch; justify-content: center; }
  .menu-panel { max-height: calc(100dvh - 82px); overflow-y: auto; }
  /* hamburger darkens over the white sticky bar / open menu */
  body.menu-open .navtoggle span, body.is-stuck .navtoggle span { background: #0a1428; }
  /* ...but once the menu is open the icon is an X on the dark panel, so it
     goes back to white. Same specificity as the rule above, so it has to
     come after it. */
  body.nav-open .navtoggle span { background: #fff; }
  /* uniform 20px side gutter so every section shares one left edge on mobile
     (the 8vw gutter resolves to ~31px here and broke alignment vs. the 20px containers) */
  .platform__head, .latest__head, .footer__inner { --gutter: 20px; }
  .latest__viewport { scroll-padding-inline: 20px; }
  .latest__track { padding-inline: 20px; }
}
@media (max-width: 560px) {
  .clients__grid { grid-template-columns: repeat(4, 1fr); }
  .pfeatures { grid-template-columns: 1fr; }
  .footer__bottom { flex-direction: column; gap: 12px; }
  .footer__legal { flex-direction: column; gap: 8px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; }
  .model-track { transform: none !important; }
}


/* =========================================================================
   Reveal on scroll — GLOBAL utility (home.css loads on every view)

   Add `reveal` to any element, or `reveal-group` to a parent to stagger its
   direct children. Nothing else is needed; home.js picks them up everywhere.

   Deliberately NOT pre-hidden in CSS. The armed state is added by JS, and only
   to elements that are BELOW the fold when the page loads, which means:
     - nothing above the fold can flash in,
     - with JS off or IntersectionObserver missing, every element just stays
       visible rather than being stranded at opacity 0.
   Matches the .pslayer animation on the homepage platform slides: a 14px rise
   over .7s on the same easing.
   ========================================================================= */
.reveal--armed {
  opacity: 0;
  transform: translateY(14px);
  will-change: opacity, transform;
}
.reveal--armed.is-in {
  opacity: 1;
  transform: none;
  /* only transform and opacity — never `all` */
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  transition-delay: var(--reveal-d, 0s);
  will-change: auto;
}

@media (prefers-reduced-motion: reduce) {
  /* belt and braces: home.js does not arm anything in this mode either */
  .reveal--armed,
  .reveal--armed.is-in { opacity: 1; transform: none; transition: none; }
}

/* =========================================================================
   Rebrand bar — GLOBAL. The first row of the document (markup in
   header-inflightai.php), in normal flow: it pushes the page down instead of
   overlaying it, and removing it lets everything move back up.
   ========================================================================= */
.rebrand {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 13px 44px;
  background: var(--blue);
  color: #fff;
}
.rebrand[hidden] { display: none; }
/* Set by the inline pre-check in header-inflightai.php when this session has
   already dismissed the bar. The markup is always sent — the page is cached, so
   a bar-less copy must never be storable — and this hides it before first paint
   rather than after, which is what keeps the collapse from being a visible jolt.
   Must stay in a render-blocking sheet in the head to beat the paint. */
html.ifa-rebrand-dismissed .rebrand { display: none; }

.rebrand__inner { display: flex; align-items: center; justify-content: center; gap: 16px; }

/* The "Learn more" link is part of the bar, so it takes the bar's type rather
   than a browser-default 16px sentence-case link sitting next to 11px caps. */
.rebrand__cta {
  flex: 0 0 auto;
  font-family: "DM Sans", "Outfit", sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(255, 255, 255, 0.5);
  white-space: nowrap;
  transition: text-decoration-color 0.2s var(--ease);
}
.rebrand__cta:hover { text-decoration-color: #fff; }
.rebrand__cta:focus-visible { outline: 2px solid #fff; outline-offset: 3px; border-radius: 2px; }
.rebrand__text {
  margin: 0;
  font-family: "DM Sans", "Outfit", sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  text-align: center;
  color: #fff;
}

.rebrand__close {
  position: absolute;
  top: 50%;
  right: 10px;
  translate: 0 -50%;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
  cursor: pointer;
  transition: background-color 0.2s var(--ease), transform 0.2s var(--ease);
}
.rebrand__close:hover { background: rgba(255, 255, 255, 0.36); }
.rebrand__close:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.rebrand__close:active { transform: translateY(-50%) scale(0.9); }

@media (max-width: 520px) {
  .rebrand { padding: 13px 0; }
  .rebrand__text { font-size: 10px; letter-spacing: 0.07em; }
}
