/* ==========================================================================
   Homepage — hero and capabilities ticker.
   Plain CSS, scoped to .hx-* (hero), .hxm-* (ticker). The navigation is
   shared by every page (assets/css/shared/nav.css + assets/js/shared/nav.js).
   Loaded only by index.html; driven by assets/js/home/hero.js.
   ========================================================================== */

:root {
    --hx-purple: #7c3aed;
    --hx-cyan: #0ea5e9;
    --hx-pink: #f472b6;
    --hx-night: #020617;
    --hx-ease: cubic-bezier(0.22, 1, 0.36, 1);
    --hx-gutter: clamp(1.25rem, 4.2vw, 3.5rem);
    --hx-max: 82rem;
}

/* Without JavaScript the page-shell gate never lifts; show the page anyway. */
.no-js body.page-shell-loading {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
}

/* ==========================================================================
   Hero — shares the About page's deep-space backdrop (star field + the
   drifting "scattered" plate), with the Nebulight mark as the title,
   "Built to move people." gathering letter by letter, and the astronaut
   descending into the scene.
   ========================================================================== */

@font-face {
    font-family: "Conthrax";
    src: url("../../fonts/conthrax-semibold.otf") format("opentype");
    font-style: normal;
    font-weight: 600;
    font-display: swap;
}

.hx {
    --hx-p: 0;
    --hx-a: 0;
    position: relative;
    z-index: 1;
    isolation: isolate;
    /* The astronaut fills the right third: as wide as it can be while its full
       height still fits beneath the nav. */
    --astro-w: clamp(16rem, min(30vw, calc((100vh - 8.5rem) / 1.5)), 32rem);
    display: flex;
    align-items: center;
    min-height: max(40rem, 100vh);
    min-height: max(40rem, 100svh);
    padding: calc(env(safe-area-inset-top, 0px) + 6rem) var(--hx-gutter) clamp(4.5rem, 9vh, 6rem);
    overflow-x: clip;
    color: #fff;
    background:
        radial-gradient(70% 60% at 18% 100%, rgba(18, 20, 52, 0.85), transparent 70%),
        #060609;
}

/* ---------- Backdrop ---------- */

.hx-bg {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
}

.hx-space {
    position: absolute;
    inset: -4% 0;
    opacity: 0.55;
    transform: translate3d(calc(var(--hx-mx, 0) * 6px), calc(var(--hx-p) * 40px), 0);
}

.hx-space picture,
.hx-space img,
.hx-plate-drift picture,
.hx-plate-drift img {
    display: block;
    width: 100%;
    height: 100%;
}

.hx-space img {
    object-fit: cover;
}

/* The plate: set into the right of the frame, dissolving leftward. */
.hx-plate {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 68%;
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.55) 22%, #000 46%);
    mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.55) 22%, #000 46%);
}

.hx-plate-par {
    position: absolute;
    inset: -6% 0;
    transform: translate3d(calc(var(--hx-mx, 0) * -14px), calc(var(--hx-p) * 90px + var(--hx-my, 0) * -10px), 0);
    -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 62%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 0%, #000 62%, transparent 100%);
}

.hx-plate-drift {
    position: absolute;
    inset: 0;
}

.hx-plate-drift img {
    object-fit: cover;
    object-position: 64% 50%;
}

/* A slow breath of nebula light behind the astronaut. */
.hx-nebula {
    position: absolute;
    top: -8rem;
    right: -12rem;
    width: 62rem;
    height: 46rem;
    border-radius: 50%;
    background:
        radial-gradient(closest-side at 45% 45%, rgba(139, 92, 246, 0.2), transparent 70%),
        radial-gradient(closest-side at 62% 58%, rgba(14, 165, 233, 0.1), transparent 70%);
}

/* One quiet shooting star, every so often. */
.hx-meteor {
    position: absolute;
    top: 16%;
    left: 70%;
    width: 9rem;
    height: 1px;
    opacity: 0;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0.95), rgba(191, 219, 254, 0.4) 30%, transparent);
    box-shadow: 0 0 6px rgba(191, 219, 254, 0.6);
    transform: rotate(-18deg);
}

.hx-vignette {
    position: absolute;
    inset: 0;
    background: radial-gradient(120% 90% at 70% 40%, transparent 55%, rgba(6, 6, 9, 0.75) 100%);
}

