/* ============================================================
   home.css  ·  Skybourne homepage
   Loaded AFTER styles.css, which still owns the shared chrome
   (nav pill, footer, contact modal, buttons) and the :root palette.
   This file owns the seven homepage sections only.

   The page is one continuous sunrise. It opens mid-incident in the
   dark and ends in ordinary morning daylight. Section order is the
   argument, so do not reorder without re-reading the copy.
   ============================================================ */

:root {
    /* Night end of the arc. --accent (#ff6a00) comes from styles.css. */
    --hp-void:   #04060a;
    --hp-panel:  #080a0d;
    --hp-line:   rgba(255, 255, 255, 0.09);
    --hp-line-2: rgba(255, 255, 255, 0.16);
    --hp-muted:  #8a93a0;
    --hp-dim:    #5a6270;
    --hp-ember:  #ffa05a;
    --hp-hot:    #ff3b30;

    /* Dawn end of the arc. */
    --hp-paper:  #f2efe9;
    --hp-ink:    #0d1014;
    --hp-ink-2:  #4e5661;

    /* Telemetry / label face. System stack on purpose: a webfont here
       would cost a render-blocking request for text that is decorative. */
    --hp-mono: ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, Consolas, monospace;

    /* Motion. styles.css hand-typed this curve four separate times. */
    --hp-ease: cubic-bezier(0.22, 1, 0.36, 1);
    --hp-dur:  0.7s;

    /* Vertical rhythm. */
    --hp-pad-y: clamp(5.5rem, 13vh, 9rem);
}

/* ---------- shared section furniture ---------- */

.hp-wrap {
    max-width: var(--content-w);
    margin: 0 auto;
    padding: 0 var(--gutter);
}

.hp-eyebrow {
    font-family: var(--hp-mono);
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--accent);
}

.hp-h2 {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(2rem, 4.4vw, 3.5rem);
    letter-spacing: -0.035em;
    line-height: 1.04;
    margin-top: 1.1rem;
    max-width: 18ch;
}

.hp-lede {
    font-size: clamp(1rem, 1.15vw, 1.19rem);
    line-height: 1.62;
    color: var(--hp-muted);
    max-width: 52ch;
    margin-top: 1.4rem;
}

/* Reveal-on-scroll. Matches the .in idiom already used by styles.css
   so both systems stay legible to the next person reading this. */
.hp-rise {
    transition: opacity var(--hp-dur) var(--hp-ease),
                transform var(--hp-dur) var(--hp-ease);
}
/* Hidden pre-reveal state applies ONLY when the reveal script is live
   (html.js is set inline before paint). If home.js never runs, the
   content stays fully visible instead of leaving the page black. */
.js .hp-rise { opacity: 0; transform: translateY(22px); }
.hp-rise.in { opacity: 1; transform: none; }
.hp-rise.d1 { transition-delay: 0.08s; }
.hp-rise.d2 { transition-delay: 0.16s; }
.hp-rise.d3 { transition-delay: 0.24s; }
.hp-rise.d4 { transition-delay: 0.32s; }

/* ============================================================
   01  HERO  ·  night, mid incident
   Keeps the existing drone video bed. The dispatch strip and the
   two racing counters are the new layer on top.
   ============================================================ */

.hp-hero {
    position: relative;
    min-height: 100svh;
    display: flex;
    align-items: flex-end;
    overflow: hidden;
    background: var(--hp-void);
}

/* The plate is placed, not stretched.
   inset:0 + object-fit:cover was wrong for this content. Cover guarantees the
   frame is filled and guarantees nothing about what stays inside it: it scales
   to whichever axis is short and crops the other from the centre, so the only
   viewport aspect where the composition held was the one the padding had been
   cut for. Any window wider than that clipped the beacons under the nav bar.
   Here the width, the ceiling on height and the distance below the nav are all
   stated outright, so the aircraft is whole and centred at every size and the
   copy always has clean ground beneath it. Letterboxing costs nothing because
   the plate's background and the page are the same black. */
.hp-hero-plate {
    position: absolute;
    /* Right half, vertically centred, bleeding slightly past the edge so
       it reads as a photographed object in the frame rather than a
       picture pasted into a slot. The copy owns the left column, which
       is why .hp-hero .hp-wrap caps its width below. */
    right: -2.5vw;
    top: 47%;
    transform: translateY(-50%);
    width: min(1180px, 60vw);
    height: auto;
    max-height: 74svh;
    object-fit: contain;
    /* No filter. Every previous value here existed to rescue a clip that was
       not graded for this slot: 0.86 saturation for drone_zoom, then 1.08 for
       the siren's blue-and-red flanks. This is a finished studio plate,
       already contrasty and already sitting on pure black, so any correction
       applied on top only moves it away from what was approved. */
    filter: none;
}

/* ---- Hero carrying the launch clip -------------------------------------
   Two columns of ONE grid, both inside .hp-wrap.

   The absolute-plate treatment above cannot be reused here and the reason is
   structural, not cosmetic. .hp-hero is align-items: flex-end, so the copy is
   pinned to the floor of the section while an absolutely positioned plate is
   centred on it. Nothing connects the two: the clip drifts up behind the
   floating header, the copy sits at the bottom, and the middle of the hero is
   dead space. Putting both in a grid gives them a shared left edge, a shared
   centre line and a shared max width, and there is no offset left to guess.

   The clip is also a FRAMED PANEL rather than a bleed. The studio plate was a
   cut-out on pure black and could run off the edge invisibly. This clip is a
   lit scene, bright lid top left and lit floor along the bottom, so any edge
   it has is visible. An edge that cannot be hidden gets drawn on purpose. */
.hp-hero.has-clip { align-items: stretch; }
.hp-hero.has-clip .hp-wrap {
    /* Clears the floating header outright instead of hoping the art does. */
    padding-top: clamp(7.5rem, 15vh, 10rem);
    padding-bottom: clamp(3rem, 7vh, 5rem);
}
/* FULL BLEED. The clip is the hero: it fills the viewport and the copy sits
   on top of it. The two-column grid this replaced framed the clip in a panel
   beside the copy, which is the layout Naman rejected for the full-screen
   video. width:100% because the grid is now a flex child of .hp-hero and
   would otherwise shrink to its content. */
.hp-hero-grid {
    display: block;
    position: relative;
    width: 100%;
    height: 100svh;
}
/* Kills `.hp-hero .hp-wrap > * { max-width: 54% }` further down this file.
   That cap exists to stop the copy running under an absolutely positioned
   plate at 60vw. There is no such plate now, and applied to a grid child it
   shrinks BOTH columns to just over half their track: the headline broke to
   three lines and the clip rendered at 322px inside a 596px column with the
   difference showing as dead space on either side. */
.hp-hero.has-clip .hp-wrap > * { max-width: none; }
/* The copy overlays the clip, pinned bottom left. It sits left of the
   aircraft and below its climb, so the power-on and the lift read clean; the
   box the aircraft rises out of is the part the copy covers, which Naman said
   was fine to lose. z-index 2 clears the scrim. */
.hp-hero-copy {
    position: absolute;
    /* A low horizontal band across the bottom, not a tall stack in the
       corner. left AND right are set so the block runs wide and the headline
       lays out on one line; the whole upper frame stays clear for the
       aircraft's climb. */
    left: clamp(1.5rem, 5vw, 4rem);
    right: clamp(1.5rem, 5vw, 4rem);
    bottom: clamp(2.5rem, 7vh, 4.5rem);
    z-index: 2;
}
/* The clip fills the frame: absolute, inset 0, cover. No panel shadow now
   that there is no panel; the brackets move to the viewport corners so the
   whole screen reads as the instrument, not a card sitting on it. */
/* Selector is .hp-hero-grid .hp-hero-slot, not bare .hp-hero-slot, ON PURPOSE.
   The figure carries two classes, .hp-slot and .hp-hero-slot. The generic
   .hp-slot further down this file sets position:relative, and at equal
   specificity the later rule won, so the clip was never actually absolute:
   it sat in flow at its own 16:9 height. On a wide desktop 16:9 is ~810px and
   nearly fills the 900px hero, so it read as full bleed by accident; on a
   375-wide phone 16:9 is only 211px, a thin band under the nav with a tall
   black gap beneath it before the copy. The descendant selector raises
   specificity so absolute + inset:0 win and the clip truly fills the frame at
   every width. */
