/**
 * SNW Landing Page — Variant A "The Guide" (/onescoop).
 *
 * Variant-specific rules only. The tokens, reset, buttons, frames, hero, sticky bar,
 * FAQ, header and footer all live in lp-shared.css, which loads first.
 */

/* ===== WAGGLE CARD =====
   Frames the live Alhena inline embed. Per the Waggle Embed Spec v1.1 §7 the chat is
   mounted in the initial DOM and is live from page load — the mock conversation in the
   design file was a placeholder only, and there is no "reveal" interaction. */
.wagcard {
  background: #fff;
  border-radius: 20px;
  box-shadow: 0 12px 40px rgba(246, 117, 153, .28);
  border: 3px solid var(--lpink);
  max-width: 480px;
  margin: 0 auto;

  /* The card is the thing that has to fit the screen, so the cap belongs here — the
     chat panel inside it then takes whatever the header and footer leave (see
     #alhena-inline-chat). 88svh, not vh: on mobile `vh` resolves against the viewport
     with the browser toolbars hidden, which is taller than what the user can actually
     see, and the Facebook in-app browser carries more chrome than Safari does. The
     remaining 12% keeps the card visibly seated on the page rather than filling it.

     overflow-y:auto, not hidden: .lp-wag-messages below holds a floor height so its
     scroll bar stays usable, and that floor can add up to more than max-height leaves —
     header + Waggle's own intro card + input alone run ~318px before the message list's
     own minimum is added. overflow:hidden would silently clip whatever does not fit
     (almost certainly the input box); scrolling the whole card is the same trade the
     message list itself already makes, just one level up, and nothing is ever cut off
     without a way to reach it. */
  display: flex;
  flex-direction: column;
  max-height: 88svh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* Short screens: the in-app browser's chrome eats a larger share of an already small
   viewport, so the card takes a smaller share of it in turn. Without this the card still
   runs past the bottom on 568px-tall handsets and in landscape. */
@media (max-height: 700px) {
  .wagcard { max-height: 80svh; }
}
@media (max-height: 480px) {
  .wagcard { max-height: 76svh; }
}
.waghead,
.wagbody,
.wagfoot {
  /* .wagcard used to clip all three of these via its own overflow:hidden; that had to
     become overflow-y:auto so the card can scroll instead of silently cutting content
     off when the SDK's message list needs more room than the card's height cap allows
     (see .wagcard and .lp-wag-messages). Each section now rounds its own corners to
     match, and only when it is actually first/last: the header can be switched off per
     page in ACF (lp_waggle_show_header) and the footer only renders when Waggle trust
     points are configured, so which section sits at each end of the card is content-
     driven, not fixed markup order. */
  border-radius: 0;
}
.waghead:first-child, .wagbody:first-child, .wagfoot:first-child { border-radius: 17px 17px 0 0; }
.waghead:last-child, .wagbody:last-child, .wagfoot:last-child { border-radius: 0 0 17px 17px; }
.waghead:only-child, .wagbody:only-child, .wagfoot:only-child { border-radius: 17px; }

.waghead {
  background: var(--pink);
  color: #fff;
  padding: 13px 18px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.waghead .av {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  overflow: hidden;
  font-size: 1.1rem;
  line-height: 1;
}
.waghead .av img { width: 22px; height: 22px; object-fit: contain; }
.waghead .t { font-family: var(--head); font-size: 1rem; line-height: 1.1; }
.waghead .t small {
  display: block;
  font-family: var(--body);
  font-weight: 600;
  font-size: .68rem;
  opacity: .92;
}
/* Relays the card's height cap down to the chat panel: itself a flex child that may
   shrink, and a flex container so #alhena-inline-chat can fill what is left.
   min-height:0 on both is what actually permits the shrink. */
.wagbody {
  padding: 12px;
  background: linear-gradient(180deg, #fff, #FDF6F8);
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
}

/* The Alhena widget fills 100% of its container, so this div controls its size.
   Spec v1.1 §7 step 2: full width within the card, ~70vh with a sensible minimum.

   Sized in svh, not vh. On mobile `vh` resolves against the *large* viewport — the
   height the page would have with the browser toolbars hidden — so on a phone the box
   is laid out taller than the area the user can actually see. `svh` is the small
   viewport height, which is what is genuinely visible with the chrome showing. That
   gap is worse in the Facebook in-app browser, which carries more chrome than Safari.

   The old `min-height: 420px` was the real defect: below a 600px-tall viewport it beat
   `height: 70svh`, so the box stopped shrinking and the card (header + chat + footer)
   grew past the screen — 732-778px of card against 428-600px of visible height on every
   device profile we simulate. The conversation was cut off with no way to reach it.
   The floor is now a proportional one that cannot outgrow the viewport, with a small
   absolute guard so the widget is never squeezed into uselessness in landscape.

   overflow-y is explicit so the panel scrolls *within* the card rather than overflowing
   it, which is what makes a scroll bar possible at all. */
#alhena-inline-chat {
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
  /* Height comes from the flex parent below rather than a viewport unit of its own.
     Sizing this panel directly was the original defect: the card also carries a header
     and a footer whose trust pills wrap to 185-206px on narrow screens, so any fixed
     fraction of the viewport here still pushed the *card* off the bottom of the screen.
     Capping the card and letting this take what is left cannot overshoot, whatever the
     footer does.

     flex-basis is a real height, not 0/auto: the Alhena widget mounts asynchronously and
     this div is empty until it does, so a content-derived basis collapses the panel to
     nothing on first paint — and stays collapsed wherever the widget fails to load.
     The basis is what the panel asks for; the card's max-height is what trims it back on
     a short screen, and min-height keeps it usable when it does. */
  flex: 1 1 60svh;
  min-height: 260px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* Short screens: the floor has to come down with the available height, or min-height
   simply becomes the new reason the card overflows. These still leave room for a couple
   of exchanges, and the panel scrolls for the rest. */
@media (max-height: 700px) {
  #alhena-inline-chat { min-height: 200px; }
}
@media (max-height: 480px) {
  #alhena-inline-chat { min-height: 150px; }
}

/* iOS and Android hide overlay scroll bars until a scroll is already in progress, so an
   overflowing panel gives no hint that there is more to read. Gordon asked for the bar
   to be visible: this paints a permanent one on the platforms that support styling it.
   Firefox uses the standard properties; WebKit/Blink need the pseudo-elements. */
#alhena-inline-chat {
  scrollbar-width: thin;
  scrollbar-color: var(--pink) rgba(246, 117, 153, .15);
}
#alhena-inline-chat::-webkit-scrollbar {
  width: 6px;
  -webkit-appearance: none;
}
#alhena-inline-chat::-webkit-scrollbar-track {
  background: rgba(246, 117, 153, .15);
  border-radius: 999px;
}
#alhena-inline-chat::-webkit-scrollbar-thumb {
  background: var(--pink);
  border-radius: 999px;
}

