/* ──────────────────────────────────────────────────────────────────
   Mobile / responsive layer — loaded LAST so it wins the cascade.
   Every rule lives behind a max-width media query (or targets the
   .subnav-wrap class introduced with this layer), so desktop rendering
   is byte-identical to the pre-responsive design.

   Breakpoint tiers:
     ≤ 900px  — shell restructure: the dark icon rail becomes a fixed
                bottom navigation bar (phones + folded/portrait tablets).
     ≤ 700px  — content compression: paddings, 2-col KPI grid, stacked
                report grids, scrollable tables, bottom-sheet modals.
     ≤ 400px  — smallest phones (Galaxy Fold cover screen is 344px).
   ────────────────────────────────────────────────────────────────── */

/* Sub-nav wrapper (base.html) — desktop value matches the inline style it
   replaced: `padding: 0 56px; margin-top: 18px`. */
.subnav-wrap { padding: 0 56px; margin-top: 18px; }

/* Tools with fewer than 2 visible pages render no tab-row (tool_subnav
   hides itself — e.g. Workspace → Users) but base.html still emits the
   sticky wrap. Without tabs it's phantom whitespace at rest and an empty
   glass sliver once stuck (a lone floating title on desktop, a bare 17px
   strip on mobile) — hide the wrap entirely. */
.subnav-wrap:not(:has(.tab-row)) { display: none; }

/* ══════════════════════════════════════════════════════════════════
   ≤ 900px — shell: rail moves to the bottom edge
   ══════════════════════════════════════════════════════════════════ */