/* Fades the lower hero into night so the astronaut sinks into darkness
   before passing behind the ticker. Above the astronaut, below the copy. */
.hx-fade {
    position: absolute;
    inset: auto 0 0;
    z-index: 2;
    height: 26%;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(2, 6, 23, 0) 0%, rgba(2, 6, 23, 0.65) 60%, var(--hx-night) 100%);
}

/* ---------- Layout: copy in the left two-thirds, the astronaut in the right third ---------- */

.hx-inner {
    position: relative;
    z-index: 3;
    display: grid;
    width: 100%;
    max-width: var(--hx-max);
    margin: 0 auto;
    /* Pulls back as you scroll away (driven by --hx-p). */
    opacity: clamp(0, calc(1 - var(--hx-p) * 1.35), 1);
    transform: translate3d(0, calc(var(--hx-p) * -80px), 0) scale(calc(1 - var(--hx-p) * 0.06));
    transform-origin: 0 50%;
}

.hx-copy {
    /* The full logo's width; the tagline and button start beneath the "N" of
       the wordmark, which sits 27.25% across the logo artwork. */
    --logo-w: clamp(19rem, 50vw, 44rem);
    --wordmark-x: calc(var(--logo-w) * 0.2725);
    min-width: 0;
}

/* ---------- Title: the full logo + "Built to move people." ---------- */

.hx-title {
    margin: 0;
    font-weight: 400;
}

.hx-mark {
    position: relative;
    display: block;
    width: var(--logo-w);
    margin-bottom: clamp(1.4rem, 3.4vh, 2.2rem);
}

.hx-mark img {
    position: relative;
    display: block;
    width: 100%;
    height: auto;
    filter: drop-shadow(0 0 30px rgba(139, 92, 246, 0.4));
}

/* A soft glow that breathes behind the logo. */
.hx-mark::before {
    content: "";
    position: absolute;
    inset: -90% -14%;
    background: radial-gradient(closest-side, rgba(139, 92, 246, 0.26), rgba(14, 165, 233, 0.08) 55%, transparent);
}

/* A band of brand light that sweeps across the logo now and then. */
.hx-mark::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(105deg,
        transparent 26%,
        rgba(196, 181, 253, 0.92) 38%,
        rgba(125, 211, 252, 0.92) 50%,
        rgba(244, 114, 182, 0.78) 62%,
        transparent 74%);
    background-size: 260% 100%;
    background-position: 100% 0;
    -webkit-mask: url("../../images/brand/logo-lockup.png") center / contain no-repeat;
    mask: url("../../images/brand/logo-lockup.png") center / contain no-repeat;
}

.hx-sub {
    display: block;
    margin-left: var(--wordmark-x);
    font-family: "Conthrax", "Manrope", sans-serif;
    /* Six disciplines rather than four short words, so the tagline wraps
       inside the lockup's width instead of being held on a single line. */
    font-size: clamp(0.72rem, 1.12vw, 1.12rem);
    font-weight: 600;
    line-height: 1.5;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: #fff;
}

.hx-sub-lines,
.hx-sub-line {
    display: block;
}

/* Three disciplines per line, set as two explicit rows. Letting all six
   flow and wrap instead left "Music" orphaned on a line of its own, with
   the star before it stranded at the end of the row above. */
.hx-sub-line {
    display: block;
    white-space: nowrap;
}

.hx-w,
.hx-ch {
    display: inline-block;
}

/* The separator between disciplines - the same four-pointed star the
   capabilities ticker uses below the hero, in plain white here rather than
   the ticker's cycling brand colours. */
.hx-star {
    display: inline-block;
    width: 0.62em;
    height: 0.62em;
    margin: 0 0.62em;
    vertical-align: 0.04em;
    background: #fff;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><path d='M5 0C5.4 3.2 6.8 4.6 10 5 6.8 5.4 5.4 6.8 5 10 4.6 6.8 3.2 5.4 0 5 3.2 4.6 4.6 3.2 5 0Z'/></svg>") center / contain no-repeat;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><path d='M5 0C5.4 3.2 6.8 4.6 10 5 6.8 5.4 5.4 6.8 5 10 4.6 6.8 3.2 5.4 0 5 3.2 4.6 4.6 3.2 5 0Z'/></svg>") center / contain no-repeat;
}