/* Alhena's own emotion-generated class on the consent/action-row wrapper it renders
   inside #alhena-inline-chat — brittle (it can change on their next widget build), but
   this is the only hook available since the markup itself isn't ours to edit. Pushes
   the row down to fix it sitting flush against the message above it. */
#waggle div#alhena-inline-chat .css-1dv442g {
  margin-top: 60px;
}

/* Shown by initWaggleFallback() in lp-shared.js when the Alhena SDK has not rendered
   anything into #alhena-inline-chat within 12s — most likely a third-party script
   blocked or failing silently in a restrictive in-app WebView. Centred in the same
   flex space the live widget would otherwise fill. */
.wagfallback {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
  padding: 20px;
}
.wagfallback p { font-size: .88rem; color: var(--ink); margin: 0; max-width: 32ch; }
.wagfallback .btn { margin: 0; width: auto; padding: 12px 22px; }

/* Tagged by initWaggleMessageList() in lp-shared.js: the SDK's own scrollable message
   list, identified by behaviour rather than its Emotion-hashed class name, which is not
   stable across SDK releases.

   The SDK's column layout (header + intro card + this list + input) leaves the list only
   ~115-120px on a phone-width card, so on mobile more than one exchange scrolls inside a
   box too short to show any of it — client feedback: "have these two in a scroll bar for
   mobile". The list already scrolls (that behaviour is how it gets tagged at all); a
   floor height is what makes that scrolling usable rather than theoretical.

   min-height means the message list can push the card taller than the max-height cap
   on .wagcard sets for everything else — a deliberate trade: on the shortest phones the
   card grows past 88svh so the conversation stays legible, rather than staying capped
   and unreadable. flex-shrink:0 stops the SDK's own flex layout re-compressing it back
   down once content grows past this floor. */