.hp-hero-grid .hp-hero-slot {
    position: absolute;
    inset: 0;
    margin: 0;
    box-shadow: none;
}
.hp-hero-slot .hp-slot-media {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.hp-hero-slot .hp-slot-c { width: 24px; height: 24px; }
.hp-hero-slot .hp-slot-c.tl { top: 24px; left: 24px; }
.hp-hero-slot .hp-slot-c.tr { top: 24px; right: 24px; }
.hp-hero-slot .hp-slot-c.bl { bottom: 24px; left: 24px; }
.hp-hero-slot .hp-slot-c.br { bottom: 24px; right: 24px; }
/* The strip spans both columns and closes the bottom of the hero, which was
   a third of a viewport of black. */
.hp-hero-grid > .hp-strip { grid-column: 1 / -1; }
@media (max-width: 760px) {
    /* Still full bleed on a phone: the clip fills the screen, the copy stays
       a bottom band. The headline is allowed to wrap here because there is no
       width to hold it on one line.

       The selector is .hp-hero.has-clip h1, not .hp-hero h1, ON PURPOSE. The
       base rule further down this file (`.hp-hero h1 { white-space: nowrap }`)
       sits AFTER this block in source order, so at equal specificity it won
       the cascade and the headline stayed nowrap on phones, so the em ran
       off the right edge. The extra class raises specificity so the wrap
       takes. The em is named explicitly for the same reason: white-space
       inherits, but stating it removes any doubt. Result on a 375 phone:
       "Risk the aircraft." on line one, the ember "Not the crew." on its own
       line two. */
    .hp-hero.has-clip h1 { white-space: normal; }
    /* "Not the crew." is the emphatic payoff, so give it its own line rather
       than letting the wrap fall mid-phrase ("Not the / crew."). display:block
       drops the ember line intact beneath "Risk the aircraft.", and because it
       keeps white-space normal it still wraps inside itself on a very narrow
       screen instead of running off the edge. */
    .hp-hero.has-clip h1 em { white-space: normal; display: block; }
    /* The dispatch eyebrow is a letter-spaced 38-character string. At desktop
       size it rides one line; at 375 the tracking pushed its tail ("RESCUE")
       past the viewport and it clipped. Pull the size and tracking in so it
       holds one clean line on a normal phone, and let it wrap instead of clip
       on anything narrower. */
    .hp-hero-copy .hp-dispatch {
        flex-wrap: wrap;
        font-size: 0.6rem;
        letter-spacing: 0.16em;
    }
}

/* Side by side needs width. Below 1000px there is none, so the plate
   goes back to a band across the top with the copy beneath it. */
@media (max-width: 1000px) {
    .hp-hero-plate {
        right: auto;
        left: 50%;
        top: clamp(5rem, 10vh, 7rem);
        transform: translateX(-50%);
        width: min(760px, 94vw);
        max-height: 38svh;
    }
}

/* Two washes over the full-bleed clip. The 90deg band darkens the left third
   so the copy has ground to sit on without a plate behind it; the 180deg band
   seats the top under the floating header and sinks the bottom into the page
   black. Tuned to leave the aircraft and its climb (centre and upper frame)
   uncovered. z-index 1 so it is above the clip and below the copy. */
.hp-hero-scrim {
    position: absolute;
    inset: 0;
    z-index: 1;
    background:
        linear-gradient(90deg, rgba(3,5,9,0.9) 0%, rgba(3,5,9,0.4) 40%, rgba(3,5,9,0) 66%),
        linear-gradient(180deg, rgba(3,5,9,0.5) 0%, rgba(3,5,9,0) 28%, rgba(3,5,9,0) 50%, rgba(3,5,9,0.95) 100%);
}

.hp-hero .hp-wrap {
    position: relative;
    z-index: 2;
    width: 100%;
    padding-bottom: clamp(2.5rem, 6vh, 4rem);
    padding-top: 7rem;
}

/* The copy is capped so it cannot run under the aircraft on a wide
   screen. 54% is measured against the plate's left edge at 60vw minus
   the bleed, with the plate's own black margin as the buffer. */
@media (min-width: 1000px) {
    .hp-hero .hp-wrap > * { max-width: 54%; }
}

.hp-dispatch {
    display: inline-flex;
    align-items: center;
    gap: 0.7rem;
    font-family: var(--hp-mono);
    font-size: 0.7rem;
    letter-spacing: 0.24em;
    color: var(--accent);
    border-left: 2px solid var(--accent);
    padding-left: 0.85rem;
}

.hp-dispatch-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--hp-hot);
    box-shadow: 0 0 10px var(--hp-hot);
    animation: hpPulse 1.9s ease-in-out infinite;
}

@keyframes hpPulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%      { opacity: 0.35; transform: scale(0.8); }
}

/* Sized off the approved full-bleed demo, pulled in about seven percent so
   the headline clears more of the aircraft: the demo was
   clamp(2.8rem, 5.6vw, 5.2rem); this is 5 to 10 percent under it. 15ch holds
   it to two lines over the clip. */
.hp-hero h1 {
    font-family: var(--font-display);
    font-weight: 800;
    /* Smaller, and on ONE horizontal line at desktop widths. The tall
       stacked block Naman rejected came from a big font in a narrow column;
       this is a small font in a wide one. nowrap holds the single line;
       the mobile query below lets it wrap when there is no width for it. */
    font-size: clamp(1.8rem, 3.5vw, 3.25rem);
    letter-spacing: -0.04em;
    line-height: 1.06;
    white-space: nowrap;
    margin-top: 0.9rem;
}

.hp-hero h1 em {
    font-style: normal;
    color: var(--hp-ember);
}

