/* ==========================================================================
   responsive-base.css — Phase 2 of docs/RESPONSIVE_APP_UI_PLAN.md
   Viewport, overflow and touch correctness.

   Loaded AFTER style.css on purpose. The theme stylesheet carries 594
   !important declarations, so correcting it from an earlier file would mean
   out-specifying all of them; loading later lets ordinary selectors win and
   keeps !important here to the few places that genuinely need it.

   This file changes behaviour, not visual design. Anything that alters layout
   or composition belongs in Phase 3/4, not here.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Viewport units
   9 rules in style.css use 100vh. On mobile that is the tallest possible
   viewport, so content jumps as the browser chrome shows and hides. dvh
   tracks the visible area instead. The vh line stays first as the fallback
   for browsers without dvh.
   -------------------------------------------------------------------------- */
.site {
  min-height: 100vh;
  min-height: 100dvh;
}

/* --------------------------------------------------------------------------
   2. Horizontal overflow guard
   overflow-x on <body> alone is unreliable while position:sticky is in use;
   applying it to both elements is what actually contains a stray wide child.
   This is a safety net, not a substitute for fixing real causes - the audit
   script in the scratchpad reports which elements exceed the viewport.
   -------------------------------------------------------------------------- */
html,
body {
  max-width: 100%;
  overflow-x: hidden;
}

/* Grid and flex items default to min-width:auto, which means they refuse to
   shrink below their content's intrinsic width and burst out of their track
   instead. Measured at 360px: .hero-content rendered 361px inside a 328px
   .hero-inner, and .ffext-left 350px inside a 312px .ffext-grid.

   min-width:0 is the standard fix - it lets the item shrink to its track.
   max-width:100% does NOT help here, because the item's containing block is
   the track it is already overflowing.

   Scoped to phones and tablets: on desktop these tracks are wide enough that
   the intrinsic width never binds, and the overflow-x guard above would only
   hide the symptom anyway. */
@media (max-width: 1199px) {
  .hero-inner > *,
  .ffext-grid > *,
  .home-container > *,
  .contact-grid > *,
  .training-grid > *,
  .fs-grid > *,
  .ts-grid > *,
  .vbs-grid > *,
  .wfext-grid > *,
  .contact-main-inner > *,
  .privacy-content-inner > * {
    min-width: 0;
  }

  /* Same trap in a flex context: .hero-input is flex:1 but keeps its default
     min-width:auto, so at 360px it holds its intrinsic width and pushes the
     Search button 16px off the right edge. */
  .hero-search form > .hero-input,
  .home-newsletter-form > input,
  .about-newsletter-form > input,
  .shortcuts-search > input {
    min-width: 0;
  }

  /* excelman-qa ships flex:1 1 320px on its search box, so the 320px basis
     plus the Search button overflows a 360px phone. Corrected here rather
     than in the plugin to keep this work in one place; the proper pass over
     that plugin's 5 shortcode surfaces is Phase 5. */
  .em-qa-searchbox {
    flex-basis: auto;
    min-width: 0;
    flex-wrap: wrap;
  }

  .em-qa-searchbox > input,
  .em-qa-searchbox > .em-qa-input {
    min-width: 0;
    flex: 1 1 auto;
  }
}

/* Media should never be the thing that widens a page. */
img,
video,
canvas,
svg,
iframe,
embed,
object {
  max-width: 100%;
}

img,
video {
  height: auto;
}

/* Long unbroken strings (URLs, formula names, code) are a common overflow
   source on narrow phones. */
p,
li,
dd,
dt,
h1, h2, h3, h4, h5, h6,
blockquote,
figcaption,
.entry-content,
.page-prose {
  overflow-wrap: break-word;
  word-wrap: break-word;
}

pre,
code,
kbd,
samp {
  overflow-wrap: break-word;
  white-space: pre-wrap;
}

