/* ════════════════════════════════════════════════════════════════════════
 * tw-metro-mobile.css - the Studio's phone column count.
 *
 * Andrew, 2026-08-22: "I think we make it genuinely mobile friendly. these are
 * long term surfaces."
 *
 * ── WHY THIS IS A LAYER AND NOT A PAGE FIX ──────────────────────────────
 * The bible already rules it: "One single design language for mobile and
 * desktop... This retires the question of whether mobile is a separate
 * treatment - it is the same language at a different column count." So this
 * adds no new look. It supplies the column count, the touch floor and the
 * wrapping rules the language always implied, in the kit's own vocabulary, so
 * every Studio surface gets them by loading one file.
 *
 * ⚠ SCOPE. This is for STUDIO surfaces - the mechanic banks and their kin.
 *   The EIGHT PLAYER surfaces have their own locked treatment in
 *   tw-mobile-input.css. The EDITOR surfaces (Slides, Buzzer) have their
 *   mobile work deferred to 1.0N by that file's header and get it in their
 *   rebuild; do not quietly pull them in here.
 *
 * ── WHAT WAS ACTUALLY WRONG, MEASURED AT 375px ──────────────────────────
 * The page scrolled sideways: document 419px against a 375px viewport, one
 * element reaching 458px. The cause was NOT structural - not one container on
 * the page asserts a fixed min-width. It was exactly two elements:
 *
 *   · the "Parameters" tab, in a .tabbar that is flex/nowrap with four tabs;
 *   · the answer "IBM (International Business Machines)", white-space:nowrap
 *     at 289px inside a flex/nowrap parent.
 *
 * Everything else already reflowed. That is why this file is short: the layout
 * was fluid and two rules stopped it flowing.
 * ════════════════════════════════════════════════════════════════════════ */

