/* ─── cm-portal · phone layer ─────────────────────────────────────────────────
 * ONE stylesheet for iOS and Android across all four portals. Loaded from
 * nav.js (admin), perms.js (rep), portal.js (vendor) and directly on the
 * customer and public pages.
 *
 * EVERYTHING here is inside a max-width media query. Nothing changes on a
 * desktop — that is deliberate: these are dense working screens that Chad uses
 * on a big monitor all day, and this work must not cost him anything there.
 *
 * The problem being solved: every page already carries
 * <meta name="viewport" content="width=device-width">, so the tags were never
 * the issue. The issue is that a 1300px-wide table on a 390px screen makes the
 * browser widen the LAYOUT viewport and scale the whole page down — the customer
 * list rendered with each column one character wide and the headers reading
 * downwards, letter by letter. Measured before this: 11 pages blew the layout
 * out (worst 913px), 4,006 tap targets under 40px, 1,235 pieces of text under
 * 12px.
 *
 * BREAKPOINTS
 *   ≤900px  phone and small tablet: stack, wrap, grow touch targets
 *   ≤640px  phone: tables become cards
 * ────────────────────────────────────────────────────────────────────────── */

@media (max-width: 900px) {

  /* iOS inflates text in landscape unless this is pinned. */
  html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

  /* Nothing may push the page wider than the screen. This is what stops the
     browser from zooming the whole layout out. */
  html, body { max-width: 100%; overflow-x: hidden; }
  img, svg, video, canvas, iframe, pre { max-width: 100%; height: auto; }

  /* The notch and the home indicator. Without this the first and last rows of
     content sit under them on an iPhone. */
  body {
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
  }

  /* ── Typing ──────────────────────────────────────────────────────────────
     16px is not a style choice. Safari on iOS ZOOMS THE PAGE IN when a field
     smaller than 16px takes focus, and does not zoom back out when it loses
     focus — the user is left stranded on a magnified page. Every field in the
     portal was smaller than this. */
  input, select, textarea, button {
    font-size: 16px !important;
    font-family: inherit;
    max-width: 100%;
  }
  input, select, textarea {
    min-height: 44px;
    box-sizing: border-box;
  }
  textarea { min-height: 88px; }
  /* Checkboxes and radios must NOT be stretched by the rule above. */
  input[type="checkbox"], input[type="radio"] {
    min-height: 0; width: 20px; height: 20px; flex: 0 0 auto;
  }

  /* ── Touch ───────────────────────────────────────────────────────────────
     44px is Apple's minimum and roughly Android's 48dp. Also kills the 300ms
     tap delay that makes every button feel broken. */
  button, .btn, .vp-btn, a.btn, [role="button"], .note-del, .tab, .cm-tab {
    min-height: 44px;
    touch-action: manipulation;
  }
  button, .btn, .vp-btn, a.btn {
    padding-top: 11px; padding-bottom: 11px;
  }
  /* Small inline buttons inside a row of actions can be shorter, but still
     need to be tappable — give them width instead of height. */
  .btn.sm, .vp-btn.sm, .note-del { min-height: 40px; padding-left: 14px; padding-right: 14px; }
  a { touch-action: manipulation; }

  /* ── Layout ──────────────────────────────────────────────────────────────
     Rows of controls built for a wide screen wrap instead of running off. */
  .row, .vp-row, .filters, .toolbar, .actions, .btn-row { flex-wrap: wrap !important; }
  .row > *, .filters > * { min-width: 0; }

  /* Two- and three-column grids collapse. */
  .grid, .grid2, .vp-grid2, .cols, .two-col, .three-col, .po-f {
    grid-template-columns: 1fr !important;
    display: grid !important;
  }

  /* Panels and cards lose their desktop padding so content gets the width. */
  .panel, .card, .vp-card, .box, section.panel { padding: 15px 14px !important; }
  .wrap, .vp-wrap, .container, .content, main {
    padding-left: 14px !important; padding-right: 14px !important;
    max-width: 100% !important;
  }

  /* Headings that were sized for a monitor. */
  h1 { font-size: 22px !important; line-height: 1.25; }
  h2 { font-size: 17.5px !important; }

  /* A heading with a button hanging off its right-hand side. */
  h1, h2 { display: block; }
  h1 > .btn, h2 > .btn, h1 > button, h2 > button { margin-top: 9px; }

  /* Anything that still insists on a fixed desktop width. */
  [style*="min-width:"], [style*="min-width :"] { min-width: 0 !important; }
  [style*="width:1"], [style*="width: 1"] { max-width: 100% !important; }

  /* A dialog opened on a page with the fixed admin bar must start BELOW it, or
     its heading and first field are hidden behind the bar. --cm-topbar-h is
     measured and published by shared/mobile.js, because the bar is two rows
     tall at 390px and three at 360px. Overlays in this codebase are either
     class="modal" or an id ending in "Modal". */
  .modal, [id$="Modal"] {
    padding-top: calc(var(--cm-topbar-h, 54px) + 12px) !important;
    padding-bottom: calc(16px + env(safe-area-inset-bottom)) !important;
  }
  /* An overlay's inner box should use the width it has. */
  [id$="Modal"] > div { max-width: 100% !important; width: 100% !important; }

  /* Modals become full-height sheets rather than a cramped floating box. */
  .modal { padding: 0 !important; align-items: flex-end !important; }
  .modal > .card, .modal > .box {
    max-width: 100% !important; width: 100% !important;
    border-radius: 14px 14px 0 0 !important;
    max-height: 92vh; overflow-y: auto;
    padding-bottom: calc(18px + env(safe-area-inset-bottom)) !important;
  }

  /* Text that was already small becomes unreadable once scaled. */
  .meta, .vp-muted, .muted, .hint, .empty { font-size: 13.5px !important; }

  /* A readable floor for the small UI furniture — status pills, table headers,
     tags. These sit at 10–11.5px for a desktop monitor; 12px is the lowest that
     stays legible at arm's length on a phone. Deliberately NOT raised to 16px,
     which would wrap every badge onto two lines. */
  th, .badge, .pill, .cm-pill, .vp-pill, .po-pill, .tag, .src-tag, .chip {
    font-size: 12px !important;
  }

  /* ── Flex rows written inline ────────────────────────────────────────────
     Most action bars are <div style="display:flex;gap:8px"> with no class, so
     a class-based rule cannot reach them. The customer list's six header
     buttons sat in one of these and ran 1,174px wide — the single biggest
     remaining overflow after the tables were fixed. */
  [style*="display:flex"], [style*="display: flex"] { flex-wrap: wrap !important; }

  /* A page header with a title on the left and buttons on the right. */
  .header, .page-header, .topline {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 10px !important;
  }
  .header .title, .page-header .title { font-size: 21px !important; }

  /* ── Admin top bar ───────────────────────────────────────────────────────
     Built for a wide screen: brand, section label, global search and a
     "Collapse all" button all on one line. On a phone the brand wrapped onto
     three lines and the search box collapsed into an empty rounded rectangle.
     The burger menu and drawer already work, so the bar only needs to shed what
     does not fit and give search its own row. */
  #cmTopbar {
    flex-wrap: wrap;
    row-gap: 8px;
    /* nav.js pins this to height:54px for the desktop single-row bar. Once the
       search box wraps onto its own row that clips, and the page content — which
       is offset by a hard-coded 54px — slides underneath the bar. Let it grow;
       shared/mobile.js then re-measures it and corrects the body offset. */
    height: auto !important;
    min-height: 54px;
    padding-top: calc(9px + env(safe-area-inset-top)) !important;
    padding-bottom: 9px !important;
  }
  #cmTopbar .cmbrand { font-size: 14px; white-space: nowrap; }
  #cmTopbar .cmsection, #cmTopbar .cmsecbtn { display: none !important; }
  #cmTopbar .cmspacer { flex: 1 1 auto; }
  #cmTopbar #cmSearchWrap { order: 10; flex: 1 0 100%; max-width: 100%; }
  #cmTopbar #cmSearchWrap input { width: 100%; box-sizing: border-box; }
  #cmTopbar #cmSearchResults { left: 0; right: 0; width: auto; }
}

