/* =============================================================================
   PD Cash — responsive / cross-browser fixes, 2026-08-23
   -----------------------------------------------------------------------------
   Companion to assets/pd-polish-20260823.css (contrast, mobile body copy, tap
   targets, footer motion, safe-area, print). This file carries only the five
   defects that layer does not cover. Loaded last on all 21 public pages.

   Additive and presentation-only. Desktop (>=1280px) rendering is unchanged:
   every rule is behind (max-width: 768px), (hover: none), (min-width: 769px)
   for a mobile-only element, or a @supports/JS-set class.
   ========================================================================== */

/* ---- 1. iOS Safari focus zoom -----------------------------------------------
   Safari zooms the viewport when a focused control computes under 16px. The
   bundle sets 16px in `.contact-route-form-grid input,...` and then 15px in
   `.contact-route-form input,...` — equal specificity (0,1,1), later wins, so
   15px shipped and every /contact field zoomed on tap. Restored on touch
   widths only; desktop keeps its 15px. */
@media (max-width: 768px) {
  .contact-route-form input,
  .contact-route-form select,
  .contact-route-form textarea,
  .contact-route-form-grid input,
  .contact-route-form-grid select,
  .contact-route-form-grid textarea,
  .contact-form input,
  .contact-form textarea,
  .hero-signup-input {
    font-size: 16px;
  }
}

/* ---- 2. Sticky :hover on touch ----------------------------------------------
   The bundle has an @media(hover:none) block that clears the hover lifts, but
   later rules in the same file re-add `transform` to .button, .feature-card,
   .plan-card, .numbered-flow li, .contact-tab and .text-link svg. Later wins,
   so after a tap the card stayed lifted until another tap landed elsewhere.
   Re-asserted here, after both stylesheets. */
@media (hover: none) {
  .button:hover,
  .feature-card:hover,
  .plan-card:hover,
  .path-card:hover,
  .who-card:hover,
  .integration-card:hover,
  .trust-duo > div:hover,
  .numbered-flow li:hover,
  .works-method:hover,
  .contact-tab:hover {
    transform: none;
  }
  .feature-card:hover .feature-icon,
  .path-card:hover .feature-icon,
  .who-card:hover .feature-icon,
  .integration-card:hover .integration-icon {
    transform: none;
  }
  .text-link:hover svg { transform: none; }
}

/* ---- 3. Mobile drawer leaking onto desktop ----------------------------------
   public-shell-*.js opens the drawer with an inline `display:block`, which
   outranks the site's own >=1021px rule. Opening the menu at phone width and then
   widening the window — or rotating a tablet to landscape — painted the raw
   drawer links across the desktop header and left html{overflow:hidden} on,
   so the page could not be scrolled. pd-responsive-fixes JS closes the drawer
   on the breakpoint change; this rule is the no-JS guarantee.
   1021px, not 769px: the site keeps the drawer (and hides .desktop-nav) all
   the way to 1020px, so a 769px guard would leave 769-1020px with a visible
   hamburger that opens nothing. */
@media (min-width: 1021px) {
  .site-header .mobile-nav,
  #mobile-navigation { display: none !important; }
}

/* ---- 4. Notch clearance for the drawer --------------------------------------
   pd-polish gives body a safe-area padding-inline, but the drawer is
   position:fixed and so is viewport-relative — body padding cannot reach it.
   In landscape on a notched iPhone its links sat under the sensor housing.
   env() resolves to 0 elsewhere, so nothing else moves. */
@supports (padding: max(0px)) {
  .mobile-nav {
    padding-left: max(24px, env(safe-area-inset-left));
    padding-right: max(24px, env(safe-area-inset-right));
  }
}

/* ---- 5. iOS dynamic viewport ------------------------------------------------
   body already had the dvh fallback; the shell wrapper was left on 100vh, so
   it kept the URL-bar-inclusive height as the bar collapsed. */
@supports (min-height: 100dvh) {
  .site-shell { min-height: 100dvh; }
}

/* ---- 6. Code panes: scroll affordance + keyboard access ---------------------
   Request/response samples on /cash-app-api and /cash-app-payment-api scroll
   horizontally on narrow screens, but the line just stopped at the pane edge
   with nothing to suggest more text. The overflowing edge now fades — the
   same treatment the dashboard mock's nav already uses — and the pane becomes
   a focusable region so the keyboard can reach it. Classes come from
   pd-responsive-fixes JS and appear only when the content actually overflows,
   so panes that fit are untouched. */
