/* =====================================================================
   H&T 1.0 — mobile & touch layer (Android / iOS)

   Loaded after app.css on every admin screen, so everything here wins on
   equal specificity. app.css stays the desktop design; this file is the
   one place that answers "what does that screen do on a phone".

   The rules that matter, and why:

   1. Nothing on a phone may scroll sideways. Wide list tables are not
      shrunk or side-scrolled — each row becomes a labelled card, so a
      14-column order list reads top to bottom like a document.
   2. iOS zooms the whole page in when a focused field is under 16px, and
      never zooms back out. Every field is 16px on a phone for that reason
      alone; it is not a type-scale choice.
   3. Fingers are not mice. Buttons, fields, tabs and menu rows are at
      least ~42px tall so they can be hit while walking a godown.
   4. The notch and the home indicator are not screen. Everything that
      touches an edge is padded with env(safe-area-inset-*).
   5. Every query is `screen and …` so a phone still PRINTS the real
      table, not the card stack.

   Widths used here: 1100 (small laptop) · 900 (tablet / drawer) ·
   760 (phone) · 560 (small phone).
   ===================================================================== */


/* =====================================================================
   0 · Global hardening — every width, phone or desktop
   ===================================================================== */

html {
  -webkit-text-size-adjust: 100%;      /* iOS: stop the landscape text inflation */
  text-size-adjust: 100%;
}
body {
  -webkit-tap-highlight-color: rgba(37, 99, 235, .14);
}

/* Nothing may be wider than its box. */
img, video, canvas { max-width: 100%; height: auto; }
svg { max-width: 100%; }
pre, code { overflow-x: auto; max-width: 100%; }

/* Icons inside a full-size button had no size rule at all — an inline
   <svg> with only a viewBox falls back to 300x150. Every .btn gets one. */
.btn svg { width: 15px; height: 15px; flex: 0 0 15px; }

/* The drawer's close button exists only while there is a drawer to close. */
.nav-close { display: none; }

/* Mobile browsers report 100vh as the height WITHOUT the URL bar, so a
   100vh sidebar sits partly under it. dvh is the live viewport height. */
.sidebar { height: 100vh; height: 100dvh; }
.login-wrap {
  min-height: 100vh;
  min-height: 100dvh;
  padding: 24px 16px;
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
  padding-bottom: max(24px, env(safe-area-inset-bottom));
}

/* Side-scrolling regions should feel native and not steal the page swipe. */
.table-wrap, .pipe, .flow, .tabs, .rkbar, .scroll-tbl, .dtree-wrap {
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}


/* =====================================================================
   1 · Responsive layout utilities
   These replace the hard-coded `style="grid-template-columns: repeat(N, 1fr)"`
   that used to sit on the KPI strips — an inline style beats every media
   query, so a 7-across strip stayed 7-across on a 390px phone.
   ===================================================================== */

/* A KPI / tile strip that decides its own column count from the space it
   has. One rule covers the 4, 6 and 7 tile strips at every width. The
   150px floor is chosen so a full-width desktop still lays all seven out
   in one row, exactly as the hard-coded repeat(7, 1fr) did. */
.kpi-strip {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  margin-bottom: 18px;
}

/* Quick-action pairs that want to stay a pair while there is room. */
.qa-grid.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* A narrow picker column beside the content it drives (Reports). */
.split-side {
  display: grid;
  gap: 18px;
  grid-template-columns: 240px minmax(0, 1fr);
  align-items: start;
}

/* A summary panel beside a wider table (Users). */
.split-1-2 {
  display: grid;
  gap: 16px;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  align-items: start;
}

@media screen and (max-width: 900px) {
  .split-side, .split-1-2 { grid-template-columns: 1fr; }
}
@media screen and (max-width: 560px) {
  .kpi-strip { gap: 10px; grid-template-columns: repeat(auto-fit, minmax(138px, 1fr)); }
}

