/*
 * exolve-mobile.css — mobile-friendliness layer for Exolve.
 *
 * Loaded *after* exolve-m.css so it can override without patching upstream.
 * Verified against exolve-m.css / exolve-m.js at commit 282fc5b (v1.71.1).
 *
 * SCOPE — read this before adding rules.
 *
 * Exolve already has a capable phone mode: it detects phones (touch + UA +
 * viewport <= 500px), sets `.xlv-phone-display`, rearranges the header area,
 * renders its own on-screen keyboard (ExolveKB), and makes the current clue
 * sticky with JS-computed width/min-height/max-height and a negative marginTop
 * so it overlays the grid (see resizeCurrClueAndControls in exolve-m.js).
 *
 * So this file deliberately does NOT touch:
 *   - .xlv-curr-clue position/padding/margin/max-height/width/left
 *   - grid dimensions or .xlv-grid-and-clues-flex direction
 *   - .xlv-controls / .xlv-controls-row structure
 * All of those are computed in JS and inline styles win anyway; overriding
 * them either does nothing or corrupts the layout maths.
 *
 * What it DOES fix are the gaps upstream leaves:
 *   1. tap targets below the 44px accessibility minimum
 *   2. text forced to 8px !important on narrow screens
 *   3. iOS zoom-on-focus from sub-16px inputs
 *   4. no safe-area insets for notched / gesture-nav devices
 *   5. .xlv-wide-box hard-capped at 325px / 480px instead of fluid
 *
 * One integration constraint, easy to break: Exolve only enables phone mode
 * when `frame.offsetTop <= 16`. Any site chrome above the puzzle must be out
 * of normal flow (position: fixed) or phone mode silently switches off. See
 * .xlvm-site-header in site.css and the visTop argument in puzzle.html.j2.
 */

/* ---------------------------------------------------------------------------
 * 1. Fluid width.
 *
 * Upstream pins .xlv-wide-box to max-width 325px (<=325px) and 480px
 * (326-500px). On a 412px Pixel or 430px iPhone Pro Max that wastes a strip
 * down the side and narrows the clue list for no reason.
 * ------------------------------------------------------------------------ */
@media (max-width: 500px) {
  .xlv-wide-box {
    width: 100% !important;
    max-width: 100% !important;
  }

  /* Upstream sets body{margin:4px}. Keep the horizontal breathing room but
     respect the notch and the home-bar. No top padding: it would push
     .xlv-frame past the offsetTop <= 16 threshold and disable phone mode. */
  body {
    margin: 0;
    padding-top: 0;
    padding-left: max(4px, env(safe-area-inset-left));
    padding-right: max(4px, env(safe-area-inset-right));
    padding-bottom: max(4px, env(safe-area-inset-bottom));
    overflow-x: hidden;
  }

  .xlv-frame {
    max-width: 100%;
  }
}

/* ---------------------------------------------------------------------------
 * 2. Tap targets.
 *
 * Upstream shrinks .xlv-button to 9-10px font with 6px/2px padding below
 * 500px — roughly a 20px-tall target. WCAG 2.5.8 and both platform HIGs put
 * the minimum around 44px. This is the biggest single source of misfires.
 *
 * min-height rather than height: the buttons sit in .xlv-controls-row and we
 * must not disturb how that row lays out.
 * ------------------------------------------------------------------------ */
@media (max-width: 500px) {
  .xlv-button {
    /* 34px, not the 44px WCAG figure. These sit in a single dense toolbar
       rather than as isolated targets, and at 44px the six of them wrapped
       onto three ragged rows that dominated the screen above the grid.
       Spacing in the toolbar below keeps them separated enough to hit. */
    font-size: 11px !important;
    min-height: 34px;
    padding: 6px 8px !important;
    border-radius: 8px !important;
    /* Remove the 300ms tap delay and the grey flash on iOS Safari. */
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
  }

  .xlv-nav-button {
    min-width: 34px;
    min-height: 34px;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
  }

  /* Upstream drops these to 10px inside the current clue; they are the
     prev/next clue arrows and are tapped constantly while solving. */
  .xlv-curr-clue .xlv-small-button,
  .xlv-clues-table .xlv-small-button {
    font-size: 13px !important;
    min-width: 32px;
    min-height: 32px;
    touch-action: manipulation;
  }

  /* Clue rows are the primary navigation on a phone. Upstream leaves them at
     text height, which makes a mis-tap likely in a dense clue list. */
  .xlv-clues-table td {
    padding-top: 6px;
    padding-bottom: 6px;
  }
}