.hp-hero .hp-lede { margin-top: 0.9rem; color: #b9c0ca; }

/* The two racing counters. This is the page's one live element:
   it runs on a clock, not on scroll, so the hero is never static. */
.hp-clock {
    position: absolute;
    right: var(--gutter);
    bottom: clamp(3rem, 8vh, 5.5rem);
    z-index: 3;
    text-align: right;
    border-right: 2px solid var(--accent);
    padding-right: 1.15rem;
}

.hp-clock-row + .hp-clock-row { margin-top: 1.1rem; }

.hp-clock-k {
    font-family: var(--hp-mono);
    font-size: 0.63rem;
    letter-spacing: 0.2em;
    color: var(--hp-dim);
}

.hp-clock-v {
    font-family: var(--hp-mono);
    font-weight: 700;
    font-size: clamp(1.6rem, 3vw, 2.7rem);
    letter-spacing: -0.03em;
    line-height: 1.05;
    font-variant-numeric: tabular-nums;
}

.hp-clock-v.slow { color: var(--hp-hot); }
.hp-clock-v.fast { color: var(--hp-ember); }

/* Halo's counter freezes when it arrives. The stopped state is the point. */
.hp-clock-v.landed { color: var(--hp-ember); }
.hp-clock-row.landed .hp-clock-k { color: var(--hp-ember); opacity: 0.75; }

/* ============================================================
   02  THE GAP  ·  the argument, as a race you have to wait through
   The signature animation. Scroll drives three bars. Halo's fills
   almost immediately and stops. The ground bar crawls for the rest
   of the section, so the visitor physically waits out the gap.
   ============================================================ */

.hp-gap {
    position: relative;
    background: var(--hp-void);
    border-top: 1px solid var(--hp-line);
}

/* Tall scroll track, pinned viewport inside it. */
.hp-gap-track  { height: 320vh; position: relative; }
.hp-gap-sticky {
    position: sticky;
    top: 0;
    height: 100svh;
    display: flex;
    align-items: center;
    overflow: hidden;
}

.hp-bars { margin-top: clamp(2.2rem, 5vh, 3.6rem); display: flex; flex-direction: column; gap: 1.5rem; }

.hp-bar-top {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 0.6rem;
    gap: 1rem;
}

.hp-bar-name {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: clamp(0.95rem, 1.3vw, 1.08rem);
}

.hp-bar-time {
    font-family: var(--hp-mono);
    font-size: clamp(0.85rem, 1.2vw, 0.98rem);
    color: var(--hp-muted);
    font-variant-numeric: tabular-nums;
}

.hp-bar-track {
    height: 13px;
    background: rgba(255, 255, 255, 0.06);
    position: relative;
    overflow: hidden;
}

.hp-bar-fill {
    position: absolute;
    inset: 0 auto 0 0;
    width: 0;
    background: linear-gradient(90deg, #4a515d, #8a93a0);
}

.hp-bar.is-halo .hp-bar-fill { background: linear-gradient(90deg, var(--accent), var(--hp-ember)); }
.hp-bar.is-halo .hp-bar-time { color: var(--hp-ember); }

/* Halo's bar gets a live head glow while it is moving. */
.hp-bar.is-halo .hp-bar-fill::after {
    content: '';
    position: absolute;
    right: 0; top: 0; bottom: 0;
    width: 26px;
    background: linear-gradient(90deg, rgba(255,160,90,0), var(--hp-ember));
}

/* No "ON SCENE" badge here. Each bar name already states its own event, so
   the badge read as redundant on the ground bar and as nonsense on the
   dispatch bar, which never goes anywhere. The arrival signal that matters
   is Halo's time locking to SUB-60S while the ground clock keeps running,
   and that is handled by data-done in home.js. */
.hp-bar.is-done .hp-bar-time { font-weight: 700; }

.hp-gap-note {
    margin-top: clamp(1.8rem, 4vh, 2.6rem);
    font-family: var(--hp-mono);
    font-size: 0.66rem;
    letter-spacing: 0.08em;
    line-height: 1.9;
    color: var(--hp-dim);
    text-transform: uppercase;
}

/* ============================================================
   03  THE AIRCRAFT  ·  learn this silhouette
   One transparent turntable frame, held big, with callout pins that
   deploy in sequence. The Halo page owns the 599 frame spin; the
   homepage deliberately does not repeat it.
   ============================================================ */

.hp-craft {
    position: relative;
    padding: var(--hp-pad-y) 0;
    background:
        radial-gradient(120% 80% at 68% 45%, rgba(255,106,0,0.14) 0%, rgba(255,106,0,0) 62%),
        var(--hp-panel);
    overflow: hidden;
}

/* The text column is deliberately narrow. "Learn this silhouette" only
   earns itself if the aircraft is the dominant object in the section, and
   the frame has a lot of transparent margin around the airframe, so the
   image has to run large to read at all. */
.hp-craft-grid {
    display: grid;
    grid-template-columns: minmax(280px, 360px) 1fr;
    gap: clamp(1.5rem, 3.5vw, 3rem);
    align-items: center;
}

/* Pull the render past the right gutter, into the section's own bleed. */
.hp-craft-grid .hp-shot { margin-right: calc(var(--gutter) * -1.4); }

.hp-specline { margin-top: 2.2rem; border-top: 1px solid var(--hp-line-2); }

.hp-specline div {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    padding: 0.8rem 0;
    border-bottom: 1px solid var(--hp-line);
    font-family: var(--hp-mono);
    font-size: 0.72rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}

.hp-specline span:first-child { color: var(--hp-dim); }
.hp-specline span:last-child  { text-align: right; }

.hp-shot { position: relative; }

.hp-shot img {
    width: 100%;
    display: block;
    filter: drop-shadow(0 40px 90px rgba(0, 0, 0, 0.9));
}

.hp-pin {
    position: absolute;
    font-family: var(--hp-mono);
    font-size: 0.63rem;
    letter-spacing: 0.16em;
    color: var(--text);
    white-space: nowrap;
    padding-left: 2.2rem;
    opacity: 0;
    transform: translateX(-8px);
    transition: opacity 0.5s var(--hp-ease), transform 0.5s var(--hp-ease);
}

.hp-shot.in .hp-pin { opacity: 1; transform: none; }
.hp-shot.in .hp-pin.p1 { transition-delay: 0.25s; }
.hp-shot.in .hp-pin.p2 { transition-delay: 0.45s; }
.hp-shot.in .hp-pin.p3 { transition-delay: 0.65s; }

.hp-pin::before {
    content: '';
    position: absolute;
    left: 0; top: 50%;
    width: 1.7rem; height: 1px;
    background: var(--accent);
}

.hp-pin::after {
    content: '';
    position: absolute;
    left: 0; top: 50%;
    width: 5px; height: 5px;
    margin: -2px 0 0 -2px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 10px var(--accent);
}

/* Pins that hang their label to the LEFT of the dot. Anchored with `right`
   so the dot, not the label edge, is what lands on the feature. */
.hp-pin.flip { padding: 0 2.2rem 0 0; }
.hp-pin.flip::before { left: auto; right: 0; }
.hp-pin.flip::after  { left: auto; right: -2px; }

/* Measured against turntable/f0179.webp: the aircraft occupies x 17..70%
   and y 41..69% of that frame, and it sits LEFT of centre. The first pass
   put these at 58..64%, which is open background to the right of the
   aircraft, so all three leader lines pointed at nothing. */
.hp-pin.p1 { right: 67%; top: 53%; }   /* forward sensor head */
.hp-pin.p2 { right: 70%; top: 67%; }   /* lower left duct */
.hp-pin.p3 { left: 55%;  top: 47%; }   /* arm, body to right motor */

/* ============================================================
   04  WHAT IT SEES  ·  mission POV
   ============================================================ */

.hp-pov { padding: var(--hp-pad-y) 0; background: var(--hp-void); }

.hp-povgrid {
    margin-top: clamp(2.2rem, 5vh, 3.4rem);
    display: grid;
    grid-template-columns: 1.55fr 1fr;
    gap: 1.1rem;
    align-items: stretch;
}

.hp-shotbox {
    position: relative;
    border: 1px solid var(--hp-line-2);
    overflow: hidden;
    background: #000;
    min-height: 180px;
}

.hp-shotbox img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.hp-tag {
    position: absolute;
    left: 0.8rem;
    top: 0.8rem;
    font-family: var(--hp-mono);
    font-size: 0.6rem;
    letter-spacing: 0.18em;
    background: rgba(4, 6, 10, 0.78);
    border: 1px solid var(--hp-line-2);
    padding: 0.35rem 0.6rem;
    color: var(--hp-ember);
    backdrop-filter: blur(6px);
}

.hp-povside { display: flex; flex-direction: column; gap: 1.1rem; }
.hp-povside .hp-shotbox { flex: 1; }

.hp-telemetry {
    margin-top: 1.3rem;
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    border-top: 1px solid var(--hp-line-2);
    border-bottom: 1px solid var(--hp-line-2);
}

.hp-telemetry > div {
    padding: 0.95rem 0.6rem;
    border-right: 1px solid var(--hp-line);
}
.hp-telemetry > div:last-child { border-right: 0; }

.hp-telemetry .k {
    font-family: var(--hp-mono);
    font-size: 0.57rem;
    letter-spacing: 0.18em;
    color: var(--hp-dim);
}

.hp-telemetry .v {
    font-family: var(--hp-mono);
    font-weight: 700;
    font-size: clamp(0.9rem, 1.4vw, 1.15rem);
    margin-top: 0.35rem;
    font-variant-numeric: tabular-nums;
}

/* ============================================================
   05  MISSIONS  ·  four cinematic bands
   Full bleed 3:1 strips, not a card grid. The source art is a mix of
   3:1, 3:2 and 4:5, and cropping wide is lossless where cropping to
   portrait would destroy the ultrawide defense plate.
   ============================================================ */

.hp-missions { padding: var(--hp-pad-y) 0 0; background: var(--hp-void); }

.hp-bands { margin-top: clamp(2.2rem, 5vh, 3.4rem); }

.hp-band {
    position: relative;
    display: block;
    height: clamp(240px, 34vw, 400px);
    overflow: hidden;
    border-top: 1px solid var(--hp-line);
    text-decoration: none;
    color: inherit;
}

.hp-band:last-child { border-bottom: 1px solid var(--hp-line); }

.hp-band-img {
    position: absolute;
    inset: -8% 0;
    width: 100%;
    height: 116%;
    object-fit: cover;
    transition: transform 1.1s var(--hp-ease), filter 0.6s ease;
    filter: brightness(0.82) saturate(0.95);
    will-change: transform;
}

.hp-band:hover .hp-band-img { filter: brightness(1) saturate(1.05); }

.hp-band-scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, rgba(4,6,10,0.9) 0%, rgba(4,6,10,0.45) 46%, rgba(4,6,10,0.1) 100%);
}

.hp-band-body {
    position: relative;
    z-index: 2;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    max-width: var(--content-w);
    margin: 0 auto;
    padding: 0 var(--gutter);
}

.hp-band-n {
    font-family: var(--hp-mono);
    font-size: 0.63rem;
    letter-spacing: 0.22em;
    color: var(--accent);
}

.hp-band h3 {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(1.5rem, 3vw, 2.4rem);
    letter-spacing: -0.03em;
    margin-top: 0.5rem;
}

.hp-band p {
    margin-top: 0.6rem;
    max-width: 40ch;
    color: #c3c9d2;
    font-size: clamp(0.92rem, 1.1vw, 1.02rem);
    line-height: 1.55;
}

.hp-band-go {
    margin-top: 1rem;
    font-family: var(--hp-mono);
    font-size: 0.63rem;
    letter-spacing: 0.18em;
    color: var(--hp-ember);
    opacity: 0;
    transform: translateX(-6px);
    transition: opacity 0.4s var(--hp-ease), transform 0.4s var(--hp-ease);
}

.hp-band:hover .hp-band-go { opacity: 1; transform: none; }

/* ============================================================
   06  THE RESPONDER  ·  the protagonist
   ============================================================ */

.hp-people {
    position: relative;
    min-height: clamp(460px, 72vh, 680px);
    display: flex;
    align-items: center;
    overflow: hidden;
    background: var(--hp-void);
}

.hp-people-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 42%;
}

.hp-people-scrim {
    position: absolute;
    inset: 0;
    background:
        linear-gradient(90deg, rgba(4,6,10,0.95) 0%, rgba(4,6,10,0.82) 34%,
                               rgba(4,6,10,0.5) 62%, rgba(4,6,10,0.16) 100%),
        linear-gradient(180deg, var(--hp-void) 0%, rgba(4,6,10,0) 22%, rgba(4,6,10,0) 76%, var(--hp-void) 100%);
}