.lp-wag-messages {
  min-height: 260px;
  flex-shrink: 0;
  scrollbar-width: thin;
  scrollbar-color: var(--pink) rgba(246, 117, 153, .15);
}
.lp-wag-messages::-webkit-scrollbar { width: 6px; -webkit-appearance: none; }
.lp-wag-messages::-webkit-scrollbar-track { background: rgba(246, 117, 153, .15); border-radius: 999px; }
.lp-wag-messages::-webkit-scrollbar-thumb { background: var(--pink); border-radius: 999px; }

@media (max-height: 700px) {
  .lp-wag-messages { min-height: 200px; }
}
@media (max-height: 480px) {
  .lp-wag-messages { min-height: 150px; }
}

/* Tagged by tagMessageList() in lp-shared.js alongside .lp-wag-unclipped, when the
   message list sits inside a clipping ancestor that needed unclipping (see below).
   Turns the message list's own scroll off: once its container scrolls as a whole, a
   second independent scroll region nested inside the first has nothing left to do
   except catch swipes unpredictably — reported by the client as "why is there
   multiple scrolls." Normal document flow here means the list's content simply grows
   the outer wrapper's scrollHeight instead of scrolling within its own box. */
.lp-wag-messages-flattened {
  overflow-y: visible !important;
  min-height: 0 !important;
}
.lp-wag-messages-flattened::-webkit-scrollbar { display: none; }

/* Tagged by unclipAncestors() in lp-shared.js: an ancestor of the message list that
   hides overflow at a fixed height, silently discarding anything past it rather than
   letting the user scroll to it. In production this cut off the consent prompt's own
   "Agree & Continue" button — reported as the button "not being seen" — because the
   message list scrolling within its own box did nothing for a sibling row rendered
   below it and outside the box the ancestor actually shows.

   overflow-y:auto is the fix, not overflow-y:visible: the ancestor's own fixed height
   is left alone (undoing it would fight the card's own max-height budget elsewhere),
   so this content now scrolls to reach what visible would just spill out unclipped. */
.lp-wag-unclipped {
  overflow-y: auto !important;
  -webkit-overflow-scrolling: touch;
  /* Same permanent bar as #alhena-inline-chat and .lp-wag-messages above, for the same
     reason: this became a third independently-scrollable region inside the widget, and
     an unstyled native scrollbar would come and go with the platform default while the
     other two stay visibly there. */
  scrollbar-width: thin;
  scrollbar-color: var(--pink) rgba(246, 117, 153, .15);
}
.lp-wag-unclipped::-webkit-scrollbar { width: 6px; -webkit-appearance: none; }
.lp-wag-unclipped::-webkit-scrollbar-track { background: rgba(246, 117, 153, .15); border-radius: 999px; }
.lp-wag-unclipped::-webkit-scrollbar-thumb { background: var(--pink); border-radius: 999px; }

/* Built by attachScrollIndicator() in lp-shared.js: iOS and Android both use overlay
   scrollbars that only paint during an active scroll gesture, and no CSS reserves space
   for a permanent one on either platform — the ::-webkit-scrollbar rules above take
   effect only on desktop WebKit/Blink. This is a second, independent scroll indicator
   that sidesteps that limit entirely: it is ordinary painted content, not the browser's
   scroll chrome, so it stays visible under normal rendering rules rather than the OS's
   overlay-scrollbar rules.

   Display-only: pointer-events:none on the track means a tap here reaches the message
   underneath rather than the indicator, since this is a position readout, not a control. */
.lp-scrollind {
  position: absolute;
  top: 2px;
  right: 2px;
  bottom: 2px;
  width: 4px;
  border-radius: 999px;
  background: rgba(246, 117, 153, .15);
  pointer-events: none;
  z-index: 4;
}
.lp-scrollind-thumb {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  border-radius: 999px;
  background: var(--pink);
  /* Matches the rAF coalescing in JS: this only ever animates a scroll-driven position
     change, so a short transition smooths that without lagging behind real scrolling. */
  transition: transform .08s linear;
}

/* flex:none on the header and footer: they are fixed furniture, and the chat panel
   between them is the element that gives up space when the card is capped. */
