/* m-hero — mobile/responsive layer.
   Inline styles in index.html win on specificity, so overrides here generally
   need !important. Loaded after checkout-modal.css.

   Scope note: the teaser card reuses the shared .co-* checkout classes. Every
   rule that touches them is scoped under .mz-hero-card so the real checkout
   component (owned elsewhere) is never affected.

   Desktop contract: NOTHING in this file may apply above 900px except inside a
   media query that also constrains max-height (i.e. landscape handsets). Two
   rules used to sit outside every query and were silently changing the 1280px
   render; they now live in the 900px band where they were always meant to be. */

/* Stacked variant of the card entrance: the desktop keyframe ends on
   scale(.93) with a right-center origin, which only makes sense when the card
   is hugging the right edge of a two-column grid. */
@keyframes mz-hero-in-stacked {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}

/* The teaser card is a canned replay of the checkout that runs for real
   further down the page. Below 900px it gets a labelled "Live demo" badge that
   links to that demo. Hidden at desktop widths — no desktop change. */
.mz-hero-card > .mz-hero-jump {
  display: none;
  position: absolute;
  z-index: 12;
  text-decoration: none;
  -webkit-tap-highlight-color: rgba(63, 115, 87, 0.12);
}
.mz-hero-card > .mz-hero-jump:focus-visible {
  outline: 2px solid #3f7357;
  outline-offset: 3px;
}

/* ============================================================
   1080px — tighten the desktop grid before it collapses
   ============================================================ */
@media (max-width: 1080px) {
  .m-hero { padding: 66px 28px 54px !important; }
  .m-hero-grid { gap: 40px !important; }
  .m-hero-wordmark { padding: 76px 28px 58px !important; }
}

/* ============================================================
   900px — single column: copy first, teaser card below
   ============================================================ */
@media (max-width: 900px) {
  .m-hero { padding: 56px 24px 48px !important; }
  .m-hero-wordmark { padding: 60px 24px 52px !important; }

  /* one rail, centred in the padded container: the copy and the CTA rail share
     BOTH edges of it, so the hero reads as a designed stack rather than a
     two-column grid with the right column removed */
  .m-hero-grid {
    grid-template-columns: minmax(0, 1fr) !important;
    max-width: 620px !important;
    gap: 40px !important;
    align-items: start !important;
    justify-items: stretch !important;
  }

  .m-hero-copy { width: 100%; }
  .m-hero-copy > p { max-width: none !important; }

  /* The card fills the rail on phones, where the rail is already narrower than
     the card's natural 392px. On tablets it is capped and centred instead —
     see the 641px band. */
  .m-hero-grid > .mz-hero-card {
    justify-self: stretch !important;
    max-width: none !important;
    width: 100% !important;
  }

  .mz-hero-card {
    transform-origin: center center !important;
    animation: mz-hero-in-stacked .7s ease both !important;
    box-shadow: 0 18px 46px rgba(8, 24, 16, 0.14) !important;
  }

  /* The confirmation step has nothing left to point at, so the fake cursor
     bows out instead of parking itself in the receipt's white space. */
  .mz-hero-card .mz-cursor {
    transition: left .8s cubic-bezier(.45,.05,.2,1),
                top .8s cubic-bezier(.45,.05,.2,1),
                opacity .45s ease;
    /* runHeroStep places the cursor's box origin on the target's centre, but
       the glyph's tip is inset from that origin — pull the box back by the
       inset so the tip, not the corner, lands on the row. */
    margin-left: -4px;
    margin-top: -2px;
  }
  .mz-hero-card:has(.co-center) .mz-cursor { opacity: 0; }

  /* Payment step: .co-sub sits 7px off the Apple Pay button, and that button
     carries a 3px focus ring which eats most of the gap. */
  .mz-hero-card .co-wallets { margin-top: 15px !important; }

  /* ---- card body height ----------------------------------------------
     min-height, never height. Two numbers feed it:

       --mz-card-min  a per-band FLOOR in this file, tuned to the tallest step
                      actually measured in that band.
       --mz-card-h    published at runtime by assets/m-hero.js, which measures
                      each step as it renders.

     min-height takes max() of the two, which is what kills the late shift.
     m-hero.js can only ever see one step at a time, so its running maximum
     used to converge UPWARD — at 390x844 it published 436px on first paint and
     441px three seconds later, when the confirmed step first rendered, sliding
     the card and everything under it down by 5px while the reader watched. The
     floor is already the final answer, so the first paint is the last paint
     and the script only has to react to step markup it has never seen.

     Because it is a MINIMUM, a value that is too small makes the box grow
     rather than clip, so the checkout owner can change the step markup freely
     without breaking this. */
  .mz-hero-card { --mz-card-min: 468px; }
  .mz-hero-card .co-body-inner {
    height: auto !important;
    min-height: max(var(--mz-card-h, 0px), var(--mz-card-min, 468px)) !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: center !important;
  }
  .mz-hero-card .co-body-inner > * { flex: none; }

  /* The confirmation carries ~110px less content than the sign-in step it has
     to share a height with, so it spends the difference on itself rather than
     banking it as two pockets of empty beige above and below. */
  .mz-hero-card .co-check {
    width: 84px !important;
    height: 84px !important;
    margin-bottom: 28px !important;
  }
  .mz-hero-card .co-check-lg { width: 42px !important; height: 42px !important; }
  .mz-hero-card .co-receipt {
    margin: 32px 0 0 !important;
    padding: 24px 20px !important;
    gap: 17px !important;
  }

  /* the sign-in step sets the card's height, so 4px off each row is 16px off
     every step's empty space */
  .mz-hero-card .co-signbtn { min-height: 54px !important; }
  .mz-hero-card .co-list { gap: 10px !important; }

  /* the "Live demo" badge and the header room it needs live in their own
     block below — they are also wanted in landscape above 900px, and under
     reduced motion at every width. */

  /* product-hero card (other hero variant): centred, not stretched to 620 */
  .m-hero-grid > *:not(.m-hero-copy):not(.mz-hero-card) {
    justify-self: center !important;
    margin: 0 !important;
  }
}

