/* ==========================================================================
   KSS HOS — shared responsive layer
   ==========================================================================
   Loaded from every dashboard page via a <link> placed AFTER that page's own
   inline <style>. A media query adds no specificity, so equal-specificity
   rules here win purely on source order -- which is why nothing below needs
   !important, and why the link must stay after the inline styles.

   Scope: layout only. Anything CSS cannot express (opening a module as its own
   page on a phone, injecting a way back) lives in mobile.js.

   Breakpoints:
     (pointer: coarse)   any touch input, any screen size
     max-width: 640px    phones (360-430 CSS px is typical; 640 also catches
                         small tablets in portrait and split-screen windows)
   The dashboard already had 720/900/1080/1150/1240px steps for desktop and
   tablet; this layer sits UNDER them and does not disturb them.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. Viewport height, all sizes.
   `100vh` on a mobile browser measures the viewport WITH the URL bar collapsed,
   so a 100vh shell is taller than what is actually visible and the bottom is
   clipped -- and it changes height as the bar hides, which makes the layout
   jump while scrolling. `100dvh` is the dynamic equivalent.

   Stated as an override rather than a replacement: a browser that does not
   know `dvh` discards the declaration as invalid and keeps the page's own
   100vh value, so this can only ever improve things.
   -------------------------------------------------------------------------- */
/* SCOPED ON PURPOSE. The page itself already releases the shell on narrow screens
   (`@media (max-width:1240px){ .app{height:auto} }`). Because this file loads last, an
   unscoped `.app{height:100dvh}` would OVERRIDE that release and lock a phone back to a
   single screen height with the content clipped underneath -- the opposite of the fix.
   So each dvh correction applies only where the original 100vh rule still governs. */
@media (min-width: 1241px) {
  .app { height: 100dvh; }
}
@media (min-width: 641px) {
  .ld { height: calc(100dvh - 150px); }
}

/* Module iframes carried their height in an inline style, which no stylesheet
   can override, so retail_ops.html now tags them with this class instead. The
   vh rule is the fallback; the dvh rule replaces it where supported. */
.modframe { height: calc(100vh - 132px); }
.modframe { height: calc(100dvh - 132px); }


/* --------------------------------------------------------------------------
   2. Touch input — independent of screen size.
   A finger needs a target of roughly 40-44px. This is keyed off the INPUT
   device, not the width, so it also covers touchscreen laptops, which a
   width-only rule would miss.
   -------------------------------------------------------------------------- */
@media (pointer: coarse) {
  .btn,
  .menu button,
  .subnav .subtab,
  .tabs button,
  select,
  input[type="date"],
  input[type="search"],
  input[type="text"],
  input[type="number"],
  input[type="password"] {
    min-height: 40px;
  }

  /* Deliberately smaller: these sit inline in dense table rows, where a 40px
     minimum would double every row's height. 34px is still a usable target. */
  .btn.sm,
  .tabs button {
    min-height: 34px;
  }

  /* Sortable headers show a pointer cursor and a hover tint that a touch
     device can never act on, and which sticks after a tap. */
  th { cursor: default; }
  tbody tr:hover { background: transparent; }
}


/* --------------------------------------------------------------------------
   3. Phones.
   -------------------------------------------------------------------------- */
