/* Phone hardening. Loaded LAST on every page, after every other stylesheet, because most
   of what is here has to outrank rules written for a mouse.

   This file fixes the class of bug that only exists on a real handset: a browser doing
   something reasonable for a desktop that reads as broken under a thumb. Nothing here is
   decoration — if a rule does not fix a specific misbehaviour, it does not belong.

   The one thing this file CANNOT do is un-apply a :hover rule, so sticky hover is fixed at
   the source instead: every hover rule in assets/*.css is wrapped in
   @media (hover: hover) and (pointer: fine) by tools/guard_hover.py. Write new hover rules
   inside that guard or the bug comes back one rule at a time. */

/* ── Tap feedback ─────────────────────────────────────────────────────────────────────
   Safari paints a grey box over anything tappable ~300ms after touchstart. It lands after
   our own :active styling and looks like a rendering fault. Killing it means WE now owe
   every control a visible pressed state — see :active below. */
html {
  -webkit-tap-highlight-color: transparent;
  /* Stops the pinch-zoom double-tap wait, which is what "the tap feels laggy" actually is:
     the browser holding the click to see whether a second tap is coming. */
  touch-action: manipulation;
}

/* Pull-to-refresh and rubber-band scroll chaining. On a study page a stray downward swipe
   at scroll-top reloads the page and takes the lesson with it. `none` also stops a
   scrolled-out modal from dragging the page behind it. */
html, body {
  overscroll-behavior: none;
}

/* ── Viewport height ──────────────────────────────────────────────────────────────────
   100vh on iOS is the height with the URL bar HIDDEN, so a 100vh element is taller than
   the visible page and its last row sits under the toolbar. dvh follows the toolbar as it
   collapses. Progressive: browsers without dvh keep the vh rule above.
   These duplicate the five 100vh declarations rather than editing them, so the fallback
   survives — the originals are in styles.css, learning-center.css, dashboard.css,
   dictionary.css and product-tour.css. */
.app-shell { min-height: 100dvh; }

/* ── The notch and the home indicator ─────────────────────────────────────────────────
   Paid for by viewport-fit=cover in partials/page-head.php. Anything pinned to an edge
   has to be pushed clear of it or the OS draws its own furniture on top. */
body {
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

/* ── Form fields ──────────────────────────────────────────────────────────────────────
   iOS zooms the whole page in when a focused field is under 16px, and never zooms back
   out — the reader is left on a page they have to pinch to escape. 16px is the threshold,
   not a preference. Scoped to coarse pointers so the typographic scale is untouched on a
   desktop, where small inputs are fine and this file's job is only the phone. */
@media (pointer: coarse) {
  input, select, textarea {
    font-size: max(16px, 1em);
  }
}

/* ── Text selection on controls ───────────────────────────────────────────────────────
   A long press on a button selects its label and raises the copy/paste bubble instead of
   firing the button. Deliberately NOT applied to prose, readings, cards or anything with
   Chinese in it: selecting a word to look it up is a real thing readers do here, and
   taking that away to tidy up buttons would be a bad trade. */
button, .btn, [role="button"], .choice-key, .btn-key, summary, .pp-opt, .lvl-pill {
  -webkit-user-select: none;
  user-select: none;
}

/* ── Pressed state ────────────────────────────────────────────────────────────────────
   Owed to the reader after removing the tap highlight above, and it has to be instant:
   feedback on pointer-down is the difference between "responsive" and "did that work?".
   No transition — a 150ms ease here is exactly the lag being fixed. */
@media (pointer: coarse) {
  button:active, .btn:active, [role="button"]:active, summary:active {
    transform: scale(0.97);
    opacity: 0.9;
    transition: none;
  }
}

/* ── Horizontal gesture surfaces ──────────────────────────────────────────────────────
   A horizontally-scrolling strip steals vertical drags, so the page stops scrolling while
   a thumb is anywhere over it. pan-y hands the vertical axis back. */
.lvl-strip, .gc-shelf-row, .readings-row, .decks-row, .hg-explorer, .tour-sample,
.dw-list, .course-toc, .rail-line, .rail-steps, .lc-lvstrip, .dash-readrow, .dash-deckrow,
.convo-subnav, [data-scroll-x] {
  touch-action: pan-y;
  -webkit-overflow-scrolling: touch;
}

/* ── Tap targets ──────────────────────────────────────────────────────────────────────
   24px is the WCAG 2.2 AA minimum (2.5.8) and this is the floor, not the target. Inline
   links in prose are exempt: padding them to 24px would visibly space out a paragraph,
   and 2.5.8 exempts text inline in a sentence for that reason. */
@media (pointer: coarse) {
  button, .btn, [role="button"], input[type="checkbox"], input[type="radio"], summary {
    min-height: 24px;
    min-width: 24px;
  }
}