/* ─── Tables become cards ────────────────────────────────────────────────────
 * A table with six or more columns cannot be made to fit a 390px screen by
 * shrinking it — that is exactly how the customer list ended up one character
 * per column. Each row becomes its own card instead, with the column name on
 * the left and the value on the right.
 *
 * The labels come from the table's own <th> text, copied onto each cell as
 * data-label by shared/mobile.js. A table that has no header row is left alone.
 * Opt a table out with class="cm-no-card".
 * ───────────────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {

  table.cm-m-card { display: block; width: 100%; border-collapse: separate; }
  table.cm-m-card thead { display: none; }
  table.cm-m-card tbody, table.cm-m-card tr, table.cm-m-card td { display: block; width: auto; }

  table.cm-m-card tr {
    border: 1px solid rgba(128, 128, 128, 0.28);
    border-radius: 11px;
    padding: 6px 12px;
    margin: 0 0 10px;
    background: rgba(128, 128, 128, 0.045);
  }
  table.cm-m-card tr:last-child { margin-bottom: 0; }

  table.cm-m-card td {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 14px;
    padding: 7px 0 !important;
    border: none !important;
    border-bottom: 1px solid rgba(128, 128, 128, 0.16) !important;
    text-align: right !important;
    font-size: 14px;
    white-space: normal !important;
  }
  table.cm-m-card td:last-child { border-bottom: none !important; }

  table.cm-m-card td::before {
    content: attr(data-label);
    flex: 0 0 38%;
    text-align: left;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    opacity: 0.62;
  }
  /* A cell with no label (an actions column) gets the full width. */
  table.cm-m-card td[data-label=""]::before,
  table.cm-m-card td:not([data-label])::before { content: none; }
  table.cm-m-card td[data-label=""], table.cm-m-card td:not([data-label]) {
    justify-content: flex-start; flex-wrap: wrap; gap: 8px; text-align: left !important;
  }
  /* The first cell reads as the card's title. */
  table.cm-m-card td.cm-m-title {
    font-size: 15.5px; font-weight: 700; padding-top: 2px !important;
  }
  table.cm-m-card td.cm-m-title::before { display: none; }
  /* Empty cells would otherwise show a lonely label. */
  table.cm-m-card td.cm-m-empty { display: none; }

  /* Buttons stacked inside an actions cell. */
  table.cm-m-card td .btn, table.cm-m-card td .note-del, table.cm-m-card td .vp-btn { flex: 0 1 auto; }

  /* A table we deliberately keep as a table still must not blow the page out. */
  table.cm-no-card { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

/* Wide elements that are not tables — code blocks, long tokens, URLs. */
@media (max-width: 640px) {
  .linkbox, code, kbd, samp { word-break: break-all; }
  input[readonly] { font-size: 13px !important; }
}
