/* ══════════════════════════════════════════════════════════════════════════
   Tenta — shared mobile + touch layer.

   Served from /static (conditional-GET + max-age=3600) and linked from
   layout.js AFTER its inline <style> block, with a ?v=<version> cache buster.
   Two reasons it is a file and not more inline CSS:
     - HTML is Cache-Control: no-store, so every inline byte is re-downloaded on
       every page view; this file is fetched once per deploy.
     - layout.js is the serialization bottleneck for parallel work.

   Because it loads after the inline sheet, equal-specificity rules here win.
   Route-level <style> blocks live in the BODY and therefore still win over
   this file — that is deliberate: feature-specific mobile rules stay with
   their feature (calendar grid, media day page, overview).

   Breakpoint is max-width: 900px everywhere — it matches the calendar's
   existing collapse and calFit()'s >= 901px self-gate, so no viewport range
   ever has both the mobile rules and the desktop viewport-fit engine active.
   Touch-specific rules use @media (pointer: coarse) instead, since a touch
   laptop is wide but still fat-fingered.

   Nothing here may change desktop rendering: every rule is inside a media
   query except the two declarations below, which only introduce a token and
   keep a mobile-only element hidden.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Height of the bottom tab bar's touch row (the safe-area inset is added on
     top of it). Consumed by the bar itself and by the container's bottom
     padding, and available to any package that must clear the bar. */
  --m-tabbar-h: 56px;
}

/* layout() renders the bar in the DOM at every viewport (the alternative — a
   server-side viewport guess — cannot survive a rotation). Hidden by default,
   shown only inside the breakpoint below. */
.m-tabbar { display: none; }

@media (max-width: 900px) {

  /* ── Page frame ──────────────────────────────────────────────────────────
     32px of side padding costs 16% of a 390px phone. Halve it, then re-declare
     the three broadcast full-bleed bands, which break out by exactly the
     container's side padding and would otherwise overflow 16px past each
     viewport edge (matching specificity + later source order = these win). */
  .container { padding: 16px 16px 40px; }
  [data-skin="broadcast"] .topbar { margin: 0 -16px; padding: 8px 16px; margin-bottom: 0; }
  [data-skin="broadcast"] .nav { margin: 0 -16px 14px; }
  [data-skin="broadcast"] .cal-layout { margin: 0 -16px; }

  /* ── Top bar ─────────────────────────────────────────────────────────────
     Desktop is a 3-column grid (user · centred title · actions). At phone width
     the centred title, squeezed between the brand and a wide action cluster,
     overflowed its middle cell and painted ON TOP of the brand wordmark. So drop
     the grid entirely and use a two-row FLEX layout that cannot overlap:
       row 1 — brand (left) + actions (pushed right, free to wrap)
       row 2 — the venue name + city, full width, left-aligned
     The username and the tiny version string are redundant on a phone. */
  .topbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: 10px;
    row-gap: 6px;
    margin-bottom: 14px;
  }
  .topbar-left { order: 1; gap: 10px; }
  .topbar-user { display: none; }
  .topbar-brand-name { font-size: 0.95rem; }
  .topbar-brand-ver { display: none; }
  .topbar-actions {
    order: 2;
    margin-left: auto;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 10px;
    row-gap: 6px;
    min-width: 0;
  }
  .topbar-actions a, .topbar-actions button { font-size: 0.75rem; }
  .topbar-title {
    order: 3;
    flex-basis: 100%;
    justify-content: flex-start;
    min-width: 0;
    gap: 6px;
  }
  .topbar-name { font-size: 1rem; }
  .topbar-city { font-size: 0.72rem; }

  /* ── Tab row (components.js clientNav) ───────────────────────────────────
     The three core tabs move to the bottom bar, so hide them here rather than
     showing the same navigation twice. The row itself disappears entirely
     unless a flag-driven tab (recurring / sheets) or a non-client link
     (accountNav's lone "dashboard") is left in it. :has() is Safari 15.4+ /
     Chrome 105+; where it is unsupported the whole rule is dropped and the
     empty row simply stays visible — a cosmetic fallback, not a breakage. */
  .nav a.nav-core { display: none; }
  .nav:not(:has(a:not(.nav-core))) { display: none; }
  .nav { flex-wrap: wrap; }

  /* ── Bottom tab bar ──────────────────────────────────────────────────────
     Token-based so both skins and all three themes come along for free. It sits
     at --z-nav; the calendar day-detail sheet deliberately stacks above it. */
  .m-tabbar {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--z-nav);
    background: var(--surface);
    border-top: 1px solid var(--separator-opaque);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .m-tabbar a {
    flex: 1 1 0;
    min-width: 0;
    height: var(--m-tabbar-h);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    font-family: var(--body);
    font-size: 0.68rem;
    font-weight: var(--weight-medium);
    letter-spacing: 0.01em;
    color: var(--text-secondary);
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
  }
  .m-tabbar a svg { width: 21px; height: 21px; display: block; }
  .m-tabbar a.active { color: var(--accent); font-weight: var(--weight-semibold); }
  /* Broadcast's metadata register: mono uppercase labels, square everything. */
  [data-skin="broadcast"] .m-tabbar a {
    font-family: var(--mono);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    border-right: 1px solid var(--separator);
  }
  [data-skin="broadcast"] .m-tabbar a:last-child { border-right: none; }
  [data-skin="broadcast"] .m-tabbar a.active { color: var(--text-primary); background: var(--surface-inset); }

  /* Page content must be able to scroll clear of the fixed bar. Set only when
     layout() actually rendered it (and kept in sync by mTabbarSync(), since
     hx-boost swaps body *contents* but leaves body's class attribute alone). */
  body.has-m-tabbar .container {
    padding-bottom: calc(var(--m-tabbar-h) + env(safe-area-inset-bottom) + 16px);
  }
}

/* ── Touch ergonomics ──────────────────────────────────────────────────────
   Deliberately NOT inside the breakpoint: a touchscreen laptop is wide and
   still needs 44px targets. touch-action: manipulation removes the ~300ms
   double-tap-to-zoom delay without disabling pinch zoom on the page. */
@media (pointer: coarse) {
  .btn, .trigger-btn, .nav a, .m-tabbar a { min-height: 44px; }
  .nav a { display: flex; align-items: center; justify-content: center; }
  .btn, .trigger-btn { justify-content: center; }
  a, button, .cal-day, .dropzone { touch-action: manipulation; }
}
