/* ============================================================================
   mobile.css — responsive layer for phones & small tablets
   ============================================================================

   THE ONE RULE: DESKTOP IS SACRED.
   Desktop (>991px) is ~90% of usage and already considered "perfect." Every
   rule in this file MUST live inside a `@media (max-width: …)` block. Nothing
   here may affect the desktop layout — if a change would apply above 991px, it
   does not belong in this file.

   Load order (see base.html <head>):
     bootstrap → style.css → inline design-system <style> → THIS FILE → per-page
     {% block extra_css %}
   So this file can refine the inline mobile foundation in base.html, and any
   page's own extra_css can still override this file.

   Breakpoints:
     ≤991px  — tablet / phone: sidebar becomes an off-canvas drawer (handled in
               base.html). Layout starts adapting.
     ≤768px  — phone: single-column, full-bleed cards, swipeable strips.
     ≤480px  — small phone: tightest spacing, largest reflow.

   Structure:
     1. Shared foundation (applies to every page)
     2. Per-page sections (added as each page gets its mobile pass)
   ============================================================================ */


/* ============================================================================
   1. SHARED FOUNDATION
   ============================================================================ */

@media (max-width: 991px) {

    /* --- Horizontal tab strips become swipeable ----------------------------
       Tab rows (top-level, dashboard billing, Bootstrap nav-tabs, agreement
       service tabs) are laid out in a single row. On a phone they overflow;
       let them pan horizontally with momentum instead of wrapping into an
       unreadable stack. Hide the scrollbar so it reads like native tabs. */
    .top-tabs,
    .dash-tabs,
    .nav-tabs,
    .seg-control,
    .status-tabs,
    .view-toggle,
    .toolbar-tabs,
    .notif-filter-tabs,
    .filter-tabs,
    .carrier-tabs {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;            /* Firefox */
        min-width: 0;                     /* allow shrink-to-scroll inside flex */
    }
    .top-tabs::-webkit-scrollbar,
    .dash-tabs::-webkit-scrollbar,
    .nav-tabs::-webkit-scrollbar,
    .seg-control::-webkit-scrollbar,
    .status-tabs::-webkit-scrollbar,
    .view-toggle::-webkit-scrollbar,
    .toolbar-tabs::-webkit-scrollbar,
    .notif-filter-tabs::-webkit-scrollbar,
    .filter-tabs::-webkit-scrollbar,
    .carrier-tabs::-webkit-scrollbar {
        display: none;                    /* WebKit */
    }
    /* Keep individual tabs from being squeezed below their label width. */
    .top-tab,
    .dash-tab,
    .nav-tabs .nav-link,
    .seg-btn,
    .status-tabs .tab-btn,
    .toolbar-tabs .status-tab,
    .notif-filter-tabs .notif-filter-tab {
        flex-shrink: 0;
        white-space: nowrap;
    }

    /* --- Filter / toolbar / action rows wrap -------------------------------
       Countless pages lay filters and action buttons in a horizontal flex row
       that assumes desktop width. Allowing them to wrap is almost always the
       right call on a phone: nothing overflows off-screen, everything stays
       tappable. Scoped to the common container class names so we don't disturb
       intentional single-line flex elsewhere. */
    .hist-filters,
    .summary-strip,
    .filter-bar,
    .filters-row,
    .toolbar,
    .toolbar-row,
    .toolbar-left,
    .toolbar-right,
    .toolbar-controls,
    .uploads-toolbar,
    .main-toolbar,
    .upload-actions,
    .filter-toolbar,
    .filter-left,
    .filter-right,
    .filter-form,
    .page-toolbar,
    .page-actions,
    .action-bar,
    .btn-toolbar {
        flex-wrap: wrap;
    }

    /* Common table wrappers that clip (overflow:hidden) on desktop pan
       horizontally on mobile so wide tables inside them stay reachable.
       `!important` is required: the page templates set `overflow: hidden` on
       these wrappers in their own <style> (loaded after this file), and since
       media queries add no specificity, source order would otherwise let that
       desktop clip win and trap the right-hand columns off-screen. */
    .data-table-wrapper:not(.allow-dropdown-overflow),
    .table-container,
    .linear-table-container,
    .data-table-scroll,
    .shipment-table-wrap,
    .table-card,
    .table-wrap {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }

    /* --- Comfortable tap targets -------------------------------------------
       Bump small inline buttons up toward the 44px touch guideline without
       changing their visual weight on desktop. */
    .btn,
    .linear-btn,
    .linear-btn-sm,
    .linear-btn-icon {
        min-height: 38px;
    }
}


