/* =====================================================================
   RC Power Portal — Mobile Responsiveness (Phase 1)
   All rules are scoped to @media (max-width: 768px) so the desktop
   layout is never affected. Colors reuse the existing theme variables.
   Breakpoint: 768px (tablet/phone). Tested at 375px / 390px.
   ===================================================================== */

/* ---------------------------------------------------------------------
   Bottom Tab Bar (Step 1) — base styles (hidden on desktop)
   --------------------------------------------------------------------- */
#mobileTabBar {
    display: none;
}

/* Mobile-only top-right logout button (base.html) — hidden on desktop. */
#mobileLogoutBtn {
    display: none;
}

@media (max-width: 768px) {
    #mobileLogoutBtn {
        display: flex;
        align-items: center;
        justify-content: center;
        position: fixed;
        top: calc(8px + env(safe-area-inset-top, 0px));
        right: max(10px, env(safe-area-inset-right, 0px));
        width: 40px;
        height: 40px;
        border-radius: 50%;
        /* Below Bootstrap modals/backdrops (~1050) so it can never steal
           taps from an open modal's close button. */
        z-index: 1030;
        background: var(--card-bg, #ffffff);
        color: var(--text-muted-color, #6c757d);
        border: 1px solid var(--border-color, #dee2e6);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
        font-size: 1.15rem;
        text-decoration: none;
        touch-action: manipulation;
        -webkit-tap-highlight-color: transparent;
    }
    /* Deterministic non-interference while any modal is open. */
    body.modal-open #mobileLogoutBtn {
        display: none;
    }
    /* The fixed tab bar (z-index 9999) paints ABOVE Bootstrap modals (~1055),
       covering modal-footer buttons (e.g. the Change Order Save) on small
       viewports. Navigation is irrelevant while a modal is open — hide the
       bar so every modal's footer is reachable; it returns on close because
       Bootstrap removes body.modal-open. */
    body.modal-open #mobileTabBar {
        display: none;
    }
}

@media (max-width: 768px) {
    #mobileTabBar {
        display: flex;
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        /* Grow by the iOS home-indicator inset (viewport-fit=cover makes
           env() non-zero) so tap targets sit above the gesture zone. */
        height: calc(56px + env(safe-area-inset-bottom, 0px));
        z-index: 9999;
        background: var(--card-bg, #ffffff);
        border-top: 1px solid var(--border-color, #dee2e6);
        box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.12);
        padding-bottom: env(safe-area-inset-bottom, 0);
    }
    #mobileTabBar .mtab {
        flex: 1 1 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 2px;
        padding: 6px 2px;
        min-height: 44px;
        text-decoration: none;
        color: var(--text-muted-color, #6c757d);
        font-size: 0.66rem;
        line-height: 1.1;
        text-align: center;
        background: transparent;
        border: none;
        touch-action: manipulation;
        -webkit-tap-highlight-color: transparent;
    }
    #mobileTabBar .mtab i {
        font-size: 1.35rem;
        line-height: 1;
    }
    #mobileTabBar .mtab span {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        max-width: 100%;
    }
    #mobileTabBar .mtab.active {
        color: var(--primary-color, #1b3a5c);
    }
    #mobileTabBar .mtab.active i {
        transform: translateY(-1px);
    }
}

/* ---------------------------------------------------------------------
   Base Layout (Step 2) — hide top navbar, content padding, AI bubble
   --------------------------------------------------------------------- */