.hx-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem 1.5rem;
    margin-top: clamp(1.9rem, 4.6vh, 2.8rem);
    margin-left: var(--wordmark-x);
}

@media (min-width: 1024px) {
    .hx-inner {
        grid-template-columns: repeat(12, minmax(0, 1fr));
        column-gap: 1.5rem;
    }

    .hx-copy {
        grid-column: 1 / span 8;
    }
}

/* ---------- Primary CTA ---------- */

.hx-cta {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 1.1rem;
    height: 3.6rem;
    padding: 0 0.45rem 0 1.7rem;
    overflow: hidden;
    border-radius: 0.375rem;
    background: linear-gradient(100deg, var(--hx-purple) 0%, #5b4af0 48%, var(--hx-cyan) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.28),
        0 14px 34px -14px rgba(124, 58, 237, 0.75);
    font-family: "Space Grotesk", sans-serif;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: #fff;
    text-decoration: none;
    isolation: isolate;
    transition: box-shadow 0.5s var(--hx-ease), transform 0.5s var(--hx-ease);
}

/* A single soft sheen that crosses the button on hover. */
.hx-cta::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, 0.28) 50%, transparent 70%);
    transform: translateX(-110%);
}

.hx-cta-arrow {
    display: inline-grid;
    place-items: center;
    width: 2.7rem;
    height: 2.7rem;
    border-radius: 0.25rem;
    background: rgba(2, 6, 23, 0.3);
    transition: background-color 0.5s var(--hx-ease);
}

.hx-cta-arrow svg {
    width: 1rem;
    height: 1rem;
    transition: transform 0.6s var(--hx-ease);
}

.hx-cta:focus-visible {
    outline: 2px solid #7dd3fc;
    outline-offset: 4px;
}

@media (hover: hover) and (pointer: fine) {
    .hx-cta:hover {
        transform: scale(1.035);
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, 0.32),
            0 18px 40px -14px rgba(124, 58, 237, 0.9),
            0 0 0 1px rgba(255, 255, 255, 0.08);
    }

    .hx-cta:hover::before {
        transform: translateX(110%);
        transition: transform 0.9s var(--hx-ease);
    }

    .hx-cta:hover .hx-cta-arrow {
        background: rgba(2, 6, 23, 0.5);
    }

    .hx-cta:hover .hx-cta-arrow svg {
        transform: translateY(2px);
    }
}

/* ---------- Scroll cue ---------- */

.hx-scroll {
    position: absolute;
    z-index: 3;
    left: max(var(--hx-gutter), calc((100% - var(--hx-max)) / 2));
    bottom: clamp(1.6rem, 4vh, 2.6rem);
    display: inline-flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.4rem 0;
    font-family: "Space Grotesk", sans-serif;
    font-size: 0.68rem;
    letter-spacing: 0.26em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.5);
    text-decoration: none;
    transition: color 0.4s var(--hx-ease), opacity 0.5s var(--hx-ease);
    opacity: calc(1 - var(--hx-p) * 4);
}

.hx-scroll:hover {
    color: #fff;
}

.hx-scroll-line {
    position: relative;
    width: 3.5rem;
    height: 1px;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.2);
}

.hx-scroll-line::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, #fff, transparent);
    transform: translateX(-100%);
    animation: hx-scan 2.8s var(--hx-ease) infinite;
}

@keyframes hx-scan {
    to { transform: translateX(100%); }
}

/* ---------- Astronaut ----------
   Layered so each motion stays simple:
   .hx-astro        scroll + pointer: descends, tumbles, recedes, drifts left
   .hx-astro-intro  the opening descent into the scene
   .hx-astro-sway   a slow sideways drift
   .hx-astro-float  weightless bob and roll
   .hx-astro-spin   a gentle tumble when clicked                              */

.hx-astro {
    position: absolute;
    z-index: 1;
    top: 50%;
    right: max(var(--hx-gutter), calc((100% - var(--hx-max)) / 2));
    width: var(--astro-w);
    margin-top: calc(var(--astro-w) * -0.75 + 2.25rem);
    aspect-ratio: 2 / 3;
    pointer-events: none;
    transform:
        translate3d(
            calc(var(--hx-mx, 0) * -18px - var(--hx-a) * 6vw),
            calc(var(--hx-a) * var(--hx-travel, 50vh) + var(--hx-my, 0) * -12px),
            0
        )
        rotate(calc(var(--hx-a) * 26deg + var(--hx-mx, 0) * 3deg))
        scale(calc(1 - var(--hx-a) * 0.16));
    will-change: transform;
}

