/* =============================================================
   Shared responsive behaviour — loaded last, after portal.css /
   masters.css, so it can override their desktop rules.

   Breakpoints
     <= 1080px  tablet landscape and below: sidebar becomes a drawer
     <=  820px  tablet portrait: header and toolbars stack
     <=  560px  phone: tighter padding, full width controls
   ============================================================= */

/* ── Never let the page scroll sideways ──
   Only body carries overflow-x. Putting it on html turns the root into a
   scroll container, which silently kills every position:sticky on the page —
   the navbar and the sidebar included. With html left visible, body's value
   propagates to the viewport and still clips sideways, but sticky keeps
   working. */
html {
    max-width: 100%;
}

body {
    max-width: 100%;
    overflow-x: hidden;
}

/* Long words / urls in table cells must not force the page wider */
.mst-tbl td,
.mst-tbl th {
    overflow-wrap: anywhere;
}

/* ── Sidebar drawer trigger — hidden on desktop ── */
.nav-burger {
    display: none;
    width: 36px;
    height: 36px;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    border: 1px solid var(--rule);
    background: var(--white);
    color: var(--ink3);
    cursor: pointer;
    flex-shrink: 0;
    transition: .14s;
}

.nav-burger:hover {
    background: var(--bg);
    color: var(--ink);
}

/* ── Drawer backdrop ── */
.ui-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(22, 33, 30, .45);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s;
    z-index: 250;
}

body.nav-open .ui-backdrop {
    opacity: 1;
    pointer-events: auto;
}

/* =============================================================
   <= 1080px — sidebar off canvas
   ============================================================= */
@media (max-width: 1080px) {

    .nav-burger {
        display: inline-flex;
    }

    /* portal.css hides .sidenav outright at this width; bring it back as a
       drawer that slides in from the left instead. */
    .sidenav {
        display: flex;
        flex-direction: column;
        position: fixed;
        top: var(--nav-h);
        left: 0;
        bottom: 0;
        width: min(282px, 84vw);
        transform: translateX(-100%);
        transition: transform .22s ease;
        z-index: 300;
        box-shadow: 0 18px 50px rgba(22, 33, 30, .18);
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }

    body.nav-open .sidenav {
        transform: none;
    }

    /* Give the drawer room to breathe and keep tap targets comfortable */
    .sidenav .snl,
    .sidenav .subnav a {
        min-height: 42px;
    }

    .main {
        width: 100%;
        min-width: 0;
    }
}

/* =============================================================
   <= 820px — header, toolbars and modals stack
   ============================================================= */
@media (max-width: 820px) {

    /* Page header: title above the action buttons */
    .page-hdr {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
        padding: 14px 16px;
    }

    .page-hdr-right {
        margin-left: 0;
        flex-wrap: wrap;
    }

    .page-title {
        font-size: 17px;
    }

    /* Master screens */
    .mst-main {
        padding: 16px;
    }

    /* List card: title over its own toolbar, search goes full width */
    .lc-hd {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
    }

    .lc-hd-right {
        flex-direction: column;
        align-items: stretch;
    }

    .lc-search {
        width: 100%;
    }

    .lc-hd-right .abtn {
        justify-content: center;
    }

    .lc-tools {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
    }

    /* The date range gets its own line; the label stays beside its input */
    .lc-tools .dt-filters {
        justify-content: flex-start;
        flex: none;
    }

    .lc-tools .dt-filters .fgroup {
        flex: 1 1 190px;
    }

    .lc-show,
    .lc-page {
        justify-content: space-between;
    }

    /* "More filters" and its panel stack rather than squeeze */
    .lc-more {
        order: -1;
        justify-content: center;
    }

    .lc-extra .fgroup {
        flex: 1 1 210px;
    }

    .lc-extra .fsel {
        flex: 1;
        max-width: none;
    }

    .lc-body {
        padding: 14px;
    }

    .mst-bar {
        gap: 8px;
    }

    .mst-search {
        min-width: 0;
        flex: 1 1 100%;
    }

    .mst-filter {
        flex: 1 1 auto;
    }

    /* Modals: use the width, keep a little margin */
    .ack-overlay {
        align-items: flex-end;
        padding: 0;
    }

    .ack-modal {
        max-width: 100% !important;
        width: 100%;
        border-radius: 18px 18px 0 0;
        max-height: 92vh;
        overflow-y: auto;
    }

    .ack-modal-ft {
        position: sticky;
        bottom: 0;
        flex-wrap: wrap;
    }

    .ack-modal-ft .abtn {
        flex: 1 1 auto;
        justify-content: center;
    }

    /* Two column form rows become one */
    .frow,
    .frow.three {
        grid-template-columns: 1fr;
    }

    /* Auth pages already collapse at 900px; keep the card comfortable */
    .auth-panel {
        padding: 32px 20px;
    }
}

