/* ==========================================================================
   mobile-native.css — "feels like an app" pass for the student portal.
   Loaded from base.html AFTER design.css so it can win specificity fights
   without !important wherever possible.

   Standards applied (researched 2026-09-15):
   - Apple HIG: minimum tap target 44x44pt
   - Material 3 / Android a11y: minimum touch target 48x48dp, 8dp spacing
   - WCAG 2.5.8 (AA): 24x24 minimum; we hold ourselves to the higher bar
   - iOS Safari: inputs with font-size < 16px trigger focus auto-zoom;
     force >= 16px on all form controls
   - 100vh is wrong on mobile (URL bar) — use dvh with vh fallback
   - overscroll-behavior on drawers/scroll traps (app-like rubber-band)
   - tap highlight transparent + :active states for touch feedback
   - env(safe-area-inset-*) for notched devices
   ========================================================================== */

/* ----- 1. Touch feedback: replace blue Android flash with subtle press --- */
html {
  -webkit-tap-highlight-color: transparent;
}
@media (hover: none) and (pointer: coarse) {
  /* Only touch devices get the press overlay — desktop hover stays as-is. */
  a:active,
  button:active,
  [role="button"]:active,
  summary:active,
  .sidebar-link:active,
  .menu-item:active,
  .btn:active {
    filter: brightness(0.96);
  }
  .mobile-bottom-nav__label,
  #mobile-bottom-nav a,
  #mobile-bottom-nav button {
    transition: opacity 120ms ease;
  }
  #mobile-bottom-nav a:active,
  #mobile-bottom-nav button:active {
    opacity: 0.7;
  }
}

/* ----- 2. No iOS input zoom: every form control >= 16px on touch -------- */
@media (max-width: 820px) {
  input[type="text"],
  input[type="search"],
  input[type="email"],
  input[type="number"],
  input[type="tel"],
  input[type="password"],
  input[type="url"],
  input[type="date"],
  input[type="time"],
  input:not([type]),
  select,
  textarea {
    font-size: 16px !important;
  }
  /* but keep the visual size of non-focus-zooming controls consistent */
  input[type="checkbox"],
  input[type="radio"] {
    font-size: revert;
  }
}

/* ----- 3. Tap target floor: interactive controls reach 44px ---------------
   We do NOT resize text links inline with copy (that would wreck reading
   flow); instead we add padding around compact chip/pill/button controls so
   their HIT AREA reaches the floor. Visual size changes are minimal. */