/* Grids a view still sets inline because the column count is computed at
   render time (the rake board) or the panel wants uneven thirds. Inline
   styles only lose to !important, so these say so out loud. */
/* 5 → 3 → 2, never 4 — see the note beside the same rule in app.css. Four
   across is the one count that strands the fifth tile on a row of its own. */
@media screen and (max-width: 1400px) { .board-qty { grid-template-columns: repeat(5, minmax(0, 1fr)) !important; } }
@media screen and (max-width: 1100px) { .xbox { grid-template-columns: 1fr !important; } }
@media screen and (max-width: 1080px) { .board-qty { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; } }
@media screen and (max-width: 700px)  { .board-qty { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; } }


/* =====================================================================
   2 · Tablet and below (<= 1100px)
   ===================================================================== */

@media screen and (max-width: 1100px) {
  .content { padding: 18px 18px 48px; }
  .figs { gap: 8px; }
  .rkbar { max-height: none; }
}


/* =====================================================================
   3 · Drawer width (<= 900px) — the sidebar becomes an off-canvas menu
   app.css already flips it to a drawer; this makes the drawer usable:
   a real close button, a locked background, safe-area padding and
   finger-sized rows.
   ===================================================================== */

@media screen and (max-width: 900px) {

  /* ---- the drawer itself ---- */
  .sidebar {
    width: 272px;
    max-width: 86vw;
    padding-left: env(safe-area-inset-left);
    padding-bottom: env(safe-area-inset-bottom);
    overscroll-behavior: contain;
  }
  .sidebar .brand { padding: 14px 14px 12px; position: relative; }
  .nav { padding: 8px 8px 14px; }

  /* Menu rows at finger size. */
  .nav a       { padding: 12px 12px; font-size: 14px; margin: 1px 0; }
  .navg-h      { padding: 12px 12px; font-size: 13.5px; }
  .navg-b a    { padding: 11px 12px; font-size: 13.5px; }
  .navg-b      { padding-left: 12px; }

  /* Close button — a drawer you can only shut by guessing where the
     backdrop is does not read as closeable on a phone. */
  .nav-close {
    display: flex; align-items: center; justify-content: center;
    position: absolute; top: 12px; right: 10px;
    width: 36px; height: 36px; padding: 0;
    background: rgba(255, 255, 255, .08); border: 1px solid var(--navy-line);
    border-radius: 9px; color: #e2e8f0; font-size: 22px; line-height: 1; cursor: pointer;
  }
  .nav-close:hover { background: rgba(255, 255, 255, .16); color: #fff; }
  .brand > div:nth-of-type(2) { padding-right: 42px; }   /* clear of the × */

  /* Background locked while the drawer is open. The inline `top` that the
     layout's script writes keeps the reading position. */
  body.nav-open {
    position: fixed; left: 0; right: 0; width: 100%;
    overflow: hidden;
  }

  /* ---- topbar ---- */
  .topbar {
    padding: 9px 14px;
    padding-left: max(14px, env(safe-area-inset-left));
    padding-right: max(14px, env(safe-area-inset-right));
    gap: 10px;
  }
  .topbar > div { min-width: 0; }
  .topbar > div:nth-of-type(1) { flex: 1 1 auto; }
  .topbar h1 {
    font-size: 15.5px; line-height: 1.25;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  .topbar .right { gap: 12px; flex: 0 0 auto; }
  .menu-btn { width: 42px; height: 42px; flex: 0 0 42px; font-size: 20px; }

  /* ---- content ---- */
  .content {
    padding: 16px 16px 56px;
    padding-left: max(16px, env(safe-area-inset-left));
    padding-right: max(16px, env(safe-area-inset-right));
    padding-bottom: calc(56px + env(safe-area-inset-bottom));
  }
  .card { padding: 14px; border-radius: 11px; margin-bottom: 14px; }

  /* ---- touch targets ---- */
  .btn { min-height: 42px; padding: 9px 16px; }
  .btn.sm { min-height: 36px; padding: 6px 12px; font-size: 12.5px; }
  .fbtn { min-height: 36px; }
  .xtog { width: 32px; height: 32px; font-size: 14px; }
  .dtoggle { width: 30px; height: 30px; font-size: 13px; }

  /* iOS zooms in on any field under 16px and never zooms back out. */
  input[type=text], input[type=number], input[type=password], input[type=date],
  input[type=datetime-local], input[type=search], input[type=tel], input[type=email],
  input[type=time], select, textarea, .ss-input {
    font-size: 16px;
    min-height: 42px;
    padding: 9px 12px;
    border-radius: 9px;
  }
  table.data.compact input, table.data.compact select,
  .xact input, .xact select, .xact textarea {
    font-size: 16px;
    min-height: 40px;
  }
  input[type=checkbox], input[type=radio] { width: 18px; height: 18px; }
  textarea { min-height: 84px; }

  /* The browser's raw file control is a 20px-tall grey button next to a
     filename — unhittable with a thumb, and the only unstyled thing on the
     form. Give it the same box as every other field. */
  input[type=file] {
    width: 100%; min-height: 42px; padding: 8px 10px; font-size: 14px;
    border: 1px solid var(--bd-4); border-radius: 9px; background: var(--sf-1); color: var(--muted);
  }
  input[type=file]::file-selector-button {
    margin-right: 10px; padding: 7px 13px; min-height: 30px;
    border: 1px solid var(--bd-4); border-radius: 7px; background: var(--sf-7);
    font: 600 13px var(--font); color: var(--ink);
  }

  /* Tab strips scroll sideways instead of stacking into five rows. */
  .tabs, .tabs.stage-tabs, .tabs.inv-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tabs a { flex: 0 0 auto; padding: 11px 14px; }

  /* Filter bars: one control per line, so nothing is 60px wide. The
     !important beats the inline widths the views set on some fields. */
  form.row > div,
  .rd-bar form.row > div {
    flex: 1 1 100% !important;
    width: auto !important;
    min-width: 0 !important;
  }
  form.row > div.row { flex-wrap: wrap; gap: 8px; }
  form.row > div.row .btn { flex: 1 1 auto; justify-content: center; }
  .content form input, .content form select, .content form textarea { max-width: 100% !important; }
  .rk-filter { width: 100%; }
  .rk-filter input[type=search] { width: 100%; flex: 1 1 100%; }

  /* Dropdown panels stay on screen. */
  .flt-panel { min-width: min(250px, 78vw); max-width: 86vw; max-height: 55vh; }
  .ss-list { max-height: 48vh; }

  /* A checkbox label carrying a supplier's full name cannot stay on one
     line at 360px — let it wrap beside its box. */
  .flt-check { white-space: normal; align-items: flex-start; line-height: 1.45; }
  .flt-check input { flex: 0 0 auto; margin-top: 2px; }

  /* Export bar: one labelled group per line. */
  .export-bar { gap: 8px; }
  .export-bar .export-title { flex: 1 1 100%; }
  .export-group { flex: 1 1 100%; flex-wrap: wrap; }

  /* Panels that cap their own height do not need to on a phone — the
     page scrolls, and a scroll box inside a scroll page fights the thumb. */
  .dtree-wrap, .scroll-tbl, .rkbar { max-height: none; overflow-y: visible; }
  .scroll-tbl th { position: static; }

  /* Charts and hero blocks. */
  .hero-top { padding: 13px 14px; }
  .hero-body { padding: 13px 14px 15px; }
  .bars { gap: 10px; height: 130px; }
  .bars .bar { width: 14px; }
  .donut-wrap { gap: 14px; }
  .qa-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
}


/* =====================================================================
   4 · Phone (<= 760px) — list tables become cards

   A 14-column order list cannot be read on a 390px screen, and pinching
   a side-scrolling table to find the Action button is how the app "looks
   odd". So every list table is turned into one card per row, each field
   on its own line with the column heading as its label. The layout's
   script supplies the labels (data-l) from the table's own header row,
   so this works on every screen without touching a single view.
   ===================================================================== */

@media screen and (max-width: 760px) {

  .content { padding: 13px 13px 52px;
             padding-left: max(13px, env(safe-area-inset-left));
             padding-right: max(13px, env(safe-area-inset-right));
             padding-bottom: calc(52px + env(safe-area-inset-bottom)); }
  .card { padding: 13px 12px; }
  .card h2 { font-size: 15px; }

  /* ---- the card stack ----
     A wrapper whose table became cards has nothing left to scroll, and a
     leftover scroll box would swallow the page swipe. Wrappers around the
     tables that stayed tables keep theirs. */
  .table-wrap:has(table.rt) { overflow-x: visible; }

  /* Everything below keys off the classes the layout's script puts on the
     table's OWN rows and cells (.rt-head / .rt-row / .rt-span / .rt-cell).
     Selecting plain `td` would also catch the cells of the tables nested
     inside an unfolded document row and stack those too; a child chain
     would in turn miss the rows that JS appends straight to <table>
     without a <tbody>. The classes are right in both cases. */
  table.data.rt { display: block; width: 100%; border-collapse: separate; }
  table.data.rt > thead, table.data.rt > tbody, table.data.rt > tfoot { display: block; }

  /* The header row is the label source, not something to draw. */
  table.data.rt tr.rt-head { display: none; }

  /* hidden rows stay hidden — `display:block` below would otherwise beat
     the browser's own [hidden] rule and unfold every detail panel. */
  table.data.rt tr.rt-row[hidden], table.data.rt tr.rt-span[hidden] { display: none !important; }

  table.data.rt tr.rt-row, table.data.rt tr.rt-span {
    display: block;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--card);
    margin: 0 0 10px;
    padding: 4px 12px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, .04);
  }
  table.data.rt tr.rt-row:hover > td { background: transparent; }

  /* The label is FLOATED, not a flex item. A flex cell would turn the
     cell's own contents into flex items too, so "0" and its unit would be
     flung to opposite ends of the line. Floating keeps the value one
     normal run of text that simply wraps under the label when it is long;
     flow-root contains the float without clipping the dropdowns that
     open out of a cell. */
  table.data.rt td.rt-cell {
    display: flow-root;
    padding: 8px 0;
    border-bottom: 1px dashed var(--bd-1);
    text-align: right;
    white-space: normal;
  }
  table.data.rt td.rt-cell:last-child { border-bottom: 0; }

  table.data.rt td.rt-cell::before {
    content: attr(data-l);
    float: left;
    width: 38%;
    padding-right: 10px;
    text-align: left;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted);
    line-height: 1.7;
  }
  /* An unlabelled column (the ▸ handle, a spacer) has nothing to align to. */
  table.data.rt td.rt-cell[data-l=""] { text-align: left; }
  table.data.rt td.rt-cell[data-l=""]::before { display: none; }

  /* A cell being typed into wants its field full width, so the label goes
     above it rather than beside it. */
  table.data.rt td.rt-cell:has(input, select, textarea) { text-align: left; }
  table.data.rt td.rt-cell:has(input, select, textarea)::before {
    float: none; display: block; width: auto; padding: 0 0 4px;
  }

  /* The row's own action buttons: full width, under their label. */
  table.data.rt td.rt-cell.actions {
    display: block;
    text-align: left;
    padding: 10px 0 4px;
    min-width: 0 !important;
  }
  table.data.rt td.rt-cell.actions::before {
    display: block; float: none; width: auto; margin-bottom: 7px;
  }
  table.data.rt td.actions form { display: block; margin: 0 0 6px; }
  table.data.rt td.actions > .btn,
  table.data.rt td.actions form > .btn { width: 100%; justify-content: center; }
  table.data.rt td.actions .actions { display: flex; flex-wrap: wrap; gap: 6px; }
  table.data.rt td.actions .actions .btn { width: auto; flex: 1 1 44%; }

  /* The ▸ handle becomes a labelled full-width control — on a card, a
     24px arrow in a corner is not a discoverable "open this document". */
  table.data.rt td.rt-cell.rt-c0 {
    padding: 10px 0 8px; border-bottom: 1px solid var(--line);
  }
  table.data.rt td.rt-c0 > .xtog {
    width: 100%; height: auto; min-height: 38px; padding: 0 12px;
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    font-size: 13px; font-weight: 700; border-radius: 9px;
    transform: none !important;                 /* the label must not rotate */
  }
  table.data.rt td.rt-c0 > .xtog::after { content: "Full details"; }
  table.data.rt td.rt-c0 > .xtog.open::after { content: "Hide details"; }

  /* Rows that span columns — sub-headings, totals, "no rows", the detail
     panel. They do not map onto the columns, so they take the whole card. */
  table.data.rt tr.rt-span:not(.xrow) {
    display: flex; flex-wrap: wrap; align-items: baseline;
    justify-content: space-between; gap: 4px 12px;
  }
  table.data.rt tr.rt-span:not(.xrow) > td,
  table.data.rt tr.rt-span:not(.xrow) > th {
    display: block; border-bottom: 0; padding: 7px 0; text-align: left; white-space: normal;
    background: transparent;
  }
  table.data.rt tr.rt-span > td::before,
  table.data.rt tr.rt-span > th::before { display: none; }

  /* The unfolded document sits flush under the card it belongs to. */
  table.data.rt tr.rt-span.xrow {
    padding: 0; border: 0; margin: -8px 0 12px; background: transparent; box-shadow: none;
  }
  table.data.rt tr.rt-span.xrow > td {
    display: block; padding: 0; text-align: left;
    border: 1px solid var(--line); border-top: 0; border-radius: 0 0 12px 12px;
  }
  table.data.rt tr.rt-row.xopen { border-radius: 12px 12px 0 0; margin-bottom: 0; }
  table.data.rt tr.rt-row.xopen > td { background: transparent; }

  /* Dealers master paints its own row colours through an #id selector. */
  #dealerTable.rt tr.drow > td, #dealerTable.rt tr.srow > td { background: transparent; }
  #dealerTable.rt tr.drow { background: var(--tint-blue-1); border-color: var(--tint-blue-7); }
  #dealerTable.rt tr.srow > td:first-child { border-left: 0; }

  /* Tables inside an unfolded document stay tables — they are narrow
     columns — but they scroll rather than stretch the card. */
  table.xtab { display: block; overflow-x: auto; white-space: nowrap; font-size: 12px; }
  .xbox > * { padding: 12px 13px; }

  /* ---- everything else on a phone ---- */
  .topbar h1 { font-size: 15px; }

  /* A headline tile carries a label, one number and a caption — two of
     them fit a phone comfortably, and one-up would mean scrolling past
     seven near-empty cards to reach the list. Scoped to grids that
     actually hold tiles, so the .cols-4 grids used for checkbox banks and
     form rows keep stacking one per line. */
  .grid:has(> .kpi) { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }

  .dl { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px 14px; }
  .kpi .k-value { font-size: 23px; }
  .dash-kpi .k-value { font-size: 26px; }
  .rd-kpi-v { font-size: 24px; }
  .flow { flex-wrap: wrap; gap: 8px; }
  .flow .step { flex: 1 1 calc(50% - 4px); min-width: 0; padding: 10px 6px 8px; }
  .flow .step .n { font-size: 22px; }
  .figs { grid-template-columns: repeat(2, 1fr); }

  /* A <summary> laid out as a flex row turns each run of text into its own
     column, so the sentence ends up in four narrow strips. Let it be prose. */
  .xpanel > summary { display: block; }
  .xpanel > summary .xsign { float: left; margin: 3px 9px 0 0; }
  .xpanel > summary .muted { display: block; margin-top: 3px; }
  .idgrid { grid-template-columns: repeat(2, 1fr); }
  .tracker { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  .needs { grid-template-columns: repeat(auto-fit, minmax(102px, 1fr)); }
  /* A grid track is at least as wide as its widest item unless the item is
     told it may shrink — without minmax(0,…) plus min-width:0 the rake
     cards keep the strip wider than the screen. */
  .rkbar { grid-template-columns: minmax(0, 1fr); }
  .rkcard, .rk-top, .rk-nums, .rk-nums > span { min-width: 0; }
  .rk-top { flex-wrap: wrap; }
  .rk-no { min-width: 0; }
  .xfacts { gap: 8px; }
  .xf { flex-direction: column; gap: 1px; }
  .xf .l { flex: none; font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; font-weight: 700; }
  .xf .v { font-size: 13px; }
  .screen-note { font-size: 12px; }
  .banner, .flash { font-size: 13px; padding: 10px 12px; }
  .pipe .pstep { min-width: 92px; }
}