.hx-astro-halo {
    position: absolute;
    inset: -18% -30% -10%;
    background:
        radial-gradient(closest-side at 50% 44%, rgba(139, 92, 246, 0.3), rgba(124, 58, 237, 0.1) 46%, transparent 72%),
        radial-gradient(closest-side at 30% 62%, rgba(14, 165, 233, 0.14), transparent 70%);
}

.hx-astro-intro,
.hx-astro-sway,
.hx-astro-float,
.hx-astro-spin {
    position: absolute;
    inset: 0;
}

.hx-astro-float,
.hx-astro-sway {
    will-change: transform;
}

.hx-astro picture,
.hx-astro-img {
    display: block;
    width: 100%;
    height: 100%;
}

.hx-astro-img {
    object-fit: contain;
    /* Rim light: cool cyan from the left, violet from the nebula behind. */
    filter:
        drop-shadow(-10px -4px 22px rgba(56, 189, 248, 0.2))
        drop-shadow(14px 10px 34px rgba(124, 58, 237, 0.4));
}

/* Grades the chrome with the environment's colour, masked to the suit. */
.hx-astro-tint {
    position: absolute;
    inset: 0;
    background: linear-gradient(205deg, rgba(56, 189, 248, 0.5) 0%, rgba(124, 58, 237, 0.45) 52%, rgba(244, 114, 182, 0.4) 100%);
    mix-blend-mode: soft-light;
    -webkit-mask: url("../../images/home/hero/astronaut-800.webp") center / contain no-repeat;
    mask: url("../../images/home/hero/astronaut-800.webp") center / contain no-repeat;
    opacity: 0.5;
}

@media (hover: hover) and (pointer: fine) {
    .hx-astro-spin {
        pointer-events: auto;
        cursor: grab;
    }
}

.hx-astro-spin.is-spinning {
    animation: hx-tumble 2.8s cubic-bezier(0.45, 0.05, 0.2, 1);
}

/* ---------- Tablet ---------- */

@media (max-width: 1023px) {
    .hx-inner {
        gap: 2.25rem;
    }

    .hx {
        --astro-w: clamp(14rem, 36vw, 22rem);
    }

    .hx-copy {
        max-width: 62%;
    }

    .hx-copy {
        --logo-w: clamp(19rem, 50vw, 28rem);
    }
}

/* ---------- Phone and small tablet, portrait: one centred stack ----------
   Logo and tagline at the top, the astronaut floating over the nebula in the
   middle, the button at the foot, all inside one screen at any phone size
   (svh: the height with the browser's toolbars showing). The middle row
   takes whatever height is left and the astronaut fills it. Short landscape
   phones keep the side-by-side layout further down. */