/* width:100% is load bearing. .hp-people is a flex container, so a child
   with margin:0 auto shrinks to fit and centres itself, which pushed this
   whole text block into the middle of the photo instead of the gutter. */
.hp-people .hp-wrap { position: relative; z-index: 2; width: 100%; }
.hp-people .hp-h2 { max-width: 15ch; font-weight: 800; }

/* The scrim is only half strength where the lede sits, so --hp-muted was
   reading as low contrast over the bright equipment behind it. */
.hp-people .hp-lede { color: #d2d7de; }

/* The dawn section is gone. It was section 07, a daylight payoff on a
   paper background with hp_dawn.webp behind it, and its markup now
   exists only in _v1_index_backup.html. Rules deleted 2026-08-17 so
   nothing here describes a section the page does not have. */

.hp-btn {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.97rem;
    padding: 0.95rem 1.8rem;
    border-radius: 999px;
    background: var(--hp-ink);
    color: var(--hp-paper);
    text-decoration: none;
    border: 1px solid var(--hp-ink);
    cursor: pointer;
    transition: transform 0.2s var(--hp-ease), opacity 0.2s ease;
}

.hp-btn:hover { transform: translateY(-2px); opacity: 0.9; }

.hp-btn.ghost {
    background: transparent;
    color: var(--hp-ink);
    border-color: rgba(13, 16, 20, 0.28);
}

/* ============================================================
   MOBILE NAV
   styles.css hides .nav-links and .contact-btn below 960px and shows
   #navToggle, but nothing ever opened a menu, so the button was inert
   and the site had no mobile navigation at all. This is the panel.
   ============================================================ */

.hp-mobile-nav {
    position: fixed;
    inset: 0;
    z-index: 998;
    background: rgba(4, 6, 10, 0.97);
    backdrop-filter: blur(20px);
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.4rem;
    padding: 2rem var(--gutter);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.32s var(--hp-ease), visibility 0.32s;
}

.hp-mobile-nav.open { opacity: 1; visibility: visible; }

.hp-mobile-nav a {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(1.9rem, 8vw, 2.6rem);
    letter-spacing: -0.03em;
    color: var(--text);
    text-decoration: none;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--hp-line);
}

.hp-mobile-nav a:last-of-type { border-bottom: 0; }
.hp-mobile-nav a.active { color: var(--accent); }

.hp-mobile-cta {
    margin-top: 1.6rem;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1rem;
    padding: 1rem 1.6rem;
    border-radius: 999px;
    background: var(--accent);
    color: #0a0a0a;
    border: 0;
    cursor: pointer;
}

.hp-mobile-close {
    position: absolute;
    top: 1.6rem;
    right: var(--gutter);
    background: transparent;
    border: 0;
    color: var(--text);
    cursor: pointer;
    padding: 0.5rem;
}

/* ============================================================
   RESPONSIVE
   ============================================================ */

@media (max-width: 1000px) {
    .hp-craft-grid  { grid-template-columns: 1fr; gap: 2.5rem; }
    .hp-shot        { max-width: 560px; margin: 0 auto; width: 100%; }
    .hp-povgrid     { grid-template-columns: 1fr; }
    .hp-povside     { flex-direction: row; }
    .hp-telemetry   { grid-template-columns: repeat(3, 1fr); }
    .hp-telemetry > div:nth-child(3) { border-right: 0; }
}

@media (max-width: 760px) {
    /* The clock sits under the headline instead of floating right, where
       it would otherwise collide with the copy on a narrow viewport. */
    .hp-clock {
        position: static;
        text-align: left;
        border-right: 0;
        border-left: 2px solid var(--accent);
        padding-right: 0;
        padding-left: 1rem;
        margin-top: 2rem;
        display: flex;
        gap: 2rem;
    }
    .hp-clock-row + .hp-clock-row { margin-top: 0; }
    .hp-hero .hp-wrap { padding-bottom: 3rem; }

    .hp-gap-track   { height: 260vh; }
    .hp-gap-sticky  { align-items: flex-start; padding-top: 6.5rem; }
    .hp-bars        { gap: 1.1rem; }

    .hp-povside     { flex-direction: column; }
    .hp-telemetry   { grid-template-columns: repeat(2, 1fr); }
    .hp-telemetry > div:nth-child(3) { border-right: 1px solid var(--hp-line); }
    .hp-telemetry > div:nth-child(2n) { border-right: 0; }

    .hp-band        { height: clamp(230px, 52vw, 300px); }
    .hp-band-scrim  { background: linear-gradient(90deg, rgba(4,6,10,0.93) 0%, rgba(4,6,10,0.7) 60%, rgba(4,6,10,0.35) 100%); }
    .hp-band p      { display: none; }

    .hp-pin         { font-size: 0.55rem; letter-spacing: 0.12em; }
    .hp-pin.p1      { left: 54%; }
    .hp-pin.p2      { left: 60%; }
}

@media (max-width: 460px) {
    .hp-clock { flex-direction: column; gap: 0.9rem; }
    .hp-clock-row + .hp-clock-row { margin-top: 0; }
}

/* ============================================================
   REDUCED MOTION
   styles.css already kills global transitions. These are the extra
   states this page needs: everything must land in its final position,
   and both scroll driven and clock driven motion must be inert.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
    .hp-rise,
    .hp-pin,
    .hp-band-go {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }
    .hp-dispatch-dot { animation: none; }
    .hp-band-img     { transition: none; }
    .hp-gap-track    { height: auto; }
    .hp-gap-sticky   { position: static; height: auto; padding: var(--hp-pad-y) 0; }
}

/* ============================================================
   v2 SECTIONS
   Built against the buyer research, not taste. Each block below
   exists because a specific finding said a specific audience
   needs it. The comments name the finding so the next person
   does not delete something load bearing.
   ============================================================ */

/* Compliance strip. Procurement reads a vendor in seconds and the
   research is explicit that an undocumented "NDAA compliant" claim is
   itself a red flag, so this states position, never just a badge. */
.hp-compliance {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.4rem;
    margin-top: 1.6rem;
    font-family: var(--hp-mono);
    font-size: 0.66rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--hp-muted);
}
.hp-compliance span { display: inline-flex; align-items: center; gap: 0.45rem; }
.hp-compliance span::before {
    content: '';
    width: 5px; height: 5px;
    border-radius: 50%;
    background: var(--accent);
}

/* THE MANDATE. Hard figures, mono, deliberately unemotional: this is
   the section a chief screenshots for a budget hearing. */
/* ============================================================
   WHAT IT CARRIES  ·  capability walk
   Pinned aircraft, list scrolls past it, active item lights its own
   marker on the airframe. The reason it is pinned rather than laid out
   as a card grid: five cards would put five small copies of the same
   aircraft on the page, and the point of the section is that it is ONE
   airframe doing all five things.
   ============================================================ */
.hp-feat {
    padding: clamp(1rem, 2vh, 1.75rem) 0 clamp(1.25rem, 3vh, 2.5rem);
    background: var(--hp-void);
}
/* ------------------------------------------------------- MEDIA SLOT + STRIP
   Two shared components, both taken from the DEEP FIELD design system rather
   than invented here, because the complaint about this page was that nothing
   related to anything else. They are the reason a video, a photograph and an
   empty placeholder now all sit in the same kind of frame.

   Corner brackets, not a border. A full outline draws a box around the media
   and makes the media a card; four brackets register the frame and leave the
   picture alone. Radius is 2px throughout, per the system: instruments do not
   have rounded corners, and the 14px radius the hero clip used to carry read
   as a consumer app screenshot. */
.hp-slot {
    position: relative;
    margin: 0;
    background: #020306;
    border-radius: 2px;
}
.hp-slot-media {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 2px;
}
.hp-slot-c {
    position: absolute;
    width: 14px; height: 14px;
    border: 1px solid var(--hp-line-2);
    pointer-events: none;
}
.hp-slot-c.tl { top: 10px; left: 10px;  border-right: 0; border-bottom: 0; }
.hp-slot-c.tr { top: 10px; right: 10px; border-left: 0;  border-bottom: 0; }
.hp-slot-c.bl { bottom: 10px; left: 10px;  border-right: 0; border-top: 0; }
.hp-slot-c.br { bottom: 10px; right: 10px; border-left: 0;  border-top: 0; }
.hp-slot-id {
    position: absolute; left: 1.4rem; bottom: 1.1rem;
    font-family: var(--hp-mono);
    font-size: 0.6rem;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: var(--hp-dim);
}

/* The spec strip. One row of cells divided by hairlines, achieved with a 1px
   grid gap over a line-coloured background rather than per-cell borders, so
   the dividers are single-width and there is no doubled edge where two cells
   meet. This is the only place numbers appear outside the ground station. */