/* =============================================================
   <= 560px — phone
   ============================================================= */
@media (max-width: 560px) {

    .mst-main {
        padding: 12px;
    }

    .page-hdr {
        padding: 12px;
    }

    /* Buttons in the header go full width so they are easy to hit */
    .page-hdr-right .abtn {
        flex: 1 1 100%;
        justify-content: center;
    }

    .mst-bar .abtn {
        flex: 1 1 auto;
        justify-content: center;
    }

    /* List card: tighter, and the row lift is dropped — it only smears
       on a touch screen where there is no hover to begin with */
    .lc-body {
        padding: 12px;
    }

    .lc-show,
    .lc-info {
        font-size: 12px;
    }

    .lc-show select {
        flex: 1;
        width: auto;
    }

    .lc-card table.dataTable tbody tr:hover {
        transform: none;
        box-shadow: none;
    }

    /* Navbar: drop the profile text, keep avatar + actions */
    .prof-nm,
    .prof-rl {
        display: none;
    }

    .prof-btn {
        padding: 3px;
    }

    .nav {
        padding-right: 12px;
    }

    .brand {
        width: auto;
        border-right: none;
        padding: 0 12px;
    }

    .epoch-logo {
        width: 88px;
    }

    /* Menu picker gets more room */
    .mst-pick {
        max-height: 46vh;
    }

    /* Dialling code sits above the number on the narrowest screens */
    .mst-phone {
        flex-wrap: wrap;
    }

    /* flex-basis again, for the same reason the base rule uses it — width
       alone would leave the 112px basis in charge and the pair would not
       stack. */
    .mst-phone-code {
        flex: 1 1 100%;
        width: 100%;
    }

    .mst-phone-number {
        flex: 1 1 100%;
    }

    /* Permission matrix: label above the level dropdown */
    .perm-row {
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
        padding: 12px 14px;
    }

    .perm-sel {
        width: 100%;
        height: 40px;
    }

    .perm-save {
        flex-direction: column;
        align-items: stretch;
    }

    .perm-save .abtn {
        justify-content: center;
    }

    .auth-title {
        font-size: 20px;
    }
}

/* Respect users who ask for less motion */
@media (prefers-reduced-motion: reduce) {

    .sidenav,
    .ui-backdrop {
        transition: none;
    }
}

/* ── Bulk upload: the two steps stack once the row gets tight ── */
@media (max-width: 820px) {
    .lc-up-grid {
        grid-template-columns: 1fr;
        gap: 18px;
    }

    .lc-up-pick .finp {
        flex: 1 1 100%;
    }

    .lc-up-pick .abtn {
        flex: 1 1 100%;
        justify-content: center;
    }
}

/* ── Customer form: the repeating rows and the save bar ── */
@media (max-width: 820px) {
    .rep-row {
        padding: 12px;
    }

    .lc-form-ft {
        position: static;
        flex-direction: column-reverse;
        align-items: stretch;
        padding: 12px;
    }

    .lc-form-ft .abtn {
        justify-content: center;
    }
}

