/*
 * Design system - dark theme ported 1:1 from the original app's
 * dashboard.html / manager_portal.html / cmo_portal.html, plus a light
 * "Microsoft Fluent"-style theme toggled via [data-theme="light"] on
 * <html> (see assets/js/theme.js). Same CSS custom properties, same
 * class names (panel, kpi, btn, toolbar, filterable-th, status-pill,
 * modal, bar-row...) throughout - only the variable VALUES change
 * between themes, not the markup.
 */
:root {
    /* Tells the browser which palette to draw native form controls in
       (date/time picker, the little calendar icon, spinner arrows,
       scrollbars) - without this the browser defaults to light-mode
       control assets even on this dark theme, rendering the date
       input's calendar icon as a near-black glyph on a near-black
       field (--input-bg #0b1220) - effectively invisible/untappable. */
    color-scheme: dark;
    --bg: #0f172a;
    --card: #1e293b;
    --text: #e2e8f0;
    --muted: #94a3b8;
    --accent: #38bdf8;
    --accent-text: #04121f;
    --green: #22c55e;
    --yellow: #eab308;
    --red: #ef4444;
    --purple: #a78bfa;
    --orange: #f97316;
    /* A solid Yellow bar/badge FILL, as opposed to --yellow (Yellow
       shown as TEXT) - light theme dims --yellow down to a muted
       brown for text legibility (plain bright yellow text on a white
       card fails contrast), but that same dimming made a Yellow bar
       "look gray" (Shoaib, 2026-09-06) - a solid rectangle doesn't
       need that same accommodation, so it stays this same sharp value
       in both themes. Same reasoning --red/--green never needed a
       second variant: their own light-theme values (below) are
       already vivid enough to work as both text AND a fill. */
    --yellow-bar: #eab308;
    --border: #2b3b57;
    --input-bg: #0b1220;
    --nav-bg: #131f38;
    --btn-secondary-bg: #334155;
    --shadow: none;
    --info-bg: #1e3a5f;
    --info-border: #38bdf8;
    --info-text: #7dd3fc;
    --warn-bg: #3a2f0f;
    --warn-border: #eab308;
    --warn-text: #fde68a;

    /* Chart palette - exactly 3 colors, on request (the previous
       "always-dark canvas + glow + rounded bars" neon treatment read as
       gimmicky, not clean - this reverts all of that: charts are back
       to following the page's own light/dark theme like every other
       panel, flat solid fills, square corners, no shadow/glow). Only
       ONE definition of these 3 values exists anywhere in the app -
       here - and every chart reads them via chartTheme() (line-
       chart.js), not a per-template copy, so changing a chart's colors
       ever again means editing these 3 lines, nothing else. Same 3
       roles used consistently across every chart: Target/New
       Enrolment=blue, Achieved/Follow-up=green, % Achieved=yellow (a
       4th series, where a chart genuinely needs one, cycles back to
       blue rather than inventing a 4th named color). Each measured
       (WCAG) at >=4.8:1 against this theme's own surface - see the
       light block below for its own (separately tuned, since a single
       hex can't clear a good contrast ratio against both a near-black
       and a near-white surface) set. */
    --chart-blue: #5b9dff;
    --chart-green: #4ade80;
    --chart-yellow: #facc15;

    /* Target vs Achievement charts (Daily FC Reporting) ONLY - matched
       directly to a reference chart image Shoaib shared (2026-09-06):
       "use this color scheme and style" - the classic Office/Excel
       navy + sky-blue + steel-blue-line + orange-% look this feature's
       own source data ("BNP 3.0 Progress and Achievement Working
       File") was originally presented in. Deliberately a real-world
       reference match, not another abstract-palette derivation - the
       dark navy sits below the data-viz skill's own lightness-band/
       chroma-floor bands (it's meant to read as a deliberately muted
       "baseline" color, same as it does in the source spreadsheet),
       but CVD separation from the sky-blue is excellent regardless
       (ΔE 38.7 deutan light / 27.0 dark, both far past the >=8 target)
       and every bar always carries a visible value label (Shoaib's own
       earlier "data labels are must"), which is exactly the relief
       channel the skill requires wherever raw contrast runs low. */
    --chart-target: #3d63a8;
    --chart-achieved: #38bdf8;
    --chart-line: #7fa6e8;
    --chart-pct: #fb923c;
}

/* "Professional Microsoft style" light theme - Fluent-ish: white/light
   gray surfaces, subtle shadows instead of hard borders, Office blue accent. */