@media (max-width: 768px) {

    /* --- Page heading scales down ------------------------------------------ */
    h1,
    .page-title,
    .dash-header h1 {
        font-size: 20px;
        line-height: 1.2;
    }

    /* --- Headers: centered WRAPPING ROW on mobile --------------------------
       A title with its action(s) on ONE centered line when they fit; when the
       action cluster is too wide (e.g. several buttons) flex-wrap drops it to
       its own centered line below. This makes the one-line-vs-stacked choice
       automatic and "selective" — no per-page guessing. Centering keeps the
       title clear of the fixed top-left hamburger, which lets us cut the tall
       top padding (that only existed to clear it) and reclaim white space.
       Titles are content-width (no width:100%) so a small action sits beside
       them; they still center via the row's justify-content. */
    .dash-header,
    .page-header,
    .notif-page-header {
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: center;
        align-items: center;
        text-align: center;
        gap: 10px 12px;
    }
    .page-title,
    .dash-header h1,
    .notif-page-title,
    .linear-page-title {
        text-align: center;
        justify-content: center;   /* flex-based titles: icon + text group */
    }
    /* A subtitle always drops to its own centered line under the title. */
    .page-subtitle {
        flex-basis: 100%;
        text-align: center;
    }

    /* Titles are centered and no longer hide behind the top-left hamburger, so
       drop most of the top padding that was only reserving space for it. */
    .main-content-inner {
        padding-top: 22px;
    }

    /* Breadcrumbs are still anchored top-left — indent them past the hamburger
       (top:16 left:16, 44px → right edge ~60px) so they aren't hidden by it. */
    .breadcrumb-nav,
    .linear-breadcrumb,
    .breadcrumb-linear {
        padding-left: 52px;
    }

    /* --- Wide bare tables stay reachable -----------------------------------
       Fallback for any table not given a nicer reflow yet: wrap it in its own
       horizontal pan so it never forces the whole page wide. Pages that opt
       into the stacked-card pattern (below) override this per-table. */
    .table-scroll-x {
        display: block;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}


/* ----------------------------------------------------------------------------
   Reusable "stacked card" table pattern
   ----------------------------------------------------------------------------
   For read-heavy tables, sideways scrolling is the wrong experience. A table
   marked `.mobile-stack` collapses on phones so each row becomes a labeled
   card: every cell shows its column header (from the cell's `data-label`) on
   the left and the value on the right. Opt in per page by adding the class to
   the <table> and `data-label="…"` to each <td>. Desktop is untouched — the
   rules only exist below 768px.
   ---------------------------------------------------------------------------- */
@media (max-width: 768px) {
    table.mobile-stack,
    table.mobile-stack thead,
    table.mobile-stack tbody,
    table.mobile-stack tr,
    table.mobile-stack td {
        display: block;
        width: 100%;
    }

    /* Visually hide the header row but keep it for accessibility. */
    table.mobile-stack thead tr {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }

    table.mobile-stack tr {
        margin-bottom: 12px;
        border: 1px solid var(--border-color);
        border-radius: 12px;
        background: var(--bg-card);
        box-shadow: var(--shadow-card);
        overflow: hidden;
    }

    table.mobile-stack td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 16px;
        padding: 9px 14px;
        text-align: right;
        border: none;
        border-bottom: 1px solid var(--border-color);
    }
    table.mobile-stack td:last-child {
        border-bottom: none;
    }

    /* The column label, pulled from data-label. */
    table.mobile-stack td::before {
        content: attr(data-label);
        flex-shrink: 0;
        text-align: left;
        font-size: 11px;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.06em;
        color: var(--text-tertiary);
    }

    /* Cells explicitly marked as empty-label (e.g. an actions cell) don't
       reserve space for a label. */
    table.mobile-stack td[data-label=""]::before {
        content: none;
    }

    /* Identity cell: renders as the card's title header — full width, left
       aligned, no label, on an elevated strip. Mark the primary column's <td>
       with `class="stack-primary"`. */
    table.mobile-stack td.stack-primary {
        justify-content: flex-start;
        text-align: left;
        gap: 10px;
        padding: 11px 14px;
        background: var(--bg-elevated);
        font-weight: 600;
        font-size: 14px;
    }
    table.mobile-stack td.stack-primary::before {
        content: none;
    }

    /* An actions cell reads best centered as a full-width footer of the card. */
    table.mobile-stack td.stack-actions {
        justify-content: center;
    }
}