@media (max-width: 768px) {
    /* Replace the top navbar with the bottom tab bar */
    nav.navbar {
        display: none !important;
    }

    /* Keep page content clear of the fixed bottom tab bar (56px + safe area)
       and clear of the iOS status bar / notch at the top (navbar is hidden
       on mobile, so nothing else reserves that space). */
    body {
        padding-bottom: calc(70px + env(safe-area-inset-bottom, 0px)) !important;
        padding-top: env(safe-area-inset-top, 0px);
    }

    /* Prevent iOS auto-zoom on input focus + keep base text readable */
    html {
        -webkit-text-size-adjust: 100%;
    }
    body {
        font-size: 15px;
    }

    /* AI chat bubble + panel must sit above the bottom tab bar */
    #rcaiBubble {
        bottom: calc(90px + env(safe-area-inset-bottom, 0px)) !important;
        right: 16px !important;
    }
    #rcaiPanel {
        bottom: calc(156px + env(safe-area-inset-bottom, 0px)) !important;
        right: 12px !important;
        left: 12px !important;
        width: auto !important;
        max-width: none !important;
        max-height: calc(100vh - 230px) !important;
    }

    /* Notification + profile dropdowns full width (when navbar shown elsewhere) */
    .dropdown-menu {
        width: 100% !important;
        max-width: 100vw !important;
    }

    /* Stack any multi-column page headers to a single column */
    .d-flex.justify-content-between.align-items-center,
    .page-header,
    .d-flex.justify-content-between.align-items-start {
        flex-wrap: wrap;
        gap: 0.5rem;
    }
}

/* ---------------------------------------------------------------------
   Mobile Notifications Overlay (Step 1/2)
   --------------------------------------------------------------------- */
#mobileNotifPanel {
    display: none;
}
@media (max-width: 768px) {
    #mobileNotifPanel.open {
        display: flex;
        flex-direction: column;
        position: fixed;
        inset: 0;
        z-index: 10000;
        background: var(--body-bg, #f8f9fa);
    }
    #mobileNotifPanel .mnotif-header {
        background: var(--primary-color, #1b3a5c);
        color: #fff;
        padding: 1rem;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 0.5rem;
    }
    #mobileNotifPanel .mnotif-body {
        flex: 1;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }
    #mobileNotifPanel .mnotif-body .notif-item {
        font-size: 0.9rem;
    }
}

/* ---------------------------------------------------------------------
   Dashboards (Step 3)
   --------------------------------------------------------------------- */
@media (max-width: 768px) {
    /* Filter / search bars and primary action buttons go full width */
    .dashboard-filter,
    .filter-bar input,
    .filter-bar select,
    .search-bar input {
        width: 100% !important;
    }

    /* Make stat-card rows readable; force at least 2-up where a row of
       equal cards exists (cards already using col-6/col-md-3 keep 2-up). */
    .stat-card,
    .summary-card {
        margin-bottom: 0.75rem;
    }
}

/* ---------------------------------------------------------------------
   Scrollable tab bars (Steps 3 & 4) — nav-tabs / nav-pills overflow
   --------------------------------------------------------------------- */