.hp-strip {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1px;
    margin: clamp(2rem, 4.5vh, 3rem) 0 0;
    background: var(--hp-line);
    border-block: 1px solid var(--hp-line);
}
.hp-strip.is-wide { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.hp-strip > div {
    display: flex; flex-direction: column; gap: 0.55rem;
    padding: clamp(0.9rem, 2vh, 1.15rem) clamp(0.6rem, 1.4vw, 1.1rem);
    background: var(--hp-void);
}
.hp-strip dt {
    font-family: var(--hp-mono);
    font-size: 0.6rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--hp-dim);
    line-height: 1;
}
.hp-strip dd {
    margin: 0;
    font-family: var(--hp-mono);
    font-size: clamp(0.95rem, 1.15vw, 1.1rem);
    font-variant-numeric: tabular-nums;
    color: var(--hp-paper);
    line-height: 1;
}

@media (max-width: 700px) {
    .hp-strip,
    .hp-strip.is-wide { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    /* An odd number of cells in a two-column grid leaves a hole in the row,
       and a hole in a hairline grid reads as a missing value rather than as
       spare space. The last cell takes the width instead. */
    .hp-strip:not(.is-wide) > div:last-child { grid-column: 1 / -1; }
}

/* ---------------------------------------------------------- THE REVEAL
   The aircraft is named here for the first time on the page, and the old
   treatment put that moment flush left in the same weight as every other
   section head, with the subline in dim grey underneath. It read as a
   paragraph, not an introduction.

   Centred, at the top of the display scale, on a single amber wash. The
   wash is a radial gradient behind the type rather than a colour on it,
   so the words stay paper white and the warmth sits in the air around
   them; a gradient ON the letters would fight the aircraft photograph
   directly below. The plate under it is one hairline and a barely-lit
   panel: glass here means depth, not frosting. */
.hp-feat-intro {
    position: relative;
    display: flex; flex-direction: column; align-items: center;
    text-align: center;
    /* No padding, no borders, no background. The title is not a panel any more:
       it sits inside the sticky stage as the label directly above the aircraft,
       so the only spacing it needs is a gap down to the figure. The old top/
       bottom hairlines (the "two lines" Naman flagged) are gone. */
    margin: 0 0 clamp(1rem, 2.6vh, 2rem);
}
/* The decorative glow behind the title is removed. Kept as a no-op so the
   <span> in the markup renders nothing. */
.hp-feat-wash { display: none; }
.hp-feat-title {
    position: relative;
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    /* Smaller than the old full-display size: the title now shares the centre
       column with the aircraft, so it is sized to sit tidily above it rather
       than to fill the page. */
    font-size: clamp(1.7rem, 3vw, 3.1rem);
    line-height: 0.98;
    letter-spacing: -0.035em;
    color: var(--hp-paper);
}
/* "Introducing," is the lead-in, set clearly smaller than the name and in
   quiet grey so the name is what the eye lands on. Own line via display:block,
   which is why the <br> was dropped from the markup. */
.hp-feat-lead {
    display: block;
    font-style: normal;
    font-weight: 500;
    font-size: 0.46em;
    letter-spacing: 0.005em;
    color: var(--hp-muted);
    margin-bottom: 0.35em;
}
/* The name is frost: a white-to-cool-grey gradient clipped to the glyphs for
   a glassy read. This is the "A frost" sample Naman approved; the old amber
   fought both the site palette and the aircraft photograph below it. */
.hp-feat-title span {
    display: block;
    background: linear-gradient(180deg, #ffffff, #c1c6cf);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.hp-feat-sub {
    position: relative;
    margin: clamp(1.2rem, 2.6vh, 1.8rem) 0 0;
    font-family: var(--hp-mono);
    font-size: clamp(0.8rem, 1.15vw, 1rem);
    letter-spacing: 0.34em;
    text-transform: uppercase;
    /* Was --hp-dim, then --hp-muted, and both still read as grey noise under
       a five-rem headline. Paper at 82% is the same family as the title and
       survives the size drop. */
    color: var(--hp-paper);
    opacity: 0.82;
}

/* ---------------------------------------------------------- WHAT IT CARRIES
   Three columns: the aircraft pinned down the middle in a full-viewport
   sticky box, the five capabilities passing it alternately left and right.

   Numbers, body copy and the amber spines are all cut. What is left per item
   is a title and an empty picture slot, which is what Naman asked for and
   also what fixes the density problem: five short lines alternating down a
   1320px page was mostly air. The slot brackets give each item a footprint
   before a single still exists. */
.hp-feat-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) minmax(0, 1fr);
    /* Row 1 is a full-viewport lead-in owned by the pinned aircraft alone: the
       name and the airframe take the first screen by themselves. The four
       capabilities begin on row 2, one screen down, so the reveal reads
       "Introducing Skybourne Halo" FIRST, then the capabilities scroll past
       the aircraft while it stays centred. Four rows, one per card: a fifth
       (from the retired indoor/outdoor card) left a trailing row-gap. */
    grid-template-rows: 56svh repeat(4, auto);
    gap: clamp(1.4rem, 3vw, 3rem);
    align-items: start;
    margin-top: clamp(0.5rem, 1.2vh, 1rem);
}
.hp-feat-list { display: contents; list-style: none; margin: 0; padding: 0; }
.hp-feat-stage {
    grid-column: 2;
    grid-row: 1 / -1;
    position: sticky;
    /* Pin the stage BELOW the fixed nav. The nav is a fixed-height bar
       (20px top + 88px tall = 108px bottom) that does NOT scale with the
       viewport, so this clearance must be a fixed length too: a viewport-
       relative offset (vh) shrinks on short laptop screens and lets the
       "Skybourne Halo" name tuck up under the nav. 7.5rem (120px) clears the
       108px nav at every viewport height. The short 56svh band keeps the
       reveal gap above the title tight; the fixed top keeps the name clear. */
    top: 7.5rem;
    height: 56svh;
    display: flex;
    flex-direction: column;
    /* Name + aircraft stay vertically centred in the pinned viewport so they
       remain in the middle of the frame while the capabilities scroll past,
       and never slip up behind the fixed nav. */
    justify-content: center;
    align-items: center;
    padding-top: 0;
}
.hp-feat-stage > .hp-feat-figure { width: 100%; }
.hp-feat-figure {
    position: relative; margin: 0;
    aspect-ratio: 2159 / 1046;
    overflow: hidden;
}
.hp-feat-figure img {
    display: block; position: absolute;
    left: -9.82%; top: -1.72%;
    width: 118.57%; max-width: none; height: auto;
}
.hp-feat-item {
    min-height: 46svh;
    display: flex; flex-direction: column; justify-content: center;
    gap: clamp(1rem, 2.2vh, 1.5rem);
    opacity: 0.32;
    transition: opacity 0.45s var(--hp-ease);
}
.hp-feat-item:nth-child(1) { grid-column: 1; grid-row: 2; }
.hp-feat-item:nth-child(2) { grid-column: 3; grid-row: 3; }
.hp-feat-item:nth-child(3) { grid-column: 1; grid-row: 4; }
.hp-feat-item:nth-child(4) { grid-column: 3; grid-row: 5; }
.hp-feat-item:nth-child(5) { grid-column: 1; grid-row: 6; }
/* Alignment still alternates toward the aircraft, which is what makes the
   column read as two files passing a centre object. The spines that used to
   carry it are gone; the text edge does the work on its own. */
.hp-feat-item:nth-child(odd)  { text-align: right; align-items: flex-end; }
.hp-feat-item:nth-child(even) { text-align: left;  align-items: flex-start; }
.hp-feat-item.is-active { opacity: 1; }

.hp-feat-item h3 {
    margin: 0;
    font-family: var(--font-display); font-weight: 700;
    font-size: clamp(1.4rem, 2.3vw, 2.1rem);
    line-height: 1.04; letter-spacing: -0.03em;
    color: var(--hp-paper);
}
/* Empty slots until the stills land. 4:3 rather than 16:9 because these are
   detail shots of one aircraft, not scenes. */