:root[data-theme="light"] {
    color-scheme: light;
    --bg: #f3f2f1;
    --card: #ffffff;
    --text: #201f1e;
    --muted: #605e5c;
    --accent: #0078d4;
    --accent-text: #ffffff;
    --green: #107c10;
    --yellow: #986f0b;
    --yellow-bar: #eab308;
    --red: #d13438;
    --purple: #5c2d91;
    --orange: #ca5010;
    --border: #e1dfdd;
    --input-bg: #ffffff;
    --nav-bg: #ffffff;
    --btn-secondary-bg: #f3f2f1;
    --shadow: 0 1px 2px rgba(0,0,0,.06), 0 1px 8px rgba(0,0,0,.04);
    --info-bg: #deecf9;
    --info-border: #0078d4;
    --info-text: #004578;
    --warn-bg: #fff4ce;
    --warn-border: #986f0b;
    --warn-text: #6b4a00;

    /* Same 3-color chart palette, light-mode steps - see the dark block
       above for why this one place is the only place these are ever
       defined. */
    --chart-blue: #1c64f2;
    --chart-green: #15803d;
    --chart-yellow: #a16207;

    /* Target vs Achievement charts only - see the dark block above for
       why (a direct match to a reference chart image, not another
       abstract-palette derivation). This is the reference image's own
       light-mode look almost exactly - navy/sky-blue/steel-blue-line/
       orange-%, the classic Office/Excel chart palette. CVD separation
       (target vs achieved) ΔE 38.7 deutan, far past the >=8 target. */
    --chart-target: #1f3864;
    --chart-achieved: #00b0f0;
    --chart-line: #4472c4;
    --chart-pct: #ed7d31;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    font-family: "Segoe UI", -apple-system, Roboto, Arial, sans-serif;
    background: var(--bg);
    color: var(--text);
    font-size: 14px;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---------- theme toggle ---------- */
.theme-toggle {
    background: var(--btn-secondary-bg);
    color: var(--text);
    border: 1px solid var(--border);
    padding: 6px 12px;
    border-radius: 6px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}
.theme-toggle:hover { filter: brightness(1.08); }

/* ---------- app shell: left sidebar nav ---------- */
/* Replaces the old horizontal topbar + nav.tabnav (Shoaib, 2026-09-22:
   "when i open coordnator or my dashboard main manu then sub manu.
   which take almost half of the screen. what i want is a the menu in
   left sile like when we open cauad [Claude] app. resizeable manu on
   left side with show and hid togel") - a left sidebar, resizable via
   its own right-edge drag handle and collapsible via a show/hide
   toggle, same idea as the Claude desktop app's own sidebar. See
   assets/js/sidebar.js for the resize/collapse/mobile-drawer JS this
   all depends on. */
:root { --sidebar-width: 240px; }

.app-shell { display: flex; min-height: 100vh; align-items: stretch; }

.sidebar {
    flex: 0 0 var(--sidebar-width);
    width: var(--sidebar-width);
    display: flex;
    flex-direction: column;
    background: var(--card);
    border-right: 1px solid var(--border);
    position: relative;
}

.sidebar-header {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 8px;
    padding: 16px 14px 12px; border-bottom: 1px solid var(--border);
}
.sidebar-header .brand { font-size: 16px; font-weight: 700; line-height: 1.3; }
/* Admin/Coordinator's own complete-name variant (Shoaib, 2026-09-17:
   "need complete... in my panel and coordinator panel only") - smaller
   than the default 16px so "Results Monitoring and Performance
   Insights Dashboard" doesn't visually dominate this header the way
   the short "RMPI" mark does at full size. */
.sidebar-header .brand.brand-full { font-size: 12.5px; font-weight: 600; }
.sidebar-collapse-btn {
    flex-shrink: 0; background: transparent; border: 1px solid var(--border); border-radius: 6px;
    color: var(--muted); width: 26px; height: 26px; cursor: pointer; font-size: 14px; line-height: 1;
    display: flex; align-items: center; justify-content: center;
}
.sidebar-collapse-btn:hover { background: var(--btn-secondary-bg); color: var(--text); }

.sidebar-nav { flex: 1 1 auto; overflow-y: auto; padding: 10px 8px; display: flex; flex-direction: column; gap: 2px; }
.sidebar-nav a, .sidebar-nav .nav-disabled {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 10px; border-radius: 6px; font-size: 13.5px; font-weight: 600;
    color: var(--muted); white-space: nowrap;
}
.sidebar-nav a:hover { background: var(--btn-secondary-bg); color: var(--text); text-decoration: none; }
/* Selected page (Shoaib, 2026-09-22 follow-up: "when a page is select
   no need to color bule to its butte only gray hover is enughf") -
   same gray as :hover above, not the blue --accent used elsewhere for
   real buttons/pills - so the current page stays marked without
   competing with those for attention. */
.sidebar-nav a.active { background: var(--btn-secondary-bg); color: var(--text); }
.sidebar-nav .nav-disabled { color: #94a3b8; opacity: .5; cursor: not-allowed; }
.sidebar-nav .nav-icon { flex-shrink: 0; width: 18px; text-align: center; font-size: 14px; }
.sidebar-section-divider { height: 1px; background: var(--border); margin: 8px 6px; flex-shrink: 0; }

/* Nested tree for Dashboard/My Dashboards (Shoaib, 2026-09-22: "My
   Dashboard -> Daily FC Repoting -> Progress -> Submission Status ->
   ... no horizonta manu" - replaces that hub page's own horizontal
   .subtabs row, and Daily FC Reporting/Logistics Dashboard's own
   horizontal .subtabs bars, with this tree built into the sidebar
   itself). A .nav-group-toggle looks like every other .sidebar-nav
   link but is a <button>, not an <a> - it only expands/collapses its
   own .nav-children, never navigates (base.html decides its initial
   .expanded/.active state from request.resolver_match; sidebar.js's
   toggleNavGroup() is the only other thing that touches it - see
   there for why that's not persisted). .nav-children nests to two
   depths (Dashboard's own 5 entries, then Daily FC Reporting/
   Logistics Dashboard's own former subtabs one level deeper) - same
   look at both, just more indent/smaller type the deeper it goes. */
.nav-group-toggle {
    width: 100%; background: none; border: none; cursor: pointer; font: inherit; text-align: left;
    display: flex; align-items: center; gap: 10px;
    padding: 9px 10px; border-radius: 6px; font-size: 13.5px; font-weight: 600;
    color: var(--muted); white-space: nowrap; text-decoration: none;
}
.nav-group-toggle:hover { background: var(--btn-secondary-bg); color: var(--text); text-decoration: none; }
.nav-group-toggle.active { background: var(--btn-secondary-bg); color: var(--text); }
/* Its own click target within a .nav-group-toggle that IS a link
   ("Dashboard" - see base.html) - a few extra px of hit area/hover
   feedback so it's easy to tap without also following the link. */
.nav-group-toggle .nav-caret {
    margin-left: auto; flex-shrink: 0; cursor: pointer;
    padding: 3px 5px; margin-right: -5px; border-radius: 4px;
    font-size: 10px; transition: transform .15s ease;
}
.nav-group-toggle .nav-caret:hover { background: rgba(127,127,127,.2); }
.nav-group.expanded > .nav-group-toggle .nav-caret { transform: rotate(90deg); }
.nav-children { display: none; flex-direction: column; gap: 2px; }
.nav-group.expanded > .nav-children { display: flex; }
.nav-children a, .nav-children .nav-group-toggle { padding-left: 32px; font-size: 13px; font-weight: 500; }
.nav-children .nav-children a, .nav-children .nav-children .nav-group-toggle { padding-left: 50px; font-size: 12.5px; }

.sidebar-footer { padding: 10px 12px 14px; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 8px; }
.sidebar-footer .user-name { font-size: 12.5px; color: var(--muted); padding: 0 2px; overflow: hidden; text-overflow: ellipsis; }
.sidebar-footer form { margin: 0; }
.sidebar-footer .btn, .sidebar-footer .theme-toggle { width: 100%; text-align: center; }

/* Drag-to-resize - an invisible strip straddling the sidebar's own
   right border, only visibly tinted on hover/while dragging so it
   doesn't read as a stray line the rest of the time. */
.sidebar-resize-handle { position: absolute; top: 0; right: -3px; width: 6px; height: 100%; cursor: col-resize; z-index: 5; }
.sidebar-resize-handle:hover, .sidebar-resize-handle:active { background: var(--accent); opacity: .35; }

/* The "bring it back" button - only ever visible while the sidebar
   itself is hidden (collapsed on desktop, or always available on
   mobile since the drawer starts closed there) - see the two
   width-scoped media blocks below for exactly when each applies. */
.sidebar-show-btn {
    display: none; position: fixed; top: 14px; left: 14px; z-index: 250;
    width: 36px; height: 36px; border-radius: 8px;
    background: var(--card); border: 1px solid var(--border); color: var(--text);
    box-shadow: var(--shadow); cursor: pointer; font-size: 16px; line-height: 1;
    align-items: center; justify-content: center;
}
.sidebar-show-btn:hover { background: var(--btn-secondary-bg); }

.sidebar-backdrop { display: none; }

.app-main { flex: 1 1 auto; min-width: 0; }

@media (min-width: 901px) {
    html.sidebar-collapsed .sidebar { display: none; }
    html.sidebar-collapsed .sidebar-show-btn { display: flex; }
}

@media (max-width: 900px) {
    /* Off-canvas drawer - a completely separate, never-persisted state
       (.mobile-nav-open, not .sidebar-collapsed - see sidebar.js) from
       the desktop collapse preference above, so a desktop session's
       remembered "hidden" choice never leaks into a phone's own
       default (always starts closed) or vice versa. */
    .sidebar {
        position: fixed; inset: 0 auto 0 0; z-index: 300;
        width: min(280px, 82vw);
        transform: translateX(-100%);
        transition: transform .2s ease;
        box-shadow: var(--shadow);
    }
    html.mobile-nav-open .sidebar { transform: translateX(0); }
    .sidebar-resize-handle { display: none; }
    .sidebar-show-btn { display: flex; }
    .sidebar-backdrop { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.4); z-index: 290; }
    html.mobile-nav-open .sidebar-backdrop { display: block; }
}

.link-button { background: none; border: none; color: var(--accent); cursor: pointer; font-size: 13px; padding: 0; }
.link-button:hover { text-decoration: underline; }

.content {
    padding: clamp(14px, 2.5vw, 28px) clamp(14px, 3vw, 32px) 60px;
    max-width: 1680px;
    margin: 0 auto;
    width: 100%;
}

h1 { font-size: clamp(18px, 2vw, 22px); margin: 0 0 16px; }
h2 { font-size: 14px; margin: 0 0 14px; }

/* ---------- layout helpers ---------- */
.grid4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 20px; }
@media (max-width: 900px) { .grid4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .grid4 { grid-template-columns: 1fr; } }
/* Same idea as .grid4 above, one more column - the CMO Dashboard's 6
   KPIs in one row (Shoaib, 2026-09-23: "then all the six pannels"). */