@media (max-width: 768px) {
    .nav-tabs,
    .nav-pills {
        flex-wrap: nowrap;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .nav-tabs::-webkit-scrollbar,
    .nav-pills::-webkit-scrollbar {
        display: none;
    }
    .nav-tabs .nav-item,
    .nav-pills .nav-item {
        flex: 0 0 auto;
    }
    .nav-tabs .nav-link,
    .nav-pills .nav-link {
        white-space: nowrap;
    }
}

/* ---------------------------------------------------------------------
   Tables (Step 6) — horizontal scroll without breaking desktop.
   Excludes DataTables (they manage their own responsive wrapper).
   --------------------------------------------------------------------- */
@media (max-width: 768px) {
    .table-responsive {
        -webkit-overflow-scrolling: touch;
    }
    /* .table-sticky tables scroll inside their .table-sticky-wrap instead
       (display:block on the table itself would break the sticky columns). */
    .table:not(.dataTable):not(.table-sticky) {
        display: block;
        width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        white-space: nowrap;
    }

    /* Other .table-sticky lists (pending projects, PM approvals, completed,
       submitted bids, client jobs…) keep the horizontal-scroll + sticky
       Job # column treatment — they still have many columns on mobile. */
    .table-sticky-wrap {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .table-sticky {
        white-space: nowrap;
    }
    .table-sticky th:first-child,
    .table-sticky td:first-child {
        position: sticky;
        left: 0;
        background: var(--card-bg, #ffffff);
        z-index: 3;
    }
    .table-sticky thead th:first-child {
        z-index: 6; /* above the sticky header row (z-index 5) and the sticky column */
    }

    /* Main dashboard project lists ONLY: fit-to-width. The whole table fits
       the phone screen with NO horizontal scroll — low-value columns are
       hidden in the templates via d-none d-md-table-cell, so the sticky
       column is disabled here (nothing scrolls sideways).
       (#completedProjectsTable is qualified with .table-sticky so only the
       senior dashboard's Completed tab is hit — the PM dashboard reuses the
       same id on a non-sticky table with different columns.) */
    #myProjectsTable,
    #activeProjectsTable,
    #completedProjectsTable.table-sticky {
        table-layout: fixed;
        width: 100%;
        font-size: 10.5px;
        white-space: normal;
    }
    #myProjectsTable th, #myProjectsTable td,
    #activeProjectsTable th, #activeProjectsTable td,
    #completedProjectsTable.table-sticky th, #completedProjectsTable.table-sticky td {
        position: static;              /* undo sticky first column */
        padding: 4px 3px !important;
        white-space: normal !important;
        overflow-wrap: anywhere;
        vertical-align: middle;
    }
    /* Compact the in-cell widgets so rows stay short. */
    #myProjectsTable .progress, #activeProjectsTable .progress { height: 14px !important; min-width: 52px; }
    #myProjectsTable .progress-bar, #activeProjectsTable .progress-bar { font-size: 9px; }
    #myProjectsTable .badge, #activeProjectsTable .badge,
    #completedProjectsTable.table-sticky .badge { font-size: 9px !important; }
    #myProjectsTable .btn-sm, #activeProjectsTable .btn-sm,
    #completedProjectsTable.table-sticky .btn-sm { padding: 2px 5px; font-size: 10.5px; }
    #myProjectsTable .btn-text-mobile, #activeProjectsTable .btn-text-mobile,
    #completedProjectsTable.table-sticky .btn-text-mobile { display: none; }
    /* Visible-column proportions (hidden columns don't take space).
       PM dashboard (#myProjectsTable) shows: Job#, Project, Progress, Status, Actions. */
    #myProjectsTable th:nth-child(1) { width: 24%; }
    #myProjectsTable th:nth-child(3) { width: 26%; }
    #myProjectsTable th:nth-child(5) { width: 20%; }
    #myProjectsTable th:nth-child(7) { width: 14%; }
    #myProjectsTable th:nth-child(8) { width: 16%; }
    /* Senior dashboard (#activeProjectsTable) shows: Job#, Project Name, Assigned PM, Progress, Actions. */
    #activeProjectsTable th:nth-child(1) { width: 16%; }
    #activeProjectsTable th:nth-child(2) { width: 26%; }
    #activeProjectsTable th:nth-child(5) { width: 18%; }
    #activeProjectsTable th:nth-child(6) { width: 24%; }
    #activeProjectsTable th:nth-child(8) { width: 16%; }
    /* Senior Completed tab shows: Job#, Contract Value, Approved, Actions. */
    #completedProjectsTable.table-sticky th:nth-child(1) { width: 24%; }
    #completedProjectsTable.table-sticky th:nth-child(6) { width: 30%; }
    #completedProjectsTable.table-sticky th:nth-child(7) { width: 22%; }
    #completedProjectsTable.table-sticky th:nth-child(8) { width: 24%; }

    /* Grids/containers never exceed the viewport — any overflow must happen
       inside a scroll container, never by widening the page body. */
    main.container,
    main.container-fluid {
        max-width: 100% !important;
        overflow-x: clip;
    }
}

/* ---------------------------------------------------------------------
   Forms & Modals (Step 5)
   --------------------------------------------------------------------- */
@media (max-width: 768px) {
    /* Full-width form controls; 16px prevents iOS zoom-on-focus */
    .form-control,
    .form-select,
    input[type="text"],
    input[type="email"],
    input[type="password"],
    input[type="number"],
    input[type="search"],
    input[type="date"],
    input[type="tel"],
    textarea,
    select {
        width: 100%;
        font-size: 16px !important;
    }

    /* Labels stack above inputs */
    .form-label {
        display: block;
        margin-bottom: 0.35rem;
    }

    /* Full-screen modals */
    .modal-dialog {
        width: 100%;
        max-width: 100%;
        min-height: 100%;
        margin: 0;
    }
    .modal-content {
        min-height: 100vh;
        border-radius: 0;
        border: none;
    }
    .modal-fullscreen-guard .modal-body {
        overflow-y: auto;
    }

    /* Dropdown menus full width */
    .dropdown-menu {
        width: 100% !important;
    }
}

/* ---------------------------------------------------------------------
   Touch Optimizations (Step 7)
   --------------------------------------------------------------------- */
/* Eliminate the 300ms tap delay + zoom-on-double-tap and the grey tap flash
   on every interactive element (applies on all viewports; harmless on desktop). */
button,
.btn,
a,
input,
select,
textarea,
label,
.nav-link,
.nav-tabs .nav-link,
.tab-pane,
.dropdown-item,
.mtab,
[role="button"],
tr[data-project-id] {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

/* ---------------------------------------------------------------------
   Instant tap feedback (Fix 2) — touch devices only.
   The touch-action + tap-highlight rules above remove the 300ms delay and
   the grey iOS flash; these :active rules replace that flash with an
   immediate physical "pressed" state (slight shrink + dim) so a tap feels
   responsive before the click/navigation resolves. Scoped to
   hover:none/pointer:coarse so desktop mouse users keep their hover styles.
   --------------------------------------------------------------------- */
@media (hover: none) and (pointer: coarse) {
    button:active,
    a:active,
    .btn:active,
    .card.clickable:active,
    .clickable:active,
    .tpl-card:active,
    [role="button"]:active,
    .mtab:active,
    .dropdown-item:active {
        transform: scale(0.97);
        filter: brightness(0.9);
        transition: transform 0.06s ease, filter 0.06s ease;
    }
    /* Disabled controls must not read as pressable. */
    button:disabled:active,
    .btn:disabled:active,
    .btn.disabled:active,
    a.disabled:active,
    [aria-disabled="true"]:active {
        transform: none;
        filter: none;
    }
}

@media (max-width: 768px) {
    /* Comfortable touch targets for non-small buttons */
    .btn:not(.btn-sm):not(.btn-close) {
        min-height: 44px;
    }
    /* Form submit / block buttons full width */
    .btn-block,
    form .btn-primary,
    form .btn-success,
    form button[type="submit"],
    .modal-footer .btn {
        width: 100%;
    }
    .modal-footer {
        flex-direction: column;
        gap: 0.5rem;
    }
    /* Larger checkbox/radio touch targets */
    .form-check-input {
        width: 1.3em;
        height: 1.3em;
    }
}

/* ---------------------------------------------------------------------
   PM Dashboard + Project Detail — mobile zoom-out + table density (Fix 4)
   Mirrors the senior-dashboard treatment so more columns fit on a phone.
   Everything is scoped to @media (max-width: 768px) so desktop is untouched.
   --------------------------------------------------------------------- */
@media (max-width: 768px) {
    /* Zoom the main content out so wide tables fit ~4-5 columns at 390px.
       `zoom` (unlike transform: scale) reflows and leaves no empty gutter;
       the fixed bottom tab bar + AI bubble live OUTSIDE <main> so they keep
       their normal size. */
    /* (zoom hack removed — wide tables now scroll inside their own
       containers and text sizes are handled by the density rules below.) */

    /* Tighter table text + cell padding everywhere on these two surfaces
       (active projects, financials tab, SOV, checklist, CO tables, etc.).
       DataTables-managed tables are EXCLUDED (:not(.dataTable)) — overriding
       their layout/display breaks column sizing + sorting UI. */
    body[data-dashboard-role="pm"] table.table:not(.dataTable),
    body[data-page="project-detail"] table.table:not(.dataTable) {
        font-size: 11px !important;
    }
    body[data-dashboard-role="pm"] table.table:not(.dataTable) td,
    body[data-dashboard-role="pm"] table.table:not(.dataTable) th,
    body[data-page="project-detail"] table.table:not(.dataTable) td,
    body[data-page="project-detail"] table.table:not(.dataTable) th {
        padding: 3px 5px !important;
        vertical-align: middle;
    }
    /* Column headers: 11px bold. */
    body[data-dashboard-role="pm"] table.table:not(.dataTable) th,
    body[data-page="project-detail"] table.table:not(.dataTable) th {
        font-size: 11px !important;
        font-weight: 700 !important;
    }

    /* Fit-to-width: these tables render as real tables (NOT display:block
       scroll boxes), locked to the container width with wrapping cells so
       there is no horizontal scroll. Low-value columns (e.g. Files) are
       hidden in the templates via d-none d-md-table-cell. */
    body[data-dashboard-role="pm"] table.table:not(.dataTable),
    body[data-page="project-detail"] table.table:not(.dataTable) {
        display: table;
        table-layout: fixed;
        width: 100%;
        overflow-x: visible;
        white-space: normal;
    }
    body[data-dashboard-role="pm"] table.table:not(.dataTable) td,
    body[data-dashboard-role="pm"] table.table:not(.dataTable) th,
    body[data-page="project-detail"] table.table:not(.dataTable) td,
    body[data-page="project-detail"] table.table:not(.dataTable) th {
        white-space: normal !important;
        overflow-wrap: anywhere;
    }
    /* Neutralize desktop inline th widths (e.g. Checklist's 130px Status)
       so fixed layout distributes the 360px evenly. Scoped to project-detail
       only — dashboard column widths are set explicitly above. */
    body[data-page="project-detail"] table.table:not(.dataTable) th {
        width: auto !important;
    }
    body[data-page="project-detail"] table.table:not(.dataTable) .btn-sm {
        padding: 2px 5px;
        font-size: 10.5px;
    }

    /* SOV Updates Labor actuals table: 8 numeric columns can't fit 360px
       legibly — this table opts OUT of the fit-to-width treatment above and
       scrolls sideways inside its own .table-responsive wrapper instead.
       (Selectors use table.table.labor-actuals-table so they tie the generic
       fit rules' specificity and win by coming later in the cascade.) */
    body[data-page="project-detail"] table.table.labor-actuals-table {
        display: table;
        table-layout: auto;            /* natural column widths */
        width: auto;
        min-width: 720px;              /* comfortable columns; wrapper scrolls */
        font-size: 12px !important;
        white-space: nowrap;
    }
    body[data-page="project-detail"] table.table.labor-actuals-table td,
    body[data-page="project-detail"] table.table.labor-actuals-table th {
        padding: 6px 8px !important;
        white-space: nowrap !important; /* numbers stay on one line */
        overflow-wrap: normal;
        word-break: normal;
    }
    body[data-page="project-detail"] table.table.labor-actuals-table .form-control-sm {
        font-size: 16px;               /* usable inputs, no iOS focus zoom */
        min-width: 84px;
    }
    body[data-page="project-detail"] table.table.labor-actuals-table .text-muted {
        font-size: 10px !important;    /* TSheets/Manual sublines */
    }
    /* Only this table's wrapper scrolls sideways — never the page. */
    body[data-page="project-detail"] .table-responsive:has(> .labor-actuals-table) {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Modals: never taller than the visible viewport, so the header row with
       the close (X) is always on screen and tappable. The body scrolls
       internally instead of pushing the header off the top. */
    .modal-dialog {
        margin: calc(8px + env(safe-area-inset-top)) 8px calc(8px + env(safe-area-inset-bottom));
        max-width: none;
    }
    .modal-content {
        max-height: calc(100dvh - 16px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
    }
    .modal-body {
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        min-height: 0;
    }
    .modal-header {
        flex-shrink: 0;
    }
    .modal-footer {
        flex-shrink: 0;
    }
}

/* =====================================================================
   App Loading Shell — instant first paint (kills PWA white screen).
   Global (NOT inside @media) so it covers desktop + mobile alike. Rendered
   straight from base.html <body>, hidden by JS once the page is ready.
   ===================================================================== */
#app-loading-shell {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #1F3864;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 999999;
}
#app-loading-shell .app-loading-logo {
    width: 120px;
    height: auto;
    margin-bottom: 24px;
    /* Force the logo to render white on the navy background. */
    filter: brightness(0) invert(1);
}
#app-loading-shell .app-loading-text {
    color: #ffffff;
    margin-top: 16px;
    margin-bottom: 0;
    font-size: 14px;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
.rc-spinner-white {
    width: 44px;
    height: 44px;
    border: 4px solid rgba(255, 255, 255, 0.25);
    border-top-color: #ffffff;
    border-radius: 50%;
    animation: rc-spin 0.8s linear infinite;
}
@keyframes rc-spin {
    to { transform: rotate(360deg); }
}

/* ---------------------------------------------------------------------
   PWA "Add to Home Screen" install banner (shown via JS, mobile only)
   --------------------------------------------------------------------- */
#pwaInstallBanner {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 10000;
    display: none;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    background: #1F3864;
    color: #ffffff;
    padding: calc(10px + env(safe-area-inset-top, 0px)) 14px 10px;
    font-size: 0.9rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}
#pwaInstallBanner .pwa-install-text {
    flex: 1 1 auto;
    line-height: 1.3;
}
#pwaInstallBanner .pwa-install-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
}
#pwaInstallBanner .pwa-install-btn {
    background: #F2A900;
    color: #1F3864;
    border: none;
    border-radius: 8px;
    padding: 8px 16px;
    font-weight: 700;
    font-size: 0.85rem;
    min-height: 40px;
    cursor: pointer;
    white-space: nowrap;
}
#pwaInstallBanner .pwa-install-dismiss {
    background: transparent;
    color: #ffffff;
    border: none;
    font-size: 1.5rem;
    line-height: 1;
    padding: 0 6px;
    min-height: 40px;
    min-width: 40px;
    cursor: pointer;
}