@media (max-width: 820px) {
  .sd-inline-link,
  .sd-skill__cta,
  .sd-mini-pill,
  .sd-weak__item,
  .sd-hero-v2__stat-cta,
  .sd-hero-v2__stat-value--editable,
  .sd-hero-v2__countdown--empty,
  .sd-countdown-date,
  .sq-refine-pill,
  .filter-tab,
  .classes-tab,
  .aim-tab,
  .mp-tab,
  .mp-section-practice-all,
  .profile-edit-btn,
  .profile-timezone-action,
  .current-plan-strip__link,
  .ticket-button,
  .ticket-tab,
  .action-btn,
  .btn-sm,
  .button.secondary,
  .button.sm {
    min-height: 44px;
  }
  /* inline text links: expand hit area without moving layout */
  .sd-inline-link,
  .sd-skill__cta,
  .current-plan-strip__link,
  a.link {
    display: inline-flex;
    align-items: center;
    padding: 10px 6px;
    margin: -10px -6px;
  }
  /* compact buttons that sit inside bars/cards: pad to the floor */
  .sd-btn--sm,
  .sd-btn--text,
  .button.sm,
  .ticket-button,
  .mp-tab,
  .filter-tab,
  .classes-tab {
    padding-top: 10px;
    padding-bottom: 10px;
  }
  /* tiny icon buttons: hit area via padding, glyph stays small */
  .profile-edit-btn,
  .profile-timezone-action,
  .action-btn {
    min-width: 44px;
    min-height: 44px;
    justify-content: center;
    display: inline-flex;
    align-items: center;
  }
  /* chip rows get breathing room so adjacent 44px targets don't overlap */
  .sq-refine-pill,
  .sd-mini-pill {
    min-width: 44px;
  }
  /* details/summary rows (Plans page) */
  summary {
    min-height: 44px;
  }

  /* --- second pass (audit round 2): remaining sub-44 controls ------------- */
  /* hero chips + all sd-btn variants
     NOTE: student-home-dashboard.css (loaded after this sheet) sets
     .sd-btn--sm { min-height:36px }, which beats plain .sd-btn — so this
     rule uses !important to hold the 44px floor. */
  .sd-hero-v2__stat-cta,
  .sd-hero-v2__cta,
  .sd-hero-v2__cta-secondary {
    min-height: 44px !important;
  }
  .sd-btn,
  .sd-btn--sm,
  .sd-btn--text {
    min-height: 44px !important;
  }
  .sd-btn--text,
  .sd-btn--sm {
    padding-top: 10px;
    padding-bottom: 10px;
  }
  /* question-bank filter pills are handled IN drills.css (same-sheet
     !important cascade); sort-reset / action-link handled there too. */
  /* orders row icon buttons */
  .action-btn {
    min-width: 44px !important;
  }
  /* plans back link */
  .plan-strip__back,
  a[href*="plan_select"] {
    display: inline-flex;
    align-items: center;
    min-height: 44px !important;
  }
  /* tickets primary button */
  .ticket-button {
    min-height: 44px !important;
    padding-top: 10px;
    padding-bottom: 10px;
  }
  /* text-link class used across cards */
  a.link {
    min-height: 44px;
  }
  /* form selects inside filter bars sit flush — pad to floor */
  .filter-row select,
  form select,
  .bookings-date-filter select {
    min-height: 44px !important;
  }
  /* bare classless inline links ("← Choose a different exam",
     "Browse Plans", order # links in My Access) — expand hit area without
     moving layout. Scoped to header contexts to avoid blanketing prose. */
  .aim-page-header a:not([class]),
  .aim-page-header p a,
  .page-header a:not([class]),
  .card a:not([class]),
  .current-plan-strip a:not([class]),
  .subscription-page p a:not([class]),
  .section-card a:not([class]) {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 10px 4px;
    margin: -10px -4px;
  }
  /* segmented tabs that sit at 41px after their own padding */
  .plan-tab,
  .ticket-tab,
  .filter-tab,
  .classes-tab {
    min-height: 44px !important;
  }
  /* question-bank toolbar: selects + the tiny dropdown chevron strip */
  .sq-filter-select {
    min-height: 44px !important;
  }
  .dd-tab .dd-tab-chevron {
    width: 32px;
    height: 44px;
    margin-left: -10px;
  }
}

/* ----- 4. Correct viewport height (dvh) for app-shell full-screen pages -- */
@supports (height: 100dvh) {
  .mobile-drawer__scroll {
    max-height: 78dvh;
  }
}

/* ----- 5. Overscroll: drawers and the page itself feel app-like ----------- */
html {
  overscroll-behavior-y: none; /* kill pull-to-refresh on the app shell */
}
#mobile-drawer .mobile-drawer__scroll,
.sidebar-scroll {
  overscroll-behavior: contain; /* scroll trap: no chaining to the page */
}

/* ----- 6. Momentum scrolling on all internal scrollers -------------------- */
.mobile-drawer__scroll,
.sidebar-scroll,
.general-table-scroll,
.mp-tabs,
.sq-quick-filters,
.aim-tabs,
.plan-tabs {
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

/* ----- 7. Sticky bars respect the home indicator / gesture bar ------------
   (Audit flagged fixed bottom bars without safe-area padding.) */
#mobile-bottom-nav {
  padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
}
.pm-action-bar,
.pm-actions,
#combined-action-section {
  padding-bottom: max(12px, env(safe-area-inset-bottom, 0px));
}

/* ----- 8. Topbar respects the notch --------------------------------------- */
.topbar {
  padding-top: env(safe-area-inset-top, 0px);
}

