:root {
  color-scheme: dark;
  --ink-0: #090a0b;
  --ink-1: #111315;
  --ink-2: #181b1e;
  --ink-3: #222528;
  --paper: #f5f5f2;
  --muted: #a4a7a9;
  --dim: #74787b;
  --hairline: rgba(255, 255, 255, 0.14);
  --hairline-strong: rgba(255, 255, 255, 0.25);
  --glass: rgba(24, 26, 28, 0.58);
  --glass-heavy: rgba(14, 16, 17, 0.8);
  --signal: #ff8a3d;
  --radius-sm: 14px;
  --radius-md: 24px;
  --radius-lg: 36px;
  --page: min(92vw, 1440px);
  /* Distance from the page's right edge to the viewport's. Always equal to the
     page's own gutter, so anything sized with it lands exactly on the screen
     edge at every width. */
  --bleed-right: calc((100vw - var(--page)) / 2);
  --ease-out: cubic-bezier(.2, .8, .2, 1);
  --ease-spring: cubic-bezier(.18, .9, .3, 1.08);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; background: var(--ink-0); }
body {
  margin: 0;
  min-width: 320px;
  overflow-x: hidden;
  color: var(--paper);
  background: var(--ink-0);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

body::selection { color: var(--ink-0); background: var(--paper); }
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; }
button, a { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 2px solid var(--paper); outline-offset: 4px; }

.skip-link {
  position: fixed;
  left: 16px;
  top: -60px;
  z-index: 200;
  padding: 12px 16px;
  color: var(--ink-0);
  background: var(--paper);
  border-radius: 999px;
  font-weight: 650;
}
.skip-link:focus { top: 16px; }

/* A band across the top of the window, not a capsule floating inside it. It is
   laid on the page's own gutter, --bleed-right, so the wordmark and the nav sit
   on exactly the vertical lines every section below them starts and ends on. No
   radius, no inset, no gap above it: the header is the top edge of the page. */
.site-header {
  position: fixed;
  z-index: 100;
  inset: 0 0 auto;
  display: flex;
  min-height: 64px;
  align-items: center;
  justify-content: space-between;
  padding-inline: var(--bleed-right);
  border-bottom: 1px solid var(--hairline);
  background: var(--ink-0);
  transition: box-shadow .35s var(--ease-out);
}
/* Opaque already, so the bar's own surface has nothing left to change. What it
   gains once content passes under it is separation from that content. */
.site-header.is-scrolled { box-shadow: 0 18px 44px rgba(0, 0, 0, .34); }
.wordmark {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  font-size: .95rem;
  font-weight: 680;
  letter-spacing: -.025em;
}
.wordmark::before {
  width: 9px;
  height: 9px;
  margin-right: 10px;
  border: 1.5px solid currentColor;
  border-radius: 50%;
  box-shadow: 0 0 0 4px rgba(255, 255, 255, .08);
  content: "";
}
.primary-nav { display: flex; align-items: center; gap: 6px; }
.primary-nav a {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  padding: 0 14px;
  border-radius: 999px;
  color: rgba(245, 245, 242, .68);
  font-size: .875rem;
  font-weight: 540;
  transition: color .25s ease, background .25s ease;
}
.primary-nav a:hover, .primary-nav a[aria-current="page"] { color: var(--paper); background: rgba(255, 255, 255, .08); }
.primary-nav a:last-child { color: var(--ink-0); background: var(--paper); }
.nav-toggle {
  display: none;
  min-width: 56px;
  min-height: 44px;
  color: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: rgba(255, 255, 255, .06);
}