pre {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* --------------------------------------------------------------------------
   3. Tables
   A wide table should scroll inside its own box rather than widening the
   document. .table-scroll is the wrapper added in templates; the bare-table
   rule catches tables in editor content that have no wrapper.
   -------------------------------------------------------------------------- */
.table-scroll {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}

@media (max-width: 767px) {
  .entry-content > table,
  .page-prose > table,
  .em-prose > table {
    display: block;
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* --------------------------------------------------------------------------
   4. Touch targets
   The audit found controls at padding:4px 10px and 6px 8px, well under the
   44px Apple HIG / Material minimum. Scoped to phones and tablets: on desktop
   with a mouse, denser controls are correct and enlarging them would be a
   visual regression.

   inline-flex + centring rather than a bare min-height, because min-height on
   an inline element does nothing.
   -------------------------------------------------------------------------- */
@media (max-width: 1199px) {
  /* Sizing only - deliberately no `display` here. An earlier version of this
     rule set display:inline-flex, which resurrected .header-signup-btn on
     phones after style.css line 649 hides it below 960px, and the resurrected
     button then pushed .header-actions 125px past the right edge. Setting a
     display value on a control the theme may be hiding is what caused it, so
     these rules now only ever grow a box that is already visible. */
  .header-menu a,
  .header-mobile-actions a,
  .mobile-action-link,
  .mobile-login-link,
  .mobile-signup-btn,
  .header-login-link,
  .header-signup-btn,
  .header-cart-btn,
  .header-user-trigger,
  .header-mobile-toggle,
  .header-user-dropdown a {
    min-height: var(--tap-min);
    align-items: center;
  }

  /* Buttons and button-like links across the theme and its plugins.
     Deliberately a list of real controls rather than a blanket rule on <a>:
     a headless pass at 360px found that most sub-44px links are inline text
     links inside prose (author names, "read more", footer links), where
     forcing a 44px box would wreck line spacing without making anything more
     tappable. Measured offenders are named explicitly below. */
  .btn,
  .btn-cta,
  button:not(.unstyled),
  input[type="submit"],
  input[type="button"],
  [role="button"],
  .wp-block-button__link,
  .woocommerce a.button,
  .woocommerce button.button,
  .woocommerce input.button,
  .tutor-btn,
  .em-btn,
  .em-qa-btn,
  .em-tyk-btn,
  /* measured at 32px - course-card bookmark control */
  .save-bookmark-btn,
  /* measured at 38-40px - course tab navigation */
  .tutor-nav-link,
  /* measured at 23px - blog pagination, a primary navigation control */
  .page-numbers,
  .nav-links a,
  /* measured at 34px - author avatar link on course cards */
  .em-course-author-avatar {
    min-height: var(--tap-min);
  }

  /* Pagination and avatars also need width, being roughly square targets.
     :not([hidden]) and the display:none guard keep this from resurrecting a
     control the theme or a plugin has deliberately hidden - the mistake that
     broke the header, documented above. */
  .page-numbers:not([hidden]),
  .em-course-author-avatar:not([hidden]) {
    min-width: var(--tap-min);
    align-items: center;
    justify-content: center;
  }

  a.page-numbers:not([hidden]),
  span.page-numbers:not([hidden]) {
    display: inline-flex;
  }

  /* Tutor's outline buttons ship at 36-40px and are the primary action on
     every course card, so they are the most-tapped control on /courses/.
     Tutor's own rule is !important, hence the match here. */
  .tutor-btn.tutor-btn-outline-primary,
  .tutor-btn.tutor-btn-primary,
  .tutor-btn.tutor-btn-secondary {
    min-height: var(--tap-min) !important;
  }

  /* Tutor quiz/lesson checkboxes render at 24px. These are answer controls in
     the quiz flow, where a mis-tap costs the learner a question, so the hit
     area is grown with padding offset by a negative margin. The box stays
     visually 24px; only the tappable region grows. */
  .tutor-form-check-input {
    min-width: 24px;
    min-height: 24px;
    padding: 10px;
    margin: -10px;
    box-sizing: content-box;
  }

  /* The label is the larger, more natural target for these - make sure it is
     comfortably tappable too. */
  .tutor-form-check label,
  .tutor-form-check-label {
    min-height: var(--tap-min);
    display: inline-flex;
    align-items: center;
  }

  /* The helper-bot greeting dismiss button. The plugin sets an explicit
     width/height of 20px, which beats min-width/min-height, so the hit area is
     grown with padding and pulled back with an equal negative margin - the box
     gets bigger without the icon moving or the greeting bubble reflowing.

     No `display` here: the greeting is dismissible, and forcing a display
     value would bring it back after the visitor closed it. */
  .emhb-greet-close {
    padding: 12px;
    margin: -12px;
    box-sizing: content-box;
  }

  /* The chatbot composer is the single control on that screen. */
  .em-chat-input,
  .em-chat-composer textarea,
  #em-chat-input {
    min-height: var(--tap-min);
  }

  /* Icon-only controls need width as well as height to be thumb-safe. */
  .header-mobile-toggle,
  .header-cart-btn,
  .header-search-close,
  .save-bookmark-btn,
  .em-icon-btn {
    min-width: var(--tap-min);
    justify-content: center;
  }

  /* Form controls. Select and input cannot use inline-flex, so they take a
     plain min-height, which works because they are replaced elements. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
  select,
  textarea {
    min-height: var(--tap-min);
  }

  /* Checkboxes and radios get a larger hit area without changing their box. */
  input[type="checkbox"],
  input[type="radio"] {
    min-width: 20px;
    min-height: 20px;
  }
}

/* --------------------------------------------------------------------------
   5. iOS zoom-on-focus
   Safari on iOS zooms the page when a focused field's font-size is under 16px,
   which instantly reads as "web page, not app". 16px is the floor; the site's
   own larger sizes still apply.

   max-width guard keeps desktop typography untouched. !important is warranted
   here: many field sizes in style.css are themselves !important.
   -------------------------------------------------------------------------- */
@media (max-width: 1199px) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select,
  textarea {
    font-size: max(16px, var(--fs-base)) !important;
  }
}

/* --------------------------------------------------------------------------
   6. Native-feeling touch behaviour
   -------------------------------------------------------------------------- */
a,
button,
[role="button"],
input,
select,
textarea,
label,
summary {
  -webkit-tap-highlight-color: transparent;
}

/* A pressed state is what replaces the grey flash removed above; without one,
   taps feel unresponsive. Pointer-coarse only, so mouse hover is unaffected. */
@media (pointer: coarse) {
  a:active,
  button:active,
  [role="button"]:active,
  .btn:active,
  .btn-cta:active {
    opacity: .72;
    transition: opacity var(--dur-fast) var(--ease-standard);
  }
}

/* Vertical scroll containers keep momentum and stop scroll chaining to the
   page behind them. */
.table-scroll,
.em-scroll-x,
.course-carousel-wrapper {
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

/* Horizontal carousels should not fight the browser's vertical scroll. */
.course-carousel-wrapper {
  touch-action: pan-x pan-y;
}

/* --------------------------------------------------------------------------
   7. Safe areas
   env() is live now that the viewport meta carries viewport-fit=cover.
   Without this the fixed pill header sits under the notch / Dynamic Island.
   -------------------------------------------------------------------------- */
.header-float-wrap {
  padding-top: calc(14px + var(--safe-top));
  padding-left: calc(24px + var(--safe-left));
  padding-right: calc(24px + var(--safe-right));
}

@media (max-width: 767px) {
  .header-float-wrap {
    padding-left: calc(var(--gutter) + var(--safe-left));
    padding-right: calc(var(--gutter) + var(--safe-right));
  }
}

/* Anything pinned to the bottom must clear the iOS home indicator. */
.site-footer {
  padding-bottom: calc(18px + var(--safe-bottom));
}

/* --------------------------------------------------------------------------
   8. Motion
   style.css honours prefers-reduced-motion in 5 places. This extends it to
   everything, including third-party and inline animation, which is the only
   way to cover the 11-15 inline <style> blocks each page emits.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --------------------------------------------------------------------------
   9. Focus visibility
   Removing the tap highlight above must not cost keyboard users their focus
   ring. :focus-visible shows it for keyboard navigation only.
   -------------------------------------------------------------------------- */
:focus-visible {
  outline: 2px solid var(--accent, #388E3C);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* --------------------------------------------------------------------------
   10. Small-phone gutters
   The theme's smallest breakpoint was 380px, so 360px devices - the most
   common width in the Indian Android market - fell into an undesigned gap.
   -------------------------------------------------------------------------- */
@media (max-width: 380px) {
  .site-main {
    padding-left: var(--gutter);
    padding-right: var(--gutter);
  }
}