/* ----- 9. Horizontal scrollers get a subtle affordance on touch ---------- */
@media (max-width: 820px) {
  .mp-tabs,
  .sq-quick-filters,
  .aim-tabs,
  .plan-tabs {
    /* hide scrollbars visually but keep them functional */
    scrollbar-width: none;
  }
  .mp-tabs::-webkit-scrollbar,
  .sq-quick-filters::-webkit-scrollbar,
  .aim-tabs::-webkit-scrollbar,
  .plan-tabs::-webkit-scrollbar {
    display: none;
  }
}

/* ----- 9b. Mobile layout: page scrolls, not main.container ---------------
   The base design.css app-shell pattern forces main.container to
   height: calc(100vh - 72px) with overflow-y: auto (so the sidebar can
   stay fixed while content scrolls internally). That desktop pattern is
   wrong on phones:
     - the viewport-sized container leaves a huge empty area below short
       content (the dashboard renders < 500px on a 700px viewport)
     - the fixed bottom-nav overlaps the last 72px of main.container
       because both occupy the same vertical space
     - users expect to scroll the WHOLE page with a finger, not have
       content trapped in an inner scrollable region
   On phones we hand scrolling back to the document so the topbar, the
   content, and the bottom-nav all behave as one continuous page.
   The bottom-nav remains fixed (z-index 1000) and we pad the bottom of
   the page so the last card clears the nav strip. Scoped to the student
   portal and to widths under the desktop sidebar breakpoint (820px)
   because the desktop pattern is correct for layouts with a fixed sidebar.
   The exception is the section-player route: it sets is_section_player,
   which removes hide_header and the app-shell entirely, so none of this
   applies to the exam/practice player views. */
@media (max-width: 820px) {
  body[data-portal="student"] .app-shell.has-sidebar {
    height: auto;
    min-height: 0;
  }
  /* Reassign scroll authority to the document. !important needed because
     design.css sets height + overflow on .app-shell.has-sidebar > .container
     under @media (min-width: 769px) which still wins cascade at 769-820px. */
  body[data-portal="student"] .app-shell.has-sidebar > .container,
  body[data-portal="student"] main.container {
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
    padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px)) !important;
  }
  /* Hide the (now empty) sidebar without breaking the checkbox drawer
     toggle. The sidebar still exists in the DOM for the drawer; we just
     neutralize its height so it doesn't reserve space when "closed".
     Design.css sets `.sidebar { height: 100vh }` at ≤ 768px via the
     `position: fixed` drawer override — without !important that wins the
     cascade for the drawer (intentional), so we only need to neutralize
     the *layout* reservation, not the drawer's own height. The cascade
     `.app-shell.has-sidebar > .sidebar` matches both: in layout it sets
     height: 0 so the app-shell grid doesn't carve out a 280px column on
     phones; in the drawer (when the checkbox is checked and transform
     slides it in) we want height: 100vh again, which the design.css
     `@media (max-width: 768px) .sidebar { height: 100vh }` rule wins via
     the :checked ~ .sidebar selector at equal specificity. We use
     `pointer-events: none` to keep the closed drawer non-clickable. */
  body[data-portal="student"] .app-shell.has-sidebar > .sidebar {
    max-height: 0 !important;
    pointer-events: none;
  }
  /* When the drawer is opened via the checkbox, restore pointer-events
     so the menu items are interactive, and let the design.css height:
     100vh rule re-take effect by clearing our max-height override. */
  html:has(.sidebar-toggle-checkbox:checked) body[data-portal="student"] .app-shell.has-sidebar > .sidebar {
    max-height: none !important;
    pointer-events: auto;
  }
}

/* ----- 10. Disable text-selection callouts on nav chrome ------------------
   Long-pressing nav items shouldn't pop the iOS copy bubble. */
.sidebar,
#mobile-bottom-nav,
#mobile-drawer,
.topbar {
  -webkit-user-select: none;
  user-select: none;
}
/* but form content and lessons remain selectable */
main,
input,
textarea,
select,
.pm-player {
  -webkit-user-select: auto;
  user-select: auto;
}