.eyebrow, .section-label, .coordinate {
  margin: 0;
  color: rgba(245, 245, 242, .58);
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: .75rem;
  font-weight: 560;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.hero {
  --hero-progress: 0;
  position: relative;
  display: grid;
  min-height: 100svh;
  align-items: end;
  isolation: isolate;
  overflow: clip;
}
.hero-glow, .hero-globe, .hero-wash { position: absolute; inset: 0; }
.hero-glow {
  z-index: -4;
  background: radial-gradient(circle at 71.5% 50%, rgba(255, 255, 255, .06), transparent 58%);
}
.hero-globe { z-index: -3; display: block; width: 100%; height: 100%; }
.hero-wash {
  z-index: -2;
  background: linear-gradient(180deg, rgba(9, 10, 11, .25), transparent 42%, var(--ink-0) 100%);
}
.hero-content {
  display: grid;
  width: var(--page);
  margin: 0 auto;
  padding: 180px 0 84px;
  grid-template-columns: minmax(0, 1.1fr) minmax(280px, .9fr);
  align-items: end;
  gap: clamp(32px, 8vw, 140px);
}
.hero-copy { max-width: 850px; }
.hero h1 {
  max-width: 950px;
  margin: 22px 0 30px;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Helvetica Neue", Arial, sans-serif;
  font-size: clamp(4rem, 9.5vw, 9.8rem);
  font-weight: 560;
  letter-spacing: -.075em;
  line-height: .82;
}
.hero-lede { max-width: 600px; margin: 0; color: rgba(245, 245, 242, .72); font-size: clamp(1.05rem, 1.5vw, 1.3rem); line-height: 1.55; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 34px; }
.button {
  display: inline-flex;
  min-height: 52px;
  align-items: center;
  justify-content: center;
  padding: 0 20px;
  border: 1px solid var(--hairline-strong);
  border-radius: 999px;
  font-size: .95rem;
  font-weight: 650;
  transition: transform .25s var(--ease-spring), background .25s ease, color .25s ease;
}
.button:hover { transform: translateY(-2px); }
.button-primary { color: var(--ink-0); border-color: var(--paper); background: var(--paper); }
.button-secondary { background: rgba(255, 255, 255, .06); backdrop-filter: blur(18px); }
.button-arrow::after { margin-left: 14px; content: "↗"; }
/* Arrows written as a real span rather than a ::after. The button is a flex box,
   so the space in the text node before the arrow is discarded as a flex item's
   whitespace and the two run together: "Unlock download→". Stated at the same
   14px as .button-arrow::after, so every arrow on the site sits the same
   distance from its label whether it is drawn or marked up. */
.button span, form button span { margin-left: 14px; }
/* The release panel's button when the build has no public location: it keeps its
   place in the layout, and stops reading as something to press. */
.button[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
.button[aria-disabled="true"]:hover { transform: none; }

.hero-aside { display: grid; justify-items: end; }
.hero-meta { display: flex; gap: 18px; }

/* Anchor navigation would otherwise land a section's top under the fixed header
   and put its first line of content behind it. */
.section { width: var(--page); margin: 0 auto; padding: clamp(90px, 12vw, 180px) 0; scroll-margin-top: 120px; }
.section-heading { max-width: 1000px; margin: 20px 0 0; font-size: clamp(2.8rem, 6.2vw, 6.6rem); font-weight: 530; letter-spacing: -.065em; line-height: .95; }
.section-intro { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(260px, .55fr); align-items: end; gap: 48px; }
.section-intro > p:last-child, .product-note { max-width: 500px; margin: 0 0 8px; color: var(--muted); font-size: 1.08rem; }

.product-stage { padding-top: 36px; }
/* Two columns that both carry weight: the label, heading, and description stand in
   the left one, and the window runs from the right one off the edge of the screen.
   The heading is set in the same clamp as every other section's — it simply
   measures three lines here rather than two.

   Everything before this put only the description beside the window. That column
   then held a single paragraph against a frame more than eight times its height,
   and the whole of the difference stood as dead space at its foot, however the
   paragraph was aligned in it: pinned to the top the space pooled below, centred
   it split, and set on the baseline it moved between the heading and the text. The
   heading is what the column was short of. Standing it there fills the column, and
   it also settles the frame's position for good: the window can no longer begin
   under the words at any width, because the words are no longer above it.

   The tracks are weighted towards the frame, which is the thing worth looking at.
   At 1.3 the words keep their three lines with room to spare — the longest of them
   measures 465px against a 580px column at 1512, and the two tracks only meet at
   around 1.8, where the heading would take a fourth line. Anything under that is
   the frame's to take. */
.product-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr);
  align-items: start;
  gap: 56px;
}
.product-note { margin: clamp(20px, 2.2vw, 34px) 0 0; }
.product-window {
  position: relative;
  overflow: hidden;
  /* The window runs off the right edge of the screen — it reads as a view onto
     something wider than the column it sits in, so that side is left open rather
     than closed with a border and a corner. Its grid track ends at the section's
     right edge; the bleed carries it the rest of the way to the viewport, so the
     right edge stays pinned there at every width and on phones, where the tracks
     collapse to one column, it is edge to edge. */
  width: calc(100% + var(--bleed-right));
  margin: 0 calc(var(--bleed-right) * -1) 0 0;
  border: 1px solid var(--hairline);
  border-right: 0;
  /* Tighter than --radius-lg: on a window this wide the 36px corner was reading
     as a card rather than a screen. */
  border-radius: 18px 0 0 18px;
  background: #111;
  box-shadow: 0 60px 120px rgba(0, 0, 0, .46);
}
.window-bar { display: flex; height: 54px; align-items: center; padding: 0 18px; border-bottom: 1px solid var(--hairline); background: #121415; }
.window-dots { display: flex; gap: 7px; }
.window-dots i { width: 10px; height: 10px; border-radius: 50%; background: #4a4d4f; }
.window-title { margin: 0 auto; color: var(--dim); font-size: .78rem; }
/* The capture is the app's content area in logical points, so the ratio is exact
   and object-fit has nothing left to crop. */
.product-image-wrap { position: relative; aspect-ratio: 1512 / 949; overflow: hidden; }
/* The screenshot is a real capture, so the only treatment is tonal: Apple Maps
   ships an olive-drab land colour and green POI confetti that fight the page's
   near-black palette. Desaturating drops both and leaves the pins reading as
   white marks on dark ground. */
/* No hover state: the capture is a static document of the app, and a slow push-in
   on a screenshot reads as a slideshow effect next to the page's own motion. */
.product-image-wrap img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(1) contrast(1.8) brightness(.46); }

.capabilities { border-top: 1px solid var(--hairline); }
.capability-grid { display: grid; margin-top: 64px; grid-template-columns: repeat(3, 1fr); }
.capability {
  position: relative;
  min-height: 270px;
  padding: 28px;
  overflow: hidden;
  border-right: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}
/* The glow follows the pointer, so it belongs to the pointer being there. Painted
   as the cell's own background it was on at all times: the two custom properties
   fall back to 50% 50% whenever the pointer is elsewhere, which parked a lit spot
   in the middle of every cell at rest. Given a layer of its own it can simply be
   absent, and it reads as the response to a hover rather than as a state. */
.capability::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at var(--pointer-x, 50%) var(--pointer-y, 50%), rgba(255, 255, 255, .08), transparent 34%);
  opacity: 0;
  transition: opacity .45s ease;
  pointer-events: none;
}
.capability:hover::before { opacity: 1; }
.capability:nth-child(3n) { border-right: 0; }
.capability h3 { max-width: 280px; margin: 75px 0 10px; font-size: 1.65rem; font-weight: 550; letter-spacing: -.04em; }
.capability p { max-width: 350px; margin: 0; color: var(--muted); }
.capability-tag { color: var(--dim); font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: .75rem; }

