/* public/mobile.css
 *
 * Phone layer for the standalone dashboards in public/*.html. Linked AFTER
 * theme.css from every dashboard, so it can override the desktop rules those
 * files define inline without any of them being edited individually.
 *
 * WHY A SHARED FILE. These eight dashboards were written at desktop widths over
 * several months and each carries its own copy of the same layout CSS. Fixing
 * them one at a time means eight chances to miss one, and the next dashboard
 * starts broken again. One file, linked once per page, means a phone fix lands
 * everywhere at once. Same reasoning as theme.css, which is why it sits beside
 * it and uses the same variables.
 *
 * EVERYTHING HERE IS INSIDE @media (max-width:760px). Nothing in this file may
 * affect a desktop render. Rowan and Sam read these on laptops and any
 * regression there is worse than the phone problem it fixes.
 *
 * THE ONE RULE THAT MATTERS: the PAGE never scrolls sideways, but a TABLE may.
 * A 12 column AR aging table cannot be made to fit 390px and should not be; a
 * buyer's name and an amount owed have to stay on one line to be readable. So
 * wide content scrolls inside its own panel and the document stays put. A page
 * that scrolls sideways feels broken; a table that scrolls sideways feels like
 * a table. Everything below is in service of that split.
 */

@media (max-width: 760px) {
  /* ---- Page frame -------------------------------------------------------- */

  /* The document must never be wider than the screen. Any child that tries is
     clipped to the panel it lives in, not allowed to push the body. */
  html,
  body {
    max-width: 100%;
    overflow-x: hidden;
  }

  body {
    /* Was padding:20px clamp(12px,2.6vw,30px) 60px. Tighter sides buy roughly
       16px of table width, which is a whole column at these font sizes. */
    padding: 14px 10px 48px;
  }

  /* The decorative corner gradients are 900px and 700px wide. On a phone they
     cover the entire screen as a flat wash and cost a repaint on every scroll. */
  body {
    background-image: none;
  }

  /* ---- Header and controls ----------------------------------------------- */

  header {
    /* flex-wrap with space-between strands a lone control on its own line and
       right aligns it against nothing. Stack instead. */
    flex-direction: column;
    align-items: stretch;
    gap: 11px;
    margin-bottom: 12px;
  }

  /* THE HEADER'S CHILDREN MUST BE ALLOWED TO SHRINK. Measured 2026-07-30 at
     375px, BEFORE this rule: header's own box was 355px but every child, .ttl,
     #brand, .sub and .controls, measured 1231px and was clipped by the
     overflow-x:hidden above. The filter strip was rendering almost entirely
     off-screen and could not be reached.
     WHY: a flex item defaults to min-width:auto, which floors it at its
     MIN-CONTENT width and lets it refuse to shrink. `.controls` is set to
     flex-wrap:nowrap just below, so its min-content width is the whole filter
     row laid out in one line (1546px here). That floor propagates up and drags
     the stretched siblings out with it.
     min-width:0 removes the floor, the strip collapses to the screen width, and
     the overflow-x:auto on `.controls` then has something to actually do. Same
     failure and same fix as the inline min-widths documented in app/globals.css
     for the React pages. */
  header > *,
  header .ttl,
  header .controls {
    min-width: 0;
    max-width: 100%;
  }

  .ttl h1 {
    /* clamp(21px,2.3vw,29px) resolves to its 21px floor on a phone anyway. Set
       it outright so the line box is predictable next to the freshness dot. */
    font-size: 20px;
  }

  .ttl .sub {
    font-size: 12px;
    flex-wrap: wrap;
    gap: 6px;
  }

  /* Control rows become one horizontally swipeable strip rather than wrapping
     into four stacked rows that push the actual data below the fold. */
  .controls {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    gap: 8px;
    padding-bottom: 4px;
    /* Momentum scrolling on iOS, and hide the scrollbar track that would
       otherwise sit under the controls on Android. */
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .controls::-webkit-scrollbar {
    display: none;
  }

  .ctrl {
    flex: 0 0 auto;
  }

  /* 200px min-width on a 390px screen is the single worst offender in these
     files: it forces the control row wider than the viewport, which is what
     made the whole page scroll sideways. */
  input[type="text"] {
    min-width: 0;
    width: 100%;
    /* 16px is not a style choice. Any smaller and iOS Safari zooms the page in
       when the field takes focus, and it never zooms back out. */
    font-size: 16px;
    padding: 10px 12px;
  }

  .ctrl:has(input[type="text"]) {
    flex: 1 1 180px;
    min-width: 160px;
  }

  select {
    /* Same iOS zoom-on-focus rule as above. */
    font-size: 16px;
    padding: 10px 30px 10px 12px;
  }

  /* ---- Tap targets -------------------------------------------------------
     Everything interactive clears roughly 44px, which is the smallest control
     a thumb hits reliably. These were 26px to 32px, sized for a mouse. */

  .seg button,
  .btn,
  #arModeSeg button {
    min-height: 40px;
    padding-top: 9px;
    padding-bottom: 9px;
    font-size: 13px;
  }

  .tabs {
    /* Five tabs at 15px with 20px of side padding wrap to three rows. One
       swipeable strip keeps the content start in the same place every time. */
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    gap: 2px;
    margin: 4px 0 14px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .tabs::-webkit-scrollbar {
    display: none;
  }

  .tabs button {
    flex: 0 0 auto;
    font-size: 14px;
    padding: 11px 14px;
    white-space: nowrap;
  }

  /* ---- KPI strip ---------------------------------------------------------- */

  .kpis {
    /* The inline rule already goes to 2 columns at 560px. Do it at 760px too,
       and let the tiles breathe, since 3 across at 390px truncates every value. */
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
  }

  .kpi .kl {
    /* min-height:26px was reserving two lines of label on every tile to keep
       nine of them aligned in one desktop row. In a 2 column grid the rows
       align themselves and that reserved space is just dead height. */
    min-height: 0;
    font-size: 9.5px;
  }

  .kpi .kv {
    font-size: 17px;
  }

  /* The hover-only drill hint can never be shown on a touch screen. */
  .kpi .kdrill {
    display: none;
  }

  /* ---- Panels, charts, tables --------------------------------------------- */

  .grid {
    grid-template-columns: 1fr;
    gap: 10px;
  }

  .panel > .hd {
    padding: 11px 12px 9px;
  }

  .panel .hd h2 {
    font-size: 14px;
  }

  .chartwrap,
  .chartwrap.tall {
    /* Fixed 300px and 340px boxes are landscape shapes on a portrait screen.
       Chart.js reads the container, so changing it here is enough; it does not
       need to be told. */
    height: 240px;
    padding: 10px 8px 6px;
  }

  /* A capped scroll box inside a page that also scrolls creates two nested
     scroll areas, and a thumb drag lands in whichever one it happens to start
     over. Letting the table run taller on a phone means one scroll surface
     vertically, and the table keeps its own horizontal one. */
  .scroll {
    max-height: none !important;
    overflow-x: auto;
    overflow-y: visible;
    -webkit-overflow-scrolling: touch;
  }

  /* Wide tables stay wide and swipe sideways INSIDE the panel. The alternative,
     reflowing each row into a stacked card, breaks column-to-column comparison,
     which is the entire reason these tables exist. */
  .scroll table {
    min-width: max-content;
  }

  th,
  td {
    padding: 9px 8px;
    font-size: 12px;
  }

  th {
    font-size: 9.5px;
  }

  /* The first column is the row's identity (retailer, SKU, strain). Pin it so a
     sideways swipe never leaves the reader looking at numbers with no subject. */
  .scroll table td:first-child,
  .scroll table th:first-child {
    position: sticky;
    left: 0;
    z-index: 3;
    background: var(--panel, #fff);
    /* A hairline, so the pinned column reads as pinned rather than as overlap. */
    box-shadow: 1px 0 0 var(--line, #e5e3dd);
  }

  /* thead cells are already sticky on the vertical axis at z-index 2. The
     top-left cell is sticky on both, so it has to outrank both. */
  .scroll table thead th:first-child {
    z-index: 4;
  }

  /* Row hover is a mouse affordance. On touch it latches on after a tap and
     stays highlighted, which reads as a selected row that cannot be cleared. */
  tbody tr:hover {
    background: transparent;
  }

  /* ---- Misc --------------------------------------------------------------- */

  .drillbar {
    padding: 9px 12px;
    gap: 8px;
    font-size: 12px;
  }

  /* Print and PDF buttons are desktop actions. They still work, they just do
     not earn a slot in a 390px control strip. */
  .noprint-mobile {
    display: none;
  }
}

/* Landscape phones and small tablets: keep the swipeable strips and the taller
   tables, but two KPI columns wastes the width. */
@media (min-width: 761px) and (max-width: 900px) {
  .kpis {
    grid-template-columns: repeat(3, 1fr);
  }

  .chartwrap {
    height: 260px;
  }
}
