/* ============================================================================
 * m-shell.css — the phone's bottom key bar.
 *
 * WHY THIS EXISTS. Everything a phone user could reach lived in a 52px strip at
 * the TOP of the screen that held 631px of controls in a 375px window and
 * scrolled sideways with no hint that it could. css/mobile.css says so itself at
 * :116-136, and records that the fix it shipped pinned two of the eleven
 * children (☰ and the avatar) and re-ordered three more. The other six — global
 * search, Undo, Redo, the sync chip, the school switcher and the presence count
 * — were left off-screen. Undo in particular is promised in words by the phone
 * screens ("You can Undo.") and, on a touch device with no Ctrl+Z, had no
 * control at all.
 *
 * So the daily keys move to the bottom edge, where a thumb already is, and the
 * top bar stops being a scroller.
 *
 * WHAT THIS FILE IS NOT. It does NOT rebuild the drawer. The 56-link menu, its
 * nine clusters, its role filtering and its drag-reorder all keep working
 * exactly as they do today, and ☰ still opens them. That was deliberate: the
 * drawer is the escape hatch that guarantees no route is ever stranded, and
 * mobile.css:120-128 records what happened the last time navigation and chrome
 * were rebuilt in one go ("cannot operate, cannot log out"). The bar is added
 * around a working menu, not instead of one.
 *
 * EVERY RULE IS SCOPED UNDER .is-mobile. Desktop loads this file and nothing in
 * it matches. That is the whole contract.
 * ==========================================================================*/

/* ---- 1. the bar ---------------------------------------------------------- */

/* 56px + the safe area. `flex: 1 1 0` and NOT a fixed 75px: 5 x 75 = 375 exactly
   edge to edge, sized to the widest cheap Android, and the modal device in this
   market is 360px CSS wide — a fixed width overflows or silently squeezes. */