/* ── Record tabs: scroll sideways rather than wrap ── */
@media (max-width: 560px) {
    .lc-tabs {
        padding: 0 12px;
    }

    .lc-tab {
        padding: 12px 12px;
        font-size: 12.5px;
    }
}

/* â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•
   LEAD WORKFLOW  â€”  stage 1 and stage 2 on the lead view

   The two field grids are auto-fit, so they reflow on their own. What is
   left is the rows that are flex: the reassign row and the two confirm
   bars, which otherwise leave a button stranded on its own line, and the
   tab bar, which needs its padding pulled in on a phone.
   â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â• */

@media (max-width: 820px) {
    /* The reassign controls stop competing for width and take a line each.
       A select showing "name â€” 2/5 active, 96% successâ€¦" is unreadable at
       half a phone's width. */
    .lw-move .abtn {
        justify-content: center;
        width: 100%;
    }

    /* The engineer rows carry five things on one line; below this they
       need the whole width, and the panel needs the whole dialog. */
    .lw-engdd-panel {
        max-height: 60vh;
    }

    .lw-engstats {
        gap: 6px 10px;
    }

    /* The dialog's two numbers stack rather than sharing a narrow row. */
    .lw-dlg-bd .lw-fields {
        grid-template-columns: 1fr;
    }

    .lw-teambar {
        align-items: stretch;
        flex-direction: column;
    }

    .lw-teambar .abtn {
        justify-content: center;
    }

    /* Guidance text above the button rather than beside it, so the button
       keeps a full-width tap target. */
    .lw-actions {
        align-items: stretch;
        flex-direction: column;
    }

    .lw-actions .fgroup,
    .lw-actions-note {
        min-width: 0;
        width: 100%;
    }

    .lw-actions .abtn {
        justify-content: center;
        width: 100%;
    }

    .lw-summary {
        gap: 14px 22px;
    }
}

@media (max-width: 560px) {
    /* Tabs scroll sideways rather than wrap â€” same as .lc-tabs above. */
    .lw-tab {
        padding: 11px 12px;
        font-size: 12.5px;
    }

    .lw-card-bd,
    .lw-job-bd {
        padding: 12px;
        gap: 10px;
    }

    .lw-item {
        padding: 12px 13px;
    }

    .lw-group-bd {
        padding: 9px 9px 1px;
    }

    .lw-job-hd {
        padding: 10px 12px;
    }

    /* The job code and the item name stop sharing a line: at this width
       the code was pushing the name down to one word per line. */
    .lw-job-hd {
        align-items: flex-start;
        flex-direction: column;
        gap: 7px;
    }

    .lw-job-hd .lw-nm {
        min-width: 0;
    }

    /* Put-back sits under the terms box rather than beside it: at this width
       the two side by side left the box too narrow to read a sentence in. */
    .qt-terms {
        align-items: stretch;
        flex-direction: column;
    }

    .qt-reterms {
        width: 100%;
        height: 34px;
    }

    /* The pick bar stacks rather than squeezing three things onto a line
       narrower than the count it is showing. */
    .qv-pickbar {
        align-items: stretch;
        flex-direction: column;
        gap: 9px;
        position: static;
    }

    .qv-group-hint {
        flex: 1 0 100%;
        order: 9;
    }

    /* The job row wraps rather than squeezing the name, the codes and the
       button onto one line narrower than any of them. */
    .qv-job-hd {
        flex-wrap: wrap;
    }

    .qv-job-sub {
        flex: 1 0 100%;
        margin-right: 0;
        order: 8;
    }

    .qv-job-go {
        margin-left: auto;
    }

    /* A quotation's buttons drop to their own line rather than crushing the
       number and the status they belong to. The chevron stays up on the first
       line, where the row it folds is. */
    .qc-hd {
        flex-wrap: wrap;
    }

    .qc-act {
        flex: 1 0 100%;
        order: 9;
        justify-content: flex-start;
    }

    /* The terms surface stacks: the Change button on its own line rather
       than squeezing the set name into three words. */
    .qt-tc {
        align-items: flex-start;
        flex-wrap: wrap;
        gap: 10px;
    }

    .qt-tc-main {
        flex: 1 1 100%;
        order: 3;
    }

    .qt-tc-cta {
        margin-left: auto;
    }

    .qt-tc-read {
        max-height: 180px;
    }

    /* The held-for-a-price line and the accepted line both read as a
       sentence, so at this width the icon goes above it rather than
       squeezing the words into a column two characters wide. */
    .lw-lock {
        align-items: flex-start;
        padding: 10px 12px;
        line-height: 1.5;
    }

    .lw-bulk-top {
        align-items: flex-start;
        flex-direction: column;
        gap: 8px;
    }

    /* Clear was pushed to the far right by margin-left:auto, which on a
       stacked column puts it on its own line miles from the count. */
    .lw-bulk-clear {
        margin-left: 0;
    }

    /* Two full-width rows rather than two squeezed columns — at this width
       neither label fits on one line. */
    .lw-modes {
        flex-direction: column;
    }

    /* Every category button on one row still, but tighter: three of them
       wrapping to two lines reads as two groups rather than one choice. */
    .lw-cat {
        padding: 7px 10px;
        font-size: 11.5px;
    }

    .lw-card-hd {
        padding: 6px 12px;
        gap: 9px;
    }

    /* On a touch screen there is no hover, so the "waiting for signature"
       message has nothing to reveal it. It stays up. */
    .lw-gate-msg {
        top: 76px;
        max-width: none;
        padding: 14px 16px;
    }
}