.grid6 { display: grid; grid-template-columns: repeat(6, 1fr); gap: 16px; margin-bottom: 20px; }
@media (max-width: 1100px) { .grid6 { grid-template-columns: repeat(3, 1fr); } }

/* A group of permission/access checkboxes laid out in even columns
   instead of one-per-line (Shoaib, 2026-09-25, Account Management's
   own form: "the access chekboesx are not visualy appling. could you
   make them more gematric and alligned") - each label lines up its
   checkbox and text the same way regardless of label length, columns
   wrap responsively, and it collapses to one column on phone width. */
.checkbox-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 6px 16px; }
.checkbox-grid label { display: flex; align-items: center; gap: 6px; font-size: 12.5px; margin: 0; }
@media (max-width: 640px) { .grid6 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 400px) { .grid6 { grid-template-columns: 1fr; } }
.kpi { background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 16px 18px; box-shadow: var(--shadow); }
.kpi .num { font-size: 26px; font-weight: 700; }
.kpi .label { color: var(--muted); font-size: 12px; margin-top: 4px; }

.row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; }
.row3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; margin-bottom: 16px; }
@media (max-width: 900px) { .row, .row3 { grid-template-columns: 1fr; } }
/* min-width: 0 - without it, a CSS Grid item (.row/.row3's own 1fr
   tracks) won't shrink below its content's intrinsic/max-content
   width. A chart-wrap'd canvas is sized in JS to fit its data (see
   line-chart.js's sizeChartCanvas() - e.g. 30 days * 34px), which for
   a wide dataset can genuinely exceed a 1fr column's fair-share width
   - without this, the grid TRACK itself grows to fit that content
   instead, pushing the whole row (and everything after it) past the
   page's own width. chart-wrap's own overflow-x:auto is meant to
   contain that overflow as an in-panel horizontal scroll instead - it
   can only do that once the panel is actually allowed to be narrower
   than its content, which is what this line grants. */
.panel { background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 18px; box-shadow: var(--shadow); min-width: 0; }
/* A filter row that's ALSO a .panel (Progress/Daily FC Reporting,
   Logistics Dashboard, CMO Dashboard, Site Targets, FC Stats Dashboard
   - every `class="panel toolbar"` form in the app) - Shoaib, 2026-09-24:
   "the filter pannel in progress, daily FC reporting and other take too
   much space... reduse ita hite little". Less top/bottom padding than a
   regular .panel (which still needs room for a heading + table/chart
   inside it) - a filter row is just one line of compact form controls,
   so it doesn't need as much breathing room above/below. */
.panel.toolbar { padding: 10px 16px; }

.detail-grid { display: grid; grid-template-columns: 1fr 1.3fr; gap: 24px; align-items: start; }
@media (max-width: 900px) { .detail-grid { grid-template-columns: 1fr; } }

/* Column picker dropdown (Follow-up/SAM/MAM queues) - lets an operator
   choose which columns their table shows, remembered per-browser. */
.col-picker {
    display: none; position: absolute; top: calc(100% + 6px); left: 0; z-index: 40;
    background: var(--card); border: 1px solid var(--border); border-radius: 10px;
    width: 250px; max-height: 400px; box-shadow: 0 10px 28px rgba(0,0,0,.35);
    overflow: hidden; flex-direction: column;
}
.col-picker.open { display: flex; }
.col-picker-header {
    padding: 12px 14px 10px; border-bottom: 1px solid var(--border);
    display: flex; justify-content: space-between; align-items: center; flex-shrink: 0;
}
.col-picker-title { font-size: 11px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; }
.col-picker-actions { display: flex; gap: 10px; }
.col-picker-actions a { font-size: 11px; font-weight: 600; color: var(--accent); cursor: pointer; }
.col-picker-actions a:hover { text-decoration: underline; }
.col-picker-list { overflow-y: auto; padding: 6px 0; }
.col-picker-item {
    display: flex; align-items: center; gap: 9px; padding: 8px 14px;
    font-size: 13px; color: var(--text); cursor: pointer;
}
.col-picker-item:hover { background: var(--input-bg); }
.col-picker-item input { width: auto; margin: 0; flex-shrink: 0; accent-color: var(--accent); cursor: pointer; }
.col-picker-footer { padding: 10px 14px; border-top: 1px solid var(--border); flex-shrink: 0; }