.is-mobile .m-navbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 48;
  display: flex; align-items: stretch;
  height: calc(56px + env(safe-area-inset-bottom));
  padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  background: var(--panel, #e8ecf2);
  /* A viewport-edge surface cannot use the raised pair — the dark half falls off
     the bottom of the glass and reads as a hard line. skin-neu.css solves welded
     edges with an inset top edge instead (its own note at :461), so that is what
     is used here: the bar looks lifted because the page is pressed away from it. */
  box-shadow: inset 0 1px 0 var(--nu-light, rgba(255,255,255,.85)), 0 -1px 0 var(--line, #d7dce4);
}
.is-mobile .m-navbar button {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  height: 56px; min-height: 56px; padding: 0 2px;
  background: none; border: 0; border-radius: 0;
  color: var(--ink-soft, #5b6675); font-size: 10px; line-height: 1.1;
  cursor: pointer;
}
/* The label is not optional. An icon-only bar is a memory test, and this app is
   used by people who were handed it last week. */
.is-mobile .m-navbar .m-nav-l {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.is-mobile .m-navbar svg { width: 22px; height: 22px; flex: 0 0 auto; }
.is-mobile .m-navbar button:active { background: var(--tint, rgba(0,0,0,.04)); }
/* The lit key. Colour AND weight, never colour alone. */
.is-mobile .m-navbar button.on { color: var(--brand, #2f6fed); font-weight: 700; }
.is-mobile .m-navbar button.on svg { stroke-width: 2.4; }

/* ---- 2. the room the bar takes ------------------------------------------- */

/* The page has to end above the bar or its last row is unreachable. */
.is-mobile.has-navbar .view {
  padding-bottom: calc(68px + env(safe-area-inset-bottom));
}
/* A screen with its own action bar stacks ABOVE the keys rather than under them:
   the bar is chrome for the whole app, the action bar is this screen's verb. */
.is-mobile.has-navbar.has-actionbar .m-actionbar {
  bottom: calc(56px + env(safe-area-inset-bottom));
}
.is-mobile.has-navbar.has-actionbar .view {
  padding-bottom: calc(140px + env(safe-area-inset-bottom));
}

/* EVERYTHING ELSE THAT LIVES ON THE BOTTOM EDGE has to come up too, or the bar
   lands on top of it. mobile.css:355 already had to do this once for the action
   bar; this is the same census taken again, and the last two matter most — the
   cloud-conflict banner is a data-loss control, and a toast is how the app says
   "saved". */
.is-mobile.has-navbar #toasts,
.is-mobile.has-navbar .try-banner { bottom: calc(68px + env(safe-area-inset-bottom)); }
.is-mobile.has-navbar.has-actionbar #toasts,
.is-mobile.has-navbar.has-actionbar .try-banner { bottom: calc(140px + env(safe-area-inset-bottom)); }

/* ---- 3. the keyboard ----------------------------------------------------- */

/* `position: fixed; bottom: 0` sits ON TOP of the Android soft keyboard, which
   would put Home/Find/More one thumb-width above the number row on #/enter —
   the most repeated screen in the product. So the bar hides while the keyboard
   is up. Driven from visualViewport in m-shell.js and NOT from focusin: a
   focus-driven rule reflows the page by 56px between every pupil in a class of
   forty, which is worse than the problem it fixes. */
.is-mobile.kb-open .m-navbar { display: none; }
.is-mobile.kb-open.has-navbar .view { padding-bottom: 12px; }
.is-mobile.kb-open.has-navbar.has-actionbar .view { padding-bottom: 96px; }

/* ---- 4. the top bar stops scrolling sideways ----------------------------- */

/* The surplus controls now live in the ⋯ sheet (js/m-shell.js moves them there
   as live nodes), so the bar has four children and fits. Once it fits, the
   horizontal scroll that mobile.css:90-98 had to allow becomes a liability
   rather than a release valve: it is what let six controls sit off-screen
   without a hint. */
.is-mobile .topbar { overflow-x: hidden; }

.is-mobile .topbar .m-tb-more {
  flex: 0 0 auto; order: 4;
  min-width: 44px; min-height: 40px;
  margin-left: auto;                 /* sits beside the pinned avatar */
  background: none; border: 0;
  font-size: 20px; line-height: 1; color: var(--ink-soft, #5b6675);
  cursor: pointer;
}
.is-mobile .topbar .m-tb-more[aria-expanded="true"] { color: var(--brand, #2f6fed); }

/* The sheet hangs BELOW the bar rather than inside it — a popover clipped by
   its own bar is the bug css/style.css had to solve once already for the
   desktop dropdowns. */
.is-mobile .topbar { position: sticky; }
.is-mobile .m-tb-pop {
  position: absolute; top: 100%; right: 6px; z-index: 70;
  display: flex; flex-direction: column; align-items: stretch; gap: 8px;
  min-width: 200px; max-width: min(86vw, 320px);
  max-height: min(70vh, 460px); overflow-y: auto;
  padding: 10px;
  background: var(--panel, #e8ecf2);
  border-radius: 14px;
  box-shadow: var(--nu-2, 0 6px 18px rgba(0,0,0,.18));
}
.is-mobile .m-tb-pop[hidden] { display: none; }
/* Whatever was moved in was built for a horizontal bar; in a column it should
   fill the width and keep a full-size hit area. */
.is-mobile .m-tb-pop > * { flex: 0 0 auto; width: 100%; }
.is-mobile .m-tb-pop button,
.is-mobile .m-tb-pop a { min-height: 44px; }

/* ---- 5. paper ------------------------------------------------------------ */

/* THE RESERVED PADDING IS THE THING THAT PRINTS, not the bar. m-sheets.js:447
   records this from a measurement — "has-actionbar reserves 84px, which prints
   as a band at the foot" — and has to zero the padding inline before printing.
   Doing it here in one rule fixes it for the new bar AND for every screen that
   never knew to. .noprint on the element itself is not enough and never was. */
@media print {
  .is-mobile .m-navbar { display: none !important; }
  .is-mobile.has-navbar .view,
  .is-mobile.has-navbar.has-actionbar .view { padding-bottom: 0 !important; }
}
