/* WDBC particle hero */
.wdbc-hero {
    position: relative;
    /* Fill the first screen, exactly.
       The site header is `position: sticky`, so it still occupies its space in
       normal flow directly above the hero — "the rest of the viewport" is
       therefore the viewport minus the real header height, not the whole
       viewport. --wdbc-header-h is measured from the live element and published
       by the inline script at the end of header.php, and kept current by a
       ResizeObserver, so a nav that wraps to two lines or a taller logo moves
       this number instead of leaving a hardcoded value stranded.
       The fallback is not a guess either: it restates the header's own CSS
       (.wbbc-header-inner min-height:10vh plus the header's 3px bottom border),
       so the very first paint is already correct if the script has not run.
       Note the fallback stays in `vh` even inside the svh block below, because
       the header's own min-height is authored in vh and resolves against the
       large viewport — mixing units there would reintroduce the error.
       `min-height`, not `height`: if the copy is ever taller than the computed
       box (very short landscape phones) the hero grows and the page scrolls,
       which is far better than clipping the headline. */
    min-height: calc(100vh - var(--wdbc-header-h, calc(10vh + 3px)));
    display: flex;
    align-items: center;
    overflow: hidden;
    background: radial-gradient(120% 120% at 72% 42%, #16233F 0%, #0B1220 100%);
    /* full-bleed: break out of any constrained content container */
    width: 100vw;
    max-width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
}
/* svh, not vh and not dvh.
   On phones `100vh` is the *large* viewport — the height the page gets once the
   browser chrome has retracted — so a vh-tall hero is taller than what is
   actually on screen at load and pushes a scrollbar before anyone has scrolled.
   `100svh` is the small viewport: exactly what is visible while the chrome is
   expanded, which is the state on first paint, so the hero's bottom edge lands
   on the bottom of the screen with nothing spilling past it.
   dvh would also fit at load, but it tracks the chrome as it hides and shows,
   which would resize the hero (and re-rasterise the canvas backing store) on
   every scroll gesture. svh is stable: measured once, correct at the moment
   that matters, and the strip of the next section that appears once the chrome
   retracts reads as an invitation to keep scrolling. */
@supports (height: 100svh) {
    .wdbc-hero {
        min-height: calc(100svh - var(--wdbc-header-h, calc(10vh + 3px)));
    }
}
.wdbc-hero-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
}
/* legibility scrim over the headline side */
.wdbc-hero::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(90deg, rgba(11,18,32,.88) 0%, rgba(11,18,32,.55) 42%, rgba(11,18,32,0) 70%);
}
.wdbc-hero-overlay {
    position: relative;
    z-index: 2;
    width: 100%;
    max-width: 1120px;
    margin: 0 auto;
    padding: 48px 24px;
    color: #EAF0FA;
    font-family: "Segoe UI", system-ui, -apple-system, Arial, sans-serif;
}
.wdbc-hero-inner { max-width: 38rem; }
.wdbc-hero-eyebrow {
    font-family: ui-monospace, "IBM Plex Mono", Menlo, Consolas, monospace;
    font-size: .72rem;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: #FFC24B;
    margin: 0 0 16px;
}
.wdbc-hero h1 {
    font-size: clamp(2rem, 4.6vw, 3.4rem);
    line-height: 1.05;
    letter-spacing: -.025em;
    font-weight: 800;
    margin: 0;
    text-wrap: balance;
    color: #EAF0FA;
}
.wdbc-hero h1 span { color: #FFC24B; }
.wdbc-hero-sub {
    font-size: clamp(1rem, 1.5vw, 1.18rem);
    color: #b9c4db;
    max-width: 44ch;
    line-height: 1.6;
    margin: 18px 0 0;
}
.wdbc-hero-cta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
.wdbc-btn {
    display: inline-block;
    padding: 13px 26px;
    border-radius: 9px;
    font-weight: 700;
    font-size: .98rem;
    text-decoration: none;
    transition: transform .15s ease, background .15s ease, border-color .15s ease, color .15s ease;
}
.wdbc-btn-primary { background: #FFC24B; color: #16233F; }
.wdbc-btn-primary:hover { background: #ffcf6e; transform: translateY(-1px); }
.wdbc-btn-ghost { border: 1.5px solid rgba(255,255,255,.42); color: #EAF0FA; }
.wdbc-btn-ghost:hover { border-color: #FFC24B; color: #FFC24B; }
/* Narrow *and* portrait — a phone held upright. The hero is now much taller than
   it is wide, so the copy takes the upper band and wdbc-hero.js drops the dot
   map into the lower one (same uniform scale, different anchor) instead of the
   two overlapping in the middle. The scrim is flipped to match that stacking:
   opaque behind the words at the top, clearing over the map below. Scoped to
   portrait deliberately — a phone in landscape has room beside the copy and is
   better served by the desktop treatment above. */
@media (max-width: 900px) and (orientation: portrait) {
    .wdbc-hero { align-items: flex-start; }
    .wdbc-hero-overlay { padding-top: 36px; }
    /* The stops run deep because on a short phone (360x640 and friends) the copy
       fills most of the box and the map has to start under the buttons. Holding
       the scrim near-opaque to ~70% keeps the CTAs readable there, and on a tall
       phone it just reads as the map fading up out of the dark. */
    .wdbc-hero::after {
        background: linear-gradient(180deg,
            rgba(11,18,32,.94) 0%, rgba(11,18,32,.90) 46%,
            rgba(11,18,32,.66) 70%, rgba(11,18,32,.14) 88%, rgba(11,18,32,0) 100%);
    }
    .wdbc-hero-inner { max-width: 100%; }
    /* The ghost button is a 1.5px outline over whatever is behind it; on a phone
       that can be the middle of the dot map, so give it something to sit on. */
    .wdbc-btn-ghost { background: rgba(11,18,32,.55); backdrop-filter: blur(2px); }
}

/* ---------- Short viewports ----------
   Now that the hero is height-capped by the screen rather than by its own
   content, the copy has to fit inside whatever is left after the header. These
   queries key off viewport height, not width, because the squeeze is vertical:
   a 1280x650 laptop window and a phone held in landscape are both wide and
   short. Spend the savings on padding and leading first, type size last. */
@media (max-height: 760px) {
    .wdbc-hero-overlay { padding-top: 30px; padding-bottom: 30px; }
    .wdbc-hero-eyebrow { margin-bottom: 12px; }
    .wdbc-hero-sub { margin-top: 14px; }
    .wdbc-hero-cta { margin-top: 20px; }
}
@media (max-height: 560px) {
    /* Landscape phones. Below this the headline itself has to give, or it and
       the buttons stop fitting between the header and the bottom of the screen. */
    .wdbc-hero-overlay { padding-top: 18px; padding-bottom: 18px; }
    .wdbc-hero h1 { font-size: clamp(1.45rem, 3.4vw, 2.1rem); }
    .wdbc-hero-eyebrow { margin-bottom: 8px; }
    .wdbc-hero-sub { font-size: .95rem; line-height: 1.45; margin-top: 10px; }
    .wdbc-hero-cta { margin-top: 14px; gap: 10px; }
    .wdbc-btn { padding: 9px 18px; font-size: .9rem; }
}
@media (max-height: 430px) {
    /* Smallest landscape phones: the sub-paragraph is the least load-bearing
       element here, so it steps back to a single tight block rather than
       crowding the CTAs off the screen. */
    .wdbc-hero-overlay { padding-top: 12px; padding-bottom: 12px; }
    .wdbc-hero h1 { font-size: 1.3rem; }
    .wdbc-hero-sub { font-size: .88rem; max-width: 52ch; margin-top: 8px; }
    .wdbc-hero-cta { margin-top: 10px; }
    .wdbc-btn { padding: 8px 16px; }
}