@media (max-width: 900px) {
    #app-v1 {
        /* minmax(0,1fr), NOT bare 1fr — a bare 1fr column can't shrink below
           its content's min-width, so one long unwrappable string (e.g. a
           long page name in the topbar breadcrumb) silently stretches the
           whole shell wider than the phone. CLAUDE.md pitfall, in the shell
           itself. */
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: 52px minmax(0, 1fr) auto;
        height: 100dvh;
    }
    body[data-chrome="rail-only"] #app-v1 {
        grid-template-rows: 0 minmax(0, 1fr) auto;
    }

    /* Rail → horizontal bottom nav. Same dark glass surface, items in a
       row, active indicator moves from the left edge to the top edge. */
    .rail {
        grid-row: 3;
        grid-column: 1;
        flex-direction: row;
        align-items: center;
        justify-content: flex-start;
        padding: 8px 10px calc(8px + env(safe-area-inset-bottom, 0px));
        gap: 4px;
        overflow-x: auto;
        overflow-y: hidden;
        scrollbar-width: none;
    }
    .rail::-webkit-scrollbar { display: none; }
    .vibe-mode .rail {
        border-right: 0;
        border-top: 0.5px solid rgba(255, 255, 255, 0.08);
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, 0.04),
            0 -2px 24px rgba(15, 23, 42, 0.10);
    }
    .rail .brand-mark {
        width: 34px; height: 34px;
        margin-bottom: 0;
        margin-right: 2px;
        flex-shrink: 0;
    }
    .rail .brand-mark img { width: 26px; height: 26px; }
    .rail .rail-divider { width: 1px; height: 26px; margin: 0 4px; flex-shrink: 0; }
    .rail .rail-item { width: 42px; height: 42px; }
    .rail .rail-item.active { box-shadow: inset 0 2px 0 var(--brand); }
    /* Hover tooltips + the add-tool tile make no sense on touch. */
    .rail .rail-item .tt { display: none; }
    .rail .add-tool { display: none; }
    .rail .rail-avatar { margin-top: 0; margin-left: 2px; }

    .v1-topbar { grid-column: 1; padding: 0 14px; }
    .v1-main { grid-column: 1; grid-row: 2; overflow-x: hidden; }

    /* User menu flies out above the bottom nav instead of beside the rail. */
    .user-menu {
        left: 12px; right: 12px;
        width: auto;
        bottom: calc(72px + env(safe-area-inset-bottom, 0px));
    }

    /* Notification flyout: same treatment as the user menu. */
    .notify-menu {
        left: 12px; right: 12px;
        width: auto;
        bottom: calc(72px + env(safe-area-inset-bottom, 0px));
        max-height: 60dvh;
    }

    /* Tool sub-nav — wraps onto extra rows exactly like the Rep/Range pill
       groups (Tanveer 2026-07-03: sideways scroll hides the trailing pills —
       same undiscoverability call as .pill-group). The capsule squares to
       18px like .pill-group.is-wrapped so multi-row doesn't read stadium. */
    .subnav-wrap {
        padding: 14px 14px 0;
        margin-top: 0;
    }
    .subnav-wrap .tab-row {
        flex-wrap: wrap;
        width: 100%;
        max-width: 100%;
        overflow: visible;
        margin-bottom: 14px;
        border-radius: 18px;
        row-gap: 2px;
    }
    /* Sectioned rows (Sales, Calls): each group becomes a full-width block —
       its label turns static on its own line, the group's tabs wrap beneath.
       The absolute overhanging labels + left-border separators only make
       sense when everything shares one line. */
    .subnav-wrap .tab-row.show-section-labels { padding-top: 8px; }
    .subnav-wrap .tab-row .tab-group {
        flex-wrap: wrap;
        width: 100%;
        row-gap: 2px;
        /* Desktop keeps position:relative (v1.css) to anchor the absolute
           overhanging group labels — but ≤900 those labels are static
           (below) or hidden (stuck), and the relative silently broke the
           stuck bar's scroll-active-tab-into-view math in app.js
           (tab.offsetLeft became group-relative, so Operate-group tabs —
           Settings / Admin / Kiosk — parked off-screen right). Static
           restores row-relative offsets. */
        position: static;
    }
    .subnav-wrap .tab-row .tab-group + .tab-group {
        margin-left: 0;
        padding-left: 0;
        border-left: 0;
        height: auto;
        margin-top: 4px;
    }
    .subnav-wrap .tab-row .tab-group-label {
        position: static;
        flex-basis: 100%;
        margin: 0 10px 2px;
    }
    /* /design-system demo stages render raw .tab-row examples outside
       .subnav-wrap — give them the same wrap treatment so the catalog page
       itself verifies clean on phones (was the page's only x-overflow). */
    .ds-stage .tab-row {
        flex-wrap: wrap;
        width: 100%;
        max-width: 100%;
        overflow: visible;
        border-radius: 18px;
        row-gap: 2px;
    }
    .ds-stage .tab-row.show-section-labels { padding-top: 8px; }
    .ds-stage .tab-row .tab-group {
        flex-wrap: wrap;
        width: 100%;
        row-gap: 2px;
        position: static;
    }
    .ds-stage .tab-row .tab-group + .tab-group {
        margin-left: 0;
        padding-left: 0;
        border-left: 0;
        height: auto;
        margin-top: 4px;
    }
    .ds-stage .tab-row .tab-group-label {
        position: static;
        flex-basis: 100%;
        margin: 0 10px 2px;
    }
    /* Sticky (sales) wrap: stays pinned on mobile, but the full wrapped
       multi-row bar would hold 100px+ of viewport hostage — so the moment it
       actually pins (.is-stuck, app.js sentinel) it collapses to one slim
       swipeable row (labels off, groups inline). Scrolling back to the top
       restores the wrapped all-visible view. The tab-row margin is zeroed
       for the sticky centering (theme.css), so the below-subnav spacing
       rides on the wrap. */
    .subnav-wrap.subnav-sticky { margin-bottom: 14px; }
    .subnav-stuck-title { display: none; }
    .subnav-wrap.subnav-sticky.is-stuck {
        padding-top: 8px;
        padding-bottom: 8px;
    }
    .subnav-wrap.subnav-sticky.is-stuck .tab-row {
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
        border-radius: 999px;
        row-gap: 0;
    }
    .subnav-wrap.subnav-sticky.is-stuck .tab-row::-webkit-scrollbar { display: none; }
    .subnav-wrap.subnav-sticky.is-stuck .tab-row.show-section-labels { padding-top: 4px; }
    .subnav-wrap.subnav-sticky.is-stuck .tab-group {
        flex-wrap: nowrap;
        width: auto;
    }
    .subnav-wrap.subnav-sticky.is-stuck .tab-group + .tab-group {
        margin-left: 10px;
        padding-left: 10px;
        border-left: 1px solid var(--hairline);
        margin-top: 0;
    }
    .subnav-wrap.subnav-sticky.is-stuck .tab-group-label { display: none; }

    /* Filter bar: long ranges (This Week … Custom) overflow even at tablet
       widths, so the wrap behavior belongs to the ≤900 shell tier, not just
       phones. (Pill groups themselves flex-wrap globally in theme.css —
       the old sideways-scroll-with-hidden-scrollbar rules are gone; they
       made the trailing pills undiscoverable.) */
    .filter-bar { flex-wrap: wrap; }

    /* Wide admin tables (workspace users matrix, sales roster, tablet fleet)
       scroll sideways inside their card instead of clipping or blowing the
       page out. Same pattern as .tbl in the ≤700 tier. */
    .users-table,
    .roster-tbl,
    .fleet-table {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* ══════════════════════════════════════════════════════════════════
   ≤ 700px — content compression (phones)
   ══════════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {
    .page-wrap,
    .density-comfort .page-wrap,
    .density-dense .page-wrap { padding: 14px 14px 40px; }
    body[data-chrome="rail-only"] .v1-main .page-wrap { padding-top: 8px; }

    .page-head { flex-wrap: wrap; gap: 12px; }
    .page-head .page-actions,
    .home-wrap .page-head .page-actions { flex-wrap: wrap; }
    /* Inline-styled page headers (workspace users, account) set display:flex
       inline but never flex-wrap — let the action button drop below the
       title instead of squeezing it. */
    .page-header { flex-wrap: wrap; gap: 12px; }
    .vibe-soft .page-head .page-title { font-size: 24px; }
    .density-comfort .page-title { font-size: 20px; }

    /* KPI grid: two tight columns instead of one long single-column scroll. */
    .weekly-kpi-grid,
    .density-dense .weekly-kpi-grid,
    .density-comfort .weekly-kpi-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 10px;
    }
    .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* Report / layout grids collapse to a single column. */
    .two-col, .three-col { grid-template-columns: minmax(0, 1fr); }
    .detail-grid { grid-template-columns: minmax(0, 1fr); }
    .rep-card-grid { grid-template-columns: minmax(0, 1fr); }
    .vibe-soft .grid-soft [class*="span-"] { grid-column: 1 / -1; }

    /* Cards: slightly tighter shells so content wins the width budget. */
    .vibe-soft .vc, .vibe-soft .card { padding: 16px; border-radius: 18px; }
    .density-comfort .vc { padding: 14px 16px; }
    .report-bento .vc, .report-row .vc { padding: 16px 14px 12px; }
    .report-bento { gap: 16px; }
    .sales-summary > .vc { margin-bottom: 16px; }

    /* Conversion-funnel bar rows: the 168px label column steals too much of
       a phone width — stack the stage label above its bar, keep the conv
       badge beside the bar. */
    .funnel-bar-row {
        grid-template-columns: minmax(0, 1fr) auto;
        row-gap: 4px;
    }
    .fb-label { grid-column: 1 / -1; text-align: left; }

    /* Filter bar: keep the glass bar, tighten it, let segments wrap and
       long pill-groups scroll sideways within it. */
    .filter-bar { gap: 10px; padding: 10px 12px; margin: 10px 0 8px; }
    /* Per-report window pills: let the section-eyebrow row and the card
       headers wrap so the pill cluster drops below the title instead of
       pushing past fold-width viewports (+42px at 344 otherwise). */
    .mockup-section-eyebrow,
    .report-bento .vc .vc-head { flex-wrap: wrap; row-gap: 6px; }
    .mockup-section-eyebrow .eyebrow-controls { flex-wrap: wrap; row-gap: 6px; }
    .card-actions { flex-wrap: wrap; justify-content: flex-end; max-width: 100%; }
    .filter-segment { flex-wrap: wrap; }
    /* (Pill groups wrap globally via theme.css — no sideways scroll.) */

    /* CX sticky filter strips: tighter capsule on phones — they pin
       multiple label+pill rows, so every pixel of padding counts. top
       clears the stuck sub-nav's mobile collapsed height (bottom edge
       56px; 55px overlaps by 1px so no raw content peeks through).
       The PINNED full-bleed horizontal padding still comes from the
       theme.css .is-stuck longhands — they outrank this shorthand on
       specificity, so only the rest-state capsule is tightened here. */
    .cx-reports-groupbar { padding: 8px 12px; gap: 8px 16px; top: 55px; }

    /* CX overview sticky Type/Range filter bar: same mobile offset. */
    .filter-bar.cx-overview-filterbar { top: 55px; }

    /* Date-range popover: pin inside the viewport regardless of the
       JS-computed left, and let the two date inputs stack. */
    .range-cal { left: 8px !important; right: 8px; max-width: none; }
    .range-cal .rc-row { flex-wrap: wrap; }
    .range-cal input[type=date] { min-width: 0; flex: 1 1 120px; }

    /* Activity card: the Phone/Email stat pills float over the top-right
       corner on desktop; on phones they collide with the headline, so they
       drop into the flow below the chart. */
    .activity-card .activity-stats {
        position: static;
        margin-top: 10px;
        flex-wrap: wrap;
        gap: 8px;
    }
    .activity-card .stat-pill { padding: 9px 14px; }
    .home-top-row .activity-card,
    .home-top-row .calls-scheduled-card { height: auto; min-height: 300px; }

    /* Data tables scroll sideways inside their card instead of blowing
       the page width out. */
    .tbl {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* KPI drilldown modal: the records table keeps its natural width and
       scrolls sideways inside the bottom sheet. */
    .kpi-drilldown-body { overflow-x: auto; -webkit-overflow-scrolling: touch; }

    /* Dense time-series / grouped-bar charts (many x labels, forced
       interval:0, stacked pipelines) are unreadable squeezed into a phone
       card. The wrapper is an unstyled div on desktop; on phones the chart
       keeps a readable near-desktop layout width and pans sideways inside
       the card (ECharts re-lays-out via its ResizeObserver).
       .chart-scroll is the tool-agnostic name (Sales weekly trends);
       .cx-chart-scroll predates it on the CX pages. */
    .cx-chart-scroll,
    .chart-scroll {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .cx-chart-scroll::-webkit-scrollbar,
    .chart-scroll::-webkit-scrollbar { display: none; }
    .cx-chart-scroll > .sb-chart,
    .chart-scroll > .sb-chart { min-width: 640px; }

    /* Modals become bottom sheets: full width, capped height, scrollable
       body. max-width beats each modal's inline `width:` style. */
    .add-tool-modal-overlay {
        align-items: flex-end;
        padding: 0;
    }
    .add-tool-modal {
        max-width: 100%;
        width: 100% !important;
        max-height: 88dvh;
        border-radius: 18px 18px 0 0;
        display: flex;
        flex-direction: column;
    }
    .add-tool-modal .am-body {
        overflow-y: auto;
        flex: 1;
        min-height: 0;
        -webkit-overflow-scrolling: touch;
    }

    /* Command palette: use the full width on phones. */
    .cmdk-overlay { padding-top: 8vh; }
    .cmdk-modal { max-width: calc(100vw - 24px); }
}

/* ══════════════════════════════════════════════════════════════════
   ≤ 400px — smallest phones (Galaxy Fold cover screen: 344px)
   ══════════════════════════════════════════════════════════════════ */
@media (max-width: 400px) {
    .page-wrap,
    .density-comfort .page-wrap,
    .density-dense .page-wrap { padding: 12px 10px 32px; }

    .vibe-soft .page-head .page-title { font-size: 21px; }

    .weekly-kpi-grid,
    .density-dense .weekly-kpi-grid,
    .density-comfort .weekly-kpi-grid { gap: 8px; }
    .density-comfort .kpi { padding: 12px; }
    .density-comfort .kpi .sk-value { font-size: 20px; }
    .kpi .k-value, .kpi .sk-value { font-size: 20px; }

    .vibe-soft .vc, .vibe-soft .card { padding: 14px 12px; }

    .rail { gap: 2px; padding-left: 6px; padding-right: 6px; }
    .rail .rail-item { width: 40px; height: 40px; }

    .v1-topbar { padding: 0 10px; }
    /* Long breadcrumbs ("Sales Analytics / Kiosk display") wrapped to two
       cramped lines inside the 52px bar — truncate the page name instead. */
    .v1-topbar .crumbs { gap: 6px; flex-wrap: nowrap; overflow: hidden; }
    .v1-topbar .crumbs .here {
        font-size: 13px;
        min-width: 0;
        overflow: hidden;
        white-space: nowrap;
    }
    .v1-topbar .crumbs .here > span:last-child {
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .subnav-wrap { padding: 14px 10px 0; }
    .vibe-soft .tab-row .tab { padding: 7px 11px; }
}

/* ══════════════════════════════════════════════════════════════════
   Calls (Demo & Training) tool — inline-style → class conversions.
   Each desktop block below carries the EXACT declarations of the inline
   style it replaced in templates/tools/calls/*, so desktop rendering is
   unchanged; the media tiers further down restack them for phones.
   (run.html / review.html mobile rules live in calls-run.css, not here.)
   ══════════════════════════════════════════════════════════════════ */

/* /calls/queue — design-system .tbl + the app.js sortable-table engine own
   the look and behavior (header chrome, row separators, hover, sort arrows).
   This block only adds: fixed layout + colgroup so every column sits at the
   same x in every row of every box (a per-row grid couldn't guarantee that —
   its auto tail track resized per row's chip count), and queue-cell details.
   The <tr> keeps .calls-row so theme.css chip/score/reviewer styles apply —
   its grid display is reset to table-row below (.calls-row's own border/
   padding don't render on a tr under .tbl's border-collapse:separate). */
.cq-table { table-layout: fixed; }
.cq-table col.c-status   { width: 116px; }
.cq-table col.c-date     { width: 100px; }
.cq-table col.c-lead     { width: 120px; }
.cq-table col.c-reviewed { width: 120px; }
.cq-table col.c-score    { width: 66px; }
.cq-table col.c-actions  { width: 226px; }
.cq-table tr.calls-row { display: table-row; }
.cq-table td { overflow: hidden; }
.cq-table thead th.cq-th-right { text-align: right; }
.cq-tr[data-href] { cursor: pointer; }
.cq-tr-static { cursor: default; }
.cq-call a { color: inherit; text-decoration: none; }
.cq-call a:hover { text-decoration: underline; }
.cq-cell-date .reviewer,
.cq-cell-lead .reviewer, .cq-cell-reviewed .reviewer {
    display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    font-size: 12px;
}
.cq-noscore { color: var(--ink-3); }
/* Actions cell: chips + pills, right-aligned, wrapping onto a second line
   rather than widening the column. */
.cq-actions-cell { text-align: right; }
.cq-actions-cell .cq-tail {
    display: inline-flex; gap: 6px; justify-content: flex-end;
    align-items: center; flex-wrap: wrap; max-width: 100%;
}
/* Mobile labels (shown only in the ≤700 stack below). */
.cq-mobile-label { display: none; }

/* /calls/queue — deleted-view row. */
.calls-row.cq-del {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) auto auto;
    gap: 18px;
    padding: 14px 22px;
    align-items: center;
}

/* /calls/manager — filter form (was repeat(5,1fr) inline). The Apply button's
   `1 / -1` equals the old `span 5` on the 5-column desktop grid. */
.cm-filters {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 12px;
    padding: 14px 18px;
    margin-bottom: 18px;
}
.cm-filters .cm-apply { grid-column: 1 / -1; }

/* /calls/playlists — content + sidebar split, and one saved-demo row. */
.cpl-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 24px;
    align-items: flex-start;
}
.calls-row.cpl-item {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    gap: 14px;
    padding: 12px 22px;
    align-items: center;
}

/* /calls/settings — Pipeline toggles + read-only Status grids. */
.cset-pipe {
    padding: 6px 4px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px 32px;
    font-size: 13px;
}
.cset-status {
    padding: 6px 4px;
    display: grid;
    grid-template-columns: 200px 1fr;
    gap: 8px 18px;
    font-size: 13px;
}

/* Storage panel (settings tab + /calls/storage) — usage strip + one
   purge-candidate row. */
.cst-usage {
    padding: 6px 4px;
    display: grid;
    grid-template-columns: repeat(3, auto);
    gap: 8px 32px;
    font-size: 13px;
}
.calls-row.cst-row {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr) auto auto auto;
    gap: 14px;
    padding: 12px 22px;
    align-items: center;
}

