/* css/mobile.css — the phone pass.
 *
 * Measured before writing this, by rendering each page in a 390px-wide frame
 * (an iPhone's CSS width) and reading the *computed* font size of every text
 * element on screen. The result was consistent and bad:
 *
 *     index.php             104 of 121 text elements below 16px
 *     student_index.php      56 of  68
 *     reserve_venue.php      54 of  56
 *     technician_dashboard   43 of  48
 *     track_report.php       33 of  37
 *     student_dashboard.php  29 of  40
 *
 * with body copy landing at 11-13px. The layouts were never the problem — no
 * page scrolls sideways and every one already fills the screen. The problem is
 * that the whole system was drawn for a desktop monitor: the type scale bottoms
 * out at --fs-xs:.6rem, which is 9.6px in a hand.
 *
 * The first version of this sheet over-corrected. It pinned the root at 18px
 * and put body copy at 16-18.7px, and because padding and gaps are in rem too,
 * everything grew with it: the public board measured 8.9 screens long, the
 * landing page 7.3. The user found it too big and too much scrolling. The
 * scale now follows the common mobile standard (Material's body 14-16, Apple's
 * caption 12), on a 16px root:
 *
 *   INPUTS    16px, and never less. Below 16px iOS Safari zooms the whole page
 *             every time a field is tapped -- reserve_venue.php was serving
 *             14.4px inputs and every tap kicked the page sideways.
 *
 *   CONTENT   15px. Body copy, field labels, buttons, list rows.
 *   SECONDARY 14px. Help text under a field, card meta, sub-lines.
 *   CHROME    12px. Decoration that carries no sentence: uppercase eyebrows,
 *             count badges, avatar initials, status dots. Recognised by shape
 *             and position, not read.
 *
 * Everything is in rem, and the root is pinned below so rem means the same
 * thing on every page -- most set html{font-size:106.25%} and reserve_venue.php
 * sets nothing, so an identical rule was rendering two different sizes.
 *
 * Load this LAST in <head>, after the page's own <style>, or the page's rules
 * win on source order. Admin pages deliberately do not load it: they are
 * desktop-only by design (see CLAUDE.md).
 */