/* ============================================================
   The "Live demo" badge
   ------------------------------------------------------------
   This used to be an invisible anchor stretched across the whole card. It
   covered the merchant header, all four fake buttons and the receipt, so a tap
   anywhere jumped the page, card text could not be selected, and on iOS a
   long-press opened the link sheet. It is now a labelled badge occupying the
   header's right end — announced, out of the content's way, and still a 62px
   tap target. The "Secure" chip it replaces is redundant with the "Secured by
   MOSS" footer three rows below.

   The label is REAL TEXT in the markup, not a CSS `content` string. As a
   pseudo-element it was invisible to find-in-page, to translation, and to
   assistive tech, and it disagreed with the aria-label ("Try the live
   checkout") that WAS exposed — so a voice-control user saying "tap Live demo"
   hit nothing. That is a WCAG 2.5.3 Label in Name failure, and the fix is for
   the accessible name to BE the visible label. The aria-label is gone; the
   name now comes from the text. The arrow is aria-hidden so the name is
   exactly "Live demo" (or "Demo" in the short form, which is likewise exactly
   what is on screen — display:none text is excluded from the name, so the two
   forms can never disagree with what is rendered).

   Wanted in three situations that no single media query describes: every
   stacked (<=900px) layout; landscape handsets ABOVE 900px (a 926x428 Pro Max
   keeps the desktop grid but gets the compacted card, and used to be left with
   no demo affordance at all); and — at any width, desktop included — a
   reduced-motion reader, whose card is frozen on step one and otherwise has
   nothing at all to say it is an illustration of the demo further down.
   ============================================================ */