/* System panel (settings tab + /calls/system) — By workflow / By status pair. */
.csys-two {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px;
}

/* /calls/poll — one Zoom-recording row. */
.calls-row.cpoll-row {
    display: grid;
    grid-template-columns: 28px minmax(0, 1.6fr) auto auto;
    gap: 14px;
    padding: 12px 22px;
    align-items: center;
    cursor: pointer;
}

/* /calls/prompts — Add-term form grid. */
.cpr-addterm {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 12px 18px;
    max-width: 760px;
}

/* ── Calls ≤900px — tablets: the 5-across manager filter can't fit. ── */
@media (max-width: 900px) {
    .cm-filters { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .cm-filters select,
    .cm-filters input { width: 100%; min-width: 0; box-sizing: border-box; }
    .cm-filters .cm-dates { grid-column: 1 / -1; }

    /* The 8-column manager table starts crushing its cells ("ready for
       review" three lines deep) below ~900 — give it its readable width and
       let the .ct-scroll wrapper pan. Same value the ≤700 tier uses. */
    .calls-page .ct-scroll.cm-tbl > table { min-width: 720px; }

    /* Failed queue rows: the desktop nowrap-ellipsis meta swallows the
       failure reason once the title column tightens — let meta lines wrap
       (host · date · duration stays short anyway). */
    .cq-table .cq-call .topic-meta { white-space: normal; }
    /* Tighten the fixed columns so the Call column keeps readable width. */
    .cq-table col.c-date { width: 92px; }
    .cq-table col.c-lead, .cq-table col.c-reviewed { width: 100px; }
    .cq-table col.c-actions { width: 170px; }
}

/* ── Calls ≤700px — phones: rows restack, pair grids collapse. ── */
@media (max-width: 700px) {
    /* Generic .calls-row grid from theme.css (1fr 160px 90px 110px 18px) —
       its consumers on the Calls pages all carry their own c*-row class
       below; the only bare users are two-child rows (time chip + meta,
       e.g. the home/sales Calls Scheduled card), so give those two
       content-sized columns instead of five fixed tracks. */
    .calls-row { grid-template-columns: auto minmax(0, 1fr); }

    /* Form controls: keep padding/border inside 100% width (no global
       border-box reset on real pages) so inputs can't poke past cards. */
    .calls-page input:not([type="checkbox"]):not([type="radio"]),
    .calls-page select,
    .calls-page textarea { box-sizing: border-box; max-width: 100%; }

    /* Row action pills (Retry / Restore / Make active / …) get a real
       touch-target height. Span pills (count badges) are untouched. */
    .calls-page button.filter-pill,
    .calls-page a.filter-pill {
        min-height: 40px;
        display: inline-flex;
        align-items: center;
    }

    /* Tables that sit in an overflow-x wrapper scroll sideways instead of
       crushing their columns. */
    .calls-page .ct-scroll { -webkit-overflow-scrolling: touch; }
    .calls-page .ct-scroll > table { min-width: 560px; }
    .calls-page .ct-scroll.cm-tbl > table { min-width: 720px; }

    /* Card heads: title/subtitle vs. the actions cluster (e.g. the Action
       plan's All/Rep/Prospect pills) — wrap instead of crushing the title
       column to one word per line. Same call as .report-bento .vc-head. */
    .calls-page .vc-head,
    .calls-run .vc-head { flex-wrap: wrap; row-gap: 6px; }

    /* Queue table restacks into cards on phones: header hidden, each row a
       bordered block, cells full-width with inline "Lead by"/"Reviewed by"/
       "Score" labels (.cq-mobile-label). No data hidden. */
    .cq-table, .cq-table tbody { display: block; }
    .cq-table thead, .cq-table colgroup { display: none; }
    .cq-table tr.calls-row { display: block; padding: 12px 14px; }
    .cq-table td { display: block; padding: 2px 0; border: 0; overflow: visible; }
    .cq-table td.cq-call { padding: 4px 0; }
    .cq-table .topic-title { white-space: normal; }
    .cq-cell-lead .reviewer, .cq-cell-reviewed .reviewer {
        display: inline; white-space: normal;
    }
    .cq-mobile-label {
        display: inline-block;
        font-size: 9px; font-weight: 700; letter-spacing: 0.12em;
        text-transform: uppercase; color: var(--ink-3);
        margin-right: 6px; min-width: 84px;
    }
    .cq-actions-cell { text-align: left; padding-top: 6px; }
    .cq-actions-cell .cq-tail { justify-content: flex-start; }
    .calls-row.cq-del {
        grid-template-columns: minmax(0, 1fr) auto;
        gap: 8px 12px;
        padding: 12px 14px;
    }
    .calls-row.cq-del > div { grid-column: 1 / -1; }
    /* The View pill sits in the 1fr column — stop it stretching to a bar. */
    .calls-row.cq-del > .filter-pill { justify-self: start; }
    .calls-row.cq-del .topic-title { white-space: normal; }
    .cq-actionbar { flex-wrap: wrap; }
    .calls-subhead { padding: 9px 14px; }

    /* Playlists: sidebar drops below the favourites/playlist lists. */
    .cpl-grid { grid-template-columns: minmax(0, 1fr); gap: 18px; }
    .calls-row.cpl-item { gap: 10px; padding: 12px 14px; }

    /* Settings: toggle pairs and the label/value status grid stack. */
    .cset-pipe { grid-template-columns: minmax(0, 1fr); gap: 12px; }
    .cset-status { grid-template-columns: minmax(0, 1fr); gap: 2px 18px; }
    .cset-status > div:nth-child(2n+3) { margin-top: 10px; }
    .cset-status code { overflow-wrap: anywhere; word-break: break-all; }

    /* Storage: usage strip wraps; purge rows keep checkbox + title up top
       with size / flag / media-size on a second line. */
    .cst-usage {
        grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
        gap: 8px 16px;
    }
    .cst-filter { flex-wrap: wrap; row-gap: 6px; }
    .cst-head { flex-wrap: wrap; row-gap: 8px; }
    .calls-row.cst-row {
        grid-template-columns: 28px minmax(0, 1fr) auto;
        gap: 4px 12px;
        padding: 12px 14px;
    }
    .calls-row.cst-row > input { grid-row: 1 / span 2; }
    .calls-row.cst-row > div { grid-column: 2 / -1; }
    .calls-row.cst-row > :nth-child(3) { grid-row: 2; grid-column: 2; justify-self: start; }
    .calls-row.cst-row > :nth-child(5) { grid-row: 2; grid-column: 3; }
    .calls-row.cst-row > :nth-child(4) { grid-row: 3; grid-column: 2 / -1; justify-self: start; }
    /* !important: the storage/playlist titles are <a> tags with an inline
       `white-space:nowrap` -- phones want the full title, wrapped. */
    .calls-row.cst-row .topic-title,
    .calls-row.cpl-item .topic-title { white-space: normal !important; }

    /* System: By workflow / By status stack. */
    .csys-two { grid-template-columns: minmax(0, 1fr); }

    /* Poll: header + look-back form wrap; rows restack like storage. */
    .cpoll-form { flex-wrap: wrap; row-gap: 8px; }
    .cpoll-head { flex-wrap: wrap; row-gap: 8px; }
    .calls-row.cpoll-row {
        grid-template-columns: 28px minmax(0, 1fr) auto;
        gap: 4px 12px;
        padding: 12px 14px;
    }
    .calls-row.cpoll-row > input { grid-row: 1 / span 2; }
    .calls-row.cpoll-row > :nth-child(3) { grid-row: 1; grid-column: 3; }
    .calls-row.cpoll-row > :nth-child(4) { grid-row: 2; grid-column: 2 / -1; }
    .calls-row.cpoll-row > .topic-meta:empty { display: none; }
    .calls-row.cpoll-row .topic-title { white-space: normal; }

    /* Prompts: Add-term fields stack. */
    .cpr-addterm { grid-template-columns: minmax(0, 1fr); }
}

/* ── Calls ≤400px — fold-width padding trims. ── */
@media (max-width: 400px) {
    .cm-filters { grid-template-columns: minmax(0, 1fr); padding: 12px; }
    .cq-table tr.calls-row,
    .calls-row.cq-del,
    .calls-row.cst-row,
    .calls-row.cpoll-row,
    .calls-row.cpl-item { padding-left: 10px; padding-right: 10px; }
    .calls-subhead { padding: 9px 10px; }
}

/* ── iOS INPUT AUTO-ZOOM (2026-08-21) ─────────────────────────────────────────
   Mobile Safari ZOOMS THE PAGE IN when you focus a form control whose computed
   font-size is under 16px — and it does not zoom back out when you leave the
   field. Every `.ipt` is 13px (theme.css), so tapping any date, time, note or
   select on a phone left the whole page magnified and horizontally scrollable,
   with no obvious way back. It reads as the layout breaking, and it is the same
   family of complaint as the 250%-zoom report that produced our own date picker.

   16px is an exact threshold, not a guideline: 15.99px zooms, 16px does not.

   Confined to the mobile layer and behind a max-width query, so desktop keeps
   its 13px controls. `-webkit-text-size-adjust` is NOT a substitute — it stops
   text reflow on rotate, not focus zoom. Verified per device by
   `scripts\mobile_devices.py`, which fails if any visible control is under 16px.

   Padding comes down a touch so a 16px control is not taller than the 44px
   tap-target floor needs it to be.

   `!important` because this is a FLOOR, not a preference, and the things that
   beat it are not stylesheets: several pages carry their own `<style>` block
   (/workspace/users at 12px, /workspace/alerts, /sops/settings at 11.5px), and a
   page-level `<style>` is emitted into <head> AFTER this file's <link>, so at
   equal specificity it wins. Same family as the inline-`style` pitfall in
   CLAUDE.md. Without it the rule fixed the Time Off sheet and silently missed
   every other form in the platform.

   Only TEXT-ENTRY controls are listed. A checkbox or radio at 13px does not
   trigger focus zoom — Safari only does it where you can type — so bumping
   those would enlarge every tick box on /workspace/users for nothing. */
@media (max-width: 700px) {
    .ipt,
    input[type="text"], input[type="email"], input[type="password"],
    input[type="date"], input[type="time"], input[type="datetime-local"],
    input[type="month"], input[type="week"], input[type="number"],
    input[type="tel"], input[type="url"], input[type="search"],
    input:not([type]), select, textarea {
        font-size: 16px !important;
    }
    .ipt { padding: 8px 9px; }
}

/* ── A 44px TAP FLOOR FOR CONTROLS (2026-08-21) ───────────────────────────────
   Tanveer asked for "every tool buttons, click throughs, headers, side bars,
   pop up targets" on a real device. The sweep found 1292 interactive controls
   under 44x44 across the platform, and the pattern was consistent: they are
   WIDE ENOUGH and TOO SHORT — 14 to 40px tall. So this sets a floor on HEIGHT
   and leaves width alone.

   `min-height`, not `height`: a control that has grown to fit two lines of text
   must keep its own height. And these are all flex/inline-flex already, so the
   label stays centred without touching padding.

   WHAT IS DELIBERATELY NOT IN HERE:
     * Links inside prose. WCAG 2.5.8 exempts inline text links, and a link in
       the middle of a sentence has no business being 44px tall.
     * Status chips. `.chip` is a badge far more often than a button — 253 of
       them on the first pass, and making every one 44px tall would wreck the
       tables they sit in. Only `.chip[data-drill]`, which is a real
       click-through, is included.
     * The 16px checkboxes on /workspace/users (114 of them). They are a dense
       permissions matrix and the fix is a decision about that table, not a
       blanket bump — see the note there.
     * `.brand-mark` (34px) and `.rail-avatar` (36px). They sit at the two ENDS
       of the bottom bar, where a thumb is most accurate, and both carry a
       visible background whose size IS the design. The six items between them
       are what needed the pixels. */
@media (max-width: 900px) {
    /* THE BOTTOM NAV. The rail is a fixed bottom bar below 900px, so these six
       icons are the platform's primary navigation on a phone. 42 -> 44. */
    .rail .rail-item { width: 44px; height: 44px; }
}

@media (max-width: 700px) {
    /* Buttons and button-like controls, platform-wide. */
    .btn, .btn-primary, .btn-ghost, .btn-link,
    .pill, .tab, .seg-item, .icon-btn,
    .filter-pill, .hs-link, .fleet-btn, .lead-link,
    .chip-soft, .chip[data-drill],
    .sops-fchip, .sops-addlink, .to-subtab, .to-linkbtn, .cx-inline {
        /* box-sizing, or `min-height: 44px` means 44px of CONTENT and the
           control comes out 44 + its padding. The sub-nav tabs went to 58px
           and dominated the page — the same no-global-reset trap as the login
           card and `.ipt`. With border-box, 44 means 44. */
        box-sizing: border-box;
        min-height: 44px;
    }
    /* Icon-only buttons are square, so they need the width too. Same for the
       short ones: a `.fleet-btn` reading "Find" is 33px wide, and `.chip-soft`
       came out exactly 43 — one pixel short, which is the kind of thing only a
       measurement finds. */
    .icon-btn, .fleet-btn, .chip-soft, .pill, .to-linkbtn, .sops-addlink {
        min-width: 44px;
    }

    /* `min-height` DOES NOTHING on a non-replaced inline element, which is why
       `.hs-link` stayed 42px after being listed above. These are standalone
       action links in table cells — not links inside a sentence — so giving
       them a box is correct rather than a workaround. */
    .hs-link, .lead-link {
        display: inline-flex;
        align-items: center;
    }
    /* The funnel bar row is a real click-through into the drilldown modal. */
    .fb-track { min-height: 44px; }
    /* Text inputs sit in the same rows as these buttons and were 40px — a row
       where the field and the button beside it disagree by 4px reads as a
       misalignment, and it is the same thumb either way. */
    .ipt { min-height: 44px; }
}

@media (max-width: 400px) {
    /* The ≤400 block shrinks rail items to 40px for the fold width. The tap
       floor still applies — a narrower screen does not make thumbs smaller. */
    .rail .rail-item { width: 44px; height: 44px; }
}
