/* ==========================================================================
   mobile.css — cross-cutting mobile mechanics
   ==========================================================================

   Loaded LAST in layouts/main.php, after $additional_head, so these rules win
   over per-page stylesheets (book.css, collection-book.css, dashboard.css…).

   Scope rule: only put a rule here when it must apply across every page AND
   must beat per-page CSS. Anything specific to one component belongs in that
   component's own stylesheet — hero.css, components.css, book.css.

   Mobile breakpoint is --bp-mobile (799px) from design-system.css. Media
   queries can't read custom properties, so 799px is written literally; keep
   it in sync with the token.
   ========================================================================== */


/* --------------------------------------------------------------------------
   reCAPTCHA badge
   --------------------------------------------------------------------------
   The v3 script is loaded site-wide (auth-modal.php is included on every
   page), so Google's floating badge renders on every page — including /book,
   where it sits bottom-right directly on top of the sticky "Continue" button
   and makes part of the primary booking CTA untappable.

   Google permits hiding the badge provided the reCAPTCHA notice is shown in
   the user flow instead. That notice is rendered in two places:
     - the registration form (the only flow that calls grecaptcha.execute)
     - the site footer (matches the badge's old site-wide presence)
   If either notice is ever removed, this rule must be removed with it.

   visibility (not display) keeps the widget's own layout intact — display:none
   has historically broken v3 execution in some browsers.
   -------------------------------------------------------------------------- */
.grecaptcha-badge {
  visibility: hidden;
}

.recaptcha-notice {
  font-size: 12px;
  line-height: 1.5;
  color: var(--gray);
  margin: var(--sp-m) 0 0;
}

.recaptcha-notice a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.recaptcha-notice a:hover {
  color: var(--main);
}

/* Footer sits on --dark-blue, so the muted grey has to lift to stay legible. */
.site-footer .recaptcha-notice {
  color: rgba(255, 255, 255, 0.7);
  text-align: center;
  margin: var(--sp-m) 0 0;
}

.site-footer .recaptcha-notice a:hover {
  color: var(--accent-1);
}


