/* =========================================================================
   Veteran Strong — MOBILE MARKETING LAYER  (≤768px)
   Loaded AFTER marketing.css / marketing-light.css.

   This file OWNS the ≤768px layout. It is not a set of responsive patches:
   each band is composed as a mobile artifact in its own right, and the
   desktop constructs that don't survive the translation (floating pill nav,
   absolute-centred brand, overlay heroes, auto-running marquees, 3-col
   grids, 100px gutters) are reset rather than squeezed.

   AUDIENCE — US Veterans, 65+. Every decision below answers to that:
   · Body copy floor 18px / 1.55. Nothing below 14px, and 14px only for
     all-caps labels. Ink is darkened to #43453f (9.5:1 on white) so body
     text clears WCAG AAA, not just AA.
   · Every interactive target ≥ 48px, with ≥ 8px between neighbours.
   · Icons never travel alone — the Menu toggle says "Menu", carousel
     arrows carry aria-labels, the FAQ chevrons sit beside real questions.
   · No auto-moving content the reader has to chase: the "coming soon"
     marquee becomes a manual carousel with explicit Previous / Next.
   · The app bar never hides on scroll (desktop hide-on-scroll is undone) —
     losing the nav is disorienting when you scroll slowly.

   COMPOSITION
   · One 20px gutter. 4px spacing grid. Three band sizes (32 / 56 / 72)
     so rhythm carries hierarchy instead of one flat beat.
   · 6-tier type ladder: 40 · 28 · 20 · 18 · 16 · 14.
   · Radii: 12 input · 16 card · 20 card-lg · 28 sheet.
   · Motion: custom ease-out, ≤ 280ms, scale(0.97) on press, and every
     animation neutralised under prefers-reduced-motion.
   ========================================================================= */

:root {
  /* Spacing — 4px grid */
  --vsm-2: 8px;
  --vsm-3: 12px;
  --vsm-4: 16px;
  --vsm-5: 20px;
  --vsm-6: 24px;
  --vsm-8: 32px;
  --vsm-10: 40px;
  --vsm-12: 48px;
  --vsm-14: 56px;
  --vsm-16: 64px;
  --vsm-18: 72px;

  /* Structure */
  --vsm-gutter: 20px;
  --vsm-bar: 56px;          /* app-bar content height */
  --vsm-tap: 48px;          /* minimum interactive box */
  --vsm-cta: 56px;          /* primary action height */

  /* Band rhythm */
  --vsm-band-sm: 32px;
  --vsm-band: 56px;
  --vsm-band-lg: 72px;

  /* Type ladder */
  --vsm-display: 40px;
  --vsm-title: 28px;
  --vsm-card: 20px;
  --vsm-body: 18px;
  --vsm-small: 16px;
  --vsm-label: 14px;

  /* Radii */
  --vsm-r-input: 12px;
  --vsm-r-card: 16px;
  --vsm-r-card-lg: 20px;
  --vsm-r-sheet: 28px;

  /* Ink — darkened from --vs-ink-muted (#5c5e58, 6.6:1) so 18px body
     copy clears AAA on both white and cream. */
  --vsm-ink-body: #43453f;
  --vsm-hairline: rgba(14, 15, 12, 0.12);
  --vsm-hairline-soft: rgba(14, 15, 12, 0.08);

  /* Motion */
  --vsm-ease: cubic-bezier(0.23, 1, 0.32, 1);
  --vsm-ease-soft: cubic-bezier(0.16, 1, 0.3, 1);
}

/* Mobile-only chrome. Declared outside the query so these elements are inert
   on desktop no matter what markup they sit in.
   NOTE: nothing here may carry marketing copy. Every string on mobile is the
   desktop string — the hero lead, the FREE label and the partner strip all
   read exactly as they do at 1440px. Layout and type do the adapting. */
.mkt-nav__menu-btn,
.mkt-carousel-nav,
.mkt-mobile-cta { display: none; }

/* =========================================================================
   1 · FOUNDATIONS
   ========================================================================= */
