/* =====================================================================
   Woulfe's K9 — Homepage Hero
   Depends on tokens.css.

   Layer order, bottom to top:
     0  .wk9-hero__bg      cross-fading images (also the video's poster)
     0  .wk9-hero__video   background video, fades in when ready
     1  .wk9-hero__shade   tint + bottom fade; guarantees headline contrast
     2  .wk9-hero__inner   content
   ===================================================================== */

.wk9-hero {
    --wk9-hero-blur: 0px;
    --wk9-hero-saturate: 0.7;
    --wk9-hero-overlay: 0.38;
    /* How far up the bottom fade reaches. The hero dissolves into the page
       rather than ending on a seam. */
    --wk9-hero-fade: 55%;
    /* The colour the fade resolves to. It MUST match whatever section sits
       directly beneath the hero, or the join shows as a hard line — on the
       homepage that is the media carousel's band, not the page black. */
    --wk9-hero-fade-to: var(--k9-surface-band);
    --wk9-hero-height: 88vh;

    position: relative;
    /* Height now applies to the TEXT block, not the section — the section has
       to grow for the video card underneath it. */
    display: flex;
    flex-direction: column;
    justify-content: center;
    overflow: hidden;
    isolation: isolate;
    background: var(--k9-black);
    color: var(--k9-white);
    font-family: var(--k9-font-body);

    /* Full-bleed out of whatever container it's dropped into. */
    left: 50%;
    right: 50%;
    width: 100vw;
    margin-left: -50vw;
    margin-right: -50vw;
    max-width: 100vw;
}

.wk9-hero *,
.wk9-hero *::before,
.wk9-hero *::after {
    box-sizing: border-box;
}

/* Builders wrap shortcodes in containers with their own top padding, which
   would otherwise sit above the hero as a band of page background. */
body.wk9-hero-page #Content > .section_wrapper,
body.wk9-hero-page .vc_row:first-child,
body.wk9-hero-page .entry-content,
body.wk9-hero-page .wpb_wrapper {
    padding-top: 0 !important;
    margin-top: 0 !important;
}

/* ---------------------------------------------------------------------
   Background
   ------------------------------------------------------------------- */

.wk9-hero__bg {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
}

.wk9-hero__image,
.wk9-hero__placeholder {
    position: absolute !important;
    inset: 0 !important;
    width: 100% !important;
    height: 100% !important;
    max-width: none !important;
    margin: 0 !important;
    object-fit: cover !important;
    display: block !important;
    /* Desaturated so photography reads as texture, not colour — the system
       stays monochrome even behind a full-colour photo.

       Blur is authored in the admin as one absolute px value, but a blur reads
       relative to the image it is on: 16px across a 1440px desktop backdrop is
       a hint of depth, while the same 16px across a 390px phone is a third of
       the visible detail and turns the photo to grey mush. The admin value is
       therefore a desktop figure that mobile scales down — via a multiplier,
       because --wk9-hero-blur itself is set inline on the section and no
       stylesheet rule can override it. */
    filter:
        blur(calc(var(--wk9-hero-blur) * var(--wk9-hero-blur-scale, 1)))
        saturate(var(--wk9-hero-saturate))
        contrast(1.08);
    transform: scale(1.08);
    opacity: 0;
    transition: opacity 1.6s var(--k9-ease);
    will-change: opacity;
}

.wk9-hero__placeholder {
    background: radial-gradient(120% 90% at 50% 0%, var(--k9-ink-700) 0%, var(--k9-black) 62%);
    filter: none;
    transform: none;
    opacity: 1;
}

.wk9-hero__image.is-active {
    opacity: 1;
    animation: wk9-hero-drift 20s ease-out forwards;
}

@keyframes wk9-hero-drift {
    from { transform: scale(1.08); }
    to   { transform: scale(1.16); }
}

/* Video ---------------------------------------------------------------
   Sits over the images, which stay underneath as the poster while it loads
   and as the fallback wherever it's suppressed. Fades in on .is-ready so
   there's no black flash. */

.wk9-hero__video {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    opacity: 0;
    transition: opacity 1.2s var(--k9-ease);
    filter: blur(var(--wk9-hero-blur)) saturate(var(--wk9-hero-saturate)) contrast(1.08);
    transform: scale(1.08);
}

.wk9-hero__video.is-ready { opacity: 1; }

.wk9-hero__video video {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    min-width: 100%;
    min-height: 100%;
    width: auto;
    height: auto;
    object-fit: cover;
    display: block;
}

/* An iframe can't be object-fit, so JS sizes it to cover the hero box.
   This is the no-JS fallback, correct whenever the hero is wider than 16:9. */