.code-sample pre.pd-scrollable {
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 30px), transparent 100%);
  mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 30px), transparent 100%);
}
.code-sample pre.pd-scrollable.pd-scroll-mid {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 30px, #000 calc(100% - 30px), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 30px, #000 calc(100% - 30px), transparent 100%);
}
.code-sample pre.pd-scrollable.pd-scroll-end {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 30px, #000 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 30px, #000 100%);
}
.code-sample pre.pd-scrollable:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: -2px;
  border-radius: 8px;
}

/* ---- 7. Overlapping hit areas from the polish layer -------------------------
   assets/pd-polish-20260823b.css enlarges tap targets with

     .legal-toc a::before, .legal-row a::before, .site-footer a::before
       { position:absolute; left:0; right:0; top:-12px; bottom:-12px }

   but those links are stacked with a 0px gap, so every overlay reaches 12px
   into its neighbour. Because the later link in DOM order wins the hit test,
   the bottom ~12px of each link activates the NEXT one. Measured live:
     - footer nav links: 44px tall, bottom 12-13px opens the next link
       (both 375px and 1280px, all 21 pages)
     - legal-row links:  44px tall, bottom 12px opens the next link
     - legal TOC rows:   30px tall, bottom 12-13px jumps to the next section
     - inline prose links inside the footer strips (e.g. "Terms" in the
       compliance strip) claim a ~12px band above and below their text box,
       so clicks on the neighbouring lines of the paragraph navigate away
   The targets were already >=44px (nav/legal-row) or >=24px (TOC), so the
   expansion buys nothing and costs a mis-navigation. Collapse the overlay to
   the link's own box; hover, focus and layout are unaffected.
   Remove this block if the polish layer stops shipping that rule. */
.legal-toc a::before,
.legal-row a::before,
.site-footer a::before {
  top: 0;
  bottom: 0;
}

/* ---- 8. Anchor targets landing a third of the way down the phone ------------
   Two offsets stack on every in-page jump below 1024px: html carries
   `scroll-padding-top:80px` (56px..68px on smaller ranges, and pd-polish
   raises it further with env(safe-area-inset-top)) AND the targets carry their
   own `scroll-margin-top` -- 82px on section[id]/form[id], 88px on
   #contact-form, 96px on .legal-container headings. Measured live at 600px:
   /#pricing leaves the section 162px down the viewport and its <h2> at 237px;
   /terms#security-deposits leaves the heading 176px down. That gap is filled
   with the PREVIOUS section, so the reader lands looking at the wrong content.
   46 links point at /#pricing, 23 at terms#security-deposits and 21 at
   /contact#contact-form across the 21 pages.
   Keep scroll-padding-top as the single source of truth and zero the
   per-target margins in the same range. .legal-intro-callout is listed
   explicitly: pd-polish gives it 0-2-1 specificity, which a bare
   `.legal-container h2` rule would lose to. Desktop is untouched -- every
   rule involved lives inside a max-width query. */
@media (max-width: 1023.98px) {
  section[id],
  form[id],
  #contact-form,
  #onboarding-form,
  .contact-route-form-section,
  .plan-comparison-section,
  .legal-container h2,
  .legal-container h3,
  .legal-container h2.legal-intro-callout {
    scroll-margin-top: 0;
  }
}

/* ---- 9. Focus ring clipped inside the legal table of contents ---------------
   `.legal-toc ol` is a scroll container (`overflow-y:auto` computes
   `overflow-x:auto` too) and `.legal-toc a` carries `margin-left:-1px`, so the
   2px ring at `outline-offset:2px` starts ~5px outside the scrollport and both
   vertical strokes are clipped away. Keyboard users on the 7 legal pages above
   1000px get a ring with no sides. An inset ring cannot be clipped.
   Desktop-visible, but it is a desktop defect, so the change is in scope. */
.legal-toc a:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--green);
}

/* ---- 10. Print: content that never reaches the paper ------------------------
   pd-polish adds a print treatment for legal pages, but three pieces of
   content vanish from every printed copy:
   1. .site-footer .compliance-strip is display:none in print. That strip
      carries the orchestrator/not-a-PSP disclosure and the security-deposit
      terms pointer. A printed Terms or AML page should not lose it.
   2. FAQ answers use the hidden attribute (the disclosure pattern), so a
      printed page shows the questions with no answers at all.
   3. The 7th+ FAQ item is display:none until View all is clicked, so it never
      prints either.
   Screen rendering is untouched: everything here is inside @media print. */
@media print {
  .site-footer .compliance-strip {
    display: block !important;
    color: #111 !important;
  }
  .site-footer .compliance-strip a {
    color: #003d80 !important;
    text-decoration: underline;
  }
  .faq-list .faq-item {
    display: block !important;
  }
  .faq-item > p[hidden] {
    display: block !important;
  }
  .faq-item button svg {
    display: none !important;
  }
  .checkout-details[hidden] {
    display: block !important;
  }
}