.workflow { position: relative; }
.workflow-list { margin: 70px 0 0; padding: 0; list-style: none; counter-reset: workflow; }
.workflow-list li { display: grid; min-height: 118px; align-items: center; border-top: 1px solid var(--hairline); grid-template-columns: 84px 1fr 1fr; gap: 24px; counter-increment: workflow; }
.workflow-list li:last-child { border-bottom: 1px solid var(--hairline); }
.workflow-list li::before { color: var(--dim); content: counter(workflow, decimal-leading-zero); font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: .75rem; }
.workflow-list h3 { margin: 0; font-size: clamp(1.35rem, 2.3vw, 2.4rem); font-weight: 520; letter-spacing: -.04em; }
.workflow-list p { max-width: 460px; margin: 0; color: var(--muted); }

/* Who the product is for, set as a list rather than as three panels. The panel
   treatment made this the only section on the page built from cards, and all three
   of them stood mostly empty: a fixed min-height with space-between threw the
   slack into the middle of the large one, and pinned both small ones to their
   floors. Hairlines carry the structure here, the way they already do in the
   capability grid, and the section takes the same intro shape as the two above it.

   The heading is a step below the other sections' on purpose. Those state what the
   product does and are the page's loudest type after the hero; this one names an
   audience, and at the full section size it read as a statement the section does
   not make. The step between the two sizes is 1.35. */