.hp-feat-shot {
    width: 100%;
    aspect-ratio: 4 / 3;
    border: 1px solid var(--hp-line);
    background:
        repeating-linear-gradient(-45deg, transparent 0 14px, rgba(255,255,255,0.012) 14px 28px),
        var(--hp-panel);
    transition: border-color 0.45s var(--hp-ease);
}
.hp-feat-item.is-active .hp-feat-shot { border-color: var(--hp-line-2); }
.hp-feat-shot .hp-slot-id { left: 1rem; bottom: 0.9rem; }
.hp-feat-item:nth-child(odd) .hp-feat-shot .hp-slot-id { left: auto; right: 1rem; }
/* A slot with a picture in it drops the hatch and the placeholder label. */
.hp-feat-shot:has(img) { background: #020306; }
.hp-feat-shot:has(img) .hp-slot-id { display: none; }
.hp-feat-shot img { display: block; width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 900px) {
    .hp-feat-grid { grid-template-columns: 1fr; grid-template-rows: none; gap: 2rem; }
    .hp-feat-stage { grid-column: 1; grid-row: auto; position: static; height: auto; display: block; padding-top: 0; }
    .hp-feat-item:nth-child(n) { grid-column: 1; grid-row: auto; }
    .hp-feat-item { min-height: 0; opacity: 1; }
    .hp-feat-item:nth-child(odd),
    .hp-feat-item:nth-child(even) { text-align: left; align-items: flex-start; }
    .hp-feat-item:nth-child(odd) .hp-feat-shot .hp-slot-id { left: 1rem; right: auto; }
}

.hp-mandate { padding: var(--hp-pad-y) 0; background: var(--hp-panel); border-top: 1px solid var(--hp-line); }

/* SECURITY. Three lines, no figure, no card grid. The point is stated once
   and the section is over; giving it furniture would make it look like the
   argument the page is built on, and it is not. Sits on --hp-void so it reads
   as a beat between the panel-coloured PROOF above and the close below. */
.hp-security {
    padding: clamp(4.5rem, 11vh, 7.5rem) 0;
    background: var(--hp-void);
    border-top: 1px solid var(--hp-line);
}
.hp-security .hp-lede { margin-top: 1.2rem; max-width: 46ch; }

.hp-figs {
    margin-top: clamp(2rem, 5vh, 3.2rem);
    display: grid;
    /* auto-fit, not a hardcoded 3. The fixed three-column rule left a
       dead cell whenever the section carried two figures: the leftover
       track showed the container background through the 1px gap gutter
       and read as a third card someone had forgotten to fill in. */
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1px;
    background: var(--hp-line);
    border: 1px solid var(--hp-line);
}
.hp-fig { background: var(--hp-panel); padding: 1.6rem 1.4rem; }
.hp-fig .v {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(1.9rem, 3.6vw, 3rem);
    letter-spacing: -0.035em;
    line-height: 1;
    color: var(--hp-ember);
}
.hp-fig .l { margin-top: 0.7rem; font-size: 0.92rem; line-height: 1.5; color: var(--hp-muted); }
.hp-fig .s {
    margin-top: 0.8rem;
    font-family: var(--hp-mono);
    font-size: 0.6rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--hp-dim);
}

/* ---------- 02 THE STAKE ----------
   This section used to borrow .hp-figs, the three-up card grid built
   for the mandate block. It carries one figure, so that grid gave it a
   single card stretched the full width of the page inside a border,
   with the rest of the band empty: the layout was announcing two
   missing cards. A number that stands alone is not a card. It is the
   consequence of an argument, so it is set in the right column against
   the paragraphs that make the argument, and the section closes on the
   line that turns the problem into the product. */
.hp-stake { padding: var(--hp-pad-y) 0; background: var(--hp-void); }

/* The readout.
   Four things the first crew does not know, each with the answer it
   actually has. The row structure is the point: a question column that
   stays put and a status column that says the same word four times, so
   the repetition is read as instrumentation rather than as rhetoric.
   The fifth row is not a question, and it is the only white line in the
   block, because it is what happens despite the four above it. */
.hp-readout {
    margin-top: clamp(2.2rem, 5vh, 3.4rem);
    /* Full wrap width. The 1120px cap was set when the row held four
       tiles; at five it gave each cell 224px, which is narrower than
       the caption needs and forces "responders" to break. */
    max-width: none;
    /* The top rule used to sit above an "At the door" label, which is gone:
       the strip below states where it is without being told. The rule stays
       as the boundary between the headline and the pictures, so the padding
       the label used to supply is now the readout's own. */
    padding-top: clamp(1.4rem, 3vh, 2.1rem);
    border-top: 1px solid var(--hp-line-2);
}

/* One line. At the shared 18ch cap this headline broke after "go", which
   left a two-word orphan under a nine-word line and cost the section its
   opening beat. The width is bounded by the viewport instead, and the
   wrap comes back below 720px, where a single line would be too small
   to read. */
.hp-stake .hp-h2 {
    max-width: none;
    white-space: nowrap;
    font-size: clamp(1.7rem, 4.6vw, 3.5rem);
}

@media (max-width: 720px) {
    .hp-stake .hp-h2 {
        white-space: normal;
        font-size: clamp(1.9rem, 8vw, 2.6rem);
    }
}

.hp-readout-label {
    padding: 1.1rem 0 1rem;
    font-family: var(--hp-mono);
    font-size: 0.64rem;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: var(--accent);
    border-bottom: 1px solid var(--hp-line);
}

/* The four scenes.
   Real incident photography, not renders. Every image in this repo is a
   product plate with the aircraft in it, and beat 1 must not contain the
   product, so these are public-domain USAF and US Army frames pulled
   from DVIDS and graded down to the page's night palette. They are the
   readout: the status word sits above the question on each tile, so the
   picture and the line it belongs to cannot drift apart.

   Five cells, not four. The fifth is the cost, and it is a cell in the
   same row rather than a figure parked underneath: the row then reads
   left to right as four unknowns and their price, which is the whole
   argument of the section in one horizontal move. */
.hp-scene-strip {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 1px;
    background: var(--hp-line);
    border-bottom: 1px solid var(--hp-line);
}
.hp-scene {
    position: relative;
    margin: 0;
    overflow: hidden;
    background: var(--hp-void);
}
.hp-scene img {
    display: block;
    width: 100%;
    height: 100%;
    aspect-ratio: 3 / 4;
    object-fit: cover;
}
/* The caption sits on the picture, on a gradient that reaches full
   page black at the bottom edge so the type has ground under it and
   the tile still ends in the section's own colour. */
.hp-scene figcaption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 2.4rem 1.05rem 1.15rem;
    background: linear-gradient(180deg, rgba(4,6,10,0) 0%,
                                rgba(4,6,10,0.82) 42%, rgba(4,6,10,0.96) 100%);
}
.hp-scene .a {
    display: block;
    margin-bottom: 0.5rem;
    font-family: var(--hp-mono);
    font-size: 0.6rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--hp-muted);
}
.hp-scene .q {
    display: block;
    font-size: clamp(0.92rem, 1.05vw, 1.06rem);
    line-height: 1.34;
    color: #fff;
}

/* Attribution, deliberately quiet and deliberately present. Public
   domain does not require it, but naming the source keeps the images
   from reading as our own footage, and it states no endorsement. */
.hp-credit {
    margin-top: clamp(1.8rem, 4vh, 2.6rem);
    font-family: var(--hp-mono);
    font-size: 0.58rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--hp-dim);
}

/* THE FIFTH CELL, the cost.
   Same footprint as a picture tile, so the row keeps one rhythm: the
   plate takes the 3:4 the images take, and the caption lands on the
   same baseline as theirs. The plate is not black. A fifth black cell
   next to four dark photographs disappears into the gap between them,
   and the number has to hold the end of the row. */
.hp-scene.is-cost { background: var(--hp-panel); }
/* The plate is now background only. The number moved INTO the figcaption,
   which on every other cell in this row is an absolutely positioned overlay
   pinned to the bottom of the figure. Leaving 209 in the plate meant the
   caption scrim was laid over the top of it: measured, the caption started
   24 px above the number's own baseline and the source line crossed the
   sentence. One stack, one flow, no overlap - and it puts the count directly
   above the line that says what it counts, which was the point. */
.hp-cost-plate {
    aspect-ratio: 3 / 4;
    background:
        radial-gradient(120% 80% at 50% 66%, rgba(214,90,42,0.16), transparent 72%),
        var(--hp-panel);
}
.hp-cost-n {
    display: block;
    margin: 0.15rem 0 0.3rem;
    font-family: var(--font-display);
    font-weight: 700;
    /* Was 4.6rem. At five cells across, a count that fills the tile edge to
       edge stops reading as a figure and becomes texture. */
    font-size: clamp(2.2rem, 3.6vw, 3.4rem);
    line-height: 0.9;
    letter-spacing: -0.05em;
    color: var(--hp-ember);
}
/* The source line only exists on this cell. */
.hp-scene .s {
    display: block;
    margin-top: 0.6rem;
    font-family: var(--hp-mono);
    font-size: 0.56rem;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--hp-dim);
}
.hp-scene.is-cost .a { color: var(--hp-ember); }

/* The close line, full width under the row. It is the only white
   sentence in the block and it answers all five cells at once, so it
   gets the whole measure rather than a column of it. */
.hp-readout-close {
    padding: clamp(1.5rem, 3.4vh, 2.3rem) 0 0;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: clamp(1.35rem, 2.4vw, 2rem);
    letter-spacing: -0.02em;
    line-height: 1.2;
}