@media (max-width: 900px),
       (orientation: landscape) and (max-height: 520px),
       (prefers-reduced-motion: reduce) {
  .mz-hero-card > div:first-child > div:last-child { display: none !important; }
  /* the badge is absolutely positioned, so the header has to reserve its
     width or the merchant name runs right up against the pill */
  .mz-hero-card > div:first-child {
    padding-right: 118px !important;
    min-width: 0;
  }
  .mz-hero-card > div:first-child > div:nth-child(2) { min-width: 0; }
  .mz-hero-card > div:first-child > div:nth-child(2) > div {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .mz-hero-card > .mz-hero-jump {
    display: flex;
    align-items: center;
    justify-content: center;
    inset: 0 12px auto auto;
    height: 62px;
    min-width: 44px;
    border-radius: 12px;
  }
  .mz-hj-pill {
    display: block;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.01em;
    line-height: 1;
    white-space: nowrap;
    color: #3f7357;
    background: #e6efe9;
    border: 1px solid rgba(63, 115, 87, 0.3);
    border-radius: 999px;
    padding: 7px 11px;
  }
  .mz-hero-card > .mz-hero-jump:active .mz-hj-pill { background: #d9e8df; }
  .mz-hj-abbr { display: none; }
}

/* How much room the header has to reserve depends on how wide the CARD is,
   not on how wide the screen is. At 844x390 — iPhone 12/13/14 landscape, the
   most common landscape viewport there is — the card column resolves to 287px
   INSIDE an 844px viewport, narrower than the 288px card a 320px phone gets,
   so the viewport-keyed guard this used to have could never fire for it and
   the merchant name rendered as "Rubber Duc...". Ask the card instead.

   304px is where "Bath use only supplies" (121px) still clears the long pill:
   20 padding + 30 mark + 11 gap + 121 + 118 reserve = 300, plus slack. Below
   it the badge gives up its adjective rather than making the merchant — whose
   card this is supposed to look like — the thing that gets truncated. */
@media (max-width: 900px),
       (orientation: landscape) and (max-height: 520px) {
  .mz-hero-card {
    container-type: inline-size;
    container-name: mzcard;
  }

  /* ---- the confirmed step spends whatever slack the tallest step leaves ----
     All three steps share one height, and which step sets it moves with the
     width: at 390 the confirmation IS the tallest, but at 320 the sign-in step
     is 438px against the confirmation's 378px, so the receipt used to float in
     60px of beige. Letting the confirmed step grow into the box and space its
     own four elements evenly turns that slack into rhythm instead of a pocket,
     and it self-adjusts: at zero slack space-evenly is indistinguishable from
     the centring it replaces. min-height:auto on a flex item means the box
     still grows if the content outgrows the floor, so this cannot clip.
     (m-hero.js neutralises the grow before it measures — otherwise this step
     would measure as "exactly as tall as the box already is" and the running
     maximum could never come back down.) */
  .mz-hero-card .co-body-inner > .co-center {
    flex: 1 1 auto !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: space-evenly !important;
  }
  /* space-evenly needs a flex container, and flex switches margin collapsing
     off — which on its own made the confirmed step 27px TALLER than the box it
     is supposed to fit inside, because the four elements' margins stopped
     overlapping and started stacking. Restate the rhythm as one-sided margins
     so the step measures at zero slack exactly what it measured in block flow:
     28 under the tick, 14 under the heading, 32 above the receipt (the outer
     two are set above and in the landscape band, and this holds for both). */
  .mz-hero-card .co-body-inner > .co-center > .co-h1 { margin: 0 0 14px !important; }
  .mz-hero-card .co-body-inner > .co-center > .co-sub { margin: 0 !important; }
}
@container mzcard (max-width: 303px) {
  .mz-hero-card > div:first-child { padding-right: 88px !important; }
  .mz-hj-full { display: none; }
  .mz-hj-abbr { display: inline; }
  .mz-hj-pill { padding: 7px 10px; }
}

/* ============================================================
   501–900px, landscape — a rail the card can fill
   ------------------------------------------------------------
   Stretched to the full 620px rail, every fixed-size part of the card stayed
   put while the box got 70% wider than its desktop self: a 566px Apple Pay
   button with a two-character label, 400px of white between "Continue with
   Apple" and its chevron, an "or" divider spanning the whole card. Landscape
   answers that by bringing the RAIL down to a width the card can fill rather
   than by centring a narrow card inside a wide one — a card floating in the
   middle of a left-aligned stack is the three-edges problem all over again.
   (Portrait is handled above: it has the page gutter to honour, so there the
   card fills the gutter-to-gutter rail and caps its contents instead. The two
   landscape bands further down override this for the viewports that have a
   real device behind them; what is left here is windowed browsers.)
   ============================================================ */
@media (min-width: 501px) and (max-width: 900px) and (orientation: landscape) {
  .m-hero-grid { max-width: 460px !important; }
  .m-hero-grid > .mz-hero-card {
    justify-self: stretch !important;
    max-width: none !important;
  }
  .m-hero-ctas { max-width: none !important; }
}

/* ============================================================
   640px — phone
   ============================================================ */
@media (max-width: 640px) {
  /* --m-hero-pad-top mirrors the padding-top on the same line; the
     landing-screen block below subtracts it from the viewport, so the two must
     never drift. */
  .m-hero { --m-hero-pad-top: 40px; padding: 40px 20px 44px !important; }
  .m-hero-wordmark { --m-hero-pad-top: 44px; padding: 44px 20px 46px !important; }

  .m-hero-grid { gap: 36px !important; }

  /* type: headline down a step, body copy stays comfortably above 15px.
     (The portrait landing-screen band further down re-scales both against the
     viewport; these are the landscape / short-screen values.) */
  .m-hero-copy > h1 { font-size: 38px !important; letter-spacing: -0.03em !important; }
  .m-hero-copy > p {
    font-size: 17px !important;
    line-height: 1.5 !important;
    margin-top: 20px !important;
  }
  /* eyebrow chip */
  .m-hero-copy > div:first-child { margin-bottom: 20px !important; }

  /* CTAs: stacked, full width, generous tap target */
  .m-hero-ctas {
    flex-direction: column !important;
    align-items: stretch !important;
    max-width: 420px;
    gap: 10px !important;
    margin-top: 26px !important;
  }
  .m-hero-ctas > a {
    justify-content: center !important;
    text-align: center;
    padding: 16px 22px !important;
    min-height: 52px;
  }

  /* product-hero card: keep its "Add to cart" a real tap target */
  .m-hero-grid > *:not(.m-hero-copy) button {
    min-height: 44px !important;
    padding: 12px 20px !important;
  }

  /* teaser card: tighter inner gutters */
  .mz-hero-card { border-radius: 20px !important; --mz-card-min: 452px; }
  .mz-hero-card .co-body-inner { padding: 24px 18px !important; }
  .mz-hero-card .co-h1 { font-size: 21px !important; }

  /* ---- wordmark hero ---- */
  .m-hero-wordmark > div > div[style*="align-items: baseline"] { gap: 12px !important; }
  .m-hero-wordmark img[alt="MOSS"] { height: 46px !important; }
  .m-hero-wordmark > div > div > span { font-size: clamp(38px, 11.5vw, 52px) !important; }
  .m-hero-wordmark h1 {
    font-size: clamp(28px, 8.4vw, 40px) !important;
    margin-top: 28px !important;
  }
  .m-hero-wordmark p {
    font-size: 17px !important;
    line-height: 1.5 !important;
    margin-top: 18px !important;
  }
  .m-hero-wordmark div[style*="margin-top: 34px"] {
    flex-direction: column !important;
    align-items: stretch !important;
    max-width: 420px;
    margin: 26px auto 0 !important;
    gap: 10px !important;
  }
  .m-hero-wordmark div[style*="margin-top: 34px"] > a {
    justify-content: center !important;
    padding: 16px 22px !important;
    min-height: 52px;
  }
}

/* ============================================================
   400px — small phone
   ============================================================ */
@media (max-width: 400px) {
  .m-hero { --m-hero-pad-top: 34px; padding: 34px 16px 40px !important; }
  .m-hero-wordmark { --m-hero-pad-top: 38px; padding: 38px 16px 42px !important; }

  .m-hero-copy > h1 { font-size: 35px !important; }
  .m-hero-copy > p { font-size: 16px !important; }

  .mz-hero-card { --mz-card-min: 442px; }
  .mz-hero-card .co-body-inner { padding: 22px 16px !important; }
  .mz-hero-card .co-h1 { font-size: 20px !important; }
  .mz-hero-card .co-list { gap: 9px !important; }
  .mz-hero-card .co-signbtn { min-height: 54px !important; padding: 0 14px !important; gap: 11px !important; }

  .m-hero-wordmark img[alt="MOSS"] { height: 40px !important; }
  .m-hero-wordmark p { font-size: 16px !important; }
}

/* ============================================================
   360px — last-resort tightening
   ============================================================ */
@media (max-width: 360px) {
  .m-hero-copy > h1 { font-size: 32px !important; }
  .mz-hero-card { --mz-card-min: 438px; }
  .mz-hero-card .co-body-inner { padding: 20px 14px !important; }
  /* drop the decorative chevrons so sign-in labels stay on one line */
  .mz-hero-card .co-chev { display: none !important; }

  /* receipt: keep every row on one line so the block reads as a column of
     pairs — "Estimated delivery / 3-5 business days" was the only wrapper */
  .mz-hero-card .co-receipt { padding: 18px 14px !important; }
  .mz-hero-card .co-kv { font-size: 12.5px !important; gap: 10px !important; flex-wrap: nowrap !important; }
  .mz-hero-card .co-kv-v { white-space: nowrap !important; word-break: normal !important; }
}

/* Two wrapping cliffs sit inside the 360px band and both of them make the
   sign-in step, which is the tallest of the three, suddenly taller: the
   passkey row's second line arrives at a 300px card (viewport 332) and the
   fifth sign-in label folds at a 293px card (viewport 325). A single floor for
   the whole band would have to assume the worst of the three and would leave
   46px of empty beige on a 360px phone, which is more slack than the bug this
   was written to fix. Measured, then set a few pixels EARLY, so the cliff
   arriving slightly sooner on another engine still lands inside the right
   step rather than making the runtime script correct the box after paint. */
@media (max-width: 339px) { .mz-hero-card { --mz-card-min: 462px; } }
@media (max-width: 333px) { .mz-hero-card { --mz-card-min: 484px; } }

/* ============================================================
   Portrait up to 900px — the hero's edge is the page's edge
   ------------------------------------------------------------
   The centred rail this file used to impose (460px from 501, 620px from 641)
   optimised the hero against itself instead of against the page, and the page
   is what the reader scrolls. Every .m-sec runs to the gutter; the hero did
   not. At 768 the eyebrow started 50px right of the wordmark above it and 50px
   right of every section heading below it; at 900 the block sat 116px in from
   a 24px gutter with left-aligned text inside it, which reads as an indented
   column rather than a centred one. The hero now starts where the page starts
   at every portrait width. The lede keeps a measure — that is typography, not
   layout, and it has no visible edge.

   Landscape is deliberately untouched: its own bands already put a rail on
   the gutter, and a full-width rail on a 390px-tall screen is a different
   problem with a different answer.
   ============================================================ */
@media (max-width: 900px) and (orientation: portrait) {
  .m-hero-grid { max-width: none !important; }
  .m-hero-copy > p { max-width: 620px !important; }
}

/* From 501px up the rail is wider than the card's natural 392px. The card
   fills it and caps its CONTENTS instead of capping itself: a 424px column is
   exactly the measure the card has at 500px, so nothing inside it re-wraps as
   the screen grows — the controls stop stretching (a 566px Apple Pay button
   with a two-character label was the original complaint) without the box
   having to strand itself in the middle of a left-aligned stack. */
@media (min-width: 501px) and (max-width: 900px) and (orientation: portrait) {
  .m-hero-grid > .mz-hero-card {
    justify-self: stretch !important;
    max-width: none !important;
  }
  .mz-hero-card .co-body-inner > * {
    width: 100%;
    max-width: 424px;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  /* and the buttons go back to a row. There is room for both on one line from
     501px (442px of content in a 461px rail), and a stacked pair on a 600px
     rail is not two buttons any more, it is two full-bleed bars. Hugging
     their content also ends the 180px of ragged space that a 420px-capped,
     stretched CTA rail used to leave beside a 620px column. */
  .m-hero-ctas {
    flex-direction: row !important;
    align-items: center !important;
    flex-wrap: wrap !important;
    max-width: none !important;
  }
  .m-hero-ctas > a { flex: 0 0 auto; }
}

/* ---- type scale across the 640/641 seam ----------------------------
   The landing screen sizes its headline against the viewport it fills and
   reached 56px at 640x900; one pixel wider, the desktop rule took over at
   4.6vw = 40px. A headline that loses 29% as the screen gets WIDER makes 640
   and 700 look like two different sites. The tablet band now tapers the
   landing scale down to the desktop curve instead of falling off it, and lands
   exactly on it: 56 at 641, 53 at 700, 50 at 768, 41.4 at 900 — which is what
   the inline clamp itself resolves to at 901, so the seam at the other end of
   the band is invisible too. The height term is carried over from the landing
   band so short portrait windows (641x700) stay continuous as well. */
@media (min-width: 641px) and (max-width: 900px) and (orientation: portrait) {
  .m-hero-copy > h1 {
    font-size: clamp(40px, min(92.1px - 5.64vw, 8.4vh - 16px), 56px) !important;
    letter-spacing: -0.03em !important;
  }
  .m-hero-copy > p {
    font-size: clamp(16px, min(25.9px - 0.77vw, 3vh - 6px), 21px) !important;
  }
  .m-hero-wordmark h1 {
    font-size: clamp(30px, min(53.5px - 1.54vw, 6.4vh - 14px), 46px) !important;
  }
  .m-hero-wordmark > div > div > span {
    font-size: clamp(40px, min(47px + 1.78vw, 7.6vh - 10px), 63px) !important;
  }
  .m-hero-wordmark p {
    font-size: clamp(16px, min(25.9px - 0.77vw, 3vh - 6px), 21px) !important;
  }
}

/* ============================================================
   Portrait phones — the hero is its own landing screen
   ------------------------------------------------------------
   On first paint you should see the eyebrow, headline, lede, both CTAs and a
   scroll cue, and NOTHING else: the teaser card starts below the fold and is a
   reward for scrolling. The copy block is given the viewport minus the sticky
   nav minus the hero's own top padding, so its bottom edge lands on the fold.

   Owning a whole screen means FILLING it. Every size below is driven by the
   viewport rather than fixed, and the vh terms are shaped so that a 320x568
   screen lands on the values it already had (that size was the one the
   composition was right at) while a 430x932 screen gets a 56px headline and
   roughly double the vertical rhythm. Without this the same 434px block sat in
   every screen from 568px to 932px tall and up to 44% of the largest ones was
   bare background.

   min-height, never height: at 320x568 the copy is only ~30px shy of the space
   available, and one more line of lede anywhere would make a fixed height clip.
   Here the block simply grows past the fold instead.

   svh, not dvh or vh: dvh re-resolves as the mobile URL bar collapses, which
   would slide the fold around under the reader's thumb mid-scroll. svh is the
   URL-bar-visible measurement, i.e. the worst case, so the hero is guaranteed
   to fit on first paint and then stays put. The vh line above is the fallback
   for engines without svh (it over-reserves by the bar's height, which only
   pushes the card further down — never up into view).

   var(--nav-h, 70px): --nav-h is declared in m-nav.css, a file this agent does
   not own. Without the fallback, renaming it there would turn every one of
   these declarations invalid and the landing screen would vanish silently.

   Gated to portrait: a full-viewport hero on an 844x390 handset would be
   absurd, and the landscape band below deliberately restores two columns.
   Gated to <=640px: this is a phone answer. At 768x1024 the same rule would
   strand ~500px of empty beige under four lines of type, which reads as a
   layout bug rather than as composition — the tablet keeps its natural stack.

   Placed after the 400px and 360px bands so its viewport-driven type wins over
   their fixed steps at equal specificity.
   ============================================================ */
@media (max-width: 640px) and (orientation: portrait) and (min-height: 480px) {
  .m-hero-copy,
  .m-hero-wordmark > div {
    box-sizing: border-box;
    min-height: calc(100vh - var(--nav-h, 70px) - var(--m-hero-pad-top, 40px));
    min-height: calc(100svh - var(--nav-h, 70px) - var(--m-hero-pad-top, 40px));
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* optical centring: a landing block reads as "centred" when it sits a
       little above true centre. Inside a border-box min-height this lifts the
       group without making the block any taller. Smaller than it was, because
       the block itself now takes up far more of the screen. */
    padding-bottom: 3vh;
  }
  /* the group must stay a group — no flex stretching of the CTA rail */
  .m-hero-copy > *,
  .m-hero-wordmark > div > * { flex: none; }
  .m-hero-copy > div:first-child { align-self: flex-start; }

  /* ---- type and rhythm scale with the screen they have to fill ---- */
  .m-hero-copy > h1 {
    font-size: clamp(30px, min(13vw, 8.4vh - 16px), 56px) !important;
  }
  .m-hero-copy > p {
    font-size: clamp(16px, min(4.8vw, 3vh - 6px), 21px) !important;
    margin-top: clamp(13px, 6vh - 19px, 30px) !important;
    /* at 430x932 the lede's last line was the single word "custodial." — an
       orphan at the largest phone size, directly above the CTAs. `pretty` is
       exactly the fix (it pulls a word down from the line above); engines
       without it wrap as before. */
    text-wrap: pretty;
  }
  .m-hero-copy > div:first-child {
    margin-bottom: clamp(14px, 10.6vh - 41px, 50px) !important;
  }
  .m-hero-ctas {
    margin-top: clamp(18px, 12vh - 48px, 62px) !important;
    /* round(): a vh-driven gap lands on 17.6px at 844, the only fractional
       gap on the page. Engines without round() drop the declaration and take
       the flat 10px from the 640 band. */
    gap: round(clamp(10px, 2.4vh - 4px, 18px), 1px) !important;
  }
  .m-hero-ctas > a {
    min-height: clamp(52px, 6vh + 18px, 64px) !important;
  }

  .m-hero-wordmark h1 {
    font-size: clamp(28px, min(9.4vw, 6.4vh - 14px), 46px) !important;
    margin-top: clamp(24px, 6vh - 12px, 40px) !important;
  }
  .m-hero-wordmark > div > div > span {
    font-size: clamp(38px, min(12.4vw, 7.6vh - 10px), 60px) !important;
  }
  .m-hero-wordmark p {
    font-size: clamp(16px, min(4.8vw, 3vh - 6px), 21px) !important;
  }
  .m-hero-wordmark div[style*="margin-top: 34px"] {
    margin-top: clamp(22px, 10vh - 31px, 62px) !important;
    gap: round(clamp(10px, 2.4vh - 4px, 18px), 1px) !important;
  }
  .m-hero-wordmark div[style*="margin-top: 34px"] > a {
    min-height: clamp(52px, 6vh + 18px, 64px) !important;
  }

  /* ---- scroll cue ----------------------------------------------------
     A clean fold costs the page its only "there is more below" signal, and at
     320x568 — where the CTA rail ends 48px clear of the fold with nothing
     peeking — the page otherwise reads as finished. It is deliberately not a
     control: no label, no hit area, no motion. It is the last flex item of the
     copy column rather than a corner ornament, so it is centred under the
     buttons and travels with them instead of sitting 200px away in the
     bottom-left. (On the column itself, not on the CTA rail, because from
     501px that rail is a ROW and the cue would land beside the buttons.) */
  .m-hero-copy::after,
  .m-hero-wordmark > div::after {
    content: "";
    align-self: center;
    flex: none;
    width: 13px;
    height: 13px;
    margin-top: round(clamp(12px, 4.6vh - 8px, 30px), 1px);
    border-right: 2.5px solid rgba(21, 41, 29, 0.55);
    border-bottom: 2.5px solid rgba(21, 41, 29, 0.55);
    border-radius: 1px;
    transform: rotate(45deg);
  }

  /* ---- 480px-tall phones ---------------------------------------------
     "both CTAs above the fold" is the whole contract of this band, and at
     320x480 it was missing by 12px: the copy block outgrows its min-height
     (446.5px of content in 376px of space) and the bottom edge of "See how it
     works" landed just under the fold. Nothing here shrinks type — the two
     things that go are the optical lift, which is meaningless once the block
     is overflowing rather than centred in slack, and 6px of the run-up to the
     buttons. That is 20px, and the rail clears the fold again. Gated to
     <=540px tall so 320x568 — where the composition is already right, with
     48px to spare — never sees it. */
  @media (max-height: 540px) {
    /* the optical lift is meaningless once the block is overflowing rather
       than centred in slack, and it is 14px */
    .m-hero-copy,
    .m-hero-wordmark > div { padding-bottom: 0; }
    .m-hero-copy > div:first-child { margin-bottom: 10px !important; }
    .m-hero-copy > h1,
    .m-hero-wordmark h1 { font-size: 28px !important; }
    .m-hero-copy > p,
    .m-hero-wordmark p { font-size: 15px !important; margin-top: 10px !important; }
    .m-hero-ctas,
    .m-hero-wordmark div[style*="margin-top: 34px"] {
      margin-top: 12px !important;
      gap: 8px !important;
    }
    /* 48px, not 52: still well clear of the 44px minimum. The padding has to
       come down with it or it, not min-height, sets the height. */
    .m-hero-ctas > a,
    .m-hero-wordmark div[style*="margin-top: 34px"] > a {
      min-height: 48px !important;
      padding-top: 12px !important;
      padding-bottom: 12px !important;
    }
    /* and the cue goes: it sits UNDER the buttons, so on the one screen where
       they only just fit it is the thing pushing them off */
    .m-hero-copy::after,
    .m-hero-wordmark > div::after { display: none; }
  }
}

/* ============================================================
   Landscape phones
   ------------------------------------------------------------
   The stacked layout is a portrait answer: on an 844x390 handset it makes the
   hero ~2.7 screens tall and pushes both CTAs below the fold. Wide-but-short
   viewports go back to two columns, and the card is compacted so the whole
   hero stays close to one screen.
   ============================================================ */
@media (orientation: landscape) and (min-width: 620px) and (max-width: 900px) {
  .m-hero-grid {
    /* The card column used to take 336px + a 40px gutter out of an 844px
       screen, leaving the copy 426px — six pixels short of fitting the two
       CTAs on one row, which cost 51px of height on a viewport that had none
       to give. A narrower card column buys the row back. */
    grid-template-columns: minmax(0, 1fr) clamp(276px, 34vw, 320px) !important;
    max-width: 960px !important;
    gap: clamp(20px, 3vw, 34px) !important;
    /* start, not center: the card is ~180px taller than the copy column, so
       centring the copy against it left 92px of empty background under the nav
       on the left and pushed BOTH CTAs below a 390px fold. Aligning to the top
       is what actually brings the buttons on screen. */
    align-items: start !important;
    justify-items: stretch !important;
  }
  .m-hero-grid > .mz-hero-card {
    justify-self: end !important;
    max-width: 320px !important;
  }
  .m-hero-copy > p { max-width: 520px !important; }
}

/* Compact landscape handsets (667x375 and friends): two columns leave the copy
   a 288px rail on a 667px-wide screen — portrait proportions on a landscape
   device — and the lede runs to six lines, which put the CTAs 121px BELOW the
   fold. Below 768px the copy takes the whole rail and the card follows beneath
   it, exactly as the portrait landing screen does. */
@media (orientation: landscape) and (max-height: 430px) and (max-width: 767px) {
  .m-hero-grid {
    /* 520, not 640: the card was capped at 400 and centred inside a 619px copy
       rail, so it sat 110px in from both of the copy's edges — the same three
       -edges problem the 501–640 band had, on the one layout where the card
       cannot be seen whole anyway. The rail comes down to a width the card can
       fill. 520 is the widest that costs nothing: the lede holds at three
       lines down to 500px and folds to four at 480, which would put the second
       CTA exactly on the fold of a 375px-tall screen. */
    grid-template-columns: minmax(0, 1fr) !important;
    max-width: 520px !important;
    gap: 26px !important;
  }
  .m-hero-grid > .mz-hero-card {
    justify-self: stretch !important;
    max-width: none !important;
  }
  .m-hero-copy > p { max-width: none !important; }
}

/* Pro-Max-class handsets in landscape are wider than the collapse point, so
   they keep the desktop grid — including its inline align-items:center, which
   strands the same 92px under the nav. Constrained by max-height, so no
   desktop viewport can match. */
@media (orientation: landscape) and (max-height: 520px) and (min-width: 901px) {
  .m-hero-grid { align-items: start !important; }
}

@media (orientation: landscape) and (max-height: 520px) {
  .m-hero { padding-top: 24px !important; padding-bottom: 32px !important; }
  .m-hero-wordmark { padding-top: 26px !important; padding-bottom: 34px !important; }

  /* type one step down so the eyebrow → headline → lede → CTA run fits the
     short viewport instead of pushing the buttons off-screen */
  .m-hero-copy > div:first-child { margin-bottom: 13px !important; }
  .m-hero-copy > h1 { font-size: 34px !important; letter-spacing: -0.03em !important; }
  .m-hero-copy > p { font-size: 16px !important; line-height: 1.42 !important; margin-top: 12px !important; }
  .m-hero-ctas { margin-top: 18px !important; }
  .m-hero-wordmark h1 { font-size: clamp(26px, 4.2vw, 34px) !important; margin-top: 20px !important; }
  .m-hero-wordmark p { font-size: 16px !important; margin-top: 14px !important; }
  .m-hero-wordmark img[alt="MOSS"] { height: 44px !important; }
  .m-hero-wordmark > div > div > span { font-size: clamp(34px, 5vw, 46px) !important; }

  /* compact teaser card: same content, phone-sized rhythm. The min-height rule
     is repeated here (rather than inherited from the 900px band) because
     Pro-Max-class handsets in landscape are 901–950px wide and would otherwise
     keep the desktop card's fixed 520px body — 138px of it empty. max-height
     keeps this off every desktop viewport.

     431px is the floor for the narrow card the two-column landscape band
     hands out (276–306px wide, at 800/844/900); the two layouts that give the
     card real width take 24px off it, below. */
  .mz-hero-card { --mz-card-min: 431px; }
  .mz-hero-card .co-body-inner {
    padding: 20px 16px !important;
    height: auto !important;
    min-height: max(var(--mz-card-h, 0px), var(--mz-card-min, 452px)) !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: center !important;
  }
  .mz-hero-card .co-body-inner > * { flex: none; }
  .mz-hero-card .co-h1 { font-size: 20px !important; }
  .mz-hero-card .co-sub { font-size: 13px !important; }
  .mz-hero-card .co-amount { margin-bottom: 14px !important; }
  .mz-hero-card .co-list { gap: 8px !important; }
  .mz-hero-card .co-signbtn { min-height: 50px !important; padding: 0 13px !important; gap: 10px !important; }
  .mz-hero-card .co-signbtn-sub { display: none !important; }
  .mz-hero-card .co-chev { display: none !important; }
  /* payment is the tallest step once sign-in is compacted — trim it to match */
  .mz-hero-card .co-applepay,
  .mz-hero-card .co-gpay { height: 48px !important; }
  .mz-hero-card .co-wallets { gap: 9px !important; margin-bottom: 12px !important; }
  .mz-hero-card .co-method { padding: 12px 13px !important; }
  .mz-hero-card .co-check { width: 64px !important; height: 64px !important; margin-bottom: 16px !important; }
  .mz-hero-card .co-check-lg { width: 32px !important; height: 32px !important; }
  .mz-hero-card .co-receipt { margin-top: 18px !important; padding: 16px 15px !important; gap: 11px !important; }
}

/* The same card, given room to lay itself out, is 24px shorter: a 520px card
   on a 667x375 handset and a ~355px one on a 926x428 Pro Max both stop
   wrapping the sign-in rows. Stated after the block above so it wins. */
@media (orientation: landscape) and (max-height: 430px) and (max-width: 767px) {
  .mz-hero-card { --mz-card-min: 407px; }
}
@media (orientation: landscape) and (max-height: 520px) and (min-width: 901px) {
  .mz-hero-card { --mz-card-min: 407px; }
}

/* ============================================================
   Reduced motion (stacked layouts only — the desktop card keeps its
   existing entrance, so ≥1100px renders exactly as before)
   ============================================================ */
@media (max-width: 900px) and (prefers-reduced-motion: reduce) {
  .mz-hero-card,
  .m-hero-copy,
  .m-hero-wordmark > div {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}

/* The card is frozen on step 1 for reduced-motion users (see the guard in
   componentDidMount) at EVERY width, including desktop: an autoplaying loop
   that a reader has explicitly asked not to see is a motion problem, not a
   mobile problem, and WCAG 2.2.2 does not have a breakpoint. So the progress
   bar must not animate its width either. */
@media (prefers-reduced-motion: reduce) {
  .mz-hero-card [style*="width: 34%"] { transition: none !important; }

  /* And it must not be THERE either. A progress bar is a promise that
     something is in progress; frozen at 34% of a checkout that will never
     reach 100% it is the one part of the card that reads as broken rather
     than as an illustration. The "Live demo" badge — which this same
     preference switches on at every width, desktop included — says what the
     card is instead, and links to the checkout that really does run. */
  .mz-hero-card > div:has(> [style*="width: 34%"]) { visibility: hidden; }
}