.audience-heading {
  /* Measured in em, not px, so the break holds at every width: the heading is set
     in a fluid clamp, and a fixed max-width would fall on a different side of the
     two candidate breaks as the size moved. At this size "One clear view across"
     measures 8.29em and "One clear view across the" 9.69em, so 9em breaks after
     "across" and leaves the two lines at 8.29em and 4.68em rather than 9.69em and
     3.28em. */
  max-width: 9em;
  margin: 20px 0 0;
  font-size: clamp(2.4rem, 4.6vw, 4.8rem);
  font-weight: 520;
  letter-spacing: -.055em;
  line-height: .98;
}
.audience-list { margin: 84px 0 0; padding: 0; list-style: none; border-top: 1px solid var(--hairline); }
.audience-list li {
  display: grid;
  grid-template-columns: minmax(0, .4fr) minmax(0, 1fr);
  align-items: baseline;
  gap: 48px;
  padding: 36px 0;
  border-bottom: 1px solid var(--hairline);
}
.audience-list h3 { margin: 0; font-size: 1.55rem; font-weight: 540; letter-spacing: -.04em; }
.audience-list p { max-width: 640px; margin: 0; color: var(--muted); }

.pilot-cta {
  position: relative;
  min-height: 72svh;
  display: grid;
  place-items: center;
  overflow: hidden;
  text-align: center;
}
/* The three concentric rings that used to sit here are now the dot grid on the
   canvas above. Same composition, same job of holding the eye at the button,
   drawn in the page's own material instead of in borrowed circles. */
.pilot-dots { position: absolute; inset: 0; z-index: 0; display: block; width: 100%; height: 100%; pointer-events: none; }
.pilot-cta-inner { position: relative; z-index: 1; max-width: 900px; padding: 90px 24px; }
.pilot-cta h2 { margin: 20px 0 24px; font-size: clamp(3.5rem, 8.6vw, 8.5rem); font-weight: 540; letter-spacing: -.075em; line-height: .86; }
.pilot-cta p:not(.section-label) { max-width: 520px; margin: 0 auto 32px; color: var(--muted); font-size: 1.1rem; }

.site-footer {
  display: grid;
  width: var(--page);
  min-height: 150px;
  margin: 0 auto;
  padding: 32px 0;
  align-items: end;
  border-top: 1px solid var(--hairline);
  grid-template-columns: 1fr auto 1fr;
  gap: 30px;
  color: var(--muted);
  font-size: .875rem;
}
.site-footer > a { display: inline-flex; min-height: 44px; align-items: center; color: var(--paper); font-weight: 650; }
.site-footer p { margin: 0; }
.site-footer nav { display: flex; justify-content: end; gap: 18px; }
.site-footer a:hover { color: var(--paper); }
.site-footer nav a { display: inline-flex; min-height: 44px; align-items: center; }

[data-reveal] { opacity: 0; transform: translateY(34px); clip-path: inset(0 0 16% 0); transition: opacity .9s var(--ease-out), transform .9s var(--ease-out), clip-path 1s var(--ease-out); }
[data-reveal].is-visible { opacity: 1; transform: none; clip-path: inset(0); }
[data-reveal-delay="1"] { transition-delay: .12s; }
[data-reveal-delay="2"] { transition-delay: .22s; }
[data-reveal-delay="3"] { transition-delay: .32s; }

.page-intro, .legal, .not-found { width: min(92vw, 960px); min-height: 58svh; margin: 0 auto; padding: 180px 0 80px; }
.page-intro h1, .legal h1, .not-found h1 { margin: 18px 0 24px; font-size: clamp(3.4rem, 8vw, 8rem); font-weight: 540; letter-spacing: -.07em; line-height: .9; }
.page-intro > p:last-child, .legal p, .not-found p { max-width: 620px; color: var(--muted); font-size: 1.1rem; }
form { width: min(92vw, 760px); margin: 0 auto 140px; }
form label { display: block; margin: 24px 0 9px; color: var(--muted); font-size: .9rem; }
form input, form select, form textarea { width: 100%; min-height: 54px; padding: 14px 16px; color: var(--paper); border: 1px solid var(--hairline); border-radius: var(--radius-sm); outline: 0; background: var(--ink-1); }
form textarea { resize: vertical; }
form input:focus, form select:focus, form textarea:focus { border-color: rgba(255,255,255,.55); box-shadow: 0 0 0 4px rgba(255,255,255,.06); }
form button { min-height: 52px; margin-top: 28px; padding: 0 22px; color: var(--ink-0); border: 0; border-radius: 999px; background: var(--paper); font-weight: 650; }
.honeypot { position: absolute; left: -9999px; }
#release-panel { width: min(92vw, 1120px); margin: 0 auto 140px; padding: 30px; border: 1px solid var(--hairline); border-radius: var(--radius-md); background: var(--ink-1); }
#download-link { display: inline-flex; min-height: 44px; align-items: center; }
.not-found a { display: inline-flex; min-height: 44px; align-items: center; margin-top: 22px; border-bottom: 1px solid var(--hairline-strong); }