/* ============================================================================
   2. PER-PAGE SECTIONS
   ============================================================================ */

/* ---- Dashboard (templates/dashboard/index.html) --------------------------- */
@media (max-width: 991px) {
    /* Four metric cards in one row is far too tight on a phone. Two columns
       reads cleanly in portrait; the hero figures shrink to fit their box. */
    .metrics-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 12px;
    }
    .metric-card {
        padding: 14px 14px 15px;
    }
    .metric-value,
    .metric-value.accent {
        font-size: 24px;
    }

    /* Chart card: trim padding so the plot keeps as much width as possible. */
    .chart-card {
        padding: 16px 12px 12px;
    }

    /* Summary strip items: tighten the wrapped rows. */
    .summary-strip {
        gap: 8px 18px;
    }
}

@media (max-width: 480px) {
    /* Single column on the smallest phones — big currency values need the
       full width to avoid truncation. */
    .metrics-grid {
        grid-template-columns: 1fr;
    }
    .metric-value,
    .metric-value.accent {
        font-size: 26px;
    }
}


/* ---- Companies list (templates/customers/index.html) ---------------------- */
@media (max-width: 768px) {
    /* Map legend is a single flex row of toggles on desktop; let it wrap. */
    .map-legend {
        flex-wrap: wrap;
        row-gap: 8px;
    }
}


/* ---- Customer billing + shared `linear-*` page layout --------------------- */
/* Used by customers/billing.html, billing_period.html, tracking_numbers.html. */
@media (max-width: 991px) {
    /* Customer sub-tabs (Ready to Bill / History / Settings / …) swipe. */
    .linear-tabs {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .linear-tabs::-webkit-scrollbar {
        display: none;
    }
    .linear-tabs .tab {
        flex-shrink: 0;
        white-space: nowrap;
    }
}

@media (max-width: 768px) {
    /* Header "<h1> … actions" as a centered wrapping row (see the global header
       rule above): title + a small action share one line; a wide action cluster
       (e.g. uploads' toggle+delete+reprocess+upload) wraps to its own line.
       Scoped under .linear-page so it out-specifies the pages' own single-class
       `.linear-page-header` rules that load after this file. */
    .linear-page .linear-page-header {
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: center;
        align-items: center;
        text-align: center;
        gap: 10px 12px;
    }

    /* The search + filter / export + action clusters (billing hub, tracking)
       stack full-width so the search field and buttons are comfortably
       tappable. NB: `.linear-actions` is overloaded across pages — this column
       treatment is for the standalone search/action bars. Header-embedded
       action button rows are handled by the more-specific rule below. */
    .linear-actions {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
    }
    .linear-actions .left,
    .linear-actions .right {
        width: 100%;
        flex-wrap: wrap;
    }
    .linear-search {
        width: 100%;
        flex: 1;
    }

    /* Uploads-index header actions (Files/Chart toggle, Bulk Delete, Reprocess,
       Upload) live INSIDE .linear-page-header. This cluster is wide (several
       buttons), so drop it onto its own centered full-width line beneath the
       title (flex-basis:100%) and let the buttons wrap within it — rather than
       squeezing into a narrow column beside the title. More specific than the
       generic .linear-actions rule above so it wins. */
    .linear-page .linear-page-header .linear-actions {
        flex-basis: 100%;
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: center;
        align-items: center;
        gap: 8px;
    }
}


/* ---- Line-items / tracking-numbers table (customers/tracking_numbers.html,
        billing_period.html) --------------------------------------------------
   This is the dense 13-column billing grid. Per product decision, the mobile
   experience here is simply horizontal scroll — keep the native column widths
   and let the wrapper pan sideways rather than crushing columns or hiding data.
   (Not the `.mobile-stack` card treatment — this table is too wide for cards
   and being able to reach every column matters more than avoiding a swipe.) */
@media (max-width: 991px) {
    /* Wrapper is `overflow: hidden` on desktop (rounded-corner clip). Let it
       pan horizontally on mobile so the wide table is fully reachable. The
       wrapper contains only the table — no dropdown to worry about clipping.
       `!important` needed to beat the page template's own `.linear-table-wrapper
       { overflow: hidden }`, which loads after this file (see note above). */
    .linear-table-wrapper {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }
    /* Keep the billing grid at usable column widths and scroll it, rather than
       letting width:100% squeeze 13 columns into a phone width. Scoped to the
       grid's id (not `.line-items-table`) because the shipment-detail pages
       reuse that class for a small 4-column charges table that should keep its
       natural width and NOT be forced into needless horizontal scroll. */
    #lineItemsTable {
        min-width: 880px;
    }

    /* The billing-period summary / fees tables are width:100% and would
       otherwise compress their 8+ columns to illegible slivers with nothing to
       scroll. Give them a floor width so they extend past the phone and the
       wrapper pans to reveal every column (Baseline, Current, Savings, Fee …). */
    .billing-page .data-table {
        min-width: 760px;
    }

    /* Toolbar: filters + view toggles + actions wrap instead of overflowing. */
    .linear-toolbar {
        flex-wrap: wrap;
        gap: 8px;
    }
    .linear-toolbar .left-side,
    .linear-toolbar .right-side {
        flex-wrap: wrap;
    }
}

