/* Hero: the drone video filling the first screen, shading overlay (the film grain is page-wide, base.css), the headline over it, and the
   dark gradient the first scroll fades into (--dive, --dive-dark on :root). */
.hero {
  position: relative;
  height: 100vh;
  height: 100svh;
  overflow: clip;
}

/* the video is shown mirrored at its native frames, cropped to cover the screen (on phones held upright, smaller and faded out at its
   edges, see below), over its poster, which shows through until the first frame is drawn and stays when the video never plays (reduced
   motion, no autoplay) */
:is(.hero-video, .hero-poster img) {
  position: absolute;
  scale: -1 1;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.shade {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* the bottom edge runs into the page colour, so the features section below (plain --bg) joins it without a seam; phones also run the
     top edge into it (--shade-edge, below) */
  background:
    var(--shade-edge, none),
    linear-gradient(to top, var(--bg) 0%, transparent 22%),
    radial-gradient(ellipse 68% 62% at 62% 38%, transparent 22%, var(--vignette) 100%),
    linear-gradient(to bottom, rgba(var(--shade), .9) 0%, rgba(var(--shade), 0) 32%),
    linear-gradient(to top, rgba(var(--shade), .96) 0%, rgba(var(--shade), 0) 46%),
    linear-gradient(to right, rgba(var(--shade), .92) 0%, rgba(var(--shade), 0) 52%);
}

/* the darkness the first scroll fades into (--dive-dark on :root, from core/scroll-dive.js): a dark gradient rising from the bottom of the
   screen until it covers it; the image is three screens tall (clear, fade, solid) and slides up from its clear third to its solid one.
   Fixed and over the features section (z-index 2), so it still covers the screen while the page lands there and then sinks back down
   off it, and rises over it again before the page goes back to the hero; clear at every other time. As tall as the screen with the
   browser bars hidden (lvh), so it also covers the strip behind Safari's see-through bottom bar, which inset: 0 stops short of */
.blackout {
  position: fixed;
  inset: 0 0 auto;
  height: 100vh;
  height: 100lvh;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(transparent 33.3%, var(--bg) 66.7%) 0 calc(var(--dive-dark, 0) * 100%) / 100% 300% no-repeat;
}

/* phones never run the dive (hero.js), so nothing writes --dive-dark there and this layer would only sit over the page doing nothing:
   iPhone Safari leaves the foot of it unpainted and the section below showed through that strip */
@media (max-width: 760px) {
  .blackout { display: none; }
}

/* headline with the key figures over it: pinned to the bottom of the first screen, fades out as the transition starts */
.copy {
  position: absolute;
  z-index: 2;
  top: 0;
  left: var(--gutter);
  right: var(--gutter);
  height: 100vh;
  height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  /* on phones the headline sits under the header (its top inset plus the 44px logo, site-header.css) and the figures at the bottom */
  padding-top: calc(max(28px, env(safe-area-inset-top)) + 44px + 28px);
  padding-bottom: max(40px, env(safe-area-inset-bottom));
  container-type: inline-size;
  /* the headline's font size: on phones it breaks into "SENTRY" over "10D", and "SENTRY" is 6.577em wide in the display face at its
     letter-spacing, so it spans exactly the gutter-to-gutter width */
  --title-em: calc(100cqw / 6.577);
}

/* wider screens: one line, "SENTRY - 10D" is 10.685em wide; the key figures' dividers are placed in the same unit */
@media (min-width: 761px) {
  /* the navy shading reaches further over the video: from the top, the bottom and the left, and the vignette from closer in */
  .shade {
    background:
      linear-gradient(to top, var(--bg) 0%, transparent 22%),
      radial-gradient(ellipse 68% 62% at 62% 38%, transparent 12%, var(--vignette) 100%),
      linear-gradient(to bottom, rgba(var(--shade), .9) 0%, rgba(var(--shade), 0) 40%),
      linear-gradient(to top, rgba(var(--shade), .96) 0%, rgba(var(--shade), 0) 56%),
      linear-gradient(to right, rgba(var(--shade), .92) 0%, rgba(var(--shade), 0) 64%);
  }

  .copy {
    padding-top: 0;
    --title-em: calc(100cqw / 10.685);
  }
}

.copy > * { opacity: calc(1 - var(--dive, 0) * 6); }

/* phones leave the hero by scrolling, so the headline and its figures fade over the first half screen of it instead (page-leave in
   base.css). On the container, so the entrance animation below keeps the children to itself; without scroll timelines it just scrolls away */
@media (max-width: 760px) {
  @supports (animation-timeline: scroll()) {
    @media (prefers-reduced-motion: no-preference) {
      .copy {
        animation: page-leave linear both;
        animation-timeline: scroll(root block);
        animation-range: 0 50vh;
      }
    }
  }
}

/* the entrance: as the splash lifts (its data-state turns ready, splash.js) the headline rises in, then the figures under it. Only the
   animation's start is filled (backwards), so once it ends the scroll fade above takes the opacity back; without the splash script or
   under reduced motion the text simply stands */
@media (prefers-reduced-motion: no-preference) {
  :root:has(.splash[data-state="ready"]) .copy > * { animation: hero-in .9s cubic-bezier(.2, .7, .2, 1) .15s backwards; }
  :root:has(.splash[data-state="ready"]) .copy > .hero-stats { animation-delay: .45s; }
}

@keyframes hero-in {
  from { opacity: 0; translate: 0 24px; }
}

.copy h1 {
  margin: 0 0 auto;
  font: 800 var(--title-em)/.95 var(--font-display);
  font-synthesis: none;
  letter-spacing: .06em;
  white-space: nowrap;
  text-transform: uppercase;
}

/* on phones the headline is two lines, "10D" set right over "SENTRY"; the dash becomes the break (it stays in the text, so the heading
   still reads "Sentry - 10D") */
.copy h1 {
  display: flex;
  flex-direction: column-reverse;
}

.hero-model { align-self: flex-end; }

.hero-dash {
  display: block;
  height: 0;
  overflow: hidden;
}

/* the display face's hyphen is short and tight; spacing keeps "SENTRY-10D" from reading as one word */
@media (min-width: 761px) {
  /* the line box hangs .193em below the capitals' baseline; pulling it in sets the letters themselves on the bottom inset, a step
     wider than the header's top inset */
  .copy h1 {
    display: block;
    margin: 0 0 -.193em;
  }

  .hero-dash {
    display: inline;
    height: auto;
    overflow: visible;
    margin-inline: .08em;
  }
}

/* key figures: a list, each value with its label beside it on one baseline; from tablets up shown above the headline (it stays first in
   the markup) */
.hero-stats {
  margin: 24px 0 0;
  display: grid;
  gap: 12px;
}

/* on phones the figures sit under the headline, split by hairlines; the value column fits the widest value, "up to 500 m", in
   --text-figure */
.hero-stats div {
  display: grid;
  grid-template-columns: 9.5rem 1fr;
  align-items: baseline;
}

.hero-stats div + div {
  padding-top: 12px;
  border-top: 1px solid var(--line-strong);
}

@media (min-width: 761px) {
  .hero-stats {
    order: -1;
    margin: 0 0 20px;
    gap: 8px;
  }

  .hero-stats div { grid-template-columns: 7.5rem 1fr; }

  .hero-stats div + div {
    padding-top: 0;
    border-top: 0;
  }
}

.hero-stats dd {
  grid-area: 1 / 1;
  margin: 0;
  font-size: var(--text-figure);
  font-weight: 500;
  line-height: 1.1;
  white-space: nowrap;
}

.hero-stats dt {
  grid-area: 1 / 2;
  font-size: var(--text-detail);
  line-height: 1.3;
  color: var(--mute);
  text-wrap: balance;
}

/* on wide screens three columns, value over label, split by hairlines over the middles of the headline's letters: E at 1.59em and
   T at 3.768em; every label breaks into two lines at its span */
@media (min-width: 1024px) {
  .hero-stats {
    margin-bottom: 32px;
    gap: 0;
    grid-template-columns: calc(var(--title-em) * 1.59) calc(var(--title-em) * 2.178) max-content;
  }

  .hero-stats div {
    display: flex;
    flex-direction: column-reverse;
    justify-content: flex-end;
    gap: 8px;
    padding-left: clamp(20px, 2vw, 32px);
    border-left: 1px solid var(--line-strong);
  }

  .hero-stats div:first-child { padding-left: 0; border-left: 0; }

  .hero-stats dt { white-space: nowrap; }

  .hero-stats dt span { display: block; }
}

/* phones held upright: at the bottom of the first screen the headline, "10D" set right over "SENTRY" spanning the gutters (the dash stays
   for screen readers only), then the figures. Each label stands across from its value in two lines broken at its span, the labels lined
   up under the headline's T (3.23em into the 6.577em "SENTRY": 49.11% across) and the values indented --indent from the left edge. The
   widest value (5.8em) fits its column with a little to spare, up to 26px; the labels are sized so the widest line, "with 1.5 kg payload"
   (9.201em), ends a little short of the Y of "SENTRY": sized for 9.455em into its column (50.89% across) less the headline's trailing
   .06em letter-spacing, halfway between the old 18px labels and a line reaching the Y */
@media (orientation: portrait) and (max-width: 760px) {
  /* the whole landscape frame, 1.85 screens wide with the drone (55% across the mirrored frame) a touch left of centre, centred in the space
     between the header (72px) and the top of "10D" (the headline block with its one figure is about 196px at the bottom), its edges fading
     into the page so the frame's borders never show. The fade is a layer in the page colour laid over the same box (the hero's ::after,
     painted over the video and under the shade), not a mask: iOS Safari can stop drawing a masked <video> */
  :is(.hero-video, .hero-poster img), .hero::after {
    inset: auto;
    top: calc(50svh - 62px);
    left: 50%;
    width: 185%;
    height: auto;
    aspect-ratio: 16 / 9;
    translate: -57% -50%;
  }

  .hero::after {
    --fade: var(--bg), transparent 22%, transparent 78%, var(--bg);
    content: '';
    position: absolute;
    pointer-events: none;
    /* the footage opens on a dark band up to about 13% of the frame tall, so from the top the fade stays solid to just short of it
       and clears soon after, leaving no edge where the picture starts */
    background: linear-gradient(to right, var(--fade)), linear-gradient(var(--bg) 12%, transparent 30%, transparent 78%, var(--bg));
    /* a touch larger than the video, so its outermost pixel rows don't show where the box lands between device pixels */
    box-shadow: 0 0 0 1px var(--bg);
    scale: 1.01;
  }

  /* the last label's baseline sits as far above the bottom as the header's logo sits below the top (its top inset); the figures pull
     the .327em of label size their last line box hangs below the baseline into that inset (margin below) */
  .copy {
    padding-top: 0;
    padding-bottom: max(28px, env(safe-area-inset-bottom));
  }

  /* the screen's top edge is the page colour, fading into the shading under the header, so it joins the black above the page (the
     status bar, and the area Safari shows when the page is pulled down) without a seam */
  .shade { --shade-edge: linear-gradient(var(--bg), transparent 12%); }

  .copy h1 { margin: 0; }

  /* "10D" smaller than "SENTRY", right-aligned over it, the stem of its 1 standing on the stem of the R: "10D" runs 2.6em of its own
     size from the 1's stem to its right end, and the R's stem starts 2.192em short of the right end of "SENTRY": 2.192 / 2.6 */
  .hero-model { font-size: .843em; }

  .hero-dash {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .hero-stats {
    --indent: 8px; /* --text-figure (tokens.css) is fitted to it */
    margin: 20px 0 calc(-.327 * var(--text-detail));
    padding-top: 12px;
    border-top: 1px solid var(--line-strong);
    container-type: inline-size;
    grid-template-columns: calc(100cqw * .4911 - 24px) 1fr;
    column-gap: 24px;
  }

  .hero-stats div {
    grid-column: 1 / -1;
    grid-template-columns: subgrid;
  }

  .hero-stats dt span { display: block; }

  .hero-stats dd { padding-left: var(--indent); }

  /* one figure at a time under a hairline below the headline: the three share one row and take turns in the same place, each rising in,
     holding and lifting out over a third of --cycle; under reduced motion they stay listed one under another */
  @media (prefers-reduced-motion: no-preference) {
    .hero-stats { --cycle: 7.5s; }

    .hero-stats div {
      grid-row: 1;
      opacity: 0;
      animation: hero-stat-turn var(--cycle) ease-in-out infinite both;
    }

    .hero-stats div + div {
      padding-top: 0;
      border-top: 0;
    }

    .hero-stats div:nth-child(2) { animation-delay: calc(var(--cycle) / 3); }
    .hero-stats div:nth-child(3) { animation-delay: calc(var(--cycle) * 2 / 3); }
  }
}

@keyframes hero-stat-turn {
  0% { opacity: 0; translate: 0 10px; }
  6%, 27% { opacity: 1; translate: 0 0; }
  33.3%, 100% { opacity: 0; translate: 0 -10px; }
}