/* The two interior form pages were authored against a layout that was never
   written. .page-shell, .surface-card, .context-card and every .form-* and
   .field-* class below had no rules at all, so the fields fell back to the
   bare element defaults above, the name/company and role/email pairs stacked
   instead of pairing, and the aside — unstyled and full width — sat on the
   viewport edge with its numbers running straight into its text.
   Neither page is wrapped in a card: the inputs already carry their own
   surface in --ink-1, so a bordered box around them would be a card holding
   cards. The structure is the page's hairlines, the same as the landing. */

/* The intro is the same document as the shell under it, so it takes the same
   width and the same left edge. Without this it stays at its shared 960px and
   the heading sets off 116px to the right of the form it introduces. */
.interior-page .page-intro { width: min(92vw, 1120px); min-height: 0; padding: 168px 0 72px; }
.interior-page .page-intro h1 { font-size: clamp(3rem, 6.4vw, 6.4rem); }

.page-shell {
  display: grid;
  width: min(92vw, 1120px);
  margin: 0 auto;
  padding-bottom: clamp(90px, 12vw, 170px);
  align-items: start;
  grid-template-columns: minmax(0, 1fr) minmax(260px, .48fr);
  gap: clamp(44px, 6vw, 96px);
}
/* The shared rule caps every form at 760px and centres it. In a grid track that
   is narrower than that the form would overflow its own column. */
.page-shell form { width: auto; margin: 0; }

.form-heading { margin-bottom: 38px; }
.form-heading h2 { margin: 14px 0 0; font-size: clamp(1.8rem, 2.9vw, 2.7rem); font-weight: 520; letter-spacing: -.05em; line-height: 1.02; }

.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 28px; }
.form-field { min-width: 0; }
.form-field--full { grid-column: 1 / -1; }
/* The shared label rule carries a 24px top margin for forms whose fields are
   siblings. Inside the grid the row gap is the spacing, so it double-counts. */
.form-field label { margin: 0 0 9px; }

.field-hint { margin: 9px 0 0; color: var(--dim); font-size: .84rem; line-height: 1.45; }
/* --signal was declared and never spent. An invalid field is what an accent is
   for, and on this near-black ground the orange reads as a warning where a red
   pulled from nowhere would read as an off-palette mistake. */
.field-error { margin: 8px 0 0; color: var(--signal); font-size: .84rem; line-height: 1.45; }
.field-error:empty { display: none; }
.form-field input[aria-invalid="true"], .form-field select[aria-invalid="true"] { border-color: var(--signal); }

.form-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 18px 26px; margin-top: 36px; }
.form-actions button { margin-top: 0; }
.form-actions p { max-width: 360px; margin: 0; color: var(--dim); font-size: .84rem; line-height: 1.45; }
.form-status { margin: 18px 0 0; color: var(--muted); }
.form-status:empty { display: none; }
/* The status line is the one place either page speaks in a sentence, so a state
   has to be legible at a glance. --signal is the accent the field errors already
   use, so a rejected submit and the field behind it read as one message. */
.form-status[data-state="error"] { color: var(--signal); }
.form-status[data-state="pending"] { color: var(--dim); }
.form-status[data-state="sent"] { color: var(--paper); }

/* Sticky because the application form is around 1200px tall: without it the
   process note has scrolled away by the time the applicant reaches the last
   field, which is exactly when they want to check what happens next. */
.context-card { position: sticky; top: 104px; }
.context-card h2 { margin: 14px 0 0; font-size: clamp(1.45rem, 2.1vw, 2rem); font-weight: 520; letter-spacing: -.045em; line-height: 1.04; }
.context-card ol { margin: 30px 0 0; padding: 0; list-style: none; border-top: 1px solid var(--hairline); }
.context-card li { display: grid; padding: 16px 0; border-bottom: 1px solid var(--hairline); color: var(--muted); font-size: .95rem; line-height: 1.45; grid-template-columns: 30px minmax(0, 1fr); gap: 12px; }
.context-card li span { color: var(--dim); font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: .75rem; line-height: 1.9; }
/* :not(.section-label) because the trailing note is the last child on the
   pilot page but the second-to-last on the download page, where a link follows
   it. Keying off :last-child would have styled the two differently. */
.context-card > p:not(.section-label) { margin: 20px 0 0; color: var(--dim); font-size: .9rem; }
.context-card > a { display: inline-flex; min-height: 44px; align-items: center; margin-top: 14px; border-bottom: 1px solid var(--hairline-strong); font-size: .95rem; }
.context-card > a span { margin-left: 8px; }