/* ---------- tables ---------- */
.scrollbox { max-height: 460px; overflow: auto; }
table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--border); white-space: nowrap; }
th { color: var(--muted); font-weight: 600; position: sticky; top: 0; background: var(--card); }
th.filterable-th { cursor: pointer; user-select: none; }
th.filterable-th:hover { color: var(--accent); }

/* FC Report tables (Protocol Detail/Treatment of MAM especially) have
   long metric labels that, combined with the nowrap rule above, forced
   the whole table wider than the screen and triggered a horizontal
   scrollbar - this lets just that one column wrap onto multiple lines
   instead of forcing the row wider. Works down to tablet width; a
   7-column table (Metric + 4 counts + 2 auto columns) still doesn't
   fit a phone screen at any reasonable font size, so phones get an
   actual layout change below, not just smaller text. */
.fc-metric-cell { white-space: normal; max-width: 160px; }
.fc-report-table th, .fc-report-table td { padding: 6px 6px; font-size: 12.5px; }
/* Overrides .mobile-content input's generous 12px/14px padding, which
   at box-sizing:border-box would leave almost no room for digits in a
   narrow cell - kept at font-size:16px regardless (never lower - that's
   what stops iOS Safari zooming the whole page in on focus). */
.mobile-content input.fc-num {
    width: 48px; padding: 7px 2px; min-height: 36px; text-align: center; font-size: 16px;
}

/* Below tablet width: still a real table (not the old stacked-chip
   layout - see git history), but now sized to fit the screen with NO
   horizontal scroll at all, on request - table-layout:fixed makes the
   browser respect an explicit width on the Metric column and split the
   REST of the table's width evenly across however many count/auto
   columns that row actually has (5 on Protocol Detail/MAM's 7-column
   rows, fewer elsewhere), so this one rule works for every section's
   different column count without hardcoding per-column percentages.
   Font size is one shared value for every cell in the table (header
   and body alike, every section) rather than varying - what was asked
   for. The Auto Calculated table (10 columns, one of them "Unit" free
   text like "CTNs/Bottles") is the tightest fit here: long values wrap
   rather than overflow, which is the trade-off of "no side-scrolling"
   on that specific table - if it's still cramped after this, a
   screenshot will make it easy to tune further. */
@media (max-width: 640px) {
    .fc-report-table { table-layout: fixed; width: 100%; }
    .fc-report-table th, .fc-report-table td {
        font-size: 9px; padding: 3px 1px; overflow-wrap: break-word; text-align: center;
    }
    /* td.fc-metric-cell (not just .fc-metric-cell) so this beats the
       ".fc-report-table td { text-align:center }" rule above on
       specificity - a plain class-only selector there would actually
       lose that fight and the label would wrongly center. Narrowed
       from 74px to 66px to give the number columns a little more of
       the table's fixed width budget - see input.fc-num below, this is
       the other half of the same fix. */
    .fc-report-table td.fc-metric-cell, .fc-report-table th:first-child {
        width: 66px; max-width: 66px; white-space: normal; text-align: left;
    }
    /* Removes the separate scroll-within-a-scroll box these tables sit
       in on desktop (.scrollbox's own max-height+overflow:auto) - with
       no horizontal overflow possible any more, this table just flows
       as part of the page, one single up/down scroll like everything
       else on the page instead of a second nested scrollbar. */
    .scrollbox:has(.fc-report-table) { max-height: none; overflow: visible; }
    /* font-size:9px here (on request) DROPS the iOS-Safari-zoom-on-
       focus protection the shared, non-mobile input.fc-num rule further
       up this file keeps at 16px on purpose - below 16px, iOS zooms the
       whole page in when one of these is tapped. Deliberate trade-off:
       every screenshot so far has been Android, where this doesn't
       apply.

       width switched from 100% (of the table cell) to a small EXPLICIT
       px value, and min-width:0 added - a two-digit value ("55") was
       still showing clipped to one visible character even after the
       previous round of shrinking, which points at this specific
       mobile browser not fully honoring width:100% against a
       table-layout:fixed cell (or not overriding the UA-stylesheet's
       own default minimum width on a text input, which content-box
       sizing can't shrink below on its own - min-width:0 is the
       standard fix for that). An explicit width sidesteps needing that
       resolution to work at all. !important throughout because the
       symptom (values rendering at what looks like the old 16px/full-
       padding despite this rule's own specificity already being higher
       than every competing rule in this file) suggests SOMETHING is
       still winning here that source-order/specificity math alone says
       shouldn't - this forces the issue rather than debug it blind. */
    /* Box width/height/font all confirmed good as they are - only the
       LEFT/RIGHT padding goes to 0 here (top/bottom kept at 1px so the
       digit doesn't touch the top/bottom border). Note this doesn't
       erase every bit of visible gap around a single narrow digit like
       "0" sitting in a 26px-wide, center-aligned box - that's the box
       being wider than that one character's own width, not padding;
       removing IT would mean shrinking the box, which was explicitly
       asked not to happen this time. */
    .mobile-content input.fc-num {
        width: 26px !important; min-width: 0 !important; max-width: none !important;
        min-height: 16px !important; padding: 1px 0 !important; margin: 0 !important;
        box-sizing: border-box !important; font-size: 9px !important; line-height: 1.2 !important;
    }

    /* Auto Calculated's own two rows (fc_portal/report_detail.html) -
       the long metric text ("New enrolment (BNP new Normal + TSFP new
       + SAM new + MMS New)") used to be its own cell squeezed into a
       10-column table alongside 9 value columns, which is what made
       the numbers overlap and run together, not just small text. It's
       a heading above its own value-only table now (9 columns, no
       Metric column), so the ".fc-report-table th:first-child" rule
       above (meant for an actual Metric column) needs overriding here
       - the compound ".fc-report-table.fc-auto-values-table" selector
       outweighs it on specificity regardless of source order. */
    /* Same 9px every other .fc-report-table cell in this section uses -
       was 12px, on request. */
    .fc-auto-title { font-weight: 600; font-size: 9px; line-height: 1.3; margin: 0 0 6px; color: var(--text); }
    .fc-report-table.fc-auto-values-table th:first-child,
    .fc-report-table.fc-auto-values-table td:first-child {
        width: auto; max-width: none; text-align: center;
    }
    .fc-report-table.fc-auto-values-table th:last-child,
    .fc-report-table.fc-auto-values-table td:last-child {
        width: 46px;
    }

    /* Opening and Closing SNF's "By Batch" table (fc_portal/monthly_
       report.html) - Shoaib, 2026-10-01: "its font size should also be
       the same like above pannels" (the schema section tables above
       it, which are .fc-report-table). Matches THAT class's mobile
       font-size/padding only - deliberately does NOT also pull in
       table-layout:fixed or the width-squeeze rules above, since THAT
       combination is what made Commodity/Batch Number run together in
       the first place (this table has two text columns, not one) -
       still a plain nowrap table that scrolls sideways in its
       .scrollbox instead of being squeezed to fit. */
    .snf-batch-table th, .snf-batch-table td { font-size: 9px; padding: 3px 4px; }
}
th.filterable-th.active-filter { color: var(--accent); }