.wk9-hero__video--embed iframe {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    height: auto;
    aspect-ratio: var(--wk9-hero-video-ratio, 1.7778);
    border: 0;
    display: block;
}

/* Video is a heavy download on mobile data, and once blurred it looks the
   same as the still. Opt in per-hero if it's genuinely worth it. */
@media (max-width: 768px) {
    .wk9-hero__video:not(.wk9-hero__video--mobile) { display: none; }
}

/* Motion is the entire point of the video, so drop it rather than freeze it. */
@media (prefers-reduced-motion: reduce) {
    .wk9-hero__video { display: none; }
    .wk9-hero__image.is-active { animation: none; }
}

.wk9-hero__shade {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    /* Two layers, top of the list paints last.

       The bottom fade reaches its target colour at FULL opacity, not a
       fraction of the overlay. That is the whole point: the hero has to arrive
       at exactly the colour of the section below at y=100%, or the join reads
       as a hard line. See --wk9-hero-fade-to.

       The tint underneath is deliberately light now the background is sharp —
       it is there to keep the headline legible, not to hide the photograph. */
    background:
        linear-gradient(
            to top,
            var(--wk9-hero-fade-to) 0%,
            color-mix(in srgb, var(--wk9-hero-fade-to) 75%, transparent) calc(var(--wk9-hero-fade) * 0.3),
            color-mix(in srgb, var(--wk9-hero-fade-to) 28%, transparent) calc(var(--wk9-hero-fade) * 0.65),
            color-mix(in srgb, var(--wk9-hero-fade-to) 0%, transparent) var(--wk9-hero-fade)
        ),
        linear-gradient(
            180deg,
            rgba(var(--k9-black-rgb), var(--wk9-hero-overlay)) 0%,
            rgba(var(--k9-black-rgb), calc(var(--wk9-hero-overlay) * 0.65)) 45%,
            rgba(var(--k9-black-rgb), calc(var(--wk9-hero-overlay) * 0.8)) 100%
        );
}

/* ---------------------------------------------------------------------
   Content
   ------------------------------------------------------------------- */

.wk9-hero__inner {
    position: relative;
    z-index: 2;
    width: min(var(--k9-container), calc(100% - (var(--k9-gutter) * 2)));
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--k9-space-5);
    padding: var(--k9-space-16) 0;
}

.wk9-hero__eyebrow {
    margin: 0;
    font-size: var(--k9-text-micro);
    font-weight: var(--k9-weight-bold);
    letter-spacing: var(--k9-tracking-micro);
    text-transform: uppercase;
    color: var(--k9-grey-200);
}

.wk9-hero__headline {
    margin: 0;
    max-width: 16ch;
    font-family: var(--k9-font-display);
    font-size: var(--k9-text-display-lg);
    font-weight: var(--k9-weight-display);
    line-height: var(--k9-leading-display);
    letter-spacing: var(--k9-tracking-display);
    text-transform: uppercase;
    text-wrap: balance;
    color: var(--k9-white);
}

/* Each word rises and resolves out of a blur. The blur is what stops a
   heavy display face reading as a blunt slide. */
.wk9-hero__word {
    display: inline-block;
    opacity: 0;
    transform: translateY(0.3em);
    filter: blur(12px);
    transition:
        opacity 900ms var(--k9-ease),
        transform 900ms var(--k9-ease),
        filter 900ms var(--k9-ease);
    transition-delay: var(--wk9-word-delay, 0ms);
    will-change: opacity, transform, filter;
}

.wk9-hero.is-in .wk9-hero__word {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
}

.wk9-hero__lede {
    margin: 0;
    max-width: 52ch;
    font-size: var(--k9-text-body-lg);
    line-height: var(--k9-leading-body);
    color: var(--k9-grey-200);
    opacity: 0;
    transform: translateY(14px);
    transition:
        opacity 800ms var(--k9-ease) 320ms,
        transform 800ms var(--k9-ease) 320ms;
}

.wk9-hero.is-in .wk9-hero__lede {
    opacity: 1;
    transform: translateY(0);
}

/* Actions ------------------------------------------------------------- */

.wk9-hero__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--k9-space-3);
    margin-top: var(--k9-space-2);
    opacity: 0;
    transform: translateY(14px);
    transition:
        opacity 800ms var(--k9-ease) 440ms,
        transform 800ms var(--k9-ease) 440ms;
}

.wk9-hero.is-in .wk9-hero__actions {
    opacity: 1;
    transform: translateY(0);
}