@media (max-width: 820px) {

  /* ---- one root, so a rem is one size everywhere -------------------------- */
  html { font-size: 100%; }              /* 16px — the browser default */

  /* Nothing is scrolling sideways, so the reserved scrollbar channel is 15px
     of a 390px screen given away for a bar that phones draw as an overlay. */
  html { scrollbar-gutter: auto; }

  /* ---- the type scale ----------------------------------------------------- */
  /* The tokens do most of the work on the pages that use them (student_index
     reads them 97 times). Raising the scale lifts those pages in one move;
     the selectors further down are for pages that hard-code their sizes. */
  :root {
    --fs-xs:   .75rem;    /* 12px — chrome */
    --fs-sm:   .875rem;   /* 14px — secondary: card meta, help lines */
    --fs-base: .9375rem;  /* 15px — body copy */
    --fs-md:   1rem;      /* 16px */
    --fs-lg:   1.0625rem; /* 17px */
    --fs-xl:   1.1875rem; /* 19px */
    --fs-2xl:  1.375rem;  /* 22px */
  }

  /* ---- CONTENT: things that get read ------------------------------------- */
  p, li, dd, dt, label, legend, blockquote { font-size: .9375rem; line-height: 1.5; }   /* 15px */
  small { font-size: .875rem; }                                                        /* 14px */

  /* Field labels at body size; the sentence under a field one step smaller,
     so the question reads first and the hint second. */
  .fl, label.fl, .q-loc, .user-name,
  .top a.back { font-size: .9375rem; }   /* reserve_venue scopes this one */
  .fi-hint, .section-sub, .panel-sub, .page-sub, .lede,
  .photo-sub, .photo-title, .or-row, .footer-link, .note, .inp-meta,
  .q-loc-sub, .q-id { font-size: .875rem; }

  /* Every control the thumb lands on. */
  button, .btn, .action-btn, .cam-trigger, .btn-submit, .addmat, .back,
  .lbtn, .tia-chip, .pwa-chip, .ni, .lout, .np-b,
  .bsnav-link, .bsnav-cta, .bsnav-skip, .skip-link,
  .bsfoot-col a, .bsfoot-contact li { font-size: .9375rem; }

  /* The iOS zoom floor: exactly 16px, never less. */
  input, select, textarea { font-size: 1rem; }

  /* ---- CHROME: recognised, not read -------------------------------------- */
  .page-eyebrow, .panel-eyebrow, .eyebrow, .brand-tag, .nav-sec, .req,
  .badge, .nbadge, .tb-dot, .qcount, .user-avatar, .uav, .ch-status,
  .bsnav-brand small, .bsfoot-brand small, .bsfoot-col h4,
  .bsfoot-motto .est, .bsfoot-note { font-size: .75rem; }

  .bsnav-brand b  { font-size: 1rem; }
  .bsfoot-motto   { font-size: .875rem; }

  /* ---- titles ------------------------------------------------------------- */
  /* 20-24px, the usual size for a heading on a phone. They were 25-27px, which
     on a 390px screen is two or three lines and a third of the first screen
     before anything is said. Each page names its own title, hence the list. */
  .hero h1 { font-size: 1.5rem; }                                     /* 24px landing hero */
  .card > h1, .page-header > h1, .page-head h1,
  .sec-title, .ticket { font-size: 1.25rem; }                         /* 20px */
  .stat-num { font-size: 1.375rem; }                                  /* 22px */
  .pc-title { font-size: 1.125rem; }                                  /* 18px */
  /* Questions, step names and card titles: a line you read, not a heading. */
  .faq-item summary, .intro-card > summary, .rt-title, .th-main strong,
  .cs-tx b, .rc-eq { font-size: 1rem; }                               /* 16px */

  /* The landing page drew its body copy with --fs-lg, a size larger than every
     other page (17px against 15px). Same 15px as the rest of the site. */
  .hero-sub, .sec-sub, .pc-desc, .faq-a, .rep-all a { font-size: .9375rem; }

  /* Eyebrows set with two classes or a class and an element outrank the
     single-class chrome rule above, and were measured at 9.6-11.5px once the
     root came down to 16px: the technician task's "WHEN THE JOB IS DONE" /
     "WHAT THE REPORTER SAID" labels, its queue badges and bottom-nav captions,
     and the public board's "TRANSPARENCY BOARD". Same 12px floor. */
  .sec-h small, .copy-label, .ws-head-copy small, .q-badges .badge, .bn, .eye { font-size: .75rem; }
  /* The finish form's field labels are uppercase, which reads a size larger;
     13px, not the 15px a sentence-case label gets. */
  .form label { font-size: .8125rem; }

  /* The technician task view hard-codes its sizes, tuned when phones ran an
     18px root; at 16px what the reporter said fell to 13.9px and the
     reporter's name line to 11.8px. Put them on the same scale as the rest. */
  .copy, .sec-lead, .waiting-pmo, .problem summary, .prev-fix summary,
  .rp-tx strong { font-size: .9375rem; }                      /* 15px content */
  .q-top strong { font-size: 1rem; }                           /* list title */
  .fhint, .tp-b, .where-rest, .rp-tx span, .hd { font-size: .875rem; }   /* 14px */
  .ws-sub, .hw { font-size: .8125rem; }                        /* 13px */

  /* ---- tap targets -------------------------------------------------------- */
  /* 44px is the size a fingertip actually covers. Listed one by one rather
     than applied to every button, because the assistant widget's own controls
     are sized to its bubble and grow into it if forced. */
  .btn, .btn-submit, .action-btn, .cam-trigger, .addmat, .lbtn, .pwa-chip,
  .bsnav-link, .bsnav-cta, .ni, .lout, .nat {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .btn-submit, .action-btn, .cam-trigger { justify-content: center; }
}

/* ── touch targets, decided by the pointer and not by the width ────────────
   The 44px minimums above live in a max-width block, and the footer had its
   own at 640px. Both guess "touch" from how wide the screen is, which gets a
   tablet wrong: measured on index.php at 768px, fifteen of thirty-two
   controls were under 44px — the footer links at 20px, "Track Report" at
   25px — because an iPad portrait is wider than every phone breakpoint while
   being just as much a finger.

   (hover: none) and (pointer: coarse) asks the question directly: is the
   primary input a finger? A mouse never matches it, so this cannot inflate a
   desktop layout at any width. */
@media (hover: none) and (pointer: coarse) {
  .bsfoot-col ul a, .bsfoot-contact a, .bsfoot-social a,
  .bsnav-link, .bsnav-cta, .bsnav-skip,
  .btn, .btn-submit, .action-btn, .cam-trigger, .addmat, .lbtn, .pwa-chip,
  .ni, .lout, .nat, .pg-btn, .np-b, .tp-b {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  /* Prose links inside a paragraph are not buttons — padding them to 44px
     would tear the line apart. Given room around them instead. */
  main a:not([class]), .sec a:not([class]), footer a:not([class]) {
    padding-block: .25rem;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * NOT mobile-specific — deliberately outside every media query.
 *
 * This file is the only stylesheet linked last in <head> on all ten
 * user-facing pages, which makes it the one place a baseline can be set
 * without adding a tenth <link> to ten files. Keyboard focus is that baseline.
 *
 * Measured: assets/css/admin-shell.css was the ONLY shared stylesheet defining
 * :focus-visible, and it reaches admin pages only. On the public side each page
 * had its own scattered rules — student_index.php seven, index.php three — and
 * student_dashboard.php, the reporter form the defence panel scrutinised, and
 * reserve_venue.php had NONE. Tabbing through either one moved an invisible
 * cursor.
 *
 * :focus-visible, not :focus, is the whole point: the browser shows this to
 * someone navigating by keyboard and withholds it from someone who clicked, so
 * nothing about the mouse experience changes. Two layers so it survives any
 * background: a dark ring, then a light halo outside it.
 * ═══════════════════════════════════════════════════════════════════════════ */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--maroon, #7B1D1D);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(255, 255, 255, .85);
  border-radius: 4px;
}
/* On the dark surfaces — the technician sidebar, the footer, the assistant
   header — a maroon ring on near-black is invisible. Invert there. */
.sb :where(a, button):focus-visible,
.bsfoot :where(a, button):focus-visible,
.ch :where(a, button):focus-visible,
.tia-head :where(a, button):focus-visible {
  outline-color: #F0C040;
  box-shadow: 0 0 0 4px rgba(0, 0, 0, .45);
}
/* Never remove it silently. A rule that sets outline:none on a focusable
   element must replace it, and this is the replacement of last resort. */
:where(a, button, input, select, textarea):focus-visible { outline-style: solid; }