/* ---- 11. Forced colors (Windows High Contrast) ------------------------------
   Section 9 replaces the clipped TOC outline with an inset box-shadow, but
   forced-colors mode drops box-shadow entirely, which would leave those links
   with no focus indicator at all. Put a system-colour outline back for that
   mode only; outline-offset is negative so it still cannot be clipped by the
   TOC scroll container. */
@media (forced-colors: active) {
  .legal-toc a:focus-visible {
    outline: 2px solid CanvasText;
    outline-offset: -2px;
  }
}


/* ---- 12. Current-theme viewport system (2026-08-25) -------------------------
   Fluid sizing and resilient layout guards for the current Tailwind public
   shell. The black/green art direction, 1280px reading width, and existing
   component hierarchy are deliberately preserved. */
:root {
  --pd-compact-gutter: 1rem;
  --pd-touch-target: 44px;
  --pd-pointer-target: 28px;
  --pd-wide-display-min: 3.9rem;
  --pd-wide-display-max: 4.25rem;
}

html {
  max-width: 100%;
  overflow-x: clip;
}

@supports not (overflow: clip) {
  html { overflow-x: hidden; }
}

main :is(h1, h2) {
  text-wrap: balance;
}

main :is(p, li, dd) {
  text-wrap: pretty;
}

main :is(h1, h2, h3, p, li, dd) {
  overflow-wrap: break-word;
}

main :is(.grid, .flex) > * {
  min-width: 0;
}

/* A visible but compact scrollbar should not consume 10px of a phone screen. */
@media (max-width: 1023.98px) {
  html { scrollbar-width: thin; }

  ::-webkit-scrollbar {
    width: 4px;
    height: 4px;
  }

  main input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  main select,
  main textarea {
    font-size: 16px;
  }

  footer nav :is(a, button) {
    display: inline-flex;
    min-height: var(--pd-touch-target);
    max-width: 100%;
    align-items: center;
  }
}

/* 320-359px: reclaim card/gutter space without shrinking readable body text. */
@media (max-width: 359.98px) {
  main > section > [class~="mx-auto"][class*="px-"],
  footer > [class~="relative"][class~="mx-auto"] {
    padding-inline: var(--pd-compact-gutter);
  }

  main h1.display {
    font-size: clamp(2rem, 10vw, 2.15rem);
    line-height: 1;
  }

  main .card[class~="p-7"],
  main .card[class~="p-8"],
  main .auth-card[class~="p-7"] {
    padding: 1.25rem;
  }

  #navShell {
    padding-inline: 1rem;
  }
}

/* Compact laptops: keep the full desktop navigation comfortably separated. */
@media (min-width: 1024px) and (max-width: 1180px) {
  header [class~="gap-8"] {
    gap: 1.25rem;
  }

  #navShell {
    padding-inline: 1rem;
  }
}

@media (min-width: 1024px) {
  header .nav-link,
  footer nav :is(a, button) {
    display: inline-flex;
    min-height: var(--pd-pointer-target);
    align-items: center;
  }
}

/* Short laptop viewports retain the CTA while avoiding a wasteful top gap. */
@media (min-width: 1024px) and (max-height: 720px) {
  main > section:first-child {
    padding-top: 7.5rem;
  }
}

/* Large desktops gain hierarchy, not wider reading lines. */
@media (min-width: 1600px) {
  main h1.display {
    font-size: clamp(
      var(--pd-wide-display-min),
      3.2vw,
      var(--pd-wide-display-max)
    );
    line-height: .98;
  }
}


/* ---- 13. Contextual interaction sizing -------------------------------------
   Standalone links and demo controls need a real hit area; prose links retain
   the WCAG inline-link exception and keep natural line flow. */
@media (max-width: 1023.98px) {
  main .card h3 > a,
  main a[class*="font-bold"],
  #ckQrToggle {
    display: inline-flex;
    min-height: var(--pd-touch-target);
    align-items: center;
  }

  label:has(> #scSearch) {
    min-height: var(--pd-touch-target);
  }
}

@media (min-width: 1024px) {
  main .card h3 > a,
  main a.inline-flex,
  main a[class*="font-bold"],
  #ckQrToggle,
  .footer-contact {
    display: inline-flex;
    min-height: var(--pd-pointer-target);
    align-items: center;
  }
}

@media (max-width: 1023.98px) { main :is(select, textarea).auth-input { font-size: 16px; } }

@media (min-width: 1600px) { main h1.display[class*="xl:text-[3.9rem]"] { font-size: 3.9rem; line-height: 1; } }