/* THE WORLDVIEW. Beat 3, the kill line.
   It used to be a black band with type in the middle of it and nothing
   else. That was defensible while the page had six sections after it to
   look at; with the page cut down it was one of two sections in a row
   with no aircraft in them, and it read as the site running out of
   material rather than as a pause.

   So the pause keeps its silence and gains a subject: the aircraft, in
   the dark, inside the kind of structure the four unknowns above were
   about. The picture is the argument, not decoration. The scrim is
   heavy and biased to the left, where the type is, so the headline
   stays the brightest thing in the frame.

   The class name is historical. This block was specced as a named
   chief's quote and the blockquote/cite rules that went with it are
   gone, since nothing on the page uses them. */
.hp-quote {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    min-height: 82svh;
    display: flex;
    align-items: center;
    padding: var(--hp-pad-y) 0;
    background: var(--hp-void);
}
.hp-believe-bg {
    position: absolute;
    inset: 0;
    z-index: -2;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 46%;
    /* The aircraft sits near the middle of its own frame, and the frame is
       almost the same aspect as the section, so object-position has nothing
       to crop with and cannot move it. Scaling past the box first creates
       the slack, then the shift spends it: the aircraft clears the end of
       "Zero decisions." and the scaled edges stay off screen. */
    transform: scale(1.2) translateX(7%);
}
.hp-believe-scrim {
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        linear-gradient(90deg, rgba(4,6,10,0.94) 0%, rgba(4,6,10,0.86) 42%,
                        rgba(4,6,10,0.38) 78%, rgba(4,6,10,0.55) 100%),
        linear-gradient(180deg, rgba(4,6,10,0.7) 0%, rgba(4,6,10,0) 30%,
                        rgba(4,6,10,0) 70%, rgba(4,6,10,0.7) 100%);
}
.hp-believe { position: relative; width: 100%; }
/* Bigger than any other h2. This is the one sentence the whole page is
   built to set up, so it is sized against the hero, not against the
   section headlines it sits among. */
.hp-believe-h {
    max-width: none;
    font-size: clamp(2.3rem, 6vw, 5rem);
    line-height: 0.98;
}
.hp-believe .hp-lede {
    max-width: 46ch;
    margin-top: clamp(1.6rem, 3.6vh, 2.5rem);
}

/* ------------------------------------------------------------------ THE
   WORLDVIEW CONSOLE.

   Copy left, ground station right. The console is deliberately the only
   lit thing on its side of the page and the headline is still the
   brightest thing on the other, so the two halves do not compete.

   Everything from --gcs-* down is the GROUND STATION'S palette, lifted
   from software/gcs/.../ui/styles.py rather than approximated out of the
   site's own tokens. The point of this section is that the interface is
   real, so it has to be the real interface's colours, not ember versions
   of them. */
.hp-quote.has-console {
    min-height: 0;
    display: block;
    padding: var(--hp-pad-y) 0 clamp(1.5rem, 3vh, 2.75rem);
}

.hp-wv {
    --gcs-ok:     #00ff88;
    --gcs-warn:   #ffaa00;
    --gcs-danger: #ff4444;
    --gcs-glass:  rgba(0, 0, 0, 0.62);
    --gcs-line:   rgba(255, 255, 255, 0.10);

    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.42fr);
    gap: clamp(2rem, 4.5vw, 4.5rem);
    align-items: center;
}
/* No character cap here. The grid column already sets the measure, and a
   30ch cap on top of it broke "Ten thousand cameras." across two lines,
   which turns a two-line headline into a four-line one. */
.hp-wv-copy { max-width: none; }
/* Two columns, so the headline cannot run at hero scale any more. Sized so
   the longer of its two sentences still sets on one line at 1280 and up. */
.hp-wv-copy .hp-believe-h {
    font-size: clamp(1.9rem, 3vw, 3.1rem);
    line-height: 0.98;
}
.hp-wv-copy .hp-lede { max-width: none; }

.hp-wv-screen {
    border: 1px solid var(--hp-line-2);
    background: #0a0a0a;
}

/* -------------------------------------------------------------- WORLDVIEW
   Copy left, the ground station right. There is no ground station chrome in
   this stylesheet any more: the console that used to be built out of .gcs-*
   rules is deleted, because the panel on screen is now a recording of the
   real application and rebuilding its furniture in CSS on top of a video of
   itself would be drawing the same thing twice. */
.hp-wv-stack { align-self: start; }
.hp-wv-slot { margin-bottom: 0; }

/* The decision log. Three cells on one hairline row, directly under the
   frame, in the same grid the spec strips use. Each one lights when the clip
   reaches its beat and stays lit, so by the end of the loop the whole
   sequence is readable at once instead of having flashed past. */
.hp-wv-log {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1px;
    background: var(--hp-line);
    border-bottom: 1px solid var(--hp-line);
}
.hp-wv-alert {
    display: flex; flex-direction: column; gap: 0.4rem;
    padding: 0.95rem 1rem 1.05rem;
    background: var(--hp-void);
    border-top: 2px solid var(--hp-line-2);
    opacity: 0.28;
    transition: opacity 0.45s var(--hp-ease), border-color 0.45s var(--hp-ease);
}
.hp-wv-alert.is-in { opacity: 1; }
.hp-wv-a-h {
    font-family: var(--hp-mono);
    font-size: 0.62rem; font-weight: 700;
    letter-spacing: 0.2em;
    color: var(--hp-paper);
}
.hp-wv-a-b {
    font-size: 0.82rem; line-height: 1.5;
    color: var(--hp-muted);
}
.hp-wv-a-k {
    display: flex; gap: 0.85rem; margin-top: auto; padding-top: 0.35rem;
    font-family: var(--hp-mono); font-size: 0.55rem;
    letter-spacing: 0.16em; color: var(--hp-dim);
}
.hp-wv-a-k em { font-style: normal; }
/* Two states, matching the two the ground station actually has: a status
   message, and a detection that holds the aircraft until somebody answers. */