@media (max-width: 899px) and (orientation: portrait), (max-width: 899px) and (min-height: 501px) {
    .hx {
        /* The fixed nav bar's height (its logo row plus padding). */
        --nav-h: 5.7rem;
        display: grid;
        grid-template-rows: auto minmax(0, 1fr) auto;
        justify-items: center;
        row-gap: clamp(0.5rem, 2.2svh, 1.75rem);
        height: 100vh;
        height: 100svh;
        min-height: 0;
        padding:
            calc(env(safe-area-inset-top, 0px) + var(--nav-h) + clamp(0.25rem, 2.2svh, 2.25rem))
            var(--hx-gutter)
            calc(env(safe-area-inset-bottom, 0px) + clamp(1.1rem, 4.2svh, 2.75rem));
    }

    /* The copy's wrappers step aside so the title, the astronaut and the
       button share the hero's grid. */
    .hx-inner,
    .hx-copy {
        display: contents;
    }

    .hx-copy {
        --logo-w: min(80vw, 22rem, 46svh);
    }

    /* ----- Logo, with the tagline on one line beneath it ----- */

    .hx-title {
        grid-row: 1;
        position: relative;
        z-index: 3;
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        opacity: clamp(0, calc(1 - var(--hx-p) * 1.6), 1);
        translate: 0 calc(var(--hx-p) * -70px);
    }

    .hx-mark {
        margin-bottom: clamp(0.6rem, 1.7svh, 1.1rem);
    }

    /* Scaled to the logo. "Built" starts in line with the left stem of the
       monogram's N, 5.25% across the logo artwork (less the B's own 0.067em
       side bearing, so the letter itself lines up). */
    .hx-sub {
        margin-left: calc(var(--logo-w) * 0.0525 - 0.067em);
        /* Two lines inside the lockup's width at this scale. */
        font-size: calc(var(--logo-w) * 0.0335);
        letter-spacing: 0.03em;
    }

    /* ----- The astronaut, as tall as the middle row allows ----- */

    .hx-astro {
        position: relative;
        grid-row: 2;
        top: auto;
        right: auto;
        width: auto;
        /* Room above and below for its float, and never wider than ~70% of
           the screen, so the nebula still frames it. */
        height: min(92%, 105vw, 36rem);
        max-width: 100%;
        margin: 0;
        align-self: center;
    }

    .hx-astro-halo {
        inset: -8% -42% -4%;
    }

    /* A tap sends it tumbling, as a click does on desktop. */
    .hx-astro-spin {
        pointer-events: auto;
        -webkit-tap-highlight-color: transparent;
    }

    /* ----- Backdrop: the nebula plate centred behind the astronaut ----- */

    .hx-plate {
        top: 13%;
        bottom: 5%;
        width: 100%;
        -webkit-mask-image: none;
        mask-image: none;
    }

    .hx-plate-par {
        -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 24%, #000 66%, transparent 100%);
        mask-image: linear-gradient(180deg, transparent 0%, #000 24%, #000 66%, transparent 100%);
    }

    .hx-plate-drift img {
        object-position: 62% 50%;
    }

    .hx-nebula {
        top: 18%;
        right: auto;
        left: calc(50% - 22rem);
        width: 44rem;
        height: 40rem;
    }

    .hx-vignette {
        background: radial-gradient(140% 80% at 50% 52%, transparent 48%, rgba(6, 6, 9, 0.82) 100%);
    }

    .hx-fade {
        height: 16%;
    }

    .hx-scroll {
        display: none;
    }

    /* ----- The button: centred and wide at the foot ----- */

    .hx-actions {
        grid-row: 3;
        position: relative;
        z-index: 3;
        width: min(100%, 24rem);
        margin: 0;
        /* Gone before the sinking astronaut reaches it. */
        opacity: clamp(0, calc(1 - var(--hx-p) * 2.6), 1);
        translate: 0 calc(var(--hx-p) * -40px);
    }

    /* The label centres in the button: the left padding matches the arrow. */
    .hx-cta {
        width: 100%;
        height: clamp(3.4rem, 7.4svh, 3.85rem);
        padding: 0 0.5rem 0 3.25rem;
        font-size: 0.8rem;
        letter-spacing: 0.24em;
        -webkit-tap-highlight-color: transparent;
    }

    .hx-cta > span:first-child {
        flex: 1;
        text-align: center;
        white-space: nowrap;
    }

    .hx-cta-arrow {
        width: 2.75rem;
        height: calc(100% - 1rem);
    }

    .hx-cta:active {
        transform: scale(0.98);
        transition-duration: 0.15s;
    }
}

/* Small tablets: the same stack, scaled up to the wider screen. */
@media (min-width: 600px) and (max-width: 899px) and (orientation: portrait), (min-width: 600px) and (max-width: 899px) and (min-height: 501px) {
    .hx-copy {
        --logo-w: min(58vw, 30rem, 40svh);
    }

    .hx-astro {
        height: min(92%, 46rem);
    }

    .hx-actions {
        width: min(100%, 28rem);
    }

    .hx-cta {
        font-size: 0.86rem;
    }
}

/* The narrowest phones: tighter tracking keeps the label on one line. */
@media (max-width: 359px) {
    .hx-cta {
        letter-spacing: 0.15em;
    }
}

@media (max-width: 767px) {
    .hx-astro-tint {
        -webkit-mask-image: url("../../images/home/hero/astronaut-560.webp");
        mask-image: url("../../images/home/hero/astronaut-560.webp");
    }
}

/* Short landscape phones: astronaut beside the copy, not above it. */
@media (max-width: 1023px) and (max-height: 500px) and (orientation: landscape) {
    /* One screen tall; the copy and the astronaut centre in the space below
       the nav, the astronaut as tall as that space allows. */
    .hx {
        --astro-w: min(clamp(8rem, 22vw, 14rem), calc((100svh - 7.5rem) / 1.5));
        flex-direction: row;
        justify-content: flex-start;
        align-items: center;
        height: 100vh;
        height: 100svh;
        min-height: 0;
        padding-top: calc(env(safe-area-inset-top, 0px) + 5.7rem);
        padding-bottom: 1rem;
    }

    .hx-copy {
        max-width: 60%;
    }

    .hx-copy {
        --logo-w: min(46vw, 22rem, 64svh);
    }

    .hx-sub {
        font-size: clamp(0.66rem, 1.5svh, 0.86rem);
    }

    .hx-actions {
        margin-top: clamp(1rem, 5svh, 2rem);
    }

    .hx-astro {
        right: 4vw;
    }

    .hx-scroll {
        display: none;
    }
}

/* ---------- Opening sequence and ambient motion ----------
   Plays once the page shell is revealed. Everything rests in its final
   state by default, so nothing stays hidden if this never runs. */

@media (prefers-reduced-motion: no-preference) {
    /* The backdrop waits (hidden) until its photographs are decoded, then
       fades in; so it never appears half-loaded or snaps in late. */
    .hx.is-bg-waiting .hx-space,
    .hx.is-bg-waiting .hx-plate {
        opacity: 0;
    }

    .hx.is-bg-ready .hx-space {
        animation: hx-fade-in 2.4s ease both;
    }

    .hx.is-bg-ready .hx-plate {
        animation: hx-plate-in 2.6s var(--hx-ease) both;
    }

    /* Starts from its first frame (fill "both"), so there is no jump when the
       slow drift takes over from the fade-in. */
    .hx.is-bg-ready .hx-plate-drift {
        animation: hx-plate-drift 42s ease-in-out 2.4s infinite alternate both;
    }

    .page-shell-ready .hx-nebula {
        animation: hx-breathe 11s ease-in-out infinite alternate;
    }

    .page-shell-ready .hx-meteor {
        animation: hx-meteor 13s linear 5s infinite;
    }

    .page-shell-ready .hx-mark {
        animation: hx-mark-in 1.6s var(--hx-ease) 0.35s both;
    }

    .page-shell-ready .hx-mark::before {
        animation: hx-breathe 7s ease-in-out 2s infinite alternate both;
    }

    .page-shell-ready .hx-mark::after {
        animation: hx-sheen 11s ease-in-out 1.2s infinite alternate both;
    }

    .page-shell-ready .hx-ch,
    .page-shell-ready .hx-star {
        animation: hx-gather 1.8s var(--hx-ease) both;
        animation-delay: calc(0.7s + var(--i, 0) * 0.035s);
    }

    .page-shell-ready .hx-actions {
        animation: hx-rise-soft 1.1s var(--hx-ease) 1.45s both;
    }

    .page-shell-ready .hx-scroll {
        animation: hx-fade-in 1.2s ease 2s both;
    }

    /* The astronaut drifts down out of the dark and settles into its float. */
    .page-shell-ready .hx-astro-intro {
        animation: hx-descend 3.4s cubic-bezier(0.16, 1, 0.3, 1) 0.2s both;
    }

    .page-shell-ready .hx-astro-sway {
        animation: hx-sway 21s ease-in-out 3s infinite;
    }

    .page-shell-ready .hx-astro-float {
        animation: hx-float 13s ease-in-out infinite;
    }

    .page-shell-ready .hxn-inner {
        animation: hx-fade-in 0.9s var(--hx-ease) 0.1s both;
    }
}

/* Phones and small tablets have no hover, so the button's sheen crosses on
   its own every few seconds once the opening has played. */
@media (max-width: 899px) and (prefers-reduced-motion: no-preference) {
    .page-shell-ready .hx-cta::before {
        animation: hx-cta-sheen 6.5s var(--hx-ease) 3.4s infinite;
    }
}

/* ---------- Phones and small tablets: the header ----------
   The bar and its menu button are there from the first frame, steady (no
   fade of their own, which could leave them unseen). Its logo waits while
   the hero's logo is on screen, then flies up out of it into the bar as the
   visitor scrolls past (assets/js/home/hero.js sets html.hx-dock and drives
   the flight); scrolling back up returns it. */

@media (max-width: 899px) {
    .page-shell-ready .hxn-inner {
        animation: none;
    }

    .hx-dock .hxn-logo {
        opacity: 0;
        transform-origin: 0 0;
        will-change: transform, opacity;
    }

    /* With the menu open, the logo sits in the bar whatever the scroll. */
    .hx-dock.hxn-open .hxn-logo {
        opacity: 1 !important;
        transform: none !important;
        transition: opacity 0.35s ease, height 0.55s var(--hx-ease);
    }
}

@keyframes hx-cta-sheen {
    0% { transform: translateX(-110%); }
    26%, 100% { transform: translateX(110%); }
}

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

@keyframes hx-rise-soft {
    from { opacity: 0; transform: translate3d(0, 14px, 0); }
}

@keyframes hx-plate-in {
    from { opacity: 0; transform: scale(1.07); }
    to { opacity: 1; transform: none; }
}

@keyframes hx-plate-drift {
    from { transform: scale(1.03) translate3d(0, 0, 0); }
    to { transform: scale(1.11) translate3d(-1.8%, 1.2%, 0); }
}

@keyframes hx-breathe {
    from { opacity: 0.55; transform: scale(1); }
    to { opacity: 1; transform: scale(1.06); }
}

@keyframes hx-meteor {
    0%, 90% { opacity: 0; transform: rotate(-18deg) translate3d(0, 0, 0); }
    91% { opacity: 1; }
    96% { opacity: 0; transform: rotate(-18deg) translate3d(-32vw, 0, 0); }
    100% { opacity: 0; transform: rotate(-18deg) translate3d(-32vw, 0, 0); }
}

@keyframes hx-mark-in {
    from { opacity: 0; transform: scale(0.82); filter: blur(12px); }
    60% { filter: blur(0); }
    to { opacity: 1; transform: none; filter: none; }
}

@keyframes hx-sheen {
    from { background-position: 100% 0; }
    to { background-position: 0% 0; }
}

@keyframes hx-gather {
    0% { opacity: 0; transform: translate3d(var(--x), var(--y), 0) rotate(var(--r)) scale(0.82); filter: blur(5px); }
    45% { opacity: 1; filter: blur(0); }
    100% { opacity: 1; transform: none; filter: none; }
}

@keyframes hx-descend {
    0% { opacity: 0; transform: translate3d(3vw, -68vh, 0) rotate(-28deg) scale(0.86); }
    30% { opacity: 1; }
    100% { opacity: 1; transform: none; }
}

@keyframes hx-sway {
    0%, 100% { transform: translate3d(0, 0, 0); }
    50% { transform: translate3d(-1rem, 0.4rem, 0); }
}

@keyframes hx-float {
    0%   { transform: translate3d(0, 0, 0) rotate(-1.6deg); }
    25%  { transform: translate3d(0.35rem, -0.9rem, 0) rotate(0.2deg); }
    50%  { transform: translate3d(0, -1.4rem, 0) rotate(1.5deg); }
    75%  { transform: translate3d(-0.35rem, -0.6rem, 0) rotate(0.1deg); }
    100% { transform: translate3d(0, 0, 0) rotate(-1.6deg); }
}

/* A clicked astronaut tumbles once through zero gravity, then rights itself. */
@keyframes hx-tumble {
    0% { transform: none; }
    45% { transform: translate3d(-1.4rem, -1.2rem, 0) rotate(200deg); }
    100% { transform: rotate(360deg); }
}

/* ==========================================================================
   Capabilities ticker — the first chapter break
   ========================================================================== */

.hxm {
    position: relative;
    z-index: 6;
    padding: 1.35rem 0 1.45rem;
    background: var(--hx-night);
    color: #fff;
}

/* Every section after the hero stacks above the drifting astronaut
   (same contract the previous hero had with the page). */
.hxm ~ section {
    position: relative;
    z-index: 6;
}

/* A horizon line of brand light where the hero ends. */
.hxm::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent 0%, rgba(124, 58, 237, 0.7) 22%, rgba(14, 165, 233, 0.85) 50%, rgba(244, 114, 182, 0.6) 78%, transparent 100%);
}

