  :root {
    --ink: #f7f6f2;
    --bg: #000;
    --header-bg: #f2f0ea;
    --header-ink: #161511;
    --header-ink-dim: #58554a;
    --header-line: rgba(22, 21, 17, 0.1);
    --serif: Georgia, "Iowan Old Style", "Times New Roman", serif;
    --sans: "Helvetica Neue", Helvetica, Arial, sans-serif;
  }

  * { box-sizing: border-box; }
  .sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
  /* Manual fallback for browsers without the `inert` IDL property — see
     setInert() in the script below. */
  .inert-fallback { pointer-events: none !important; user-select: none !important; }
  /* Single, site-wide motion policy rather than scattered per-component
     prefers-reduced-motion overrides (this used to be inconsistent —
     some transitions/animations honoured it, most didn't). 0.01ms
     instead of 0s: JS in this file listens for transitionend on several
     of these (modal open/close, focus handoff), and a genuinely
     zero-duration transition doesn't reliably fire that event in every
     browser, whereas a near-zero one still does, immediately. */
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }
  html, body { height: 100%; overflow: hidden; }
  html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
  body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--sans);
    -webkit-font-smoothing: antialiased;
  }
  a { color: inherit; }
  button { font-family: inherit; -webkit-tap-highlight-color: transparent; }

  .app {
    position: relative;
    height: 100vh;
    height: 100svh;
    width: 100%;
    overflow: hidden;
    /* A triple-click anywhere on the hero background lands on this
       element's own ::before gradient overlay (the topmost decorative
       paint layer at that point, above the video) rather than any text
       node — with no text directly under the cursor, the browser's
       triple-click fallback then expands the selection outward to the
       nearest surrounding text (the nav and headline), highlighting it.
       Blocking selection at this ancestor, rather than only on the video
       or the individual text elements, stops it at the actual point of
       origin instead of chasing every element the fallback might land on. */
    user-select: none;
    -webkit-user-select: none;
  }

  .app video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
  }

  .app::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background: linear-gradient(180deg, rgba(0,0,0,0.42) 0%, rgba(0,0,0,0) 22%, rgba(0,0,0,0) 58%, rgba(0,0,0,0.5) 100%);
  }

  /* ---------- Header: transparent, overlaid on video ---------- */
  header {
    position: absolute;
    top: 0; left: 0; right: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* viewport-fit=cover (above) makes these env() vars resolve to the
       actual notch/rounded-corner/status-bar extent instead of 0; adding
       them (rather than max()-ing) keeps the existing visual spacing and
       pushes it further in on devices that need it. */
    padding: calc(clamp(20px, 3.4vh, 34px) + env(safe-area-inset-top, 0px))
             calc(clamp(20px, 4vw, 44px) + env(safe-area-inset-right, 0px))
             0
             calc(clamp(20px, 4vw, 44px) + env(safe-area-inset-left, 0px));
    color: var(--ink);
  }

  .brand { display: flex; align-items: center; gap: 22px; }
  .crest {
    width: 42px; height: 42px;
    color: var(--ink);
    flex: 0 0 auto;
    display: block;
  }
  .logo {
    font-family: var(--serif);
    font-size: 42px;
    line-height: 1;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    user-select: none;
    -webkit-user-select: none;
  }

  nav.desktop-nav {
    position: relative;
    display: flex;
    gap: 4px;
    align-items: center;
    height: 42px;
    background: rgba(242, 240, 234, 0.96);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border-radius: 999px;
    padding: 0 5px;
    user-select: none;
    -webkit-user-select: none;
    box-shadow: 0 12px 32px rgba(0,0,0,0.22);
  }
  .navgroup { height: 100%; display: flex; align-items: center; }
  .pill {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 32px;
    background: transparent;
    border: none;
    cursor: default;
    padding: 0 18px;
    border-radius: 999px;
    font-size: 13.5px;
    letter-spacing: 0.02em;
    color: var(--header-ink);
    transition: background 0.2s ease, color 0.2s ease;
  }
  .pill:hover { background: rgba(22, 21, 17, 0.06); }
  .pill.active { background: var(--header-ink); color: var(--header-bg); }
  .pill-plain:hover { background: var(--header-ink); color: var(--header-bg); }
  .pill .chev { transition: transform 0.2s ease; }
  .pill.active .chev { transform: rotate(180deg); }

  .dropdown {
    position: absolute;
    top: calc(100% + 10px);
    left: 0;
    right: 0;
    background: #fff;
    border-radius: 18px;
    box-shadow: 0 20px 50px rgba(0,0,0,0.35);
    padding: 14px;
    display: none;
    flex-direction: column;
    gap: 2px;
  }
  .dropdown.open { display: flex; }
  .dropdown button.ditem {
    background: none;
    border: none;
    text-align: left;
    cursor: default;
    padding: 11px 16px;
    border-radius: 999px;
    font-size: 14.5px;
    color: var(--header-ink);
    border: 1px solid transparent;
    transition: border-color 0.18s ease;
  }
  .dropdown button.ditem:hover { border-color: var(--header-line); }
  /* Items with no real destination yet are disabled rather than left as
     operable controls that silently do nothing — this dims them and drops
     the interactive-looking hover cues to match. */
  .ditem:disabled,
  .subitem:disabled,
  .pill-plain:disabled {
    opacity: 0.45;
    cursor: default;
  }
  .dropdown button.ditem:disabled:hover { border-color: transparent; }
  .pill-plain:disabled:hover { background: none; color: var(--header-ink); }

  .menu-btn {
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    width: 44px;
    height: 44px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
    flex: 0 0 auto;
  }
  .menu-btn span { width: 22px; height: 1px; background: var(--ink); }

  /* ---------- Hero: bottom content over full-bleed video ---------- */
  .hero {
    position: relative;
    height: 100%;
    z-index: 0;
  }

  .hero-statement {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 0 8vw;
    pointer-events: none;
  }
  .hero-statement span {
    font-family: var(--serif);
    font-weight: 400;
    font-size: clamp(32px, 4.2vw, 64px);
    line-height: 1.2;
    color: var(--ink);
    text-shadow: 0 2px 24px rgba(0,0,0,0.55);
    max-width: 36ch;
    user-select: none;
    -webkit-user-select: none;
  }

  .foot {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    z-index: 2;
    padding: 0
             calc(5vw + env(safe-area-inset-right, 0px))
             calc(clamp(28px, 5vh, 56px) + env(safe-area-inset-bottom, 0px))
             calc(5vw + env(safe-area-inset-left, 0px));
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 24px;
  }

  .status-badge {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: #fff;
    white-space: nowrap;
  }
  .status-badge .dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #22c55e;
    animation: marketPulse 2s ease-in-out infinite;
  }
  .markets {
    display: grid;
    grid-template-columns: auto auto auto auto;
    align-items: baseline;
    column-gap: 16px;
    row-gap: 12px;
    font-size: 15px;
  }
  .markets .market { display: contents; }
  .markets .dot {
    position: relative;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ink);
    align-self: center;
  }
  .markets .market.open .dot {
    background: #22c55e;
    animation: marketPulse 2s ease-in-out infinite;
  }
  .markets .dot::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: inherit;
    opacity: 0;
  }
  .markets .market.open .dot::after {
    animation: marketPulseRing 2s ease-out infinite;
  }
  @keyframes marketPulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.5); }
    50% { box-shadow: 0 0 0 4px rgba(34, 197, 94, 0); }
  }
  @keyframes marketPulseRing {
    0% { transform: scale(1); opacity: 0.6; }
    100% { transform: scale(2.4); opacity: 0; }
  }
  .markets .mkt-name {
    color: #fff;
    font-weight: 600;
  }
  .markets .mkt-status {
    color: #fff;
    font-weight: 600;
  }
  .markets .market.open .mkt-status { color: #fff; }
  .markets .mkt-countdown {
    color: #fff;
    font-weight: 600;
    letter-spacing: 0.02em;
  }
  .foot-actions { display: flex; flex-direction: column; align-items: flex-end; gap: 16px; }

  .clocks {
    display: grid;
    /* The weather column used to be auto-sized like the other two, so
       each city's independently-arriving weather text (wildly variable
       length: "5°C Clear" vs. "-2°C Freezing Drizzle") resized the whole
       column — and everything sharing this grid — as each result landed.
       A fixed width caps that at a known, enforced budget instead. Sized
       to fit the longest label ("Freezing Drizzle") plus a sign and a
       two-digit temperature (e.g. "-15°C ").
       minmax(0, 22ch), not a bare 22ch: a plain track can't shrink below
       its size, so on the narrow-viewport max-width cap below 640px it
       pushed .weather's own box past the container and the viewport
       instead of letting overflow/ellipsis do its job. minmax(0, ...)
       lets the track compress to what's available; ellipsis still
       clips the text itself. */
    grid-template-columns: auto auto minmax(0, 22ch);
    align-items: baseline;
    column-gap: 16px;
    row-gap: 12px;
    font-size: 15px;
  }
  .clocks .clock { display: contents; }
  .clocks .time {
    color: #fff;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    text-align: right;
  }
  .clocks .city {
    color: #fff;
    font-weight: 600;
  }
  .clocks .weather {
    color: #fff;
    font-weight: 600;
    letter-spacing: 0.02em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .clocks .weather.stale { opacity: 0.6; }

  .markets,
  .clocks,
  .status-badge {
    text-shadow: 0 1px 8px rgba(0,0,0,0.65);
  }


  /* ---------- Overlay panels ---------- */
  .panel {
    position: fixed;
    inset: 0;
    z-index: 200;
    background: rgba(242, 240, 234, 0.4);
    backdrop-filter: blur(9px) saturate(160%);
    -webkit-backdrop-filter: blur(9px) saturate(160%);
    display: flex;
    flex-direction: column;
    opacity: 0;
    visibility: hidden;
    transform: translateY(10px);
    transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s;
    user-select: none;
    -webkit-user-select: none;
  }
  .panel.open { opacity: 1; visibility: visible; transform: translateY(0); }
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    /* Without backdrop-filter the 0.4-alpha scrim leaves background content
       legible through the menu text, which fails contrast for content that
       is supposed to have been visually and functionally dismissed. Fall
       back to a near-opaque scrim so the menu still reads as its own
       surface. */
    .panel { background: rgba(242, 240, 234, 0.97); }
  }
  .panel-head {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: clamp(20px, 3vh, 32px) 5vw;
    border-bottom: 1px solid var(--header-line);
    flex: 0 0 auto;
  }
  .panel-brand {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;
    gap: 14px;
  }
  .panel-brand .crest { width: 26px; height: 26px; color: var(--header-ink); flex: 0 0 auto; }
  .panel-head .logo { font-size: 22px; color: var(--header-ink); }
  .panel-close {
    background: none;
    border: 1px solid var(--header-line);
    color: var(--header-ink);
    width: 38px;
    height: 38px;
    border-radius: 50%;
    cursor: pointer;
    font-size: 17px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: border-color 0.2s ease, background 0.2s ease;
  }
  .panel-close:hover { border-color: var(--header-ink); background: var(--header-ink); color: var(--header-bg); }
  .panel-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 0 5vw clamp(48px, 6vh, 80px);
  }
  .principle { display: flex; flex-direction: column; gap: 0; padding: 0; border-top: none; max-width: 720px; scroll-margin-top: 20px; }
  .principle:last-child { border-bottom: none; }
  .panel-body .ditem {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    text-align: left;
    background: none;
    border: none;
    border-top: 1px solid var(--header-line);
    cursor: pointer;
    padding: 18px 4px;
    font-family: var(--sans);
    font-style: normal;
    font-size: 17px;
    font-weight: 500;
    letter-spacing: 0.02em;
    color: var(--header-ink);
  }
  .panel-body .principle:first-child .ditem { border-top: none; }
  .panel-body .principle:last-child .ditem { border-bottom: 1px solid var(--header-line); }
  .panel-body .ditem .chev {
    flex: 0 0 auto;
    color: var(--header-ink-dim);
    transform: rotate(-90deg);
    transition: transform 0.25s ease;
  }
  .panel-body .principle.open .ditem .chev { transform: rotate(0deg); }
  .panel-body .principle:not(.has-sub) .ditem { cursor: default; }
  .subitems-wrap {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.3s ease;
  }
  .principle.open .subitems-wrap { grid-template-rows: 1fr; }
  .subitems-inner { overflow: hidden; }
  .subitem {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    cursor: default;
    padding: 13px 4px 13px 18px;
    font-family: var(--sans);
    font-size: 14.5px;
    font-weight: 400;
    color: var(--header-ink-dim);
  }

  /* ---------- Responsive ---------- */
  @media (max-width: 980px) {
    nav.desktop-nav { display: none; }
    .menu-btn { display: flex; }
    header {
      display: grid;
      grid-template-columns: 1fr auto 1fr;
      align-items: center;
    }
    .brand {
      grid-column: 2;
      justify-self: center;
    }
    .menu-btn { grid-column: 3; justify-self: end; }
    .foot { flex-direction: column; align-items: flex-start; gap: 20px; }
    .foot-actions { align-items: flex-start; }
    .markets { display: none; }
  }

  @media (max-width: 640px) {
    .logo { font-size: 30px; }
    .clocks {
      padding: 14px 18px;
      column-gap: 8px;
      row-gap: 8px;
      max-width: calc(100vw - 10vw);
      font-size: clamp(14px, 4vw, 18px);
    }
    /* Below this width the weather column (minmax(0, 22ch) — see the
       .clocks rule above) can shrink narrower than the longest realistic
       condition string ("-15°C Freezing Drizzle"), which the ellipsis
       would then clip exactly like the bug this whole column was widened
       to fix. There's no spare column width left to give it on a 320px
       screen, so let it wrap to a second line instead of eliding —
       .clock's own row simply grows taller (row-gap already spaces rows),
       rather than the text losing information. */
    .clocks .weather {
      white-space: normal;
      /* text-overflow only has an effect when overflow is hidden/scroll/
         auto (spec) — no need to also reset it now that overflow is
         visible again. */
      overflow: visible;
    }
  }

  @media (max-width: 400px) {
    .logo { font-size: 24px; }
  }

  /* ---------- No-JS fallback ---------- */
  .noscript-gate {
    position: fixed;
    inset: 0;
    z-index: 600;
    background: rgba(14, 13, 11, 0.92);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4vh 5vw;
  }
  .noscript-gate-card {
    background: var(--header-bg);
    color: var(--header-ink);
    max-width: 480px;
    padding: 34px;
    border-radius: 18px;
    font-family: var(--sans);
    font-size: 14px;
    line-height: 1.6;
    text-align: center;
  }
  .noscript-gate-card p { margin: 0 0 12px; }
  .noscript-gate-card p:last-child { margin-bottom: 0; }

  /* ---------- Contact modal ---------- */
  .contact-modal {
    position: fixed;
    inset: 0;
    z-index: 700;
    background: rgba(14, 13, 11, 0.72);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4vh 5vw;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s ease, visibility 0.3s;
  }
  .contact-modal.open { opacity: 1; visibility: visible; }
  .contact-modal-card {
    position: relative;
    width: 100%;
    /* A flat pixel max-width can only ever be a guess at how wide the
       email needs to be, calibrated against whichever font happened to
       render when that guess was made — exactly what let it wrap to two
       lines on desktop under a wider font substitution. `ch` is defined
       against this element's own current font, so sizing against it here
       (with the same font-family/font-size the email itself uses) tracks
       whatever font actually renders instead of assuming one. This is the
       CSS-only fallback for when the JS-driven exact fit below can't run;
       22ch covers "venture@aldrech.com" (20 characters) with a little
       headroom, plus the fixed width of the gap, copy button and padding.
       If the mailbox name ever changes to something longer, bump 22ch. */
    max-width: calc(22ch + 122px);
    font-family: var(--serif);
    padding: 40px;
    text-align: center;
    transform: translateY(10px);
    transition: transform 0.3s ease;
    --email-size: clamp(32px, 5.5vw, 64px);
    font-size: var(--email-size);
  }
  /* font-family/font-size above exist only so max-width's `ch` unit
     resolves against the email's own font — they're not meant to be this
     card's typographic default, and every current child happens to
     already set its own explicit font, which is why this hasn't visibly
     mattered yet. But that makes it a trap: a future direct child of the
     card with real text and no font override would silently render in
     giant serif rather than the site's normal body copy. :where() keeps
     this at zero specificity, so it only ever supplies a default and can
     never out-rank a more specific override (present or future) — not
     even one added later in the file, which is what an ordinary selector
     here would depend on. */
  .contact-modal-card > :where(*) {
    font-family: var(--sans);
    font-size: 14px;
  }
  .contact-modal.open .contact-modal-card { transform: translateY(0); }
  .contact-modal-email {
    display: inline-block;
    font-family: var(--serif);
    font-weight: 400;
    font-size: var(--email-size);
    color: var(--ink);
    text-shadow: 0 2px 24px rgba(0,0,0,0.55);
    text-decoration: underline;
    text-underline-offset: 0.14em;
    transition: opacity 0.2s ease;
  }
  .contact-modal-email:hover { opacity: 0.7; }
  .contact-modal-email-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    flex-wrap: wrap;
  }
  .contact-modal-email-group {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: nowrap;
  }
  .contact-modal-copy {
    position: relative;
    top: calc(var(--email-size) * 0.093);
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: rgba(22, 21, 17, 0.55);
    color: var(--header-bg);
    display: flex;
    align-items: center;
    justify-content: center;
    appearance: none;
    -webkit-appearance: none;
    border: none;
    padding: 0;
    font: inherit;
    cursor: pointer;
    transition: background 0.2s ease;
  }
  .contact-modal-copy:hover { background: rgba(22, 21, 17, 0.75); }
  @media (forced-colors: active) {
    .contact-modal-copy { border: 1px solid CanvasText; }
  }
  .contact-modal-copy-status {
    font-family: var(--sans);
    font-size: 13px;
    color: var(--ink);
    opacity: 0;
    transition: opacity 0.25s ease;
  }
  .contact-modal-copy-status.visible { opacity: 0.85; }
  .contact-modal-copy-fallback {
    display: block;
    margin: 14px auto 0;
    max-width: 280px;
    width: 100%;
    text-align: center;
    font-family: var(--sans);
    font-size: 14px;
    color: var(--ink);
    background: rgba(247, 246, 242, 0.12);
    border: 1px solid rgba(247, 246, 242, 0.4);
    border-radius: 8px;
    padding: 8px 12px;
  }
  .contact-modal-copy-fallback[hidden] { display: none; }
  .contact-modal-close {
    position: fixed;
    top: 24px;
    right: 24px;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 1px solid rgba(247, 246, 242, 0.4);
    background: rgba(14, 13, 11, 0.3);
    color: var(--ink);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease;
  }
  .contact-modal-close:hover { border-color: var(--ink); background: var(--ink); color: #161511; }
  @media (max-width: 600px) {
    .contact-modal-close { top: 16px; right: 16px; }
  }

  /* ---------- Investor gate ---------- */
  .gate {
    position: fixed;
    inset: 0;
    z-index: 500;
    background: rgba(14, 13, 11, 0.72);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4vh 5vw;
  }
  .gate[hidden] { display: none; }
  .gate-card {
    background: var(--header-bg);
    color: var(--header-ink);
    width: 100%;
    max-width: 640px;
    max-height: 92vh;
    border-radius: 18px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    user-select: none;
    -webkit-user-select: none;
  }
  .gate-card:focus {
    outline: none;
  }
  .gate-card:focus-visible {
    outline: 2px solid var(--header-ink);
    outline-offset: 3px;
  }
  @media (forced-colors: active) {
    .gate-card:focus-visible { outline: 2px solid CanvasText; }
  }
  .gate-head {
    padding: 28px 34px;
    border-bottom: 1px solid var(--header-line);
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .gate-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
  }
  .gate-brand .crest { width: 54px; height: 54px; color: var(--header-ink); }
  .gate-brand .logo { font-size: 34px; color: var(--header-ink); letter-spacing: 0.14em; }
  .gate-body-wrap {
    position: relative;
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
  }
  .gate-body {
    flex: 1 1 auto;
    min-height: 0;
    /* Extra bottom padding reserves room for .gate-scroll-indicator, which
       floats (position: absolute) inside .gate-body-wrap at bottom: 10px —
       without it, the indicator sits on top of the final lines of
       scrolling text instead of in dedicated empty space below them. */
    padding: 20px 34px 72px;
    overflow-y: auto;
    overscroll-behavior: contain;
    overflow-clip-margin: 2px;
    overflow-wrap: break-word;
  }
  /* Once genuinely scrolled to the end (gate.js toggles this alongside
     hiding the indicator), that reserved space has nothing left to clear —
     the indicator is gone — so it just reads as a stray gap of empty
     space below the final paragraph. Collapse it back to match the top
     padding once there's no more content to scroll to. */
  .gate-body.at-end {
    padding-bottom: 20px;
  }
  .gate-body:focus {
    outline: none;
  }
  .gate-body.kb-focus {
    box-shadow: inset 0 0 0 2px rgba(22, 21, 17, 0.45);
  }
  @media (forced-colors: active) {
    .gate-body.kb-focus { outline: 2px solid CanvasText; }
  }
  .gate-scroll-indicator {
    position: absolute;
    left: 50%;
    bottom: 10px;
    transform: translateX(-50%);
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: rgba(22, 21, 17, 0.55);
    color: var(--header-bg);
    display: flex;
    align-items: center;
    justify-content: center;
    appearance: none;
    -webkit-appearance: none;
    border: none;
    padding: 0;
    font: inherit;
    cursor: pointer;
    opacity: 1;
    visibility: visible;
    transition: opacity 0.2s ease, background 0.2s ease, visibility 0.2s ease;
  }
  .gate-scroll-indicator:hover { background: rgba(22, 21, 17, 0.75); }
  .gate-scroll-indicator.hidden { opacity: 0; visibility: hidden; pointer-events: none; }
  @media (forced-colors: active) {
    .gate-scroll-indicator { border: 1px solid CanvasText; }
  }
  @media (max-height: 600px) {
    .gate-scroll-indicator {
      width: 24px;
      height: 24px;
      bottom: 4px;
    }
    .gate-scroll-indicator svg { width: 8px; height: 5px; }
  }
  @media (max-height: 480px) {
    /* Below this, .gate-head and .gate-foot alone leave too little room in
       .gate-body-wrap for any amount of reserved padding to keep the
       indicator clear of the last line of text. The previous threshold
       here (380px, on a claimed measured overlap "under ~350px") was
       itself wrong: re-measured directly (last visible line's bottom edge
       vs. the indicator's top edge, at the scroll position just before
       the indicator would hide) it actually overlaps up to ~400px under
       the site's real default fonts, and up to ~430px under this
       repo's wide-font-substitution stress test (DejaVu Serif/Sans, used
       elsewhere in this codebase's own tests for exactly this kind of
       margin check). A first fix raised it to 460px, which turned out to
       leave only ~2px of margin at the narrowest realistic width (320px)
       under the same wide-font test — narrow enough to plausibly flip to
       overlap under ordinary subpixel/engine rounding differences, not a
       real safety margin. 480px leaves ~20px of clearance under that same
       combined narrow-width-plus-wide-font check. Hiding the indicator is
       a safe degradation either way — the notice is still fully
       scrollable by every other means, it just loses this one decorative
       cue. */
    .gate-scroll-indicator { display: none; }
    /* .gate-body's 72px bottom padding exists only to keep that indicator
       clear of the last line of text — with it hidden here, that space
       has nothing to reserve room for and would otherwise sit as a
       permanent dead gap at the bottom of the scrollable notice for the
       entire time it's above this breakpoint, not just once scrolled to
       the true end (which .gate-body.at-end already handles separately). */
    .gate-body { padding-bottom: 20px; }
  }
  .gate-body h4 {
    font-size: 12.5px;
    letter-spacing: 0.04em;
    color: var(--header-ink);
    margin: 20px 0 6px;
  }
  .gate-body h4:first-child { margin-top: 0; }
  .gate-body p {
    font-size: 12.5px;
    line-height: 1.65;
    color: var(--header-ink-dim);
    margin: 0 0 10px;
    text-align: justify;
    text-justify: inter-word;
    -webkit-hyphens: auto;
    hyphens: auto;
  }
  .jurisdiction-list { padding-left: 20px; }
  .gate-foot {
    padding: 20px 34px 28px;
    border-top: 1px solid var(--header-line);
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 16px;
  }
  .gate-confirm {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--header-ink);
    cursor: pointer;
  }
  .gate-confirm span {
    text-align: justify;
    text-justify: inter-word;
    -webkit-hyphens: auto;
    hyphens: auto;
  }
  .gate-confirm input {
    margin-top: 3px;
    width: 15px;
    height: 15px;
    accent-color: var(--header-ink);
    flex: 0 0 auto;
    cursor: pointer;
  }
  .gate-accept {
    align-self: flex-end;
    flex: 0 0 auto;
    height: 32px;
    background: var(--header-ink);
    color: var(--header-bg);
    border: none;
    padding: 0 22px;
    font-size: 11px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    border-radius: 999px;
    cursor: pointer;
    transition: opacity 0.2s ease, background 0.2s ease;
  }
  .gate-accept:disabled {
    opacity: 0.35;
    cursor: not-allowed;
  }
  .gate-accept:not(:disabled):hover { background: #000; }

  @media (max-width: 560px) {
    .gate-head, .gate-body, .gate-foot { padding-left: 22px; padding-right: 22px; }
  }