.hp-wv-alert.is-in.is-ok  { border-top-color: #00ff88; }
.hp-wv-alert.is-in.is-hot { border-top-color: var(--hp-hot); }
.hp-wv-alert.is-in.is-hot .hp-wv-a-h { color: var(--hp-hot); }

.hp-wv-cap {
    margin: 1rem 0 0;
    font-family: var(--hp-mono);
    font-size: 0.6rem; letter-spacing: 0.24em;
    text-transform: uppercase; color: var(--hp-dim);
}

@media (max-width: 900px) {
    .hp-wv { grid-template-columns: 1fr; gap: clamp(1.8rem, 4vh, 2.6rem); }
    .hp-wv-copy { max-width: none; }
    /* The cards are sized against the video and the video is now a phone
       wide. Full width under the frame instead of a 48% column of
       six-point type nobody can read. */
    .hp-wv-log { grid-template-columns: 1fr; }
    .hp-wv-a-k { margin-top: 0; }
}

/* THE MATH. Operating cost only. Both figures are already published
   and sourced on use-cases.html, so nothing new is being claimed. */
.hp-math { padding: var(--hp-pad-y) 0; background: var(--hp-panel); }

/* Full page, no picture. This was a two column layout with the argument on
   the left and the aircraft on its ground station on the right. The picture
   went, because a product shot beside a cost argument makes the section about
   the hardware, and the hardware is not what is being argued here. The
   .hp-math-grid and .hp-math-shot rules went with it; nothing else used them.

   The numbers get the whole viewport instead. Roughly full height, so the
   count is the only thing on screen while it runs. */
.hp-math.is-solo {
    min-height: 92svh;
    display: flex;
    align-items: center;
    padding: clamp(4rem, 10vh, 8rem) 0;
}
.hp-math.is-solo .hp-wrap { width: 100%; }
.hp-math.is-solo .hp-h2 { margin-bottom: clamp(2.6rem, 6vh, 4.5rem); }
.hp-math.is-solo .hp-gap-note { margin-top: clamp(1.5rem, 3vh, 2.4rem); }
.hp-costs { margin-top: clamp(2rem, 5vh, 3rem); display: flex; flex-direction: column; gap: 1.3rem; }
.hp-cost-top { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; margin-bottom: 0.55rem; }
.hp-cost-name { font-family: var(--font-display); font-weight: 600; font-size: clamp(0.95rem, 1.3vw, 1.08rem); }
.hp-cost-v { font-family: var(--hp-mono); font-weight: 700; font-size: clamp(1rem, 1.6vw, 1.3rem); font-variant-numeric: tabular-nums; }
.hp-cost-track { height: 11px; background: rgba(255,255,255,0.06); position: relative; overflow: hidden; }
/* min-width keeps the Halo bar visible. At a true 0.7% of the helicopter
   figure it renders as literally nothing, which reads as a broken bar
   rather than as the point being made. */
.hp-cost-fill { position: absolute; inset: 0 auto 0 0; min-width: 4px; background: linear-gradient(90deg,#4a515d,#8a93a0); }
.hp-cost.is-halo .hp-cost-fill { background: linear-gradient(90deg, var(--accent), var(--hp-ember)); }
.hp-cost.is-halo .hp-cost-v { color: var(--hp-ember); }

/* ---- .is-big: the full page animated variant used by THE MATH ----------
   Same component, scaled up to carry a section on its own. The compact
   .hp-costs above is still used elsewhere and is untouched. */
.hp-costs.is-big { gap: clamp(1.4rem, 3.4vh, 2.4rem); }
.hp-costs.is-big .hp-cost {
    border-top: 1px solid var(--hp-line-2);
    padding-top: clamp(1.4rem, 3vh, 2.2rem);
}
.hp-costs.is-big .hp-cost:last-child {
    border-bottom: 1px solid var(--hp-line-2);
    padding-bottom: clamp(1.4rem, 3vh, 2.2rem);
}
/* Number first and hard left, so it sits directly over the origin of its own
   bar. Pushed to the right edge (which is what space-between does once the
   figure is this large) it reads as a separate column, and the eye has to
   cross the whole page to pair a figure with its meter. */
.hp-costs.is-big .hp-cost-top {
    justify-content: flex-start;
    gap: clamp(1rem, 2.2vw, 2rem);
    margin-bottom: clamp(0.9rem, 2vh, 1.4rem);
}
.hp-costs.is-big .hp-cost-v {
    order: -1;
    font-family: var(--font-display);
    font-weight: 700;
    /* Tabular figures. Without them the number jitters sideways the whole way
       up as glyph widths change, and the eye tracks the wobble not the count. */
    font-variant-numeric: tabular-nums;
    font-size: clamp(2.3rem, 5.6vw, 4.8rem);
    line-height: 0.86;
    letter-spacing: -0.045em;
    color: var(--hp-paper);
}
.hp-costs.is-big .hp-cost.is-halo .hp-cost-v { color: var(--hp-ember); }
.hp-costs.is-big .hp-cost-name {
    font-family: var(--hp-mono);
    font-weight: 500;
    font-size: 0.72rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--hp-muted);
}
.hp-costs.is-big .hp-cost-track { height: 12px; }
/* The shipped fill carries min-width:4px so a hardcoded 0.7% bar stays
   visible. Here the bar animates up from zero, and a floor would leave both
   bars looking pre-filled before the count starts. */
.hp-costs.is-big .hp-cost-fill { min-width: 0; width: 0; }

/* Lands only once Halo has stopped and the other one visibly has not. */
.hp-still {
    display: inline-block;
    margin-left: 1rem;
    color: var(--hp-ember);
    opacity: 0;
    transition: opacity 0.6s ease 0.4s;
}
.hp-math.is-run .hp-still { opacity: 1; }

@media (max-width: 700px) {
    /* Side by side, the label runs off the right edge: it is one uppercase
       mono line with wide tracking and it will not wrap inside a baseline
       aligned flex row. Stack it with the number instead. */
    .hp-costs.is-big .hp-cost-top { display: block; margin-bottom: 0.9rem; }
    .hp-costs.is-big .hp-cost-v { display: block; margin-top: 0.5rem; }
    .hp-costs.is-big .hp-cost-name { display: block; letter-spacing: 0.14em; }
    .hp-still { display: block; margin: 0.6rem 0 0; }
}

/* WHAT IT DOES NOT DO. Two independent sources landed on the same
   point: stating limits out-credentials competitors who claim
   everything, and "never fails" is treated as a disqualifier. */
.hp-limits { padding: var(--hp-pad-y) 0; background: var(--hp-void); }
.hp-limit-grid {
    margin-top: clamp(2rem, 5vh, 3rem);
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1px;
    background: var(--hp-line);
    border: 1px solid var(--hp-line);
}
.hp-limit { background: var(--hp-void); padding: 1.5rem 1.4rem; }
.hp-limit h3 {
    font-family: var(--hp-mono);
    font-size: 0.66rem;
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--hp-dim);
}
.hp-limit p { margin-top: 0.7rem; font-size: 0.98rem; line-height: 1.55; color: #c3c9d2; }

/* Shared full-bleed render figure, used by the aircraft section. */
.hp-plate { position: relative; margin-top: clamp(2rem, 5vh, 3rem); border: 1px solid var(--hp-line); overflow: hidden; background: #000; }
.hp-plate img,
.hp-plate video { width: 100%; display: block; }
/* An <img> gets its aspect ratio from the width/height attributes via the UA
   sheet, so width:100% alone is enough for it. A <video> does not get that
   treatment reliably, and without this it renders 1280x720 squashed to
   column-width x 720. Stating the ratio also holds the space before the
   file loads, so the section does not jump. */
.hp-plate video { height: auto; aspect-ratio: 16 / 9; }
.hp-plate figcaption {
    position: absolute; left: 0; right: 0; bottom: 0;
    padding: 1.4rem;
    background: linear-gradient(180deg, rgba(4,6,10,0), rgba(4,6,10,0.92));
    font-family: var(--hp-mono);
    font-size: 0.63rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--hp-muted);
}

/* Three up, then two. Five portrait tiles across a phone gives each one
   about 75px of width and every caption breaks mid-word. Below 860 the
   row becomes 3 + 2, and the cost cell takes the full width of the
   second line so the number still closes the block. */
@media (max-width: 860px) {
    .hp-figs, .hp-limit-grid { grid-template-columns: 1fr; }
    .hp-scene-strip { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .hp-scene.is-cost { grid-column: 1 / -1; }
    .hp-cost-plate {
        aspect-ratio: auto;
        min-height: 8.5rem;
        /* The 4.6rem bottom pad was clearing a caption that no longer sits
           below the number; with the stack bottom aligned it was just a
           block of empty panel under the sentence. */
        padding: 1.6rem 1.1rem 1.4rem;
    }
}
@media (max-width: 560px) {
    .hp-scene-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ============================================================
   CLOSE. Replaces the dawn/paper section.
   The page now ends dark and on a statement of intent rather than
   on a sunrise. .voice.md calls for "confident without arrogance",
   and the sentimental ending was neither.
   ============================================================ */
.hp-close {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    min-height: min(94svh, 900px);
    display: flex;
    align-items: flex-start;
    padding: clamp(2.75rem, 7vh, 4.5rem) 0 clamp(3rem, 7vh, 5rem);
    background: #05060a;
}
.hp-close-bg {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover; object-position: 50% 46%;
    z-index: -2;
}
.hp-close-scrim {
    position: absolute; inset: 0;
    z-index: -1;
    /* Feather the top and bottom edges into the near-black sections above and
       the footer below for a seamless seam, while the middle stays clear so
       Halo and the responder read bright. */
    background:
      linear-gradient(180deg,
        rgba(4,6,10,1) 0%,
        rgba(4,6,10,1) 4.5%,
        rgba(4,6,10,0.86) 11%,
        rgba(5,6,10,0.52) 20%,
        rgba(5,6,10,0.22) 30%,
        rgba(5,6,10,0.06) 42%,
        rgba(5,6,10,0.02) 52%,
        rgba(5,6,10,0.02) 68%,
        rgba(5,6,10,0.18) 83%,
        rgba(5,6,10,0.44) 93%,
        rgba(5,6,10,0.74) 100%);
}
.hp-close-inner { position: relative; z-index: 1; text-align: center; }
.hp-close h2 {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: clamp(2rem, 5vw, 3.8rem);
    letter-spacing: -0.04em;
    line-height: 1.04;
    margin: 0 auto;
    max-width: 19ch;
    color: #fff;
    text-shadow: 0 2px 44px rgba(0,0,0,0.6);
}
.hp-close .hp-lede {
    max-width: 56ch;
    margin: 1.35rem auto 0;
    color: rgba(255,255,255,0.82);
    text-shadow: 0 1px 22px rgba(0,0,0,0.5);
}
.hp-close-cta { margin-top: 2.3rem; display: inline-flex; gap: 0.85rem; flex-wrap: wrap; justify-content: center; }
.hp-close .hp-btn { background: var(--accent); color: #0a0a0a; border-color: var(--accent); }
.hp-close .hp-btn.ghost { background: rgba(10,12,18,0.32); color: #fff; border-color: rgba(255,255,255,0.5); backdrop-filter: blur(2px); }

/* Pull quote used inside a content section rather than as its own slab. */
.hp-pull {
    margin-top: clamp(2rem, 5vh, 3rem);
    border-left: 2px solid var(--accent);
    padding-left: clamp(1.2rem, 3vw, 2rem);
    max-width: 60ch;
}
.hp-pull blockquote {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: clamp(1.15rem, 2.1vw, 1.7rem);
    line-height: 1.32;
    letter-spacing: -0.02em;
}
.hp-pull cite {
    display: block;
    margin-top: 1rem;
    font-style: normal;
    font-family: var(--hp-mono);
    font-size: 0.66rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--hp-dim);
    line-height: 1.8;
}