/* =====================================================================
   5 · Small phone (<= 560px)
   ===================================================================== */

@media screen and (max-width: 560px) {
  .topbar { padding: 8px 11px; gap: 8px; }
  .topbar h1 { font-size: 14.5px; }
  .topbar .right { gap: 10px; }
  .topbar .right .userchip { display: none; }   /* the drawer already names the user */
  .content { padding: 11px 11px 48px;
             padding-left: max(11px, env(safe-area-inset-left));
             padding-right: max(11px, env(safe-area-inset-right));
             padding-bottom: calc(48px + env(safe-area-inset-bottom)); }
  .card { padding: 12px 11px; border-radius: 10px; }

  table.data.rt tr.rt-row, table.data.rt tr.rt-span { padding: 3px 11px; }
  table.data.rt td.rt-cell { font-size: 12.5px; padding: 7px 0; }
  table.data.rt td.rt-cell::before { width: 42%; font-size: 9.5px; }
  table.data.rt td.actions .actions .btn { flex: 1 1 100%; }

  /* Only once the line is genuinely narrow do the export buttons share it. */
  .export-group .btn { flex: 1 1 auto; justify-content: center; }

  .kpi.kpi-ico { gap: 10px; }
  .k-ico { width: 38px; height: 38px; flex: 0 0 38px; }
  .k-ico svg { width: 19px; height: 19px; }
  .qa-grid, .qa-grid.two { grid-template-columns: 1fr; }
  .chips .chip { flex: 1 1 100%; justify-content: flex-start; }
  .daystrip .day, .board-notes .note { flex: 1 1 100%; }
  .login-card { padding: 26px 20px 22px; }
  .totalbox .v { font-size: 17px; }
  .sec h2 { font-size: 14.5px; }
}


/* =====================================================================
   6 · Safety net
   A phone must never scroll sideways. `clip` (unlike `hidden`) is not a
   scroll container, so the sticky topbar keeps working; browsers without
   it simply ignore the line.
   ===================================================================== */

@media screen and (max-width: 900px) {
  html, body { max-width: 100%; overflow-x: clip; }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar, .kpi, .rd-kpi, .rkcard, .flow .step, .tk, .qlink, .chip { transition: none !important; }
}


/* Company allocation budget — on a phone the name and the remainder stop
   competing for one line, and the calculation footnote steps down a size. */
@media screen and (max-width: 640px) {
  .cbtop { flex-direction: column; align-items: flex-start; gap: 2px; }
  .cbleft { white-space: normal; }
  .cbkeys { gap: 3px 10px; font-size: 11px; }
  .cbcalc { font-size: 10.5px; }
}