/* ---------------------------------------------------------------------------
 * 3. Legibility.
 *
 * Below 325px upstream forces 8px (and 6px for .xlv-saving) with !important.
 * The narrowest phone still in real use is ~320 CSS px (iPhone SE 1st gen),
 * so that rule fires on a live device and is genuinely unreadable.
 * ------------------------------------------------------------------------ */
@media (max-width: 500px) {
  .xlv-anno-text,
  .xlv-status,
  .xlv-solution,
  .xlv-answer,
  .xlv-incluefill,
  .xlv-clue-extraction-slot,
  .xlv-shuffle {
    font-size: 13px !important;
    line-height: 1.45 !important;
  }

  .xlv-saving {
    font-size: 11px !important;
  }

  .xlv-small-print,
  .xlv-small-print *,
  .xlv-copyright,
  .xlv-metadata {
    font-size: 12px !important;
    line-height: 1.45 !important;
  }

  .xlv-preamble,
  .xlv-postscript {
    font-size: 15px;
    line-height: 1.5;
  }

  /* The clue text itself — what you actually read for an hour. */
  .xlv-clues-box .xlv-clue {
    font-size: 15px;
    line-height: 1.5;
  }
}

/* ---------------------------------------------------------------------------
 * 4. iOS zoom-on-focus.
 *
 * Mobile Safari zooms the viewport whenever a focused input renders below
 * 16px. Upstream sets .xlv-input and .xlv-scratchpad to 12px !important, so
 * every tap on the grid or the scratchpad shifts the layout. 16px is the
 * exact threshold. Not media-queried: the behaviour is not width-dependent.
 * ------------------------------------------------------------------------ */
.xlv-input,
.xlv-scratchpad,
.xlv-frame input[type="text"],
.xlv-frame textarea {
  font-size: 16px !important;
}

/* ---------------------------------------------------------------------------
 * 5. Scroll behaviour.
 *
 * Stop the clue list's scroll from chaining to the page (and triggering
 * pull-to-refresh) when it hits its end.
 * ------------------------------------------------------------------------ */
@media (max-width: 500px) {
  .xlv-clues-box {
    overscroll-behavior: contain;
  }
}

/* ---------------------------------------------------------------------------
 * 5b. Telegraph-style phone layout.
 *
 * Controls into a compact toolbar above the grid, current clue docked to the
 * bottom above the on-screen keyboard. Gated on .xlvm-phone, which
 * exolve-mobile.js adds only when Exolve itself decided this is a phone, so
 * the desktop layout is untouched.
 *
 * These rules use !important far more than the rest of this file, and that is
 * deliberate rather than lazy: Exolve computes the current clue's geometry in
 * JS and writes it as *inline* styles (width, left, marginTop, minHeight,
 * maxHeight in resizeCurrClueAndControls). An author !important declaration is
 * the only thing that outranks an inline one, so moving this element is not
 * possible without it. The trade-off is that this section is the most likely
 * thing in the repo to need attention after an Exolve upgrade.
 * ------------------------------------------------------------------------ */