.hxm::after {
    content: "";
    position: absolute;
    left: 20%;
    right: 20%;
    top: -1.5rem;
    height: 3rem;
    pointer-events: none;
    background: radial-gradient(closest-side, rgba(14, 165, 233, 0.16), transparent);
}

.hxm-viewport {
    overflow: hidden;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}

.hxm-track {
    display: flex;
    width: max-content;
    animation: hxm-scroll 40s linear infinite;
}

.hxm-group {
    display: flex;
    align-items: center;
    flex: none;
    gap: clamp(1rem, 1.6vw, 1.5rem);
    margin: 0;
    padding: 0 clamp(1rem, 1.6vw, 1.5rem) 0 0;
    list-style: none;
}

.hxm-item {
    display: inline-flex;
    align-items: center;
    gap: clamp(1rem, 1.6vw, 1.5rem);
    font-family: "Manrope", sans-serif;
    font-size: clamp(0.82rem, 1vw, 0.95rem);
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    white-space: nowrap;
    color: rgba(240, 240, 250, 0.84);
}

/* Each discipline sits in its own container, led by an icon in its colour. */
.hxm-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.8rem 1.15rem 0.8rem 0.95rem;
    border: 1px solid rgba(255, 255, 255, 0.09);
    border-radius: 0.375rem;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.055), rgba(255, 255, 255, 0.02));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