.wk9-hero__cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 56px;
    padding: var(--k9-space-4) var(--k9-space-8);
    border: var(--k9-border-width) solid transparent;
    border-radius: var(--k9-radius-pill);
    background: var(--k9-white);
    color: var(--k9-black);
    font-family: var(--k9-font-body);
    font-size: var(--k9-text-body-sm);
    font-weight: var(--k9-weight-bold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    text-decoration: none;
    line-height: 1.2;
    cursor: pointer;
    transition:
        transform var(--k9-duration) var(--k9-ease),
        background var(--k9-duration) var(--k9-ease);
}

.wk9-hero__cta:hover,
.wk9-hero__cta:focus-visible {
    transform: translateY(-2px);
    background: var(--k9-grey-100);
    color: var(--k9-black);
}

.wk9-hero__cta--ghost {
    background: rgba(255, 255, 255, 0.08);
    color: var(--k9-white);
    border-color: rgba(255, 255, 255, 0.38);
    backdrop-filter: blur(10px) saturate(140%);
    -webkit-backdrop-filter: blur(10px) saturate(140%);
}

.wk9-hero__cta--ghost:hover,
.wk9-hero__cta--ghost:focus-visible {
    background: var(--k9-white);
    color: var(--k9-black);
    border-color: var(--k9-white);
}

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

.wk9-hero__cue {
    position: absolute;
    z-index: 2;
    left: 50%;
    bottom: var(--k9-space-6);
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--k9-space-2);
    pointer-events: none;
    opacity: 0;
    transition: opacity 800ms var(--k9-ease) 900ms;
}

.wk9-hero.is-in .wk9-hero__cue { opacity: 1; }

.wk9-hero__cue-label {
    font-size: var(--k9-text-micro);
    font-weight: var(--k9-weight-bold);
    letter-spacing: var(--k9-tracking-micro);
    text-transform: uppercase;
    color: var(--k9-grey-300);
}

.wk9-hero__cue-line {
    width: 1px;
    height: 42px;
    background: linear-gradient(180deg, var(--k9-grey-300), transparent);
    position: relative;
    overflow: hidden;
}

.wk9-hero__cue-line::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--k9-white);
    animation: wk9-hero-cue 2.2s var(--k9-ease) infinite;
}

@keyframes wk9-hero-cue {
    0%   { transform: translateY(-100%); }
    60%  { transform: translateY(100%); }
    100% { transform: translateY(100%); }
}

@media (prefers-reduced-motion: reduce) {
    .wk9-hero__cue-line::after { animation: none; opacity: 0.4; }

    /* Entrance animations collapse to "already there". */
    .wk9-hero__word,
    .wk9-hero__lede,
    .wk9-hero__actions,
    .wk9-hero__cue {
        opacity: 1 !important;
        transform: none !important;
        filter: none !important;
        transition: none !important;
    }
}

/* ---------------------------------------------------------------------
   Mobile

   NOTE: the two-column block further down re-declares .wk9-hero__inner and
   .wk9-hero__actions OUTSIDE a media query, so anything set here that it also
   sets is overridden at every width — this block cannot be trusted to have
   the last word. Mobile layout therefore lives in one place, at the very
   bottom of this file, after every desktop rule. Keep it that way.
   ------------------------------------------------------------------- */

@media (max-width: 768px) {
    .wk9-hero {
        height: auto;
        min-height: 78vh;
    }

    .wk9-hero__headline { max-width: 14ch; }

    .wk9-hero__lede { font-size: var(--k9-text-body); }

    /* Full-width stacked buttons beat two cramped pills on a phone. */
    .wk9-hero__actions { flex-direction: column; }

    .wk9-hero__cta { width: 100%; }
}

/* =====================================================================
   Two-column top block

   Headline left, supporting copy + actions right. The eyebrow keeps its
   rule on the same baseline as the text via flex, not a ::before offset,
   so it survives the label wrapping.
   ===================================================================== */

.wk9-hero__inner {
    padding-top: calc(var(--wk9-header-offset, 88px) + var(--k9-space-10));
    padding-bottom: 0;
    /* The centred layout stretched its children to content width. The video
       card's children are all absolutely positioned, so its content width was
       zero and aspect-ratio gave it zero height — the card vanished. */
    align-items: stretch;
    text-align: left;
}

.wk9-hero__top,
.wk9-hero__media { width: 100%; }

.wk9-hero__top {
    display: grid;
    /* Copy left, portrait video right. The video column is narrower because a
       9:16 card gets tall fast — at anything wider it drives the whole hero
       past the fold on a laptop. */
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    align-items: center;
    gap: var(--k9-space-16);
    min-height: calc(var(--wk9-hero-height) - 220px);
    text-align: left;
    padding-bottom: var(--k9-space-12);
}

.wk9-hero__lead {
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--k9-space-6);
}