@media (max-width: 760px) {

  /* ── 1. NOTHING SCROLLS SIDEWAYS ──────────────────────────────────────
     A row of controls that cannot wrap will always win against a viewport.
     Wrapping is the fix; overflow-x:hidden would only hide the symptom and
     take the content with it. */
  .tabbar,
  .m-row,
  .m-tile--row,
  .legend,
  .m-counts,
  .doors {
    flex-wrap: wrap;
  }
  /* ⚠ THIS LIST IS MEASURED, NOT GUESSED, and it is deliberately a list rather
     than a blanket `[class] { flex-wrap: wrap }` - some rows are meant to hold
     their line. .legend and .m-counts were added after the first deployed run
     still measured 394 against 375 on /studio/mechanic: the legend chips
     ("13 Regulars / 19 Occasional / 46 Never seated") sat on one unwrapped
     line at 378px inside a 343px column. Nothing reported as overflowing
     because the offender was a CONTAINER, not a text node.
     ★ The gate is what keeps this list honest - it measures the rendered page,
       so a row that starts overflowing later shows up as a red, not as a
       silently sideways-scrolling phone. */

  /* Long unbroken strings - a full company name, a URL, a file path - must be
     allowed to break rather than push the page. `anywhere` rather than
     `break-all` so ordinary prose still breaks at spaces. */
  .m-tile, .m-card, .answer, .crumb, .m-hint, .m-data, td, th {
    overflow-wrap: anywhere;
  }
  .answer, .answer > * { white-space: normal; }

  /* ── 2. THE TOUCH FLOOR ───────────────────────────────────────────────
     44px is the accessibility minimum and the number the Capture tool already
     works to. The VISUAL size is untouched: the target grows by padding, so
     nothing in the design gets bigger and everything gets hittable. */
  .tabbar button, .tabbar a,
  .m-btn, .m-tile, .doors a, nav a, .crumb a,
  summary {          /* a <details> disclosure is a control; measured at 31px */
    min-height: 44px;
  }
  summary { display: flex; align-items: center; }
  .tabbar button, .tabbar a, .m-btn, .doors a, nav a {
    display: inline-flex;
    align-items: center;
    padding-block: 10px;
  }

  /* ── 3. iOS MUST NOT ZOOM THE VIEWPORT ────────────────────────────────
     Safari zooms when a focused field is under 16px. The house fixed this on
     the player surfaces in May by raising the FLOOR rather than by setting
     user-scalable=no, which is a WCAG 1.4.4 failure - pinch-zoom must survive.
     Same fix, same reason, now on the Studio.
     ⚠ Only text-entry fields: font-size does not affect a checkbox, and
       sweeping every input would change nothing and imply it had. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select, textarea {
    font-size: max(16px, 1rem);
  }

  /* ── 4. ONE COLUMN ────────────────────────────────────────────────────
     The kit already collapses .m-grid-2/3/4 at 640px. Local two-column
     layouts on Studio pages need the same instruction, and 760 is where the
     mechanic bank's own .cols starts to crush rather than compress. */
  .cols, .m-split, .m-two {
    grid-template-columns: 1fr;
  }

  /* ── 4b. A MODAL SHOULD NOT SPEND A FIFTH OF A PHONE ON GUTTERS ───────
     Measured on the register modal at 375px: the content box was 304px, so 19%
     of the screen went to nested padding - 16px on the scrim plus 16px on the
     body, each side, on a screen that has none to spare. On a phone the modal
     IS the view; it does not need to prove it is floating above something.
     ⚠ THE DOUBLED CLASS NAMES ARE LOAD-BEARING, do not "tidy" them.
       tw-modal.js INJECTS its stylesheet at runtime, so it lands after this
       file and wins every tie at equal specificity. `.tw-modal-scrim` alone is
       0,1,0 against its 0,1,0 and LOSES on source order. I wrote the scoped
       version first, believing scoping was enough, and measured it live: the
       modal went 304 -> 312px instead of the expected ~332. Being inside an
       @media block adds NO specificity. Doubling the class is 0,2,0 and wins. */
  .tw-modal-scrim.tw-modal-scrim { padding: 8px; }
  /* ⚠ AND THE BINDING CONSTRAINT WAS NONE OF THE PADDING. With both padding
     rules applying cleanly the modal was still 337.5px: tw-modal.js line 360
     sets `modal.style.maxWidth` from its size map, and the "full" size is
     90vw. That is an INLINE style, so no selector of any specificity beats it -
     I tried the doubled-class form first and measured no change at all.
     ★ !important IS THE CORRECT TOOL HERE, and close to the only one: the
       alternative is editing tw-modal.js's size map, which is shared with
       surfaces this pass does not own. 90vw is a sensible desktop rule and a
       wasteful phone one - on a phone the scrim's own 8px already insets it. */
  .tw-modal-scrim .tw-modal { max-width: 100% !important; }
  .tw-modal-scrim .tw-modal-body.tw-modal-body { padding: 12px; }
  .tw-modal-scrim .tw-modal-header.tw-modal-header,
  .tw-modal-scrim .tw-modal-footer.tw-modal-footer { padding: 12px; }

  /* ── 5. A STICKY BAR MUST CLEAR THE HOME INDICATOR ────────────────────
     Otherwise Save sits under the gesture bar and the phone eats the tap. */
  .savebar, .m-sticky {
    padding-bottom: calc(12px + env(safe-area-inset-bottom));
  }

  /* ── 6. KPI FIGURES MAY WRAP THEIR LABEL ──────────────────────────────
     Measured: "IN PROGRESS" and "APPROVED" were rendering clipped to
     "IN PROGRES:" and "APPROVED" with the ends cut off, because the label sat
     on one nowrap line beside the figure. */
  .k, .m-kpi, .legend .c { min-width: 0; }

  /* ⚠ `.k *` WAS WRONG and the deployed measurement proved it: `.k` IS the
     label element, not its container, so a descendant selector never reached
     the nowrap. Measured on /studio/mechanic: "Never seated" wanted 129px in a
     78px box, which is where the last 35px of sideways scroll came from - the
     legend itself wrapped correctly and its three chips fitted, so every
     container looked innocent. THE OVERFLOW WAS THE LEAF ALL ALONG.
     Include the element AND its descendants. */
  .legend .c .k, .m-counts .c .k, .m-counts .k, .k.m-micro,
  .k, .k *, .m-micro, .m-kpi, .m-kpi * {
    white-space: normal;
    overflow-wrap: anywhere;
  }
  /* ⚠ THE LONG SELECTORS ARE LOAD-BEARING, do not "tidy" them away.
     tw-metro-shell.css carries `.m-counts .c .k { white-space: nowrap }` at
     specificity 0,3,0. A bare `.k` is 0,1,0 and LOSES, in every media query and
     at any source order. The rule was present, the media query matched, the
     element matched the selector - and the computed value was still nowrap.
     Proven by injecting the higher-specificity form into the live page: the
     document went 394 -> 375 immediately.
     ★ Same shape as the local-token-block scar: a shared layer cannot raise a
       floor that a more specific local rule has already set. */
}

/* ── 7. THE PLACEMENT EDITOR IS DRAGGED BY A FINGER ─────────────────────
   Not inside the media query: a touch-capable laptop is still a finger.
   The handle stays 11px to the eye and becomes 44px to the hand via a
   pseudo-element, which is the standard fix and costs the design nothing.
   ⚠ touch-action:none on the box, or the browser scrolls the page instead of
     moving the stem - the drag simply would not work on a phone. */
.twze-box { touch-action: none; }
.twze-h { position: absolute; }
.twze-h::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: 44px; height: 44px;
  transform: translate(-50%, -50%);
}
@media (pointer: coarse) {
  /* A finger cannot aim at 11px, so the DOT grows too - on touch only. */
  .twze-h { width: 18px; height: 18px; }
  .twze-num { min-height: 44px; font-size: max(16px, 1rem); }
}