@media (max-width: 768px) {
    /* Sticky footer: on desktop it's one row of "counts … pagination". On a
       phone that overflows and wraps into a tall multi-line stack. Reflow into
       two tidy rows — counts (ellipsized to one line) above a single centered
       pagination row — and drop the "Rows per page" label to save width.
       Handles both footer structures in use: tracking-numbers
       (.footer-left/.footer-right) and shipments index (.footer-info +
       .pagination-bar as a direct child). */
    .sticky-footer {
        flex-direction: column;
        align-items: stretch;
        gap: 4px;
        padding: 6px 10px;
    }
    .sticky-footer > .footer-left,
    .sticky-footer > .footer-info,
    .sticky-footer > .footer-right {
        justify-content: center;
    }
    /* Keep the counts line to a single ellipsized row rather than wrapping. */
    .sticky-footer .footer-info,
    .sticky-footer #footerCountsText {
        display: block;
        min-width: 0;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        text-align: center;
    }
    .sticky-footer .pagination-bar {
        justify-content: center;
        gap: 10px;
        flex-wrap: nowrap;
    }
    .sticky-footer .pagination-rows-per-page label {
        display: none;
    }

    /* Detail flyout: full-width sheet, and its two inner columns (package
       characteristics + charges) stack so each is readable. */
    .flyout-panel {
        width: 100vw;
        max-width: 100vw;
    }
    .flyout-body > .d-flex {
        flex-direction: column;
    }
    .flyout-body .package-characteristics {
        width: 100% !important;
    }
    /* The flyout's own charge table can pan if it's wider than the sheet. */
    .flyout-body {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}


/* ---- Shipments list + Uploads (shipments/index.html, uploads/index.html,
        uploads/view.html) ----------------------------------------------------
   Wide list tables get a floor width so they extend past the phone and their
   scroll container pans to every column, rather than compressing to slivers.
   Scoped (page container / id) so narrow sibling tables — the 2-column upload
   totals table, the 3-column column-mapping preview — keep their natural width
   and don't scroll needlessly. */
@media (max-width: 991px) {
    .shipments-page .data-table {
        min-width: 820px;
    }
    /* Same fixed-layout clipping trap as #uploadsTable — size to content. */
    #shipmentTable {
        table-layout: auto;
        min-width: 720px;
    }
    #shipmentTable thead th,
    #shipmentTable tbody td {
        overflow: visible;
        white-space: nowrap;
    }
    /* The uploads table is `table-layout: fixed` with 12 percentage-width
       columns and `overflow:hidden` cells — on a phone that jams every column
       to a sliver and clips the text ("Invoice Date" → "Invoic…", filenames
       cut off). A min-width alone can't help while fixed layout is dividing a
       small width. Switch to content-based sizing so each column takes the
       room its text needs, stop clipping, and let the whole table pan. */
    #uploadsTable {
        table-layout: auto;
        min-width: 940px;
    }
    #uploadsTable thead th,
    #uploadsTable tbody td {
        overflow: visible;
        white-space: nowrap;
    }

    /* Uploads toolbar: on desktop it's [ files toggle | spacer | controls ] in
       one row. On mobile the toggle gets its own full-width row and scrolls
       horizontally (so All / Processed / Failed stay full-size and reachable),
       the desktop growth spacer is removed, and the search + filter controls
       take the next full row. */
    .uploads-toolbar .toolbar-tabs {
        flex: 1 1 100%;
    }
    .uploads-toolbar .toolbar-spacer {
        display: none;
    }
    .uploads-toolbar .toolbar-controls {
        flex: 1 1 100%;
    }
}