@media (max-width: 500px) {
  /* --- toolbar above the grid --- */

  /* .xlv-grid-panel holds the grid then .xlv-controls-etc. Flex + order lifts
     the controls above the grid without moving anything in the DOM, so
     Exolve's element references all stay valid. */
  .xlvm-phone .xlv-grid-panel {
    display: flex;
    flex-direction: column;
  }

  .xlvm-phone .xlv-controls-etc {
    order: -1;
    padding: 0 !important;
  }

  .xlvm-phone .xlv-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 4px 0 6px 0;
    border-bottom: 1px solid rgba(128, 128, 128, 0.35);
    margin-bottom: 6px;
  }

  /* Upstream's 6px vertical margin on each row is what made the buttons read
     as three separate stacked blocks rather than one toolbar. */
  .xlvm-phone .xlv-controls-row {
    display: contents !important;
    margin: 0 !important;
  }

  /* Back link, injected into the controls row by exolve-mobile.js. */
  .xlvm-back-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 34px;
    min-height: 34px;
    margin-right: auto;
    border-radius: 8px;
    font-size: 15px;
    text-decoration: none;
    color: inherit;
    opacity: 0.75;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
  }

  .xlvm-back-link:hover,
  .xlvm-back-link:focus-visible {
    opacity: 1;
  }

  /* Hidden on desktop: there the site header provides this. */
  .xlvm-back-link {
    display: none;
  }

  .xlvm-phone .xlvm-back-link {
    display: inline-flex;
  }

  /* --- current clue docked to the bottom --- */

  .xlvm-phone .xlv-curr-clue {
    position: fixed !important;
    top: auto !important;
    /* --xlvm-kb-h is published by exolve-mobile.js from the live height of
       .xlv-phone-kb, which is fixed to the bottom and changes size with the
       viewport and the "More" row. Falls back to 0 before the first
       measurement, or if the keyboard never appears. */
    bottom: var(--xlvm-kb-h, 0px) !important;
    left: 0 !important;
    right: 0 !important;
    width: 100% !important;
    /* Cancels the negative marginTop Exolve sets to overlay the sticky clue
       on the grid; at the bottom of the screen that would hide it. */
    margin: 0 !important;
    min-height: 0 !important;
    max-height: 38vh !important;
    padding: 10px 44px !important;
    z-index: 4 !important;
    box-sizing: border-box !important;
    text-align: center !important;
    background: var(--xlv-background, #fff);
    border-top: 1px solid rgba(128, 128, 128, 0.4);
    box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.18);
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .xlvm-phone .xlv-curr-clue-inner {
    padding: 0 !important;
    font-size: 15px !important;
    line-height: 1.45 !important;
  }

  /* Clue navigation, moved in here by exolve-mobile.js. Absolutely placed at
     the bar's edges, which is why the bar carries 44px of side padding. */
  .xlvm-phone .xlv-curr-clue .xlvm-clue-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 36px;
    height: 36px;
    min-width: 36px;
    min-height: 36px;
    padding: 0 !important;
    border-radius: 50% !important;
    font-size: 14px !important;
    opacity: 0.9;
  }

  .xlvm-phone .xlv-curr-clue .xlvm-clue-nav-prev { left: 6px; }
  .xlvm-phone .xlv-curr-clue .xlvm-clue-nav-next { right: 6px; }

  /* Reserved by Exolve for the current clue when it is sticky at the top.
     The clue now lives at the bottom, so this is just dead space above the
     grid. The !important beats the height Exolve injects in a <style>. */
  .xlvm-phone .xlv-clear-area {
    height: 0 !important;
    display: none;
  }

  /* Segmented pairs built by groupButtons(). Zero gap plus flattened inner
     corners is what makes two buttons read as one control. */
  .xlvm-phone .xlvm-btn-group {
    display: inline-flex;
    align-items: stretch;
  }

  .xlvm-phone .xlvm-btn-lead {
    border-top-right-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
    margin-right: 0 !important;
  }

  .xlvm-phone .xlvm-btn-trail {
    border-top-left-radius: 0 !important;
    border-bottom-left-radius: 0 !important;
    margin-left: 0 !important;
    border-left: 1px solid rgba(255, 255, 255, 0.35) !important;
    opacity: 0.92;
  }

  /* Moved below the grid by demoteChrome(); they are the last children of
     .xlv-grid-panel, and the flex order keeps them there. */
  .xlvm-phone .xlv-status,
  .xlvm-phone .xlv-small-print {
    order: 3;
    text-align: center;
  }

  .xlvm-phone .xlv-grid-parent-centerer {
    order: 1;
  }

  /* Stop the docked bar covering the end of the clue list. Generous because
     the bar grows with a long clue. */
  .xlvm-phone .xlv-clues-panel:last-child {
    padding-bottom: 45vh;
  }
}

/* ---------------------------------------------------------------------------
 * 7. Print. Never print our own site chrome.
 * ------------------------------------------------------------------------ */
@media print {
  .xlvm-site-header,
  .xlvm-site-footer {
    display: none !important;
  }
}