/* ===================================================================== */
/* Voice Input — mobile touch targets + recording banner                 */
/* ===================================================================== */
@media (max-width: 768px) {
    .voice-mic-btn {
        width: 44px;
        height: 44px;
        font-size: 20px;
        right: 2px;
    }
    .voice-field-wrap.voice-textarea .voice-mic-btn {
        top: 4px;
    }
    /* Reserve a wider gutter so the larger mic never covers typed text. */
    .voice-has-mic {
        padding-right: 50px !important;
    }
    /* Keep the recording banner clear of the iOS status bar / notch. */
    #voiceRecordingBanner {
        padding-top: calc(10px + env(safe-area-inset-top, 0px));
        font-size: 1rem;
    }
}

/* ---------------------------------------------------------------------
   Senior Dashboard — mobile compactness (Fix 1)
   --------------------------------------------------------------------- */
@media (max-width: 768px) {
    /* Financial Overview card: shrink padding + the big dollar figures so the
       whole card fits on a 390px screen without internal scrolling. */
    [data-dashboard-section="financial-overview"] .card-body {
        padding: 0.65rem 0.85rem !important;
    }
    [data-dashboard-section="financial-overview"] [style*="font-size:1.35rem"] {
        font-size: 1.02rem !important;
    }
    [data-dashboard-section="financial-overview"] .row {
        --bs-gutter-x: 0.75rem;
    }

    /* Project Status Overview: tighten so the 3 stat figures stay in one row. */
    [data-dashboard-section="status-overview"] .card-body {
        padding: 0.75rem !important;
    }
    #chart-bar .d-flex {
        gap: 0.75rem !important;
    }

    /* Sort / client-filter / search controls stack full width and stay aligned. */
    .dashboard-controls-bar {
        flex-direction: column;
        align-items: stretch !important;
    }
    #dashboardSortSelect,
    #clientFilterSelect,
    .dashboard-global-filter {
        width: 100% !important;
        min-width: 0 !important;
    }
    .dashboard-global-filter .project-table-filter {
        width: 100% !important;
    }

    /* Admin Tools card collapses by default on mobile (toggle in the header). */
    .admin-tools-body {
        display: none;
    }
    .admin-tools-body.expanded {
        display: block;
    }
    .admin-tools-toggle {
        line-height: 1;
    }
}