.waghead { flex: none; }
.wagfoot {
  padding: 0 16px 16px;
  text-align: center;
  background: #FDF6F8;
  flex: none;
}
.wagpoints { display: flex; flex-wrap: wrap; justify-content: center; gap: 7px; margin: 14px 0 4px; }
.wagpoints span {
  display: flex;
  align-items: center;
  gap: 5px;
  background: #fff;
  border: 2px solid var(--lblue);
  border-radius: 999px;
  padding: 7px 13px;
  font-size: .75rem;
  font-weight: 700;
}
.wagpoints span .ic { font-size: .9rem; }

/* Short screens: the trust pills wrap to 199-220px — taller than the chat panel they sit
   under — which is what pushed the card past the bottom of the screen on small handsets.
   Tightening the pills here buys that height back for the conversation, which is the
   point of the section; the pills stay legible, just less padded. */
@media (max-height: 700px) {
  .wagfoot { padding: 0 12px 12px; }
  .wagpoints { gap: 5px; margin: 10px 0 2px; }
  .wagpoints span { padding: 5px 10px; font-size: .7rem; border-width: 1px; }
}

/* ===== TESTER GRID =====
   Single column below 480px: at two fixed columns every phone under ~480px wide (most
   handsets) squeezed each tester video into ~170px, well short of the aspect-ratio:3/4
   frame reading as anything but a thumbnail. Full-width rows fix that; two columns
   return once there is enough room for each to stay a comfortable size. */
.grid2 { display: grid; grid-template-columns: 1fr; gap: 10px; }
@media (min-width: 480px) {
  .grid2 { grid-template-columns: 1fr 1fr; }
}
.grid2 .frame { aspect-ratio: 3/4; }
/* Lift the shot brief clear of the dog name / caption that sits in the same corner. */
.grid2 .frame .slot { bottom: 36px; }
.dogname {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(transparent, rgba(43, 43, 51, .6));
  color: #fff;
  font-size: .78rem;
  font-weight: 700;
  padding: 24px 12px 8px;
  text-align: left;
  z-index: 2;
}
.testernote { text-align: center; font-size: .92rem; margin-top: 16px; }

/* ===== PICKER: weight band -> priority -> named SKU ===== */
.picker { background: var(--pale); }
.picker .lead { font-size: .8rem; font-weight: 700; color: var(--pink); margin-top: 6px; }

/* Second heading in the picker: the self-serve route sits below the Waggle card, so it
   is deliberately a step down in weight from the section's own heading. It is also the
   hero CTA's scroll target, hence the scroll-margin so it does not land flush against
   the top of the viewport. */
.sh.selfserve { margin-top: 38px; scroll-margin-top: 24px; }
.sh.selfserve h2 { font-size: 1.25rem; }
.sh.selfserve .hand { font-size: 1.15rem; }