@media (max-width: 768px) {
  /* `clip`, not `hidden`: overflow-x:hidden on <body> forces overflow-y
     to auto and turns the body into the scroll container. */
  .vs-mkt-page { overflow-x: clip; }
  .vs-mkt-page img,
  .vs-mkt-page svg { max-width: 100%; }

  /* Clear the fixed app bar and the sticky action bar. */
  .vs-mkt-page {
    padding-top: calc(var(--vsm-bar) + env(safe-area-inset-top, 0px));
  }
  /* ...unless there is no app bar. /home-newday carries its lockup inside
     the hero, so the reserve is a band of dead white above the photograph. */
  .vs-mkt-page.has-no-nav {
    padding-top: env(safe-area-inset-top, 0px);
  }
  body.has-mobile-cta {
    padding-bottom: calc(var(--vsm-cta) + var(--vsm-8) + env(safe-area-inset-bottom, 0px));
  }

  /* Kill the 300ms tap delay; keep a visible but quiet press highlight. */
  .vs-mkt-page a,
  .vs-mkt-page button {
    touch-action: manipulation;
    -webkit-tap-highlight-color: rgba(14, 15, 12, 0.06);
  }

  /* Focus is a legibility feature at this age, not a debug artifact. */
  .vs-mkt-page a:focus-visible,
  .vs-mkt-page button:focus-visible,
  .vs-mkt-page input:focus-visible {
    outline: 3px solid var(--vs-olive, #5a6b3f);
    outline-offset: 2px;
    border-radius: 4px;
  }

  /* Buttons acknowledge the press. */
  .vs-mkt-page .mkt-btn { transition: transform 140ms var(--vsm-ease), background-color 200ms ease; }
  .vs-mkt-page .mkt-btn:active { transform: scale(0.97); }

  /* Section titles are fully legible from the moment they exist.
     The scroll-tied word reveal holds each word at 0.18 opacity until the
     title has travelled far enough up the viewport — that is 1.49:1, and on
     a phone the scroll increments are large enough that a slow reader meets
     a half-faded headline. It is a pointer-era flourish that costs
     legibility here, so it does not run below 769px. */
  .vs-mkt-page .mkt-reveal-word { opacity: 1; transition: none; }

  /* Full-width action treatment, applied once instead of per section. */
  .vs-mkt-page .mkt-hero__cta-row .mkt-btn,
  .vs-mkt-page .mkt-benefits__cta .mkt-btn,
  .vs-mkt-page .mkt-how__cta .mkt-btn,
  .vs-mkt-page .mkt-vs-fox__copy .mkt-btn,
  .vs-mkt-page .mkt-concierge-feature__copy .mkt-btn,
  .vs-mkt-page .mkt-have-q__copy .mkt-btn,
  .vs-mkt-page .mkt-mobile-cta .mkt-btn,
  .vs-mkt-page .mkt-menu__signup {
    display: flex;
    width: 100%;
    min-height: var(--vsm-cta);
    padding: 14px var(--vsm-5);
    justify-content: center;
    align-items: center;
    gap: var(--vsm-3);
    border-radius: var(--vsm-r-input);
    font-size: var(--vsm-body);
    letter-spacing: 0.06em;
  }
}

/* =========================================================================
   2 · APP BAR  —  full-width, fixed, solid.  [brand · · · Menu]
   Undoes the desktop floating capsule, the absolute-centred brand, and the
   hide-on-scroll-down behaviour.
   ========================================================================= */
@media (max-width: 768px) {
  .vs-mkt-page .mkt-nav-wrap {
    position: fixed;
    inset: 0 0 auto 0;
    width: 100%;
    pointer-events: auto;
    background: var(--vs-bg, #ede8da);
    border-bottom: 1px solid transparent;
    box-shadow: none;
    padding-top: env(safe-area-inset-top, 0px);
    transition:
      border-color 200ms ease,
      box-shadow 200ms ease;
  }

  /* Elevation appears only once the page has moved — a flat bar at rest,
     a defined bar over content. Set by marketing-menu.js. */
  body.is-scrolled .mkt-nav-wrap {
    border-bottom-color: var(--vsm-hairline);
    box-shadow: 0 2px 12px rgba(14, 15, 12, 0.06);
  }

  /* The bar stays put. Desktop hides it on scroll-down; at 65+ a nav that
     disappears while you read is a navigation failure, not a flourish. */
  .vs-mkt-page .mkt-nav-wrap[data-nav-hidden] {
    transform: none;
    opacity: 1;
    pointer-events: auto;
  }

  /* Flatten the capsule into the bar itself.
     Selector is `.mkt-nav-wrap .mkt-nav`, not `.mkt-nav`, on purpose:
     `.mkt-nav-wrap[data-nav-theme="light"] .mkt-nav` in marketing.css is
     (0,3,0) and would otherwise win, leaving the desktop floating capsule's
     translucent white fill, 22px backdrop blur, inset white hairline and two
     drop shadows layered on top of the solid cream bar. That milky, double-
     edged wash is what made the bar look broken. Matching (0,3,0) + later in
     the cascade wins cleanly, and also covers the default dark theme on pages
     with no data-nav-theme attribute. */
  .vs-mkt-page .mkt-nav-wrap .mkt-nav {
    position: static;
    transform: none;
    top: auto;
    left: auto;
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0 var(--vsm-gutter);
    min-height: var(--vsm-bar);
    display: flex;
    align-items: center;
    /* NOT space-between: with the link row hidden there are three children
       (brand, auth group, menu), and space-between strands Login in the
       middle of the bar. Brand takes the free space instead, so the auth
       group and the menu button stay paired at the right edge. */
    justify-content: flex-start;
    gap: var(--vsm-2);
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  /* The desktop link row moves into the sheet. The auth group stays in the
     bar, showing Login only — Sign Up is already the sticky bottom action and
     the sheet's footer button, so a third instance in a 375px bar would just
     be noise competing with itself. */
  .vs-mkt-page .mkt-nav__left { display: none; }
  .vs-mkt-page .mkt-nav__right {
    display: flex;
    align-items: center;
    gap: var(--vsm-2);
  }
  .vs-mkt-page .mkt-nav__right .mkt-btn--primary { display: none; }

  /* Login: the visible word on the bar. Paired with the icon-only hamburger
     it keeps the bar from being a row of unlabelled glyphs. */
  .vs-mkt-page .mkt-nav__right .mkt-btn--ghost {
    height: var(--vsm-tap);
    padding: 0 var(--vsm-4);
    gap: 6px;
    border-radius: var(--vsm-r-input);
    font-size: var(--vsm-small);
    letter-spacing: 0.04em;
    color: var(--vs-ink, #0e0f0c);
    border: 1.5px solid rgba(14, 15, 12, 0.22);
    background: transparent;
    white-space: nowrap;
  }
  /* The person glyph goes. "Login" is already an explicit label — the 65+ rule
     is that an icon never travels alone, not that a word needs a picture — and
     the 22px it frees is what lets the brand wordmark sit on the bar at all. */
  .vs-mkt-page .mkt-nav__right .mkt-btn--ghost .mkt-btn__icon { display: none; }

  /* Brand anchors left, always ink on the cream bar regardless of the
     page's data-nav-theme. */
  .vs-mkt-page .mkt-nav__brand {
    position: static;
    transform: none;
    top: auto;
    left: auto;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-height: var(--vsm-tap);
    /* Below 390px the wordmark hides and the link collapses to the 36px mark,
       which is under the 48px floor on the horizontal axis. */
    min-width: var(--vsm-tap);
    /* Absorbs the free space, pinning the auth group + menu to the right. */
    margin-right: auto;
    color: var(--vs-ink, #0e0f0c) !important;
  }

  .vs-mkt-page .mkt-nav__brand-mark { width: 36px; height: 27px; }

  /* Hero lockup (/home-newday, which has no app bar) — same sizing the bar
     would have given it. */
  .vs-mkt-page .mkt-hero__brand { gap: 12px; margin-bottom: var(--vsm-6); }
  /* +30%, then +20% (26 Aug), in step with the desktop rule. */
  .vs-mkt-page .mkt-hero__brand-mark { width: 68px; height: 52px; }
  /* --card, not --title: "VETERAN STRONG" is 14 tracked caps, and at 28px
     the lockup measures ~366px against a 375px viewport. */
  .vs-mkt-page .mkt-hero__brand-word {
    font-size: var(--vsm-card);
    letter-spacing: 0.13em;
  }
  .vs-mkt-page .mkt-nav__brand-word {
    font-size: var(--vsm-label);
    letter-spacing: 0.13em;
    white-space: nowrap;
  }

  /* Menu toggle — icon only. The accessible name is on aria-label, so the
     control is still explicitly named for assistive tech and voice control. */
  .vs-mkt-page .mkt-nav__menu-btn {
    appearance: none;
    display: inline-grid;
    place-items: center;
    width: var(--vsm-tap);
    height: var(--vsm-tap);
    padding: 0;
    background: rgba(14, 15, 12, 0.06);
    border: 0;
    border-radius: var(--vsm-r-input);
    color: var(--vs-ink, #0e0f0c);
    cursor: pointer;
    flex-shrink: 0;
    transition: transform 140ms var(--vsm-ease), background-color 180ms ease;
  }
  .vs-mkt-page .mkt-nav__menu-btn:active {
    transform: scale(0.95);
    background: rgba(14, 15, 12, 0.10);
  }
  /* The glyph is centred by place-items; the SVG must not also stretch. */
  .vs-mkt-page .mkt-nav__menu-btn svg { display: block; }

  /* The wordmark needs 134px plus breathing room. Free space on the bar is
     (viewport − 220px) once gutters, mark, Login and the menu button are
     placed, so it only genuinely fits from ~390px up. Below that the logomark
     carries the brand alone rather than being crushed against Login. */
  @media (max-width: 389px) {
    .vs-mkt-page .mkt-nav__brand-word { display: none; }
  }
}

/* =========================================================================
   3 · MENU SHEET  —  full-screen, large rows, one primary action
   ========================================================================= */
@media (max-width: 768px) {
  /* ────────────────────────────────────────────────────────────────────────
     `hidden` MUST win over the display below.
     An author `display: flex` beats the UA stylesheet's `[hidden]{display:none}`
     regardless of order, so without this rule the sheet stays in the layout
     permanently: 375×812, z-index 200, pointer-events auto, opacity 0.
     Invisible — and it swallowed every tap and every scroll gesture on the
     page. Tapping "Menu" landed on the sheet's own close button; tapping a
     FAQ row or a carousel arrow landed on the sheet's Sign Up link, which is
     why the page navigated to signup; and `overflow-y:auto` +
     `overscroll-behavior:contain` on a viewport-height element with nothing
     to scroll is what made the page feel frozen.
     ──────────────────────────────────────────────────────────────────────── */
  .mkt-menu[hidden] { display: none; }

  .mkt-menu {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    flex-direction: column;
    background: var(--vs-bg, #ede8da);
    padding:
      calc(env(safe-area-inset-top, 0px) + var(--vsm-2))
      var(--vsm-gutter)
      calc(env(safe-area-inset-bottom, 0px) + var(--vsm-6));
    opacity: 0;
    transition: opacity 200ms var(--vsm-ease);
    overscroll-behavior: contain;
    overflow-y: auto;
  }
  .mkt-menu.is-open { opacity: 1; }

  .mkt-menu__bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: var(--vsm-bar);
    margin-bottom: var(--vsm-6);
  }
  .mkt-menu__brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    color: var(--vs-ink);
    font-family: var(--vs-font-display, inherit);
    font-weight: 700;
    font-size: var(--vsm-label);
    letter-spacing: 0.13em;
    text-transform: uppercase;
  }
  .mkt-menu__close {
    appearance: none;
    width: var(--vsm-tap);
    height: var(--vsm-tap);
    border: 0;
    border-radius: var(--vsm-r-input);
    background: rgba(14, 15, 12, 0.06);
    color: var(--vs-ink);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: transform 140ms var(--vsm-ease), background-color 180ms ease;
  }
  .mkt-menu__close:active {
    transform: scale(0.95);
    background: rgba(14, 15, 12, 0.10);
  }

  .mkt-menu__nav { display: flex; flex-direction: column; }
  .mkt-menu__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--vsm-4);
    min-height: 64px;
    padding: 0 4px;
    border-bottom: 1px solid var(--vsm-hairline-soft);
    text-decoration: none;
    color: var(--vs-ink);
    font-family: var(--vs-font-body, inherit);
    font-size: 22px;
    font-weight: 500;
    letter-spacing: -0.3px;
    transition: color 180ms ease;
  }
  .mkt-menu__row--active { color: var(--vs-olive-deep, #3f4a2a); }
  .mkt-menu__row-chev { color: rgba(14, 15, 12, 0.32); display: inline-flex; }

  .mkt-menu__foot {
    margin-top: auto;
    padding-top: var(--vsm-8);
    display: flex;
    flex-direction: column;
    gap: var(--vsm-4);
  }

  /* Rows rise 8px as the sheet fades in. */
  .mkt-menu__row,
  .mkt-menu__foot {
    opacity: 0;
    transform: translateY(8px);
    transition:
      opacity 240ms var(--vsm-ease),
      transform 240ms var(--vsm-ease);
    transition-delay: calc(var(--menu-i, 0) * 40ms);
  }
  .mkt-menu.is-open .mkt-menu__row,
  .mkt-menu.is-open .mkt-menu__foot {
    opacity: 1;
    transform: translateY(0);
  }
  @media (prefers-reduced-motion: reduce) {
    .mkt-menu { transition: opacity 150ms ease; }
    .mkt-menu__row,
    .mkt-menu__foot {
      transition: opacity 150ms ease;
      transform: none;
      transition-delay: 0ms;
    }
  }
}

/* =========================================================================
   4 · STICKY ACTION BAR  —  appears only once the hero CTA is gone, so the
   page never shows two "Become a member" buttons at the same time.
   ========================================================================= */
@media (max-width: 768px) {
  .mkt-mobile-cta {
    display: block;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 90;
    padding: var(--vsm-3) var(--vsm-gutter)
             calc(var(--vsm-3) + env(safe-area-inset-bottom, 0px));
    background: var(--vs-bg, #ede8da);
    border-top: 1px solid var(--vsm-hairline);
    box-shadow: 0 -2px 16px rgba(14, 15, 12, 0.06);
    transform: translateY(calc(100% + 8px));
    opacity: 0;
    transition:
      transform 260ms var(--vsm-ease),
      opacity 200ms ease;
  }
  body.show-mobile-cta .mkt-mobile-cta {
    transform: translateY(0);
    opacity: 1;
  }

  @media (prefers-reduced-motion: reduce) {
    .mkt-mobile-cta { transition: opacity 150ms ease; transform: none; }
    body:not(.show-mobile-cta) .mkt-mobile-cta { opacity: 0; pointer-events: none; }
  }
}

/* =========================================================================
   5 · BAND RHYTHM  —  three beats, not one
   32 quiet · 56 standard · 72 major. Replaces the inherited desktop
   56/72/96/104/120 paddings and the flat 40px the previous layer used.
   ========================================================================= */
@media (max-width: 768px) {
  .vs-mkt-page .mkt-benefits,
  .vs-mkt-page .mkt-benefits--section,
  .vs-mkt-page .mkt-soon,
  .vs-mkt-page .mkt-how,
  .vs-mkt-page .mkt-vs-fox {
    padding: var(--vsm-band) var(--vsm-gutter);
  }
  .vs-mkt-page .mkt-mission,
  .vs-mkt-page .mkt-have-q {
    padding: var(--vsm-band-lg) var(--vsm-gutter);
  }
  /* The partner strip is a quiet proof band. It stays on the page background
     exactly as it does on desktop — an earlier version tinted it cream to
     extend the hero's warm zone, which diverged from desktop for no real gain
     and turned the page's vertical colour story into cream/white/cream/white. */
  .vs-mkt-page .mkt-logo-strip {
    padding: var(--vsm-10) 0;
  }

  /* Section headers: eyebrow → title → lead tight; header → body 24px. */
  .vs-mkt-page .mkt-benefits__head,
  .vs-mkt-page .mkt-how__head {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    gap: var(--vsm-3);
    max-width: none;
    margin: 0 0 var(--vsm-6);
    padding: 0;
    border-bottom: 0;
  }
  .vs-mkt-page .mkt-eyebrow { margin: 0; }
  .vs-mkt-page .mkt-benefits__lead { margin: 0; }
}

/* =========================================================================
   6 · HERO  —  image-led editorial sheet
   The desktop hero overlays copy on a 2.4:1 landscape product shot. That
   composition cannot survive a 375px portrait viewport: the previous layer
   solved it by veiling the photo to 97% opacity, which erased the image into
   a grey smear and left the fold looking broken.
   The mobile composition instead: the product shot on top, then a cream
   sheet rising 24px over it carrying headline → lead → action. Text sits on
   flat cream, never on photography.

   Copy is the desktop copy, verbatim — headline, full lead, and the closing
   "AT NO COST TO YOU." inside it. The photo height is what gives way (260px)
   so the full lead and the CTA still clear the fold at 812px.

   Image is the desktop image. `hero-vs-card-mobile.jpg` is the same shot,
   art-directed to the box and card and re-encoded at 106KB — `cover` on the
   1584×672 original would crop it arbitrarily anyway, and the 1MB PNG is not
   something to send this audience over a cellular connection.
   ========================================================================= */
@media (max-width: 768px) {
  .vs-mkt-page .mkt-hero { padding: 0; }

  .vs-mkt-page .mkt-hero--short .mkt-hero__inner,
  .vs-mkt-page .mkt-hero__inner {
    min-height: 0;
    padding: 0;
    border-radius: 0;
    /* Yuval (23 Aug): "the image needs to cover down to the content
       background, with no white gap." The photo is a flow block and the cream
       sheet below it rises -24px over it, so the two should meet — but the
       V1/V2 presentation switch is a flow item between them (deliberately, so
       it can't cover V2's slogan — 2 Aug), and `transparent` let the white
       body show through that 44px band. Painting the hero cream closes the
       seam without moving the switch back on top of the media. */
    background: var(--vs-bg, #ede8da);
    display: flex;
    flex-direction: column;
    overflow: visible;
  }

  /* Photograph: static block in flow, not an absolute background. */
  .vs-mkt-page .mkt-hero--light .mkt-hero__bg-light {
    position: relative;
    inset: auto;
    z-index: 0;
    order: 1;
    width: 100%;
    height: min(34vh, 260px);
    background-color: #eef0ef;
    background-image: url('../img/home/hero-vs-card-mobile.jpg');
    background-size: cover;
    background-position: center;
  }

  /* The desktop scrim has no job here — the copy is off the photo. */
  .vs-mkt-page .mkt-hero--light .mkt-hero__scrim { display: none; }

  /* Cream sheet. Rises over the photo; rounded top corners read as a
     deliberate surface rather than a section boundary. */
  .vs-mkt-page .mkt-hero__copy {
    order: 2;
    position: relative;
    z-index: 2;
    max-width: none;
    margin-top: -24px;
    padding: var(--vsm-8) var(--vsm-gutter) var(--vsm-10);
    background: var(--vs-bg, #ede8da);
    border-radius: var(--vsm-r-sheet) var(--vsm-r-sheet) 0 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    /* Desktop sets gap:32px here. Inherited, it stacks on top of every
       margin below and inflates each step in the sheet — the rhythm is
       owned by the individual margins, not by a blanket gap. */
    gap: 0;
  }

  .vs-mkt-page .mkt-hero__title { margin: 0; }
  .vs-mkt-page .mkt-hero__tm { font-size: 0.45em; vertical-align: super; }

  .vs-mkt-page .mkt-hero__lead { margin: var(--vsm-4) 0 0; }

  .vs-mkt-page .mkt-hero__cta-row {
    margin-top: var(--vsm-6);
    display: flex;
  }
}

/* =========================================================================
   7 · PARTNER STRIP  —  readable density, labelled
   Was 56px item padding: two logos per screen with State Farm cropped
   mid-word, which reads as a rendering bug rather than a proof band.
   ========================================================================= */
@media (max-width: 768px) {
  .vs-mkt-page .mkt-logo-strip__viewport {
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 32px, #000 calc(100% - 32px), transparent 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 32px, #000 calc(100% - 32px), transparent 100%);
  }
  .vs-mkt-page .mkt-logo-strip__item { padding: 0 20px; }
  .vs-mkt-page .mkt-logo-strip__item img { height: 26px; max-width: 128px; }
  .vs-mkt-page .mkt-logo-strip__item img[src*="card-fox"]          { height: 30px; }
  .vs-mkt-page .mkt-logo-strip__item img[src*="card-afba"]         { height: 30px; }
  .vs-mkt-page .mkt-logo-strip__item img[src*="coursera-wordmark"] { height: 18px; }
  .vs-mkt-page .mkt-logo-strip__item img[src*="auto-nation"]       { height: 21px; }
  .vs-mkt-page .mkt-logo-strip__item img[src*="housing-adt"]       { height: 23px; }
  /* Slower than desktop: the strip is being read, not skimmed past. */
  .vs-mkt-page .mkt-logo-strip__track { animation-duration: 64s; }

  /* With the marquee stopped, an animation-driven strip becomes a dead band
     showing three logos and hiding seven. Hand the reader the scroll. */
  @media (prefers-reduced-motion: reduce) {
    .vs-mkt-page .mkt-logo-strip__viewport {
      overflow-x: auto;
      scrollbar-width: none;
      -webkit-mask-image: none;
              mask-image: none;
    }
    .vs-mkt-page .mkt-logo-strip__viewport::-webkit-scrollbar { display: none; }
    .vs-mkt-page .mkt-logo-strip__track { width: max-content; }
    .vs-mkt-page .mkt-logo-strip__track > [aria-hidden="true"] { display: none; }
  }
}

/* =========================================================================
   8 · BENEFITS  —  two full-width photo cards
   FREE moves onto the visual as a badge (that's where a value marker is
   looked for) and the separate value row is retired, which takes a whole
   block of height out of each card without losing the message.
   ========================================================================= */
@media (max-width: 768px) {
  .vs-mkt-page .mkt-benefits__inner { gap: var(--vsm-4); }
  .vs-mkt-page .mkt-benefits__inner--two { grid-template-columns: 1fr; }

  .vs-mkt-page .mkt-benefit-card {
    border-radius: var(--vsm-r-card-lg);
    border-width: 1px;
    background: #faf9f5;
  }

  .vs-mkt-page .mkt-benefit-card__visual { height: 200px; }
  .vs-mkt-page .mkt-benefit-card__visual::after { height: 72%; }

  .vs-mkt-page .mkt-benefit-card__logo-img {
    bottom: var(--vsm-5);
    left: var(--vsm-5);
    height: 28px;
    max-width: 52%;
  }
  .vs-mkt-page .mkt-benefit-card__logo-img[alt="Equifax"],
  .vs-mkt-page .mkt-benefit-card__logo-img[alt="State Farm"] { height: 26px; }

  /* Graphic variant only (Yuval, 23 Aug: "the Equifax logo on the card needs
     to be much bigger"). The heights above were written for the photo card,
     where the mark tucks into the image's bottom-left corner and stays out of
     the way. On the graphic panel it is the centred brand statement, sitting
     under a 64px icon disc in a 335x200 field — 26px read as an afterthought.
     Scaled off the desktop table's per-brand ratios so a row still balances. */
  .vs-mkt-page .mkt-benefit-card__visual--graphic .mkt-benefit-card__logo-img {
    height: 40px;
    max-width: 76%;
  }
  .vs-mkt-page .mkt-benefit-card__visual--graphic .mkt-benefit-card__logo-img[alt="Equifax"] { height: 44px; }
  .vs-mkt-page .mkt-benefit-card__visual--graphic .mkt-benefit-card__logo-img[alt="State Farm"] { height: 40px; }
  .vs-mkt-page .mkt-benefit-card__visual--graphic .mkt-benefit-card__logo-img[alt="TaxHawk"] { height: 56px; }
  .vs-mkt-page .mkt-benefit-card__visual--graphic .mkt-benefit-card__logo-img[alt="AFBA"] { height: 60px; }
  .vs-mkt-page .mkt-benefit-card__visual--graphic .mkt-benefit-card__logo-img[alt="Fox Nation"] { height: 72px; }

  /* Light variant: the same trim as desktop. 200px around a 66px mark left
     the panel reading as an empty box on a phone too. */
  .vs-mkt-page .mkt-benefit-card__visual--light { height: 152px; }

  /* Light variant (home-newday): the +65% has to survive down here too. The
     rule above pins every graphic-card mark to 40px, which cancelled it
     outright below 768px. Scaled off the mobile baseline, not the desktop
     one — the panel is 335x200 here, not 380x318. */
  .vs-mkt-page .mkt-benefit-card__visual--light .mkt-benefit-card__logo-img { height: 66px; }
  /* +13% (Li, 30 Aug: "the VS Roadside logo could be bigger", then a step
     back down on 30 Aug: "a bit smaller"). It is a 4:3
     stack — chevron, two lines of type, then a reversed band — not a flat
     wordmark, so it needs about twice the height of the two marks either
     side of it to carry the same weight. That is the relationship the
     desktop row already runs, 158 against 79. */
  .vs-mkt-page .mkt-benefit-card__visual--light .mkt-benefit-card__logo-img[alt="Veteran Strong Roadside Assistance"] { height: 140px; max-width: 84%; }
  /* NewDay USA, in ADT's place from 30 Aug. Same cap-height reasoning as the
     desktop rule: Experian at 66px carries a ~30px cap here, and this mark's
     caps are 68% of its height, so 42 x 0.68 = 28.5px sits alongside it. */
  .vs-mkt-page .mkt-benefit-card__visual--light .mkt-benefit-card__logo-img[alt="NewDay USA"] { height: 42px; max-width: 92%; }

  /* ---------------------------------------------------------------------
     One box, not three bands (Li, 30 Aug: "these boxes don't need to have
     the logo area in white with the rest in tan. Can't it just be one box
     without compartmentalizing?").

     Desktop keeps the banded construction on purpose: three cards sit side
     by side there and the internal rules are what hold eyebrow, mark and
     copy on the same line across the row. Stacked on a phone there is no
     neighbouring card to line up with, so the bands were only dividing an
     object that already reads as one. The card's own cream now runs the
     whole surface; the page behind it is white, so radius and shadow still
     do the separating.
     --------------------------------------------------------------------- */
  .vs-mkt-page .mkt-benefit-card--light .mkt-benefit-card__eyebrow,
  .vs-mkt-page .mkt-benefit-card--light .mkt-benefit-card__visual--light {
    background: transparent;
    border-bottom: 0;
  }
  .vs-mkt-page .mkt-benefit-card--light .mkt-benefit-card__eyebrow {
    padding: 24px 20px 0;
  }
  /* The fixed panel height existed to keep the three marks on one baseline
     across the row. Stacked, it only trapped the mark inside a box that no
     longer has edges, so the panel is sized by what is in it. */
  .vs-mkt-page .mkt-benefit-card--light .mkt-benefit-card__visual--light {
    height: auto;
    padding: 24px 20px 8px;
  }

  /* The roll-over list is written white for the olive panel it slides over
     on /home. This page has no olive under it, and with no hover to trigger
     it `@media (hover: none)` drops it into the flow — white type and grey
     ticks on a white panel, which is the ghost row of check marks in Li's
     screenshot. The card body already carries the summary in full, so the
     list is hover-only detail with nowhere to go on a phone. */
  .vs-mkt-page .mkt-benefit-card--light .mkt-benefit-card__reveal { display: none; }

  /* Experian's mark is 150px wide and centred; the pill was pinned to the
     top-right of the same 335px panel, so the logo's own box painted over
     it — "the Experian logo is cutting off the Already Active box". Below
     the mark instead: nothing to collide with, and it reads as a caption on
     the thing it describes. `order` moves it past the lockup without
     touching the markup, which desktop still needs in source order for the
     absolute corner placement. */
  .vs-mkt-page .mkt-benefit-card--have .mkt-benefit-card__have-flag {
    position: static;
    order: 2;
  }

  /* White, not the card's cream (Slav, 30 Aug: "the tan is too similar to the
     BG"). The section behind these cards runs a warm wash — rgba(243,238,224)
     at 85% — and #faf9f5 sat about four points off it, which was enough
     separation when the card was banded and is not enough now that one flat
     surface has to hold the whole card. White is what the desktop card is
     built on anyway; the mobile sheet was the only place overriding it. */
  .vs-mkt-page .mkt-benefit-card--light { background: #ffffff; }

  /* No hover on a phone. The lift and the shadow bloom are already gated to
     `(hover: hover) and (pointer: fine)`, which covers real touch screens —
     but a narrow desktop window is still a fine pointer, and that is where
     the card was lifting under the cursor at phone width. Below 768px the
     card is a static object either way. */
  /* The shadow carries a bit more weight here than on desktop (Slav, 30 Aug).
     Desktop has three cards holding each other up in a row; stacked, each one
     has to lift off the section's warm wash on its own, and a white card on a
     warm ground has almost no colour difference to do that with. Still the
     same two-layer shape — a 3px contact shadow and a wide soft cast — just
     deeper on the cast. */
  .vs-mkt-page .mkt-benefit-card--light,
  .vs-mkt-page .mkt-benefit-card--light:hover {
    transform: none;
    transition: none;
    box-shadow:
      0 2px 4px rgba(14, 15, 12, 0.08),
      0 20px 48px -12px rgba(14, 15, 12, 0.38);
  }
  .vs-mkt-page .mkt-benefit-card--light:hover .mkt-benefit-card__lockup {
    transform: none;
    opacity: 1;
  }
  /* The shared eyebrow rule further down does not list this class, and its own
     comment warns what that means: it would sit at the 18px desktop size down
     here. Its own rule rather than joining that list, because it carries the
     +20% and the 700 weight the shared one does not. */
  .vs-mkt-page .mkt-benefit-card__eyebrow {
    padding: var(--vsm-5) var(--vsm-5) var(--vsm-3);
    font-size: calc(var(--vsm-label) * 1.2);
    font-weight: 700;
  }
  /* The card-copy bump follows down here, where the base rule is overridden
     for colour only and the size still comes from the desktop sheet. */
  .vs-mkt-page .mkt-benefit-card--light .mkt-benefit-card__body-text { font-size: var(--vs-mkt-small); }

  .vs-mkt-page .mkt-benefit-card__body {
    padding: var(--vsm-6) var(--vsm-5);
    gap: var(--vsm-3);
  }
  .vs-mkt-page .mkt-benefit-card__title {
    min-height: 0;
    color: var(--vs-ink);
  }
  .vs-mkt-page .mkt-benefit-card__body-text { color: var(--vsm-ink-body); }

  /* FREE keeps the desktop structure: the card's closing statement, a
     full-width olive band with the word centred in it.
     An earlier version demoted it to a small pill pinned to the top-right of
     the photo. Two things were wrong with that. It put a value marker on top
     of uncontrolled photography — bright sky on one card, a lit window on the
     other — so its contrast changed per card and it read as faint. And it
     turned the card's conclusion into decoration. The band does the work
     here, not the type size: 28px keeps FREE at the section-title tier
     instead of out-shouting it, which is the same relationship it has to
     headings on desktop. */
  .vs-mkt-page .mkt-benefit-card__valuebox {
    padding: var(--vsm-5) var(--vsm-5);
    justify-content: center;
  }
  .vs-mkt-page .mkt-benefit-card__tier {
    font-size: var(--vsm-title);
    letter-spacing: 0.06em;
    /* FREE is all-caps with no descenders, so an untrimmed line box centres
       ~1px high in the band. */
    text-box: trim-both cap alphabetic;
  }

  .vs-mkt-page .mkt-benefits__cta { margin-top: var(--vsm-6); display: flex; }
}

/* =========================================================================
   9 · COMING SOON  —  auto-marquee becomes a manual carousel
   An 80s auto-scroll is a moving target: you cannot finish reading a card
   before it leaves, and there is no way to go back. On mobile the track
   stops moving, the cloned duplicate set is dropped, and explicit
   Previous / Next controls plus a position counter are injected by
   mkt-carousel.js.
   ========================================================================= */
@media (max-width: 768px) {
  .vs-mkt-page .mkt-soon { padding-left: 0; padding-right: 0; }
  .vs-mkt-page .mkt-soon .mkt-benefits__head {
    margin: 0 var(--vsm-gutter) var(--vsm-6);
  }

  .vs-mkt-page .mkt-soon__viewport {
    overflow-x: auto;
    -webkit-mask-image: none;
            mask-image: none;
    scroll-snap-type: x mandatory;
    /* "start" means 20px in, not flush to the bezel — this is what keeps
       snap and the Previous/Next buttons landing in the same place. */
    scroll-padding-left: var(--vsm-gutter);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    overscroll-behavior-x: contain;
  }
  .vs-mkt-page .mkt-soon__viewport::-webkit-scrollbar { display: none; }

  .vs-mkt-page .mkt-soon__track {
    animation: none;
    width: max-content;
    gap: var(--vsm-3);
    padding: 0 var(--vsm-gutter);
  }
  /* No animation → the cloned half is dead weight and would double the
     carousel's item count. */
  .vs-mkt-page .mkt-soon__track > [aria-hidden="true"] { display: none; }

  .vs-mkt-page .mkt-soon-card {
    flex: 0 0 calc(100vw - 72px);
    scroll-snap-align: start;
    border-radius: var(--vsm-r-card-lg);
    background: #faf9f5;
  }
  .vs-mkt-page .mkt-soon-card__visual { height: 168px; }
  /* 0.16em of tracking is applied after the final N too, so a symmetric
     padding renders ~2.2px of dead space on the right and the pill looks
     off-balance. Take the trailing track back out of the right padding. */
  .vs-mkt-page .mkt-soon-card__chip { padding-right: calc(14px - 0.16em); }
  .vs-mkt-page .mkt-soon-card__body {
    padding: var(--vsm-5);
    gap: var(--vsm-2);
  }
  .vs-mkt-page .mkt-soon-card__text { opacity: 1; color: var(--vsm-ink-body); }
}

/* ---- Carousel controls (shared affordance) ------------------------------
   Arrows and a position readout, sized as real targets. Swipe still works;
   this is for everyone who does not know that it does. */
@media (max-width: 768px) {
  .mkt-carousel-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--vsm-3);
    margin: var(--vsm-5) var(--vsm-gutter) 0;
  }
  .mkt-carousel-nav__btn {
    appearance: none;
    width: var(--vsm-tap);
    height: var(--vsm-tap);
    flex-shrink: 0;
    display: inline-grid;
    place-items: center;
    border: 0;
    border-radius: var(--vsm-r-input);
    background: rgba(14, 15, 12, 0.06);
    color: var(--vs-ink);
    cursor: pointer;
    transition:
      transform 140ms var(--vsm-ease),
      background-color 180ms ease,
      opacity 180ms ease;
  }
  .mkt-carousel-nav__btn:active { transform: scale(0.95); background: rgba(14, 15, 12, 0.10); }
  .mkt-carousel-nav__btn[disabled] { opacity: 0.32; cursor: default; }
  .mkt-carousel-nav__btn[disabled]:active { transform: none; }

  .mkt-carousel-nav__count {
    min-width: 72px;
    text-align: center;
    font-family: var(--vs-font-body);
    font-size: var(--vsm-small);
    font-weight: 500;
    /* Tabular so the readout doesn't reflow as the index changes width. */
    font-variant-numeric: tabular-nums;
    text-box: trim-both cap alphabetic;
    color: var(--vsm-ink-body);
  }

  @media (prefers-reduced-motion: reduce) {
    .mkt-carousel-nav__btn { transition: none; }
  }
}

/* =========================================================================
   10 · HOW IT WORKS  —  3-col grid becomes a vertical timeline
   The previous layer put three ordered steps in a horizontal carousel:
   steps 2 and 3 were off-screen with no affordance saying so, which breaks
   a sequence — the one content type where order is the message. Stacked
   with a connecting rail, all three are visible and the order is literal.
   ========================================================================= */
@media (max-width: 768px) {
  .vs-mkt-page .mkt-how__inner { padding: 0; max-width: none; }

  .vs-mkt-page .mkt-how__steps {
    display: flex;
    flex-direction: column;
    gap: 0;
    grid-template-columns: none;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .vs-mkt-page .mkt-how__step {
    position: relative;
    display: grid;
    grid-template-columns: 44px 1fr;
    column-gap: var(--vsm-4);
    row-gap: 4px;
    align-items: start;
    background: transparent;
    border: 0;
    border-radius: 0;
    padding: 0 0 var(--vsm-8);
  }
  .vs-mkt-page .mkt-how__step:last-child { padding-bottom: 0; }

  /* The rail: a hairline from this step's numeral to the next one. */
  .vs-mkt-page .mkt-how__step::before {
    content: "";
    position: absolute;
    left: 21px;
    top: 44px;
    /* Meets the next numeral rather than stopping short of it — a rail with
       an 8px gap at each end reads as three disconnected items. */
    bottom: 0;
    width: 2px;
    background: var(--vsm-hairline);
  }
  .vs-mkt-page .mkt-how__step:last-child::before { display: none; }

  .vs-mkt-page .mkt-how__num {
    grid-column: 1;
    grid-row: 1;
    width: 44px;
    height: 44px;
    margin: 0;
    /* MUST be reset explicitly. marketing-light.css re-purposes this element
       on light pages as a large underlined numeral — `padding-bottom: 14px;
       border-bottom: 1px; min-width: 44px` — and box-sizing is border-box, so
       leaving them in place meant `place-items: center` was centring the digit
       inside a 29px content box at the top of a 44px circle. That is the 8px
       the numerals were sitting high by; it was never a font-metrics problem.
       Re-purposing a component another stylesheet already re-purposed means
       resetting every property it touched, not only the ones being set. */
    padding: 0;
    border: 0;
    min-width: 0;
    display: inline-grid;
    place-items: center;
    border-radius: 999px;
    background: var(--vs-olive, #5a6b3f);
    color: #fff;
    font-family: var(--vs-font-display);
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0;
    /* Equal advances so 1, 2 and 3 sit identically rather than each finding
       its own centre, and trim the line box to cap-height/baseline so
       centring lands on the ink instead of on the (descender-padded) line
       box. Digits have no descenders, which is what makes an untrimmed line
       box read high. Ignored by browsers without text-box; the padding reset
       above already brings the error under ~0.7px on its own. */
    font-variant-numeric: tabular-nums;
    text-box: trim-both cap alphabetic;
  }
  .vs-mkt-page .mkt-how__step-title {
    grid-column: 2;
    grid-row: 1;
    margin: 0;
    align-self: center;
  }
  .vs-mkt-page .mkt-how__step-text {
    grid-column: 2;
    grid-row: 2;
    margin: var(--vsm-2) 0 0;
    color: var(--vsm-ink-body);
  }

  .vs-mkt-page .mkt-how__cta { margin-top: var(--vsm-10); display: flex; }
}

/* =========================================================================
   11 · MISSION  —  overlay becomes portrait, then quote
   Desktop reads copy over the right-anchored photograph. Stacked, the
   order is inverted from the previous layer: you meet the Chairman first,
   then read what he says. A quote before its attribution has nobody
   speaking it.
   ========================================================================= */
@media (max-width: 768px) {
  .vs-mkt-page .mkt-mission__panel {
    min-height: 0;
    display: flex;
    flex-direction: column;
    border-radius: var(--vsm-r-card-lg);
    overflow: hidden;
  }
  .vs-mkt-page .mkt-mission__bg {
    position: relative;
    inset: auto;
    order: 1;
    height: 260px;
    flex: 0 0 auto;
    /* The source is 1888×721; at this height `cover` is height-driven, so
       there is no vertical overflow and only the x anchor matters. Both the
       Chairman and his signature sit in the right third — anchor right or
       the signature gets sliced mid-word. */
    background-position: right center;
  }
  .vs-mkt-page .mkt-mission__veil { display: none; }
  .vs-mkt-page .mkt-mission__copy {
    order: 2;
    position: relative;
    padding: var(--vsm-8) var(--vsm-6) var(--vsm-10);
    gap: var(--vsm-4);
    max-width: none;
  }
  .vs-mkt-page .mkt-mission__eyebrow {
    font-size: var(--vsm-label);
    letter-spacing: 0.16em;
    color: rgba(255, 255, 255, 0.78);
  }
  .vs-mkt-page .mkt-mission__body {
    margin: 0;
    max-width: none;
    color: rgba(255, 255, 255, 0.94);
  }
  .vs-mkt-page .mkt-mission__pullquote {
    margin: var(--vsm-2) 0 0;
    max-width: none;
  }
  .vs-mkt-page .mkt-mission__attr {
    margin: var(--vsm-4) 0 0;
    align-items: flex-start;
    gap: var(--vsm-3);
    line-height: 1.45;
    color: rgba(255, 255, 255, 0.76);
  }
  .vs-mkt-page .mkt-mission__attr-rule { margin-top: 10px; }
}

/* =========================================================================
   12 · BUILT FOR VETERANS  +  inline FAQ  +  CONCIERGE
   Every desktop split collapses to one column.
   ========================================================================= */
@media (max-width: 768px) {
  .vs-mkt-page .mkt-vs-fox__inner {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    gap: var(--vsm-8);
    padding: 0;
    max-width: none;
  }
  .vs-mkt-page .mkt-vs-fox__copy {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--vsm-4);
  }
  .vs-mkt-page .mkt-vs-fox__body { margin: 0; color: var(--vsm-ink-body); }
  .vs-mkt-page .mkt-vs-fox__copy .mkt-btn { margin-top: var(--vsm-2); }

  /* Inline FAQ — 64px rows, hairline separated. */
  .vs-mkt-page .mkt-faq { margin: 0; }
  .vs-mkt-page .mkt-faq__q {
    padding: var(--vsm-5) 0;
    min-height: 64px;
    gap: var(--vsm-4);
  }
  .vs-mkt-page .mkt-faq__caret { width: 36px; height: 36px; }
  /* The shared rule further down pins the question to --vsm-card, so the
     --large variant restates it here or the +50% disappears on a phone. */
  .vs-mkt-page .mkt-faq--large .mkt-faq__q {
    font-size: calc(var(--vsm-card) * var(--vs-faq-scale, 1.5));
  }
  /* Answer starts on the same left edge as its question — the desktop 8px
     inset reads as an accidental indent at this width. */
  .vs-mkt-page .mkt-faq__a { padding: 0 0 var(--vsm-6); }
  /* .mkt-faq__a[hidden] is also (0,2,0) and lives in an earlier stylesheet,
     so the rule above would win and leave 24px of padding inside every
     CLOSED row. Re-assert the collapsed state at (0,3,0). */
  .vs-mkt-page .mkt-faq__a[hidden] { padding-bottom: 0; }
  .vs-mkt-page .mkt-faq__a > p { color: var(--vsm-ink-body); }

  /* Concierge — media over copy. */
  .vs-mkt-page .mkt-concierge-feature__wrap { margin-top: var(--vsm-10); }
  .vs-mkt-page .mkt-concierge-feature {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    gap: var(--vsm-6);
  }
  .vs-mkt-page .mkt-concierge-feature__visual { width: 100%; }
  .vs-mkt-page .mkt-concierge-feature__media {
    min-height: 0;
    aspect-ratio: 4 / 3;
    border-radius: var(--vsm-r-card-lg);
  }
  .vs-mkt-page .mkt-concierge-feature__copy {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--vsm-4);
  }
  /* Desktop puts 16/20px margins on the title; stacked under a flex gap
     they compound into a 36px hole between the title and its own body copy. */
  .vs-mkt-page .mkt-concierge-feature__title { margin: 0; }
  .vs-mkt-page .mkt-concierge-feature__body { margin: 0; color: var(--vsm-ink-body); }
}

/* =========================================================================
   13 · HAVE QUESTIONS  —  copy over accordion
   ========================================================================= */
@media (max-width: 768px) {
  .vs-mkt-page .mkt-have-q__inner,
  .vs-mkt-page .mkt-have-q__inner--framed {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    gap: var(--vsm-8);
    padding: 0;
    max-width: none;
  }
  .vs-mkt-page .mkt-have-q__copy {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--vsm-4);
    margin: 0;
  }
  .vs-mkt-page .mkt-have-q__head { gap: var(--vsm-3); }
  .vs-mkt-page .mkt-have-q__eyebrow {
    margin: 0;
    font-size: var(--vsm-label);
    letter-spacing: 0.16em;
  }
  .vs-mkt-page .mkt-have-q__title { white-space: normal; margin: 0; }
  .vs-mkt-page .mkt-have-q__body { margin: 0; max-width: none; color: var(--vsm-ink-body); }
  .vs-mkt-page .mkt-have-q__copy .mkt-btn { margin-top: var(--vsm-2); }

  .vs-mkt-page .mkt-have-q__list { gap: var(--vsm-3); max-width: none; }
  .vs-mkt-page .mkt-have-q__list > li { border-radius: var(--vsm-r-card); }
  .vs-mkt-page .mkt-have-q__item {
    padding: var(--vsm-5);
    min-height: 64px;
    gap: var(--vsm-4);
    align-items: center;
  }
  .vs-mkt-page .mkt-have-q__icon { width: 32px; height: 32px; }
  .vs-mkt-page .mkt-have-q__a { padding: 0 var(--vsm-5) var(--vsm-5); }
  /* Same specificity trap as .mkt-faq__a above — without this, every closed
     tile carries 20px of the open panel's padding and the list looks like a
     column of half-empty boxes. */
  .vs-mkt-page .mkt-have-q__a[hidden] { padding-bottom: 0; }
  .vs-mkt-page .mkt-have-q__a > p { color: var(--vsm-ink-body); }
}

/* =========================================================================
   14 · FOOTER  —  the desktop footer had no mobile design at all: a 3-column
   flex row, a 645px newsletter block, 24px inline inputs and a clamped
   140px ghost wordmark, all landing in 375px. Rebuilt as a single column
   with contact rows as real 48px targets.
   ========================================================================= */
@media (max-width: 768px) {
  .vs-mkt-page .mkt-footer {
    padding: var(--vsm-10) var(--vsm-gutter) var(--vsm-8);
    border-top-left-radius: var(--vsm-r-sheet);
    border-top-right-radius: var(--vsm-r-sheet);
  }
  .vs-mkt-page .mkt-footer__inner { gap: var(--vsm-10); max-width: none; }

  .vs-mkt-page .mkt-footer__top {
    display: flex;
    flex-direction: column;
    gap: var(--vsm-10);
  }

  /* Newsletter leads on mobile — it is the only input on the page. */
  .vs-mkt-page .mkt-footer__newsletter {
    order: -1;
    width: 100%;
    gap: var(--vsm-5);
  }
  .vs-mkt-page .mkt-footer__newsletter-head { gap: var(--vsm-2); }
  .vs-mkt-page .mkt-footer__newsletter-title { font-size: var(--vsm-title); }
  .vs-mkt-page .mkt-footer__newsletter-sub {
    font-size: var(--vsm-body);
    color: var(--vsm-ink-body);
  }
  .vs-mkt-page .mkt-footer__newsletter-row {
    flex-direction: column;
    align-items: stretch;
    gap: var(--vsm-3);
    padding: 0;
    background: transparent;
  }
  .vs-mkt-page .mkt-footer__input {
    flex: 0 0 auto;
    width: 100%;
    min-height: var(--vsm-cta);
    padding: 0 var(--vsm-4);
    background: var(--vs-mkt-platinum, #e6e6e0);
    border-radius: var(--vsm-r-input);
    /* ≥16px or iOS zooms the whole page on focus. */
    font-size: var(--vsm-body);
    letter-spacing: 0;
  }
  .vs-mkt-page .mkt-footer__input::placeholder { opacity: 0.56; }
  .vs-mkt-page .mkt-footer__subscribe {
    width: 100%;
    min-height: var(--vsm-cta);
    border-radius: var(--vsm-r-input);
    font-size: var(--vsm-body);
    transition: transform 140ms var(--vsm-ease), background-color 200ms ease;
  }
  .vs-mkt-page .mkt-footer__subscribe:active { transform: scale(0.98); }

  .vs-mkt-page .mkt-footer__cols {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: var(--vsm-8);
  }
  .vs-mkt-page .mkt-footer__col { gap: var(--vsm-4); }
  .vs-mkt-page .mkt-footer__col-title {
    font-size: var(--vsm-label);
    letter-spacing: 0.16em;
    /* Desktop's 0.4 opacity lands at ~4.3:1 here, under the 4.5 floor for
       14px. 0.7 clears AA without turning a quiet label into a heading. */
    opacity: 0.7;
  }

  /* Sitemap + contact + legal all become 48px rows. */
  .vs-mkt-page .mkt-footer__col-list { gap: 0; }
  .vs-mkt-page .mkt-footer__col-list a,
  .vs-mkt-page .mkt-footer__contact-link {
    display: flex;
    align-items: center;
    gap: var(--vsm-3);
    min-height: var(--vsm-tap);
    font-size: var(--vsm-body);
    color: var(--vs-ink);
  }
  .vs-mkt-page .mkt-footer__col-list li + li { border-top: 1px solid var(--vsm-hairline-soft); }

  /* ---- Minimal footer (/home-newday) ------------------------------------
     Desktop puts the lockup and the contact links on opposite ends of one
     row; ≤768px __top is a column, so `align-items: center` would centre
     the lockup over left-aligned links. Everything hangs left. The lockup
     also drops to the app bar's sizing: at the desktop 43px mark + 24px
     wordmark it ran nearly edge to edge in a 375px column and read as a
     headline, not a sign-off. */
  .vs-mkt-page .mkt-footer--minimal .mkt-footer__top { align-items: flex-start; }
  .vs-mkt-page .mkt-footer--minimal .mkt-footer__brand-mark { width: 36px; height: 27px; }
  .vs-mkt-page .mkt-footer--minimal .mkt-footer__brand-word {
    font-size: var(--vsm-label);
    letter-spacing: 0.13em;
  }
  .vs-mkt-page .mkt-footer__contact { gap: 0; }
  .vs-mkt-page .mkt-footer__address {
    font-size: var(--vsm-small);
    line-height: 1.55;
    color: var(--vsm-ink-body);
    margin: 0 0 var(--vsm-3);
  }
  .vs-mkt-page .mkt-footer__contact-icon { width: 20px; height: 20px; flex-shrink: 0; }

  .vs-mkt-page .mkt-footer__social { gap: var(--vsm-2); }
  .vs-mkt-page .mkt-footer__social a {
    width: var(--vsm-tap);
    height: var(--vsm-tap);
    display: inline-grid;
    place-items: center;
    border-radius: var(--vsm-r-input);
    background: rgba(14, 15, 12, 0.05);
  }
  .vs-mkt-page .mkt-footer__social img { width: 20px; height: 20px; }

  .vs-mkt-page .mkt-footer__bottom {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--vsm-4);
    padding-top: var(--vsm-6);
    border-top: 1px solid var(--vsm-hairline-soft);
  }
  /* Desktop dims these with opacity (0.4 on the copyright, 0.8 on the
     links), which at 16px is ~2.5:1 and ~5.3:1. Legal text is exactly the
     text this audience needs to be able to read — full opacity, and the
     colour alone carries the "quiet" hierarchy at 9.5:1. */
  .vs-mkt-page .mkt-footer__legal {
    font-size: var(--vsm-small);
    color: var(--vsm-ink-body);
    opacity: 1;
    margin: 0;
  }
  .vs-mkt-page .mkt-footer__legal-links {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    width: 100%;
  }
  .vs-mkt-page .mkt-footer__legal-links li { width: 100%; }
  .vs-mkt-page .mkt-footer__legal-links a {
    display: flex;
    align-items: center;
    gap: var(--vsm-2);
    min-height: var(--vsm-tap);
    font-size: var(--vsm-small);
    color: var(--vsm-ink-body);
    opacity: 1;
  }
}

/* =========================================================================
   15 · TYPE LADDER LOCK  —  40 · 28 · 20 · 18 · 16 · 14
   One ladder for the whole page. Desktop tokens clamp against viewport
   width and land at arbitrary sizes down here; these are absolute.
   ========================================================================= */
@media (max-width: 768px) {
  /* Display — page H1s */
  .vs-mkt-page .mkt-hero__title,
  .vs-mkt-page .mkt-services-hero__title,
  .vs-mkt-page .mkt-about-hero__title,
  .vs-mkt-page .mkt-ct-hero__title {
    font-size: var(--vsm-display);
    line-height: 1.06;
    letter-spacing: -1.2px;
  }
  .vs-mkt-page .mkt-have-q__title {
    font-size: var(--vsm-display);
    line-height: 1.08;
    letter-spacing: -1.2px;
  }

  /* Section titles */
  .vs-mkt-page .mkt-section-title,
  .vs-mkt-page .mkt-more__title,
  .vs-mkt-page .mkt-more__subtitle,
  .vs-mkt-page .mkt-concierge__title,
  .vs-mkt-page .mkt-portal__title,
  .vs-mkt-page .mkt-about-story__title,
  .vs-mkt-page .mkt-ct-msg__title,
  .vs-mkt-page .mkt-ct-help__title,
  .vs-mkt-page .mkt-jp-stay__title,
  .vs-mkt-page .mkt-jp-follow__title {
    font-size: var(--vsm-title);
    line-height: 1.14;
    letter-spacing: -0.7px;
  }

  /* Card / feature / quote titles */
  .vs-mkt-page .mkt-benefit-card__title,
  .vs-mkt-page .mkt-soon-card__title,
  .vs-mkt-page .mkt-how__step-title,
  .vs-mkt-page .mkt-concierge-feature__title,
  .vs-mkt-page .mkt-mission__pullquote,
  .vs-mkt-page .mkt-faq__q,
  .vs-mkt-page .mkt-have-q__q,
  .vs-mkt-page .mkt-feature__title,
  .vs-mkt-page .mkt-about-story__lead,
  .vs-mkt-page .mkt-ct-card__title {
    font-size: var(--vsm-card);
    line-height: 1.3;
    letter-spacing: -0.3px;
  }
  .vs-mkt-page .mkt-how__num { font-size: var(--vsm-card); }
  /* Stat "values" are phrases as often as figures ("Created by Veterans"),
     and on desktop they sit at 73px against a 72px section title — i.e. peer
     level, not a tier above. Mapping them to the title tier keeps that exact
     relationship; the display tier would invert it. */
  .vs-mkt-page .mkt-about-stat__value {
    font-size: var(--vsm-title);
    line-height: 1.1;
    letter-spacing: -0.7px;
  }

  /* Call CTA — the desktop text link becomes a filled, full-width button
     (Slav, 26 Aug). On a phone the number is one tap away from being dialled
     and it is the page's only action, so it gets the full target rather than
     an underlined phrase. Same label as desktop; only the shape changes. */
  .vs-mkt-page .mkt-call-link {
    display: flex;
    width: 100%;
    justify-content: center;
    min-height: var(--vsm-cta);
    padding: 0 var(--vsm-5);
    border-radius: var(--vsm-r-input);
    background: #576038;
    color: #fff;
    font-size: var(--vsm-body);
    text-decoration: none;
    text-align: center;
  }
  .vs-mkt-page .mkt-call-link:active { transform: scale(0.99); }
  .vs-mkt-page .mkt-call-link svg { width: 20px; height: 20px; }
  @media (prefers-reduced-motion: reduce) {
    .vs-mkt-page .mkt-call-link:active { transform: none; }
  }

  /* Body — the 18px senior floor */
  .vs-mkt-page .mkt-hero__lead,
  .vs-mkt-page .mkt-benefits__lead,
  .vs-mkt-page .mkt-vs-fox__body,
  .vs-mkt-page .mkt-mission__body,
  .vs-mkt-page .mkt-have-q__body,
  .vs-mkt-page .mkt-concierge-feature__body,
  .vs-mkt-page .mkt-benefit-card__body-text,
  .vs-mkt-page .mkt-how__step-text,
  .vs-mkt-page .mkt-soon-card__text,
  .vs-mkt-page .mkt-faq__a > p,
  .vs-mkt-page .mkt-have-q__a > p,
  .vs-mkt-page .mkt-services-hero__lead,
  .vs-mkt-page .mkt-about-hero__lead,
  .vs-mkt-page .mkt-ct-hero__lead,
  .vs-mkt-page .mkt-more__lead,
  .vs-mkt-page .mkt-more__sub-body,
  .vs-mkt-page .mkt-feature__body,
  .vs-mkt-page .mkt-concierge__body,
  .vs-mkt-page .mkt-concierge__item,
  .vs-mkt-page .mkt-portal__body,
  .vs-mkt-page .mkt-about-story__body,
  .vs-mkt-page .mkt-ct-help__body,
  .vs-mkt-page .mkt-jp-stay__lead,
  .vs-mkt-page .mkt-jp-follow__lead {
    font-size: var(--vsm-body);
    line-height: 1.55;
  }

  /* Small */
  .vs-mkt-page .mkt-mission__attr { font-size: var(--vsm-small); }

  /* Body tier additions that live outside the main body list */
  .vs-mkt-page .mkt-about-stat__label,
  .vs-mkt-page .mkt-about-story__copy {
    font-size: var(--vsm-body);
    line-height: 1.55;
  }

  /* Labels — one size, one tracking. List extended (2026-08-02) to every
     eyebrow class: desktop unified them onto the --vs-mkt-overline-* tokens,
     so any class missing here would have stayed at the 18px desktop size on
     mobile. Weight comes from the shared token (400). */
  .vs-mkt-page .mkt-eyebrow,
  .vs-mkt-page .mkt-mission__eyebrow,
  .vs-mkt-page .mkt-have-q__eyebrow,
  .vs-mkt-page .mkt-soon-card__chip,
  .vs-mkt-page .mkt-services-hero__eyebrow,
  .vs-mkt-page .mkt-about-hero__eyebrow,
  .vs-mkt-page .mkt-ct-hero__eyebrow,
  .vs-mkt-page .mkt-concierge__eyebrow,
  .vs-mkt-page .mkt-portal__eyebrow,
  .vs-mkt-page .mkt-jp-stay__eyebrow,
  .vs-mkt-page .mkt-moment__eyebrow,
  .vs-mkt-page .mkt-unified__eyebrow,
  .vs-mkt-page .mkt-partnerships__eyebrow,
  .vs-mkt-page .mkt-partnerships__caption-eyebrow,
  .vs-mkt-page .mkt-hear__eyebrow,
  .vs-mkt-page .mkt-meaningful__eyebrow,
  .vs-mkt-page .mkt-jp-hero__eyebrow {
    font-size: var(--vsm-label);
    letter-spacing: 0.16em;
  }
}

/* Narrow phones (≤360px): display drops one notch, cards go edge-tighter. */
@media (max-width: 360px) {
  :root { --vsm-gutter: 16px; }
  .vs-mkt-page .mkt-hero__title,
  .vs-mkt-page .mkt-have-q__title { font-size: 36px; }
  .vs-mkt-page .mkt-section-title { font-size: 26px; }
}

/* =========================================================================
   16 · SIGNUP  —  focused single-column conversion flow
   (marketing-mobile.css is also loaded by signup.html, which has no
   .mkt-nav; these rules stand alone.)
   ========================================================================= */
@media (max-width: 768px) {
  main.signup-page .auth-showcase { display: none; }
  main.signup-page .signup__left {
    padding: var(--vsm-6) var(--vsm-gutter) 0;
    min-height: auto;
  }
  main.signup-page .signup__form--wizard { gap: var(--vsm-5) !important; }
  main.signup-page .signup__head { gap: var(--vsm-2) !important; margin-bottom: 0; }
  main.signup-page .signup__view { gap: var(--vsm-4) !important; }

  /* Paired fields stack. Two inputs across 335px leaves neither wide enough
     to read back what you typed. */
  main.signup-page .signup__row {
    grid-template-columns: 1fr !important;
    gap: var(--vsm-4) !important;
  }

  main.signup-page .signup__title { line-height: 1.15; letter-spacing: -0.4px; }

  .signup__field { gap: var(--vsm-2); }
  .signup__row { gap: var(--vsm-4); }
  .signup__input {
    padding: 14px var(--vsm-4);
    min-height: var(--vsm-cta);
    font-size: var(--vsm-body);      /* ≥16px: no iOS zoom on focus */
    border-radius: var(--vsm-r-input);
  }
  .signup__label { font-size: var(--vsm-small); font-weight: 600; }

  .signup__consent,
  .signup__check { min-height: var(--vsm-tap); }
  .signup__consent-text { font-size: var(--vsm-small); line-height: 1.5; }

  /* Primary action rides above the thumb zone. */
  .signup__actions {
    position: sticky;
    bottom: 0;
    z-index: 10;
    margin: var(--vsm-4) calc(var(--vsm-gutter) * -1) 0;
    padding: var(--vsm-4) var(--vsm-gutter)
             calc(var(--vsm-4) + env(safe-area-inset-bottom, 0px));
    /* Opaque under the button, feathered above it. A fully transparent top
       stop let the consent paragraph read straight through the bar. */
    background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, #ffffff 40%);
  }
  /* The sticky bar overlays the end of the form, so the last field needs room
     to scroll clear of it rather than ending underneath. */
  main.signup-page .signup__left {
    padding-bottom: calc(var(--vsm-cta) + var(--vsm-10)) !important;
  }
  .signup__actions .portal-btn { min-height: var(--vsm-cta); font-size: var(--vsm-body); }

  .signup__code { gap: var(--vsm-2); justify-content: center; }
  .signup__code-cell {
    width: 44px;
    height: var(--vsm-cta);
    font-size: 24px;
    border-radius: var(--vsm-r-input);
  }
}

/* =========================================================================
   17 · SERVICES  (/services)
   Bands: hero · "more" category explorer · concierge · live portal · FAQ.
   FAQ + footer + chrome come from the shared sections above.
   ========================================================================= */
@media (max-width: 768px) {
  /* ---- Hero: centred, hugs its content (desktop min-height is 807px) ---- */
  .vs-mkt-page .mkt-services-hero { padding: 0; }
  .vs-mkt-page .mkt-services-hero__inner {
    min-height: 0;
    max-width: none;
    padding: var(--vsm-8) var(--vsm-gutter) var(--vsm-10);
    border-radius: 0;
    gap: var(--vsm-4);
  }
  .vs-mkt-page .mkt-services-hero__eyebrow { margin: 0; }
  .vs-mkt-page .mkt-services-hero__title { max-width: none; }
  .vs-mkt-page .mkt-services-hero__lead {
    max-width: none;
    color: var(--vsm-ink-body);
  }

  /* ---- "More" category explorer -------------------------------------------
     Desktop is a 2-up split: a 720px photo panel carrying six 56px category
     tabs in white over the image, beside the selected panel's content.
     Two things do not survive the translation. Tabs set in 56px display type
     do not fit six labels in 335px, and tabs sitting on photography have no
     guaranteed contrast — the same mistake as a value badge on a photo, and
     the reason those tabs also measured 47px tall (under the 48px floor).
     Mobile: the photo becomes a plain 180px band, and the tabs come off it
     into a horizontal chip rail on a flat surface where contrast is fixed
     and each chip is a real 48px target. Selector first, then content —
     the standard mobile category pattern.
     ---------------------------------------------------------------------- */
  .vs-mkt-page .mkt-more { padding: var(--vsm-band) var(--vsm-gutter) 0; }
  .vs-mkt-page .mkt-more__head {
    max-width: none;
    margin: 0 0 var(--vsm-6);
    padding: 0;
    align-items: flex-start;
    text-align: left;
    gap: var(--vsm-3);
  }
  .vs-mkt-page .mkt-more__lead { max-width: none; color: var(--vsm-ink-body); }

  .vs-mkt-page .mkt-more__split {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    gap: var(--vsm-5);
    padding: var(--vsm-5);
    border-radius: var(--vsm-r-card-lg);
  }

  /* The visual stops being an overlay surface and becomes a plain stack. */
  .vs-mkt-page .mkt-more__visual {
    order: 1;
    min-height: 0;
    padding: 0;
    border-radius: 0;
    overflow: visible;
    color: inherit;
    display: flex;
    flex-direction: column;
    gap: var(--vsm-4);
  }
  /* marketing-light adds a scrim ::before and marketing.css an ::after —
     both exist to make white text readable over the photo. No text sits on
     the photo now, so both would just dim the image. */
  .vs-mkt-page .mkt-more__visual::before,
  .vs-mkt-page .mkt-more__visual::after { display: none; }

  .vs-mkt-page .mkt-more__visual-bg {
    position: relative;
    inset: auto;
    z-index: 0;
    order: 1;
    height: 180px;
    border-radius: var(--vsm-r-card);
  }

  /* Chip rail. Full-bleed out of the slab's padding so it can scroll to the
     edges, which is what tells the reader there is more than fits. */
  .vs-mkt-page .mkt-more__tabs {
    order: 2;
    flex-direction: row;
    gap: var(--vsm-2);
    margin: 0 calc(var(--vsm-5) * -1);
    padding: 0 var(--vsm-5);
    overflow-x: auto;
    scrollbar-width: none;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
  .vs-mkt-page .mkt-more__tabs::-webkit-scrollbar { display: none; }
  .vs-mkt-page .mkt-more__tabs > li { flex: 0 0 auto; scroll-snap-align: start; }

  .vs-mkt-page .mkt-more__tab {
    width: auto;
    min-height: var(--vsm-tap);
    padding: 0 var(--vsm-4);
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
    border-radius: var(--vsm-r-input);
    background: #fff;
    border: 1.5px solid rgba(14, 15, 12, 0.14);
    color: var(--vsm-ink-body);
    font-size: var(--vsm-small);
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0;
    text-shadow: none;
    text-align: center;
    transition:
      transform 140ms var(--vsm-ease),
      background-color 180ms ease,
      color 180ms ease,
      border-color 180ms ease;
  }
  /* The caret was the desktop selection cue; a filled chip is the mobile one. */
  .vs-mkt-page .mkt-more__tab::before { display: none; }
  .vs-mkt-page .mkt-more__tab:active { transform: scale(0.97); }
  .vs-mkt-page .mkt-more__tab[aria-selected="true"] {
    background: var(--vs-olive, #5a6b3f);
    border-color: var(--vs-olive, #5a6b3f);
    color: #fff;
    font-weight: 700;
  }

  /* ---- Selected panel ---- */
  .vs-mkt-page .mkt-more__content { order: 2; min-width: 0; }
  /* Trap #1 again: the `display: flex` below defeats the `hidden` attribute,
     which rendered all six category panels at once — the section measured
     7386px instead of ~1200. Any mobile rule that sets `display` on an
     element the page toggles with `hidden` must re-assert the hidden state. */
  .vs-mkt-page .mkt-more__panel[hidden] { display: none; }
  .vs-mkt-page .mkt-more__panel {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--vsm-4);
    padding: 0;
  }
  .vs-mkt-page .mkt-more__subtitle { margin: 0; }
  .vs-mkt-page .mkt-more__sub-body { margin: 0; color: var(--vsm-ink-body); }
  .vs-mkt-page .mkt-more__panel .mkt-btn {
    display: flex;
    width: 100%;
    min-height: var(--vsm-cta);
    padding: 14px var(--vsm-5);
    justify-content: center;
    align-items: center;
    gap: var(--vsm-3);
    border-radius: var(--vsm-r-input);
    font-size: var(--vsm-body);
    letter-spacing: 0.06em;
  }

  /* Feature list — desktop 2-col grid of cards becomes one column. The card
     surface (white, hairline, 12px radius) and the ink icon chip are the
     desktop treatment and stay exactly as they are; only the internal
     arrangement changes, so the icon sits beside the title it labels rather
     than stacked above it — at 335px a stacked icon wastes a whole row. */
  .vs-mkt-page .mkt-features {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    gap: var(--vsm-3);
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .vs-mkt-page .mkt-feature {
    display: grid;
    grid-template-columns: 32px 1fr;
    column-gap: var(--vsm-3);
    row-gap: 4px;
    align-items: start;
    padding: var(--vsm-4);
  }
  .vs-mkt-page .mkt-feature__icon {
    grid-column: 1;
    grid-row: 1;
  }
  .vs-mkt-page .mkt-feature__icon svg { display: block; }
  .vs-mkt-page .mkt-feature__title {
    grid-column: 2;
    grid-row: 1;
    margin: 0;
    align-self: center;
  }
  .vs-mkt-page .mkt-feature__body {
    grid-column: 2;
    grid-row: 2;
    margin: var(--vsm-2) 0 0;
    color: var(--vsm-ink-body);
  }

  /* ---- Concierge: photo band over a dark copy panel ---------------------
     marketing.css already stacks this at ≤768px; these are the type,
     spacing and target sizes on top of that. ---------------------------- */
  .vs-mkt-page .mkt-concierge { padding: var(--vsm-band) var(--vsm-gutter) 0; }
  .vs-mkt-page .mkt-concierge__panel { border-radius: var(--vsm-r-card-lg); }
  .vs-mkt-page .mkt-concierge__photo { height: 220px; }
  .vs-mkt-page .mkt-concierge__copy {
    max-width: none;
    padding: var(--vsm-8) var(--vsm-6) var(--vsm-10);
    gap: var(--vsm-4);
    align-items: stretch;
  }
  .vs-mkt-page .mkt-concierge__eyebrow {
    margin: 0;
    font-weight: 700;
    opacity: 1;
    color: rgba(255, 255, 255, 0.82);
  }
  .vs-mkt-page .mkt-concierge__title { margin: 0; }
  .vs-mkt-page .mkt-concierge__body { margin: 0; opacity: 1; color: rgba(255, 255, 255, 0.92); }
  .vs-mkt-page .mkt-concierge__list { margin: var(--vsm-2) 0 0; gap: var(--vsm-4); }
  .vs-mkt-page .mkt-concierge__item { align-items: flex-start; gap: var(--vsm-3); }
  .vs-mkt-page .mkt-concierge__check { width: 26px; height: 26px; margin-top: 1px; }
  .vs-mkt-page .mkt-concierge__check svg { display: block; }
  .vs-mkt-page .mkt-concierge__copy .mkt-btn {
    display: flex;
    width: 100%;
    min-height: var(--vsm-cta);
    padding: 14px var(--vsm-5);
    justify-content: center;
    align-items: center;
    gap: var(--vsm-3);
    border-radius: var(--vsm-r-input);
    font-size: var(--vsm-body);
    letter-spacing: 0.06em;
  }

  /* ---- Live portal preview ----------------------------------------------
     Desktop pins the iMac at left 36.9% / width 65% of a 1888×1034 panel
     with the copy beside it. At 375px that lands a 474px-wide device inside
     a 335px panel. Stack instead: copy, then the device at full width. The
     device stays (it is the "there is a member portal" proof) but it is
     decorative and aria-hidden, so its legibility is not load-bearing.
     -------------------------------------------------------------------- */
  .vs-mkt-page .mkt-portal { padding: var(--vsm-band) var(--vsm-gutter); }
  .vs-mkt-page .mkt-portal__panel {
    aspect-ratio: auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: var(--vsm-6);
    padding: var(--vsm-8) var(--vsm-5) 0;
    border-radius: var(--vsm-r-card-lg);
  }
  .vs-mkt-page .mkt-portal__copy {
    order: 1;
    max-width: none;
    gap: var(--vsm-4);
    align-items: stretch;
  }
  .vs-mkt-page .mkt-portal__eyebrow { margin: 0; }
  .vs-mkt-page .mkt-portal__title { margin: 0; }
  .vs-mkt-page .mkt-portal__body { margin: 0; max-width: none; }
  .vs-mkt-page .mkt-portal__copy .mkt-btn {
    display: flex;
    width: 100%;
    min-height: var(--vsm-cta);
    padding: 14px var(--vsm-5);
    justify-content: center;
    align-items: center;
    gap: var(--vsm-3);
    border-radius: var(--vsm-r-input);
    font-size: var(--vsm-body);
    letter-spacing: 0.06em;
  }
  /* The panel is a column flex here, so `align-items` controls horizontal
     size. marketing.css sets it to center (and flex-start ≤1280px), which
     stops children stretching — the device rendered at its intrinsic width. */
  .vs-mkt-page .mkt-portal__panel { align-items: stretch; }

  /* Device: out of absolute positioning, into the flow at full width.
     marketing.css has its OWN ≤768px block giving this
     `left/right: -16%; width: 132%; bottom: 16px`. Resetting only `left`
     left `right: -16%` in force, which on a relatively-positioned box still
     shifts it ~54px sideways and pushed it out past the panel edge. Every
     offset it sets has to be neutralised, not just the one you notice. */
  .vs-mkt-page .mkt-portal__panel--live .mkt-portal__device,
  .vs-mkt-page .mkt-portal__device {
    position: relative;
    order: 2;
    left: auto;
    right: auto;
    top: auto;
    bottom: auto;
    width: 100%;
    max-width: 100%;
    transform: none;
    margin-bottom: calc(var(--vsm-8) * -1);
  }
  .vs-mkt-page .mkt-portal__imac,
  .vs-mkt-page .mkt-portal__panel--live .mkt-portal__imac {
    position: relative;
    left: auto;
    top: auto;
    width: 100%;
    display: block;
  }
  /* The non-live play affordance (home-backup) is positioned against the
     desktop panel; it has no anchor once the device is in the flow, so hide
     it. The --live play button lives INSIDE the flowed device, so it keeps
     its centre-of-screen anchor and stays visible. */
  .vs-mkt-page .mkt-portal__play { display: none; }
  .vs-mkt-page .mkt-portal__panel--live .mkt-portal__play { display: block; }
  .vs-mkt-page .mkt-portal__glow { display: none; }
}

/* =========================================================================
   18 · ABOUT  (/about)
   Bands: hero · mission (shared, §11) · our story · stats · photo slider · FAQ.
   ========================================================================= */
@media (max-width: 768px) {
  /* ---- Hero ---- */
  .vs-mkt-page .mkt-about-hero { padding: var(--vsm-8) var(--vsm-gutter) var(--vsm-band); }
  .vs-mkt-page .mkt-about-hero__inner { max-width: none; gap: var(--vsm-4); }
  .vs-mkt-page .mkt-about-hero__eyebrow { margin: 0; }
  .vs-mkt-page .mkt-about-hero__lead {
    max-width: none;
    margin: 0;
    color: var(--vsm-ink-body);
  }
  .vs-mkt-page .mkt-about-hero__inner .mkt-btn {
    display: flex;
    width: 100%;
    min-height: var(--vsm-cta);
    padding: 14px var(--vsm-5);
    justify-content: center;
    align-items: center;
    gap: var(--vsm-3);
    border-radius: var(--vsm-r-input);
    font-size: var(--vsm-body);
    letter-spacing: 0.06em;
  }

  /* ---- Our story: 2-col grid (heading | narrative) becomes one column ---- */
  .vs-mkt-page .mkt-about-story { padding: var(--vsm-band) var(--vsm-gutter); }
  .vs-mkt-page .mkt-about-story__inner {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    gap: var(--vsm-6);
    max-width: none;
  }
  .vs-mkt-page .mkt-about-story__head { gap: var(--vsm-3); }
  .vs-mkt-page .mkt-about-story__body { gap: var(--vsm-5); }
  .vs-mkt-page .mkt-about-story__lead { margin: 0; }
  .vs-mkt-page .mkt-about-story__copy { margin: 0; color: var(--vsm-ink-body); }

  /* ---- Stats: 3-up row becomes three stacked cards ----------------------
     Each card keeps the desktop relationship — value dominant, label
     beneath — rather than being squeezed into columns, which is what forces
     wrapping and misalignment in a ~335px box. -------------------------- */
  .vs-mkt-page .mkt-about-stats { padding: 0 var(--vsm-gutter) var(--vsm-band); }
  .vs-mkt-page .mkt-about-stats__grid {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    gap: var(--vsm-3);
    max-width: none;
  }
  .vs-mkt-page .mkt-about-stat {
    min-height: 0;
    padding: var(--vsm-5);
    gap: var(--vsm-2);
    border-radius: var(--vsm-r-card);
  }
  .vs-mkt-page .mkt-about-stat__value {
    margin: 0;
    /* Figures, no descenders — trim so the numeral reads optically centred
       against its label rather than sitting high in its line box. */
    font-variant-numeric: tabular-nums;
    text-box: trim-both cap alphabetic;
  }
  .vs-mkt-page .mkt-about-stat__label { margin: 0; }

  /* ---- Photo slider: 60s auto-marquee becomes a manual carousel ---------
     Same rule as the coming-soon rail: nothing on this page moves on its
     own. 480×600 items are also simply too large for a 375px viewport, so
     they come down to a 4:5 card the reader can actually take in.
     `data-mkt-carousel` on the track wires up swipe + Previous/Next; the
     cloned half is dropped so it isn't counted as extra slides.
     -------------------------------------------------------------------- */
  /* The section itself is the scroll container (the track is just the flex
     row). Both axes are declared explicitly: leaving one `visible` while the
     other is `auto` makes the browser compute the visible one to `auto` too,
     which would quietly turn this into a vertical scroller as well. */
  .vs-mkt-page .mkt-about-slider {
    padding: 0 0 var(--vsm-band);
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    scroll-snap-type: x mandatory;
    scroll-padding-left: var(--vsm-gutter);
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
  }
  .vs-mkt-page .mkt-about-slider::-webkit-scrollbar { display: none; }
  .vs-mkt-page .mkt-about-slider__track {
    animation: none;
    width: max-content;
    gap: var(--vsm-3);
    padding: 0 var(--vsm-gutter);
  }
  .vs-mkt-page .mkt-about-slider__track > [aria-hidden="true"] { display: none; }
  .vs-mkt-page .mkt-about-slider__item {
    width: calc(100vw - 72px);
    height: auto;
    aspect-ratio: 4 / 5;
    scroll-snap-align: start;
    border-radius: var(--vsm-r-card-lg);
  }
}

/* =========================================================================
   19 · CONTACT  (/contact)
   Bands: hero + direct-contact links · help card + message form · FAQ ·
   newsletter panel · follow row.
   Forms are the whole point of this page, so every control is ≥48px and
   every input is ≥16px (below that iOS zooms the page on focus and the
   reader loses their place).
   ========================================================================= */
@media (max-width: 768px) {
  /* ---- Hero ---- */
  .vs-mkt-page .mkt-ct-hero { padding: var(--vsm-8) var(--vsm-gutter) var(--vsm-band); }
  .vs-mkt-page .mkt-ct-hero__inner { max-width: none; gap: var(--vsm-5); }
  .vs-mkt-page .mkt-ct-hero__eyebrow { margin: 0; }
  .vs-mkt-page .mkt-ct-hero__lead { max-width: none; color: var(--vsm-ink-body); }

  /* Phone and email are the fastest route to help for this audience, so they
     become full-width rows rather than a wrapped 27px inline list. */
  /* Yuval (23 Aug): "centre the phone number and turn it into a dial button
     with the number on it, and the email underneath it, centred." Calling is
     the primary action on a phone, so the tel row becomes the button and the
     divider between the two rows goes with it — a rule under a button reads
     as a seam, not a separator. */
  .vs-mkt-page .mkt-ct-hero__contacts {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--vsm-4);
    margin: var(--vsm-5) 0 0;
    width: 100%;
  }
  .vs-mkt-page .mkt-ct-hero__contacts > li { width: 100%; }
  .vs-mkt-page .mkt-ct-hero__contacts > li + li { border-top: 0; }
  .vs-mkt-page .mkt-ct-hero__link {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--vsm-3);
    min-height: var(--vsm-cta);
    font-size: var(--vsm-body);
    line-height: 1.3;
    text-align: center;
  }
  /* The dial button. Same skin as every other full-width mobile action
     (§1), so it reads as the page's primary control. */
  .vs-mkt-page .mkt-ct-hero__link[href^="tel:"] {
    padding: 14px var(--vsm-5);
    border-radius: var(--vsm-r-input);
    background: #576038;
    border: 1px solid #576038;
    color: #fff;
    font-weight: 600;
    letter-spacing: 0.06em;
  }
  .vs-mkt-page .mkt-ct-hero__link[href^="tel:"]:active { transform: scale(0.98); }
  .vs-mkt-page .mkt-ct-hero__icon { width: 24px; height: 24px; flex-shrink: 0; }
  .vs-mkt-page .mkt-ct-hero__icon svg { display: block; }

  /* ---- Help card + message form: 2-up becomes stacked ---- */
  .vs-mkt-page .mkt-ct-form { padding: var(--vsm-band) var(--vsm-gutter); }
  .vs-mkt-page .mkt-ct-form__inner {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    gap: var(--vsm-6);
    max-width: none;
  }
  .vs-mkt-page .mkt-ct-help {
    min-height: 280px;
    padding: var(--vsm-8) var(--vsm-6);
    border-radius: var(--vsm-r-card-lg);
  }
  .vs-mkt-page .mkt-ct-help__copy { gap: var(--vsm-3); }
  .vs-mkt-page .mkt-ct-help__title { margin: 0; }
  .vs-mkt-page .mkt-ct-help__body { margin: 0; max-width: none; }

  .vs-mkt-page .mkt-ct-msg { padding: 0; gap: var(--vsm-5); }
  .vs-mkt-page .mkt-ct-msg__title { margin: 0; }
  .vs-mkt-page .mkt-ct-msg__form { gap: var(--vsm-4); }
  /* Paired fields (first/last, etc.) stack — two inputs in 335px leaves
     neither wide enough to read what you typed. */
  .vs-mkt-page .mkt-ct-msg__row {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    gap: var(--vsm-4);
  }
  .vs-mkt-page .mkt-ct-field input,
  .vs-mkt-page .mkt-ct-field textarea,
  .vs-mkt-page .mkt-ct-field select {
    min-height: var(--vsm-cta);
    padding: 14px var(--vsm-4);
    border-radius: var(--vsm-r-input);
    font-size: var(--vsm-body);
    border-color: rgba(14, 15, 12, 0.12);
  }
  .vs-mkt-page .mkt-ct-field textarea {
    min-height: 132px;
    padding-top: var(--vsm-3);
  }
  .vs-mkt-page .mkt-ct-field--select select { padding-right: 44px; }
  .vs-mkt-page .mkt-ct-field__chev { right: var(--vsm-4); }
  .vs-mkt-page .mkt-ct-msg__submit {
    width: 100%;
    min-height: var(--vsm-cta);
    border-radius: var(--vsm-r-input);
    font-size: var(--vsm-body);
    transition: transform 140ms var(--vsm-ease), background-color 200ms ease;
  }
  .vs-mkt-page .mkt-ct-msg__submit:active { transform: scale(0.98); }

  /* ---- Newsletter panel -------------------------------------------------
     The desktop control is an input and a button side by side inside one
     pill. At 335px that leaves the input too narrow to read an email
     address back, so the pill unwraps into a stacked field + full-width
     button. -------------------------------------------------------------- */
  .vs-mkt-page .mkt-jp-stay { padding: var(--vsm-band) var(--vsm-gutter); }
  .vs-mkt-page .mkt-jp-stay__inner {
    min-height: 0;
    padding: var(--vsm-10) var(--vsm-6);
    border-radius: var(--vsm-r-card-lg);
    /* Yuval (23 Aug): "the email address overflows." The panel is a grid with
       one implicit `auto` track, so the track sized to the form's min-content
       (261px) rather than the 240px content box at 320px wide — and the
       panel's own `overflow: hidden` clipped the right edge of the input and
       the Subscribe button. minmax(0, …) lets the track shrink. */
    grid-template-columns: minmax(0, 1fr);
    /* Dark base under the photo so the panel can never resolve to a light
       surface behind white text, whatever the image does. */
    background-color: #14170f;
  }
  /* The desktop veil is a 70° left-heavy gradient built for left-aligned copy
     in a wide panel — it fades to rgba(0,0,0,.15) at the right edge. With the
     copy centred and full-width here, the right half of every line would sit
     on effectively bare photography. Replace it with an even scrim: at .72
     white clears AAA even if the photo underneath is pure white. */
  .vs-mkt-page .mkt-jp-stay__veil {
    background: linear-gradient(
      180deg,
      rgba(0, 0, 0, 0.72) 0%,
      rgba(0, 0, 0, 0.78) 100%
    );
  }
  .vs-mkt-page .mkt-jp-stay__copy { gap: var(--vsm-4); width: 100%; }
  .vs-mkt-page .mkt-jp-stay__eyebrow { margin: 0; }
  .vs-mkt-page .mkt-jp-stay__title { margin: 0; }
  .vs-mkt-page .mkt-jp-stay__lead { margin: 0; }
  .vs-mkt-page .mkt-jp-stay__form {
    flex-direction: column;
    align-items: stretch;
    gap: var(--vsm-3);
    padding: var(--vsm-3);
    max-width: none;
    border-radius: var(--vsm-r-card);
  }
  .vs-mkt-page .mkt-jp-stay__input {
    flex: 0 0 auto;
    min-height: var(--vsm-cta);
    padding: 0 var(--vsm-4);
    background: #fff;
    border-radius: var(--vsm-r-input);
    font-size: var(--vsm-body);
  }
  .vs-mkt-page .mkt-jp-stay__btn {
    width: 100%;
    min-height: var(--vsm-cta);
    border-radius: var(--vsm-r-input);
    font-size: var(--vsm-body);
    transition: transform 140ms var(--vsm-ease), background-color 200ms ease;
  }
  .vs-mkt-page .mkt-jp-stay__btn:active { transform: scale(0.98); }

  /* ---- Follow row ---- */
  .vs-mkt-page .mkt-jp-follow { padding: 0 var(--vsm-gutter) var(--vsm-band); }
  .vs-mkt-page .mkt-jp-follow__inner {
    max-width: none;
    gap: var(--vsm-4);
  }
  .vs-mkt-page .mkt-jp-follow__title { margin: 0; }
  .vs-mkt-page .mkt-jp-follow__lead { margin: 0; max-width: none; }
  .vs-mkt-page .mkt-jp-follow__icons { gap: var(--vsm-2); flex-wrap: wrap; }
  .vs-mkt-page .mkt-jp-follow__icon {
    width: var(--vsm-tap);
    height: var(--vsm-tap);
    display: inline-grid;
    place-items: center;
    border-radius: var(--vsm-r-input);
  }
  .vs-mkt-page .mkt-jp-follow__icon svg { display: block; }
}

/* =========================================================================
   20 · AUTH  (/login · /forgot-password · /signup · /signup-success)
   These pages had no mobile layer at all until now — the stylesheet was not
   even linked on login, forgot-password or signup-success.

   Desktop is a 2-up: the form on the left, a full-height dark showcase panel
   on the right. On a phone the showcase is a 100vh wall between the reader
   and the form, so it goes. What is left is a single focused column: brand,
   title, fields, one primary action.

   The §16 signup rules below this stay as they are; these are the shared
   auth foundations all four pages need.

   WHY !important IS USED IN THIS SECTION ONLY
   All four auth pages carry a large page-local <style> re-skin that sets
   nearly every declaration with !important (login.html alone has ~60). An
   inline <style> also loads after this <link>, so neither specificity nor
   cascade order can reach those properties — !important is the only lever.
   The real fix is to lift those four page-local re-skins into a shared auth
   layer so no page owns its own copy of the layout; that is a larger
   refactor than a mobile pass and is flagged, not attempted here. Nothing
   outside §20 uses !important.
   ========================================================================= */
@media (max-width: 768px) {
  /* ---- Shell: one column, no showcase ---- */
  main.login-page,
  main.signup-page,
  main.fp-page,
  main.signup-success-page {
    display: block !important;
    grid-template-columns: none !important;
    min-height: 0 !important;
  }
  main.login-page .auth-showcase,
  main.signup-page .auth-showcase,
  main.fp-page .auth-showcase,
  main.signup-success-page .auth-showcase { display: none !important; }

  main.login-page .login__left,
  main.fp-page .fp__left,
  main.signup-success-page .signup-success__left {
    display: block !important;
    padding: var(--vsm-8) var(--vsm-gutter) var(--vsm-10) !important;
    /* Fills the screen so the form's white surface reaches the bottom rather
       than stopping at the content and leaving a band of page grey below it.
       dvh tracks the real viewport as mobile browser chrome shows and hides. */
    min-height: 100vh !important;
    min-height: 100dvh !important;
  }

  main.login-page .login__form-wrap,
  main.fp-page .fp__wrap,
  main.signup-success-page .signup-success__wrap {
    max-width: none !important;
    width: 100% !important;
  }

  /* ---- Form rhythm: desktop gaps are 52/40/28px ---- */
  main.login-page .login__form { gap: var(--vsm-8) !important; }
  main.login-page .login__view { gap: var(--vsm-6) !important; }
  main.login-page .login__fields { gap: var(--vsm-5) !important; }
  main.login-page .login__field { gap: var(--vsm-2) !important; }

  main.login-page .login__brand-word { height: 22px !important; }
  main.login-page .login__title,
  main.fp-page .fp__title,
  main.signup-success-page .signup-success__title,
  main.signup-page .signup__title {
    font-size: var(--vsm-display) !important;
    line-height: 1.1 !important;
    letter-spacing: -1.2px !important;
  }
  main.login-page .login__code-prompt,
  main.login-page .login__signup,
  main.login-page .login__mode-switch,
  main.login-page .login__demo-hint,
  main.login-page .login__code-actions-text {
    font-size: var(--vsm-body) !important;
    line-height: 1.5 !important;
  }
  main.login-page .login__label { font-size: var(--vsm-small) !important; opacity: 1 !important; color: var(--vsm-ink-body) !important; }

  /* ---- Inputs: 77px tall with 30px padding is a desktop control ---- */
  main.login-page .login__input,
  main.fp-page .fp__input {
    height: auto !important;
    min-height: var(--vsm-cta) !important;
    padding: 0 var(--vsm-4) !important;
    border-radius: var(--vsm-r-input) !important;
    /* ≥16px or iOS zooms the page on focus. */
    font-size: var(--vsm-body) !important;
  }
  main.login-page .login__pw .login__input { padding-right: 60px !important; }
  main.login-page .login__pw-toggle {
    right: var(--vsm-2) !important;
    width: var(--vsm-tap) !important;
    height: var(--vsm-tap) !important;
    display: inline-grid !important;
    place-items: center !important;
  }
  main.login-page .login__pw-toggle svg { display: block !important; }

  /* ---- OTP cells --------------------------------------------------------
     Six 77px cells with 20px gaps needs 582px. At 375px the grid gets the
     gap it can afford and the cells take the rest, so all six stay on one
     row — wrapping a 6-digit code across two lines makes it unreadable as
     a single value. -------------------------------------------------------- */
  main.login-page .login__code {
    gap: var(--vsm-2) !important;
    width: 100% !important;
  }
  main.login-page .login__code-cell {
    height: var(--vsm-cta) !important;
    min-width: 0 !important;
    border-radius: var(--vsm-r-input) !important;
    font-size: 24px !important;
  }

  /* forgot-password has its own code grid and password-rule list. Cells are
     aspect-ratio 1/1, so at 375px six of them plus 12px gaps would be ~46px
     square — under the target floor. Tighten the gap and let the cell take a
     56px minimum height instead of staying square. */
  main.fp-page .fp__code {
    gap: var(--vsm-2) !important;
  }
  main.fp-page .fp__code-cell {
    aspect-ratio: auto !important;
    height: var(--vsm-cta) !important;
    min-width: 0 !important;
    border-radius: var(--vsm-r-input) !important;
    font-size: 24px !important;
  }
  /* Two columns of 14px rule text in 335px truncates each rule mid-phrase. */
  main.fp-page .fp__pw-rules {
    grid-template-columns: 1fr !important;
    gap: var(--vsm-2) !important;
    font-size: var(--vsm-small) !important;
  }

  /* .login__brand is page-local (not a canonical), so it stays here. */
  main.login-page .login__brand {
    min-height: var(--vsm-tap) !important;
    display: inline-flex !important;
    align-items: center !important;
  }

  main.login-page .login__code-actions {
    flex-wrap: wrap !important;
    gap: var(--vsm-2) !important;
    align-items: center !important;
  }
  main.login-page .login__resend { min-height: var(--vsm-tap) !important; }
  main.login-page .login__error-banner { font-size: var(--vsm-small) !important; line-height: 1.5 !important; }

  main.login-page .login__submit-block {
    display: flex !important;
    flex-direction: column !important;
    gap: var(--vsm-4) !important;
    width: 100% !important;
  }

  /* Inline links inside auth copy need a real target without breaking the
     sentence they sit in. */
  /* Auth links ("Sign up here", "Forgot password?") are the page's secondary
     route, not incidental prose — each sits alone on its own line, so giving
     them a full 48px target costs nothing in line flow. */
  main.login-page a:not(.portal-btn):not(.login__brand):not(.portal-brand),
  main.fp-page a:not(.portal-btn):not(.portal-brand),
  main.signup-page a:not(.portal-btn):not(.portal-brand),
  main.signup-success-page a:not(.portal-btn):not(.portal-brand) {
    display: inline-flex !important;
    align-items: center !important;
    padding: var(--vsm-3) 0 !important;
    min-height: var(--vsm-tap) !important;
  }

  /* ---- Success page ---- */
  main.signup-success-page .signup-success__actions {
    display: flex !important;
    flex-direction: column !important;
    gap: var(--vsm-3) !important;
    width: 100% !important;
  }
}

/* =========================================================================
   21 · LEGAL  (/privacy-policy · /terms-of-use · /ca-privacy-notice ·
                /your-privacy-choices)
   These pages carry the marketing nav and footer but never loaded this
   layer, so at 375px they rendered the desktop floating capsule and the
   3-column footer. Linking the layer fixes both — and the pages also needed
   marketing-menu.js, without which hiding .mkt-nav__left would have left
   them with no navigation at all.
   The prose itself is already sized correctly (20px/1.5 body, 18px lists);
   what needed work is the navigation chrome around it.
   ========================================================================= */
@media (max-width: 768px) {
  .vs-legal-page .lgl-page { padding: 0; }
  .vs-legal-page .lgl-hero {
    padding: var(--vsm-8) var(--vsm-gutter) var(--vsm-6);
  }
  .vs-legal-page .lgl-layout {
    display: flex;
    flex-direction: column;
    grid-template-columns: none;
    gap: var(--vsm-8);
    padding: 0 var(--vsm-gutter) var(--vsm-band);
  }
  .vs-legal-page .lgl-prose { max-width: none; }

  /* Breadcrumbs: real rows, not 24px-tall links. */
  .vs-legal-page .lgl-hero__crumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--vsm-2);
  }
  .vs-legal-page .lgl-hero__crumbs a {
    display: inline-flex;
    align-items: center;
    min-height: var(--vsm-tap);
    padding: 0 2px;
  }

  /* Table of contents — the page's primary navigation on a phone, where the
     desktop sidebar has collapsed into the flow. Each entry gets a full row. */
  .vs-legal-page .lgl-toc { position: static; max-width: none; }
  .vs-legal-page .lgl-toc__list { gap: 0; }
  .vs-legal-page .lgl-toc__list li + li {
    border-top: 1px solid var(--vsm-hairline-soft);
  }
  .vs-legal-page .lgl-toc a {
    display: flex;
    align-items: center;
    min-height: var(--vsm-tap);
    font-size: var(--vsm-small);
    line-height: 1.4;
  }

  .vs-legal-page .lgl-back-to-top {
    min-height: var(--vsm-tap);
    display: inline-flex;
    align-items: center;
  }

  /* Wide legal tables scroll in their own box rather than widening the page. */
  .vs-legal-page .lgl-table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Opt-out / contact forms follow the same input rules as everywhere else. */
  .vs-legal-page .lgl-form input,
  .vs-legal-page .lgl-form select,
  .vs-legal-page .lgl-form textarea {
    min-height: var(--vsm-cta);
    font-size: var(--vsm-body);
    border-radius: var(--vsm-r-input);
  }
  .vs-legal-page .lgl-optout-cta,
  .vs-legal-page .lgl-form button {
    width: 100%;
    min-height: var(--vsm-cta);
    font-size: var(--vsm-body);
    border-radius: var(--vsm-r-input);
  }
}