/* ---------------------------------------------------------------------
   Senior Dashboard — zoom out + density (Fix 2, mobile only)
   `zoom` (unlike transform: scale) reflows layout and leaves no empty
   gutter; the fixed bottom tab bar + AI bubble live OUTSIDE <main> so
   they are not scaled. Everything here is scoped to the senior dashboard
   body so other pages and the desktop layout are untouched.
   --------------------------------------------------------------------- */
@media (max-width: 768px) {
    /* (zoom hack removed — tables scroll in .table-sticky-wrap containers
       and the density rules below keep content compact.) */

    /* Reduce card padding + margins ~40%. */
    body[data-dashboard-role="senior"] .card-body {
        padding: 0.55rem 0.7rem !important;
    }
    body[data-dashboard-role="senior"] .card {
        margin-bottom: 0.6rem !important;
    }

    /* Headers down 2-3px. */
    body[data-dashboard-role="senior"] h2 { font-size: 1.25rem !important; }
    body[data-dashboard-role="senior"] h3 { font-size: 1.05rem !important; }
    body[data-dashboard-role="senior"] h4,
    body[data-dashboard-role="senior"] h5,
    body[data-dashboard-role="senior"] .card-header { font-size: 0.95rem !important; }

    /* Table text 11px, tight cell padding, shorter rows. */
    body[data-dashboard-role="senior"] table.table {
        font-size: 11px !important;
    }
    body[data-dashboard-role="senior"] table.table td,
    body[data-dashboard-role="senior"] table.table th {
        padding: 4px 6px !important;
        vertical-align: middle;
    }

    /* Stat-card numbers to 1.1rem (top counts + status-overview figures). */
    body[data-dashboard-role="senior"] .stat-number,
    body[data-dashboard-role="senior"] .display-6,
    body[data-dashboard-role="senior"] .stat-card .h3,
    body[data-dashboard-role="senior"] [data-dashboard-section="status-overview"] .fw-bold {
        font-size: 1.1rem !important;
    }

    /* Button text 12px. */
    body[data-dashboard-role="senior"] .btn {
        font-size: 12px !important;
    }

    /* =============================================================
       Client dashboard — Project Status Overview breathing room.
       Stack the title above the chart-type toggle buttons so the
       count numbers never sit under the buttons, and give the bar
       chart clear vertical space. Client mobile only.
       ============================================================= */
    body[data-dashboard-role="client"] [data-dashboard-section="stat-cards"] .card-body > .d-flex.justify-content-between {
        flex-direction: column;
        align-items: flex-start !important;
        gap: 10px;
        margin-bottom: 1.25rem !important;
    }
    body[data-dashboard-role="client"] [data-dashboard-section="stat-cards"] .chart-view {
        padding-top: 6px;
    }
    body[data-dashboard-role="client"] [data-dashboard-section="stat-cards"] #chart-bar .d-flex.align-items-end {
        gap: 1rem !important;
    }
    body[data-dashboard-role="client"] [data-dashboard-section="stat-cards"] #chart-bar .fw-bold {
        margin-bottom: 4px;
    }
}