/* The release panel is the one thing on either page that is a genuine panel:
   a separate state revealed after access is confirmed, not a wrapper around
   other content. Its own shell was styled; everything inside it was not. */
.release-header { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 20px; }
.release-header h2 { margin: 12px 0 0; font-size: clamp(1.5rem, 2.4vw, 2.1rem); font-weight: 530; letter-spacing: -.045em; }
.release-meta { display: grid; margin: 32px 0 0; padding: 24px 0; border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }
.release-meta dt { color: var(--dim); font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: .72rem; }
.release-meta dd { margin: 8px 0 0; font-size: 1.05rem; }
.release-copy { display: grid; margin-top: 28px; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px; }
.release-copy h3 { margin: 0 0 10px; font-size: 1rem; font-weight: 620; }
.release-copy p { margin: 0; color: var(--muted); font-size: .95rem; }

@media (max-width: 900px) {
  .site-header { min-height: 58px; padding-inline: 16px; }
  .nav-toggle { display: inline-flex; align-items: center; justify-content: center; }
  .primary-nav { position: fixed; top: 66px; left: 4vw; right: 4vw; display: grid; visibility: hidden; padding: 12px; border: 1px solid var(--hairline); border-radius: 22px; background: rgba(11,12,13,.94); box-shadow: 0 24px 60px rgba(0,0,0,.36); opacity: 0; pointer-events: none; transform: translateY(-10px); transition: opacity .22s ease, transform .22s ease, visibility 0s linear .22s; backdrop-filter: blur(24px); }
  .primary-nav a { padding: 0 16px; }
  .nav-open .primary-nav { visibility: visible; opacity: 1; pointer-events: auto; transform: none; transition-delay: 0s; }
  .hero-content { grid-template-columns: 1fr; gap: 46px; }
  .interior-page .page-intro { padding: 132px 0 52px; }
  .page-shell { grid-template-columns: 1fr; gap: 52px; }
  .context-card { position: static; }
  .form-grid { grid-template-columns: 1fr; }
  .release-meta, .release-copy { grid-template-columns: 1fr; }
  .hero-glow { background: radial-gradient(circle at 50% 27%, rgba(255, 255, 255, .06), transparent 58%); }
  .hero-aside { justify-items: start; }
  /* Single column: the globe sits behind the copy, so dissolve it well above
     the headline instead of letting dots run through the type. */
  .hero-wash { background: linear-gradient(180deg, rgba(9, 10, 11, .05), rgba(9, 10, 11, .92) 26%, var(--ink-0) 38%); }
  .section-intro, .product-body { grid-template-columns: 1fr; }
  .audience-list li { grid-template-columns: 1fr; gap: 12px; padding: 28px 0; }
  .capability-grid { grid-template-columns: repeat(2, 1fr); }
  .capability:nth-child(3n) { border-right: 1px solid var(--hairline); }
  .capability:nth-child(2n) { border-right: 0; }
  .workflow-list li { grid-template-columns: 54px 1fr; padding: 28px 0; }
  .workflow-list li p { grid-column: 2; }
}

@media (max-width: 620px) {
  .hero-content { min-height: 100svh; padding: 140px 0 44px; }
  .hero h1 { font-size: clamp(3.8rem, 19vw, 6rem); }
  .hero-lede { max-width: 90%; }
  .hero-aside { justify-items: start; }
  .hero-meta { gap: 12px; }
  .section { padding: 90px 0; }
  .section-heading { font-size: clamp(2.75rem, 14vw, 4.4rem); }
  .section-intro { gap: 24px; }
  .product-window { border-radius: 12px 0 0 12px; }
  /* Portrait crop of a landscape capture: anchoring the left edge keeps the
     app's own search field and filters in the frame, with the map and its pins
     falling away to the right. */
  .product-image-wrap { aspect-ratio: .92; }
  .product-image-wrap img { object-position: left center; }
  .capability-grid { grid-template-columns: 1fr; }
  .capability, .capability:nth-child(3n) { min-height: 225px; border-right: 0; }
  .audience-heading { font-size: clamp(2.1rem, 9vw, 3rem); }
  .audience-list { margin-top: 56px; }
  .site-footer { grid-template-columns: 1fr; align-items: start; }
  .site-footer nav { justify-content: start; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  [data-reveal] { opacity: 1; transform: none; clip-path: none; }
}