.wk9-hero__eyebrow {
    display: flex;
    align-items: center;
    gap: var(--k9-space-3);
}

.wk9-hero__eyebrow-rule {
    display: block;
    width: 44px;
    height: 1px;
    flex: 0 0 44px;
    background: var(--k9-text-muted);
}

/* Monochrome emphasis: the headline sits back in grey and the accent word
   comes forward in pure white. Contrast is the accent — there is no hue to
   reach for, and none is wanted. */
.wk9-hero__headline { color: var(--k9-text-secondary); }
.wk9-hero__word.is-accent { color: var(--k9-text); }

.wk9-hero__lede { margin: 0; max-width: 46ch; }
.wk9-hero__actions { margin: 0; }

/* Stat row under the buttons. A <dl>, with the figure as the term and the
   wording as the description — the number is the thing being defined, so it
   comes first both visually and in the markup. */
.wk9-hero__stats {
    margin: var(--k9-space-2) 0 0;
    padding: var(--k9-space-6) 0 0;
    border-top: 1px solid var(--k9-line);
    display: flex;
    flex-wrap: wrap;
    gap: var(--k9-space-8);
    width: 100%;
    max-width: 620px;
}

.wk9-hero__stat {
    position: relative;
    min-width: 0;
    padding-right: var(--k9-space-8);
}

.wk9-hero__stat:not(:last-child)::after {
    content: "";
    position: absolute;
    right: 0;
    top: 2px;
    bottom: 2px;
    width: 1px;
    background: var(--k9-line);
}

.wk9-hero__stat-value {
    margin: 0 0 var(--k9-space-1);
    font-family: var(--k9-font-display);
    font-weight: var(--k9-weight-display);
    font-size: var(--k9-text-title-lg);
    line-height: 1;
    letter-spacing: var(--k9-tracking-display);
    color: var(--k9-text);
}

.wk9-hero__stat-label {
    margin: 0;
    font-size: var(--k9-text-micro);
    font-weight: var(--k9-weight-semibold);
    letter-spacing: var(--k9-tracking-micro);
    text-transform: uppercase;
    color: var(--k9-text-muted);
}

/* =====================================================================
   Video card
   ===================================================================== */

.wk9-hero__media {
    min-width: 0;
    justify-self: end;
    width: 100%;
    max-width: 460px;
}

/* Deck ---------------------------------------------------------------
   A stack of cards, fanned. Every card is absolutely positioned except the
   first, which stays in flow so the deck keeps a real height — a container
   of nothing but absolute children collapses, and the aspect-ratio would
   have nothing to work from.
   ------------------------------------------------------------------- */

.wk9-deck {
    position: relative;
    /* Room either side for the fanned cards to lean into without clipping. */
    padding: 0 var(--k9-space-4);
}

.wk9-card {
    position: relative;
    overflow: hidden;
    border-radius: var(--k9-radius-xl);
    border: 1px solid var(--k9-line);
    background: var(--k9-surface-card);
    box-shadow: var(--k9-shadow-4);
    /* Portrait — the format the clips are actually shot in. */
    aspect-ratio: 9 / 16;
    max-height: 76vh;
}

.wk9-deck .wk9-card {
    transition:
        transform var(--k9-duration-slow) var(--k9-ease-spring),
        opacity var(--k9-duration-slow) var(--k9-ease),
        filter var(--k9-duration-slow) var(--k9-ease);
    transform-origin: 50% 100%;
}

.wk9-deck .wk9-card + .wk9-card {
    position: absolute;
    inset: 0 var(--k9-space-4);
}

/* Depth positions. data-pos is rewritten by the JS as the deck cycles, so the
   angles belong to the SLOT, not to any particular card. */
.wk9-deck .wk9-card[data-pos="0"] {
    transform: rotate(0deg) translateY(0) scale(1);
    opacity: 1;
    z-index: 3;
}

.wk9-deck .wk9-card[data-pos="1"] {
    transform: rotate(4.5deg) translate(14px, -14px) scale(0.955);
    opacity: 0.75;
    filter: saturate(0.5) brightness(0.72);
    z-index: 2;
}

.wk9-deck .wk9-card[data-pos="2"] {
    transform: rotate(-4deg) translate(-16px, -24px) scale(0.915);
    opacity: 0.5;
    filter: saturate(0.35) brightness(0.58);
    z-index: 1;
}

/* Anything deeper than the third slot hides behind the stack. */
.wk9-deck .wk9-card:not([data-pos="0"]):not([data-pos="1"]):not([data-pos="2"]) {
    transform: rotate(0deg) translateY(-30px) scale(0.9);
    opacity: 0;
    z-index: 0;
}