@media (max-width: 799px) {

  /* ------------------------------------------------------------------------
     Form controls — 16px minimum
     ------------------------------------------------------------------------
     iOS Safari zooms the viewport on focus for any control under 16px, then
     leaves the user pinching back out. Every field on the site was 14px (some
     13.33px), so this fired on every step of registration and checkout.

     Checkboxes, radios and ranges are excluded: font-size doesn't affect them
     and forcing it changes their box metrics on some engines.

     !important is deliberate and load-bearing. A bare `select` selector (0,0,1)
     loses to any per-page class such as .form-select (0,1,0), and the failure
     is silent — the field just keeps zooming, and nobody catches it in desktop
     review. This rule is the single guarantee that no field on the site drops
     below the iOS zoom threshold, so it has to outrank whatever a page
     stylesheet does. Desktop sizing is untouched; only mobile is pinned.
     Do not drop the !important without re-measuring every form.
     ------------------------------------------------------------------------ */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="hidden"]),
  select,
  textarea {
    font-size: var(--input-size) !important;
  }

  /* ------------------------------------------------------------------------
     Hero headline
     ------------------------------------------------------------------------
     Lives here rather than in hero.css because `.hero h1` (0,1,1) is declared
     in BOTH main.css and pages.css, which load after hero.css — a rule there
     loses on specificity and load order. `.hero .hero-heading` is 0,2,0 and
     this file loads last, so it wins on both counts.

     At --h1-size the headline ran to four lines on a phone and pushed the CTA
     off screen by itself, independently of the vh/dvh problem.
     ------------------------------------------------------------------------ */
  .hero .hero-heading {
    /* --h1-size is 38px below 800px (see the mobile type scale in
       design-system.css). Named here rather than repeated as a literal. */
    font-size: var(--h1-size);
    line-height: 1.1;
    margin-bottom: var(--sp-m);
  }

  .hero p {
    font-size: 16px;
    margin-bottom: var(--sp-ml);
  }

  /* Helper/hint text under fields bottoms out at 11.52px in the auth modal.
     13px is the floor for supporting copy on a phone. */
  .auth-modal__field-note,
  .auth-modal__helper,
  .form-help-text,
  .form-hint {
    font-size: 13px;
  }


  /* ------------------------------------------------------------------------
     .mobile-rail — horizontal card rail
     ------------------------------------------------------------------------
     One stacked column shows one card per screen, which is how the homepage
     sections and the /book simulator picker each came to be over 1,000px of
     scrolling. A rail carries the whole set in roughly one screenful.

     Cards default to 78% of the viewport so the next one always peeks in from
     the right — that sliver is what tells a thumb there is more sideways.
     --compact halves that for small tiles the user is comparing rather than
     reading, where seeing two at once is the point.

     The negative inline margin bleeds the rail to the screen edges while the
     matching padding keeps the first card aligned to its container, so the
     last card can scroll fully into view instead of ending against a hard
     edge. scroll-padding-inline keeps scroll-snap and scrollIntoView() honest
     about that padding.

     Lives here rather than in a page stylesheet because two pages use it and
     it has to outrank whatever grid rules those pages already set.
     ------------------------------------------------------------------------ */
  .mobile-rail {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 78%;
    grid-template-columns: none;
    gap: var(--sp-m);
    max-width: none;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    margin-inline: calc(-1 * var(--sp-m));
    padding-inline: var(--sp-m);
    padding-bottom: var(--sp-xs);
    scroll-padding-inline: var(--sp-m);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .mobile-rail::-webkit-scrollbar {
    display: none;
  }

  .mobile-rail > * {
    scroll-snap-align: start;
  }

  /* Comparison tiles: two and a bit on screen at once. */
  .mobile-rail--compact {
    grid-auto-columns: 46%;
    gap: var(--sp-sm);
  }


  /* ------------------------------------------------------------------------
     Tap targets — 44px minimum
     ------------------------------------------------------------------------
     44px is the WCAG 2.5.5 / iOS HIG target. Footer link rows measured
     17–20px tall with ~4px between neighbours, which makes mis-taps near
     certain. Height comes from the anchor itself (not the li) so the whole
     row is the hit area, not just the glyphs.
     ------------------------------------------------------------------------ */
  .footer-column li {
    margin-bottom: 0;
  }

  .footer-column li > a {
    display: flex;
    align-items: center;
    min-height: 48px;
  }

  /* Opening-hours rows are spans, not links — no hit area needed, so restore
     the spacing the rule above removed. Same specificity as .footer-column li,
     and this file loads later, so it wins. */
  .footer-hours li {
    margin-bottom: var(--sp-sm);
  }

  .footer-social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--tap-min);
    min-height: var(--tap-min);
    border-radius: var(--radius);
  }

  /* Keep the legal links wrapping in a row and give each one a 44px height,
     rather than stacking them one-per-line. Stacking is compliant but costs
     ~176px of footer; wrapping lands the same four targets in two rows (~88px)
     with the inherited 32px horizontal gap keeping neighbours well apart. */
  .footer-legal-links a {
    display: flex;
    align-items: center;
    min-height: var(--tap-min);
  }

  /* Header account/profile button measured 24px wide. */
  .site-header-v2 .action-link {
    min-width: var(--tap-min);
    min-height: var(--tap-min);
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* Mobile nav rows measured 20px tall. */
  .mobile-menu-list > li > a,
  .mobile-submenu > li > a {
    display: flex;
    align-items: center;
    min-height: 48px;
  }


  /* ------------------------------------------------------------------------
     Dashboard and modal controls
     ------------------------------------------------------------------------
     Measured on the signed-in screens at 375x812. All of these are live
     controls that were under the minimum on both axes.
     ------------------------------------------------------------------------ */

  /* Header settings cog, present on every dashboard screen. Was 36x36. */
  .settings-icon-link {
    min-width: var(--tap-min);
    min-height: var(--tap-min);
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* "View All" links in dashboard card headers were 49x21 — the text itself
     was the entire hit area. */
  .card-link {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap-min);
  }

  /* .btn-sm is 40px tall by design on desktop; on a phone the small variant
     still has to be tappable. Scoped to the dashboard so marketing pages keep
     their own sizing. */
  .dashboard-layout .btn-sm {
    min-height: var(--tap-min);
  }

  /* Dialog close buttons: 29x29 on the auth modal, 36x36 on the payment and
     reschedule modals. These are the control people reach for first when a
     dialog opens over the whole screen. */
  .modal-close,
  /* The payment-success dialog's close button does not carry .modal-close,
     so it needs naming separately — it was 40x40. */
  .payment-success-modal__close {
    min-width: var(--tap-min);
    min-height: var(--tap-min);
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* "Forgot Password?" and the account-switch links sit on their own row as
     standalone actions, not inline in a sentence, so the WCAG inline
     exception does not cover them. They measured 23px tall. */
  .auth-modal__link {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap-min);
  }

  /* Reschedule dialog's month navigation was 32x32 and its "Today" shortcut
     59x25 — a date picker is repeated tapping, which is exactly where an
     undersized target costs a mis-tap. */
  .reschedule-calendar__nav-btn,
  .reschedule-calendar__nav button {
    min-width: var(--tap-min);
    min-height: var(--tap-min);
  }

  .reschedule-calendar__today-btn {
    min-height: var(--tap-min);
    padding-inline: var(--sp-sm);
  }

  /* Bottom-nav labels were 11px. The bar itself is the primary navigation for
     signed-in users on a phone, so its labels should not be the smallest text
     on the screen. */
  .bottom-nav-label {
    font-size: 12px;
  }
}