/* ---------------------------------------------------------------------------
   Safety pages + MOP detail — mobile table treatment (≤768px only).
   Two treatments, matching the established patterns above:
   - FIT: read-only list tables (project_safety, mop_detail, JHA pre-start)
     get the dashboard fit-to-width treatment (table-layout fixed, compact
     font, word wrapping) so they read with NO sideways scroll.
   - SCROLL: input-heavy JHA form tables (crew, equipment, JHA steps, site
     conditions, hazard mitigation, permits) slide cleanly like the SOV
     Labor table — touch scroll, headers on one line, inputs kept at a
     usable width, never squished or per-character wrapped.
--------------------------------------------------------------------------- */
@media (max-width: 768px) {

    /* ----- FIT tables (override the generic display:block + nowrap rule) -- */
    table.table.safety-fit,
    table.table.mop-fit,
    table.table.jha-table.jha-fit {
        display: table !important;
        table-layout: fixed;
        width: 100% !important;
        font-size: 10.5px;
        white-space: normal !important;
    }
    table.table.safety-fit th, table.table.safety-fit td,
    table.table.mop-fit th, table.table.mop-fit td,
    table.table.jha-table.jha-fit th, table.table.jha-table.jha-fit td {
        padding: 4px 3px !important;
        white-space: normal !important;
        overflow-wrap: break-word;   /* wrap at word boundaries, not per-char */
        vertical-align: middle;
    }
    table.table.safety-fit .badge,
    table.table.mop-fit .badge { font-size: 9px !important; }
    table.table.safety-fit .btn-sm,
    table.table.mop-fit .btn-sm { padding: 2px 5px; font-size: 10.5px; }
    /* MOP detail action buttons stack vertically instead of side-by-side */
    table.table.mop-fit td .btn-sm {
        display: block;
        width: 100%;
        margin: 0 0 3px 0 !important;
    }
    /* Column proportions — keep action/date columns from starving.
       Safety library docs: Title / (Added By / Added / Files) / View */
    table.table.safety-fit th:last-child { width: 17%; }
    /* JHA plan list: Task/Location/Date/Status/Risk/Actions */
    #jhaTable.safety-fit th:nth-child(3) { width: 15%; }
    #jhaTable.safety-fit th:nth-child(5) { width: 11%; }
    #jhaTable.safety-fit th:nth-child(6) { width: 17%; }
    /* MOP lists: #/Title/Steps/Status/Date/Actions */
    table.table.mop-fit th:nth-child(1) { width: 14%; }
    table.table.mop-fit th:nth-child(3) { width: 9%; }
    table.table.mop-fit th:nth-child(6) { width: 21%; }
    /* JHA pre-start: Item/Status/Notes — undo the desktop min-width */
    table.table.jha-table.jha-fit th:nth-child(2) { min-width: 0 !important; width: 30%; }
    table.table.jha-table.jha-fit .form-select,
    table.table.jha-table.jha-fit .form-control { min-width: 0; font-size: 10.5px; }

    /* ----- SCROLL tables (JHA form + RAC matrix): clean slide ------------- */
    /* The generic .table rule already makes these display:block with
       overflow-x:auto + touch scrolling; here we make the slide CLEAN:
       headers stay on one line, and every input keeps a usable width so
       columns never squish or wrap character-by-character. */
    table.table.jha-table:not(.jha-fit) th {
        white-space: nowrap;
    }
    table.table.jha-table:not(.jha-fit) td {
        min-width: 96px;
    }
    table.table.jha-table:not(.jha-fit) .form-control,
    table.table.jha-table:not(.jha-fit) .form-select {
        min-width: 110px;
        font-size: 12px;
    }
    table.table.jha-table:not(.jha-fit) textarea.form-control { min-width: 150px; }
    /* narrow utility cells (row #, delete button) stay narrow */
    table.table.jha-table:not(.jha-fit) td:last-child { min-width: 44px; }
    table.table.rac-matrix { max-width: none !important; }
}