/* Two-pane Follow-up queue layout (queue.html) - the case list on the
   left, the opened case's detail panel on the right, so a call operator
   working through a list of cases never loses the list off-screen the
   way a single stacked column did. Both panes share one fixed height
   (--queue-split-h) so their bottoms line up instead of the right pane
   trailing off wherever its content happens to end, and each scrolls
   independently within that height rather than growing the page. Below
   1100px there isn't room for both panes at a usable width, so it drops
   back to a stacked layout with natural (unclipped) height. */
.queue-split {
    display: flex; gap: 16px; align-items: stretch;
    --queue-split-h: calc(100vh - 260px);
}
.queue-split-left { flex: 1 1 70%; min-width: 0; display: flex; flex-direction: column; height: var(--queue-split-h); min-height: 420px; }
.queue-split-left .scrollbox { flex: 1; max-height: none; overflow-y: auto; }
.queue-split-right {
    flex: 1 1 30%; min-width: 0; position: sticky; top: 16px;
    height: var(--queue-split-h); min-height: 420px; overflow-y: auto;
}
@media (max-width: 1100px) {
    .queue-split { display: block; }
    .queue-split-left, .queue-split-right { height: auto; min-height: 0; }
    .queue-split-left .scrollbox { max-height: 460px; }
    .queue-split-right { position: static; margin-top: 16px; }
}

/* Detail panel tab strip (_record_detail_content.html) - Details/Log a
   Call/Call History/CMO render one at a time (see that template's own
   comment for why a combined single-column view - tried right before
   this - still didn't work: even at full pane width, the four sections
   together were simply too tall for the pane's fixed/sticky height, so
   only splitting them into separate views actually solved it). */