/* Same on any pointerless device, whatever its width — a tablet is wide
   enough to miss the rule above and still has nothing to hover with. */
@media (hover: none) {
    .lw-gate.locked .lw-gate-msg {
        opacity: 1;
        transform: none;
    }
}

/* ── Quotation builder ─────────────────────────────────────────────────
   The document's three-up header and the notes-beside-totals split are the
   two things that cannot survive a narrow screen. Both collapse to one
   column; the lines table keeps its min-width and scrolls inside its own
   wrapper rather than pushing the page sideways. */

@media (max-width: 1080px) {
    .qt-grid { grid-template-columns: repeat(2, 1fr) }
    .qt-bottom { grid-template-columns: 1fr }
}

@media (max-width: 820px) {
    .qt-brandrow { flex-direction: column; gap: 14px }
    .qt-brandmeta { gap: 18px }
    .qt-grid { grid-template-columns: 1fr }
    .qt-revise { flex: 1 1 100% }
}

@media (max-width: 560px) {
    .qt-brandmeta { flex-direction: column; gap: 10px }
    .qt-tr .finp, .qt-tr .fsel { max-width: 108px }
    .qt-grand { font-size: 14px }
    .qt-grand b { font-size: 15px }
}

/* ── Quotation list: the lead row and its jobs ─────────────────────────
   The action column is the first thing to go: on a narrow screen the row
   itself is the control, and the jobs fold out under it either way. */

@media (max-width: 820px) {
    .qx-act .abtn { padding: 6px 10px; font-size: 12px }
    .qx-jobcode { padding-left: 10px !important }
}

@media (max-width: 560px) {
    .qx-n { display: block; margin-left: 0 }
}

/* ── Quotation view pages ──────────────────────────────────────────────
   The gap between stacked blocks tightens with the screen, so a card that
   holds a grid, a note and a button does not become mostly whitespace. */

@media (max-width: 820px) {
    .qt-page .lw-card-bd > * + * { margin-top: 13px }
}

@media (max-width: 560px) {
    .qt-page .lw-card-bd > * + * { margin-top: 11px }
}

/* ── Followup timeline ─────────────────────────────────────────────────
   The author's name drops under the header row rather than being pushed
   off the end of it. */

@media (max-width: 560px) {
    .fu-by { margin-left: 0; width: 100% }
    .fu-entry-ft { gap: 8px }
}