/* Only the front card is interactive — the ones behind are scenery. */
.wk9-deck .wk9-card:not([data-pos="0"]) { pointer-events: none; }

/* Desktop: the controls sit in a column beside the card, the way a reel is
   driven on a desktop screen — thumb-side, not underneath. The media block
   becomes the row, so the arrows take their own track and never overlap the
   footage. */
.wk9-hero__media {
    display: flex;
    align-items: center;
    gap: var(--k9-space-4);
}

.wk9-deck { flex: 1 1 auto; min-width: 0; }

.wk9-deck__nav {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--k9-space-4);
    flex: 0 0 auto;
}

.wk9-deck__arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    flex: 0 0 46px;
    padding: 0;
    border: 1px solid var(--k9-line-strong);
    border-radius: var(--k9-radius-pill);
    background: rgba(var(--k9-black-rgb), 0.35);
    color: var(--k9-text);
    cursor: pointer;
    transition:
        background var(--k9-duration-fast) var(--k9-ease),
        border-color var(--k9-duration-fast) var(--k9-ease);
}

.wk9-deck__arrow:hover {
    background: var(--k9-action);
    border-color: var(--k9-action);
    color: var(--k9-action-text);
}

.wk9-deck__arrow:focus-visible {
    outline: none;
    box-shadow: var(--k9-focus-ring);
}

/* Stacked, the chevrons have to read as up/down. CSS rotates clockwise for a
   positive angle, so +90deg takes the left chevron to "up" (previous) and the
   right one to "down" (next). -90deg inverts the pair. */
.wk9-deck__arrow svg { transform: rotate(90deg); }

.wk9-deck__count {
    font-size: var(--k9-text-micro);
    font-weight: var(--k9-weight-bold);
    letter-spacing: var(--k9-tracking-micro);
    text-transform: uppercase;
    color: var(--k9-text-muted);
    font-variant-numeric: tabular-nums;
    min-width: 54px;
    text-align: center;
}

.wk9-card__poster,
.wk9-card__video,
.wk9-card__placeholder {
    position: absolute;
    inset: 0;
}

.wk9-card__poster {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* An iframe cannot be object-fit, so the player is oversized and centred:
   whichever axis binds gets 100%, the other overflows and is clipped. */
/* A 16:9 player inside a 9:16 frame: height binds, so the player is sized off
   the card's height and the excess width is clipped either side. */
.wk9-card__video iframe {
    position: absolute;
    top: 50%;
    left: 50%;
    height: 100%;
    width: 177.78%;           /* 16:9 of the height */
    min-width: 100%;
    transform: translate(-50%, -50%);
    border: 0;
    pointer-events: none;
}

.wk9-card__placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--k9-space-6);
    text-align: center;
    background: var(--k9-surface-inset);
    color: var(--k9-text-faint);
    font-size: var(--k9-text-body-sm);
}

/* Darkens the lower half so the stat row always has something to sit on,
   whatever frame the clip happens to be showing. */
.wk9-card__shade {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(
        to top,
        rgba(var(--k9-black-rgb), 0.85) 0%,
        rgba(var(--k9-black-rgb), 0.35) 34%,
        rgba(var(--k9-black-rgb), 0) 62%
    );
}

.wk9-card__play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 104px;
    height: 104px;
    padding: 0 0 0 6px;      /* optical centring for the triangle */
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: var(--k9-radius-pill);
    background: rgba(255, 255, 255, 0.14);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    color: var(--k9-white);
    cursor: pointer;
    transition:
        background var(--k9-duration) var(--k9-ease),
        transform var(--k9-duration) var(--k9-ease);
}

.wk9-card__play:hover {
    background: var(--k9-action);
    color: var(--k9-action-text);
    transform: translate(-50%, -50%) scale(1.06);
}

.wk9-card__play:focus-visible {
    outline: none;
    box-shadow: var(--k9-focus-ring);
}

/* Stats -------------------------------------------------------------- */

/* Glass panel, inset from the bottom-left corner. The blur is what makes it
   read as a pane over the footage rather than a caption printed on it — but
   it is backed by a real translucent fill, so where backdrop-filter is
   unsupported the numbers stay legible instead of sitting on bare video. */
/* A panel in the bottom-left corner, sized to its contents rather than
   stretched across the card. Three stats will not sit in a row inside a
   portrait frame without shrinking to nothing, so they stack — which is also
   what makes it read as a floating pane rather than a caption bar. */