@media (max-width: 640px) {

  /* 3.1 Reclaim horizontal space. Every module page uses .wrap with 20-22px of
     side padding; on a 360px screen that is ~11% of the width spent on margin. */
  .wrap { padding-left: 12px; padding-right: 12px; padding-bottom: 28px; }
  .panel { padding: 11px; border-radius: 13px; }

  /* 3.2 Collapse multi-column grids.
     Two groups, treated differently on purpose:
       - structural grids (side-by-side panels, form rows, fixed-px columns)
         go to a single column;
       - tile grids stay TWO across, because a column of full-width KPI cards
         is a very long scroll and the numbers are short enough to pair up. */
  .buckets,
  .tiles,
  .grid,
  .row,
  .split,
  .formrow,
  .formrow.roles,
  .formrow.schedule,
  .formrow.schedule2,
  .filter-grid,
  .reports-layout,
  .ld-main,
  .ld-people,
  .cockpit-body,
  .dash-charts,
  .dash-ops {
    /* `1fr` is shorthand for `minmax(AUTO, 1fr)`, and that `auto` minimum means the track
       is never allowed to shrink below its content's min-content width. A single dense
       table inside therefore widens the track, the grid, and the whole page -- measured at
       795px on a 430px viewport before this was changed. `minmax(0, 1fr)` removes the
       floor so the track really can be one screen wide. */
    grid-template-columns: minmax(0, 1fr);
  }

  /* The other half of the same trap: a grid/flex ITEM also defaults to `min-width: auto`.
     Both the track and the item have to be allowed to shrink, or the one that still has a
     content-based minimum wins and the page overflows anyway. */
  .panel, .card, .drawer, .scroll, .wrap > *, .split > * { min-width: 0; }

  .kpis,
  .mini,
  .kpi-strip,
  .ld-kpis {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* 3.3 Header rows stop competing for one line. */
  .head { flex-direction: column; align-items: stretch; gap: 10px; }
  .head h1 { font-size: 16px; }
  .tools { flex-wrap: wrap; }
  .tools > * { flex: 1 1 auto; }
  .tools > a.btn, .tools > button.btn { text-align: center; }

  /* 3.4 Nested scroll boxes.
     A max-height scroller inside a scrolling page means the page stops moving
     when your thumb happens to land inside the box. On a phone the page itself
     should be the only vertical scroller. */
  .scroll { max-height: none; overflow-y: visible; }

  /* 3.5 Wide tables scroll THEMSELVES rather than pushing the page sideways.
     Every table in this app is `white-space: nowrap`, which is right for dense
     financial columns and wrong for a 360px screen; making the table its own
     horizontal scroller keeps the columns readable and the page aligned. */
  .panel table,
  .card table,
  .scroll table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* 3.6 The dashboard shell. */
  .app { padding: 8px; gap: 8px; }
  .header { padding: 10px 12px; border-radius: 13px; }
  .title { font-size: 1.05rem; }
  .subtitle { display: none; }   /* decorative; the title already says where you are */
  .who { font-size: .74rem; }

  /* 3.7 The nav.
     Nine pills wrapping on a 360px screen costs three or four rows before any
     content appears. One horizontally-scrollable strip keeps it to a single
     row; the scrollbar is hidden because it is a thumb-swipe affordance here. */
  .menu {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .menu::-webkit-scrollbar { display: none; }
  .menu button { flex: 0 0 auto; }

  /* 3.8 The cockpit was built as a fixed one-screen 14" layout that must never
     scroll. That is exactly wrong on a phone: let it grow and scroll instead. */
  .dashboard-view.active { overflow: visible; }
  .ld { height: auto; grid-template-rows: none; }
  .cockpit { height: auto; overflow: visible; }
  .cockpit > .dash-charts { flex: 0 0 auto; }
  .chartbox { min-height: 200px; }

  /* 3.9 Login. */
  .card { padding: 16px; }

  /* 3.10 The tank slideshow — the thing that was spilling over the screen.
     `.tank-slide` is a two-column grid (`1fr 158px`) whose capsule is sized
     `height:100%` of a row that only HAS a height while the cockpit is a fixed
     one-screen layout. Released to auto height on a phone, the fixed column plus
     the capsule's own demands push the grid wider than the viewport. That is not
     just a cosmetic overflow: every sibling panel then lays out against the
     inflated width, which is why the attendant grid was computing four columns
     instead of two and the panel edges fell off-screen. Stack it instead. */
  .tank-slide {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto;
    grid-template-areas: "top" "cap" "kpis";
    gap: 8px;
    /* THE reason the capsule escaped its panel.
       `.tank-slide` is `flex: 1 1 0` inside the flex-COLUMN `.ld-panel`. A flex-basis of
       0 gives it a hypothetical height of ZERO, and `min-height: 0` removes the automatic
       content-based minimum that would otherwise have saved it. On desktop that is fine:
       the fixed-height cockpit gives the panel a definite height, so there is free space
       for flex-grow to consume. With the cockpit released to auto height on a phone there
       is no free space at all -- the slide computes to 0px and its 132px capsule simply
       paints outside the panel, over whatever panel comes next.
       On a phone it must size to its content instead of trying to fill a parent that has
       no height to give. */
    flex: 0 0 auto;
  }
  .tk-capsule { width: 100%; height: 132px; min-height: 132px; }
  .tk-kpis { grid-template-columns: 1fr; }

  /* Same trap, applied to the panel and every other child: `min-height: 0` is what lets a
     flex item collapse below its content. Restore the automatic minimum so panels grow to
     fit and the PAGE scrolls, which is the phone behaviour we want throughout. */
  .ld-panel, .ld-panel > * { min-height: auto; }
  .ld-bars { height: auto; overflow: visible; }

  /* 3.11 Blow-out guard. A grid/flex item defaults to `min-width:auto`, meaning it
     refuses to shrink below its content — the standard reason a layout ends up
     wider than the screen. */
  .ld, .ld-people, .ld-main, .ld-panel, .ld-att,
  .tank-slide, .cockpit, .cockpit-body { min-width: 0; }
  .ld-panel > *, .ld-att > * { min-width: 0; }

  /* 3.12 Attendant cards were being sliced through the amount.
     `.ld-att` is a scroll box sized for the fixed-height cockpit; with the cockpit
     released it still capped itself and cut each card off mid-figure. */
  /* Explicit rather than relying on auto-fill: auto-fill computes against the
     container's width, so if any overflow source remains it would again resolve
     to four columns. Two is what fits a phone. */
  .ld-att { overflow: visible; max-height: none;
            grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ld-attcard { overflow: visible; }

  /* 3.13 THE ONE THAT MADE EVERYTHING ELSE LOOK BROKEN.
     `.ld-bar` (the COMPANY / SHIFT / date strip) is a flex row, and flex defaults to
     `nowrap`. Its <select> is as wide as its LONGEST OPTION -- "SITE004 · CALTEX
     (Subway Service Station)" -- so the row's minimum width is roughly
     label + 300px select + shift + timestamp, about 700px.

     It is the first child of `.ld`, so that minimum became the minimum of `.ld`, then of
     `.view`, then of `.app`, and the whole page laid out at ~700px on a 390px screen.
     Every other symptom -- KPI cards off the right edge, the tank capsule out of its
     frame, panel borders cutting through text -- was those elements being sized against
     that inflated width, not a fault of their own.

     A <select> with long option text is the classic cause of this; it is why the
     max-width/min-width pair below is applied to form controls generally. */
  .ld-bar { flex-wrap: wrap; gap: 8px 10px; }
  .ld-bar > label { margin-right: 0; }
  .ld-bar select { flex: 1 1 100%; }
  .ld-shift, .ld-when { flex: 0 1 auto; }

  /* A replaced element sizes to its content unless told otherwise, and a grid/flex item
     defaults to `min-width:auto` -- together that is what lets one long string widen a
     whole page. */
  select, input, textarea { max-width: 100%; min-width: 0; }
  .app, .app > *, .view, .view.dashboard-view.active { min-width: 0; }
}