.bands { display: flex; flex-wrap: wrap; justify-content: center; gap: 9px; margin: 18px 0 20px; }
.band {
  background: #fff;
  border: 2.5px solid var(--lblue);
  border-radius: 15px;
  cursor: pointer;
  padding: 11px 9px 9px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  min-width: 86px;
  font-family: var(--body);
  color: var(--ink);
  transition: .15s;
}
.band.sel {
  border-color: var(--pink);
  background: var(--lpink);
  box-shadow: 0 5px 14px rgba(246, 117, 153, .3);
}
.band .bn { font-family: var(--head); font-size: .8rem; }
.band .bk { font-size: .68rem; color: #6b6b76; font-weight: 600; }

/* Weight category images from the pa_pet-size terms — the same artwork the product
   pages use. They scale across the bands so the size ladder reads at a glance, which
   is what the emoji ramp in the design file was standing in for. */
.band .bimg { display: block; object-fit: contain; height: 34px; width: auto; }
.band[data-i="0"] .bimg { height: 24px; }
.band[data-i="1"] .bimg { height: 28px; }
.band[data-i="2"] .bimg { height: 32px; }
.band[data-i="3"] .bimg { height: 36px; }
.band[data-i="4"] .bimg { height: 40px; }
.band[data-i="5"] .bimg { height: 44px; }
.band[data-i="6"] .bimg { height: 48px; }

/* Fallback emoji when a term has no image attached (e.g. local dev, where the band PNGs
   are production-only) — the design file's 🐾, ramped so the size ladder still reads. */
.band .bpaw { display: block; line-height: 1; }
.band[data-i="0"] .bpaw { font-size: .9rem; }
.band[data-i="1"] .bpaw { font-size: 1.1rem; }
.band[data-i="2"] .bpaw { font-size: 1.3rem; }
.band[data-i="3"] .bpaw { font-size: 1.5rem; }
.band[data-i="4"] .bpaw { font-size: 1.7rem; }
.band[data-i="5"] .bpaw { font-size: 1.9rem; }
.band[data-i="6"] .bpaw { font-size: 2.1rem; }

#prioStep { display: none; text-align: center; margin-top: 6px; }
#prioStep .q { font-weight: 700; font-size: .95rem; margin-bottom: 10px; }
#prioChips { margin: 0 0 16px; }
.prio {
  display: flex;
  align-items: center;
  gap: 6px;
  background: #fff;
  border: 2px solid var(--lblue);
  border-radius: 999px;
  padding: 9px 15px;
  font-size: .82rem;
  font-weight: 700;
  cursor: pointer;
  font-family: var(--body);
  color: var(--ink);
  transition: .15s;
}
.prio .ic { font-size: 1rem; }
.prio.sel { border-color: var(--pink); background: var(--lpink); }

#prioResult { display: none; font-size: .88rem; margin-bottom: 10px; }
#prioResult .muted { color: #6b6b76; }
#prioResult .alt { display: block; font-size: .82rem; margin-top: 4px; }
#prioResult .alt a { color: var(--blue); font-weight: 700; }

#bandCta { display: none; }

.reassure { text-align: center; font-size: .82rem; color: #6b6b76; margin-top: 12px; }
.express { text-align: center; font-size: .85rem; margin-top: 8px; }
.express a { color: var(--blue); font-weight: 700; }

.offerbox { text-align: center; margin-top: 22px; background: #fff; border-radius: 16px; padding: 18px 16px; }
.offerbox .auto { font-weight: 700; font-size: .92rem; margin-bottom: 2px; }
.offerbox .oneoff { font-size: .84rem; margin: 8px 0 4px; }
.offerbox .codechip {
  border-color: var(--pink);
  color: var(--ink);
  background: var(--pale);
  margin-top: 2px;
}
.offerbox .codechip b { color: var(--pink); }
.offerbox .browse { margin-top: 12px; }
.offerbox .browse a { color: var(--blue); font-weight: 700; font-size: .88rem; }

/* ===== PRODUCT IN ACTION ===== */
.tiles { display: grid; gap: 12px; }
@media (min-width: 560px) {
  .tiles { grid-template-columns: 1fr 1fr 1fr; }
}
.tile { border-radius: 18px; overflow: hidden; position: relative; }
.tile .frame { aspect-ratio: 1/1; border-radius: 18px; }
.tile .frame .slot { bottom: 40px; }
.tile .cap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(transparent, rgba(43, 43, 51, .72));
  color: #fff;
  padding: 26px 14px 10px;
  font-size: .82rem;
  font-weight: 700;
  z-index: 2;
}
.steps {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 16px;
  flex-wrap: wrap;
  font-size: .8rem;
  font-weight: 600;
  color: #6b6b76;
}
.steps b { color: var(--pink); font-family: var(--head); }
.madenote { text-align: center; font-size: .92rem; margin-top: 14px; }
.madenote .hand { color: var(--pink); font-size: 1.2rem; }

/* ===== BLENDS ===== */
.blends { background: var(--pale); }
.bcard {
  background: #fff;
  border-radius: 15px;
  padding: 13px 16px;
  margin-bottom: 9px;
  display: flex;
  gap: 12px;
  align-items: flex-start;
  box-shadow: 0 2px 8px rgba(43, 43, 51, .05);
}
.bcard .ic { flex: none; font-size: 1.7rem; line-height: 1; margin-top: 1px; }
.bcard h3 { font-size: 1rem; }
.bcard p { font-size: .86rem; }
.cred { text-align: center; font-size: .86rem; font-weight: 600; margin-top: 18px; }
.blendhelp { text-align: center; margin-top: 10px; font-size: .88rem; }
.blendhelp a { color: var(--blue); font-weight: 700; }

/* ===== VIDEO BAND ===== */
.vband .frame { aspect-ratio: 16/9; }

/* ===== TARGETED / COMMITMENT ===== */
.commit { background: var(--lpink); text-align: center; }
.commit h2 { font-size: 1.5rem; margin-bottom: 10px; }
.commit p { max-width: 500px; margin: 0 auto; }
.commit .hand { font-size: 1.4rem; display: block; margin-top: 14px; }
.targeted { background: var(--pale); }
.targeted .wrap { text-align: left; }
.targeted h2 { font-size: 1.5rem; margin-bottom: 10px; }
.targeted p + p { margin-top: 10px; }

/* ===== WHY WEIGHT MATTERS ===== */
.weight { text-align: center; background: var(--pale); }
.weight .stat {
  font-family: var(--head);
  font-size: 3.2rem;
  color: var(--pink);
  display: block;
  margin: 14px 0 2px;
}
.weight .statsub { font-size: .88rem; font-weight: 600; }

/* ===== TRUST ===== */
.trust .row { display: grid; grid-template-columns: 1fr; gap: 16px; text-align: center; }
@media (min-width: 540px) {
  .trust .row { grid-template-columns: 1fr 1fr 1fr; }
}
.trust .frame { width: 84px; height: 84px; border-radius: 50%; margin: 0 auto 10px; }
.trust .frame::before { border-radius: 50%; inset: 6px; }
/* Client feedback: at 84px the shot-brief label (frame.php's .slot, sized for the much
   larger tester/tile frames) reads as a dark box sitting on top of the circle rather
   than a caption — it was measured at 41% of the circle's area, roughly covering the
   middle third of exactly where a face would be. It also duplicates the <h3> title
   already rendered directly beneath every trust frame ("Andy Miller BVSc MRCVS", etc.),
   so hiding it here costs nothing — the shot brief is still visible on the tester grid
   and tiles, where the same field has room to read as a caption rather than an overlay. */
.trust .frame .slot { display: none; }
/* The trust frames are 84px circles, so the placeholder emoji is scaled down to suit. */
.trust .frame .paw { font-size: 1.6rem; }
.trust h3 { font-size: .98rem; }
.trust p { font-size: .82rem; color: #6b6b76; }

/* ===== FOUNDING MEMBER URGENCY =====
   Same frame + scrim + content layering as .hero (lp-shared.css), reused here with
   content pinned to the top instead of the bottom and the scrim gradient inverted to
   match — dark at the top, clearing lower down, since that's where the text sits.

   padding: 0 is required, not cosmetic: lp-shared.css's bare `section { padding: 46px 0 }`
   rule applies to every section by default, and .hero/.closer both override it to zero
   for exactly this reason — without it here too, .urg silently gets 46px of empty space
   above AND below the frame (the .frame is in normal flow and defines the section's
   height; .scrim/.content are absolutely positioned and don't).

   The frame's aspect-ratio + max-height pairing is deliberately the same restraint the
   hero uses (capped, not left to grow with the image): without it a tall/wide upload
   would blow the section's height out on real viewports, which is exactly the "web view
   is too big" failure mode to avoid here. Cropping is plain object-fit: cover at 100%,
   inherited from the shared .frame > img rule — same as .hero and .closer, not a custom
   zoom on top of it, so the aspect-ratio itself is what "approximately 2x the container"
   in the reference actually comes from, not a double crop that hides more of the shot.

   max-height is min()'d with a flat px ceiling, not vh alone: a vh percentage still
   scales up to a huge absolute size on a tall/large monitor (56vh of a 2900px-tall
   screen is ~1620px — confirmed live, that's what "takes up the whole screen" was) —
   the px number is what actually stops it growing past a sane size on real hardware.

   background + min-height on .urg itself (not just .frame) are a required fallback,
   not decoration: frame.php renders nothing at all — no placeholder, no box — when
   image, icon and slot are all empty (confirmed live on staging: urg_image/urg_icon/
   urg_slot were never set there, only in this local DB). Without its own background
   and height, .urg collapses to 0px, and its absolutely-positioned .content still
   renders at top:0 — landing exactly on top of .closer, which paints over it since it
   comes later in the DOM. Net effect on staging: the entire founding-pack urgency
   block (heading, copy, CTA) was present in the DOM but invisible, hidden behind the
   next section's photo. This restores the section's original dark-text-only look as
   the no-image fallback, so it degrades gracefully instead of disappearing. */
.urg { position: relative; padding: 0; background: var(--ink); color: #fff; text-align: center; min-height: 320px; }
.urg .frame { border-radius: 0; width: 100%; aspect-ratio: 4/5; max-height: min(70svh, 560px); }
@media (min-width: 700px) {
  .urg { min-height: 360px; }
  .urg .frame { aspect-ratio: 16/9; max-height: min(56vh, 480px); }
}
.urg .scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(43, 43, 51, .78) 0%, rgba(43, 43, 51, .15) 55%);
  pointer-events: none;
}
.urg .content {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  max-width: 620px;
  margin: 0 auto;
  padding: 28px 18px 0;
}
.urg .hand { color: var(--pink); font-size: 1.35rem; display: block; }
.urg h2 { font-size: 1.7rem; margin: 2px 0 12px; }
.urg p { max-width: 460px; margin: 0 auto; font-size: .95rem; }
.urg .kicker { color: var(--lpink); font-size: 1.3rem; margin-top: 14px; }
.urg .btn { margin-top: 16px; }

/* Narrow viewports: the founding-pack copy (kicker, heading, 3-line paragraph, script
   line, button) is taller than the 4/5 frame it's overlaid on, and since .content is
   absolutely positioned it doesn't add height to .urg — it just spills past the
   image's bottom edge into whatever section follows. Flipping the roles fixes that
   without giving up the overlay: .frame becomes the absolutely-positioned full-bleed
   background (inset: 0, stretched via the shared .frame > img object-fit: cover), and
   .content goes back to normal flow so its real height is what sizes .urg. The image
   then always covers the whole section, however tall the copy makes it, instead of
   either overflowing past it or (an earlier attempt) being pushed below it as a
   separate block. .content stays position: relative rather than static so it still
   paints above the absolutely-positioned .frame/.scrim, per DOM order. */
@media (max-width: 769px) {
  .urg .frame {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
    max-height: none;
  }
  .urg .content {
    position: relative;
    padding: 28px 18px 40px;
  }
}

/* Short viewports (landscape phones): the floating Alhena launcher always claims the
   bottom-right corner, and content here reads top-down inside a height-capped frame —
   without this the CTA can end up sitting right where the launcher does. Same
   short-viewport pattern already used for .wagcard elsewhere in this file. */
@media (max-height: 480px) {
  .urg .content { padding-top: 14px; }
  .urg h2 { font-size: 1.35rem; margin: 2px 0 6px; }
  .urg p { font-size: .85rem; }
  .urg .kicker { margin-top: 6px; font-size: 1.1rem; }
  .urg .btn { margin-top: 8px; }
}

/* ===== CLOSER ===== */
.closer { background: var(--blue); color: #fff; text-align: center; padding: 0 0 56px; }
/* Previously unconstrained: no aspect-ratio, no max-height, so the image rendered at
   its native ratio scaled to 100% width — fine at modest widths, but with no ceiling
   it scales up without limit on a wide viewport (a 3840px-wide screen with no cap here
   was the actual source of the "still too big" section, not .urg's — the two now sit
   flush against each other with no gap between them, so they read as one block). The
   base .frame > img rule already does width:100%;height:100%;object-fit:cover, so once
   max-height caps the box, cropping follows the same mechanism .hero/.urg use — no
   aspect-ratio needed here since .closer's text sits below the frame, not overlaid on it. */
.closer .frame { border-radius: 0; width: 100%; max-height: 600px; margin-bottom: 34px; }
.closer h2 { font-size: 1.9rem; margin-bottom: 6px; }
.closer .hand { color: var(--lpink); font-size: 1.4rem; display: block; margin-bottom: 18px; }
.closer .btn { background: #fff; color: var(--blue); }
.closer .alt { margin-top: 12px; font-size: .9rem; }
.closer .alt a { color: #fff; font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.offer {
  background: rgba(255, 255, 255, .16);
  border-radius: 13px;
  padding: 12px 16px;
  font-size: .9rem;
  font-weight: 600;
  max-width: 480px;
  margin: 20px auto 0;
}
.offer small { display: block; font-weight: 500; font-size: .78rem; opacity: .92; margin-top: 2px; }
