/* ===========================================================================
   mobile.css — phone-only layer for GQ CONNECT
   ---------------------------------------------------------------------------
   Jake, 2026-09-28: "I dont want the computer app to change at all … I just
   want the phone app to work alongside it."

   EVERY rule in this file lives inside the media query below. Above the
   breakpoint the browser does not apply any of it — there is no specificity
   contest to lose and nothing to override. Desktop and iPad are untouched by
   construction, not by care.

   DO NOT ADD A RULE OUTSIDE THE MEDIA BLOCK. scripts/check-mobile-scope.py
   fails the build if you do.

   Breakpoint reasoning:
     max-width: 600px            → phones upright (iPhone SE 375, 15 393, Max 430)
     max-height: 450px + coarse  → phones on their SIDE. An iPhone 15 in
                                   landscape is 852px WIDE, so a width-only
                                   rule would hand it the desktop layout on a
                                   393px-tall screen. `pointer: coarse` keeps a
                                   short desktop window out of it.
   The smallest iPad is 744px wide, so engineers' iPads stay on desktop.
   =========================================================================== */

@media (max-width: 600px), (max-height: 450px) and (pointer: coarse) {

  /* ---- 1. The iOS zoom trap -----------------------------------------------
     Safari zooms the page whenever a focused form control is under 16px, and
     it does NOT zoom back out afterwards. 359 of 360 controls in the app were
     under 16px, which is the single biggest cause of "it goes oversized".
     16px is the floor, not a preference.                                     */
  input, select, textarea, button {
    font-size: 16px !important;
  }
  html { -webkit-text-size-adjust: 100%; }

  /* ---- 2. Natural page scrolling ------------------------------------------
     The desktop shell scrolls an inner pane (.content) inside a 100%-height
     body. On iOS that fights the URL bar and loses momentum scrolling. Let
     the page itself scroll instead.                                          */
  html, body { height: auto; min-height: 100%; }

  /* .app-view is `height:100vh; overflow:hidden` in styles.css. That is
     correct for the desktop, where .content scrolls inside it. Once scrolling
     moves to the PAGE, that same rule clips everything past the first
     screenful and makes it unreachable - which is exactly what it did.
     dvh tracks the iOS URL bar; the vh line is the fallback under it. */
  .app-view {
    height: auto;
    min-height: 100vh;
    min-height: 100dvh;
    overflow: visible;
  }

  .app-body   { display: block; min-height: 0; }
  .content    { overflow: visible; padding: 14px 14px 88px; }

  /* ---- 3. Reclaim the screen ----------------------------------------------
     The 64px icon rail took 16% of the width on every page. It becomes a
     full-screen sheet, opened from the bottom bar.                           */
  .nav {
    position: fixed; inset: 0; z-index: 900;
    width: auto; padding: 14px 14px 96px;
    overflow-y: auto; display: none;
  }
  body.gq-nav-open .nav { display: block; }
  body.gq-nav-open     { overflow: hidden; }

  .nav-item {
    font-size: 16px; padding: 14px; min-height: 48px;
    width: 100%; border-radius: 10px;
  }
  .nav-section-title { display: block; padding: 10px 6px 6px; font-size: 11px; }

  /* ---- 4. Slimmer header --------------------------------------------------
     Logo + title + two straplines + user box ate a third of the screen.      */
  /* The page has viewport-fit=cover and apple-mobile-web-app-status-bar-style
     black-translucent, so it draws UNDER the iOS clock and battery. In Safari
     you can scroll away from it; installed to the Home Screen there is no URL
     bar, so the header would sit under the clock permanently. Pad by the safe
     area. The left/right insets matter in landscape, where the notch eats into
     the side. env() resolves to 0 anywhere without insets, so this is inert on
     an older phone or an Android. */
  header {
    padding: calc(8px + env(safe-area-inset-top, 0px))
             calc(12px + env(safe-area-inset-right, 0px))
             8px
             calc(12px + env(safe-area-inset-left, 0px));
    gap: 10px;
  }
  .content {
    padding-left:  calc(14px + env(safe-area-inset-left, 0px));
    padding-right: calc(14px + env(safe-area-inset-right, 0px));
  }
  .gq-tabbar {
    padding-left:  env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
  }
  .nav { padding-top: calc(14px + env(safe-area-inset-top, 0px)); }
  header .title .sub, header .title .sub2 { display: none; }
  header .title h1 .brand-gq,
  header .title h1 .brand-merlin { font-size: 18px; }
  #headerLogo { max-height: 34px; }
  .user-box  { gap: 6px; }
  .user-name { display: none; }

  /* ---- 5. Bottom tab bar (built by js/mobile.js) --------------------------
     Only exists in the DOM on a phone — the script that creates it returns
     early on anything else.                                                  */
  .gq-tabbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 950;
    display: flex; background: #fff;
    border-top: 1px solid var(--line);
    box-shadow: 0 -2px 12px rgba(21,57,91,0.08);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .gq-tab {
    flex: 1; border: none; background: transparent;
    min-height: 52px; padding: 8px 4px 6px;
    font-family: inherit; font-size: 11px !important; font-weight: 700;
    color: var(--muted); letter-spacing: 0.3px;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  }
  .gq-tab .gq-tab-dot {
    width: 18px; height: 3px; border-radius: 2px; background: transparent;
  }
  .gq-tab.active            { color: var(--navy); }
  .gq-tab.active .gq-tab-dot { background: var(--teal); }

  /* ---- 6. Touch targets ---------------------------------------------------
     26 controls were under Apple's 44px minimum.                             */
  .btn-primary, .btn-ghost, .btn-danger,
  .page-actions button, .list-controls button { min-height: 44px; }

  /* ---- 7. Stop sideways dragging -----------------------------------------
     Wide tables keep their own scroller rather than shoving the whole pane
     sideways. Phase 2 turns these into stacked cards; this stops the page
     itself moving in the meantime.                                           */
  .card { overflow-x: auto; }
  .page-head { gap: 8px; }
  .page-actions { width: 100%; }
  .list-controls { flex-direction: column; align-items: stretch; }
  .list-controls input, .list-controls select { min-width: 0; width: 100%; }

  /* ---- 8. Modals become full-screen sheets -------------------------------
     Measured on the Add Booking modal at 393px: the card was 1424px tall in
     an 850px viewport with Save stranded at y=1357, the close button was
     12x16px, and 95px of the 391px width (24%) went on nested padding.      */
  .modal { padding: 0; align-items: stretch; }
  .modal-card {
    max-width: none; width: 100%; min-height: 100%;
    border-radius: 0; padding: 54px 14px 14px;
  }
  .modal-close {
    top: 6px; right: 6px;
    width: 44px; height: 44px; font-size: 24px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 10px; background: var(--bg);
  }
  /* Save / Delete pinned to the bottom of the screen. Without this you scroll
     past every field on the form to reach them, every single time.           */
  .modal-card .form-buttons {
    position: sticky; bottom: 0; z-index: 5;
    margin: 16px -14px 0; padding: 10px 14px;
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
    background: #fff; border-top: 1px solid var(--line);
    box-shadow: 0 -4px 14px rgba(21,57,91,0.10);
    display: flex; flex-wrap: wrap; gap: 8px;
  }
  .modal-card .form-buttons button { flex: 1 1 140px; margin: 0; }

  /* ---- 9. Tables become stacked cards ------------------------------------
     The invoice list was 558px wide and the to-be-invoiced table 871px, both
     inside a 361px card, so both dragged sideways. Each row becomes a block
     and each cell gets its column name from js/mobile.js.                    */
  .data-table, .data-table tbody, .data-table tr, .data-table td {
    display: block; width: auto;
  }
  .data-table thead { display: none; }
  .data-table tr {
    border: 1px solid var(--line); border-radius: 10px;
    padding: 8px 12px; margin-bottom: 10px; background: #fff;
  }
  .data-table td {
    border: none; padding: 6px 0;
    display: flex; gap: 12px; align-items: baseline; justify-content: space-between;
    text-align: right;
  }
  .data-table td::before {
    content: attr(data-label);
    flex: 0 0 40%; text-align: left;
    font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px;
    color: var(--muted); font-weight: 700;
  }
  /* Action cells have no column name - let them use the full width. */
  .data-table td:not([data-label])::before { display: none; }
  .data-table td:not([data-label]) { justify-content: flex-end; }
  .card { overflow-x: visible; }

  /* ---- 10. Calendar becomes a day-by-day list ----------------------------
     A 7-column grid gave 43px-wide days and 33px-wide chips at 10px. Nobody
     can read that. Empty leading cells are dropped and each day stacks.      */
  .cal-grid  { display: block; }
  .cal-head  { display: none; }
  .cal-empty { display: none; }
  .cal-cell {
    min-height: 0; max-height: none; overflow: visible;
    margin-bottom: 8px; padding: 10px 12px;
  }
  .cal-daynum { font-size: 13px; color: var(--navy); margin-bottom: 6px; }
  .cal-today  { border-color: var(--teal); border-width: 2px; }
  .cal-chip   { font-size: 13px; padding: 8px 10px; margin-bottom: 6px; }
  .cal-chip-line  { white-space: normal; }
  .cal-chip-muted { font-size: 12px; }

  /* ---- 12. Two things that still dragged the booking form sideways -------
     Found by measuring the Add Booking modal after Phase 2, not by eye.

     (a) .gqs-hidden-select is the real <select> behind the practice search
         box. styles.css sets it to width:1px, but `.field-grid select`
         (0,1,1) out-specifies `.gqs-hidden-select` (0,1,0) and forces it to
         100%. It is invisible either way, but at 348px it doubled the
         form's scroll width to 696px. Harmless on a wide desktop, which is
         why it was never noticed.

     (b) .job-line rows are flex with no wrapping, so the machine and service
         pickers alone came to 579px in a 326px row.                         */
  .gqs-hidden-select {
    /* width:1px alone is not enough - `.field-grid select` also applies
       padding:10px 12px, and under border-box that padding is the floor, so
       it still measured 26px and sat to the RIGHT of the input at left:348px.
       Zero the padding and border and pin it to the corner.                 */
    width: 1px !important; height: 1px !important;
    padding: 0 !important; border: 0 !important;
    left: 0 !important; top: 0 !important;
  }

  .job-line-top, .job-line-bottom { flex-wrap: wrap; }
  .job-line-top > *, .job-line-bottom > * { min-width: 0; }
  .job-line-top .jl-eq,
  .job-line-top .jl-svc,
  .job-line-bottom .jl-desc { flex: 1 1 100%; width: 100%; }
  .job-line-top .jl-remove { flex: 0 0 auto; margin-left: auto; }
  .job-line-bottom .jl-money,
  .job-line-bottom .jl-disc,
  .job-line-bottom .jl-total { flex: 1 1 auto; }

  /* ---- 11. Stop "Sign out" wrapping in the header ------------------------ */
  .role-tag { display: none; }

}