/* ---- Reports & analysis (reports/*.html, analysis/*.html) ----------------- */
@media (max-width: 768px) {
    /* Report filter rows are "LABEL | control" side-by-side (label fixed at
       100px). Stack them so the control — company picker, date range, file
       name — gets the full width and nothing is cramped. */
    .filter-row {
        flex-direction: column;
        align-items: stretch;
        gap: 6px;
    }
    .filter-row.align-top {
        align-items: stretch;
    }
    .filter-label {
        width: auto;
    }
    .filter-row.align-top .filter-label {
        padding-top: 0;
    }

    /* Date-range picker: the dual-calendar card is 460px on desktop and would
       overflow a phone. Fit it to the viewport and stack the two months
       vertically instead of side-by-side. (Shared component — reports,
       analysis, transit.) */
    .drp-cal-card {
        max-width: 100%;
    }
    .drp-cal-card.open {
        max-height: 720px;
    }
    .drp-cal-card-inner {
        flex-direction: column;
    }
    .drp-cal + .drp-cal {
        margin-left: 0;
        padding-left: 0;
        border-left: none;
        margin-top: 12px;
        padding-top: 12px;
        border-top: 1px solid var(--border-color);
    }

    /* Refund claims table: its wrapper already scrolls; give the table a floor
       width so its columns stay legible and pan rather than compressing. */
    .claims-table {
        min-width: 760px;
    }

    /* Time-in-transit table: same — wrapper (.transit-table-wrap) already
       scrolls; keep the columns legible with a floor width. */
    .transit-table {
        min-width: 640px;
    }
}


/* ---- Power-user editors (best-effort — desktop-first tools) ---------------
   These pages (service-name mappings, 4S rundown, agreement review editor,
   service guides, admin) are built for a mouse and wide screens. The global
   foundation already keeps them reachable on a phone (page + wrapper scroll,
   wrapping toolbars). The two fixes here stop `table-layout: fixed` tables from
   clipping their text on mobile. */
@media (max-width: 991px) {
    /* Service-name mapping editor. Its `table-layout: fixed` is REQUIRED — the
       row virtualization (content-visibility: auto) depends on fixed layout, so
       do NOT switch to auto. Instead give it a wide floor so its ~6 columns get
       ~150px each and it pans, rather than cramming into the phone width. */
    .mapping-table {
        min-width: 900px;
    }

    /* Rundown service/surcharge summary tables (fixed layout) sit in an
       overflow-x:auto wrapper already — a floor width keeps columns legible. */
    .svc-summary-table {
        min-width: 680px;
    }
}


/* ---- Customer sub-tab partials (customers/_connections.html, etc.) --------
   The billing hub's tab panels (Connections, Agreements, To Do) render inside
   `.linear-partial-card`, which is `overflow: hidden`. The Carrier Connections
   table (.conn-table) has a wide non-wrapping Actions column, so on a phone it
   compresses and the actions get clipped off the right edge with no way to
   reach them. Let that table pan horizontally so every carrier's actions are
   reachable. Scoped with :has(.conn-table) so only the connections table's card
   body scrolls — the other partials on the page are unaffected. Action popovers
   inside use position:fixed, so a scroll container won't clip them. */
@media (max-width: 991px) {
    .linear-partial-body:has(.conn-table) {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .conn-table {
        min-width: 760px;
    }

    /* The card header's action cluster (Reveal Credentials / Intake Link / Add
       Connection) wraps instead of overflowing on a narrow screen. */
    .linear-partial-header {
        flex-wrap: wrap;
        gap: 10px;
    }
}