.wk9-card__stats {
    position: absolute;
    left: var(--k9-space-5);
    bottom: var(--k9-space-5);
    max-width: calc(100% - (var(--k9-space-5) * 2));
    margin: 0;
    padding: var(--k9-space-4) var(--k9-space-5);
    display: flex;
    flex-direction: column;
    gap: var(--k9-space-3);
    border-radius: var(--k9-radius-lg);
    border: 1px solid rgba(255, 255, 255, 0.14);
    background: rgba(var(--k9-black-rgb), 0.42);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    backdrop-filter: blur(18px) saturate(140%);
    box-shadow: var(--k9-shadow-inset);
}

.wk9-card__stat {
    position: relative;
    min-width: 0;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--k9-space-5);
}

.wk9-card__stat:not(:last-child) {
    padding-bottom: var(--k9-space-3);
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.wk9-card__stat-label {
    margin: 0;
    font-size: var(--k9-text-micro);
    letter-spacing: var(--k9-tracking-micro);
    text-transform: uppercase;
    font-weight: var(--k9-weight-medium);
    color: var(--k9-text-secondary);
}

.wk9-card__stat-value {
    margin: 0;
    white-space: nowrap;
    font-family: var(--k9-font-display);
    font-weight: var(--k9-weight-display);
    font-size: var(--k9-text-title-md);
    line-height: 1;
    letter-spacing: var(--k9-tracking-display);
    color: var(--k9-text);
}

/* =====================================================================
   Lightbox
   ===================================================================== */

.wk9-lightbox {
    position: fixed;
    inset: 0;
    z-index: var(--k9-z-sheet);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--k9-gutter);
}

.wk9-lightbox[hidden] { display: none; }

.wk9-lightbox__scrim {
    position: absolute;
    inset: 0;
    background: rgba(var(--k9-black-rgb), 0.92);
    opacity: 0;
    transition: opacity var(--k9-duration-slow) var(--k9-ease);
}

.wk9-lightbox__panel {
    position: relative;
    width: min(1200px, 100%);
    opacity: 0;
    transform: scale(0.97);
    transition:
        opacity var(--k9-duration-slow) var(--k9-ease),
        transform var(--k9-duration-slow) var(--k9-ease-spring);
}

.wk9-lightbox.is-open .wk9-lightbox__scrim { opacity: 1; }
.wk9-lightbox.is-open .wk9-lightbox__panel { opacity: 1; transform: scale(1); }

.wk9-lightbox__frame {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: var(--k9-radius-lg);
    overflow: hidden;
    background: var(--k9-black);
    box-shadow: var(--k9-shadow-4);
}

.wk9-lightbox__frame iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

.wk9-lightbox__close {
    position: absolute;
    top: calc(var(--k9-space-12) * -1);
    right: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 1px solid var(--k9-line);
    border-radius: var(--k9-radius-pill);
    background: transparent;
    color: var(--k9-text);
    cursor: pointer;
}

.wk9-lightbox__close:hover { background: var(--k9-surface-hover); }

.wk9-lightbox__close:focus-visible {
    outline: none;
    box-shadow: var(--k9-focus-ring);
}

/* =====================================================================
   Responsive
   ===================================================================== */

@media (max-width: 1024px) {
    .wk9-hero__top {
        grid-template-columns: 1fr;
        align-items: start;
        gap: var(--k9-space-10);
    }

    .wk9-hero__media {
        justify-self: start;
        max-width: 460px;
    }

    .wk9-card__play { width: 84px; height: 84px; }
}

/* Below the two-column layout the column of arrows would eat width the card
   needs, so they go back under it. */
@media (max-width: 720px) {
    .wk9-hero__media {
        flex-direction: column;
        align-items: stretch;
        gap: var(--k9-space-5);
    }

    .wk9-deck__nav {
        flex-direction: row;
        gap: var(--k9-space-4);
    }

    .wk9-deck__arrow svg { transform: none; }
}

@media (max-width: 720px) {
    .wk9-hero__stats { gap: var(--k9-space-5); }
    .wk9-hero__stat { padding-right: var(--k9-space-5); }
    .wk9-hero__stat-value { font-size: var(--k9-text-title-sm); }

    .wk9-hero__top {
        min-height: 0;
        padding-bottom: var(--k9-space-8);
    }

    .wk9-hero__media { max-width: none; }

    /* The 4:5 override that used to sit here is gone. It was trading the
       card's true aspect for height, and the cost was a pillarboxed portrait
       clip — black bars down both sides — on every phone. The mobile block at
       the foot of this file keeps 9:16 and buys the height back by narrowing
       the card instead. */

    .wk9-card__play { width: 68px; height: 68px; }

    .wk9-card__stats {
        gap: var(--k9-space-3);
        padding: var(--k9-space-4);
        left: var(--k9-space-4);
        right: var(--k9-space-4);
        bottom: var(--k9-space-4);
    }

    .wk9-card__stat-value { font-size: var(--k9-text-title-sm); }

    .wk9-lightbox__close { top: calc(var(--k9-space-10) * -1); }
}