.hxm-icon {
    flex: none;
    width: 1.3rem;
    font-size: 1.3rem;
    line-height: 1;
    overflow: hidden;
    color: var(--hxm-c, var(--hx-purple));
}

.hxm-item::after {
    content: "";
    width: 0.62rem;
    height: 0.62rem;
    flex: none;
    background: var(--hxm-c, var(--hx-purple));
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><path d='M5 0C5.4 3.2 6.8 4.6 10 5 6.8 5.4 5.4 6.8 5 10 4.6 6.8 3.2 5.4 0 5 3.2 4.6 4.6 3.2 5 0Z'/></svg>") center / contain no-repeat;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><path d='M5 0C5.4 3.2 6.8 4.6 10 5 6.8 5.4 5.4 6.8 5 10 4.6 6.8 3.2 5.4 0 5 3.2 4.6 4.6 3.2 5 0Z'/></svg>") center / contain no-repeat;
}

.hxm-item:nth-child(3n + 2) {
    --hxm-c: var(--hx-cyan);
}

.hxm-item:nth-child(3n) {
    --hxm-c: var(--hx-pink);
}

@keyframes hxm-scroll {
    to { transform: translate3d(-50%, 0, 0); }
}

@media (max-width: 767px) {
    .hxm {
        padding: 1.25rem 0 1.35rem;
    }

    .hxm-track {
        animation-duration: 30s;
    }
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    .hx-astro-float,
    .hx-astro-sway,
    .hx-astro-spin,
    .hx-scroll-line::after {
        animation: none !important;
    }

    .hx-astro,
    .hx-inner,
    .hx-space,
    .hx-plate-par {
        transform: none;
    }

    .hx-inner {
        opacity: 1;
    }

    .hx-meteor {
        display: none;
    }

    .hx-astro-spin {
        pointer-events: none;
    }

    .hxm-track {
        animation: none;
        width: auto;
        justify-content: center;
    }

    .hxm-group {
        flex-wrap: wrap;
        justify-content: center;
        row-gap: 0.9rem;
        padding: 0 var(--hx-gutter);
    }

    .hxm-group[aria-hidden="true"] {
        display: none;
    }

    .hxm-viewport {
        -webkit-mask-image: none;
        mask-image: none;
    }

    .hx-cta,
    .hx-cta::before {
        transition: none;
    }
}

/* ==========================================================================
   Skip link: hidden until a keyboard user tabs to it.
   ========================================================================== */

.skip-link {
    position: fixed;
    z-index: 100;
    top: 0.75rem;
    left: 0.75rem;
    padding: 0.75rem 1.1rem;
    border-radius: 0.5rem;
    background: #fff;
    color: #0c0b1d;
    font-family: "Manrope", sans-serif;
    font-size: 0.95rem;
    font-weight: 700;
    text-decoration: none;
    transform: translateY(-160%);
    transition: transform 0.25s ease;
}

.skip-link:focus {
    transform: none;
    outline: 2px solid #7c3aed;
    outline-offset: 2px;
}

main:focus {
    outline: none;
}