.detail-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; }
.detail-tab {
    padding: 6px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
    background: var(--btn-secondary-bg); color: var(--muted); border: 1px solid var(--border);
    cursor: pointer; text-decoration: none; white-space: nowrap;
}
.detail-tab:hover { color: var(--text); text-decoration: none; }
.detail-tab.active { background: var(--accent); color: #fff; border-color: var(--accent); }

/* Call History / CMO Report History tables inside the detail panel - the
   panel can be well under half the page width in the split queue view
   above, where the default global `white-space: nowrap` on every td (see
   the base `th, td` rule) forced these particular multi-column tables
   into a horizontal scrollbar. table-layout:fixed divides the width
   evenly across columns and lets every cell wrap instead of stretching
   the row - short values (dates, names, statuses) still render on one
   line since they're never wide enough to need wrapping in the first
   place; only the longer free-text cells (Remark/Text Msg/Report)
   actually wrap in practice. */
.detail-wrap-table { table-layout: fixed; width: 100%; }
.detail-wrap-table td { white-space: normal; word-break: break-word; }

/* Drag-to-reorder column headers (Follow-up queue - see wireColumnDrag()
   in queue.html). filterable-th already sets cursor:pointer for the
   filter click; :active swaps in a grab cursor just while a header is
   actually being pressed/dragged. */
th[data-drag-key]:active { cursor: grabbing; }
th.dragging-col { opacity: .4; }
th.drag-over-col { box-shadow: inset 2px 0 0 var(--accent), inset -2px 0 0 var(--accent); }

.status-pill { padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; background: var(--btn-secondary-bg); color: var(--text); }

/* ---------- forms / buttons ---------- */
input, select, textarea {
    background: var(--input-bg);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 8px 10px;
    border-radius: 6px;
    font-size: 13px;
    font-family: inherit;
}
form label { display: block; font-size: 12px; color: var(--muted); margin: 10px 0 4px; }
form input, form select, form textarea { width: 100%; }

/* A radio group rendered as a row of pill buttons instead of the
   default bare-bullet list - still a real <input type="radio">
   underneath (so "pick exactly one, required" is enforced by the
   browser exactly as before), just the native circle is visually
   hidden and the label itself becomes the tappable, highlighted-
   when-selected control. Markup: <label class="radio-pill">{{ radio.tag }}<span>{{ radio.choice_label }}</span></label>
   inside a <div class="radio-pills">, one per option (see
   fc_portal/due_case_resolve.html for the full loop). `display:
   inline-flex` here is required, not decorative - `form label` above
   would otherwise make each pill's wrapping <label> block-level and
   stack them vertically instead of in one row. */
.radio-pills { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 16px; }
.radio-pill { display: inline-flex; align-items: center; position: relative; cursor: pointer; margin: 0; }
.radio-pill input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.radio-pill span {
    display: inline-block; padding: 8px 14px; border: 1px solid var(--border);
    border-radius: 999px; background: var(--input-bg); color: var(--text);
    font-size: 14px; white-space: nowrap; user-select: none;
}
.radio-pill input:checked + span { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.radio-pill input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

button, .btn {
    background: var(--accent);
    color: var(--accent-text);
    border: none;
    padding: 8px 16px;
    border-radius: 6px;
    font-weight: 700;
    cursor: pointer;
    font-size: 13px;
}
button:hover, .btn:hover { filter: brightness(1.08); }
.btn.secondary { background: var(--btn-secondary-bg); color: var(--text); border: 1px solid var(--border); }
.btn.danger { background: var(--red); color: #fff; }
.btn.small { padding: 4px 10px; font-size: 11px; }

.toolbar { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; align-items: center; }

/* ---------- messages ---------- */
.message { padding: 10px 14px; border-radius: 8px; margin-bottom: 16px; font-size: 13px; }
.message-error { background: #451a1a; color: #fca5a5; border: 1px solid #7f1d1d; }
.message-success { background: #14301f; color: #86efac; border: 1px solid #166534; }
:root[data-theme="light"] .message-error { background: #fdf3f4; color: #a4262c; border-color: #d13438; }
:root[data-theme="light"] .message-success { background: #dff6dd; color: #0b6a0b; border-color: #107c10; }

/* ---------- bar charts (plain divs, no canvas needed for simple bars) ---------- */
.bar-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.bar-label { width: 150px; font-size: 12px; color: var(--muted); flex-shrink: 0; overflow: hidden; text-overflow: ellipsis; }
.bar-track { flex: 1; background: var(--input-bg); border-radius: 6px; height: 16px; overflow: hidden; }
.bar-fill { height: 100%; border-radius: 6px; background: var(--accent); }
.bar-val { width: 100px; text-align: right; font-size: 12px; color: var(--muted); flex-shrink: 0; }

/* ---------- daily trend charts (hand-rolled canvas, no chart library) ---------- */
/* Horizontal scroll, not a cramped fit, once a chart has more
   categories than comfortably fit the container - see line-chart.js's
   sizeChartCanvas(), which sets the canvas's own inline width past
   100% (overriding the rule below) exactly when that happens. Vertical
   scroll too (Shoaib, 2026-09-06: "zoom is only left to right, I also
   need it up and down") - sizeChartCanvas() now grows a zoomed-in
   canvas's inline height past this rule's own 260px the same way, and
   this needs overflow-y: auto instead of hidden or that taller canvas
   would just get clipped instead of becoming scrollable. */
.chart-wrap { height: 260px; overflow-x: auto; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.chart-wrap canvas { width: 100%; height: 100%; display: block; }
.chart-legend { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 8px; font-size: 13px; color: var(--text); }
.chart-legend i { display: inline-block; width: 14px; height: 4px; border-radius: 2px; margin-right: 6px; vertical-align: middle; }

/* Tap/click any chart to expand it full-screen - see registerChartExpand()
   in line-chart.js. One shared overlay, reused by every chart on the page. */
.chart-lightbox {
    display: none; position: fixed; inset: 0; z-index: 300;
    background: rgba(0,0,0,.88); padding: 20px 20px calc(20px + env(safe-area-inset-bottom));
    align-items: center; justify-content: center;
}
.chart-lightbox.open { display: flex; }
/* A real card surface (var(--card), the same one every .panel sits on),
   not the bare dark overlay showing straight through a transparent
   canvas - and a fixed, sane height instead of stretching to fill
   nearly the whole viewport, which distorted a chart tuned for a
   ~260px-tall .chart-wrap into an oddly tall, sparse shape (Shoaib,
   2026-09-06: "background is transparent...spread over all screen"). */
.chart-lightbox-inner {
    width: 100%; max-width: 1400px; height: min(80vh, 720px);
    background: var(--card); border: 1px solid var(--border); border-radius: 10px;
    box-shadow: var(--shadow); padding: 20px 24px;
    display: flex; flex-direction: column; gap: 8px;
}
.chart-lightbox-title { margin: 0; font-size: 18px; font-weight: 600; color: var(--text); flex: 0 0 auto; }
/* Same scroll behavior as the small chart's own .chart-wrap (see
   line-chart.js's sizeChartCanvas()/scroll-to-right default) - kept as
   its own class rather than reusing .chart-wrap so its height comes
   from the surrounding flex column, not that class's fixed 260px.
   overflow-y: auto for the same reason as .chart-wrap's own (Shoaib,
   2026-09-06: vertical wheel-zoom, wired onto the lightbox canvas too). */
.chart-lightbox-canvas-wrap { flex: 1 1 auto; min-height: 0; overflow-x: auto; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.chart-lightbox-canvas-wrap canvas { width: 100%; height: 100%; display: block; }
.chart-lightbox-legend { flex: 0 0 auto; }
/* registerPanelZoom()'s content mode - a bar-row list or table cloned
   in at a larger, more legible size than its small card version, with
   its own scroll (a tall district list or the Transitions table can
   both run past the lightbox's fixed height/width). */
.chart-lightbox-content { flex: 1 1 auto; min-height: 0; overflow: auto; font-size: 15px; }
.chart-lightbox-content table { font-size: 15px; }
.chart-lightbox-content .bar-row { margin-bottom: 14px; }
.chart-lightbox-content .bar-label { width: 220px; font-size: 14px; }
.chart-lightbox-content .bar-val { width: 130px; font-size: 14px; }
.chart-lightbox-content .bar-track { height: 20px; }
/* The small "⤢" button registerPanelZoom() appends to a panel's own
   <h2> - a plain outlined icon button, not a full zoom-in cursor on
   the whole panel (unlike a chart canvas, a bar-row/table panel has
   no single element that unambiguously means "this is the zoomable
   thing" to click). */
.panel-expand-btn {
    background: none; border: 1px solid var(--border); border-radius: 6px; color: var(--muted);
    cursor: pointer; font-size: 13px; line-height: 1; padding: 3px 7px; margin-left: 8px;
    vertical-align: middle;
}
.panel-expand-btn:hover { color: var(--text); border-color: var(--accent); }
.chart-lightbox-close {
    position: absolute; top: 14px; right: 14px; width: 40px; height: 40px; border-radius: 50%;
    border: none; background: rgba(255,255,255,.12); color: #fff; font-size: 18px; line-height: 1;
    cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.chart-lightbox-close:hover { background: rgba(255,255,255,.22); }
.chart-wrap canvas[data-expandable] { cursor: zoom-in; }

/* ---------- modal / column-filter popup ---------- */
.modal-backdrop {
    display: none; position: fixed; inset: 0; background: rgba(0,0,0,.6);
    align-items: center; justify-content: center; z-index: 50;
}
.modal-backdrop.open { display: flex; }
.modal { background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 20px; width: 480px; max-width: 92vw; max-height: 80vh; overflow: auto; box-shadow: var(--shadow); }
.modal h3 { margin-top: 0; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }

#colFilterPopup a { color: var(--accent); }

/* Year -> Month -> Day tree used by openDateColumnFilterPopup()
   (assets/js/column-filter.js) for date-valued columns - e.g. the
   Follow-up queue's "Last Called" column - instead of the flat
   alphabetical checklist openColumnFilterPopup() shows every other
   column, which would be hundreds of individual dates in useless
   string order. */
.date-filter-tree {
    overflow: auto; flex: 1; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
    padding: 4px 0; margin-bottom: 8px; max-height: 260px; font-size: 12px;
}
.date-tree-row { display: flex; align-items: center; gap: 4px; padding: 2px 4px; color: var(--text); }
.date-tree-row label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.date-tree-row input[type="checkbox"] { width: auto; margin: 0; flex-shrink: 0; accent-color: var(--accent); cursor: pointer; }
.date-tree-toggle { cursor: pointer; width: 14px; display: inline-block; color: var(--muted); user-select: none; }
.date-tree-leaf { padding-left: 20px; }
.date-tree-month .date-tree-row { padding-left: 14px; }
.date-tree-children { padding-left: 12px; }

/* ---------- login page ---------- */
.login-body {
    display: flex; align-items: center; justify-content: center; min-height: 100vh; background: var(--bg); padding: 16px;
}
.login-card { background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 32px; width: 400px; max-width: 100%; box-shadow: var(--shadow); }
.login-header-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 4px; }
.login-header-row h1 { flex: 1; }
.login-card h1 { font-size: 18px; margin: 0; text-align: center; }
.login-card .subtitle { color: var(--muted); margin: 0 0 8px; font-size: 13px; text-align: center; }
.login-card button { width: 100%; margin-top: 20px; padding: 10px; }
.login-card .hint { color: #64748b; font-size: 11px; margin-top: 16px; text-align: center; }

/* Fixed 2x2 grid, not a squeezed flex row - the previous flex-wrap +
   white-space:nowrap combination let tab labels overflow their own
   boundary and overlap the neighboring tab on a narrow card instead of
   wrapping or shrinking, which read as "text/buttons merged together". */
.role-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin: 18px 0 4px; }
.role-tab {
    background: var(--input-bg); border: 1px solid var(--border); border-radius: 7px; color: var(--muted);
    padding: 9px 8px; font-size: 12.5px; font-weight: 600; cursor: pointer;
    text-align: center; line-height: 1.3;
}
.role-tab:hover { color: var(--text); border-color: var(--accent); }
.role-tab.active { color: var(--accent-text); background: var(--accent); border-color: var(--accent); }
.role-panel { display: none; }
.role-panel.active { display: block; }

/* Manage Accounts role tabs (core/manage_accounts.html) - same idea as
   .role-tabs above (login page), but a plain underlined row like
   nav.tabnav instead of a 2-column grid of filled chips - this page has
   the full page width to work with, not a narrow login card. */
.account-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 18px; flex-wrap: wrap; }
.account-tab {
    background: transparent; border: none; color: var(--muted); padding: 10px 16px;
    cursor: pointer; font-size: 13px; font-weight: 600; border-bottom: 2px solid transparent; font-family: inherit;
}
.account-tab:hover { color: var(--text); }
.account-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.account-panel { display: none; }
.account-panel.active { display: block; }

/* Same underlined-tab-row pattern as .account-tabs above, generalized
   for reuse on any page that wants this "sub-header" layout (currently
   the Logistics Dashboard, logistics_admin/dashboard.html) - kept as
   its own separate rule set rather than renaming .account-tab/
   .account-panel in place, so this didn't require touching Manage
   Accounts' own already-working markup/JS at all. */
.subtabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 18px; flex-wrap: wrap; }
/* .subtab started as a <button> (JS-toggled panels, e.g. Daily FC
   Reporting's own Progress/Submission Status/etc.) - core/dashboards_
   hub.html reuses the same class on plain <a> links instead (real
   navigations to a different page, not a panel to toggle), so
   display:inline-block is needed here for an anchor to accept the
   padding/border the way a <button> already does by default; no visual
   change for any existing <button class="subtab"> usage. */
.subtab {
    background: transparent; border: none; color: var(--muted); padding: 10px 16px;
    cursor: pointer; font-size: 13px; font-weight: 600; border-bottom: 2px solid transparent; font-family: inherit;
    display: inline-block;
}
.subtab:hover { color: var(--text); }
.subtab.active { color: var(--accent); border-bottom-color: var(--accent); }
.subtab-panel { display: none; }
.subtab-panel.active { display: block; }

/* ---------- pagination ---------- */
.pagination { margin-top: 16px; display: flex; gap: 12px; align-items: center; font-size: 13px; color: var(--muted); flex-wrap: wrap; }

/* ---------- CMO mobile portal (always a phone screen, regardless of the
   viewport-width breakpoints elsewhere - sized like a native app UI, not
   scaled down to match the desktop screens) ---------- */
.mobile-header {
    background: var(--card); padding: 16px 18px; border-bottom: 1px solid var(--border);
    position: sticky; top: 0; z-index: 5; box-shadow: var(--shadow);
}
.mobile-header h1 { font-size: 20px; margin: 0 0 4px; }

/* FC Coordinator portal's own two-panel header (Shoaib, 2026-09-24: "1
   pannel for site name, Coordinator Name, Number of reports, Theam
   option, and logot option and second pannel for Stats Dashboard,
   Monthly Data Reports, Due Cases and Upload Due Cases and SAM and MAM
   Cases... same size" - fc_portal/dashboard.html only, the one FC
   portal page whose old single-row header crowded identity info,
   5 nav buttons, the theme toggle AND Log Out into one flex-wrap row,
   pushing the last couple of controls to the right edge where they
   read as clipped/hidden on a narrow phone screen). Same visual
   treatment for both (background/border/radius/padding all identical,
   only their content differs) so they read as a matched pair, sitting
   one above the other inside .mobile-header's own sticky bar. */
.fc-header-panel {
    background: var(--input-bg); border: 1px solid var(--border); border-radius: 10px;
    padding: 12px 14px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.fc-header-panel + .fc-header-panel { margin-top: 10px; }
.fc-header-panel .fc-site-name { font-size: 17px; font-weight: 700; margin: 0; }
.fc-header-panel .fc-coord-meta { color: var(--muted); font-size: 12.5px; margin: 2px 0 0; }
.mobile-content { padding: 14px; max-width: 640px; margin: 0 auto; font-size: 16px; }

/* form controls in the CMO portal / any login page are always full-size,
   not conditioned on a viewport-width media query - prevents iOS Safari's
   auto-zoom-on-focus regardless of how a browser reports its width, and
   these screens are only ever used on a phone anyway. */
.mobile-content input, .mobile-content select, .mobile-content textarea,
.login-body input, .login-body select, .login-body textarea {
    font-size: 16px; padding: 12px 14px; min-height: 46px;
}
.mobile-content textarea, .login-body textarea { min-height: 90px; }
.mobile-content button, .mobile-content .btn,
.login-body button, .login-body .btn {
    font-size: 16px; padding: 12px 18px; min-height: 46px;
}
.mobile-content .btn.small, .login-body .btn.small { font-size: 13px; padding: 9px 14px; min-height: 38px; }
.mobile-content form label, .login-body form label { font-size: 14px; }

.case-card {
    background: var(--card); border: 1px solid var(--border); border-radius: 12px;
    margin-bottom: 12px; color: var(--text); box-shadow: var(--shadow); overflow: hidden;
}
.case-card-link { display: block; padding: 16px; color: var(--text); }
.case-card-link:hover { text-decoration: none; }
.case-card .top { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.case-card .name { font-weight: 700; font-size: 17px; }
.case-card .addr { color: var(--muted); font-size: 14px; margin-top: 5px; }
.case-card .meta { color: var(--muted); font-size: 13px; margin-top: 7px; }

.case-actions {
    display: flex; gap: 6px; padding: 10px 12px; border-top: 1px solid var(--border);
    background: var(--input-bg); flex-wrap: nowrap;
}
.case-actions .btn { flex: 1; min-width: 100px; text-align: center; }
/* Shoaib, 2026-10-27: "Call, Log Call And Full Reports should aslo be
   in onw row in mobile view" - .mobile-content .btn.small's own touch-
   friendly sizing (13px font, 14px side padding) is right everywhere
   ELSE it's used, but 3 of those side by side don't fit a real phone's
   width (320-375px minus the card's own padding) - min-width:100px
   above forced them to wrap onto a second row the moment they
   couldn't all fit at that size. This specific row instead shrinks
   each button equally to fill whatever width IS available (min-width:
   0 overrides the generic rule above for just these three) and
   truncates with an ellipsis rather than wrapping its text if a label
   still doesn't fit, so the row itself never breaks even on the
   narrowest phone screens. Matches .mobile-content .btn.small's own
   specificity (4 classes) so it reliably wins regardless of source order. */
.mobile-content .case-actions .btn.small { flex: 1 1 0; min-width: 0; padding: 8px 4px; font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.pill { padding: 4px 11px; border-radius: 999px; font-size: 12px; font-weight: 700; flex-shrink: 0; }
.pill.assigned, .pill.pending { background: #3a2f0f; color: var(--yellow); }
.pill.reported, .pill.resolved, .pill.responded { background: #14301f; color: var(--green); }
.pill.escalated, .pill.not_responded { background: #3a1414; color: var(--red); }
.pill.aged_out, .pill.na { background: var(--input-bg); color: var(--muted); }
:root[data-theme="light"] .pill.assigned, :root[data-theme="light"] .pill.pending { background: #fff4ce; }
:root[data-theme="light"] .pill.reported, :root[data-theme="light"] .pill.resolved, :root[data-theme="light"] .pill.responded { background: #dff6dd; }
:root[data-theme="light"] .pill.escalated, :root[data-theme="light"] .pill.not_responded { background: #fde2e2; }

.empty { color: var(--muted); text-align: center; padding: 40px 20px; font-size: 15px; }

.cmo-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(128px, 1fr)); gap: 8px; margin-bottom: 14px; }
.cmo-stat { background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; box-shadow: var(--shadow); }
.cmo-stat-num { font-size: 21px; font-weight: 700; }
.cmo-stat-label { font-size: 11px; color: var(--muted); margin-top: 2px; line-height: 1.3; }

/* Shoaib, 2026-10-27: "two filter per row in a butifull manner", then
   follow-up: "cutten filters are taking too much sapce on moble. make
   them like previous one butt two pwnnels in one row must" - the
   labeled-field-above-select/panel-box version that first request
   produced was itself the thing taking too much space (a label line
   plus the panel's own border/padding/shadow on top of 5 already-tall
   46px touch-friendly selects); back to plain bare <select> elements
   with no label and no box (each one's own first option serves as its
   label, same as the original .toolbar row before either change), just
   kept in a strict 2-column grid instead of .toolbar's free-wrapping
   flex row - the one part of the "beautiful" version actually worth
   keeping. Sort (the lone 5th field) spans both columns directly via
   its own class rather than a wrapper div, since there's no longer a
   per-field wrapper to put it on. */
/* Shoaib: "two pwnnels in one row must" - no narrow-width fallback to
   a single column (unlike most of this app's other responsive grids) -
   a <select>'s own CLOSED-state text just clips/ellipses within
   whatever width it gets, same as a button already does elsewhere in
   this file, so staying at 2 columns even at the narrowest real phone
   width doesn't break anything, it only shortens what's visible until
   the dropdown is actually opened. */
.cmo-filter-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 14px; }
.cmo-filter-grid select { width: 100%; min-width: 0; text-overflow: ellipsis; }
.cmo-filter-grid select.span2 { grid-column: span 2; }

.detail-list { margin: 10px 0 0; }
.detail-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 14px; }
.detail-row:last-child { border-bottom: none; }
.detail-row .k { color: var(--muted); flex-shrink: 0; }
.detail-row .v { text-align: right; font-weight: 600; word-break: break-word; }

/* ---------- district/site scope picker (Manage Coordinators/Operators/CMOs) ---------- */
.scope-picker { display: flex; gap: 14px; flex-wrap: wrap; }
.scope-col { min-width: 210px; flex: 1; }
.scope-label { font-size: 11px; color: var(--muted); margin-bottom: 4px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.scope-search { width: 100%; margin-bottom: 6px; padding: 6px 8px; font-size: 12.5px; }
.scope-list { max-height: 170px; overflow-y: auto; border: 1px solid var(--border); border-radius: 6px; background: var(--input-bg); }
.scope-item { display: flex; align-items: center; gap: 7px; padding: 6px 10px; font-size: 12.5px; cursor: pointer; border-bottom: 1px solid var(--border); }
.scope-item:last-child { border-bottom: none; }
.scope-item:hover { background: var(--card); }
.scope-item input { width: auto; margin: 0; flex-shrink: 0; }
.scope-item span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.scope-count { font-size: 11px; color: var(--muted); margin-top: 4px; }
.scope-hint { font-size: 11px; color: var(--muted); margin-top: 4px; font-style: italic; }
.scope-empty { padding: 10px; font-size: 12px; color: var(--muted); }

/* ---------- small screens ---------- */
@media (max-width: 640px) {
    body { font-size: 14px; }
    .content { padding: 12px 12px 40px; }
    .panel { padding: 14px; }
    table { font-size: 12px; }
    th, td { padding: 6px 8px; }
    .login-card { padding: 22px; }

    /* iOS Safari auto-zooms the whole page when a focused input's
       computed font-size is under 16px - this is the real cause behind
       "the page looks small/zoomed" complaints on phones, not an actual
       layout bug. Every form control needs to clear that threshold. */
    input:not([type=checkbox]):not([type=radio]), select, textarea, button, .btn { font-size: 16px; }
    form label { font-size: 13px; }

    /* bigger tap targets - Apple/Google HIG recommend ~44px minimum
       (checkboxes/radios excluded - browsers ignore padding/min-height
       on them anyway, and the scope-picker's checkboxes already have
       their own tighter sizing) */
    button, .btn { padding: 11px 18px; min-height: 44px; }
    .btn.small { padding: 8px 14px; min-height: 36px; }
    input:not([type=checkbox]):not([type=radio]), select, textarea { padding: 11px 12px; min-height: 44px; }
    textarea { min-height: 90px; }
    .theme-toggle { min-height: 36px; padding: 8px 12px; }

    /* CMO field portal - the screen this is most likely to be opened on */
    .mobile-header { padding: 12px 14px; }
    .mobile-header h1 { font-size: 18px; }
    .mobile-content { padding: 10px; }
    .case-card { padding: 16px; }
    .case-card .name { font-size: 16px; }
    .case-card .addr { font-size: 14px; }
    .case-card .meta { font-size: 13px; }
    .pill { padding: 5px 11px; font-size: 12px; }
}