@media (prefers-reduced-motion: reduce) {
    .wk9-deck .wk9-card { transition: none; }
    .wk9-card__play,
    .wk9-lightbox__scrim,
    .wk9-lightbox__panel { transition: none; }
}

/* =====================================================================
   Mobile layout — authoritative block

   Last in the file on purpose. The two-column desktop layout above sets
   .wk9-hero__inner / __actions / __stats outside any media query, so a
   mobile block placed earlier loses to it. Everything phone-shaped lives
   here, after all of it.

   Most of this site's traffic is a phone, so this is the layout that
   matters — the desktop grid above is the variant, not the baseline.
   ===================================================================== */

@media (max-width: 768px) {

    /* -- Background ---------------------------------------------------
       The section is ~1.4 screens tall once the video card is in it, and
       .wk9-hero__bg used to span all of it. object-fit: cover then had to
       fit a 1728x700 photo into a 390x1230 box — a 13% vertical sliver,
       magnified past recognition, which is what made the backdrop read as
       grey mush rather than a photograph.

       Pinning the media to a viewport-tall band fixes the crop at source:
       the same photo now covers 390x844, roughly three times as much of
       the frame. Below the band the section falls through to its own
       background, which is set to the fade target so the join is
       invisible — the shade is clipped to the band too, or its gradient
       would still be resolving hundreds of pixels lower down. */
    .wk9-hero {
        background: var(--wk9-hero-fade-to, var(--k9-surface-band));
    }

    .wk9-hero__bg,
    .wk9-hero__shade {
        height: 100vh;
        height: 100svh;
        bottom: auto;
    }

    /* A tall crop of a wide photo loses the subject off the bottom; the
       people and dogs in this set all sit in the upper-middle. */
    .wk9-hero__image { object-position: 50% 38%; }

    /* 16px of blur is a desktop figure — see the note on .wk9-hero__image.
       At phone width it erases the picture, so it scales back to ~40%. */
    .wk9-hero__image { --wk9-hero-blur-scale: 0.4; }

    /* The drift zoom crops even harder as it runs. Cheap to keep on a
       desktop, expensive here — it eats the framing the fix above bought. */
    .wk9-hero__image.is-active { animation: none; }

    /* -- Content column ----------------------------------------------- */

    .wk9-hero__inner {
        /* Tracks the real header height, which site-header.js measures and
           writes to --wk9-header-offset. Do not hard-code it: the header is
           gaining a mega menu and its height will change. */
        padding-top: calc(var(--wk9-header-offset, 88px) + var(--k9-space-6));
        padding-bottom: 0;
        gap: 0;
    }

    .wk9-hero__top {
        gap: var(--k9-space-8);
        padding-bottom: var(--k9-space-10);
    }

    .wk9-hero__lead { gap: var(--k9-space-5); }

    /* Headline, lede, buttons and stats all start at the gutter and run to
       the same right edge. The buttons used to stop 15px short of the text
       above them (max-width: 340px against a 355px column), which read as a
       misalignment rather than a choice. */
    .wk9-hero__actions {
        width: 100%;
        max-width: none;
        gap: var(--k9-space-3);
    }

    .wk9-hero__cta {
        min-height: 54px;
        padding-inline: var(--k9-space-5);
    }

    /* -- Stats --------------------------------------------------------
       Three stats will not sit on one flex line at 390px, so the third
       wrapped underneath and the divider belonging to the second was left
       pointing at empty space. A three-column grid can't wrap, so the row
       stays a row and the rules always fall between two columns. */
    .wk9-hero__stats {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 0;
        max-width: none;
        padding-top: var(--k9-space-5);
    }

    .wk9-hero__stat {
        padding-right: 0;
        padding-left: var(--k9-space-4);
    }

    .wk9-hero__stat:first-child { padding-left: 0; }

    /* Replaces the trailing ::after rules with real dividers between
       columns — drawn on the left edge, so the last column can't grow one. */
    .wk9-hero__stat:not(:last-child)::after { content: none; }

    .wk9-hero__stat + .wk9-hero__stat {
        border-left: 1px solid var(--k9-line);
    }

    .wk9-hero__stat-value {
        font-size: var(--k9-text-title-md);
        margin-bottom: var(--k9-space-1);
    }

    /* Stays on --k9-text-micro, the system's 11px floor for caps labels. The
       tracking is what gets trimmed instead: 0.09em is tuned for a label with
       room around it, and three of these have to share a 390px row. Labels
       wrap to two lines here; that is the intended outcome, not an overflow. */
    .wk9-hero__stat-label {
        font-size: var(--k9-text-micro);
        letter-spacing: 0.04em;
        line-height: var(--k9-leading-snug);
    }

    /* -- Video card ---------------------------------------------------
       Centred and capped rather than run to full gutter width, so it reads
       as a phone screen held up — which is what the footage is. Scales with
       the viewport so a 768px tablet doesn't get a 264px card marooned in
       the middle of it. */
    .wk9-hero__media {
        max-width: clamp(248px, 68vw, 360px);
        margin-inline: auto;
        justify-self: center;
    }

    /* 9:16 is this card's real aspect — it is what the base rule sets, and
       what desktop has always used, because the clip is a portrait reel and
       at 9:16 it fills the frame exactly. The max-width: 720px rule further
       up overrode it to 4:5 to save height, which is what put black
       pillarbox bars down both sides of the card on every phone. Restoring
       the true aspect and paying for the height by narrowing the card
       instead costs ~80px and gets rid of the bars. */
    .wk9-card { aspect-ratio: 9 / 16; }

    /* -- Scroll cue ---------------------------------------------------
       Removed on mobile. It is absolutely positioned against the bottom of
       the section, which is exactly where the deck's own prev/next controls
       and 1/3 counter sit — the word "Scroll" was landing on top of them.
       A phone does not need to be told the page scrolls, and the hero
       already runs past the fold, so the cue is the thing to drop. */
    .wk9-hero__cue { display: none; }
}

/* Very narrow phones: buy the stat columns width back from the gutters
   between them rather than from the type, which is already on the system's
   smallest step. */
@media (max-width: 380px) {
    .wk9-hero__stat { padding-left: var(--k9-space-2); }
    .wk9-hero__stat-label { letter-spacing: 0.02em; }
}

/* 320px (SE-generation phones). Three columns leave ~87px each, and
   "PROFESSIONALS" is a single 97px word that cannot wrap — it spilled into
   the next column. The type is already on --k9-text-micro, the system floor
   for caps labels, so the column count gives way instead of the type: two up,
   with the third across the foot on a rule of its own. */
@media (max-width: 340px) {
    .wk9-hero__stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    .wk9-hero__stat:nth-child(3) {
        grid-column: 1 / -1;
        margin-top: var(--k9-space-4);
        padding-top: var(--k9-space-4);
        padding-left: 0;
        border-left: 0;
        border-top: 1px solid var(--k9-line);
    }
}

/* =====================================================================
   Mobile: centred, and given the whole first screen.

   Left-aligned, the copy sat in a corner of a full-bleed photo and the
   headline was only ~39px, so on a phone the hero read as just another
   section. Centred, with a bigger headline and the text block filling the
   first screen, it reads as the opening of the site. The video card follows
   on the next scroll.

   Placed last so it wins over the left-aligned mobile block above.
   ===================================================================== */
@media (max-width: 768px) {
    .wk9-hero__top { text-align: center; }

    .wk9-hero__lead {
        align-items: center;
        justify-content: center;
        gap: var(--k9-space-6);
        /* The first screen, less the header and the inner's top padding. */
        min-height: calc(100svh - var(--wk9-header-offset, 88px) - var(--k9-space-6) * 2);
    }

    /* A rule either side, so the eyebrow reads as a centred label rather
       than a left-aligned one with a stray line in front of it. */
    .wk9-hero__eyebrow { justify-content: center; }
    .wk9-hero__eyebrow-rule,
    .wk9-hero__eyebrow::after {
        width: 28px;
        flex: 0 0 28px;
    }
    .wk9-hero__eyebrow::after {
        content: "";
        display: block;
        height: 1px;
        background: var(--k9-text-muted);
    }

    /* ~53px at 390px wide, against ~39px before. "PROFESSIONAL" is the
       longest word and still clears the gutters at 320px. */
    .wk9-hero__headline {
        font-size: clamp(2.75rem, 13.5vw, 4.25rem);
        line-height: 0.95;
        max-width: none;
        margin-inline: auto;
    }

    .wk9-hero__lede {
        /* The full column: three balanced lines at phone width rather than
           four short ones. */
        max-width: none;
        margin-inline: auto;
        /* Even line lengths: centred text otherwise ends on a lone "dog." */
        text-wrap: balance;
    }

    /* Stats centred in their columns, with even padding either side of the
       dividers rather than flush-left text. */
    .wk9-hero__stats { text-align: center; }
    .wk9-hero__stat,
    .wk9-hero__stat:first-child { padding-inline: var(--k9-space-2); }
}
